@kernelonpanic/kitcode 1.3.2 → 1.4.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/README.md +46 -8
- package/README.ru.md +45 -7
- package/dist/index.js +244 -50
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -75,6 +75,9 @@ var configSchema = z.object({
|
|
|
75
75
|
theme: themeSchema.default({ accent: "#a78bfa" }),
|
|
76
76
|
effort: effortSchema.default("xhigh"),
|
|
77
77
|
thinking: z.boolean().default(true),
|
|
78
|
+
// Manual override for the model's context window. Unset means the window
|
|
79
|
+
// comes from the provider catalogue or the endpoint's model list.
|
|
80
|
+
contextWindow: z.number().int().min(1e3).max(1e7).optional(),
|
|
78
81
|
maxTokens: z.number().int().positive().max(2e5).default(64e3),
|
|
79
82
|
budget: budgetSchema.default({
|
|
80
83
|
maxTokensPerTurn: 1e7,
|
|
@@ -3704,12 +3707,12 @@ var SUBAGENT_SYSTEM = [
|
|
|
3704
3707
|
].join("\n");
|
|
3705
3708
|
function createSubagentRunner(makeConfig, tools) {
|
|
3706
3709
|
const permissionLane = createExecutionLane();
|
|
3707
|
-
const executionLane = createExecutionLane();
|
|
3708
|
-
const modelRequestLane = createExecutionLane();
|
|
3709
3710
|
return {
|
|
3710
3711
|
async run(request) {
|
|
3711
3712
|
if (request.signal.aborted) return SUBAGENT_CANCELLED;
|
|
3712
3713
|
let steps = 0;
|
|
3714
|
+
const executionLane = createExecutionLane();
|
|
3715
|
+
const modelRequestLane = createExecutionLane();
|
|
3713
3716
|
const base = makeConfig(SUBAGENT_SYSTEM, tools);
|
|
3714
3717
|
const cfg = {
|
|
3715
3718
|
...base,
|
|
@@ -3940,7 +3943,7 @@ function clip(value) {
|
|
|
3940
3943
|
// package.json
|
|
3941
3944
|
var package_default = {
|
|
3942
3945
|
name: "@kernelonpanic/kitcode",
|
|
3943
|
-
version: "1.
|
|
3946
|
+
version: "1.4.0",
|
|
3944
3947
|
description: "Terminal coding agent with a config you never have to write by hand",
|
|
3945
3948
|
type: "module",
|
|
3946
3949
|
license: "MIT",
|
|
@@ -3973,6 +3976,7 @@ var package_default = {
|
|
|
3973
3976
|
dependencies: {
|
|
3974
3977
|
"@anthropic-ai/sdk": "^0.115.0",
|
|
3975
3978
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
3979
|
+
build: "^0.1.4",
|
|
3976
3980
|
chalk: "^6.0.0",
|
|
3977
3981
|
commander: "^15.0.0",
|
|
3978
3982
|
"fast-glob": "^3.3.3",
|
|
@@ -4008,7 +4012,7 @@ var package_default = {
|
|
|
4008
4012
|
|
|
4009
4013
|
// src/version.ts
|
|
4010
4014
|
var KITCODE_VERSION = package_default.version;
|
|
4011
|
-
var KITCODE_COMMIT = true ? "
|
|
4015
|
+
var KITCODE_COMMIT = true ? "f5ecc5fb8dac2872eeb1a988705c06552b250129" : "development";
|
|
4012
4016
|
|
|
4013
4017
|
// src/mcp/client.ts
|
|
4014
4018
|
var clientInfo = { name: "kitcode", version: KITCODE_VERSION };
|
|
@@ -6619,6 +6623,7 @@ async function boot(options) {
|
|
|
6619
6623
|
const notifyContext = () => {
|
|
6620
6624
|
for (const listener of contextListeners) listener();
|
|
6621
6625
|
};
|
|
6626
|
+
const resolveContextWindow = (ref, discovered) => config.contextWindow ?? discovered ?? knownContextWindow(ref);
|
|
6622
6627
|
const knownContextWindow = (ref) => {
|
|
6623
6628
|
const parsed = parseModelRef(ref);
|
|
6624
6629
|
if (!parsed) return null;
|
|
@@ -6635,27 +6640,27 @@ async function boot(options) {
|
|
|
6635
6640
|
modelRef = ref;
|
|
6636
6641
|
if (latestRateLimits?.model !== ref) latestRateLimits = void 0;
|
|
6637
6642
|
contextUsage = restoredContext?.model === ref ? restoredContext : void 0;
|
|
6638
|
-
modelContextWindow =
|
|
6643
|
+
modelContextWindow = resolveContextWindow(ref, discoveredWindow);
|
|
6639
6644
|
notifyContext();
|
|
6640
6645
|
};
|
|
6641
|
-
modelContextWindow =
|
|
6646
|
+
modelContextWindow = resolveContextWindow(modelRef);
|
|
6642
6647
|
async function refreshModelContextWindow() {
|
|
6643
6648
|
const targetRef = modelRef;
|
|
6644
6649
|
const parsed = parseModelRef(targetRef);
|
|
6645
6650
|
if (!parsed) {
|
|
6646
6651
|
if (modelRef === targetRef) {
|
|
6647
|
-
modelContextWindow = null;
|
|
6652
|
+
modelContextWindow = config.contextWindow ?? null;
|
|
6648
6653
|
notifyContext();
|
|
6649
6654
|
}
|
|
6650
6655
|
return;
|
|
6651
6656
|
}
|
|
6652
|
-
let next =
|
|
6657
|
+
let next = resolveContextWindow(targetRef);
|
|
6653
6658
|
try {
|
|
6654
6659
|
const provider = registry.get(parsed.provider);
|
|
6655
6660
|
const models = await loadModels(provider);
|
|
6656
6661
|
rememberModels(parsed.provider, models);
|
|
6657
6662
|
const found = models.find((m) => m.id === parsed.model);
|
|
6658
|
-
next = found?.contextWindow
|
|
6663
|
+
next = resolveContextWindow(targetRef, found?.contextWindow);
|
|
6659
6664
|
} catch {
|
|
6660
6665
|
}
|
|
6661
6666
|
if (modelRef === targetRef) {
|
|
@@ -6999,6 +7004,16 @@ async function boot(options) {
|
|
|
6999
7004
|
draft.thinking = enabled;
|
|
7000
7005
|
});
|
|
7001
7006
|
},
|
|
7007
|
+
getContextWindowOverride: () => config.contextWindow,
|
|
7008
|
+
async setContextWindowOverride(tokens3) {
|
|
7009
|
+
await persistConfig((draft) => {
|
|
7010
|
+
if (tokens3 === void 0) delete draft.contextWindow;
|
|
7011
|
+
else draft.contextWindow = tokens3;
|
|
7012
|
+
});
|
|
7013
|
+
modelContextWindow = config.contextWindow ?? resolveContextWindow(modelRef);
|
|
7014
|
+
notifyContext();
|
|
7015
|
+
void refreshModelContextWindow();
|
|
7016
|
+
},
|
|
7002
7017
|
getMaxTokensPerTurn: () => config.budget.maxTokensPerTurn,
|
|
7003
7018
|
async setMaxTokensPerTurn(tokens3) {
|
|
7004
7019
|
await persistConfig((draft) => {
|
|
@@ -7632,36 +7647,38 @@ function stdioServer(name, command, args) {
|
|
|
7632
7647
|
}
|
|
7633
7648
|
|
|
7634
7649
|
// src/ui/commands.ts
|
|
7650
|
+
var BUSY_SAFE = { runsWhileBusy: true };
|
|
7635
7651
|
var COMMANDS = [
|
|
7636
|
-
{ name: "model" },
|
|
7652
|
+
{ name: "model", ...BUSY_SAFE },
|
|
7637
7653
|
{ name: "login" },
|
|
7638
7654
|
{ name: "provider" },
|
|
7639
7655
|
{ name: "logout", args: "[provider]" },
|
|
7640
7656
|
{ name: "key", args: "[provider]" },
|
|
7641
7657
|
{ name: "refresh", args: "[provider]" },
|
|
7642
|
-
{ name: "effort" },
|
|
7643
|
-
{ name: "thinking" },
|
|
7644
|
-
{ name: "
|
|
7645
|
-
{ name: "
|
|
7646
|
-
{ name: "
|
|
7658
|
+
{ name: "effort", ...BUSY_SAFE },
|
|
7659
|
+
{ name: "thinking", ...BUSY_SAFE },
|
|
7660
|
+
{ name: "context", args: "[tokens|auto]", ...BUSY_SAFE },
|
|
7661
|
+
{ name: "budget", args: "[tokens]", ...BUSY_SAFE },
|
|
7662
|
+
{ name: "theme", args: "[color]", ...BUSY_SAFE },
|
|
7663
|
+
{ name: "lang", ...BUSY_SAFE },
|
|
7647
7664
|
{ name: "prompt", args: "[save <name>|delete <name>]" },
|
|
7648
7665
|
{ name: "skills", args: "[install <source>]" },
|
|
7649
7666
|
{ name: "bypass" },
|
|
7650
|
-
{ name: "usage" },
|
|
7667
|
+
{ name: "usage", ...BUSY_SAFE },
|
|
7651
7668
|
{ name: "mcp", args: "[add|list|delete|enable|disable]" },
|
|
7652
7669
|
{ name: "attach", args: "<path|clipboard|clear>" },
|
|
7653
7670
|
{ name: "memory", args: "[show|set <text>|clear]" },
|
|
7654
7671
|
{ name: "compact" },
|
|
7655
7672
|
{ name: "update" },
|
|
7656
|
-
{ name: "checker" },
|
|
7673
|
+
{ name: "checker", ...BUSY_SAFE },
|
|
7657
7674
|
{ name: "sessions", args: "[list|rename|delete [all]|export]" },
|
|
7658
|
-
{ name: "config" },
|
|
7675
|
+
{ name: "config", ...BUSY_SAFE },
|
|
7659
7676
|
{ name: "resume" },
|
|
7660
7677
|
{ name: "undo" },
|
|
7661
7678
|
{ name: "clear" },
|
|
7662
|
-
{ name: "help" },
|
|
7663
|
-
{ name: "exit" },
|
|
7664
|
-
{ name: "subagents" }
|
|
7679
|
+
{ name: "help", ...BUSY_SAFE },
|
|
7680
|
+
{ name: "exit", ...BUSY_SAFE },
|
|
7681
|
+
{ name: "subagents", ...BUSY_SAFE }
|
|
7665
7682
|
];
|
|
7666
7683
|
var SUBCOMMANDS = [
|
|
7667
7684
|
{ name: "mcp add", args: "<name> <url|-- command>" },
|
|
@@ -7675,6 +7692,10 @@ var SUBCOMMANDS = [
|
|
|
7675
7692
|
{ name: "sessions delete all" },
|
|
7676
7693
|
{ name: "sessions export", args: "[id] [path]" }
|
|
7677
7694
|
];
|
|
7695
|
+
function commandRunsWhileBusy(name) {
|
|
7696
|
+
if (name === "quit") return true;
|
|
7697
|
+
return COMMANDS.some((command) => command.name === name && command.runsWhileBusy === true);
|
|
7698
|
+
}
|
|
7678
7699
|
function matchCommands(line) {
|
|
7679
7700
|
if (!line.startsWith("/")) return [];
|
|
7680
7701
|
const token = line.slice(1);
|
|
@@ -7977,6 +7998,13 @@ ${url}`,
|
|
|
7977
7998
|
undoResult: (restored, removed) => `Undo complete: ${restored} restored, ${removed} newly created removed.`,
|
|
7978
7999
|
undoConflicts: (paths) => `Kept newer changes in: ${paths.join(", ")}`,
|
|
7979
8000
|
undoFailed: (failures) => `Could not restore: ${failures.join("; ")}`,
|
|
8001
|
+
titleContext: "Context window",
|
|
8002
|
+
contextCurrent: (tokens3) => `Context window: ${tokens3.toLocaleString()} tokens`,
|
|
8003
|
+
contextSet: (tokens3) => `Context window set to ${tokens3.toLocaleString()} tokens. Auto-compact triggers at 80%.`,
|
|
8004
|
+
contextAuto: (tokens3) => tokens3 === null ? "Context window: unknown \u2014 using whatever the provider reports." : `Context window: auto (${tokens3.toLocaleString()} tokens from the provider).`,
|
|
8005
|
+
contextUnknown: "Context window: unknown. Set it with /context 256k, /context 512k or /context 1m.",
|
|
8006
|
+
contextInvalid: "Usage: /context 256k | 512k | 1m | <tokens> | auto",
|
|
8007
|
+
contextCurrentLabel: "current",
|
|
7980
8008
|
titleAccent: "Accent colour",
|
|
7981
8009
|
titleEffort: "Reasoning depth",
|
|
7982
8010
|
titleModel: "Model",
|
|
@@ -7997,6 +8025,7 @@ ${url}`,
|
|
|
7997
8025
|
refresh: "reload the model list for a provider",
|
|
7998
8026
|
effort: "set reasoning depth",
|
|
7999
8027
|
thinking: "toggle reasoning",
|
|
8028
|
+
context: "set or show the model context window",
|
|
8000
8029
|
budget: "set token budget per turn",
|
|
8001
8030
|
theme: "change the accent colour",
|
|
8002
8031
|
lang: "change the interface language",
|
|
@@ -8169,6 +8198,13 @@ ${url}`,
|
|
|
8169
8198
|
undoResult: (restored, removed) => `\u041E\u0442\u043A\u0430\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043D: \u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E ${restored}, \u0443\u0434\u0430\u043B\u0435\u043D\u043E \u043D\u043E\u0432\u044B\u0445 \u0444\u0430\u0439\u043B\u043E\u0432 ${removed}.`,
|
|
8170
8199
|
undoConflicts: (paths) => `\u0411\u043E\u043B\u0435\u0435 \u0441\u0432\u0435\u0436\u0438\u0435 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u044B \u0432: ${paths.join(", ")}`,
|
|
8171
8200
|
undoFailed: (failures) => `\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C: ${failures.join("; ")}`,
|
|
8201
|
+
titleContext: "\u041E\u043A\u043D\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430",
|
|
8202
|
+
contextCurrent: (tokens3) => `\u041E\u043A\u043D\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430: ${tokens3.toLocaleString()} \u0442\u043E\u043A\u0435\u043D\u043E\u0432`,
|
|
8203
|
+
contextSet: (tokens3) => `\u041E\u043A\u043D\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430: ${tokens3.toLocaleString()} \u0442\u043E\u043A\u0435\u043D\u043E\u0432. \u0410\u0432\u0442\u043E\u0441\u0436\u0430\u0442\u0438\u0435 \u0441\u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043D\u0430 80%.`,
|
|
8204
|
+
contextAuto: (tokens3) => tokens3 === null ? "\u041E\u043A\u043D\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430: \u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u043E \u2014 \u0431\u0435\u0440\u0451\u043C \u0442\u043E, \u0447\u0442\u043E \u0441\u043E\u043E\u0431\u0449\u0430\u0435\u0442 \u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440." : `\u041E\u043A\u043D\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430: \u0430\u0432\u0442\u043E (${tokens3.toLocaleString()} \u0442\u043E\u043A\u0435\u043D\u043E\u0432 \u043E\u0442 \u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440\u0430).`,
|
|
8205
|
+
contextUnknown: "\u041E\u043A\u043D\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430 \u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u043E. \u0417\u0430\u0434\u0430\u0439 \u0435\u0433\u043E: /context 256k, /context 512k \u0438\u043B\u0438 /context 1m.",
|
|
8206
|
+
contextInvalid: "\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435: /context 256k | 512k | 1m | <\u0442\u043E\u043A\u0435\u043D\u044B> | auto",
|
|
8207
|
+
contextCurrentLabel: "\u0442\u0435\u043A\u0443\u0449\u0435\u0435",
|
|
8172
8208
|
titleAccent: "\u0426\u0432\u0435\u0442 \u0430\u043A\u0446\u0435\u043D\u0442\u0430",
|
|
8173
8209
|
titleEffort: "\u0413\u043B\u0443\u0431\u0438\u043D\u0430 \u0440\u0430\u0437\u043C\u044B\u0448\u043B\u0435\u043D\u0438\u0439",
|
|
8174
8210
|
titleModel: "\u041C\u043E\u0434\u0435\u043B\u044C",
|
|
@@ -8189,6 +8225,7 @@ ${url}`,
|
|
|
8189
8225
|
refresh: "\u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A \u043C\u043E\u0434\u0435\u043B\u0435\u0439 \u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440\u0430",
|
|
8190
8226
|
effort: "\u0433\u043B\u0443\u0431\u0438\u043D\u0430 \u0440\u0430\u0437\u043C\u044B\u0448\u043B\u0435\u043D\u0438\u0439",
|
|
8191
8227
|
thinking: "\u0432\u043A\u043B\u044E\u0447\u0438\u0442\u044C/\u0432\u044B\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u0440\u0430\u0437\u043C\u044B\u0448\u043B\u0435\u043D\u0438\u044F",
|
|
8228
|
+
context: "\u0437\u0430\u0434\u0430\u0442\u044C \u0438\u043B\u0438 \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u043E\u043A\u043D\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430 \u043C\u043E\u0434\u0435\u043B\u0438",
|
|
8192
8229
|
budget: "\u043B\u0438\u043C\u0438\u0442 \u0442\u043E\u043A\u0435\u043D\u043E\u0432 \u0437\u0430 \u0445\u043E\u0434 (0 = \u0431\u0435\u0437\u043B\u0438\u043C\u0438\u0442)",
|
|
8193
8230
|
theme: "\u0441\u043C\u0435\u043D\u0438\u0442\u044C \u0446\u0432\u0435\u0442 \u0430\u043A\u0446\u0435\u043D\u0442\u0430",
|
|
8194
8231
|
lang: "\u0441\u043C\u0435\u043D\u0438\u0442\u044C \u044F\u0437\u044B\u043A \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430",
|
|
@@ -8665,6 +8702,18 @@ function appendInputHistory(history, value, limit = 100) {
|
|
|
8665
8702
|
// src/ui/components/PromptInput.tsx
|
|
8666
8703
|
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
8667
8704
|
var WINDOW2 = 6;
|
|
8705
|
+
var CAT_FRAME_MS = 500;
|
|
8706
|
+
var CAT_FRAMES = [
|
|
8707
|
+
"/\u1420\uFF61\uA788\uFF61\u141F\\ ~",
|
|
8708
|
+
"/\u1420\uFF61\uA788\uFF61\u141F\\ \u223F",
|
|
8709
|
+
"/\u1420\uFF61\uA788\uFF61\u141F\\ ~",
|
|
8710
|
+
"/\u1420\uFF61\uA788\uFF61\u141F\\ \u223E",
|
|
8711
|
+
"/\u1420\uFF61\uA788\uFF61\u141F\\ ~",
|
|
8712
|
+
"/\u1420\uFF61\uA788\uFF61\u141F\\ \u223F",
|
|
8713
|
+
"/\u1420-\uA788-\u141F\\ ~",
|
|
8714
|
+
"/\u1420\uFF61\uA788\uFF61\u141F\\ \u223E"
|
|
8715
|
+
];
|
|
8716
|
+
var MAX_INPUT_ROWS = 6;
|
|
8668
8717
|
var PromptInput = memo(function PromptInput2({
|
|
8669
8718
|
value,
|
|
8670
8719
|
onChange,
|
|
@@ -8680,7 +8729,18 @@ var PromptInput = memo(function PromptInput2({
|
|
|
8680
8729
|
}) {
|
|
8681
8730
|
const theme = useTheme();
|
|
8682
8731
|
const { columns } = useTerminalSize();
|
|
8732
|
+
const panelWidth = Math.max(2, columns - 1);
|
|
8733
|
+
const inputRows = MAX_INPUT_ROWS;
|
|
8683
8734
|
const strings = useStrings();
|
|
8735
|
+
const [catFrame, setCatFrame] = useState4(0);
|
|
8736
|
+
useEffect(() => {
|
|
8737
|
+
if (!disabled) return;
|
|
8738
|
+
const timer = setInterval(() => setCatFrame((frame) => (frame + 1) % CAT_FRAMES.length), CAT_FRAME_MS);
|
|
8739
|
+
return () => clearInterval(timer);
|
|
8740
|
+
}, [disabled]);
|
|
8741
|
+
const panelColor = disabled ? theme.warn : theme.accent;
|
|
8742
|
+
const fullTitle = disabled ? `KitCode ${CAT_FRAMES[catFrame]}` : "KitCode";
|
|
8743
|
+
const panelTitle = fullTitle.slice(0, Math.max(0, panelWidth - 5));
|
|
8684
8744
|
const safeValue = sanitizeTerminalText(value);
|
|
8685
8745
|
const [selectionCursor, setSelectionCursor] = useState4(0);
|
|
8686
8746
|
const [inputCursor, setInputCursor] = useState4(() => characters2(safeValue).length);
|
|
@@ -8843,28 +8903,64 @@ var PromptInput = memo(function PromptInput2({
|
|
|
8843
8903
|
const start = Math.max(0, Math.min(active2 - WINDOW2 + 2, suggestions.length - WINDOW2));
|
|
8844
8904
|
const visible = suggestions.slice(start, start + WINDOW2);
|
|
8845
8905
|
const fileStart = Math.max(0, Math.min(active2 - WINDOW2 + 2, files.length - WINDOW2));
|
|
8846
|
-
return /* @__PURE__ */ jsxs8(Box8, { width:
|
|
8847
|
-
/* @__PURE__ */ jsxs8(
|
|
8848
|
-
Box8,
|
|
8849
|
-
{
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
8906
|
+
return /* @__PURE__ */ jsxs8(Box8, { width: panelWidth, maxWidth: "100%", flexDirection: "column", marginTop: 1, flexShrink: 0, children: [
|
|
8907
|
+
/* @__PURE__ */ jsxs8(Box8, { width: "100%", flexShrink: 0, children: [
|
|
8908
|
+
/* @__PURE__ */ jsx8(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx8(Text8, { color: panelColor, children: "\u256D" }) }),
|
|
8909
|
+
/* @__PURE__ */ jsx8(Box8, { flexShrink: 1, minWidth: 0, children: /* @__PURE__ */ jsxs8(Text8, { color: panelColor, wrap: "truncate-end", children: [
|
|
8910
|
+
"\u2500 ",
|
|
8911
|
+
panelTitle,
|
|
8912
|
+
" "
|
|
8913
|
+
] }) }),
|
|
8914
|
+
/* @__PURE__ */ jsx8(
|
|
8915
|
+
Box8,
|
|
8916
|
+
{
|
|
8917
|
+
flexGrow: 1,
|
|
8918
|
+
flexShrink: 1,
|
|
8919
|
+
minWidth: 0,
|
|
8920
|
+
height: 1,
|
|
8921
|
+
borderStyle: "single",
|
|
8922
|
+
borderColor: panelColor,
|
|
8923
|
+
borderTop: false,
|
|
8924
|
+
borderBottom: true,
|
|
8925
|
+
borderLeft: false,
|
|
8926
|
+
borderRight: false
|
|
8927
|
+
}
|
|
8928
|
+
),
|
|
8929
|
+
/* @__PURE__ */ jsx8(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx8(Text8, { color: panelColor, children: "\u256E" }) })
|
|
8930
|
+
] }),
|
|
8931
|
+
/* @__PURE__ */ jsxs8(Box8, { width: "100%", paddingX: 1, maxHeight: inputRows, overflowY: "hidden", children: [
|
|
8932
|
+
/* @__PURE__ */ jsx8(Text8, { color: panelColor, children: "\u203A " }),
|
|
8933
|
+
/* @__PURE__ */ jsx8(Box8, { flexGrow: 1, flexShrink: 1, minWidth: 0, children: /* @__PURE__ */ jsx8(EditableText, { value: safeValue, cursor: inputCursor, placeholder: strings.placeholder }) }),
|
|
8934
|
+
pending && pending > 0 ? /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
8935
|
+
" \xB7 ",
|
|
8936
|
+
strings.queued(pending)
|
|
8937
|
+
] }) : null
|
|
8938
|
+
] }),
|
|
8862
8939
|
attachments.length > 0 && /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
|
|
8863
8940
|
" ",
|
|
8864
8941
|
"\u{1F4CE} ",
|
|
8865
8942
|
attachments.map(sanitizeTerminalText).join(" \xB7 ")
|
|
8866
8943
|
] }),
|
|
8867
|
-
|
|
8944
|
+
/* @__PURE__ */ jsxs8(Box8, { width: "100%", flexShrink: 0, children: [
|
|
8945
|
+
/* @__PURE__ */ jsx8(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx8(Text8, { color: panelColor, children: "\u2570" }) }),
|
|
8946
|
+
/* @__PURE__ */ jsx8(
|
|
8947
|
+
Box8,
|
|
8948
|
+
{
|
|
8949
|
+
flexGrow: 1,
|
|
8950
|
+
flexShrink: 1,
|
|
8951
|
+
minWidth: 0,
|
|
8952
|
+
height: 1,
|
|
8953
|
+
borderStyle: "single",
|
|
8954
|
+
borderColor: panelColor,
|
|
8955
|
+
borderTop: false,
|
|
8956
|
+
borderBottom: true,
|
|
8957
|
+
borderLeft: false,
|
|
8958
|
+
borderRight: false
|
|
8959
|
+
}
|
|
8960
|
+
),
|
|
8961
|
+
/* @__PURE__ */ jsx8(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx8(Text8, { color: panelColor, children: "\u256F" }) })
|
|
8962
|
+
] }),
|
|
8963
|
+
disabled && hint && /* @__PURE__ */ jsxs8(Text8, { color: theme.accent, children: [
|
|
8868
8964
|
" ",
|
|
8869
8965
|
sanitizeTerminalText(hint)
|
|
8870
8966
|
] }),
|
|
@@ -9148,13 +9244,12 @@ function ContextMeter({
|
|
|
9148
9244
|
// src/ui/components/TerminalViewport.tsx
|
|
9149
9245
|
import { Box as Box10 } from "ink";
|
|
9150
9246
|
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
9151
|
-
function interactiveViewportRows(rows) {
|
|
9152
|
-
if (!Number.isFinite(rows)) return 22;
|
|
9153
|
-
return Math.max(1, Math.floor(rows) - 2);
|
|
9154
|
-
}
|
|
9155
9247
|
var INTERACTIVE_CHROME_ROWS = 14;
|
|
9248
|
+
var MAX_LIVE_ROWS = 8;
|
|
9249
|
+
var MIN_LIVE_ROWS = 4;
|
|
9156
9250
|
function liveTranscriptRows(rows) {
|
|
9157
|
-
|
|
9251
|
+
if (!Number.isFinite(rows)) return MAX_LIVE_ROWS;
|
|
9252
|
+
return Math.max(MIN_LIVE_ROWS, Math.min(MAX_LIVE_ROWS, Math.floor(rows) - INTERACTIVE_CHROME_ROWS - 2));
|
|
9158
9253
|
}
|
|
9159
9254
|
function TerminalViewport({ children, rows }) {
|
|
9160
9255
|
const { columns } = useTerminalSize();
|
|
@@ -9164,7 +9259,7 @@ function TerminalViewport({ children, rows }) {
|
|
|
9164
9259
|
width: columns,
|
|
9165
9260
|
maxWidth: "100%",
|
|
9166
9261
|
flexDirection: "column",
|
|
9167
|
-
maxHeight:
|
|
9262
|
+
maxHeight: liveTranscriptRows(rows) + INTERACTIVE_CHROME_ROWS,
|
|
9168
9263
|
overflowY: "hidden",
|
|
9169
9264
|
children
|
|
9170
9265
|
}
|
|
@@ -9183,9 +9278,17 @@ import { createContext as createContext3, Fragment as Fragment4, useContext as u
|
|
|
9183
9278
|
import stringWidth from "string-width";
|
|
9184
9279
|
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
9185
9280
|
var DimContext = createContext3(false);
|
|
9186
|
-
function Text10({ dimColor, color, ...props }) {
|
|
9281
|
+
function Text10({ dimColor, color, bold, ...props }) {
|
|
9187
9282
|
const dim = useContext3(DimContext);
|
|
9188
|
-
return /* @__PURE__ */ jsx11(
|
|
9283
|
+
return /* @__PURE__ */ jsx11(
|
|
9284
|
+
InkText,
|
|
9285
|
+
{
|
|
9286
|
+
...props,
|
|
9287
|
+
color: dim ? void 0 : color,
|
|
9288
|
+
bold: dim ? void 0 : bold,
|
|
9289
|
+
dimColor: dimColor ?? dim
|
|
9290
|
+
}
|
|
9291
|
+
);
|
|
9189
9292
|
}
|
|
9190
9293
|
function Markdown({ children, dim = false }) {
|
|
9191
9294
|
const blocks = useMemo3(() => extractBlocks(children), [children]);
|
|
@@ -9758,6 +9861,8 @@ var Transcript = memo2(function Transcript2({
|
|
|
9758
9861
|
}
|
|
9759
9862
|
const live = liveAt === -1 ? [] : bubbles.slice(liveAt);
|
|
9760
9863
|
const staticItems = [HEADER, ...stableRef.current];
|
|
9864
|
+
const agents = live.filter((bubble) => bubble.kind === "subagent");
|
|
9865
|
+
const groupedAgents = agents.length > 1;
|
|
9761
9866
|
return /* @__PURE__ */ jsxs11(
|
|
9762
9867
|
Box12,
|
|
9763
9868
|
{
|
|
@@ -9768,7 +9873,7 @@ var Transcript = memo2(function Transcript2({
|
|
|
9768
9873
|
overflowY: "hidden",
|
|
9769
9874
|
children: [
|
|
9770
9875
|
/* @__PURE__ */ jsx12(Static, { items: staticItems, children: (item) => item.kind === "header" ? /* @__PURE__ */ jsx12(Logo, { workspace }, "kitcode-header") : /* @__PURE__ */ jsx12(BubbleView, { bubble: item }, item.id) }),
|
|
9771
|
-
/* @__PURE__ */
|
|
9876
|
+
/* @__PURE__ */ jsxs11(
|
|
9772
9877
|
Box12,
|
|
9773
9878
|
{
|
|
9774
9879
|
flexDirection: "column",
|
|
@@ -9777,7 +9882,10 @@ var Transcript = memo2(function Transcript2({
|
|
|
9777
9882
|
maxHeight: maxLiveRows,
|
|
9778
9883
|
overflowY: "hidden",
|
|
9779
9884
|
justifyContent: "flex-end",
|
|
9780
|
-
children:
|
|
9885
|
+
children: [
|
|
9886
|
+
live.filter((bubble) => !groupedAgents || bubble.kind !== "subagent" && !(bubble.kind === "tool" && bubble.name === "task")).map((bubble) => /* @__PURE__ */ jsx12(BubbleView, { bubble, maxRows: maxLiveRows }, bubble.id)),
|
|
9887
|
+
groupedAgents && /* @__PURE__ */ jsx12(SubagentSummary, { agents })
|
|
9888
|
+
]
|
|
9781
9889
|
}
|
|
9782
9890
|
)
|
|
9783
9891
|
]
|
|
@@ -9914,6 +10022,30 @@ function previewLines(content) {
|
|
|
9914
10022
|
if (lines.length <= 6) return lines;
|
|
9915
10023
|
return [...lines.slice(0, 6), `\u2026 ${lines.length - 6} more lines`];
|
|
9916
10024
|
}
|
|
10025
|
+
var VISIBLE_SUBAGENTS = 3;
|
|
10026
|
+
function SubagentSummary({ agents }) {
|
|
10027
|
+
const theme = useTheme();
|
|
10028
|
+
const running = agents.filter((agent) => agent.state === "running");
|
|
10029
|
+
return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", marginTop: 1, minWidth: 0, children: [
|
|
10030
|
+
/* @__PURE__ */ jsxs11(Text11, { color: theme.accent, wrap: "truncate-end", children: [
|
|
10031
|
+
"Subagents: ",
|
|
10032
|
+
running.length,
|
|
10033
|
+
" running \xB7 ",
|
|
10034
|
+
agents.length - running.length,
|
|
10035
|
+
" done"
|
|
10036
|
+
] }),
|
|
10037
|
+
running.slice(0, VISIBLE_SUBAGENTS).map((agent) => {
|
|
10038
|
+
const latest = agent.bubbles.at(-1);
|
|
10039
|
+
const progress = latest?.kind === "tool" ? latest.summary : latest?.kind === "assistant" ? sanitizeThinkingText(latest.text || latest.thinking, latest.streaming) : "waiting";
|
|
10040
|
+
return /* @__PURE__ */ jsxs11(Text11, { dimColor: true, wrap: "truncate-end", children: [
|
|
10041
|
+
agent.description,
|
|
10042
|
+
" \xB7 ",
|
|
10043
|
+
progress.replace(/\s+/g, " ").trim() || "waiting"
|
|
10044
|
+
] }, agent.id);
|
|
10045
|
+
}),
|
|
10046
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "/subagents \xB7 all active tasks" })
|
|
10047
|
+
] });
|
|
10048
|
+
}
|
|
9917
10049
|
function SubagentView({ bubble, maxRows }) {
|
|
9918
10050
|
const theme = useTheme();
|
|
9919
10051
|
const { columns } = useTerminalSize();
|
|
@@ -10172,6 +10304,18 @@ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
|
10172
10304
|
var EFFORTS = ["auto", "low", "medium", "high", "xhigh", "max"];
|
|
10173
10305
|
var STREAM_FRAME_MS = 50;
|
|
10174
10306
|
var MAX_ATTACHMENTS = 8;
|
|
10307
|
+
var CONTEXT_PRESETS = [256e3, 512e3, 1e6];
|
|
10308
|
+
function formatContextTokens(tokens3) {
|
|
10309
|
+
if (tokens3 >= 1e6) return `${tokens3 / 1e6}M`;
|
|
10310
|
+
return `${Math.round(tokens3 / 1e3)}k`;
|
|
10311
|
+
}
|
|
10312
|
+
function parseContextTokens(input) {
|
|
10313
|
+
const match = /^(\d+(?:\.\d+)?)\s*([km])?$/i.exec(input.trim());
|
|
10314
|
+
if (!match) return null;
|
|
10315
|
+
const scale = match[2]?.toLowerCase() === "m" ? 1e6 : match[2]?.toLowerCase() === "k" ? 1e3 : 1;
|
|
10316
|
+
const tokens3 = Math.round(Number(match[1]) * scale);
|
|
10317
|
+
return tokens3 >= 1e3 && tokens3 <= 1e7 ? tokens3 : null;
|
|
10318
|
+
}
|
|
10175
10319
|
function App({
|
|
10176
10320
|
runtime,
|
|
10177
10321
|
initialHistory,
|
|
@@ -11092,6 +11236,57 @@ ${strings.mcpAddUsage}`
|
|
|
11092
11236
|
}
|
|
11093
11237
|
return;
|
|
11094
11238
|
}
|
|
11239
|
+
case "context": {
|
|
11240
|
+
const override = runtime.getContextWindowOverride();
|
|
11241
|
+
const current = runtime.modelContext();
|
|
11242
|
+
const requested = rest[0]?.toLowerCase();
|
|
11243
|
+
if (requested !== void 0 && requested !== "") {
|
|
11244
|
+
if (requested === "auto") {
|
|
11245
|
+
await runtime.setContextWindowOverride(void 0);
|
|
11246
|
+
notice("info", strings.contextAuto(runtime.modelContext().window));
|
|
11247
|
+
forceRender((n) => n + 1);
|
|
11248
|
+
return;
|
|
11249
|
+
}
|
|
11250
|
+
const tokens3 = parseContextTokens(requested);
|
|
11251
|
+
if (tokens3 === null) {
|
|
11252
|
+
notice("warn", strings.contextInvalid);
|
|
11253
|
+
return;
|
|
11254
|
+
}
|
|
11255
|
+
await runtime.setContextWindowOverride(tokens3);
|
|
11256
|
+
notice("info", strings.contextSet(tokens3));
|
|
11257
|
+
forceRender((n) => n + 1);
|
|
11258
|
+
return;
|
|
11259
|
+
}
|
|
11260
|
+
const effective = override ?? current.window;
|
|
11261
|
+
notice("info", effective === null ? strings.contextUnknown : strings.contextCurrent(effective));
|
|
11262
|
+
const choice = await pick(
|
|
11263
|
+
strings.titleContext,
|
|
11264
|
+
CONTEXT_PRESETS.map((preset) => ({
|
|
11265
|
+
key: String(preset),
|
|
11266
|
+
label: formatContextTokens(preset),
|
|
11267
|
+
hint: current.window === preset ? strings.contextCurrentLabel : void 0
|
|
11268
|
+
})).concat([
|
|
11269
|
+
{
|
|
11270
|
+
key: "auto",
|
|
11271
|
+
label: "auto",
|
|
11272
|
+
hint: override === void 0 ? strings.contextCurrentLabel : void 0
|
|
11273
|
+
}
|
|
11274
|
+
])
|
|
11275
|
+
);
|
|
11276
|
+
if (!choice) return;
|
|
11277
|
+
const chosen = CONTEXT_PRESETS.find((preset) => String(preset) === choice);
|
|
11278
|
+
if (choice === "auto") {
|
|
11279
|
+
await runtime.setContextWindowOverride(void 0);
|
|
11280
|
+
notice("info", strings.contextAuto(runtime.modelContext().window));
|
|
11281
|
+
} else if (chosen !== void 0) {
|
|
11282
|
+
await runtime.setContextWindowOverride(chosen);
|
|
11283
|
+
notice("info", strings.contextSet(chosen));
|
|
11284
|
+
} else {
|
|
11285
|
+
return;
|
|
11286
|
+
}
|
|
11287
|
+
forceRender((n) => n + 1);
|
|
11288
|
+
return;
|
|
11289
|
+
}
|
|
11095
11290
|
case "model": {
|
|
11096
11291
|
const items = await runtime.listModelItems();
|
|
11097
11292
|
if (items.length === 0) {
|
|
@@ -11332,8 +11527,7 @@ Rename the file if you want a different name.`);
|
|
|
11332
11527
|
const submitSlash = () => {
|
|
11333
11528
|
if (!detachedInput) setInput("");
|
|
11334
11529
|
const command = text.slice(1).trim().split(/\s+/)[0]?.toLowerCase();
|
|
11335
|
-
|
|
11336
|
-
if (busyRef.current && !liveCommand || slashPendingRef.current > 0) {
|
|
11530
|
+
if (busyRef.current && !commandRunsWhileBusy(command) || slashPendingRef.current > 0) {
|
|
11337
11531
|
queueRef.current = [...queueRef.current, { kind: "command", line: text }];
|
|
11338
11532
|
setPendingCount(queueRef.current.length);
|
|
11339
11533
|
return;
|