dual-brain 0.2.30 → 0.3.1

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 (312) hide show
  1. package/.dual-brain/docs/claude-code-extension-points.md +32 -0
  2. package/.dual-brain/docs/data-tools-capabilities.md +181 -0
  3. package/.dual-brain/docs/ecosystem-tools.md +91 -0
  4. package/.dual-brain/docs/panel-handoff.md +124 -0
  5. package/.dual-brain/docs/ruflo-analysis.md +48 -0
  6. package/bin/dual-brain.mjs +56 -56
  7. package/dist/mcp-server/index.d.ts +27 -0
  8. package/dist/mcp-server/index.js +359 -0
  9. package/dist/mcp-server/index.js.map +1 -0
  10. package/dist/src/agent-protocol.d.ts +163 -0
  11. package/dist/src/agent-protocol.js +368 -0
  12. package/dist/src/agent-protocol.js.map +1 -0
  13. package/dist/src/agents/registry.d.ts +52 -0
  14. package/dist/src/agents/registry.js +393 -0
  15. package/dist/src/agents/registry.js.map +1 -0
  16. package/dist/src/awareness.d.ts +93 -0
  17. package/dist/src/awareness.js +406 -0
  18. package/dist/src/awareness.js.map +1 -0
  19. package/dist/src/brief.d.ts +48 -0
  20. package/dist/src/brief.js +179 -0
  21. package/dist/src/brief.js.map +1 -0
  22. package/dist/src/calibration.d.ts +32 -0
  23. package/dist/src/calibration.js +133 -0
  24. package/dist/src/calibration.js.map +1 -0
  25. package/dist/src/checkpoint.d.ts +33 -0
  26. package/dist/src/checkpoint.js +99 -0
  27. package/dist/src/checkpoint.js.map +1 -0
  28. package/dist/src/ci-triage.d.ts +33 -0
  29. package/dist/src/ci-triage.js +193 -0
  30. package/dist/src/ci-triage.js.map +1 -0
  31. package/dist/src/cognitive-loop.d.ts +56 -0
  32. package/dist/src/cognitive-loop.js +495 -0
  33. package/dist/src/cognitive-loop.js.map +1 -0
  34. package/dist/src/collaboration.d.ts +147 -0
  35. package/dist/src/collaboration.js +438 -0
  36. package/dist/src/collaboration.js.map +1 -0
  37. package/dist/src/context-intel.d.ts +47 -0
  38. package/dist/src/context-intel.js +156 -0
  39. package/dist/src/context-intel.js.map +1 -0
  40. package/dist/src/context.d.ts +53 -0
  41. package/dist/src/context.js +332 -0
  42. package/dist/src/context.js.map +1 -0
  43. package/dist/src/continuity.d.ts +89 -0
  44. package/dist/src/continuity.js +230 -0
  45. package/dist/src/continuity.js.map +1 -0
  46. package/dist/src/cost-tracker.d.ts +47 -0
  47. package/dist/src/cost-tracker.js +170 -0
  48. package/dist/src/cost-tracker.js.map +1 -0
  49. package/dist/src/debrief.d.ts +53 -0
  50. package/dist/src/debrief.js +222 -0
  51. package/dist/src/debrief.js.map +1 -0
  52. package/dist/src/decide.d.ts +96 -0
  53. package/dist/src/decide.js +744 -0
  54. package/dist/src/decide.js.map +1 -0
  55. package/dist/src/decompose.d.ts +39 -0
  56. package/dist/src/decompose.js +218 -0
  57. package/dist/src/decompose.js.map +1 -0
  58. package/dist/src/detect.d.ts +91 -0
  59. package/dist/src/detect.js +544 -0
  60. package/dist/src/detect.js.map +1 -0
  61. package/dist/src/dispatch.d.ts +154 -0
  62. package/dist/src/dispatch.js +1306 -0
  63. package/dist/src/dispatch.js.map +1 -0
  64. package/dist/src/doctor.d.ts +421 -0
  65. package/dist/src/doctor.js +1689 -0
  66. package/dist/src/doctor.js.map +1 -0
  67. package/dist/src/engine.d.ts +70 -0
  68. package/dist/src/engine.js +155 -0
  69. package/dist/src/engine.js.map +1 -0
  70. package/dist/src/envelope.d.ts +36 -0
  71. package/dist/src/envelope.js +80 -0
  72. package/dist/src/envelope.js.map +1 -0
  73. package/dist/src/failure-memory.d.ts +55 -0
  74. package/dist/src/failure-memory.js +175 -0
  75. package/dist/src/failure-memory.js.map +1 -0
  76. package/dist/src/fx.d.ts +87 -0
  77. package/dist/src/fx.js +272 -0
  78. package/dist/src/fx.js.map +1 -0
  79. package/dist/src/governance.d.ts +93 -0
  80. package/dist/src/governance.js +261 -0
  81. package/dist/src/governance.js.map +1 -0
  82. package/dist/src/handoff.d.ts +11 -0
  83. package/dist/src/handoff.js +90 -0
  84. package/dist/src/handoff.js.map +1 -0
  85. package/dist/src/head-protocol.d.ts +76 -0
  86. package/dist/src/head-protocol.js +109 -0
  87. package/dist/src/head-protocol.js.map +1 -0
  88. package/dist/src/head.d.ts +222 -0
  89. package/dist/src/head.js +765 -0
  90. package/dist/src/head.js.map +1 -0
  91. package/dist/src/health.d.ts +132 -0
  92. package/dist/src/health.js +435 -0
  93. package/dist/src/health.js.map +1 -0
  94. package/dist/src/inbox.d.ts +70 -0
  95. package/dist/src/inbox.js +218 -0
  96. package/dist/src/inbox.js.map +1 -0
  97. package/dist/src/index.d.ts +33 -0
  98. package/dist/src/index.js +38 -0
  99. package/dist/src/index.js.map +1 -0
  100. package/dist/src/install-hooks.d.ts +13 -0
  101. package/dist/src/install-hooks.js +88 -0
  102. package/dist/src/install-hooks.js.map +1 -0
  103. package/dist/src/integrity.d.ts +59 -0
  104. package/dist/src/integrity.js +206 -0
  105. package/dist/src/integrity.js.map +1 -0
  106. package/dist/src/intelligence.d.ts +104 -0
  107. package/dist/src/intelligence.js +391 -0
  108. package/dist/src/intelligence.js.map +1 -0
  109. package/dist/src/ledger.d.ts +54 -0
  110. package/dist/src/ledger.js +179 -0
  111. package/dist/src/ledger.js.map +1 -0
  112. package/dist/src/living-docs.d.ts +14 -0
  113. package/dist/src/living-docs.js +197 -0
  114. package/dist/src/living-docs.js.map +1 -0
  115. package/dist/src/memory-tiers.d.ts +37 -0
  116. package/dist/src/memory-tiers.js +160 -0
  117. package/dist/src/memory-tiers.js.map +1 -0
  118. package/dist/src/model-profiles.d.ts +65 -0
  119. package/dist/src/model-profiles.js +568 -0
  120. package/dist/src/model-profiles.js.map +1 -0
  121. package/dist/src/models.d.ts +58 -0
  122. package/dist/src/models.js +327 -0
  123. package/dist/src/models.js.map +1 -0
  124. package/dist/src/narrative.d.ts +54 -0
  125. package/dist/src/narrative.js +163 -0
  126. package/dist/src/narrative.js.map +1 -0
  127. package/dist/src/nextstep.d.ts +16 -0
  128. package/dist/src/nextstep.js +103 -0
  129. package/dist/src/nextstep.js.map +1 -0
  130. package/dist/src/observer.d.ts +18 -0
  131. package/dist/src/observer.js +251 -0
  132. package/dist/src/observer.js.map +1 -0
  133. package/dist/src/outcome.d.ts +110 -0
  134. package/dist/src/outcome.js +377 -0
  135. package/dist/src/outcome.js.map +1 -0
  136. package/dist/src/pipeline.d.ts +167 -0
  137. package/dist/src/pipeline.js +1503 -0
  138. package/dist/src/pipeline.js.map +1 -0
  139. package/dist/src/playbook.d.ts +59 -0
  140. package/dist/src/playbook.js +238 -0
  141. package/dist/src/playbook.js.map +1 -0
  142. package/dist/src/pr-agent.d.ts +97 -0
  143. package/dist/src/pr-agent.js +195 -0
  144. package/dist/src/pr-agent.js.map +1 -0
  145. package/dist/src/predictive.d.ts +57 -0
  146. package/dist/src/predictive.js +230 -0
  147. package/dist/src/predictive.js.map +1 -0
  148. package/dist/src/profile.d.ts +294 -0
  149. package/dist/src/profile.js +1347 -0
  150. package/dist/src/profile.js.map +1 -0
  151. package/dist/src/prompt-audit.d.ts +22 -0
  152. package/dist/src/prompt-audit.js +194 -0
  153. package/dist/src/prompt-audit.js.map +1 -0
  154. package/dist/src/prompt-intel.d.ts +12 -0
  155. package/dist/src/prompt-intel.js +321 -0
  156. package/dist/src/prompt-intel.js.map +1 -0
  157. package/dist/src/provider-context.d.ts +121 -0
  158. package/dist/src/provider-context.js +222 -0
  159. package/dist/src/provider-context.js.map +1 -0
  160. package/dist/src/provider-manager.d.ts +92 -0
  161. package/dist/src/provider-manager.js +428 -0
  162. package/dist/src/provider-manager.js.map +1 -0
  163. package/dist/src/receipt.d.ts +87 -0
  164. package/dist/src/receipt.js +326 -0
  165. package/dist/src/receipt.js.map +1 -0
  166. package/dist/src/recommendations.d.ts +13 -0
  167. package/dist/src/recommendations.js +291 -0
  168. package/dist/src/recommendations.js.map +1 -0
  169. package/dist/src/redact.d.ts +15 -0
  170. package/dist/src/redact.js +129 -0
  171. package/dist/src/redact.js.map +1 -0
  172. package/dist/src/replit.d.ts +397 -0
  173. package/dist/src/replit.js +1160 -0
  174. package/dist/src/replit.js.map +1 -0
  175. package/dist/src/repo.d.ts +149 -0
  176. package/dist/src/repo.js +416 -0
  177. package/dist/src/repo.js.map +1 -0
  178. package/dist/src/revert.d.ts +30 -0
  179. package/dist/src/revert.js +166 -0
  180. package/dist/src/revert.js.map +1 -0
  181. package/dist/src/room.d.ts +102 -0
  182. package/dist/src/room.js +212 -0
  183. package/dist/src/room.js.map +1 -0
  184. package/dist/src/routing-advisor.d.ts +57 -0
  185. package/dist/src/routing-advisor.js +221 -0
  186. package/dist/src/routing-advisor.js.map +1 -0
  187. package/dist/src/self-correct.d.ts +40 -0
  188. package/dist/src/self-correct.js +137 -0
  189. package/dist/src/self-correct.js.map +1 -0
  190. package/dist/src/session-lock.d.ts +35 -0
  191. package/dist/src/session-lock.js +134 -0
  192. package/dist/src/session-lock.js.map +1 -0
  193. package/dist/src/session.d.ts +267 -0
  194. package/dist/src/session.js +1660 -0
  195. package/dist/src/session.js.map +1 -0
  196. package/dist/src/settings-tui.d.ts +5 -0
  197. package/dist/src/settings-tui.js +422 -0
  198. package/dist/src/settings-tui.js.map +1 -0
  199. package/dist/src/setup-flow.d.ts +63 -0
  200. package/dist/src/setup-flow.js +233 -0
  201. package/dist/src/setup-flow.js.map +1 -0
  202. package/dist/src/signal.d.ts +19 -0
  203. package/dist/src/signal.js +122 -0
  204. package/dist/src/signal.js.map +1 -0
  205. package/dist/src/simmer.d.ts +85 -0
  206. package/dist/src/simmer.js +224 -0
  207. package/dist/src/simmer.js.map +1 -0
  208. package/dist/src/state-export.d.ts +129 -0
  209. package/dist/src/state-export.js +233 -0
  210. package/dist/src/state-export.js.map +1 -0
  211. package/dist/src/strategy.d.ts +54 -0
  212. package/dist/src/strategy.js +95 -0
  213. package/dist/src/strategy.js.map +1 -0
  214. package/dist/src/subscription.d.ts +40 -0
  215. package/dist/src/subscription.js +189 -0
  216. package/dist/src/subscription.js.map +1 -0
  217. package/dist/src/templates.d.ts +208 -0
  218. package/dist/src/templates.js +238 -0
  219. package/dist/src/templates.js.map +1 -0
  220. package/dist/src/test.d.ts +9 -0
  221. package/dist/src/test.js +1173 -0
  222. package/dist/src/test.js.map +1 -0
  223. package/dist/src/think-engine.d.ts +67 -0
  224. package/dist/src/think-engine.js +412 -0
  225. package/dist/src/think-engine.js.map +1 -0
  226. package/dist/src/tui.d.ts +71 -0
  227. package/dist/src/tui.js +242 -0
  228. package/dist/src/tui.js.map +1 -0
  229. package/dist/src/types.d.ts +177 -0
  230. package/dist/src/types.js +6 -0
  231. package/dist/src/types.js.map +1 -0
  232. package/dist/src/update-check.d.ts +7 -0
  233. package/dist/src/update-check.js +36 -0
  234. package/dist/src/update-check.js.map +1 -0
  235. package/dist/src/wave-planner.d.ts +30 -0
  236. package/dist/src/wave-planner.js +281 -0
  237. package/dist/src/wave-planner.js.map +1 -0
  238. package/hooks/head-guard.sh +41 -0
  239. package/hooks/precompact.mjs +3 -3
  240. package/hooks/session-end.mjs +3 -3
  241. package/hooks/task-classifier.mjs +328 -0
  242. package/hooks/vibe-router.mjs +387 -0
  243. package/install.mjs +2 -2
  244. package/package.json +29 -153
  245. package/src/agents/registry.mjs +0 -405
  246. package/src/awareness.mjs +0 -425
  247. package/src/brief.mjs +0 -266
  248. package/src/calibration.mjs +0 -148
  249. package/src/checkpoint.mjs +0 -109
  250. package/src/ci-triage.mjs +0 -191
  251. package/src/cognitive-loop.mjs +0 -562
  252. package/src/collaboration.mjs +0 -545
  253. package/src/context-intel.mjs +0 -158
  254. package/src/context.mjs +0 -389
  255. package/src/continuity.mjs +0 -298
  256. package/src/cost-tracker.mjs +0 -184
  257. package/src/debrief.mjs +0 -228
  258. package/src/decide.mjs +0 -1099
  259. package/src/decompose.mjs +0 -331
  260. package/src/detect.mjs +0 -702
  261. package/src/dispatch.mjs +0 -1447
  262. package/src/doctor.mjs +0 -1607
  263. package/src/envelope.mjs +0 -139
  264. package/src/failure-memory.mjs +0 -178
  265. package/src/fx.mjs +0 -276
  266. package/src/governance.mjs +0 -279
  267. package/src/handoff.mjs +0 -87
  268. package/src/head-protocol.mjs +0 -128
  269. package/src/head.mjs +0 -952
  270. package/src/health.mjs +0 -528
  271. package/src/inbox.mjs +0 -195
  272. package/src/index.mjs +0 -44
  273. package/src/install-hooks.mjs +0 -100
  274. package/src/integrity.mjs +0 -245
  275. package/src/intelligence.mjs +0 -447
  276. package/src/ledger.mjs +0 -196
  277. package/src/living-docs.mjs +0 -210
  278. package/src/memory-tiers.mjs +0 -193
  279. package/src/models.mjs +0 -363
  280. package/src/narrative.mjs +0 -169
  281. package/src/nextstep.mjs +0 -100
  282. package/src/observer.mjs +0 -241
  283. package/src/outcome.mjs +0 -400
  284. package/src/pipeline.mjs +0 -1711
  285. package/src/playbook.mjs +0 -257
  286. package/src/pr-agent.mjs +0 -214
  287. package/src/predictive.mjs +0 -250
  288. package/src/profile.mjs +0 -1411
  289. package/src/prompt-audit.mjs +0 -231
  290. package/src/prompt-intel.mjs +0 -325
  291. package/src/provider-context.mjs +0 -257
  292. package/src/receipt.mjs +0 -344
  293. package/src/recommendations.mjs +0 -296
  294. package/src/redact.mjs +0 -192
  295. package/src/replit.mjs +0 -1210
  296. package/src/repo.mjs +0 -445
  297. package/src/revert.mjs +0 -149
  298. package/src/routing-advisor.mjs +0 -204
  299. package/src/self-correct.mjs +0 -147
  300. package/src/session-lock.mjs +0 -160
  301. package/src/session.mjs +0 -1655
  302. package/src/settings-tui.mjs +0 -373
  303. package/src/setup-flow.mjs +0 -223
  304. package/src/signal.mjs +0 -115
  305. package/src/simmer.mjs +0 -241
  306. package/src/strategy.mjs +0 -235
  307. package/src/subscription.mjs +0 -212
  308. package/src/templates.mjs +0 -260
  309. package/src/think-engine.mjs +0 -428
  310. package/src/tui.mjs +0 -276
  311. package/src/update-check.mjs +0 -35
  312. package/src/wave-planner.mjs +0 -294
@@ -0,0 +1,63 @@
1
+ interface DetectedEnvironment {
2
+ claude: boolean;
3
+ codex: boolean;
4
+ git: boolean;
5
+ gitBranch: string | null;
6
+ language: string;
7
+ existingConfig: boolean;
8
+ }
9
+ interface SetupAnswers {
10
+ subscription?: string;
11
+ workStyle?: string;
12
+ advanced?: AdvancedOptions;
13
+ setupMode?: string;
14
+ }
15
+ interface AdvancedOptions {
16
+ thinkEnabled?: boolean;
17
+ cascadeEnabled?: boolean;
18
+ learningEnabled?: boolean;
19
+ explorationRate?: number;
20
+ sessionLimitTokens?: number | null;
21
+ warnAtPercent?: number;
22
+ models?: Record<string, string>;
23
+ }
24
+ interface SetupConfig {
25
+ version: number;
26
+ subscription: string;
27
+ workStyle: string;
28
+ providers: {
29
+ claude: boolean;
30
+ openai: boolean;
31
+ };
32
+ routing: {
33
+ thinkEnabled: boolean;
34
+ cascadeEnabled: boolean;
35
+ learningEnabled: boolean;
36
+ explorationRate: number;
37
+ };
38
+ models: Record<string, string>;
39
+ budget: {
40
+ sessionLimitTokens: number | null;
41
+ warnAtPercent: number;
42
+ };
43
+ configuredAt: string;
44
+ setupMode: string;
45
+ detectedEnv: {
46
+ claude: boolean;
47
+ codex: boolean;
48
+ language: string;
49
+ };
50
+ }
51
+ interface SetupOptions {
52
+ nonInteractive?: boolean;
53
+ reconfigure?: boolean;
54
+ subscription?: string;
55
+ workStyle?: string;
56
+ }
57
+ export declare function detectEnvironment(cwd: string): DetectedEnvironment;
58
+ export declare function renderWelcome(detected: DetectedEnvironment): string;
59
+ export declare function renderConfirmation(config: SetupConfig): string;
60
+ export declare function buildConfig(answers: SetupAnswers, detected: DetectedEnvironment): SetupConfig;
61
+ export declare function saveConfig(config: SetupConfig, cwd: string): void;
62
+ export declare function runSetup(cwd: string, options?: SetupOptions): Promise<SetupConfig | null>;
63
+ export {};
@@ -0,0 +1,233 @@
1
+ // setup-flow.ts — Interactive first-run setup for dual-brain
2
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { createInterface } from 'node:readline';
5
+ import { execSync } from 'node:child_process';
6
+ // ── ANSI helpers ──────────────────────────────────────────────────────────────
7
+ const c = {
8
+ bold: (s) => `\x1b[1m${s}\x1b[0m`,
9
+ dim: (s) => `\x1b[2m${s}\x1b[0m`,
10
+ green: (s) => `\x1b[32m${s}\x1b[0m`,
11
+ yellow: (s) => `\x1b[33m${s}\x1b[0m`,
12
+ cyan: (s) => `\x1b[36m${s}\x1b[0m`,
13
+ red: (s) => `\x1b[31m${s}\x1b[0m`,
14
+ };
15
+ // ── Detection ─────────────────────────────────────────────────────────────────
16
+ export function detectEnvironment(cwd) {
17
+ const tryCmd = (cmd) => { try {
18
+ execSync(cmd, { stdio: 'pipe' });
19
+ return true;
20
+ }
21
+ catch {
22
+ return false;
23
+ } };
24
+ let language = 'unknown';
25
+ if (existsSync(join(cwd, 'package.json')))
26
+ language = 'node';
27
+ else if (existsSync(join(cwd, 'pyproject.toml')) ||
28
+ existsSync(join(cwd, 'setup.py')))
29
+ language = 'python';
30
+ else if (existsSync(join(cwd, 'go.mod')))
31
+ language = 'go';
32
+ else if (existsSync(join(cwd, 'Cargo.toml')))
33
+ language = 'rust';
34
+ else if (existsSync(join(cwd, 'pom.xml')))
35
+ language = 'java';
36
+ let gitBranch = null;
37
+ try {
38
+ gitBranch = execSync('git -C "' + cwd + '" branch --show-current', { stdio: 'pipe' }).toString().trim();
39
+ }
40
+ catch { }
41
+ return {
42
+ claude: tryCmd('claude --version'),
43
+ codex: tryCmd('codex --version'),
44
+ git: !!gitBranch,
45
+ gitBranch: gitBranch || null,
46
+ language,
47
+ existingConfig: existsSync(join(cwd, '.dualbrain', 'config.json')),
48
+ };
49
+ }
50
+ // ── Welcome banner ────────────────────────────────────────────────────────────
51
+ export function renderWelcome(detected) {
52
+ const row = (ok, label) => c.cyan('│') + ` ${ok ? c.green('✓') : c.dim('✗')} ${ok ? label : c.dim(label)}`.padEnd(49) + c.cyan('│');
53
+ const bar = (s) => c.cyan('│') + s.padEnd(49) + c.cyan('│');
54
+ return [
55
+ c.cyan('╭' + '─'.repeat(49) + '╮'),
56
+ bar(''),
57
+ bar(` ${c.bold('dual-brain')} — intelligent model orchestration`),
58
+ bar(''),
59
+ bar(' Detected:'),
60
+ row(detected.claude, 'Claude CLI available'),
61
+ row(detected.codex, 'Codex CLI available'),
62
+ row(detected.git, `Git repository (${detected.gitBranch || 'no branch'} branch)`),
63
+ row(detected.language !== 'unknown', `${detected.language} project`),
64
+ bar(''),
65
+ c.cyan('╰' + '─'.repeat(49) + '╯'),
66
+ ].join('\n');
67
+ }
68
+ const SUB_LABELS = {
69
+ 'claude-pro': 'Claude Pro', 'claude-max-5x': 'Claude Max 5x',
70
+ 'claude-max-20x': 'Claude Max 20x', 'chatgpt-plus': 'ChatGPT Plus',
71
+ 'chatgpt-pro': 'ChatGPT Pro', 'dual-pro': 'Both Pro tiers', 'dual-max': 'Max + Pro tiers',
72
+ };
73
+ // ── Confirmation display ──────────────────────────────────────────────────────
74
+ export function renderConfirmation(config) {
75
+ const row = (k, v) => ` ${c.dim(k.padEnd(16))} ${c.cyan(v)}`;
76
+ return [
77
+ '', c.bold(' Configuration:'), '',
78
+ row('Subscription:', SUB_LABELS[config.subscription] || config.subscription),
79
+ row('Work style:', config.workStyle),
80
+ row('Primary model:', config.models.execute),
81
+ row('Think agent:', config.routing.thinkEnabled ? 'enabled' : 'disabled'),
82
+ row('Learning:', config.routing.learningEnabled ? 'on' : 'off'),
83
+ '',
84
+ ].join('\n');
85
+ }
86
+ // ── Config builder ────────────────────────────────────────────────────────────
87
+ export function buildConfig(answers, detected) {
88
+ const { subscription = 'claude-pro', workStyle = 'balanced', advanced = {}, setupMode = 'quick' } = answers;
89
+ const dual = subscription.startsWith('dual-');
90
+ const isMax = subscription.includes('max') || subscription === 'chatgpt-pro';
91
+ const topModel = isMax ? 'opus' : 'sonnet';
92
+ const exploreRate = { aggressive: 0.3, conservative: 0.1, auto: 0.25 }[workStyle] ?? 0.2;
93
+ return {
94
+ version: 1, subscription, workStyle,
95
+ providers: { claude: subscription.startsWith('claude-') || dual, openai: subscription.startsWith('chatgpt-') || dual },
96
+ routing: {
97
+ thinkEnabled: advanced.thinkEnabled ?? true,
98
+ cascadeEnabled: advanced.cascadeEnabled ?? true,
99
+ learningEnabled: advanced.learningEnabled ?? true,
100
+ explorationRate: advanced.explorationRate ?? exploreRate,
101
+ },
102
+ models: advanced.models || { search: 'haiku', execute: 'sonnet', think: topModel, review: topModel },
103
+ budget: { sessionLimitTokens: advanced.sessionLimitTokens ?? null, warnAtPercent: advanced.warnAtPercent ?? 80 },
104
+ configuredAt: new Date().toISOString(),
105
+ setupMode,
106
+ detectedEnv: { claude: detected.claude, codex: detected.codex, language: detected.language },
107
+ };
108
+ }
109
+ // ── Save config ───────────────────────────────────────────────────────────────
110
+ export function saveConfig(config, cwd) {
111
+ const dir = join(cwd, '.dualbrain');
112
+ if (!existsSync(dir))
113
+ mkdirSync(dir, { recursive: true });
114
+ writeFileSync(join(dir, 'config.json'), JSON.stringify(config, null, 2), 'utf8');
115
+ const orchPath = join(cwd, '.claude', 'orchestrator.json');
116
+ if (existsSync(orchPath)) {
117
+ try {
118
+ const orch = JSON.parse(readFileSync(orchPath, 'utf8'));
119
+ if (!orch.providers)
120
+ orch.providers = {};
121
+ orch.providers.claude = { ...(orch.providers.claude || {}), enabled: config.providers.claude, subscription: config.subscription };
122
+ orch.providers.openai = { ...(orch.providers.openai || {}), enabled: config.providers.openai };
123
+ if (config.routing)
124
+ orch.routing = { ...(orch.routing || {}), ...config.routing };
125
+ writeFileSync(orchPath, JSON.stringify(orch, null, 2), 'utf8');
126
+ }
127
+ catch { /* non-fatal */ }
128
+ }
129
+ }
130
+ // ── Readline prompt helper ────────────────────────────────────────────────────
131
+ async function ask(rl, question, options) {
132
+ const lines = options.map((o, i) => ` ${c.cyan(String(i + 1) + ')')} ${o.label}${o.description ? c.dim(' — ' + o.description) : ''}`);
133
+ const prompt = `\n${c.bold(question)}\n${lines.join('\n')}\n${c.dim('> ')}`;
134
+ return new Promise(resolve => {
135
+ rl.question(prompt, answer => {
136
+ const trimmed = answer.trim();
137
+ const idx = parseInt(trimmed, 10) - 1;
138
+ if (idx >= 0 && idx < options.length)
139
+ resolve(options[idx].value);
140
+ else
141
+ resolve(options[0].value);
142
+ });
143
+ });
144
+ }
145
+ async function askYN(rl, question, defaultYes = true) {
146
+ return new Promise(resolve => {
147
+ rl.question(`\n${c.bold(question)} ${c.dim(defaultYes ? '(Y/n)' : '(y/N)')} `, answer => {
148
+ const t = answer.trim().toLowerCase();
149
+ if (!t)
150
+ resolve(defaultYes);
151
+ else
152
+ resolve(t === 'y' || t === 'yes');
153
+ });
154
+ });
155
+ }
156
+ // ── Main entry point ──────────────────────────────────────────────────────────
157
+ export async function runSetup(cwd, options = {}) {
158
+ const detected = detectEnvironment(cwd);
159
+ // Non-TTY fast path — stdin is piped or in CI
160
+ if (!process.stdin.isTTY && !options.nonInteractive) {
161
+ process.stderr.write('[dual-brain] Non-interactive terminal detected. Use --non-interactive flag or run in a TTY.\n');
162
+ const config = buildConfig({ subscription: 'claude-pro', workStyle: 'balanced' }, detected);
163
+ saveConfig(config, cwd);
164
+ return config;
165
+ }
166
+ // Non-interactive fast path
167
+ if (options.nonInteractive) {
168
+ const config = buildConfig({
169
+ subscription: options.subscription || 'claude-pro',
170
+ workStyle: options.workStyle || 'balanced',
171
+ setupMode: 'non-interactive',
172
+ }, detected);
173
+ saveConfig(config, cwd);
174
+ return config;
175
+ }
176
+ // Already configured?
177
+ if (detected.existingConfig && !options.reconfigure) {
178
+ console.log('\n' + c.yellow('dual-brain is already configured.') + ' Pass --reconfigure to change settings.\n');
179
+ return JSON.parse(readFileSync(join(cwd, '.dualbrain', 'config.json'), 'utf8'));
180
+ }
181
+ console.log('\n' + renderWelcome(detected) + '\n');
182
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
183
+ const close = () => rl.close();
184
+ try {
185
+ const mode = await ask(rl, 'Setup mode:', [
186
+ { label: 'Quick setup', value: 'quick', description: '3 questions, ~20 seconds' },
187
+ { label: 'Advanced', value: 'advanced', description: 'full control over routing, budgets, models' },
188
+ ]);
189
+ const subscription = await ask(rl, 'Your AI subscription:', [
190
+ { label: 'Claude Pro ($20/mo)', value: 'claude-pro' },
191
+ { label: 'Claude Max 5x ($100/mo)', value: 'claude-max-5x' },
192
+ { label: 'Claude Max 20x ($200/mo)', value: 'claude-max-20x' },
193
+ { label: 'ChatGPT Plus ($20/mo)', value: 'chatgpt-plus' },
194
+ { label: 'ChatGPT Pro ($200/mo)', value: 'chatgpt-pro' },
195
+ { label: 'Both providers (Pro tiers)', value: 'dual-pro' },
196
+ { label: 'Both providers (Max tiers)', value: 'dual-max' },
197
+ ]);
198
+ const workStyle = await ask(rl, 'How should dual-brain route your work?', [
199
+ { label: 'Balanced', value: 'balanced', description: 'smart defaults, asks before expensive ops' },
200
+ { label: 'Conservative', value: 'conservative', description: 'minimize tokens, prefer cheaper models' },
201
+ { label: 'Aggressive', value: 'aggressive', description: 'best model available, maximize quality' },
202
+ { label: 'Full auto', value: 'auto', description: 'never ask, optimize silently' },
203
+ ]);
204
+ let advanced = {};
205
+ if (mode === 'advanced') {
206
+ const thinkEnabled = await askYN(rl, 'Enable think agent?', true);
207
+ const cascadeEnabled = await askYN(rl, 'Enable cascade routing?', true);
208
+ const learningEnabled = await askYN(rl, 'Enable learning (improves routing over time)?', true);
209
+ const explorationRate = await ask(rl, 'Routing exploration rate:', [
210
+ { label: 'Low (0.1)', value: 0.1, description: 'rarely tries new routes' },
211
+ { label: 'Medium (0.2)', value: 0.2, description: 'balanced' },
212
+ { label: 'High (0.3)', value: 0.3, description: 'frequently explores alternatives' },
213
+ ]);
214
+ advanced = { thinkEnabled, cascadeEnabled, learningEnabled, explorationRate };
215
+ }
216
+ const config = buildConfig({ subscription, workStyle, advanced, setupMode: mode }, detected);
217
+ console.log(renderConfirmation(config));
218
+ if (!await askYN(rl, 'Save and start?', true)) {
219
+ console.log('\n' + c.yellow('Setup cancelled.') + '\n');
220
+ close();
221
+ return null;
222
+ }
223
+ saveConfig(config, cwd);
224
+ console.log('\n' + c.green('✓') + ' ' + c.bold('dual-brain configured.') + ' Config saved to ' + c.cyan('.dualbrain/config.json') + '\n');
225
+ close();
226
+ return config;
227
+ }
228
+ catch (err) {
229
+ close();
230
+ throw err;
231
+ }
232
+ }
233
+ //# sourceMappingURL=setup-flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-flow.js","sourceRoot":"","sources":["../../src/setup-flow.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAa,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,iFAAiF;AACjF,MAAM,CAAC,GAAG;IACR,IAAI,EAAI,CAAC,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS;IAC3C,GAAG,EAAK,CAAC,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS;IAC3C,KAAK,EAAG,CAAC,CAAS,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS;IAC5C,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS;IAC5C,IAAI,EAAI,CAAC,CAAS,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS;IAC5C,GAAG,EAAK,CAAC,CAAS,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS;CAC7C,CAAC;AA4DF,iFAAiF;AACjF,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,MAAM,MAAM,GAAG,CAAC,GAAW,EAAW,EAAE,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC,CAAC,CAAC,CAAC;IAE5H,IAAI,QAAQ,GAAG,SAAS,CAAC;IACzB,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAAO,QAAQ,GAAG,MAAM,CAAC;SAC7D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QACvC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAAO,QAAQ,GAAG,QAAQ,CAAC;SAChE,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAAS,QAAQ,GAAG,IAAI,CAAC;SAC5D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAAK,QAAQ,GAAG,MAAM,CAAC;SAC9D,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAAQ,QAAQ,GAAG,MAAM,CAAC;IAEnE,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,IAAI,CAAC;QAAC,SAAS,GAAG,QAAQ,CAAC,UAAU,GAAG,GAAG,GAAG,yBAAyB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEzH,OAAO;QACL,MAAM,EAAU,MAAM,CAAC,kBAAkB,CAAC;QAC1C,KAAK,EAAW,MAAM,CAAC,iBAAiB,CAAC;QACzC,GAAG,EAAa,CAAC,CAAC,SAAS;QAC3B,SAAS,EAAO,SAAS,IAAI,IAAI;QACjC,QAAQ;QACR,cAAc,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;KACnE,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,aAAa,CAAC,QAA6B;IACzD,MAAM,GAAG,GAAG,CAAC,EAAW,EAAE,KAAa,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvJ,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpE,OAAO;QACL,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;QAClC,GAAG,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,oCAAoC,CAAC;QACnE,GAAG,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,cAAc,CAAC;QACnB,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;QAC5C,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAG,qBAAqB,CAAC;QAC3C,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAK,mBAAmB,QAAQ,CAAC,SAAS,IAAI,WAAW,UAAU,CAAC;QACpF,GAAG,CAAC,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,GAAG,QAAQ,CAAC,QAAQ,UAAU,CAAC;QACpE,GAAG,CAAC,EAAE,CAAC;QACP,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;KACnC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,GAA2B;IACzC,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe;IAC5D,gBAAgB,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc;IAClE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,iBAAiB;CAC1F,CAAC;AAEF,iFAAiF;AACjF,MAAM,UAAU,kBAAkB,CAAC,MAAmB;IACpD,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE;QAClC,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC;QAC5E,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC;QACpC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QAC5C,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;QACzE,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;QAC/D,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,OAAqB,EAAE,QAA6B;IAC9E,MAAM,EAAE,YAAY,GAAG,YAAY,EAAE,SAAS,GAAG,UAAU,EAAE,QAAQ,GAAG,EAAE,EAAE,SAAS,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC;IAC5G,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,YAAY,KAAK,aAAa,CAAC;IAC7E,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC3C,MAAM,WAAW,GAAI,EAAE,UAAU,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAA6B,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC;IACrH,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS;QACnC,SAAS,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,IAAI,EAAE;QACtH,OAAO,EAAE;YACP,YAAY,EAAK,QAAQ,CAAC,YAAY,IAAO,IAAI;YACjD,cAAc,EAAG,QAAQ,CAAC,cAAc,IAAK,IAAI;YACjD,eAAe,EAAE,QAAQ,CAAC,eAAe,IAAI,IAAI;YACjD,eAAe,EAAE,QAAQ,CAAC,eAAe,IAAI,WAAW;SACzD;QACD,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE;QACpG,MAAM,EAAE,EAAE,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB,IAAI,IAAI,EAAE,aAAa,EAAE,QAAQ,CAAC,aAAa,IAAI,EAAE,EAAE;QAChH,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACtC,SAAS;QACT,WAAW,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE;KAC7F,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,UAAU,CAAC,MAAmB,EAAE,GAAW;IACzD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACpC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,mBAAmB,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;YACxD,IAAI,CAAC,IAAI,CAAC,SAAS;gBAAE,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;YACzC,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;YAClI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YAC/F,IAAI,MAAM,CAAC,OAAO;gBAAE,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YAClF,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACjE,CAAC;QAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,KAAK,UAAU,GAAG,CAAC,EAAa,EAAE,QAAgB,EAAE,OAAqB;IACvE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvI,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5E,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;YAC3B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;YACtC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM;gBAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;;gBAC7D,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,EAAa,EAAE,QAAgB,EAAE,UAAU,GAAG,IAAI;IACrE,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE;YACtF,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACtC,IAAI,CAAC,CAAC;gBAAE,OAAO,CAAC,UAAU,CAAC,CAAC;;gBACvB,OAAO,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,UAAwB,EAAE;IACpE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAExC,8CAA8C;IAC9C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+FAA+F,CAAC,CAAC;QACtH,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC5F,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACxB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,4BAA4B;IAC5B,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,WAAW,CAAC;YACzB,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,YAAY;YAClD,SAAS,EAAK,OAAO,CAAC,SAAS,IAAO,UAAU;YAChD,SAAS,EAAK,iBAAiB;SAChC,EAAE,QAAQ,CAAC,CAAC;QACb,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACxB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,sBAAsB;IACtB,IAAI,QAAQ,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,mCAAmC,CAAC,GAAG,2CAA2C,CAAC,CAAC;QAChH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;IAEnD,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAE/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,aAAa,EAAE;YACxC,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAK,WAAW,EAAE,0BAA0B,EAAE;YACpF,EAAE,KAAK,EAAE,UAAU,EAAK,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,4CAA4C,EAAE;SACvG,CAAW,CAAC;QACb,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,uBAAuB,EAAE;YAC1D,EAAE,KAAK,EAAE,qBAAqB,EAAS,KAAK,EAAE,YAAY,EAAE;YAC5D,EAAE,KAAK,EAAE,yBAAyB,EAAK,KAAK,EAAE,eAAe,EAAE;YAC/D,EAAE,KAAK,EAAE,0BAA0B,EAAI,KAAK,EAAE,gBAAgB,EAAE;YAChE,EAAE,KAAK,EAAE,uBAAuB,EAAO,KAAK,EAAE,cAAc,EAAE;YAC9D,EAAE,KAAK,EAAE,uBAAuB,EAAO,KAAK,EAAE,aAAa,EAAE;YAC7D,EAAE,KAAK,EAAE,4BAA4B,EAAE,KAAK,EAAE,UAAU,EAAE;YAC1D,EAAE,KAAK,EAAE,4BAA4B,EAAE,KAAK,EAAE,UAAU,EAAE;SAC3D,CAAW,CAAC;QACb,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,wCAAwC,EAAE;YACxE,EAAE,KAAK,EAAE,UAAU,EAAM,KAAK,EAAE,UAAU,EAAM,WAAW,EAAE,2CAA2C,EAAE;YAC1G,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,wCAAwC,EAAE;YACvG,EAAE,KAAK,EAAE,YAAY,EAAI,KAAK,EAAE,YAAY,EAAI,WAAW,EAAE,wCAAwC,EAAE;YACvG,EAAE,KAAK,EAAE,WAAW,EAAK,KAAK,EAAE,MAAM,EAAU,WAAW,EAAE,8BAA8B,EAAE;SAC9F,CAAW,CAAC;QACb,IAAI,QAAQ,GAAoB,EAAE,CAAC;QACnC,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,MAAM,YAAY,GAAM,MAAM,KAAK,CAAC,EAAE,EAAE,qBAAqB,EAAE,IAAI,CAAC,CAAC;YACrE,MAAM,cAAc,GAAI,MAAM,KAAK,CAAC,EAAE,EAAE,yBAAyB,EAAE,IAAI,CAAC,CAAC;YACzE,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,EAAE,EAAE,+CAA+C,EAAE,IAAI,CAAC,CAAC;YAC/F,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,2BAA2B,EAAE;gBACjE,EAAE,KAAK,EAAE,WAAW,EAAK,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,yBAAyB,EAAE;gBAC7E,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE;gBAC9D,EAAE,KAAK,EAAE,YAAY,EAAI,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,kCAAkC,EAAE;aACvF,CAAW,CAAC;YACb,QAAQ,GAAG,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC;QAChF,CAAC;QACD,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7F,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,CAAC;YACxD,KAAK,EAAE,CAAC;YAAC,OAAO,IAAI,CAAC;QACvB,CAAC;QACD,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,GAAG,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,GAAG,IAAI,CAAC,CAAC;QAC1I,KAAK,EAAE,CAAC;QAAC,OAAO,MAAM,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QAAC,KAAK,EAAE,CAAC;QAAC,MAAM,GAAG,CAAC;IAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { Tier, TaskOutcome } from './types.ts';
2
+ export declare const EXPECTED_DURATION_MS: Record<Tier, number>;
3
+ export declare function scoreDurationRatio(durationMs: number, tier: Tier): number | null;
4
+ export declare function measureFileSurvival(outcome: TaskOutcome, cwd: string): number | null;
5
+ interface ScoreOutcomeContext {
6
+ fileSurvival?: number | null;
7
+ }
8
+ interface OutcomeScoreResult {
9
+ reward: number;
10
+ confidence: number;
11
+ signals: {
12
+ exitSuccess: number | boolean;
13
+ durationRatio: number | null;
14
+ tokenEfficiency: number | null;
15
+ fileSurvival: number | null;
16
+ };
17
+ }
18
+ export declare function scoreOutcome(outcome: TaskOutcome, context?: ScoreOutcomeContext): OutcomeScoreResult;
19
+ export {};
@@ -0,0 +1,122 @@
1
+ // signal.ts — Compound outcome signal scoring
2
+ // Combines multiple weak signals into one reliable reward score.
3
+ import { existsSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { execSync } from 'node:child_process';
6
+ export const EXPECTED_DURATION_MS = {
7
+ search: 15000,
8
+ execute: 45000,
9
+ think: 30000,
10
+ review: 40000,
11
+ };
12
+ export function scoreDurationRatio(durationMs, tier) {
13
+ try {
14
+ if (durationMs <= 0)
15
+ return null;
16
+ const expectedMs = EXPECTED_DURATION_MS[tier] || EXPECTED_DURATION_MS.execute;
17
+ const ratio = durationMs / expectedMs;
18
+ if (ratio >= 0.5 && ratio <= 1.5)
19
+ return 1.0;
20
+ if (ratio < 0.2)
21
+ return 0.5;
22
+ if (ratio > 3.0)
23
+ return 0.3;
24
+ if (ratio < 0.5)
25
+ return 0.5 + ((ratio - 0.2) / (0.5 - 0.2)) * 0.5;
26
+ // ratio 1.5–3.0
27
+ return 1.0 - ((ratio - 1.5) / (3.0 - 1.5)) * 0.7;
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ export function measureFileSurvival(outcome, cwd) {
34
+ try {
35
+ const files = Array.isArray(outcome.filesChanged)
36
+ ? outcome.filesChanged
37
+ : [];
38
+ if (files.length === 0)
39
+ return 1.0;
40
+ let changed;
41
+ try {
42
+ changed = new Set(execSync('git diff --name-only', { cwd, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] })
43
+ .split('\n')
44
+ .map(f => f.trim())
45
+ .filter(Boolean));
46
+ }
47
+ catch {
48
+ changed = new Set();
49
+ }
50
+ const survived = files.filter(f => {
51
+ const abs = join(cwd, f);
52
+ return existsSync(abs) && !changed.has(f);
53
+ });
54
+ return survived.length / files.length;
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ export function scoreOutcome(outcome, context = {}) {
61
+ try {
62
+ const tier = (outcome.tier ?? 'execute');
63
+ const signals = [];
64
+ // Signal 1: exit success (weight 0.3)
65
+ let exitVal;
66
+ if (outcome.success === true)
67
+ exitVal = 1.0;
68
+ else if (outcome.status === 'partial')
69
+ exitVal = 0.4;
70
+ else
71
+ exitVal = 0.0;
72
+ signals.push({ name: 'exitSuccess', value: exitVal, weight: 0.3 });
73
+ // Signal 2: duration ratio (weight 0.25)
74
+ const durationMs = outcome.durationMs ?? 0;
75
+ const durVal = durationMs > 0 ? scoreDurationRatio(durationMs, tier) : null;
76
+ signals.push({ name: 'durationRatio', value: durVal, weight: 0.25 });
77
+ // Signal 3: token efficiency (weight 0.25)
78
+ let effVal = null;
79
+ const filesChanged = outcome.filesChanged ?? 0;
80
+ const fileCount = Array.isArray(filesChanged) ? filesChanged.length : (typeof filesChanged === 'number' ? filesChanged : 0);
81
+ if (!(fileCount === 0 && tier === 'think')) {
82
+ const tokensUsed = outcome.tokensUsed?.output ??
83
+ (durationMs > 0 ? Math.round(durationMs / 100) : null);
84
+ if (tokensUsed !== null && tokensUsed !== undefined) {
85
+ const efficiency = fileCount / Math.max(1, tokensUsed / 1000);
86
+ if (efficiency > 2)
87
+ effVal = 1.0;
88
+ else if (efficiency >= 0.5)
89
+ effVal = 0.5 + ((efficiency - 0.5) / 1.5) * 0.5;
90
+ else if (efficiency < 0.1)
91
+ effVal = 0.2;
92
+ else
93
+ effVal = 0.2 + ((efficiency - 0.1) / 0.4) * 0.3;
94
+ }
95
+ }
96
+ signals.push({ name: 'tokenEfficiency', value: effVal, weight: 0.25 });
97
+ // Signal 4: file survival (weight 0.2) — delayed, may be null
98
+ const survivalVal = context.fileSurvival ?? null;
99
+ signals.push({ name: 'fileSurvival', value: survivalVal, weight: 0.2 });
100
+ // Compound score with weight redistribution
101
+ const active = signals.filter(s => s.value !== null);
102
+ const totalWeight = active.reduce((sum, s) => sum + s.weight, 0);
103
+ const reward = totalWeight > 0
104
+ ? active.reduce((sum, s) => sum + (s.value * s.weight / totalWeight), 0)
105
+ : 0;
106
+ const confidence = totalWeight;
107
+ return {
108
+ reward: Math.min(1, Math.max(0, reward)),
109
+ confidence: Math.min(1, confidence),
110
+ signals: {
111
+ exitSuccess: exitVal,
112
+ durationRatio: durVal,
113
+ tokenEfficiency: effVal,
114
+ fileSurvival: survivalVal,
115
+ },
116
+ };
117
+ }
118
+ catch {
119
+ return { reward: 0, confidence: 0, signals: { exitSuccess: false, durationRatio: null, tokenEfficiency: null, fileSurvival: null } };
120
+ }
121
+ }
122
+ //# sourceMappingURL=signal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal.js","sourceRoot":"","sources":["../../src/signal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ interface SimmerItem {
2
+ id: string;
3
+ idea: string;
4
+ origin: string;
5
+ heat: number;
6
+ createdAt: number;
7
+ lastHeated: number;
8
+ signals: string[];
9
+ crystallized: boolean;
10
+ crystallizedAs: string | null;
11
+ }
12
+ /**
13
+ * @typedef {object} SimmerItem
14
+ * @property {string} id
15
+ * @property {string} idea - The raw idea in prose
16
+ * @property {string} origin - Where it came from (user quote, observation, debrief finding)
17
+ * @property {number} heat - Current heat score
18
+ * @property {number} createdAt
19
+ * @property {number} lastHeated - Last time heat was added
20
+ * @property {string[]} signals - Evidence trail (why heat was added)
21
+ * @property {boolean} crystallized - Whether it's crossed the threshold
22
+ * @property {string|null} crystallizedAs - What it became (task description, architecture decision, etc)
23
+ */
24
+ /**
25
+ * Add a new idea to the simmer buffer.
26
+ * If a similar idea already exists (fuzzy match), heat it instead of duplicating.
27
+ *
28
+ * @param {string} idea - The idea in natural language
29
+ * @param {object} opts
30
+ * @param {string} opts.origin - Where this came from
31
+ * @param {number} opts.initialHeat - Starting heat (default 1)
32
+ * @returns {SimmerItem} The created or heated item
33
+ */
34
+ export declare function add(idea: string, { origin, initialHeat }?: {
35
+ origin?: string;
36
+ initialHeat?: number;
37
+ }): SimmerItem;
38
+ /**
39
+ * Add heat to an existing item. If it crosses the threshold, mark as crystallized.
40
+ *
41
+ * @param {string} id
42
+ * @param {number} amount - Heat to add (default 1)
43
+ * @param {string} signal - Why heat is being added
44
+ * @returns {SimmerItem|null}
45
+ */
46
+ export declare function heat(id: string, amount?: number, signal?: string): SimmerItem | null;
47
+ /**
48
+ * Get all items that have crystallized but haven't been surfaced yet.
49
+ * These should be presented to HEAD during deliberation.
50
+ *
51
+ * @returns {SimmerItem[]}
52
+ */
53
+ export declare function harvest(): SimmerItem[];
54
+ /**
55
+ * Mark a crystallized item as actioned — record what it became.
56
+ *
57
+ * @param {string} id
58
+ * @param {string} became - Description of what action was taken
59
+ */
60
+ export declare function resolve(id: string, became: string): void;
61
+ /**
62
+ * Get all active (non-resolved) simmering items, sorted by heat descending.
63
+ * Used by the narrative to include "what's brewing" context.
64
+ *
65
+ * @returns {SimmerItem[]}
66
+ */
67
+ export declare function active(): SimmerItem[];
68
+ /**
69
+ * Check if an idea already exists in the buffer (for deduplication).
70
+ * @param {string} idea
71
+ * @returns {SimmerItem|null}
72
+ */
73
+ export declare function find(idea: string): SimmerItem | null;
74
+ /**
75
+ * Generate a brief for HEAD showing what's simmering.
76
+ * Included in the narrative context so HEAD is aware of brewing ideas.
77
+ *
78
+ * @returns {string} Prose summary of active simmer items, or empty string
79
+ */
80
+ export declare function brief(): string;
81
+ /**
82
+ * Prune resolved and cold-dead items.
83
+ */
84
+ export declare function prune(): void;
85
+ export {};