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,222 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const PROVIDER_CAPS = {
4
+ claude: {
5
+ name: 'Claude Code',
6
+ cli: 'claude',
7
+ hasNativeCompaction: true,
8
+ compactionStrategy: 'automatic',
9
+ contextFormat: 'markdown-blocks',
10
+ supportsSpecialists: true,
11
+ supportsSituationBrief: true,
12
+ maxContextTokens: 200_000,
13
+ sessionStorage: 'claude-internal',
14
+ authCheck: 'claude --version',
15
+ resumeSupport: 'receipt + handoff',
16
+ },
17
+ openai: {
18
+ name: 'Codex CLI',
19
+ cli: 'codex',
20
+ hasNativeCompaction: false,
21
+ compactionStrategy: 'none',
22
+ contextFormat: 'plain-text',
23
+ supportsSpecialists: false,
24
+ supportsSituationBrief: true,
25
+ maxContextTokens: 128_000,
26
+ sessionStorage: '~/.codex/sessions/YYYY/MM/DD/*.jsonl',
27
+ authCheck: 'codex --version',
28
+ resumeSupport: 'handoff-only',
29
+ },
30
+ };
31
+ export function getProviderCaps(provider) {
32
+ return PROVIDER_CAPS[provider] || PROVIDER_CAPS.claude;
33
+ }
34
+ // ── Provider-agnostic context injection ─────────────────────────────────────
35
+ /**
36
+ * Build a context block that works for any provider.
37
+ * Adapts format based on provider capabilities.
38
+ */
39
+ export function buildContextBlock(provider, sections) {
40
+ const caps = getProviderCaps(provider);
41
+ const lines = [];
42
+ if (caps.contextFormat === 'markdown-blocks') {
43
+ for (const [label, content] of Object.entries(sections)) {
44
+ if (!content)
45
+ continue;
46
+ lines.push(`[${label.toUpperCase()}]`);
47
+ lines.push(typeof content === 'string' ? content : JSON.stringify(content));
48
+ lines.push(`[/${label.toUpperCase()}]`);
49
+ lines.push('');
50
+ }
51
+ }
52
+ else {
53
+ for (const [label, content] of Object.entries(sections)) {
54
+ if (!content)
55
+ continue;
56
+ lines.push(`--- ${label} ---`);
57
+ lines.push(typeof content === 'string' ? content : JSON.stringify(content));
58
+ lines.push('');
59
+ }
60
+ }
61
+ return lines.join('\n').trim();
62
+ }
63
+ /**
64
+ * Build a compaction survival block tuned for the target provider.
65
+ */
66
+ export function buildSurvivalBlock(provider, state) {
67
+ const caps = getProviderCaps(provider);
68
+ const coreLines = [];
69
+ if (state.activeTask)
70
+ coreLines.push(`TASK: ${state.activeTask}`);
71
+ if (state.provider)
72
+ coreLines.push(`PROVIDER: ${state.provider}/${state.model || 'default'}`);
73
+ if (state.tier)
74
+ coreLines.push(`TIER: ${state.tier}`);
75
+ if (state.risk)
76
+ coreLines.push(`RISK: ${state.risk}`);
77
+ if (state.filesInProgress?.length)
78
+ coreLines.push(`FILES: ${state.filesInProgress.slice(0, 10).join(', ')}`);
79
+ if (state.decisions?.length)
80
+ coreLines.push(`DECISIONS: ${state.decisions.slice(0, 3).join('; ')}`);
81
+ if (state.warnings?.length)
82
+ coreLines.push(`WARNINGS: ${state.warnings.slice(0, 3).join('; ')}`);
83
+ if (state.routingRules?.length)
84
+ coreLines.push(`ROUTING: ${state.routingRules.join('; ')}`);
85
+ if (caps.hasNativeCompaction) {
86
+ return `[DUAL-BRAIN CONTINUITY]\n${coreLines.join('\n')}\n[/DUAL-BRAIN CONTINUITY]`;
87
+ }
88
+ // Codex: compact header block — placed at prompt start for max visibility
89
+ return `## dual-brain state\n${coreLines.join('\n')}\n---`;
90
+ }
91
+ /**
92
+ * Generate a handoff receipt that works for both providers.
93
+ */
94
+ export function generateProviderHandoff(sessionState, provider) {
95
+ const caps = getProviderCaps(provider);
96
+ return {
97
+ version: 2,
98
+ provider,
99
+ providerCaps: caps.name,
100
+ timestamp: new Date().toISOString(),
101
+ task: sessionState.taskDescription || null,
102
+ progress: {
103
+ filesChanged: (sessionState.filesChanged || []).slice(0, 20),
104
+ testsRun: sessionState.testsRun || [],
105
+ decisions: (sessionState.decisions || []).slice(0, 5),
106
+ },
107
+ unresolved: (sessionState.unresolved || []).slice(0, 5),
108
+ routing: {
109
+ lastProvider: provider,
110
+ lastModel: sessionState.routingHistory?.lastModel || null,
111
+ failedProviders: sessionState.routingHistory?.failedProviders || [],
112
+ },
113
+ resumeHint: sessionState.resumeHint || null,
114
+ resumeStrategy: caps.resumeSupport,
115
+ };
116
+ }
117
+ /**
118
+ * Build a resume brief from the latest handoff, adapted for the resuming provider.
119
+ */
120
+ export function buildProviderResumeBrief(cwd, targetProvider) {
121
+ const dir = join(cwd || process.cwd(), '.dualbrain', 'handoffs');
122
+ if (!existsSync(dir))
123
+ return null;
124
+ const files = readdirSync(dir)
125
+ .filter(f => f.startsWith('handoff-') && f.endsWith('.json'))
126
+ .sort()
127
+ .reverse();
128
+ if (files.length === 0)
129
+ return null;
130
+ let handoff;
131
+ try {
132
+ handoff = JSON.parse(readFileSync(join(dir, files[0]), 'utf8'));
133
+ }
134
+ catch {
135
+ return null;
136
+ }
137
+ const age = (Date.now() - Date.parse(handoff.timestamp)) / 3600000;
138
+ if (age > 48)
139
+ return null;
140
+ const caps = getProviderCaps(targetProvider);
141
+ const lines = [];
142
+ const ageLabel = age < 1 ? 'just now' : age < 24 ? `${Math.round(age)}h ago` : `${Math.round(age / 24)}d ago`;
143
+ lines.push(`Resuming from previous session (${ageLabel}, ran on ${handoff.provider || 'unknown'}):`);
144
+ if (handoff.task)
145
+ lines.push(` Task: ${handoff.task}`);
146
+ if (handoff.resumeHint)
147
+ lines.push(` Next: ${handoff.resumeHint}`);
148
+ if (handoff.progress?.filesChanged?.length) {
149
+ const shown = handoff.progress.filesChanged.slice(0, caps.hasNativeCompaction ? 5 : 10);
150
+ lines.push(` Changed: ${shown.join(', ')}`);
151
+ }
152
+ if (handoff.unresolved?.length) {
153
+ lines.push(` Unresolved: ${handoff.unresolved.join('; ')}`);
154
+ }
155
+ // Codex gets extra context since it has no native session memory
156
+ if (!caps.hasNativeCompaction && handoff.progress?.decisions?.length) {
157
+ lines.push(` Prior routing: ${handoff.progress.decisions.map(d => `${d.provider}/${d.model}`).join(', ')}`);
158
+ }
159
+ if (handoff.routing?.failedProviders?.length) {
160
+ lines.push(` Note: ${handoff.routing.failedProviders.join(', ')} failed last session`);
161
+ }
162
+ return lines.join('\n');
163
+ }
164
+ // ── Specialist/plugin injection (provider-aware) ────────────────────────────
165
+ /**
166
+ * Build a capability hint block for the target provider.
167
+ */
168
+ export function buildCapabilityHint(provider, prompt, cwd) {
169
+ if (provider === 'claude') {
170
+ return null; // Handled by dispatch.mjs specialist injection
171
+ }
172
+ // Codex: try to match plugins
173
+ try {
174
+ // Dynamic require for optional dependency
175
+ const { matchPluginsForTask } = require('./replit.mjs');
176
+ const matched = matchPluginsForTask(prompt, undefined, cwd);
177
+ if (matched.length > 0) {
178
+ const names = matched.slice(0, 3).map(m => m.plugin.id).join(', ');
179
+ return `[Available Codex plugins: ${names}. Consider using matching plugins for direct API access.]`;
180
+ }
181
+ }
182
+ catch { /* non-fatal */ }
183
+ return null;
184
+ }
185
+ /**
186
+ * Estimate remaining context budget for a provider.
187
+ */
188
+ export function estimateContextBudget(provider, usedTokens) {
189
+ const caps = getProviderCaps(provider);
190
+ const remaining = caps.maxContextTokens - usedTokens;
191
+ return {
192
+ provider,
193
+ maxTokens: caps.maxContextTokens,
194
+ usedTokens,
195
+ remainingTokens: Math.max(0, remaining),
196
+ utilizationPct: Math.round((usedTokens / caps.maxContextTokens) * 100),
197
+ compactionRisk: remaining < 20_000 ? 'critical' : remaining < 50_000 ? 'high' : remaining < 100_000 ? 'medium' : 'low',
198
+ hasNativeCompaction: caps.hasNativeCompaction,
199
+ action: caps.hasNativeCompaction
200
+ ? (remaining < 20_000 ? 'survival-kit-injected' : 'none')
201
+ : (remaining < 30_000 ? 'manual-handoff-recommended' : 'none'),
202
+ };
203
+ }
204
+ // ── Cross-provider compatibility helpers ────────────────────────────────────
205
+ /**
206
+ * Get the opposite provider for cross-review.
207
+ */
208
+ export function getReviewProvider(workProvider, availableProviders) {
209
+ const opposite = workProvider === 'claude' ? 'openai' : 'claude';
210
+ if (availableProviders?.includes(opposite))
211
+ return opposite;
212
+ return workProvider;
213
+ }
214
+ /**
215
+ * Check if both providers are available for true dual-brain operation.
216
+ */
217
+ export function isDualProviderAvailable(profile) {
218
+ const claude = profile?.providers?.claude?.enabled !== false;
219
+ const openai = !!(profile?.providers?.openai?.enabled && profile?.providers?.openai?.plan);
220
+ return { claude, openai, dual: claude && openai };
221
+ }
222
+ //# sourceMappingURL=provider-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-context.js","sourceRoot":"","sources":["../../src/provider-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * provider-manager.ts — Provider health, failover, and rate-limit management
3
+ *
4
+ * The "invisible failover" layer: when Claude is rate-limited, work seamlessly
5
+ * continues on GPT. When GPT is down, Claude handles everything.
6
+ *
7
+ * State storage:
8
+ * - Provider states: .dual-brain/providers/{provider}.json (atomic writes)
9
+ * - Global dispatch log: .dual-brain/dispatch-log.ndjson (append-only)
10
+ */
11
+ /** Maximum dispatches allowed per rolling window (default: 30 per 5 min). */
12
+ export declare const MAX_DISPATCHES_PER_WINDOW = 30;
13
+ /** Default rolling window in minutes. */
14
+ export declare const DEFAULT_WINDOW_MINUTES = 5;
15
+ export interface ProviderState {
16
+ provider: 'anthropic' | 'openai';
17
+ status: 'healthy' | 'degraded' | 'rate-limited' | 'down';
18
+ lastCheck: string;
19
+ lastSuccess: string;
20
+ lastFailure?: string;
21
+ cooldownUntil?: string;
22
+ remainingCapacity: number;
23
+ recentDispatches: number;
24
+ consecutiveFailures: number;
25
+ }
26
+ export interface FailoverResult {
27
+ provider: string;
28
+ model: string;
29
+ reason: string;
30
+ wasFailover: boolean;
31
+ }
32
+ export interface DispatchPermission {
33
+ allowed: boolean;
34
+ reason: string;
35
+ suggestedDelay?: number;
36
+ alternativeProvider?: string;
37
+ }
38
+ /**
39
+ * Get the current health state for a provider.
40
+ */
41
+ export declare function getProviderState(provider: string, cwd?: string): ProviderState;
42
+ /**
43
+ * Get health states for all known providers.
44
+ */
45
+ export declare function getAllProviderStates(cwd?: string): ProviderState[];
46
+ /**
47
+ * Record a successful dispatch to a provider.
48
+ */
49
+ export declare function recordSuccess(provider: string, model: string, cwd?: string): void;
50
+ /**
51
+ * Record a dispatch failure. Detects rate limits automatically.
52
+ */
53
+ export declare function recordFailure(provider: string, model: string, error: string, cwd?: string): void;
54
+ /**
55
+ * Explicitly record a rate limit event.
56
+ */
57
+ export declare function recordRateLimit(provider: string, resetTime?: string, cwd?: string): void;
58
+ /**
59
+ * Check whether dispatching to a provider is allowed right now.
60
+ */
61
+ export declare function canDispatch(provider: string, cwd?: string): DispatchPermission;
62
+ /**
63
+ * If the preferred provider cannot handle work right now, find the best alternative.
64
+ */
65
+ export declare function getFailoverTarget(preferredProvider: string, preferredModel: string, cwd?: string): FailoverResult;
66
+ /**
67
+ * Choose the best provider right now based on health + task tier.
68
+ */
69
+ export declare function selectProvider(taskTier: number, preferredProvider?: string, cwd?: string): FailoverResult;
70
+ /**
71
+ * Get the total number of dispatches across all providers in the given window.
72
+ */
73
+ export declare function getGlobalDispatchCount(windowMinutes?: number, cwd?: string): number;
74
+ /**
75
+ * Append a dispatch attempt to the global log (file-based, shared across processes).
76
+ */
77
+ export declare function recordDispatchAttempt(provider: string, model: string, taskId: string, cwd?: string): void;
78
+ /**
79
+ * Check whether dispatch rate is within budget.
80
+ */
81
+ export declare function isWithinBudget(maxPerWindow?: number, windowMinutes?: number, cwd?: string): boolean;
82
+ /**
83
+ * Parse an error message for rate limit signals.
84
+ */
85
+ export declare function detectRateLimit(error: string): {
86
+ isRateLimit: boolean;
87
+ resetTime?: string;
88
+ };
89
+ /**
90
+ * One-line health status string for TUI display.
91
+ */
92
+ export declare function getHealthSummary(cwd?: string): string;