@corbat-tech/coco 2.31.0 → 2.33.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.
- package/dist/cli/index.js +141 -64
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -50765,6 +50765,118 @@ function parseThinkingArg(arg) {
|
|
|
50765
50765
|
if (!isNaN(n) && n >= 0) return { budget: n };
|
|
50766
50766
|
return null;
|
|
50767
50767
|
}
|
|
50768
|
+
function modeDescription(mode, hasBudget) {
|
|
50769
|
+
if (typeof mode === "object") return `${mode.budget} token budget`;
|
|
50770
|
+
const descs = {
|
|
50771
|
+
off: "No reasoning \u2014 fastest and cheapest",
|
|
50772
|
+
auto: hasBudget ? "Dynamic budget \u2014 provider decides" : "Provider default effort",
|
|
50773
|
+
low: hasBudget ? "~2 048 tokens \u2014 quick reasoning" : "Minimal effort",
|
|
50774
|
+
medium: hasBudget ? "~8 000 tokens \u2014 balanced" : "Balanced effort",
|
|
50775
|
+
high: hasBudget ? "~16 000 tokens \u2014 deep reasoning" : "Maximum effort"
|
|
50776
|
+
};
|
|
50777
|
+
return descs[mode] ?? mode;
|
|
50778
|
+
}
|
|
50779
|
+
async function selectThinkingInteractively(modes, currentMode, hasBudget) {
|
|
50780
|
+
const currentLabel = formatThinkingMode(currentMode);
|
|
50781
|
+
return new Promise((resolve4) => {
|
|
50782
|
+
let selectedIndex = modes.findIndex((m) => formatThinkingMode(m) === currentLabel);
|
|
50783
|
+
if (selectedIndex === -1) selectedIndex = 0;
|
|
50784
|
+
let lastTotalLines = 0;
|
|
50785
|
+
const clearPrevious = () => {
|
|
50786
|
+
if (lastTotalLines === 0) return;
|
|
50787
|
+
process.stdout.write("\x1B[2K\r");
|
|
50788
|
+
for (let i = 0; i < lastTotalLines; i++) {
|
|
50789
|
+
process.stdout.write("\x1B[1A\x1B[2K");
|
|
50790
|
+
}
|
|
50791
|
+
process.stdout.write("\r");
|
|
50792
|
+
};
|
|
50793
|
+
const renderMenu = () => {
|
|
50794
|
+
clearPrevious();
|
|
50795
|
+
let totalLines = 0;
|
|
50796
|
+
for (let i = 0; i < modes.length; i++) {
|
|
50797
|
+
const mode = modes[i];
|
|
50798
|
+
const label = formatThinkingMode(mode);
|
|
50799
|
+
const isCurrent = label === currentLabel;
|
|
50800
|
+
const isSelected = i === selectedIndex;
|
|
50801
|
+
const desc = modeDescription(mode, hasBudget);
|
|
50802
|
+
let line = "";
|
|
50803
|
+
if (isSelected) {
|
|
50804
|
+
line = chalk.bgBlue.white(` \u25B6 ${label.padEnd(8)}`) + chalk.bgBlue.white(` ${desc} `);
|
|
50805
|
+
} else if (isCurrent) {
|
|
50806
|
+
line = chalk.green(` \u25CF ${label.padEnd(8)}`) + chalk.dim(` ${desc}`);
|
|
50807
|
+
} else {
|
|
50808
|
+
line = chalk.dim(` \u25CB ${label.padEnd(8)}`) + chalk.dim(` ${desc}`);
|
|
50809
|
+
}
|
|
50810
|
+
process.stdout.write(line + "\n");
|
|
50811
|
+
totalLines++;
|
|
50812
|
+
}
|
|
50813
|
+
process.stdout.write("\n" + chalk.dim("\u2191/\u2193 navigate \u2022 Enter select \u2022 Esc cancel") + "\n");
|
|
50814
|
+
totalLines += 2;
|
|
50815
|
+
lastTotalLines = totalLines;
|
|
50816
|
+
};
|
|
50817
|
+
const cleanup = () => {
|
|
50818
|
+
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
50819
|
+
process.stdin.pause();
|
|
50820
|
+
process.stdin.removeListener("data", onKeyPress);
|
|
50821
|
+
};
|
|
50822
|
+
const onKeyPress = (data) => {
|
|
50823
|
+
const key = data.toString();
|
|
50824
|
+
if (key === "\r" || key === "\n") {
|
|
50825
|
+
clearPrevious();
|
|
50826
|
+
cleanup();
|
|
50827
|
+
resolve4(modes[selectedIndex] ?? null);
|
|
50828
|
+
return;
|
|
50829
|
+
}
|
|
50830
|
+
if (key === "\x1B" || key === "q" || key === "") {
|
|
50831
|
+
clearPrevious();
|
|
50832
|
+
cleanup();
|
|
50833
|
+
resolve4(null);
|
|
50834
|
+
return;
|
|
50835
|
+
}
|
|
50836
|
+
if (key === "\x1B[A") {
|
|
50837
|
+
selectedIndex = (selectedIndex - 1 + modes.length) % modes.length;
|
|
50838
|
+
renderMenu();
|
|
50839
|
+
return;
|
|
50840
|
+
}
|
|
50841
|
+
if (key === "\x1B[B") {
|
|
50842
|
+
selectedIndex = (selectedIndex + 1) % modes.length;
|
|
50843
|
+
renderMenu();
|
|
50844
|
+
return;
|
|
50845
|
+
}
|
|
50846
|
+
};
|
|
50847
|
+
if (process.stdin.isTTY) process.stdin.setRawMode(true);
|
|
50848
|
+
process.stdin.resume();
|
|
50849
|
+
process.stdin.on("data", onKeyPress);
|
|
50850
|
+
renderMenu();
|
|
50851
|
+
});
|
|
50852
|
+
}
|
|
50853
|
+
async function applyMode(parsed, session, provider, model) {
|
|
50854
|
+
const capability = getThinkingCapability(provider, model);
|
|
50855
|
+
if ((provider === "kimi" || provider === "kimi-code") && parsed !== "off" && parsed !== "auto") {
|
|
50856
|
+
console.log(
|
|
50857
|
+
chalk.yellow(
|
|
50858
|
+
"\n\u26A0 Enabling thinking on Kimi may cause issues with tool calling.\n If you experience errors, run /thinking off to restore default behavior.\n"
|
|
50859
|
+
)
|
|
50860
|
+
);
|
|
50861
|
+
}
|
|
50862
|
+
const previousMode = session.config.provider.thinking;
|
|
50863
|
+
const newMode = parsed === "off" ? void 0 : parsed;
|
|
50864
|
+
session.config.provider.thinking = newMode;
|
|
50865
|
+
const modeToSave = newMode ?? resolveDefaultThinking(provider, model);
|
|
50866
|
+
await saveThinkingPreference(provider, modeToSave);
|
|
50867
|
+
const previousLabel = previousMode !== void 0 ? formatThinkingMode(previousMode) : "off";
|
|
50868
|
+
const newLabel = newMode !== void 0 ? formatThinkingMode(newMode) : "off";
|
|
50869
|
+
if (previousLabel === newLabel) {
|
|
50870
|
+
console.log(chalk.dim(`
|
|
50871
|
+
Already using thinking: ${newLabel}
|
|
50872
|
+
`));
|
|
50873
|
+
} else {
|
|
50874
|
+
const kindLabel = capability.kinds.includes("budget") ? "budget" : "effort";
|
|
50875
|
+
console.log(chalk.green(`
|
|
50876
|
+
\u2713 Thinking (${kindLabel}): ${previousLabel} \u2192 ${newLabel}
|
|
50877
|
+
`));
|
|
50878
|
+
}
|
|
50879
|
+
}
|
|
50768
50880
|
var thinkingCommand = {
|
|
50769
50881
|
name: "thinking",
|
|
50770
50882
|
aliases: ["think", "reason"],
|
|
@@ -50774,43 +50886,39 @@ var thinkingCommand = {
|
|
|
50774
50886
|
const provider = session.config.provider.type;
|
|
50775
50887
|
const model = session.config.provider.model;
|
|
50776
50888
|
const capability = getThinkingCapability(provider, model);
|
|
50777
|
-
if (
|
|
50778
|
-
|
|
50779
|
-
|
|
50780
|
-
if (!capability.supported) {
|
|
50781
|
-
console.log(
|
|
50782
|
-
chalk.yellow(`
|
|
50889
|
+
if (!capability.supported) {
|
|
50890
|
+
console.log(
|
|
50891
|
+
chalk.yellow(`
|
|
50783
50892
|
\u26A0 Thinking not supported for ${model} on ${provider}.
|
|
50784
50893
|
`) + chalk.dim(
|
|
50785
|
-
|
|
50786
|
-
|
|
50787
|
-
|
|
50788
|
-
|
|
50789
|
-
|
|
50894
|
+
" Compatible models: claude-3-7+, claude-4+, o3, o4-mini, gpt-5*, gemini-2.5+\n"
|
|
50895
|
+
)
|
|
50896
|
+
);
|
|
50897
|
+
return false;
|
|
50898
|
+
}
|
|
50899
|
+
const hasBudget = capability.kinds.includes("budget");
|
|
50900
|
+
const current = session.config.provider.thinking;
|
|
50901
|
+
const currentMode = current ?? "off";
|
|
50902
|
+
if (args.length === 0) {
|
|
50790
50903
|
console.log(chalk.cyan.bold("\n\u2550\u2550\u2550 Thinking Mode \u2550\u2550\u2550\n"));
|
|
50791
|
-
console.log(
|
|
50792
|
-
|
|
50793
|
-
|
|
50794
|
-
if (capability.budgetRange) {
|
|
50795
|
-
const { min, max
|
|
50796
|
-
console.log(` Budget range: ${chalk.dim(`${min}\u2013${max} tokens (default ${def})`)}`);
|
|
50797
|
-
}
|
|
50798
|
-
console.log(`
|
|
50799
|
-
${chalk.dim("Available modes:")}`);
|
|
50800
|
-
for (const level of capability.levels) {
|
|
50801
|
-
const label = formatThinkingMode(level);
|
|
50802
|
-
const isCurrent = label === display;
|
|
50904
|
+
console.log(
|
|
50905
|
+
` ${chalk.dim(provider + "/")}${chalk.cyan(model)} ${chalk.dim("\xB7")} kind: ${chalk.dim(capability.kinds.join(", "))}`
|
|
50906
|
+
);
|
|
50907
|
+
if (hasBudget && capability.budgetRange) {
|
|
50908
|
+
const { min, max } = capability.budgetRange;
|
|
50803
50909
|
console.log(
|
|
50804
|
-
|
|
50910
|
+
chalk.dim(` Budget range: ${min}\u2013${max} tokens (/thinking 8000 for custom)
|
|
50911
|
+
`)
|
|
50805
50912
|
);
|
|
50806
|
-
}
|
|
50807
|
-
if (capability.kinds.includes("budget")) {
|
|
50808
|
-
console.log(chalk.dim(`
|
|
50809
|
-
You can also pass a token budget: /thinking 8000
|
|
50810
|
-
`));
|
|
50811
50913
|
} else {
|
|
50812
50914
|
console.log();
|
|
50813
50915
|
}
|
|
50916
|
+
const selected = await selectThinkingInteractively(capability.levels, currentMode, hasBudget);
|
|
50917
|
+
if (selected === null) {
|
|
50918
|
+
console.log(chalk.dim(" Cancelled\n"));
|
|
50919
|
+
return false;
|
|
50920
|
+
}
|
|
50921
|
+
await applyMode(selected, session, provider, model);
|
|
50814
50922
|
return false;
|
|
50815
50923
|
}
|
|
50816
50924
|
const rawArg = args[0].toLowerCase();
|
|
@@ -50823,17 +50931,7 @@ var thinkingCommand = {
|
|
|
50823
50931
|
);
|
|
50824
50932
|
return false;
|
|
50825
50933
|
}
|
|
50826
|
-
if (
|
|
50827
|
-
console.log(
|
|
50828
|
-
chalk.yellow(`
|
|
50829
|
-
\u26A0 Thinking not supported for ${model} on ${provider}.
|
|
50830
|
-
`) + chalk.dim(
|
|
50831
|
-
" Compatible models: claude-3-7+, claude-4+, o3, o4-mini, gpt-5*, gemini-2.5+\n"
|
|
50832
|
-
)
|
|
50833
|
-
);
|
|
50834
|
-
return false;
|
|
50835
|
-
}
|
|
50836
|
-
if (typeof parsed === "object" && !capability.kinds.includes("budget")) {
|
|
50934
|
+
if (typeof parsed === "object" && !hasBudget) {
|
|
50837
50935
|
console.log(
|
|
50838
50936
|
chalk.red(`
|
|
50839
50937
|
\u2717 ${provider}/${model} uses effort levels, not token budgets.`) + chalk.dim("\n Use: off, auto, low, medium, or high\n")
|
|
@@ -50852,29 +50950,7 @@ var thinkingCommand = {
|
|
|
50852
50950
|
return false;
|
|
50853
50951
|
}
|
|
50854
50952
|
}
|
|
50855
|
-
|
|
50856
|
-
console.log(
|
|
50857
|
-
chalk.yellow(
|
|
50858
|
-
"\n\u26A0 Enabling thinking on Kimi may cause issues with tool calling.\n If you experience errors, run /thinking off to restore default behavior.\n"
|
|
50859
|
-
)
|
|
50860
|
-
);
|
|
50861
|
-
}
|
|
50862
|
-
const previousMode = session.config.provider.thinking;
|
|
50863
|
-
const newMode = parsed === "off" ? void 0 : parsed;
|
|
50864
|
-
session.config.provider.thinking = newMode;
|
|
50865
|
-
const modeToSave = newMode ?? resolveDefaultThinking(provider, model);
|
|
50866
|
-
await saveThinkingPreference(provider, modeToSave);
|
|
50867
|
-
const previousLabel = previousMode !== void 0 ? formatThinkingMode(previousMode) : "off";
|
|
50868
|
-
const newLabel = newMode !== void 0 ? formatThinkingMode(newMode) : "off";
|
|
50869
|
-
if (previousLabel === newLabel) {
|
|
50870
|
-
console.log(chalk.dim(`
|
|
50871
|
-
Already using thinking: ${newLabel}
|
|
50872
|
-
`));
|
|
50873
|
-
} else {
|
|
50874
|
-
console.log(chalk.green(`
|
|
50875
|
-
\u2713 Thinking: ${previousLabel} \u2192 ${newLabel}
|
|
50876
|
-
`));
|
|
50877
|
-
}
|
|
50953
|
+
await applyMode(parsed, session, provider, model);
|
|
50878
50954
|
return false;
|
|
50879
50955
|
}
|
|
50880
50956
|
};
|
|
@@ -55469,8 +55545,9 @@ function formatStatusBar(projectPath, config, gitCtx, contextUsagePercent) {
|
|
|
55469
55545
|
parts.push(chalk.dim("\u{1F4C1} ") + chalk.magenta(projectName));
|
|
55470
55546
|
const providerName = config.provider.type;
|
|
55471
55547
|
const modelName = getDisplayModel(config);
|
|
55548
|
+
const capability = getThinkingCapability(providerName, modelName);
|
|
55472
55549
|
const thinkingMode = config.provider.thinking;
|
|
55473
|
-
const thinkingSuffix =
|
|
55550
|
+
const thinkingSuffix = capability.supported ? chalk.dim("/") + chalk.magenta(formatThinkingMode(thinkingMode ?? "off")) : "";
|
|
55474
55551
|
parts.push(chalk.dim(`${providerName}/`) + chalk.cyan(modelName) + thinkingSuffix);
|
|
55475
55552
|
if (isQualityLoop()) {
|
|
55476
55553
|
parts.push(chalk.green("\u{1F504} quality loop"));
|