@codemoot/cli 0.2.13 → 0.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -424,12 +424,8 @@ async function buildReviewCommand(buildId) {
424
424
  }
425
425
  const sessionMgr = new SessionManager(db);
426
426
  const session2 = sessionMgr.resolveActive("build-review");
427
- const overflowCheck = sessionMgr.preCallOverflowCheck(session2.id);
428
- if (overflowCheck.rolled) {
429
- console.error(chalk3.yellow(` ${overflowCheck.message}`));
430
- }
431
427
  const currentSession = sessionMgr.get(session2.id);
432
- const existingSession = overflowCheck.rolled ? void 0 : currentSession?.codexThreadId ?? run.reviewCodexSession ?? void 0;
428
+ const existingSession = currentSession?.codexThreadId ?? run.reviewCodexSession ?? void 0;
433
429
  const prompt = buildHandoffEnvelope({
434
430
  command: "build-review",
435
431
  task: `Review code changes for the task: "${run.task}"
@@ -486,7 +482,7 @@ Review for:
486
482
  buildStore.updateWithEvent(
487
483
  buildId,
488
484
  {
489
- reviewCodexSession: result.sessionId ?? existingSession,
485
+ reviewCodexSession: result.sessionId ?? void 0,
490
486
  reviewCycles: run.reviewCycles + 1
491
487
  },
492
488
  {
@@ -550,7 +546,8 @@ import {
550
546
  preflightTokenCheck
551
547
  } from "@codemoot/core";
552
548
  import chalk4 from "chalk";
553
- import { writeFileSync } from "fs";
549
+ import { mkdirSync as mkdirSync2, writeFileSync } from "fs";
550
+ import { join as join3 } from "path";
554
551
  async function debateStartCommand(topic, options) {
555
552
  let db;
556
553
  try {
@@ -590,6 +587,40 @@ async function debateStartCommand(topic, options) {
590
587
  process.exit(1);
591
588
  }
592
589
  }
590
+ var DEFAULT_RESPONSE_CAP = 16384;
591
+ var MAX_RESPONSE_CAP = 24576;
592
+ function buildResponseOutput(debateId, round, responseText, cap, explicitOutput) {
593
+ const text = responseText ?? "";
594
+ const byteLen = Buffer.byteLength(text, "utf-8");
595
+ const truncated = byteLen > cap;
596
+ let responseFile;
597
+ if (truncated && !explicitOutput) {
598
+ const dir = join3(process.cwd(), ".codemoot", "debates");
599
+ mkdirSync2(dir, { recursive: true, mode: 448 });
600
+ responseFile = join3(dir, `${debateId}-r${round}.txt`);
601
+ writeFileSync(responseFile, text, { encoding: "utf-8", mode: 384 });
602
+ } else if (explicitOutput && text.length > 0) {
603
+ responseFile = explicitOutput;
604
+ }
605
+ let sliced = text;
606
+ if (truncated) {
607
+ let lo = 0;
608
+ let hi = text.length;
609
+ while (lo < hi) {
610
+ const mid = lo + hi + 1 >>> 1;
611
+ if (Buffer.byteLength(text.slice(0, mid), "utf-8") <= cap) lo = mid;
612
+ else hi = mid - 1;
613
+ }
614
+ sliced = text.slice(0, lo);
615
+ }
616
+ return {
617
+ response: sliced,
618
+ responseTruncated: truncated,
619
+ responseBytes: byteLen,
620
+ responseCap: cap,
621
+ responseFile
622
+ };
623
+ }
593
624
  async function debateTurnCommand(debateId, prompt, options) {
594
625
  let db;
595
626
  try {
@@ -619,6 +650,11 @@ async function debateTurnCommand(debateId, prompt, options) {
619
650
  }
620
651
  const rawRound = options.round ?? criticRow.round + 1;
621
652
  const newRound = Number.isFinite(rawRound) && rawRound > 0 ? rawRound : criticRow.round + 1;
653
+ const responseCap = Math.min(
654
+ options.responseCap && options.responseCap > 0 ? options.responseCap : DEFAULT_RESPONSE_CAP,
655
+ MAX_RESPONSE_CAP
656
+ );
657
+ const quiet = options.quiet ?? false;
622
658
  const proposerStateForLimit = store.loadState(debateId, "proposer");
623
659
  const storedTimeout = proposerStateForLimit?.defaultTimeout;
624
660
  const rawTimeout = options.timeout ?? storedTimeout ?? 600;
@@ -643,14 +679,13 @@ async function debateTurnCommand(debateId, prompt, options) {
643
679
  }
644
680
  if (options.output && existing.responseText) {
645
681
  writeFileSync(options.output, existing.responseText, "utf-8");
646
- console.error(chalk4.dim(`Full response written to ${options.output}`));
682
+ if (!quiet) console.error(chalk4.dim(`Full response written to ${options.output}`));
647
683
  }
684
+ const responseFields = buildResponseOutput(debateId, newRound, existing.responseText, responseCap, options.output);
648
685
  const output = {
649
686
  debateId,
650
687
  round: newRound,
651
- response: existing.responseText?.slice(0, 2e3) ?? "",
652
- responseTruncated: (existing.responseText?.length ?? 0) > 2e3,
653
- responseFile: options.output ?? void 0,
688
+ ...responseFields,
654
689
  sessionId: existing.sessionId,
655
690
  resumed: false,
656
691
  cached: true,
@@ -669,7 +704,7 @@ async function debateTurnCommand(debateId, prompt, options) {
669
704
  }
670
705
  const staleThreshold = timeout + 6e4;
671
706
  const recovered = msgStore.recoverStaleForDebate(debateId, staleThreshold);
672
- if (recovered > 0) {
707
+ if (recovered > 0 && !quiet) {
673
708
  console.error(chalk4.yellow(` Recovered ${recovered} stale message(s) from prior crash.`));
674
709
  }
675
710
  const current = msgStore.getByRound(debateId, newRound, "critic");
@@ -694,14 +729,13 @@ async function debateTurnCommand(debateId, prompt, options) {
694
729
  if (recheckRow?.status === "completed") {
695
730
  if (options.output && recheckRow.responseText) {
696
731
  writeFileSync(options.output, recheckRow.responseText, "utf-8");
697
- console.error(chalk4.dim(`Full response written to ${options.output}`));
732
+ if (!quiet) console.error(chalk4.dim(`Full response written to ${options.output}`));
698
733
  }
734
+ const recheckResponseFields = buildResponseOutput(debateId, newRound, recheckRow.responseText, responseCap, options.output);
699
735
  const output = {
700
736
  debateId,
701
737
  round: newRound,
702
- response: recheckRow.responseText?.slice(0, 2e3) ?? "",
703
- responseTruncated: (recheckRow.responseText?.length ?? 0) > 2e3,
704
- responseFile: options.output ?? void 0,
738
+ ...recheckResponseFields,
705
739
  sessionId: recheckRow.sessionId,
706
740
  resumed: false,
707
741
  cached: true,
@@ -734,28 +768,32 @@ async function debateTurnCommand(debateId, prompt, options) {
734
768
  db.close();
735
769
  process.exit(1);
736
770
  } else if (preflight.shouldStop && options.force) {
737
- console.error(chalk4.yellow(` Token budget at ${Math.round(preflight.utilizationRatio * 100)}% (${preflight.totalTokensUsed}/${maxContext}) \u2014 forced past budget limit.`));
771
+ if (!quiet) console.error(chalk4.yellow(` Token budget at ${Math.round(preflight.utilizationRatio * 100)}% (${preflight.totalTokensUsed}/${maxContext}) \u2014 forced past budget limit.`));
738
772
  } else if (preflight.shouldSummarize) {
739
- console.error(chalk4.yellow(` Token budget at ${Math.round(preflight.utilizationRatio * 100)}%. Older rounds will be summarized on resume failure.`));
740
- }
741
- const overflowCheck = sessionMgr.preCallOverflowCheck(unifiedSession.id);
742
- if (overflowCheck.rolled) {
743
- console.error(chalk4.yellow(` ${overflowCheck.message}`));
744
- console.error(chalk4.yellow(" Warning: Session rolled over \u2014 previous conversation context has been lost."));
745
- sessionMgr.updateThreadId(unifiedSession.id, null);
746
- existingSessionId = void 0;
773
+ if (!quiet) console.error(chalk4.yellow(` Token budget at ${Math.round(preflight.utilizationRatio * 100)}%. Older rounds will be summarized on resume failure.`));
747
774
  }
748
775
  try {
749
776
  const progress = createProgressCallbacks("debate");
750
- let result = await adapter.callWithResume(prompt, {
751
- sessionId: existingSessionId,
752
- timeout,
753
- ...progress
754
- });
777
+ let result;
778
+ try {
779
+ result = await adapter.callWithResume(prompt, {
780
+ sessionId: existingSessionId,
781
+ timeout,
782
+ ...progress
783
+ });
784
+ } catch (err) {
785
+ if (existingSessionId) {
786
+ sessionMgr.updateThreadId(unifiedSession.id, null);
787
+ }
788
+ throw err;
789
+ }
790
+ if (existingSessionId && result.sessionId !== existingSessionId) {
791
+ sessionMgr.updateThreadId(unifiedSession.id, null);
792
+ }
755
793
  const resumed = attemptedResume && result.sessionId === existingSessionId;
756
794
  const resumeFailed = attemptedResume && !resumed;
757
795
  if (resumeFailed && result.text.length < 50) {
758
- console.error(chalk4.yellow(" Resume failed with minimal response. Reconstructing from ledger..."));
796
+ if (!quiet) console.error(chalk4.yellow(" Resume failed with minimal response. Reconstructing from ledger..."));
759
797
  const history = msgStore.getHistory(debateId);
760
798
  const reconstructed = buildReconstructionPrompt(history, prompt);
761
799
  result = await adapter.callWithResume(reconstructed, {
@@ -764,7 +802,7 @@ async function debateTurnCommand(debateId, prompt, options) {
764
802
  });
765
803
  }
766
804
  if (result.text.length < 200 && (result.durationMs ?? 0) > 6e4) {
767
- console.error(chalk4.yellow(` Warning: GPT response is only ${result.text.length} chars after ${Math.round((result.durationMs ?? 0) / 1e3)}s \u2014 possible output truncation (codex may have spent its turn on tool calls).`));
805
+ if (!quiet) console.error(chalk4.yellow(` Warning: GPT response is only ${result.text.length} chars after ${Math.round((result.durationMs ?? 0) / 1e3)}s \u2014 possible output truncation (codex may have spent its turn on tool calls).`));
768
806
  }
769
807
  const verdict = parseDebateVerdict(result.text);
770
808
  const completed = msgStore.markCompleted(msgId, {
@@ -801,7 +839,7 @@ async function debateTurnCommand(debateId, prompt, options) {
801
839
  store.upsert({
802
840
  debateId,
803
841
  role: "critic",
804
- codexSessionId: result.sessionId ?? existingSessionId,
842
+ codexSessionId: result.sessionId ?? void 0,
805
843
  round: newRound,
806
844
  status: "active"
807
845
  });
@@ -816,14 +854,13 @@ async function debateTurnCommand(debateId, prompt, options) {
816
854
  }
817
855
  if (options.output) {
818
856
  writeFileSync(options.output, result.text, "utf-8");
819
- console.error(chalk4.dim(`Full response written to ${options.output}`));
857
+ if (!quiet) console.error(chalk4.dim(`Full response written to ${options.output}`));
820
858
  }
859
+ const freshResponseFields = buildResponseOutput(debateId, newRound, result.text, responseCap, options.output);
821
860
  const output = {
822
861
  debateId,
823
862
  round: newRound,
824
- response: result.text.slice(0, 2e3),
825
- responseTruncated: result.text.length > 2e3,
826
- responseFile: options.output ?? void 0,
863
+ ...freshResponseFields,
827
864
  sessionId: result.sessionId,
828
865
  resumed,
829
866
  cached: false,
@@ -831,14 +868,16 @@ async function debateTurnCommand(debateId, prompt, options) {
831
868
  usage: result.usage,
832
869
  durationMs: result.durationMs
833
870
  };
834
- const stanceColor = verdict.stance === "SUPPORT" ? chalk4.green : verdict.stance === "OPPOSE" ? chalk4.red : chalk4.yellow;
835
- console.error(stanceColor(`
871
+ if (!quiet) {
872
+ const stanceColor = verdict.stance === "SUPPORT" ? chalk4.green : verdict.stance === "OPPOSE" ? chalk4.red : chalk4.yellow;
873
+ console.error(stanceColor(`
836
874
  Round ${newRound} \u2014 Stance: ${verdict.stance}`));
837
- const previewLines = result.text.split("\n").filter((l) => l.trim().length > 10).slice(0, 3);
838
- for (const line of previewLines) {
839
- console.error(chalk4.dim(` ${line.trim().slice(0, 120)}`));
875
+ const previewLines = result.text.split("\n").filter((l) => l.trim().length > 10).slice(0, 3);
876
+ for (const line of previewLines) {
877
+ console.error(chalk4.dim(` ${line.trim().slice(0, 120)}`));
878
+ }
879
+ console.error(chalk4.dim(`Duration: ${(result.durationMs / 1e3).toFixed(1)}s | Output: ${result.usage?.outputTokens ?? "?"} tokens | Input: ${result.usage?.inputTokens ?? "?"} (includes sandbox) | Resumed: ${resumed}`));
840
880
  }
841
- console.error(chalk4.dim(`Duration: ${(result.durationMs / 1e3).toFixed(1)}s | Output: ${result.usage?.outputTokens ?? "?"} tokens | Input: ${result.usage?.inputTokens ?? "?"} (includes sandbox) | Resumed: ${resumed}`));
842
881
  console.log(JSON.stringify(output, null, 2));
843
882
  } catch (error) {
844
883
  msgStore.markFailed(msgId, error instanceof Error ? error.message : String(error));
@@ -1127,10 +1166,6 @@ async function cleanupCommand(path, options) {
1127
1166
  }
1128
1167
  const sessionMgr = new SessionManager3(db);
1129
1168
  const session2 = sessionMgr.resolveActive("cleanup");
1130
- const overflowCheck = sessionMgr.preCallOverflowCheck(session2.id);
1131
- if (overflowCheck.rolled) {
1132
- console.error(chalk5.yellow(` ${overflowCheck.message}`));
1133
- }
1134
1169
  const currentSession = sessionMgr.get(session2.id);
1135
1170
  const sessionThreadId = currentSession?.codexThreadId ?? void 0;
1136
1171
  const [deterministicFindings, semanticFindings] = await Promise.all([
@@ -1511,7 +1546,7 @@ async function costCommand(options) {
1511
1546
  // src/commands/doctor.ts
1512
1547
  import { existsSync, accessSync, constants } from "fs";
1513
1548
  import { execSync as execSync2 } from "child_process";
1514
- import { join as join3 } from "path";
1549
+ import { join as join4 } from "path";
1515
1550
  import chalk7 from "chalk";
1516
1551
  import { VERSION } from "@codemoot/core";
1517
1552
  async function doctorCommand() {
@@ -1531,7 +1566,7 @@ async function doctorCommand() {
1531
1566
  fix: "npm install -g @openai/codex"
1532
1567
  });
1533
1568
  }
1534
- const configPath = join3(cwd, ".cowork.yml");
1569
+ const configPath = join4(cwd, ".cowork.yml");
1535
1570
  if (existsSync(configPath)) {
1536
1571
  checks.push({ name: "config", status: "pass", message: ".cowork.yml found" });
1537
1572
  } else {
@@ -1542,8 +1577,8 @@ async function doctorCommand() {
1542
1577
  fix: "codemoot init"
1543
1578
  });
1544
1579
  }
1545
- const dbDir = join3(cwd, ".cowork", "db");
1546
- const dbPath = join3(dbDir, "cowork.db");
1580
+ const dbDir = join4(cwd, ".cowork", "db");
1581
+ const dbPath = join4(dbDir, "cowork.db");
1547
1582
  if (existsSync(dbDir)) {
1548
1583
  try {
1549
1584
  accessSync(dbDir, constants.W_OK);
@@ -1571,11 +1606,11 @@ async function doctorCommand() {
1571
1606
  let gitFound = false;
1572
1607
  let searchDir = cwd;
1573
1608
  while (searchDir) {
1574
- if (existsSync(join3(searchDir, ".git"))) {
1609
+ if (existsSync(join4(searchDir, ".git"))) {
1575
1610
  gitFound = true;
1576
1611
  break;
1577
1612
  }
1578
- const parent = join3(searchDir, "..");
1613
+ const parent = join4(searchDir, "..");
1579
1614
  if (parent === searchDir) break;
1580
1615
  searchDir = parent;
1581
1616
  }
@@ -1793,11 +1828,6 @@ async function fixCommand(fileOrGlob, options) {
1793
1828
  )
1794
1829
  );
1795
1830
  for (let round = 1; round <= options.maxRounds; round++) {
1796
- const overflowCheck = sessionMgr.preCallOverflowCheck(session2.id);
1797
- if (overflowCheck.rolled) {
1798
- console.error(chalk9.yellow(` ${overflowCheck.message}`));
1799
- threadId = void 0;
1800
- }
1801
1831
  const roundStart = Date.now();
1802
1832
  console.error(chalk9.dim(`
1803
1833
  \u2500\u2500 Round ${round}/${options.maxRounds} \u2500\u2500`));
@@ -2053,12 +2083,12 @@ Result: ${converged ? "CONVERGED" : "NOT CONVERGED"} (${exitReason})`));
2053
2083
 
2054
2084
  // src/commands/init.ts
2055
2085
  import { existsSync as existsSync2 } from "fs";
2056
- import { basename, join as join4 } from "path";
2086
+ import { basename, join as join5 } from "path";
2057
2087
  import { loadConfig as loadConfig5, writeConfig } from "@codemoot/core";
2058
2088
  import chalk10 from "chalk";
2059
2089
  async function initCommand(options) {
2060
2090
  const cwd = process.cwd();
2061
- const configPath = join4(cwd, ".cowork.yml");
2091
+ const configPath = join5(cwd, ".cowork.yml");
2062
2092
  if (existsSync2(configPath) && !options.force) {
2063
2093
  console.error(chalk10.red("Already initialized. Use --force to overwrite."));
2064
2094
  process.exit(1);
@@ -2090,8 +2120,8 @@ Initialized with '${presetName}' preset`));
2090
2120
  }
2091
2121
 
2092
2122
  // src/commands/install-skills.ts
2093
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
2094
- import { dirname, join as join5 } from "path";
2123
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
2124
+ import { dirname, join as join6 } from "path";
2095
2125
  import chalk11 from "chalk";
2096
2126
  var SKILLS = [
2097
2127
  {
@@ -2532,21 +2562,21 @@ async function installSkillsCommand(options) {
2532
2562
  console.error(chalk11.cyan("\n Installing CodeMoot integration for Claude Code\n"));
2533
2563
  console.error(chalk11.dim(" Skills & Agents:"));
2534
2564
  for (const skill of SKILLS) {
2535
- const fullPath = join5(cwd, skill.path);
2565
+ const fullPath = join6(cwd, skill.path);
2536
2566
  const dir = dirname(fullPath);
2537
2567
  if (existsSync3(fullPath) && !options.force) {
2538
2568
  console.error(chalk11.dim(` SKIP ${skill.path} (exists)`));
2539
2569
  skipped++;
2540
2570
  continue;
2541
2571
  }
2542
- mkdirSync2(dir, { recursive: true });
2572
+ mkdirSync3(dir, { recursive: true });
2543
2573
  writeFileSync3(fullPath, skill.content, "utf-8");
2544
2574
  console.error(chalk11.green(` OK ${skill.path}`));
2545
2575
  installed++;
2546
2576
  }
2547
2577
  console.error("");
2548
2578
  console.error(chalk11.dim(" CLAUDE.md:"));
2549
- const claudeMdPath = join5(cwd, "CLAUDE.md");
2579
+ const claudeMdPath = join6(cwd, "CLAUDE.md");
2550
2580
  const marker = "## CodeMoot \u2014 Multi-Model Collaboration";
2551
2581
  if (existsSync3(claudeMdPath)) {
2552
2582
  const existing = readFileSync3(claudeMdPath, "utf-8");
@@ -2578,8 +2608,8 @@ ${CLAUDE_MD_SECTION}`, "utf-8");
2578
2608
  }
2579
2609
  console.error("");
2580
2610
  console.error(chalk11.dim(" Hooks:"));
2581
- const settingsDir = join5(cwd, ".claude");
2582
- const settingsPath = join5(settingsDir, "settings.json");
2611
+ const settingsDir = join6(cwd, ".claude");
2612
+ const settingsPath = join6(settingsDir, "settings.json");
2583
2613
  if (existsSync3(settingsPath)) {
2584
2614
  try {
2585
2615
  const existing = JSON.parse(readFileSync3(settingsPath, "utf-8"));
@@ -2603,7 +2633,7 @@ ${CLAUDE_MD_SECTION}`, "utf-8");
2603
2633
  skipped++;
2604
2634
  }
2605
2635
  } else {
2606
- mkdirSync2(settingsDir, { recursive: true });
2636
+ mkdirSync3(settingsDir, { recursive: true });
2607
2637
  writeFileSync3(settingsPath, JSON.stringify(HOOKS_CONFIG, null, 2), "utf-8");
2608
2638
  console.error(chalk11.green(" OK .claude/settings.json (created with post-commit hook)"));
2609
2639
  installed++;
@@ -2656,18 +2686,12 @@ async function sessionCurrentCommand() {
2656
2686
  return;
2657
2687
  }
2658
2688
  const events = mgr.getEvents(session2.id, 5);
2659
- const overflow = mgr.getOverflowStatus(session2.id);
2660
2689
  console.log(JSON.stringify({
2661
2690
  sessionId: session2.id,
2662
2691
  name: session2.name,
2663
2692
  codexThreadId: session2.codexThreadId,
2664
2693
  status: session2.status,
2665
- tokenBudget: {
2666
- used: overflow.cumulativeTokens,
2667
- lastTurnInput: overflow.lastTurnInputTokens,
2668
- max: overflow.maxContext,
2669
- utilization: `${Math.round(overflow.utilizationRatio * 100)}%`
2670
- },
2694
+ tokenUsage: session2.tokenUsage,
2671
2695
  recentEvents: events.map((e) => ({
2672
2696
  command: e.command,
2673
2697
  subcommand: e.subcommand,
@@ -2707,20 +2731,12 @@ async function sessionStatusCommand(sessionId) {
2707
2731
  process.exit(1);
2708
2732
  }
2709
2733
  const events = mgr.getEvents(sessionId, 20);
2710
- const overflow = mgr.getOverflowStatus(sessionId);
2711
2734
  console.log(JSON.stringify({
2712
2735
  sessionId: session2.id,
2713
2736
  name: session2.name,
2714
2737
  codexThreadId: session2.codexThreadId,
2715
2738
  status: session2.status,
2716
- tokenBudget: {
2717
- used: overflow.cumulativeTokens,
2718
- lastTurnInput: overflow.lastTurnInputTokens,
2719
- max: overflow.maxContext,
2720
- utilization: `${Math.round(overflow.utilizationRatio * 100)}%`,
2721
- shouldWarn: overflow.shouldWarn,
2722
- shouldReconstruct: overflow.shouldReconstruct
2723
- },
2739
+ tokenUsage: session2.tokenUsage,
2724
2740
  eventCount: events.length,
2725
2741
  events: events.map((e) => ({
2726
2742
  command: e.command,
@@ -3060,12 +3076,8 @@ async function planReviewCommand(planFile, options) {
3060
3076
  db = openDatabase9(dbPath);
3061
3077
  const sessionMgr = new SessionManager7(db);
3062
3078
  const session2 = sessionMgr.resolveActive("plan-review");
3063
- const overflowCheck = sessionMgr.preCallOverflowCheck(session2.id);
3064
- if (overflowCheck.rolled) {
3065
- console.error(chalk15.yellow(` ${overflowCheck.message}`));
3066
- }
3067
3079
  const currentSession = sessionMgr.get(session2.id);
3068
- const threadId = overflowCheck.rolled ? void 0 : currentSession?.codexThreadId ?? void 0;
3080
+ const threadId = currentSession?.codexThreadId ?? void 0;
3069
3081
  const phaseContext = options.phase ? `
3070
3082
  This is Phase ${options.phase} of a multi-phase plan.` : "";
3071
3083
  const buildContext = options.build ? `
@@ -3266,10 +3278,6 @@ async function reviewCommand(fileOrGlob, options) {
3266
3278
  db.close();
3267
3279
  process.exit(1);
3268
3280
  }
3269
- const overflowCheck = sessionMgr.preCallOverflowCheck(session2.id);
3270
- if (overflowCheck.rolled) {
3271
- console.error(chalk16.yellow(` ${overflowCheck.message}`));
3272
- }
3273
3281
  const preset = options.preset ? getReviewPreset(options.preset) : void 0;
3274
3282
  if (options.preset && !preset) {
3275
3283
  console.error(chalk16.red(`Unknown preset: ${options.preset}. Use: security-audit, performance, quick-scan, pre-commit, api-review`));
@@ -3635,7 +3643,7 @@ async function shipitCommand(options) {
3635
3643
  // src/commands/start.ts
3636
3644
  import { existsSync as existsSync5 } from "fs";
3637
3645
  import { execFileSync as execFileSync4, execSync as execSync6 } from "child_process";
3638
- import { join as join6, basename as basename2 } from "path";
3646
+ import { join as join7, basename as basename2 } from "path";
3639
3647
  import chalk19 from "chalk";
3640
3648
  import { loadConfig as loadConfig9, writeConfig as writeConfig2 } from "@codemoot/core";
3641
3649
  async function startCommand() {
@@ -3655,7 +3663,7 @@ async function startCommand() {
3655
3663
  }
3656
3664
  console.error(chalk19.green(` Codex CLI ${codexVersion} found.`));
3657
3665
  console.error(chalk19.dim(" [2/4] Checking project config..."));
3658
- const configPath = join6(cwd, ".cowork.yml");
3666
+ const configPath = join7(cwd, ".cowork.yml");
3659
3667
  if (existsSync5(configPath)) {
3660
3668
  console.error(chalk19.green(" .cowork.yml exists \u2014 using it."));
3661
3669
  } else {
@@ -3665,9 +3673,9 @@ async function startCommand() {
3665
3673
  console.error(chalk19.green(" Created .cowork.yml with cli-first preset."));
3666
3674
  }
3667
3675
  console.error(chalk19.dim(" [3/4] Detecting project..."));
3668
- const hasGit = existsSync5(join6(cwd, ".git"));
3669
- const hasSrc = existsSync5(join6(cwd, "src"));
3670
- const hasPackageJson = existsSync5(join6(cwd, "package.json"));
3676
+ const hasGit = existsSync5(join7(cwd, ".git"));
3677
+ const hasSrc = existsSync5(join7(cwd, "src"));
3678
+ const hasPackageJson = existsSync5(join7(cwd, "package.json"));
3671
3679
  let reviewTarget = "";
3672
3680
  if (hasGit) {
3673
3681
  try {
@@ -4105,8 +4113,8 @@ debate.command("start").description("Start a new debate").argument("<topic>", "D
4105
4113
  if (n <= 0) throw new InvalidArgumentError("Timeout must be a positive integer");
4106
4114
  return n;
4107
4115
  }).action(debateStartCommand);
4108
- debate.command("turn").description("Send a prompt to GPT and get critique (with session resume)").argument("<debate-id>", "Debate ID from start command").argument("<prompt>", "Prompt to send to GPT").option("--round <n>", "Round number", (v) => Number.parseInt(v, 10)).option("--timeout <seconds>", "Timeout in seconds", (v) => Number.parseInt(v, 10)).option("--output <file>", "Write full untruncated response to file").option("--force", "Continue past token budget limit", false).action(debateTurnCommand);
4109
- debate.command("next").description("Continue debate with auto-generated prompt").argument("<debate-id>", "Debate ID").option("--timeout <seconds>", "Timeout in seconds", (v) => Number.parseInt(v, 10)).option("--output <file>", "Write full untruncated response to file").option("--force", "Continue past token budget limit", false).action(debateNextCommand);
4116
+ debate.command("turn").description("Send a prompt to GPT and get critique (with session resume)").argument("<debate-id>", "Debate ID from start command").argument("<prompt>", "Prompt to send to GPT").option("--round <n>", "Round number", (v) => Number.parseInt(v, 10)).option("--timeout <seconds>", "Timeout in seconds", (v) => Number.parseInt(v, 10)).option("--output <file>", "Write full untruncated response to file").option("--force", "Continue past token budget limit", false).option("--quiet", "Suppress non-error stderr output", false).option("--response-cap <bytes>", "Max response bytes in JSON output (default: 16384)", (v) => Number.parseInt(v, 10)).action(debateTurnCommand);
4117
+ debate.command("next").description("Continue debate with auto-generated prompt").argument("<debate-id>", "Debate ID").option("--timeout <seconds>", "Timeout in seconds", (v) => Number.parseInt(v, 10)).option("--output <file>", "Write full untruncated response to file").option("--force", "Continue past token budget limit", false).option("--quiet", "Suppress non-error stderr output", false).option("--response-cap <bytes>", "Max response bytes in JSON output (default: 16384)", (v) => Number.parseInt(v, 10)).action(debateNextCommand);
4110
4118
  debate.command("status").description("Show debate status and session info").argument("<debate-id>", "Debate ID").action(debateStatusCommand);
4111
4119
  debate.command("list").description("List all debates").option("--status <status>", "Filter by status (active|completed|stale)").option("--limit <n>", "Max results", (v) => Number.parseInt(v, 10), 20).action(debateListCommand);
4112
4120
  debate.command("history").description("Show full message history with token budget").argument("<debate-id>", "Debate ID").option("--output <file>", "Write full untruncated history to file").action(debateHistoryCommand);