kimiflare 0.81.0 → 0.82.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/index.js +384 -174
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7198,6 +7198,41 @@ function isNewer(local, remote) {
|
|
|
7198
7198
|
}
|
|
7199
7199
|
return false;
|
|
7200
7200
|
}
|
|
7201
|
+
async function readOptionalDepVersion(name) {
|
|
7202
|
+
try {
|
|
7203
|
+
const here = dirname6(fileURLToPath2(import.meta.url));
|
|
7204
|
+
const candidate = join12(here, "..", "..", "node_modules", name, "package.json");
|
|
7205
|
+
const raw = await readFile7(candidate, "utf8");
|
|
7206
|
+
const parsed = JSON.parse(raw);
|
|
7207
|
+
return parsed.version ?? null;
|
|
7208
|
+
} catch {
|
|
7209
|
+
return null;
|
|
7210
|
+
}
|
|
7211
|
+
}
|
|
7212
|
+
async function fetchDistTagVersion(name, tag2) {
|
|
7213
|
+
try {
|
|
7214
|
+
const res = await fetch(`https://registry.npmjs.org/${name}/${tag2}`, {
|
|
7215
|
+
headers: { "User-Agent": getUserAgent(), Accept: "application/json" }
|
|
7216
|
+
});
|
|
7217
|
+
if (!res.ok) return null;
|
|
7218
|
+
const data = await res.json();
|
|
7219
|
+
return data.version ?? null;
|
|
7220
|
+
} catch {
|
|
7221
|
+
return null;
|
|
7222
|
+
}
|
|
7223
|
+
}
|
|
7224
|
+
async function checkOptionalDependency(name, tag2) {
|
|
7225
|
+
const localVersion = await readOptionalDepVersion(name);
|
|
7226
|
+
if (!localVersion) {
|
|
7227
|
+
return { name, hasUpdate: false, localVersion: null, latestVersion: null };
|
|
7228
|
+
}
|
|
7229
|
+
const latestVersion = await fetchDistTagVersion(name, tag2);
|
|
7230
|
+
if (!latestVersion) {
|
|
7231
|
+
return { name, hasUpdate: false, localVersion, latestVersion: null };
|
|
7232
|
+
}
|
|
7233
|
+
const hasUpdate = isNewer(localVersion, latestVersion);
|
|
7234
|
+
return { name, hasUpdate, localVersion, latestVersion };
|
|
7235
|
+
}
|
|
7201
7236
|
async function checkForUpdate(force = false) {
|
|
7202
7237
|
const localVersion = await readLocalVersion();
|
|
7203
7238
|
if (!localVersion) return { hasUpdate: false, localVersion: null, latestVersion: null };
|
|
@@ -13997,6 +14032,30 @@ Do not include speculation. Do not include chat-style pleasantries. Use short bu
|
|
|
13997
14032
|
}
|
|
13998
14033
|
});
|
|
13999
14034
|
|
|
14035
|
+
// src/agent/distill.ts
|
|
14036
|
+
function distillSessionPlan(messages) {
|
|
14037
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
14038
|
+
const m = messages[i];
|
|
14039
|
+
if (m?.role !== "assistant") continue;
|
|
14040
|
+
let text = "";
|
|
14041
|
+
if (typeof m.content === "string") {
|
|
14042
|
+
text = m.content;
|
|
14043
|
+
} else if (Array.isArray(m.content)) {
|
|
14044
|
+
text = m.content.filter((p) => p.type === "text").map((p) => p.text).join("\n");
|
|
14045
|
+
}
|
|
14046
|
+
text = text.trim();
|
|
14047
|
+
if (text.length > 20) {
|
|
14048
|
+
return text;
|
|
14049
|
+
}
|
|
14050
|
+
}
|
|
14051
|
+
return null;
|
|
14052
|
+
}
|
|
14053
|
+
var init_distill = __esm({
|
|
14054
|
+
"src/agent/distill.ts"() {
|
|
14055
|
+
"use strict";
|
|
14056
|
+
}
|
|
14057
|
+
});
|
|
14058
|
+
|
|
14000
14059
|
// src/ui/greetings.ts
|
|
14001
14060
|
function pick(arr) {
|
|
14002
14061
|
if (arr.length === 0) throw new Error("pick() called with empty array");
|
|
@@ -14861,6 +14920,40 @@ var init_theme = __esm({
|
|
|
14861
14920
|
}
|
|
14862
14921
|
});
|
|
14863
14922
|
|
|
14923
|
+
// src/util/clipboard.ts
|
|
14924
|
+
import { execSync as execSync3 } from "child_process";
|
|
14925
|
+
import { platform as platform3 } from "os";
|
|
14926
|
+
function writeToClipboard(text) {
|
|
14927
|
+
const os2 = platform3();
|
|
14928
|
+
try {
|
|
14929
|
+
if (os2 === "darwin") {
|
|
14930
|
+
execSync3("pbcopy", { input: text, timeout: 5e3 });
|
|
14931
|
+
return { success: true, message: "Copied to clipboard" };
|
|
14932
|
+
}
|
|
14933
|
+
if (os2 === "win32") {
|
|
14934
|
+
execSync3("clip", { input: text, timeout: 5e3 });
|
|
14935
|
+
return { success: true, message: "Copied to clipboard" };
|
|
14936
|
+
}
|
|
14937
|
+
try {
|
|
14938
|
+
execSync3("xclip -selection clipboard", { input: text, timeout: 5e3 });
|
|
14939
|
+
return { success: true, message: "Copied to clipboard" };
|
|
14940
|
+
} catch {
|
|
14941
|
+
execSync3("xsel --clipboard --input", { input: text, timeout: 5e3 });
|
|
14942
|
+
return { success: true, message: "Copied to clipboard" };
|
|
14943
|
+
}
|
|
14944
|
+
} catch {
|
|
14945
|
+
return {
|
|
14946
|
+
success: false,
|
|
14947
|
+
message: "Clipboard not available \u2014 plan will be shown below"
|
|
14948
|
+
};
|
|
14949
|
+
}
|
|
14950
|
+
}
|
|
14951
|
+
var init_clipboard = __esm({
|
|
14952
|
+
"src/util/clipboard.ts"() {
|
|
14953
|
+
"use strict";
|
|
14954
|
+
}
|
|
14955
|
+
});
|
|
14956
|
+
|
|
14864
14957
|
// src/cloud/ai-gateway-api.ts
|
|
14865
14958
|
function baseUrl(accountId) {
|
|
14866
14959
|
return `https://api.cloudflare.com/client/v4/accounts/${encodeURIComponent(accountId)}/ai-gateway/gateways`;
|
|
@@ -16088,11 +16181,11 @@ __export(ui_mode_exports, {
|
|
|
16088
16181
|
runCamouflageOnboarding: () => runCamouflageOnboarding,
|
|
16089
16182
|
runUiMode: () => runUiMode
|
|
16090
16183
|
});
|
|
16091
|
-
import { execSync as
|
|
16184
|
+
import { execSync as execSync4, spawn as spawn5 } from "child_process";
|
|
16092
16185
|
import { appendFileSync, openSync } from "fs";
|
|
16093
|
-
import { readdir as readdir7 } from "fs/promises";
|
|
16186
|
+
import { readdir as readdir7, unlink as unlink4 } from "fs/promises";
|
|
16094
16187
|
import { join as join28, relative as relative6 } from "path";
|
|
16095
|
-
import { platform as
|
|
16188
|
+
import { platform as platform4 } from "os";
|
|
16096
16189
|
function kimiLog(payload) {
|
|
16097
16190
|
if (!KIMI_LOG_PATH) return;
|
|
16098
16191
|
try {
|
|
@@ -16209,6 +16302,17 @@ ${err instanceof Error ? err.message : err}`);
|
|
|
16209
16302
|
}
|
|
16210
16303
|
} catch {
|
|
16211
16304
|
}
|
|
16305
|
+
try {
|
|
16306
|
+
const dep = await checkOptionalDependency("camouflage-tui", "beta");
|
|
16307
|
+
if (dep.hasUpdate && dep.latestVersion) {
|
|
16308
|
+
cam.send("ShowToast", {
|
|
16309
|
+
text: `camouflage-tui update available: ${dep.localVersion} \u2192 ${dep.latestVersion} \xB7 run npm update camouflage-tui`,
|
|
16310
|
+
kind: "info",
|
|
16311
|
+
ttl_ms: 6e3
|
|
16312
|
+
});
|
|
16313
|
+
}
|
|
16314
|
+
} catch {
|
|
16315
|
+
}
|
|
16212
16316
|
})();
|
|
16213
16317
|
cam.send("ShowToast", {
|
|
16214
16318
|
text: "EXPERIMENTAL \u2014 switch back any time with `kimiflare --ui ink`",
|
|
@@ -17625,20 +17729,41 @@ Executor opened PR: ${prUrl}` : plan });
|
|
|
17625
17729
|
return true;
|
|
17626
17730
|
}
|
|
17627
17731
|
case "update": {
|
|
17628
|
-
|
|
17629
|
-
|
|
17630
|
-
|
|
17631
|
-
|
|
17632
|
-
|
|
17633
|
-
|
|
17634
|
-
|
|
17635
|
-
|
|
17636
|
-
|
|
17637
|
-
|
|
17638
|
-
|
|
17732
|
+
const updateArg = (rest[0] ?? "").toLowerCase();
|
|
17733
|
+
if (updateArg === "camouflage") {
|
|
17734
|
+
cam.send("ShowToast", { text: "checking camouflage-tui for updates\u2026", kind: "info", ttl_ms: 1500 });
|
|
17735
|
+
try {
|
|
17736
|
+
const dep = await checkOptionalDependency("camouflage-tui", "beta");
|
|
17737
|
+
if (dep.hasUpdate && dep.latestVersion) {
|
|
17738
|
+
cam.send("ShowToast", {
|
|
17739
|
+
text: `camouflage-tui update available: ${dep.localVersion} \u2192 ${dep.latestVersion}. Run: npm update camouflage-tui`,
|
|
17740
|
+
kind: "success",
|
|
17741
|
+
ttl_ms: 5e3
|
|
17742
|
+
});
|
|
17743
|
+
} else if (dep.localVersion) {
|
|
17744
|
+
cam.send("ShowToast", { text: `camouflage-tui up to date (${dep.localVersion})`, kind: "info", ttl_ms: 2500 });
|
|
17745
|
+
} else {
|
|
17746
|
+
cam.send("ShowToast", { text: "camouflage-tui is not installed", kind: "info", ttl_ms: 2500 });
|
|
17747
|
+
}
|
|
17748
|
+
} catch (err) {
|
|
17749
|
+
cam.send("ShowToast", { text: `camouflage-tui update check failed: ${err instanceof Error ? err.message : String(err)}`, kind: "error", ttl_ms: 3e3 });
|
|
17750
|
+
}
|
|
17751
|
+
} else {
|
|
17752
|
+
cam.send("ShowToast", { text: "checking for updates\u2026", kind: "info", ttl_ms: 1500 });
|
|
17753
|
+
try {
|
|
17754
|
+
const r = await checkForUpdate(true);
|
|
17755
|
+
if (r.hasUpdate && r.latestVersion) {
|
|
17756
|
+
cam.send("ShowToast", {
|
|
17757
|
+
text: `update available: ${r.localVersion} \u2192 ${r.latestVersion}. Run: npm i -g kimiflare@latest`,
|
|
17758
|
+
kind: "success",
|
|
17759
|
+
ttl_ms: 5e3
|
|
17760
|
+
});
|
|
17761
|
+
} else {
|
|
17762
|
+
cam.send("ShowToast", { text: `up to date (${r.localVersion ?? "unknown"})`, kind: "info", ttl_ms: 2500 });
|
|
17763
|
+
}
|
|
17764
|
+
} catch (err) {
|
|
17765
|
+
cam.send("ShowToast", { text: `update check failed: ${err instanceof Error ? err.message : String(err)}`, kind: "error", ttl_ms: 3e3 });
|
|
17639
17766
|
}
|
|
17640
|
-
} catch (err) {
|
|
17641
|
-
cam.send("ShowToast", { text: `update check failed: ${err instanceof Error ? err.message : String(err)}`, kind: "error", ttl_ms: 3e3 });
|
|
17642
17767
|
}
|
|
17643
17768
|
return true;
|
|
17644
17769
|
}
|
|
@@ -17980,8 +18105,43 @@ Executor opened PR: ${prUrl}` : plan });
|
|
|
17980
18105
|
ttl_ms: 4e3
|
|
17981
18106
|
});
|
|
17982
18107
|
return true;
|
|
18108
|
+
case "fresh": {
|
|
18109
|
+
if (currentPhase !== "idle") {
|
|
18110
|
+
cam.send("ShowToast", { text: "can't /fresh while model is running \u2014 press Esc to interrupt first", kind: "warn", ttl_ms: 2500 });
|
|
18111
|
+
return true;
|
|
18112
|
+
}
|
|
18113
|
+
const plan = distillSessionPlan(messages);
|
|
18114
|
+
if (!plan) {
|
|
18115
|
+
cam.send("ShowToast", { text: "No plan found to start fresh with.", kind: "error", ttl_ms: 2500 });
|
|
18116
|
+
return true;
|
|
18117
|
+
}
|
|
18118
|
+
const clipResult = writeToClipboard(plan);
|
|
18119
|
+
const systemMessages = messages.filter((m) => m.role === "system");
|
|
18120
|
+
messages.length = 0;
|
|
18121
|
+
messages.push(...systemMessages);
|
|
18122
|
+
sessionCostUsd = 0;
|
|
18123
|
+
promptTokens = 0;
|
|
18124
|
+
cachedTokens = 0;
|
|
18125
|
+
completionTokens = 0;
|
|
18126
|
+
cam.send("TranscriptCleared", {});
|
|
18127
|
+
cam.send("StatusUpdate", {
|
|
18128
|
+
segments: { tokens: "in 0", cost: "$0.00", elapsed: "" }
|
|
18129
|
+
});
|
|
18130
|
+
messages.push({ role: "user", content: plan });
|
|
18131
|
+
cam.send("ShowToast", {
|
|
18132
|
+
text: clipResult.success ? "Plan copied to clipboard. Starting fresh session with plan only\u2026" : "Clipboard unavailable. Starting fresh session with plan only\u2026",
|
|
18133
|
+
kind: "info",
|
|
18134
|
+
ttl_ms: 3e3
|
|
18135
|
+
});
|
|
18136
|
+
if (!clipResult.success) {
|
|
18137
|
+
cam.send("UserMessageCreated", { text: "--- Plan ---\n" + plan });
|
|
18138
|
+
}
|
|
18139
|
+
return true;
|
|
18140
|
+
}
|
|
17983
18141
|
case "logout": {
|
|
17984
|
-
|
|
18142
|
+
unlink4(configPath()).catch(() => {
|
|
18143
|
+
});
|
|
18144
|
+
cam.send("ShowToast", { text: `credentials cleared from ${configPath()}`, kind: "success", ttl_ms: 2500 });
|
|
17985
18145
|
return true;
|
|
17986
18146
|
}
|
|
17987
18147
|
case "remote": {
|
|
@@ -18090,7 +18250,7 @@ function formatShortDate(iso) {
|
|
|
18090
18250
|
}
|
|
18091
18251
|
}
|
|
18092
18252
|
function openBrowser(url) {
|
|
18093
|
-
const cmd =
|
|
18253
|
+
const cmd = platform4() === "darwin" ? "open" : platform4() === "win32" ? "start" : "xdg-open";
|
|
18094
18254
|
const child = spawn5(cmd, [url], { detached: true, stdio: "ignore" });
|
|
18095
18255
|
child.unref();
|
|
18096
18256
|
}
|
|
@@ -18110,7 +18270,7 @@ function formatElapsed2(secs) {
|
|
|
18110
18270
|
}
|
|
18111
18271
|
function tryGitBranch2() {
|
|
18112
18272
|
try {
|
|
18113
|
-
const out =
|
|
18273
|
+
const out = execSync4("git rev-parse --abbrev-ref HEAD 2>/dev/null", {
|
|
18114
18274
|
encoding: "utf8",
|
|
18115
18275
|
timeout: 200
|
|
18116
18276
|
}).trim();
|
|
@@ -18220,9 +18380,11 @@ var init_ui_mode = __esm({
|
|
|
18220
18380
|
init_builtins();
|
|
18221
18381
|
init_sessions();
|
|
18222
18382
|
init_llm_summarize();
|
|
18383
|
+
init_distill();
|
|
18223
18384
|
init_greetings();
|
|
18224
18385
|
init_theme();
|
|
18225
18386
|
init_update_check();
|
|
18387
|
+
init_clipboard();
|
|
18226
18388
|
init_pricing();
|
|
18227
18389
|
init_config();
|
|
18228
18390
|
init_ai_gateway_api();
|
|
@@ -19645,12 +19807,19 @@ var init_chat = __esm({
|
|
|
19645
19807
|
for (const [sig, count] of toolCounts) {
|
|
19646
19808
|
if (count >= 3) repeatedSigs.add(sig);
|
|
19647
19809
|
}
|
|
19810
|
+
let lastAssistantIndex = -1;
|
|
19811
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
19812
|
+
if (events[i].kind === "assistant") {
|
|
19813
|
+
lastAssistantIndex = i;
|
|
19814
|
+
break;
|
|
19815
|
+
}
|
|
19816
|
+
}
|
|
19648
19817
|
return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", children: events.map((e, i) => {
|
|
19649
19818
|
const prev = events[i - 1];
|
|
19650
19819
|
const showSeparator = !!(prev && (e.kind === "user" && prev.kind !== "user" || e.kind === "assistant" && prev.kind !== "assistant" && prev.kind !== "tool"));
|
|
19651
19820
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
19652
19821
|
showSeparator && /* @__PURE__ */ jsx6(Box5, { marginY: 1, children: /* @__PURE__ */ jsx6(Text5, { color: theme.info.color, children: "\u2500".repeat(40) }) }),
|
|
19653
|
-
/* @__PURE__ */ jsx6(EventView, { evt: e, showReasoning, verbose, repeatedSigs, intentTier })
|
|
19822
|
+
/* @__PURE__ */ jsx6(EventView, { evt: e, showReasoning, verbose, repeatedSigs, intentTier, isLastAssistant: i === lastAssistantIndex })
|
|
19654
19823
|
] }, e.key);
|
|
19655
19824
|
}) });
|
|
19656
19825
|
});
|
|
@@ -19659,7 +19828,8 @@ var init_chat = __esm({
|
|
|
19659
19828
|
showReasoning,
|
|
19660
19829
|
verbose,
|
|
19661
19830
|
repeatedSigs,
|
|
19662
|
-
intentTier
|
|
19831
|
+
intentTier,
|
|
19832
|
+
isLastAssistant
|
|
19663
19833
|
}) {
|
|
19664
19834
|
const theme = useTheme();
|
|
19665
19835
|
if (evt.kind === "user") {
|
|
@@ -19704,7 +19874,7 @@ var init_chat = __esm({
|
|
|
19704
19874
|
evt.reasoning.length > 400 ? evt.reasoning.slice(0, 400) + "\u2026" : evt.reasoning
|
|
19705
19875
|
] }) }) : null,
|
|
19706
19876
|
evt.text ? /* @__PURE__ */ jsx6(MD, { text: evt.text }) : null,
|
|
19707
|
-
evt.streaming && /* @__PURE__ */ jsx6(Text5, { color: theme.spinner, children: /* @__PURE__ */ jsx6(Spinner2, { type: "dots" }) })
|
|
19877
|
+
evt.streaming && isLastAssistant && /* @__PURE__ */ jsx6(Text5, { color: theme.spinner, children: /* @__PURE__ */ jsx6(Spinner2, { type: "dots" }) })
|
|
19708
19878
|
] })
|
|
19709
19879
|
] }) });
|
|
19710
19880
|
}
|
|
@@ -20405,7 +20575,7 @@ var init_source = __esm({
|
|
|
20405
20575
|
|
|
20406
20576
|
// src/ui/text-input.tsx
|
|
20407
20577
|
import { useState as useState3, useEffect as useEffect3, useRef } from "react";
|
|
20408
|
-
import { Text as Text7, useInput } from "ink";
|
|
20578
|
+
import { Text as Text7, useInput, usePaste } from "ink";
|
|
20409
20579
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
20410
20580
|
function shouldTreatAsPaste(input) {
|
|
20411
20581
|
if (input.length >= PASTE_CHAR_THRESHOLD) return true;
|
|
@@ -20422,6 +20592,9 @@ function makePastePreview(input, lines, id) {
|
|
|
20422
20592
|
function countLines(s) {
|
|
20423
20593
|
return s.split("\n").length;
|
|
20424
20594
|
}
|
|
20595
|
+
function sanitizeInput(input) {
|
|
20596
|
+
return input.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "").replace(/\t/g, " ");
|
|
20597
|
+
}
|
|
20425
20598
|
function findWordBoundaryForward(text, pos) {
|
|
20426
20599
|
while (pos < text.length && /\w/.test(text[pos])) pos++;
|
|
20427
20600
|
while (pos < text.length && !/\w/.test(text[pos])) pos++;
|
|
@@ -20459,13 +20632,51 @@ function CustomTextInput({
|
|
|
20459
20632
|
};
|
|
20460
20633
|
const pastesRef = useRef(/* @__PURE__ */ new Map());
|
|
20461
20634
|
const pasteCounterRef = useRef(0);
|
|
20635
|
+
const prevValueRef = useRef(value);
|
|
20636
|
+
const cursorOffsetRef = useRef(cursorOffset);
|
|
20637
|
+
cursorOffsetRef.current = cursorOffset;
|
|
20462
20638
|
useEffect3(() => {
|
|
20463
20639
|
if (!focus) return;
|
|
20464
|
-
const
|
|
20465
|
-
|
|
20640
|
+
const prevValue = prevValueRef.current;
|
|
20641
|
+
prevValueRef.current = value;
|
|
20642
|
+
if (value === prevValue) return;
|
|
20643
|
+
const currentCursor = cursorOffsetRef.current;
|
|
20644
|
+
if (currentCursor === prevValue.length) {
|
|
20645
|
+
if (currentCursor !== value.length) {
|
|
20646
|
+
setCursorOffset(value.length);
|
|
20647
|
+
}
|
|
20648
|
+
return;
|
|
20649
|
+
}
|
|
20650
|
+
const next = currentCursor > value.length ? value.length : currentCursor;
|
|
20651
|
+
if (next !== currentCursor) {
|
|
20466
20652
|
setCursorOffset(next);
|
|
20467
20653
|
}
|
|
20468
|
-
}, [value, focus
|
|
20654
|
+
}, [value, focus]);
|
|
20655
|
+
const handleInsert = (rawInput) => {
|
|
20656
|
+
let toInsert = sanitizeInput(rawInput);
|
|
20657
|
+
if (enablePaste && shouldTreatAsPaste(toInsert)) {
|
|
20658
|
+
const lines = countLines(toInsert);
|
|
20659
|
+
const id = ++pasteCounterRef.current;
|
|
20660
|
+
const placeholder = makePastePreview(toInsert, lines, id);
|
|
20661
|
+
pastesRef.current.set(placeholder, toInsert);
|
|
20662
|
+
toInsert = placeholder;
|
|
20663
|
+
}
|
|
20664
|
+
const nextValue = value.slice(0, cursorOffset) + toInsert + value.slice(cursorOffset);
|
|
20665
|
+
const nextCursor = cursorOffset + toInsert.length;
|
|
20666
|
+
if (nextCursor !== cursorOffset) {
|
|
20667
|
+
setCursorOffset(nextCursor);
|
|
20668
|
+
}
|
|
20669
|
+
if (nextValue !== value) {
|
|
20670
|
+
onChange(nextValue);
|
|
20671
|
+
}
|
|
20672
|
+
};
|
|
20673
|
+
usePaste(
|
|
20674
|
+
(input) => {
|
|
20675
|
+
if (!focus || !enablePaste) return;
|
|
20676
|
+
handleInsert(input);
|
|
20677
|
+
},
|
|
20678
|
+
{ isActive: focus && enablePaste }
|
|
20679
|
+
);
|
|
20469
20680
|
useInput(
|
|
20470
20681
|
(input, key) => {
|
|
20471
20682
|
if (!focus) return;
|
|
@@ -20590,12 +20801,13 @@ function CustomTextInput({
|
|
|
20590
20801
|
didDelete = true;
|
|
20591
20802
|
nextValue = value.slice(0, cursorOffset);
|
|
20592
20803
|
} else if (input.length > 0 && !key.ctrl && !key.meta) {
|
|
20593
|
-
|
|
20594
|
-
|
|
20595
|
-
|
|
20804
|
+
const sanitized = sanitizeInput(input);
|
|
20805
|
+
let toInsert = sanitized;
|
|
20806
|
+
if (enablePaste && shouldTreatAsPaste(toInsert)) {
|
|
20807
|
+
const lines = countLines(toInsert);
|
|
20596
20808
|
const id = ++pasteCounterRef.current;
|
|
20597
|
-
const placeholder = makePastePreview(
|
|
20598
|
-
pastesRef.current.set(placeholder,
|
|
20809
|
+
const placeholder = makePastePreview(toInsert, lines, id);
|
|
20810
|
+
pastesRef.current.set(placeholder, toInsert);
|
|
20599
20811
|
toInsert = placeholder;
|
|
20600
20812
|
}
|
|
20601
20813
|
nextValue = value.slice(0, cursorOffset) + toInsert + value.slice(cursorOffset);
|
|
@@ -20617,10 +20829,9 @@ function CustomTextInput({
|
|
|
20617
20829
|
);
|
|
20618
20830
|
const displayValue = mask ? mask.repeat(value.length) : value;
|
|
20619
20831
|
let renderedValue = "";
|
|
20620
|
-
let i = 0;
|
|
20621
|
-
|
|
20832
|
+
for (let i = 0; i < displayValue.length; i++) {
|
|
20833
|
+
const char = displayValue[i];
|
|
20622
20834
|
renderedValue += i === cursorOffset ? source_default.inverse(char) : char;
|
|
20623
|
-
i++;
|
|
20624
20835
|
}
|
|
20625
20836
|
if (displayValue.length === 0) {
|
|
20626
20837
|
renderedValue = source_default.inverse(" ");
|
|
@@ -20651,7 +20862,7 @@ var init_text_input = __esm({
|
|
|
20651
20862
|
// src/ui/permission.tsx
|
|
20652
20863
|
import { useState as useState4, useCallback } from "react";
|
|
20653
20864
|
import { Box as Box7, Text as Text8, useInput as useInput2 } from "ink";
|
|
20654
|
-
import { platform as
|
|
20865
|
+
import { platform as platform5 } from "os";
|
|
20655
20866
|
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
20656
20867
|
function formatSelection(label, shortcut) {
|
|
20657
20868
|
return `${label} [${MOD_KEY}+${shortcut}]`;
|
|
@@ -20815,7 +21026,7 @@ var init_permission = __esm({
|
|
|
20815
21026
|
{ value: { decision: "deny", scope: "once" }, label: "Something else", key: 3 }
|
|
20816
21027
|
];
|
|
20817
21028
|
DENY = { decision: "deny", scope: "once" };
|
|
20818
|
-
MOD_KEY =
|
|
21029
|
+
MOD_KEY = platform5() === "darwin" ? "\u2325" : "Alt";
|
|
20819
21030
|
}
|
|
20820
21031
|
});
|
|
20821
21032
|
|
|
@@ -25707,10 +25918,10 @@ var init_inbox_modal = __esm({
|
|
|
25707
25918
|
});
|
|
25708
25919
|
|
|
25709
25920
|
// src/ui/app-helpers.ts
|
|
25710
|
-
import { execSync as
|
|
25921
|
+
import { execSync as execSync5, spawn as spawn7 } from "child_process";
|
|
25711
25922
|
import { existsSync as existsSync5, readFileSync as readFileSync4, statSync as statSync5 } from "fs";
|
|
25712
25923
|
import { join as join30 } from "path";
|
|
25713
|
-
import { platform as
|
|
25924
|
+
import { platform as platform6 } from "os";
|
|
25714
25925
|
function buildFilePickerIgnoreList(cwd) {
|
|
25715
25926
|
const hardcoded = [
|
|
25716
25927
|
// Dependencies
|
|
@@ -25829,7 +26040,7 @@ function gatewayUsageLookupFromConfig(cfg, meta) {
|
|
|
25829
26040
|
};
|
|
25830
26041
|
}
|
|
25831
26042
|
function openBrowser2(url) {
|
|
25832
|
-
const cmd =
|
|
26043
|
+
const cmd = platform6() === "darwin" ? "open" : platform6() === "win32" ? "start" : "xdg-open";
|
|
25833
26044
|
const child = spawn7(cmd, [url], { detached: true, stdio: "ignore" });
|
|
25834
26045
|
child.unref();
|
|
25835
26046
|
}
|
|
@@ -25839,7 +26050,7 @@ function detectGitHubRepo(cachedRepo) {
|
|
|
25839
26050
|
if (parts.length === 2) return { owner: parts[0], name: parts[1] };
|
|
25840
26051
|
}
|
|
25841
26052
|
try {
|
|
25842
|
-
const remoteUrl =
|
|
26053
|
+
const remoteUrl = execSync5("git remote get-url origin", { cwd: process.cwd(), encoding: "utf8" }).trim();
|
|
25843
26054
|
const httpsMatch = remoteUrl.match(/github\.com\/([^\/]+)\/([^\/]+?)(?:\.git)?$/);
|
|
25844
26055
|
if (httpsMatch) return { owner: httpsMatch[1], name: httpsMatch[2] };
|
|
25845
26056
|
const sshMatch = remoteUrl.match(/github\.com:([^\/]+)\/([^\/]+?)(?:\.git)?$/);
|
|
@@ -25850,7 +26061,7 @@ function detectGitHubRepo(cachedRepo) {
|
|
|
25850
26061
|
}
|
|
25851
26062
|
function detectGitBranch() {
|
|
25852
26063
|
try {
|
|
25853
|
-
return
|
|
26064
|
+
return execSync5("git branch --show-current", { cwd: process.cwd(), encoding: "utf8" }).trim() || null;
|
|
25854
26065
|
} catch {
|
|
25855
26066
|
return null;
|
|
25856
26067
|
}
|
|
@@ -26290,7 +26501,7 @@ var init_multi_agent_modal = __esm({
|
|
|
26290
26501
|
});
|
|
26291
26502
|
|
|
26292
26503
|
// src/hooks/recommended.ts
|
|
26293
|
-
import { platform as
|
|
26504
|
+
import { platform as platform7 } from "os";
|
|
26294
26505
|
function getRecommendedHook(id) {
|
|
26295
26506
|
return RECOMMENDED_HOOKS.find((r) => r.id === id);
|
|
26296
26507
|
}
|
|
@@ -26298,7 +26509,7 @@ var isMac, RECOMMENDED_HOOKS;
|
|
|
26298
26509
|
var init_recommended = __esm({
|
|
26299
26510
|
"src/hooks/recommended.ts"() {
|
|
26300
26511
|
"use strict";
|
|
26301
|
-
isMac =
|
|
26512
|
+
isMac = platform7() === "darwin";
|
|
26302
26513
|
RECOMMENDED_HOOKS = [
|
|
26303
26514
|
// ── Stop notifications ───────────────────────────────────────────────
|
|
26304
26515
|
{
|
|
@@ -27193,6 +27404,7 @@ var init_help_menu = __esm({
|
|
|
27193
27404
|
{ command: "/cost", description: "show cost report" },
|
|
27194
27405
|
{ command: "/model", description: "show current model" },
|
|
27195
27406
|
{ command: "/update", description: "check for updates" },
|
|
27407
|
+
{ command: "/update camouflage", description: "check for camouflage-tui updates" },
|
|
27196
27408
|
{ command: "/hello", description: "send a voice note to the creator" }
|
|
27197
27409
|
]
|
|
27198
27410
|
},
|
|
@@ -27229,42 +27441,10 @@ var init_help_menu = __esm({
|
|
|
27229
27441
|
}
|
|
27230
27442
|
});
|
|
27231
27443
|
|
|
27232
|
-
// src/ui/
|
|
27444
|
+
// src/ui/modal-host.tsx
|
|
27233
27445
|
import { Box as Box38, Text as Text39 } from "ink";
|
|
27234
27446
|
import SelectInput21 from "ink-select-input";
|
|
27235
27447
|
import { jsx as jsx40, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
27236
|
-
function PlanCompletePicker({ onPick }) {
|
|
27237
|
-
const theme = useTheme();
|
|
27238
|
-
const items = [
|
|
27239
|
-
{ label: "\u25B8 Execute this plan and accept changes (auto mode)", value: "auto", key: "auto" },
|
|
27240
|
-
{ label: "\u25B8 Start building and ask for permission (edit mode)", value: "edit", key: "edit" },
|
|
27241
|
-
{ label: "\u25B8 Continue planning / ask a question", value: "continue", key: "continue" }
|
|
27242
|
-
];
|
|
27243
|
-
return /* @__PURE__ */ jsxs38(Box38, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
27244
|
-
/* @__PURE__ */ jsx40(Text39, { color: theme.accent, bold: true, children: "Plan complete \u2014 what next?" }),
|
|
27245
|
-
/* @__PURE__ */ jsx40(Text39, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
|
|
27246
|
-
/* @__PURE__ */ jsx40(Box38, { marginTop: 1, children: /* @__PURE__ */ jsx40(
|
|
27247
|
-
SelectInput21,
|
|
27248
|
-
{
|
|
27249
|
-
items,
|
|
27250
|
-
onSelect: (item) => onPick(item.value),
|
|
27251
|
-
onHighlight: () => {
|
|
27252
|
-
}
|
|
27253
|
-
}
|
|
27254
|
-
) })
|
|
27255
|
-
] });
|
|
27256
|
-
}
|
|
27257
|
-
var init_plan_complete_picker = __esm({
|
|
27258
|
-
"src/ui/plan-complete-picker.tsx"() {
|
|
27259
|
-
"use strict";
|
|
27260
|
-
init_theme_context();
|
|
27261
|
-
}
|
|
27262
|
-
});
|
|
27263
|
-
|
|
27264
|
-
// src/ui/modal-host.tsx
|
|
27265
|
-
import { Box as Box39, Text as Text40 } from "ink";
|
|
27266
|
-
import SelectInput22 from "ink-select-input";
|
|
27267
|
-
import { jsx as jsx41, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
27268
27448
|
function ModalHost(props) {
|
|
27269
27449
|
const {
|
|
27270
27450
|
modals,
|
|
@@ -27297,7 +27477,7 @@ function ModalHost(props) {
|
|
|
27297
27477
|
onInboxOpen
|
|
27298
27478
|
} = props;
|
|
27299
27479
|
if (modals.showRemoteDashboard) {
|
|
27300
|
-
return /* @__PURE__ */
|
|
27480
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: selectedRemoteSession ? /* @__PURE__ */ jsx40(
|
|
27301
27481
|
RemoteSessionDetail,
|
|
27302
27482
|
{
|
|
27303
27483
|
session: selectedRemoteSession,
|
|
@@ -27306,7 +27486,7 @@ function ModalHost(props) {
|
|
|
27306
27486
|
void onCancelRemoteSession(session);
|
|
27307
27487
|
}
|
|
27308
27488
|
}
|
|
27309
|
-
) : /* @__PURE__ */
|
|
27489
|
+
) : /* @__PURE__ */ jsx40(
|
|
27310
27490
|
RemoteDashboard,
|
|
27311
27491
|
{
|
|
27312
27492
|
onSelect: (session) => onSelectRemoteSession(session),
|
|
@@ -27315,7 +27495,7 @@ function ModalHost(props) {
|
|
|
27315
27495
|
) }) });
|
|
27316
27496
|
}
|
|
27317
27497
|
if (modals.showInboxModal) {
|
|
27318
|
-
return /* @__PURE__ */
|
|
27498
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27319
27499
|
InboxModal,
|
|
27320
27500
|
{
|
|
27321
27501
|
onDone: () => modals.setShowInboxModal(false),
|
|
@@ -27324,7 +27504,7 @@ function ModalHost(props) {
|
|
|
27324
27504
|
) }) });
|
|
27325
27505
|
}
|
|
27326
27506
|
if (modals.showMultiAgentModal) {
|
|
27327
|
-
return /* @__PURE__ */
|
|
27507
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27328
27508
|
MultiAgentModal,
|
|
27329
27509
|
{
|
|
27330
27510
|
initial: props.multiAgentSettings ?? {},
|
|
@@ -27337,7 +27517,7 @@ function ModalHost(props) {
|
|
|
27337
27517
|
) }) });
|
|
27338
27518
|
}
|
|
27339
27519
|
if (modals.showHooksDashboard) {
|
|
27340
|
-
return /* @__PURE__ */
|
|
27520
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27341
27521
|
HooksDashboard,
|
|
27342
27522
|
{
|
|
27343
27523
|
getConfigured: props.getConfiguredHooks,
|
|
@@ -27348,7 +27528,7 @@ function ModalHost(props) {
|
|
|
27348
27528
|
) }) });
|
|
27349
27529
|
}
|
|
27350
27530
|
if (modals.showHelpMenu) {
|
|
27351
|
-
return /* @__PURE__ */
|
|
27531
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27352
27532
|
HelpMenu,
|
|
27353
27533
|
{
|
|
27354
27534
|
customCommands: customCommands.map((c) => ({ name: c.name, description: c.description })),
|
|
@@ -27362,10 +27542,10 @@ function ModalHost(props) {
|
|
|
27362
27542
|
) }) });
|
|
27363
27543
|
}
|
|
27364
27544
|
if (modals.showShellPicker) {
|
|
27365
|
-
return /* @__PURE__ */
|
|
27545
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(ShellPicker, { current: props.currentShell, onPick: props.onPickShell }) }) });
|
|
27366
27546
|
}
|
|
27367
27547
|
if (modals.showMemoryPicker) {
|
|
27368
|
-
return /* @__PURE__ */
|
|
27548
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27369
27549
|
MemoryPicker,
|
|
27370
27550
|
{
|
|
27371
27551
|
enabled: props.memoryEnabled,
|
|
@@ -27376,7 +27556,7 @@ function ModalHost(props) {
|
|
|
27376
27556
|
) }) });
|
|
27377
27557
|
}
|
|
27378
27558
|
if (modals.showGatewayPicker) {
|
|
27379
|
-
return /* @__PURE__ */
|
|
27559
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27380
27560
|
GatewayPicker,
|
|
27381
27561
|
{
|
|
27382
27562
|
gatewayId: props.gatewayId,
|
|
@@ -27389,10 +27569,10 @@ function ModalHost(props) {
|
|
|
27389
27569
|
) }) });
|
|
27390
27570
|
}
|
|
27391
27571
|
if (modals.showSkillsPicker) {
|
|
27392
|
-
return /* @__PURE__ */
|
|
27572
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(SkillsPicker, { onAction: props.onSkillsAction, onDone: props.onSkillsDone }) }) });
|
|
27393
27573
|
}
|
|
27394
27574
|
if (modals.showLspWizard) {
|
|
27395
|
-
return /* @__PURE__ */
|
|
27575
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27396
27576
|
LspWizard,
|
|
27397
27577
|
{
|
|
27398
27578
|
servers: lspServers,
|
|
@@ -27404,7 +27584,7 @@ function ModalHost(props) {
|
|
|
27404
27584
|
) }) });
|
|
27405
27585
|
}
|
|
27406
27586
|
if (modals.commandWizard) {
|
|
27407
|
-
return /* @__PURE__ */
|
|
27587
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27408
27588
|
CommandWizard,
|
|
27409
27589
|
{
|
|
27410
27590
|
mode: modals.commandWizard.mode,
|
|
@@ -27418,7 +27598,7 @@ function ModalHost(props) {
|
|
|
27418
27598
|
}
|
|
27419
27599
|
if (modals.commandPicker) {
|
|
27420
27600
|
const pickerMode = modals.commandPicker.mode;
|
|
27421
|
-
return /* @__PURE__ */
|
|
27601
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27422
27602
|
CommandPicker,
|
|
27423
27603
|
{
|
|
27424
27604
|
commands: customCommands,
|
|
@@ -27437,15 +27617,15 @@ function ModalHost(props) {
|
|
|
27437
27617
|
}
|
|
27438
27618
|
if (modals.commandToDelete) {
|
|
27439
27619
|
const cmd = modals.commandToDelete;
|
|
27440
|
-
return /* @__PURE__ */
|
|
27441
|
-
/* @__PURE__ */
|
|
27620
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsxs38(Box38, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
27621
|
+
/* @__PURE__ */ jsxs38(Text39, { color: theme.accent, bold: true, children: [
|
|
27442
27622
|
"Delete /",
|
|
27443
27623
|
cmd.name,
|
|
27444
27624
|
"?"
|
|
27445
27625
|
] }),
|
|
27446
|
-
/* @__PURE__ */
|
|
27447
|
-
/* @__PURE__ */
|
|
27448
|
-
|
|
27626
|
+
/* @__PURE__ */ jsx40(Text39, { color: theme.info.color, children: cmd.filepath }),
|
|
27627
|
+
/* @__PURE__ */ jsx40(Box38, { marginTop: 1, children: /* @__PURE__ */ jsx40(
|
|
27628
|
+
SelectInput21,
|
|
27449
27629
|
{
|
|
27450
27630
|
items: [
|
|
27451
27631
|
{ label: "Yes, delete", value: "yes", key: "yes" },
|
|
@@ -27463,7 +27643,7 @@ function ModalHost(props) {
|
|
|
27463
27643
|
] }) });
|
|
27464
27644
|
}
|
|
27465
27645
|
if (modals.showCommandList) {
|
|
27466
|
-
return /* @__PURE__ */
|
|
27646
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27467
27647
|
CommandList,
|
|
27468
27648
|
{
|
|
27469
27649
|
commands: customCommands,
|
|
@@ -27472,27 +27652,24 @@ function ModalHost(props) {
|
|
|
27472
27652
|
) }) });
|
|
27473
27653
|
}
|
|
27474
27654
|
if (modals.showThemePicker) {
|
|
27475
|
-
return /* @__PURE__ */
|
|
27655
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(ThemePicker, { themes, onPick: onPickTheme }) }) });
|
|
27476
27656
|
}
|
|
27477
27657
|
if (modals.showUiPicker) {
|
|
27478
|
-
return /* @__PURE__ */
|
|
27658
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(UiPicker, { current: currentUiEngine, onPick: onPickUi }) }) });
|
|
27479
27659
|
}
|
|
27480
27660
|
if (modals.showModelPicker) {
|
|
27481
|
-
return /* @__PURE__ */
|
|
27661
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(ModelPicker, { current: currentModel, onPick: onPickModel }) }) });
|
|
27482
27662
|
}
|
|
27483
27663
|
if (modals.showModePicker) {
|
|
27484
|
-
return /* @__PURE__ */
|
|
27485
|
-
}
|
|
27486
|
-
if (modals.showPlanCompletePicker) {
|
|
27487
|
-
return /* @__PURE__ */ jsx41(ThemeProvider, { theme, children: /* @__PURE__ */ jsx41(Box39, { flexDirection: "column", children: /* @__PURE__ */ jsx41(PlanCompletePicker, { onPick: props.onPlanCompletePick }) }) });
|
|
27664
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(ModePicker, { current: props.currentMode, onPick: props.onPickMode, multiAgentEnabled: props.multiAgentEnabled }) }) });
|
|
27488
27665
|
}
|
|
27489
27666
|
if (modals.billingChooserFor) {
|
|
27490
27667
|
const model = modals.billingChooserFor;
|
|
27491
|
-
return /* @__PURE__ */
|
|
27668
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(BillingChooser, { model, onPick: (choice) => onPickBilling(model, choice) }) }) });
|
|
27492
27669
|
}
|
|
27493
27670
|
if (modals.unifiedProbeFor) {
|
|
27494
27671
|
const model = modals.unifiedProbeFor;
|
|
27495
|
-
return /* @__PURE__ */
|
|
27672
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27496
27673
|
UnifiedBillingStatus,
|
|
27497
27674
|
{
|
|
27498
27675
|
model,
|
|
@@ -27505,7 +27682,7 @@ function ModalHost(props) {
|
|
|
27505
27682
|
}
|
|
27506
27683
|
if (modals.keyEntryFor) {
|
|
27507
27684
|
const model = modals.keyEntryFor;
|
|
27508
|
-
return /* @__PURE__ */
|
|
27685
|
+
return /* @__PURE__ */ jsx40(ThemeProvider, { theme, children: /* @__PURE__ */ jsx40(Box38, { flexDirection: "column", children: /* @__PURE__ */ jsx40(
|
|
27509
27686
|
KeyEntryModal,
|
|
27510
27687
|
{
|
|
27511
27688
|
model,
|
|
@@ -27526,7 +27703,7 @@ function ModalOverlay({
|
|
|
27526
27703
|
}) {
|
|
27527
27704
|
if (modals.limitModal) {
|
|
27528
27705
|
const m = modals.limitModal;
|
|
27529
|
-
return /* @__PURE__ */
|
|
27706
|
+
return /* @__PURE__ */ jsx40(
|
|
27530
27707
|
LimitModal,
|
|
27531
27708
|
{
|
|
27532
27709
|
limit: m.limit,
|
|
@@ -27540,7 +27717,7 @@ function ModalOverlay({
|
|
|
27540
27717
|
}
|
|
27541
27718
|
if (modals.loopModal) {
|
|
27542
27719
|
const m = modals.loopModal;
|
|
27543
|
-
return /* @__PURE__ */
|
|
27720
|
+
return /* @__PURE__ */ jsx40(
|
|
27544
27721
|
LimitModal,
|
|
27545
27722
|
{
|
|
27546
27723
|
limit: 50,
|
|
@@ -27585,7 +27762,38 @@ var init_modal_host = __esm({
|
|
|
27585
27762
|
init_multi_agent_modal();
|
|
27586
27763
|
init_hooks_dashboard();
|
|
27587
27764
|
init_help_menu();
|
|
27588
|
-
|
|
27765
|
+
}
|
|
27766
|
+
});
|
|
27767
|
+
|
|
27768
|
+
// src/ui/plan-complete-picker.tsx
|
|
27769
|
+
import { Box as Box39, Text as Text40 } from "ink";
|
|
27770
|
+
import SelectInput22 from "ink-select-input";
|
|
27771
|
+
import { jsx as jsx41, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
27772
|
+
function PlanCompletePicker({ onPick }) {
|
|
27773
|
+
const theme = useTheme();
|
|
27774
|
+
const items = [
|
|
27775
|
+
{ label: "\u25B8 Execute this plan and accept changes (auto mode)", value: "auto", key: "auto" },
|
|
27776
|
+
{ label: "\u25B8 Start building and ask for permission (edit mode)", value: "edit", key: "edit" },
|
|
27777
|
+
{ label: "\u25B8 Continue planning / ask a question", value: "continue", key: "continue" }
|
|
27778
|
+
];
|
|
27779
|
+
return /* @__PURE__ */ jsxs39(Box39, { flexDirection: "column", borderStyle: "round", borderColor: theme.accent, paddingX: 1, children: [
|
|
27780
|
+
/* @__PURE__ */ jsx41(Text40, { color: theme.accent, bold: true, children: "Plan complete \u2014 what next?" }),
|
|
27781
|
+
/* @__PURE__ */ jsx41(Text40, { color: theme.info.color, dimColor: false, children: "Arrow keys to navigate, Enter to select, Esc to cancel." }),
|
|
27782
|
+
/* @__PURE__ */ jsx41(Box39, { marginTop: 1, children: /* @__PURE__ */ jsx41(
|
|
27783
|
+
SelectInput22,
|
|
27784
|
+
{
|
|
27785
|
+
items,
|
|
27786
|
+
onSelect: (item) => onPick(item.value),
|
|
27787
|
+
onHighlight: () => {
|
|
27788
|
+
}
|
|
27789
|
+
}
|
|
27790
|
+
) })
|
|
27791
|
+
] });
|
|
27792
|
+
}
|
|
27793
|
+
var init_plan_complete_picker = __esm({
|
|
27794
|
+
"src/ui/plan-complete-picker.tsx"() {
|
|
27795
|
+
"use strict";
|
|
27796
|
+
init_theme_context();
|
|
27589
27797
|
}
|
|
27590
27798
|
});
|
|
27591
27799
|
|
|
@@ -27925,64 +28133,6 @@ var init_input_handlers = __esm({
|
|
|
27925
28133
|
}
|
|
27926
28134
|
});
|
|
27927
28135
|
|
|
27928
|
-
// src/agent/distill.ts
|
|
27929
|
-
function distillSessionPlan(messages) {
|
|
27930
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
27931
|
-
const m = messages[i];
|
|
27932
|
-
if (m?.role !== "assistant") continue;
|
|
27933
|
-
let text = "";
|
|
27934
|
-
if (typeof m.content === "string") {
|
|
27935
|
-
text = m.content;
|
|
27936
|
-
} else if (Array.isArray(m.content)) {
|
|
27937
|
-
text = m.content.filter((p) => p.type === "text").map((p) => p.text).join("\n");
|
|
27938
|
-
}
|
|
27939
|
-
text = text.trim();
|
|
27940
|
-
if (text.length > 20) {
|
|
27941
|
-
return text;
|
|
27942
|
-
}
|
|
27943
|
-
}
|
|
27944
|
-
return null;
|
|
27945
|
-
}
|
|
27946
|
-
var init_distill = __esm({
|
|
27947
|
-
"src/agent/distill.ts"() {
|
|
27948
|
-
"use strict";
|
|
27949
|
-
}
|
|
27950
|
-
});
|
|
27951
|
-
|
|
27952
|
-
// src/util/clipboard.ts
|
|
27953
|
-
import { execSync as execSync5 } from "child_process";
|
|
27954
|
-
import { platform as platform7 } from "os";
|
|
27955
|
-
function writeToClipboard(text) {
|
|
27956
|
-
const os2 = platform7();
|
|
27957
|
-
try {
|
|
27958
|
-
if (os2 === "darwin") {
|
|
27959
|
-
execSync5("pbcopy", { input: text, timeout: 5e3 });
|
|
27960
|
-
return { success: true, message: "Copied to clipboard" };
|
|
27961
|
-
}
|
|
27962
|
-
if (os2 === "win32") {
|
|
27963
|
-
execSync5("clip", { input: text, timeout: 5e3 });
|
|
27964
|
-
return { success: true, message: "Copied to clipboard" };
|
|
27965
|
-
}
|
|
27966
|
-
try {
|
|
27967
|
-
execSync5("xclip -selection clipboard", { input: text, timeout: 5e3 });
|
|
27968
|
-
return { success: true, message: "Copied to clipboard" };
|
|
27969
|
-
} catch {
|
|
27970
|
-
execSync5("xsel --clipboard --input", { input: text, timeout: 5e3 });
|
|
27971
|
-
return { success: true, message: "Copied to clipboard" };
|
|
27972
|
-
}
|
|
27973
|
-
} catch {
|
|
27974
|
-
return {
|
|
27975
|
-
success: false,
|
|
27976
|
-
message: "Clipboard not available \u2014 plan will be shown below"
|
|
27977
|
-
};
|
|
27978
|
-
}
|
|
27979
|
-
}
|
|
27980
|
-
var init_clipboard = __esm({
|
|
27981
|
-
"src/util/clipboard.ts"() {
|
|
27982
|
-
"use strict";
|
|
27983
|
-
}
|
|
27984
|
-
});
|
|
27985
|
-
|
|
27986
28136
|
// src/cost-attribution/tui-report.ts
|
|
27987
28137
|
var tui_report_exports = {};
|
|
27988
28138
|
__export(tui_report_exports, {
|
|
@@ -28066,7 +28216,7 @@ var init_tui_report = __esm({
|
|
|
28066
28216
|
|
|
28067
28217
|
// src/ui/slash-commands.ts
|
|
28068
28218
|
import { join as join32 } from "path";
|
|
28069
|
-
import { unlink as
|
|
28219
|
+
import { unlink as unlink5 } from "fs/promises";
|
|
28070
28220
|
import QRCode from "qrcode";
|
|
28071
28221
|
function dispatchSlashCommand(ctx, cmd) {
|
|
28072
28222
|
const raw = cmd.trim();
|
|
@@ -28932,8 +29082,27 @@ ${lines.join("\n")}` }]);
|
|
|
28932
29082
|
void ctx.runInit();
|
|
28933
29083
|
return true;
|
|
28934
29084
|
};
|
|
28935
|
-
handleUpdate = (ctx) => {
|
|
29085
|
+
handleUpdate = (ctx, _rest, arg) => {
|
|
28936
29086
|
const { setEvents, mkKey: mkKey2 } = ctx;
|
|
29087
|
+
if (arg === "camouflage") {
|
|
29088
|
+
void checkOptionalDependency("camouflage-tui", "beta").then((dep) => {
|
|
29089
|
+
if (dep.hasUpdate && dep.latestVersion) {
|
|
29090
|
+
setEvents((e) => [
|
|
29091
|
+
...e,
|
|
29092
|
+
{ kind: "info", key: mkKey2(), text: `camouflage-tui update available: ${dep.localVersion} \u2192 ${dep.latestVersion}` }
|
|
29093
|
+
]);
|
|
29094
|
+
setEvents((e) => [
|
|
29095
|
+
...e,
|
|
29096
|
+
{ kind: "info", key: mkKey2(), text: "run: npm update camouflage-tui" }
|
|
29097
|
+
]);
|
|
29098
|
+
} else if (dep.localVersion) {
|
|
29099
|
+
setEvents((e) => [...e, { kind: "info", key: mkKey2(), text: `camouflage-tui up to date (${dep.localVersion})` }]);
|
|
29100
|
+
} else {
|
|
29101
|
+
setEvents((e) => [...e, { kind: "info", key: mkKey2(), text: "camouflage-tui is not installed" }]);
|
|
29102
|
+
}
|
|
29103
|
+
});
|
|
29104
|
+
return true;
|
|
29105
|
+
}
|
|
28937
29106
|
void checkForUpdate(true).then((result) => {
|
|
28938
29107
|
if (result.hasUpdate) {
|
|
28939
29108
|
ctx.setHasUpdate(true);
|
|
@@ -29188,7 +29357,7 @@ project: ${projectSettingsPath(cwd)}`
|
|
|
29188
29357
|
return true;
|
|
29189
29358
|
};
|
|
29190
29359
|
handleLogout = (ctx) => {
|
|
29191
|
-
|
|
29360
|
+
unlink5(configPath()).catch(() => {
|
|
29192
29361
|
});
|
|
29193
29362
|
ctx.setEvents((e) => [
|
|
29194
29363
|
...e,
|
|
@@ -30986,6 +31155,26 @@ ${wcagWarnings.join("\n")}` }
|
|
|
30986
31155
|
]);
|
|
30987
31156
|
}
|
|
30988
31157
|
});
|
|
31158
|
+
void checkOptionalDependency("camouflage-tui", "beta").then((dep) => {
|
|
31159
|
+
if (dep.hasUpdate && dep.latestVersion) {
|
|
31160
|
+
setEvents((e) => [
|
|
31161
|
+
...e,
|
|
31162
|
+
{
|
|
31163
|
+
kind: "info",
|
|
31164
|
+
key: mkKey(),
|
|
31165
|
+
text: `camouflage-tui update available: ${dep.localVersion} \u2192 ${dep.latestVersion}`
|
|
31166
|
+
}
|
|
31167
|
+
]);
|
|
31168
|
+
setEvents((e) => [
|
|
31169
|
+
...e,
|
|
31170
|
+
{
|
|
31171
|
+
kind: "info",
|
|
31172
|
+
key: mkKey(),
|
|
31173
|
+
text: "run: npm update camouflage-tui"
|
|
31174
|
+
}
|
|
31175
|
+
]);
|
|
31176
|
+
}
|
|
31177
|
+
});
|
|
30989
31178
|
}, [cfg, initialUpdateResult]);
|
|
30990
31179
|
useEffect11(() => {
|
|
30991
31180
|
modeRef.current = mode;
|
|
@@ -31045,6 +31234,26 @@ ${wcagWarnings.join("\n")}` }
|
|
|
31045
31234
|
}
|
|
31046
31235
|
}
|
|
31047
31236
|
});
|
|
31237
|
+
void checkOptionalDependency("camouflage-tui", "beta").then((dep) => {
|
|
31238
|
+
if (dep.hasUpdate && dep.latestVersion) {
|
|
31239
|
+
setEvents((e) => [
|
|
31240
|
+
...e,
|
|
31241
|
+
{
|
|
31242
|
+
kind: "info",
|
|
31243
|
+
key: mkKey(),
|
|
31244
|
+
text: `camouflage-tui update available: ${dep.localVersion} \u2192 ${dep.latestVersion}`
|
|
31245
|
+
}
|
|
31246
|
+
]);
|
|
31247
|
+
setEvents((e) => [
|
|
31248
|
+
...e,
|
|
31249
|
+
{
|
|
31250
|
+
kind: "info",
|
|
31251
|
+
key: mkKey(),
|
|
31252
|
+
text: "run: npm update camouflage-tui"
|
|
31253
|
+
}
|
|
31254
|
+
]);
|
|
31255
|
+
}
|
|
31256
|
+
});
|
|
31048
31257
|
}, 30 * 60 * 1e3);
|
|
31049
31258
|
return () => clearInterval(id);
|
|
31050
31259
|
}, [cfg]);
|
|
@@ -31488,7 +31697,6 @@ ${wcagWarnings.join("\n")}` }
|
|
|
31488
31697
|
clearTaskTracking();
|
|
31489
31698
|
compactSuggestedRef.current = false;
|
|
31490
31699
|
updateNudgedRef.current = false;
|
|
31491
|
-
messagesRef.current.push({ role: "user", content: plan });
|
|
31492
31700
|
setEvents((e) => [
|
|
31493
31701
|
...e,
|
|
31494
31702
|
{
|
|
@@ -31501,8 +31709,10 @@ ${wcagWarnings.join("\n")}` }
|
|
|
31501
31709
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: "--- Plan ---\n" + plan }]);
|
|
31502
31710
|
}
|
|
31503
31711
|
setMode(picked);
|
|
31712
|
+
modeRef.current = picked;
|
|
31713
|
+
submitRef.current(plan);
|
|
31504
31714
|
},
|
|
31505
|
-
[mkKey, setShowPlanCompletePicker, setMode, setEvents, setUsage, setSessionUsage, setGatewayMeta, clearTaskTracking, resetSession]
|
|
31715
|
+
[mkKey, setShowPlanCompletePicker, setMode, setEvents, setUsage, setSessionUsage, setGatewayMeta, clearTaskTracking, resetSession, submitRef]
|
|
31506
31716
|
);
|
|
31507
31717
|
const handleModelPick = useCallback10(
|
|
31508
31718
|
(picked) => {
|
|
@@ -32633,8 +32843,7 @@ ${conflicts.join("\n")}` }
|
|
|
32633
32843
|
}
|
|
32634
32844
|
setEvents((e) => [...e, { kind: "info", key: mkKey(), text: `Type /skills ${action} <name> to ${action} a skill.` }]);
|
|
32635
32845
|
},
|
|
32636
|
-
onSkillsDone: () => setShowSkillsPicker(false)
|
|
32637
|
-
onPlanCompletePick: handlePlanCompletePick
|
|
32846
|
+
onSkillsDone: () => setShowSkillsPicker(false)
|
|
32638
32847
|
}
|
|
32639
32848
|
);
|
|
32640
32849
|
}
|
|
@@ -32662,7 +32871,7 @@ ${conflicts.join("\n")}` }
|
|
|
32662
32871
|
loopResolveRef.current = null;
|
|
32663
32872
|
}
|
|
32664
32873
|
}
|
|
32665
|
-
) : /* @__PURE__ */ jsxs40(Box40, { flexDirection: "column", marginTop: 1, children: [
|
|
32874
|
+
) : showPlanCompletePicker ? /* @__PURE__ */ jsx42(PlanCompletePicker, { onPick: handlePlanCompletePick }) : /* @__PURE__ */ jsxs40(Box40, { flexDirection: "column", marginTop: 1, children: [
|
|
32666
32875
|
(activeWorkers.length > 0 || coordinatorNarration) && /* @__PURE__ */ jsx42(WorkerList, { workers: activeWorkers, isSynthesizing, narration: coordinatorNarration }),
|
|
32667
32876
|
tasks.length > 0 && /* @__PURE__ */ jsx42(
|
|
32668
32877
|
TaskList,
|
|
@@ -32847,6 +33056,7 @@ var init_app = __esm({
|
|
|
32847
33056
|
init_use_picker_controller();
|
|
32848
33057
|
init_use_modal_host();
|
|
32849
33058
|
init_modal_host();
|
|
33059
|
+
init_plan_complete_picker();
|
|
32850
33060
|
init_use_session_manager();
|
|
32851
33061
|
init_use_turn_controller();
|
|
32852
33062
|
init_input_handlers();
|