@codemoot/cli 0.2.10 → 0.2.12
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/LICENSE +21 -0
- package/dist/index.js +120 -35
- package/dist/index.js.map +1 -1
- package/dist/prompts-GB7HH4EL.js +0 -0
- package/package.json +27 -11
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CodeMoot Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.js
CHANGED
|
@@ -538,6 +538,7 @@ import {
|
|
|
538
538
|
preflightTokenCheck
|
|
539
539
|
} from "@codemoot/core";
|
|
540
540
|
import chalk4 from "chalk";
|
|
541
|
+
import { writeFileSync } from "fs";
|
|
541
542
|
async function debateStartCommand(topic, options) {
|
|
542
543
|
let db;
|
|
543
544
|
try {
|
|
@@ -560,7 +561,8 @@ async function debateStartCommand(topic, options) {
|
|
|
560
561
|
status: "running",
|
|
561
562
|
sessionIds: {},
|
|
562
563
|
resumeStats: { attempted: 0, succeeded: 0, fallbacks: 0 },
|
|
563
|
-
maxRounds: options.maxRounds ?? 5
|
|
564
|
+
maxRounds: options.maxRounds ?? 5,
|
|
565
|
+
defaultTimeout: options.timeout
|
|
564
566
|
});
|
|
565
567
|
const output = {
|
|
566
568
|
debateId,
|
|
@@ -605,9 +607,10 @@ async function debateTurnCommand(debateId, prompt, options) {
|
|
|
605
607
|
}
|
|
606
608
|
const rawRound = options.round ?? criticRow.round + 1;
|
|
607
609
|
const newRound = Number.isFinite(rawRound) && rawRound > 0 ? rawRound : criticRow.round + 1;
|
|
608
|
-
const rawTimeout = options.timeout ?? 600;
|
|
609
|
-
const timeout = (Number.isFinite(rawTimeout) && rawTimeout > 0 ? rawTimeout : 600) * 1e3;
|
|
610
610
|
const proposerStateForLimit = store.loadState(debateId, "proposer");
|
|
611
|
+
const storedTimeout = proposerStateForLimit?.defaultTimeout;
|
|
612
|
+
const rawTimeout = options.timeout ?? storedTimeout ?? 600;
|
|
613
|
+
const timeout = (Number.isFinite(rawTimeout) && rawTimeout > 0 ? rawTimeout : 600) * 1e3;
|
|
611
614
|
const rawMax = proposerStateForLimit?.maxRounds ?? 5;
|
|
612
615
|
const maxRounds = Number.isFinite(rawMax) && rawMax > 0 ? rawMax : 5;
|
|
613
616
|
if (newRound > maxRounds) {
|
|
@@ -626,10 +629,16 @@ async function debateTurnCommand(debateId, prompt, options) {
|
|
|
626
629
|
status: "active"
|
|
627
630
|
});
|
|
628
631
|
}
|
|
632
|
+
if (options.output && existing.responseText) {
|
|
633
|
+
writeFileSync(options.output, existing.responseText, "utf-8");
|
|
634
|
+
console.error(chalk4.dim(`Full response written to ${options.output}`));
|
|
635
|
+
}
|
|
629
636
|
const output = {
|
|
630
637
|
debateId,
|
|
631
638
|
round: newRound,
|
|
632
639
|
response: existing.responseText?.slice(0, 2e3) ?? "",
|
|
640
|
+
responseTruncated: (existing.responseText?.length ?? 0) > 2e3,
|
|
641
|
+
responseFile: options.output ?? void 0,
|
|
633
642
|
sessionId: existing.sessionId,
|
|
634
643
|
resumed: false,
|
|
635
644
|
cached: true,
|
|
@@ -671,10 +680,16 @@ async function debateTurnCommand(debateId, prompt, options) {
|
|
|
671
680
|
if (!msgStore.markRunning(msgId)) {
|
|
672
681
|
const recheckRow = msgStore.getByRound(debateId, newRound, "critic");
|
|
673
682
|
if (recheckRow?.status === "completed") {
|
|
683
|
+
if (options.output && recheckRow.responseText) {
|
|
684
|
+
writeFileSync(options.output, recheckRow.responseText, "utf-8");
|
|
685
|
+
console.error(chalk4.dim(`Full response written to ${options.output}`));
|
|
686
|
+
}
|
|
674
687
|
const output = {
|
|
675
688
|
debateId,
|
|
676
689
|
round: newRound,
|
|
677
690
|
response: recheckRow.responseText?.slice(0, 2e3) ?? "",
|
|
691
|
+
responseTruncated: (recheckRow.responseText?.length ?? 0) > 2e3,
|
|
692
|
+
responseFile: options.output ?? void 0,
|
|
678
693
|
sessionId: recheckRow.sessionId,
|
|
679
694
|
resumed: false,
|
|
680
695
|
cached: true,
|
|
@@ -702,14 +717,20 @@ async function debateTurnCommand(debateId, prompt, options) {
|
|
|
702
717
|
const completedHistory = msgStore.getHistory(debateId).filter((m) => m.status === "completed");
|
|
703
718
|
const maxContext = adapter.capabilities.maxContextTokens;
|
|
704
719
|
const preflight = preflightTokenCheck(completedHistory, prompt, maxContext);
|
|
705
|
-
if (preflight.shouldStop) {
|
|
706
|
-
console.error(chalk4.
|
|
720
|
+
if (preflight.shouldStop && !options.force) {
|
|
721
|
+
console.error(chalk4.red(`Token budget at ${Math.round(preflight.utilizationRatio * 100)}% (${preflight.totalTokensUsed}/${maxContext}). Debate blocked \u2014 use --force to override.`));
|
|
722
|
+
db.close();
|
|
723
|
+
process.exit(1);
|
|
724
|
+
} else if (preflight.shouldStop && options.force) {
|
|
725
|
+
console.error(chalk4.yellow(` Token budget at ${Math.round(preflight.utilizationRatio * 100)}% (${preflight.totalTokensUsed}/${maxContext}) \u2014 forced past budget limit.`));
|
|
707
726
|
} else if (preflight.shouldSummarize) {
|
|
708
727
|
console.error(chalk4.yellow(` Token budget at ${Math.round(preflight.utilizationRatio * 100)}%. Older rounds will be summarized on resume failure.`));
|
|
709
728
|
}
|
|
710
729
|
const overflowCheck = sessionMgr.preCallOverflowCheck(unifiedSession.id);
|
|
711
730
|
if (overflowCheck.rolled) {
|
|
712
731
|
console.error(chalk4.yellow(` ${overflowCheck.message}`));
|
|
732
|
+
console.error(chalk4.yellow(" Warning: Session rolled over \u2014 previous conversation context has been lost."));
|
|
733
|
+
sessionMgr.updateThreadId(unifiedSession.id, null);
|
|
713
734
|
existingSessionId = void 0;
|
|
714
735
|
}
|
|
715
736
|
try {
|
|
@@ -781,11 +802,16 @@ async function debateTurnCommand(debateId, prompt, options) {
|
|
|
781
802
|
proposerState.resumeStats = stats;
|
|
782
803
|
store.saveState(debateId, "proposer", proposerState);
|
|
783
804
|
}
|
|
805
|
+
if (options.output) {
|
|
806
|
+
writeFileSync(options.output, result.text, "utf-8");
|
|
807
|
+
console.error(chalk4.dim(`Full response written to ${options.output}`));
|
|
808
|
+
}
|
|
784
809
|
const output = {
|
|
785
810
|
debateId,
|
|
786
811
|
round: newRound,
|
|
787
812
|
response: result.text.slice(0, 2e3),
|
|
788
813
|
responseTruncated: result.text.length > 2e3,
|
|
814
|
+
responseFile: options.output ?? void 0,
|
|
789
815
|
sessionId: result.sessionId,
|
|
790
816
|
resumed,
|
|
791
817
|
cached: false,
|
|
@@ -800,7 +826,7 @@ Round ${newRound} \u2014 Stance: ${verdict.stance}`));
|
|
|
800
826
|
for (const line of previewLines) {
|
|
801
827
|
console.error(chalk4.dim(` ${line.trim().slice(0, 120)}`));
|
|
802
828
|
}
|
|
803
|
-
console.error(chalk4.dim(`Duration: ${(result.durationMs / 1e3).toFixed(1)}s |
|
|
829
|
+
console.error(chalk4.dim(`Duration: ${(result.durationMs / 1e3).toFixed(1)}s | Output: ${result.usage?.outputTokens ?? "?"} tokens | Input: ${result.usage?.inputTokens ?? "?"} (includes sandbox) | Resumed: ${resumed}`));
|
|
804
830
|
console.log(JSON.stringify(output, null, 2));
|
|
805
831
|
} catch (error) {
|
|
806
832
|
msgStore.markFailed(msgId, error instanceof Error ? error.message : String(error));
|
|
@@ -813,6 +839,10 @@ Round ${newRound} \u2014 Stance: ${verdict.stance}`));
|
|
|
813
839
|
process.exit(1);
|
|
814
840
|
}
|
|
815
841
|
}
|
|
842
|
+
async function debateNextCommand(debateId, options) {
|
|
843
|
+
const prompt = "Continue your analysis. Respond to the previous round's arguments and refine your position.";
|
|
844
|
+
return debateTurnCommand(debateId, prompt, options);
|
|
845
|
+
}
|
|
816
846
|
async function debateStatusCommand(debateId) {
|
|
817
847
|
let db;
|
|
818
848
|
try {
|
|
@@ -893,7 +923,7 @@ async function debateListCommand(options) {
|
|
|
893
923
|
process.exit(1);
|
|
894
924
|
}
|
|
895
925
|
}
|
|
896
|
-
async function debateHistoryCommand(debateId) {
|
|
926
|
+
async function debateHistoryCommand(debateId, options = {}) {
|
|
897
927
|
let db;
|
|
898
928
|
try {
|
|
899
929
|
const dbPath = getDbPath();
|
|
@@ -937,6 +967,29 @@ async function debateHistoryCommand(debateId) {
|
|
|
937
967
|
completedAt: m.completedAt ? new Date(m.completedAt).toISOString() : null
|
|
938
968
|
}))
|
|
939
969
|
};
|
|
970
|
+
if (options.output) {
|
|
971
|
+
const fullOutput = {
|
|
972
|
+
...output,
|
|
973
|
+
messages: history.map((m) => ({
|
|
974
|
+
round: m.round,
|
|
975
|
+
role: m.role,
|
|
976
|
+
bridge: m.bridge,
|
|
977
|
+
model: m.model,
|
|
978
|
+
status: m.status,
|
|
979
|
+
stance: m.stance,
|
|
980
|
+
confidence: m.confidence,
|
|
981
|
+
durationMs: m.durationMs,
|
|
982
|
+
sessionId: m.sessionId,
|
|
983
|
+
promptText: m.promptText,
|
|
984
|
+
responseText: m.responseText ?? null,
|
|
985
|
+
error: m.error,
|
|
986
|
+
createdAt: new Date(m.createdAt).toISOString(),
|
|
987
|
+
completedAt: m.completedAt ? new Date(m.completedAt).toISOString() : null
|
|
988
|
+
}))
|
|
989
|
+
};
|
|
990
|
+
writeFileSync(options.output, JSON.stringify(fullOutput, null, 2), "utf-8");
|
|
991
|
+
console.error(chalk4.dim(`Full history written to ${options.output}`));
|
|
992
|
+
}
|
|
940
993
|
console.log(JSON.stringify(output, null, 2));
|
|
941
994
|
db.close();
|
|
942
995
|
} catch (error) {
|
|
@@ -1199,8 +1252,8 @@ Scan complete in ${(durationMs / 1e3).toFixed(1)}s`));
|
|
|
1199
1252
|
durationMs
|
|
1200
1253
|
});
|
|
1201
1254
|
if (options.output) {
|
|
1202
|
-
const { writeFileSync:
|
|
1203
|
-
|
|
1255
|
+
const { writeFileSync: writeFileSync5 } = await import("fs");
|
|
1256
|
+
writeFileSync5(options.output, JSON.stringify(report, null, 2), "utf-8");
|
|
1204
1257
|
console.error(chalk5.green(` Findings written to ${options.output}`));
|
|
1205
1258
|
}
|
|
1206
1259
|
const reportJson = JSON.stringify(report, null, 2);
|
|
@@ -1618,7 +1671,7 @@ async function eventsCommand(options) {
|
|
|
1618
1671
|
|
|
1619
1672
|
// src/commands/fix.ts
|
|
1620
1673
|
import { execFileSync as execFileSync2, execSync as execSync3 } from "child_process";
|
|
1621
|
-
import { readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
1674
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
1622
1675
|
import { resolve } from "path";
|
|
1623
1676
|
import {
|
|
1624
1677
|
DEFAULT_RULES,
|
|
@@ -1666,7 +1719,7 @@ function applyFix(fix, projectDir) {
|
|
|
1666
1719
|
const trimmedOld = fix.oldCode.trim();
|
|
1667
1720
|
if (content.includes(trimmedOld)) {
|
|
1668
1721
|
const updated = content.replace(trimmedOld, fix.newCode.trim());
|
|
1669
|
-
|
|
1722
|
+
writeFileSync2(filePath, updated, "utf-8");
|
|
1670
1723
|
return true;
|
|
1671
1724
|
}
|
|
1672
1725
|
return false;
|
|
@@ -1676,7 +1729,7 @@ function applyFix(fix, projectDir) {
|
|
|
1676
1729
|
const newLines = fix.newCode.trim().split("\n");
|
|
1677
1730
|
const oldLineCount = Math.max(1, newLines.length);
|
|
1678
1731
|
lines.splice(lineIdx, oldLineCount, ...newLines);
|
|
1679
|
-
|
|
1732
|
+
writeFileSync2(filePath, lines.join("\n"), "utf-8");
|
|
1680
1733
|
return true;
|
|
1681
1734
|
}
|
|
1682
1735
|
async function fixCommand(fileOrGlob, options) {
|
|
@@ -1777,11 +1830,26 @@ ${fixOutputContract}`,
|
|
|
1777
1830
|
const timeoutMs = options.timeout * 1e3;
|
|
1778
1831
|
const progress = createProgressCallbacks("fix-review");
|
|
1779
1832
|
console.error(chalk9.dim(" GPT reviewing..."));
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1833
|
+
let reviewResult;
|
|
1834
|
+
try {
|
|
1835
|
+
reviewResult = await adapter.callWithResume(reviewPrompt, {
|
|
1836
|
+
sessionId: threadId,
|
|
1837
|
+
timeout: timeoutMs,
|
|
1838
|
+
...progress
|
|
1839
|
+
});
|
|
1840
|
+
} catch (err) {
|
|
1841
|
+
if (threadId) {
|
|
1842
|
+
console.error(chalk9.yellow(" Clearing stale codex thread ID after failure."));
|
|
1843
|
+
sessionMgr.updateThreadId(session2.id, null);
|
|
1844
|
+
threadId = void 0;
|
|
1845
|
+
}
|
|
1846
|
+
throw err;
|
|
1847
|
+
}
|
|
1848
|
+
const resumed = threadId && reviewResult.sessionId === threadId;
|
|
1849
|
+
if (threadId && !resumed) {
|
|
1850
|
+
threadId = void 0;
|
|
1851
|
+
sessionMgr.updateThreadId(session2.id, null);
|
|
1852
|
+
}
|
|
1785
1853
|
if (reviewResult.sessionId) {
|
|
1786
1854
|
threadId = reviewResult.sessionId;
|
|
1787
1855
|
sessionMgr.updateThreadId(session2.id, reviewResult.sessionId);
|
|
@@ -1999,7 +2067,7 @@ Initialized with '${presetName}' preset`));
|
|
|
1999
2067
|
}
|
|
2000
2068
|
|
|
2001
2069
|
// src/commands/install-skills.ts
|
|
2002
|
-
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as
|
|
2070
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
2003
2071
|
import { dirname, join as join5 } from "path";
|
|
2004
2072
|
import chalk11 from "chalk";
|
|
2005
2073
|
var SKILLS = [
|
|
@@ -2449,7 +2517,7 @@ async function installSkillsCommand(options) {
|
|
|
2449
2517
|
continue;
|
|
2450
2518
|
}
|
|
2451
2519
|
mkdirSync2(dir, { recursive: true });
|
|
2452
|
-
|
|
2520
|
+
writeFileSync3(fullPath, skill.content, "utf-8");
|
|
2453
2521
|
console.error(chalk11.green(` OK ${skill.path}`));
|
|
2454
2522
|
installed++;
|
|
2455
2523
|
}
|
|
@@ -2467,7 +2535,7 @@ async function installSkillsCommand(options) {
|
|
|
2467
2535
|
const afterMarker = sectionEnd >= 0 ? existing.slice(sectionEnd + CLAUDE_MD_SECTION.trimEnd().length) : existing.slice(markerIdx + marker.length);
|
|
2468
2536
|
const nextHeadingMatch = sectionEnd >= 0 ? null : afterMarker.match(/\n#{1,6} (?!CodeMoot)/);
|
|
2469
2537
|
const after = nextHeadingMatch ? afterMarker.slice(nextHeadingMatch.index) : "";
|
|
2470
|
-
|
|
2538
|
+
writeFileSync3(claudeMdPath, before.trimEnd() + "\n" + CLAUDE_MD_SECTION + after, "utf-8");
|
|
2471
2539
|
console.error(chalk11.green(" OK CLAUDE.md (updated CodeMoot section)"));
|
|
2472
2540
|
installed++;
|
|
2473
2541
|
} else {
|
|
@@ -2475,12 +2543,12 @@ async function installSkillsCommand(options) {
|
|
|
2475
2543
|
skipped++;
|
|
2476
2544
|
}
|
|
2477
2545
|
} else {
|
|
2478
|
-
|
|
2546
|
+
writeFileSync3(claudeMdPath, existing.trimEnd() + "\n" + CLAUDE_MD_SECTION, "utf-8");
|
|
2479
2547
|
console.error(chalk11.green(" OK CLAUDE.md (appended CodeMoot section)"));
|
|
2480
2548
|
installed++;
|
|
2481
2549
|
}
|
|
2482
2550
|
} else {
|
|
2483
|
-
|
|
2551
|
+
writeFileSync3(claudeMdPath, `# Project Instructions
|
|
2484
2552
|
${CLAUDE_MD_SECTION}`, "utf-8");
|
|
2485
2553
|
console.error(chalk11.green(" OK CLAUDE.md (created with CodeMoot section)"));
|
|
2486
2554
|
installed++;
|
|
@@ -2502,7 +2570,7 @@ ${CLAUDE_MD_SECTION}`, "utf-8");
|
|
|
2502
2570
|
...existing.hooks,
|
|
2503
2571
|
PostToolUse: [...otherHooks, ...HOOKS_CONFIG.hooks.PostToolUse]
|
|
2504
2572
|
};
|
|
2505
|
-
|
|
2573
|
+
writeFileSync3(settingsPath, JSON.stringify(existing, null, 2), "utf-8");
|
|
2506
2574
|
console.error(chalk11.green(" OK .claude/settings.json (added post-commit hint hook)"));
|
|
2507
2575
|
installed++;
|
|
2508
2576
|
}
|
|
@@ -2513,7 +2581,7 @@ ${CLAUDE_MD_SECTION}`, "utf-8");
|
|
|
2513
2581
|
}
|
|
2514
2582
|
} else {
|
|
2515
2583
|
mkdirSync2(settingsDir, { recursive: true });
|
|
2516
|
-
|
|
2584
|
+
writeFileSync3(settingsPath, JSON.stringify(HOOKS_CONFIG, null, 2), "utf-8");
|
|
2517
2585
|
console.error(chalk11.green(" OK .claude/settings.json (created with post-commit hook)"));
|
|
2518
2586
|
installed++;
|
|
2519
2587
|
}
|
|
@@ -2811,7 +2879,7 @@ async function jobsStatusCommand(jobId) {
|
|
|
2811
2879
|
}
|
|
2812
2880
|
|
|
2813
2881
|
// src/commands/plan.ts
|
|
2814
|
-
import { readFileSync as readFileSync4, writeFileSync as
|
|
2882
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
2815
2883
|
import {
|
|
2816
2884
|
ModelRegistry as ModelRegistry4,
|
|
2817
2885
|
Orchestrator,
|
|
@@ -2928,7 +2996,7 @@ async function planGenerateCommand(task, options) {
|
|
|
2928
2996
|
maxRounds: options.rounds
|
|
2929
2997
|
});
|
|
2930
2998
|
if (options.output) {
|
|
2931
|
-
|
|
2999
|
+
writeFileSync4(options.output, result.finalOutput, "utf-8");
|
|
2932
3000
|
console.error(chalk15.green(`Plan saved to ${options.output}`));
|
|
2933
3001
|
}
|
|
2934
3002
|
printSessionSummary(result);
|
|
@@ -3079,7 +3147,7 @@ Verdict: ${verdict.toUpperCase()} (${score ?? "?"}/10)`));
|
|
|
3079
3147
|
};
|
|
3080
3148
|
console.log(JSON.stringify(output, null, 2));
|
|
3081
3149
|
if (options.output) {
|
|
3082
|
-
|
|
3150
|
+
writeFileSync4(options.output, JSON.stringify(output, null, 2), "utf-8");
|
|
3083
3151
|
console.error(chalk15.green(`Review saved to ${options.output}`));
|
|
3084
3152
|
}
|
|
3085
3153
|
db.close();
|
|
@@ -3297,11 +3365,22 @@ ${fileContents}`,
|
|
|
3297
3365
|
}
|
|
3298
3366
|
const timeoutMs = (options.timeout ?? 600) * 1e3;
|
|
3299
3367
|
const progress = createProgressCallbacks("review");
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3368
|
+
let result;
|
|
3369
|
+
try {
|
|
3370
|
+
result = await adapter.callWithResume(prompt, {
|
|
3371
|
+
sessionId: sessionThreadId,
|
|
3372
|
+
timeout: timeoutMs,
|
|
3373
|
+
...progress
|
|
3374
|
+
});
|
|
3375
|
+
} catch (err) {
|
|
3376
|
+
if (sessionThreadId) {
|
|
3377
|
+
sessionMgr.updateThreadId(session2.id, null);
|
|
3378
|
+
}
|
|
3379
|
+
throw err;
|
|
3380
|
+
}
|
|
3381
|
+
if (sessionThreadId && result.sessionId !== sessionThreadId) {
|
|
3382
|
+
sessionMgr.updateThreadId(session2.id, null);
|
|
3383
|
+
}
|
|
3305
3384
|
if (result.sessionId) {
|
|
3306
3385
|
sessionMgr.updateThreadId(session2.id, result.sessionId);
|
|
3307
3386
|
}
|
|
@@ -3985,11 +4064,17 @@ var plan = program.command("plan").description("Plan generation and review \u201
|
|
|
3985
4064
|
plan.command("generate").description("Generate a plan using architect + reviewer loop").argument("<task>", "Task to plan").option("--rounds <n>", "Max plan-review rounds", (v) => Number.parseInt(v, 10), 3).option("--output <file>", "Save plan to file").action(planGenerateCommand);
|
|
3986
4065
|
plan.command("review").description("Send a host-authored plan to codex for review").argument("<plan-file>", "Plan file to review (use - for stdin)").option("--build <id>", "Link review to a build ID").option("--phase <id>", 'Phase identifier (e.g. "1", "setup")').option("--timeout <seconds>", "Review timeout", (v) => Number.parseInt(v, 10), 300).option("--output <file>", "Save review result to file").action(planReviewCommand);
|
|
3987
4066
|
var debate = program.command("debate").description("Multi-model debate with session persistence");
|
|
3988
|
-
debate.command("start").description("Start a new debate").argument("<topic>", "Debate topic or question").option("--max-rounds <n>", "Max debate rounds", (v) => Number.parseInt(v, 10), 5).
|
|
3989
|
-
|
|
4067
|
+
debate.command("start").description("Start a new debate").argument("<topic>", "Debate topic or question").option("--max-rounds <n>", "Max debate rounds", (v) => Number.parseInt(v, 10), 5).option("--timeout <seconds>", "Default timeout for debate turns in seconds", (v) => {
|
|
4068
|
+
if (!/^\d+$/.test(v)) throw new InvalidArgumentError("Timeout must be a positive integer");
|
|
4069
|
+
const n = Number.parseInt(v, 10);
|
|
4070
|
+
if (n <= 0) throw new InvalidArgumentError("Timeout must be a positive integer");
|
|
4071
|
+
return n;
|
|
4072
|
+
}).action(debateStartCommand);
|
|
4073
|
+
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);
|
|
4074
|
+
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);
|
|
3990
4075
|
debate.command("status").description("Show debate status and session info").argument("<debate-id>", "Debate ID").action(debateStatusCommand);
|
|
3991
4076
|
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);
|
|
3992
|
-
debate.command("history").description("Show full message history with token budget").argument("<debate-id>", "Debate ID").action(debateHistoryCommand);
|
|
4077
|
+
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);
|
|
3993
4078
|
debate.command("complete").description("Mark a debate as completed").argument("<debate-id>", "Debate ID").action(debateCompleteCommand);
|
|
3994
4079
|
var build = program.command("build").description("Automated build loop: debate \u2192 plan \u2192 implement \u2192 review \u2192 fix");
|
|
3995
4080
|
build.command("start").description("Start a new build session").argument("<task>", "Task description").option("--max-rounds <n>", "Max debate rounds", (v) => Number.parseInt(v, 10), 5).option("--allow-dirty", "Allow starting with dirty working tree (auto-stashes)").action(buildStartCommand);
|