dual-brain 3.0.0 → 3.1.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.
@@ -200,6 +200,8 @@ function allOpusCost(records, rateMap, datePrefix = null) {
200
200
  // Formatting helpers
201
201
  // ---------------------------------------------------------------------------
202
202
 
203
+ const W = 50;
204
+
203
205
  const TIER_ORDER = ["search", "execute", "think"];
204
206
 
205
207
  const TIER_LABELS = {
@@ -224,8 +226,6 @@ function renderTable(title, aggregated, allOpus, records = []) {
224
226
  const savings = allOpus - totalCost;
225
227
  const savingsPct = allOpus > 0 ? Math.round((savings / allOpus) * 100) : 0;
226
228
 
227
- const W = 50; // total inner width (between ║ chars)
228
-
229
229
  const line = (s) => `║ ${pad(s, W - 2)} ║`;
230
230
  const border = (l, r, m) => l + "═".repeat(W) + r;
231
231
  const sep = () => "╠" + "═".repeat(W) + "╣";
@@ -14,7 +14,7 @@
14
14
 
15
15
  import { execSync, spawnSync } from 'child_process';
16
16
  import { readFileSync } from 'fs';
17
- import { dirname, resolve } from 'path';
17
+ import { dirname, join, resolve } from 'path';
18
18
  import { fileURLToPath } from 'url';
19
19
 
20
20
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -119,7 +119,7 @@ async function main() {
119
119
 
120
120
  console.log(` ║ Quality gate: ${gateEnabled ? 'enabled' : 'disabled'}`.padEnd(53) + '║');
121
121
  console.log(' ╠══════════════════════════════════════════════════╣');
122
- console.log(' ║ Restart Claude Code to activate the orchestrator ║');
122
+ console.log(' ║ Hooks are active no restart needed ║');
123
123
  console.log(' ╚══════════════════════════════════════════════════╝');
124
124
  console.log('');
125
125
 
@@ -0,0 +1,5 @@
1
+ {"timestamp":"2026-05-14T00:33:17.462Z","type":"tier_recommendation","detected_tier":"search","recommended_model":"haiku","actual_model":"opus","prompt_hash":"9990d6fd8943","followed":false}
2
+ {"timestamp":"2026-05-14T00:33:17.501Z","type":"tier_recommendation","detected_tier":"execute","recommended_model":"sonnet","actual_model":"sonnet","prompt_hash":"c636a5e74cdc","followed":true}
3
+ {"timestamp":"2026-05-14T00:33:17.536Z","type":"tier_recommendation","detected_tier":"think","recommended_model":"opus","actual_model":"haiku","prompt_hash":"bd666c33402c","followed":false}
4
+ {"timestamp":"2026-05-14T00:33:17.606Z","type":"tier_recommendation","detected_tier":"execute","recommended_model":"sonnet","actual_model":"unknown-model-xyz","prompt_hash":"913203af69f8","followed":false}
5
+ {"timestamp":"2026-05-14T00:33:17.746Z","type":"tier_recommendation","detected_tier":"think","recommended_model":"opus","actual_model":"gpt-4.1-mini","prompt_hash":"7196103e6569","followed":false}
package/install.mjs CHANGED
@@ -24,6 +24,11 @@ const force = flag('--force');
24
24
  const dryRun = flag('--dry-run');
25
25
  const jsonOut = flag('--json');
26
26
 
27
+ if (flag('--version') || flag('-v')) {
28
+ console.log(`dual-brain v${VERSION}`);
29
+ process.exit(0);
30
+ }
31
+
27
32
  if (flag('--help') || flag('-h')) {
28
33
  console.log(`
29
34
  dual-brain v${VERSION} — Dual-provider orchestrator for Claude Code
@@ -240,7 +245,20 @@ function generateSettings(workspace) {
240
245
  ],
241
246
  };
242
247
 
243
- return { ...existing, hooks };
248
+ const DUAL_BRAIN_CMDS = [
249
+ 'node .claude/hooks/enforce-tier.mjs',
250
+ 'node .claude/hooks/cost-logger.mjs',
251
+ ];
252
+
253
+ const merged = { ...(existing.hooks || {}) };
254
+ for (const [event, entries] of Object.entries(hooks)) {
255
+ const existingEntries = (merged[event] || []).filter(e =>
256
+ !e.hooks?.some(h => DUAL_BRAIN_CMDS.includes(h.command))
257
+ );
258
+ merged[event] = [...existingEntries, ...entries];
259
+ }
260
+
261
+ return { ...existing, hooks: merged };
244
262
  }
245
263
 
246
264
  function generateClaudeMd(mode) {
@@ -322,7 +340,7 @@ function install(workspace, env, mode) {
322
340
  if (needed.length > 0) {
323
341
  writeFileSync(
324
342
  join(workspace, '.gitignore'),
325
- gi + '\n# Dual-Brain Orchestrator\n' + needed.join('\n') + '\n'
343
+ (gi && !gi.endsWith('\n') ? gi + '\n' : gi) + '\n# Dual-Brain Orchestrator\n' + needed.join('\n') + '\n'
326
344
  );
327
345
  actions.push('✓ .gitignore updated');
328
346
  }
@@ -397,6 +415,29 @@ function printReport(env, mode, actions) {
397
415
  console.log('');
398
416
  for (const l of lines) console.log(` ${l}`);
399
417
  console.log('');
418
+
419
+ if (actions) {
420
+ console.log(' What just happened:');
421
+ console.log(' Every Claude Code session in this project now auto-routes');
422
+ console.log(' agent work by complexity — cheap models for search, mid-tier');
423
+ console.log(' for execution, best models for thinking. Cost is tracked.');
424
+ if (mode.mode === 'dual') {
425
+ console.log(' Both Claude and GPT are available as work providers.');
426
+ }
427
+ console.log('');
428
+ console.log(' Try these in your next Claude Code session:');
429
+ console.log(' node .claude/hooks/health-check.mjs # verify setup');
430
+ console.log(' node .claude/hooks/cost-report.mjs # see activity');
431
+ console.log(' node .claude/hooks/budget-balancer.mjs # provider balance');
432
+ if (mode.openaiEnabled) {
433
+ console.log(' node .claude/hooks/dual-brain-review.mjs # GPT code review');
434
+ }
435
+ console.log('');
436
+ console.log(' Customize:');
437
+ console.log(' .claude/review-rules.md # your project\'s review rules');
438
+ console.log(' .claude/orchestrator.json # routing, budgets, tiers');
439
+ console.log('');
440
+ }
400
441
  }
401
442
 
402
443
  // ─── Main ───────────────────────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dual-brain",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "Dual-provider orchestration for Claude Code — tiered routing, budget balancing, and GPT dual-brain review across Claude + OpenAI subscriptions",
5
5
  "type": "module",
6
6
  "bin": {