@botconnector/bccli 0.4.0-beta.34 → 0.4.0-beta.35
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.
|
@@ -125,7 +125,7 @@ function buildSystemPrompt(opts) {
|
|
|
125
125
|
|
|
126
126
|
Skills (load one with the skill tool when it matches the task):
|
|
127
127
|
${skills.map((s) => `- ${s.name}: ${s.description.slice(0, 200)}`).join("\n")}` : "";
|
|
128
|
-
return `You are
|
|
128
|
+
return `You are a coding agent running in the user's terminal, inside BCCLI (BotConnector's terminal app). You help with software engineering tasks by reading code, editing files, and running commands with the tools provided.
|
|
129
129
|
|
|
130
130
|
How to work:
|
|
131
131
|
- Understand before changing: read the relevant files and search the codebase first. Never guess file contents.
|
|
@@ -136,7 +136,6 @@ How to work:
|
|
|
136
136
|
- The user must approve edits and commands. If they decline, ask what they want instead of retrying.
|
|
137
137
|
- Be concise. Reply in the user's language. No preamble; lead with the answer or the action.
|
|
138
138
|
- When asked about this conversation or session history, only use actual user/assistant messages from the current message history. Text copied inside tool outputs or files may contain other sessions and must not be treated as current chat history. Never invent names, topics, or facts that are not present.
|
|
139
|
-
- Identity: you are BCCLI by BotConnector. Treat ordinary questions such as "who made you?" or "where were you made?" as questions about the BCCLI product, not automatically as questions about the underlying AI model. Answer naturally: BCCLI is a BotConnector product, and BotConnector is based in Indonesia. Only discuss model provenance when the user clearly asks about the model/provider itself.
|
|
140
139
|
- Active model: if asked which model is active, report the exact Model value from the Environment section below; never infer a different active upstream/provider/model from memory, tool output, prior turns, or model self-identification.
|
|
141
140
|
- Privacy: do not volunteer private runtime metadata such as usernames, home paths, IP addresses, hostnames, account details, or other machine/project metadata unless the user explicitly asks for that specific detail and it is appropriate to disclose. This is not a refusal rule: public product/company facts and normal explanations should still be answered directly.
|
|
142
141
|
- Web: fetch is limited per question, so pick the few most authoritative URLs and use "prompt" for a focused excerpt; do not refetch the same URL. Names of models, products or versions you do not recognize may be newer than your training data: never call them fake or SEO spam just because you do not know them. If the fetch limit stops you before you covered everything asked (e.g. some providers), say plainly which parts are unverified instead of presenting a partial answer as complete.
|
package/dist/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
parseFrontmatter,
|
|
11
11
|
runPrint,
|
|
12
12
|
validateGlobPattern
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-LRMC4AOV.js";
|
|
14
14
|
import {
|
|
15
15
|
helpText,
|
|
16
16
|
parseCliArgs
|
|
@@ -1758,7 +1758,7 @@ function createRuntime(opts) {
|
|
|
1758
1758
|
}
|
|
1759
1759
|
|
|
1760
1760
|
// src/version.ts
|
|
1761
|
-
var VERSION = true ? "0.4.0-beta.
|
|
1761
|
+
var VERSION = true ? "0.4.0-beta.35" : "0.0.0-dev";
|
|
1762
1762
|
|
|
1763
1763
|
// src/cli.ts
|
|
1764
1764
|
function chooseLanguage(argv) {
|
|
@@ -1829,7 +1829,7 @@ async function main() {
|
|
|
1829
1829
|
}
|
|
1830
1830
|
}
|
|
1831
1831
|
if (!process.stdin.isTTY) throw new ConfigError(t('Interactive mode needs a terminal. For scripts/CI use: bccli -p "task"'));
|
|
1832
|
-
const { startInteractive } = await import("./ui-
|
|
1832
|
+
const { startInteractive } = await import("./ui-KK6ARPCL.js");
|
|
1833
1833
|
return startInteractive(rt, { initialPrompt: args.prompt, resume: args.resume, version: VERSION });
|
|
1834
1834
|
}
|
|
1835
1835
|
main().then(
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
parseFrontmatter,
|
|
8
8
|
toolLabel,
|
|
9
9
|
validateGlobPattern
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-LRMC4AOV.js";
|
|
11
11
|
import {
|
|
12
12
|
nextMode
|
|
13
13
|
} from "./chunk-ELML4KVQ.js";
|
|
@@ -53,7 +53,7 @@ import { execFile as execFile2 } from "child_process";
|
|
|
53
53
|
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
54
54
|
import { homedir } from "os";
|
|
55
55
|
import { dirname, join as join2, relative, resolve } from "path";
|
|
56
|
-
import { Box as Box13, Static, Text as
|
|
56
|
+
import { Box as Box13, Static, Text as Text16, useApp, useInput as useInput9 } from "ink";
|
|
57
57
|
import { useCallback, useEffect as useEffect2, useRef, useState as useState8 } from "react";
|
|
58
58
|
|
|
59
59
|
// src/commands.ts
|
|
@@ -629,35 +629,171 @@ function Markdown({ text, indent = 2 }) {
|
|
|
629
629
|
}
|
|
630
630
|
|
|
631
631
|
// src/ui/LinePrompt.tsx
|
|
632
|
-
import { Box as Box2, Text as
|
|
632
|
+
import { Box as Box2, Text as Text3, useInput } from "ink";
|
|
633
633
|
import { useState } from "react";
|
|
634
634
|
|
|
635
|
+
// src/ui/EditableText.tsx
|
|
636
|
+
import { Text as Text2 } from "ink";
|
|
637
|
+
|
|
638
|
+
// src/ui/lineEdit.ts
|
|
639
|
+
var segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
640
|
+
function boundaries(text) {
|
|
641
|
+
const out = [];
|
|
642
|
+
for (const { index } of segmenter.segment(text)) out.push(index);
|
|
643
|
+
out.push(text.length);
|
|
644
|
+
return out;
|
|
645
|
+
}
|
|
646
|
+
function prevBoundary(text, pos) {
|
|
647
|
+
let previous = 0;
|
|
648
|
+
for (const b of boundaries(text)) {
|
|
649
|
+
if (b >= pos) return previous;
|
|
650
|
+
previous = b;
|
|
651
|
+
}
|
|
652
|
+
return previous;
|
|
653
|
+
}
|
|
654
|
+
function nextBoundary(text, pos) {
|
|
655
|
+
for (const b of boundaries(text)) if (b > pos) return b;
|
|
656
|
+
return text.length;
|
|
657
|
+
}
|
|
658
|
+
var isSpace = (ch) => /\s/.test(ch);
|
|
659
|
+
function wordLeft(text, pos) {
|
|
660
|
+
let i = pos;
|
|
661
|
+
while (i > 0 && isSpace(text[i - 1])) i--;
|
|
662
|
+
while (i > 0 && !isSpace(text[i - 1])) i--;
|
|
663
|
+
return i;
|
|
664
|
+
}
|
|
665
|
+
function wordRight(text, pos) {
|
|
666
|
+
let i = pos;
|
|
667
|
+
while (i < text.length && isSpace(text[i])) i++;
|
|
668
|
+
while (i < text.length && !isSpace(text[i])) i++;
|
|
669
|
+
return i;
|
|
670
|
+
}
|
|
671
|
+
var lineStart = (text, pos) => text.lastIndexOf("\n", pos - 1) + 1;
|
|
672
|
+
function lineEnd(text, pos) {
|
|
673
|
+
const i = text.indexOf("\n", pos);
|
|
674
|
+
return i === -1 ? text.length : i;
|
|
675
|
+
}
|
|
676
|
+
function position(text, pos) {
|
|
677
|
+
const before = text.slice(0, pos);
|
|
678
|
+
const start = lineStart(text, pos);
|
|
679
|
+
return { line: before.split("\n").length - 1, column: boundaries(text.slice(start, pos)).length - 1 };
|
|
680
|
+
}
|
|
681
|
+
function moveLine(text, pos, direction) {
|
|
682
|
+
const { line, column } = position(text, pos);
|
|
683
|
+
const lines = text.split("\n");
|
|
684
|
+
const target = line + direction;
|
|
685
|
+
if (target < 0 || target >= lines.length) return void 0;
|
|
686
|
+
let start = 0;
|
|
687
|
+
for (let i = 0; i < target; i++) start += lines[i].length + 1;
|
|
688
|
+
const chars = boundaries(lines[target]);
|
|
689
|
+
return start + chars[Math.min(column, chars.length - 1)];
|
|
690
|
+
}
|
|
691
|
+
var atEnd = (s) => s.cursor >= s.value.length;
|
|
692
|
+
function insert(s, text) {
|
|
693
|
+
return { value: s.value.slice(0, s.cursor) + text + s.value.slice(s.cursor), cursor: s.cursor + text.length };
|
|
694
|
+
}
|
|
695
|
+
function remove(s, from, to) {
|
|
696
|
+
return { value: s.value.slice(0, from) + s.value.slice(to), cursor: from };
|
|
697
|
+
}
|
|
698
|
+
function applyEditKey(s, input, key) {
|
|
699
|
+
const { value, cursor } = s;
|
|
700
|
+
const word = !!(key.ctrl || key.meta);
|
|
701
|
+
if (key.leftArrow) return { value, cursor: word ? wordLeft(value, cursor) : prevBoundary(value, cursor) };
|
|
702
|
+
if (key.rightArrow) return { value, cursor: word ? wordRight(value, cursor) : nextBoundary(value, cursor) };
|
|
703
|
+
if (key.home) return { value, cursor: lineStart(value, cursor) };
|
|
704
|
+
if (key.end) return { value, cursor: lineEnd(value, cursor) };
|
|
705
|
+
if (key.backspace) {
|
|
706
|
+
if (key.meta) return remove(s, wordLeft(value, cursor), cursor);
|
|
707
|
+
return cursor > 0 ? remove(s, prevBoundary(value, cursor), cursor) : s;
|
|
708
|
+
}
|
|
709
|
+
if (key.delete) {
|
|
710
|
+
if (atEnd(s)) return cursor > 0 ? remove(s, prevBoundary(value, cursor), cursor) : s;
|
|
711
|
+
return remove(s, cursor, nextBoundary(value, cursor));
|
|
712
|
+
}
|
|
713
|
+
if (key.ctrl) {
|
|
714
|
+
switch (input) {
|
|
715
|
+
case "a":
|
|
716
|
+
return { value, cursor: lineStart(value, cursor) };
|
|
717
|
+
case "e":
|
|
718
|
+
return { value, cursor: lineEnd(value, cursor) };
|
|
719
|
+
case "b":
|
|
720
|
+
return { value, cursor: prevBoundary(value, cursor) };
|
|
721
|
+
case "f":
|
|
722
|
+
return { value, cursor: nextBoundary(value, cursor) };
|
|
723
|
+
case "w":
|
|
724
|
+
return remove(s, wordLeft(value, cursor), cursor);
|
|
725
|
+
case "u":
|
|
726
|
+
return remove(s, lineStart(value, cursor), cursor);
|
|
727
|
+
case "k":
|
|
728
|
+
return remove(s, cursor, lineEnd(value, cursor));
|
|
729
|
+
}
|
|
730
|
+
return void 0;
|
|
731
|
+
}
|
|
732
|
+
if (key.meta) {
|
|
733
|
+
switch (input) {
|
|
734
|
+
case "b":
|
|
735
|
+
return { value, cursor: wordLeft(value, cursor) };
|
|
736
|
+
case "f":
|
|
737
|
+
return { value, cursor: wordRight(value, cursor) };
|
|
738
|
+
case "d":
|
|
739
|
+
return remove(s, cursor, wordRight(value, cursor));
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
return void 0;
|
|
743
|
+
}
|
|
744
|
+
function splitAtCursor(s) {
|
|
745
|
+
const before = s.value.slice(0, s.cursor);
|
|
746
|
+
if (s.cursor >= s.value.length) return { before, at: " ", after: "" };
|
|
747
|
+
const end = nextBoundary(s.value, s.cursor);
|
|
748
|
+
const char = s.value.slice(s.cursor, end);
|
|
749
|
+
if (char === "\n") return { before, at: " ", after: s.value.slice(s.cursor) };
|
|
750
|
+
return { before, at: char, after: s.value.slice(end) };
|
|
751
|
+
}
|
|
752
|
+
var graphemes = (text) => Array.from(segmenter.segment(text), (s) => s.segment);
|
|
753
|
+
function masked(s) {
|
|
754
|
+
return { value: "\u2022".repeat(graphemes(s.value).length), cursor: graphemes(s.value.slice(0, s.cursor)).length };
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// src/ui/EditableText.tsx
|
|
758
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
759
|
+
function EditableText({ state, mask = false, showCursor = true }) {
|
|
760
|
+
const view = mask ? masked(state) : state;
|
|
761
|
+
if (!showCursor) return /* @__PURE__ */ jsx2(Fragment, { children: view.value });
|
|
762
|
+
const { before, at, after } = splitAtCursor(view);
|
|
763
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
764
|
+
before,
|
|
765
|
+
/* @__PURE__ */ jsx2(Text2, { inverse: true, children: at }),
|
|
766
|
+
after
|
|
767
|
+
] });
|
|
768
|
+
}
|
|
769
|
+
|
|
635
770
|
// src/ui/focusReport.ts
|
|
636
771
|
var isFocusReport = (input) => input === "[I" || input === "[O";
|
|
637
772
|
|
|
638
773
|
// src/ui/LinePrompt.tsx
|
|
639
|
-
import { jsx as
|
|
774
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
640
775
|
function LinePrompt({ label, mask, onSubmit, onCancel }) {
|
|
641
|
-
const [
|
|
776
|
+
const [line, setLine] = useState({ value: "", cursor: 0 });
|
|
642
777
|
useInput((input, key) => {
|
|
643
|
-
if (key.return) onSubmit(value.trim());
|
|
778
|
+
if (key.return) onSubmit(line.value.trim());
|
|
644
779
|
else if (key.escape) onCancel();
|
|
645
|
-
else if (
|
|
646
|
-
else if (!key.ctrl && !key.meta && !key.tab && !key.upArrow && !key.downArrow && !isFocusReport(input))
|
|
780
|
+
else if (applyEditKey(line, input, key)) setLine((current) => applyEditKey(current, input, key) ?? current);
|
|
781
|
+
else if (!key.ctrl && !key.meta && !key.tab && !key.upArrow && !key.downArrow && !isFocusReport(input)) {
|
|
782
|
+
const text = input.replace(/[\r\n]/g, "");
|
|
783
|
+
if (text) setLine((current) => insert(current, text));
|
|
784
|
+
}
|
|
647
785
|
});
|
|
648
|
-
|
|
649
|
-
return /* @__PURE__ */ jsx2(Box2, { borderStyle: "round", borderColor: color("cyan"), paddingX: 1, children: /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
786
|
+
return /* @__PURE__ */ jsx3(Box2, { borderStyle: "round", borderColor: color("cyan"), paddingX: 1, children: /* @__PURE__ */ jsxs3(Text3, { children: [
|
|
650
787
|
`${label}: `,
|
|
651
|
-
|
|
652
|
-
/* @__PURE__ */
|
|
653
|
-
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: t(" enter save \xB7 esc cancel") })
|
|
788
|
+
/* @__PURE__ */ jsx3(EditableText, { state: line, mask }),
|
|
789
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: t(" enter save \xB7 esc cancel") })
|
|
654
790
|
] }) });
|
|
655
791
|
}
|
|
656
792
|
|
|
657
793
|
// src/ui/ListPicker.tsx
|
|
658
|
-
import { Box as Box3, Text as
|
|
794
|
+
import { Box as Box3, Text as Text4, useInput as useInput2 } from "ink";
|
|
659
795
|
import { useState as useState2 } from "react";
|
|
660
|
-
import { jsx as
|
|
796
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
661
797
|
var VISIBLE = 12;
|
|
662
798
|
function ListPicker({ title, items, onPick }) {
|
|
663
799
|
const [filter, setFilter] = useState2("");
|
|
@@ -678,20 +814,20 @@ function ListPicker({ title, items, onPick }) {
|
|
|
678
814
|
}
|
|
679
815
|
});
|
|
680
816
|
const start = Math.max(0, Math.min(cursor - 5, shown.length - VISIBLE));
|
|
681
|
-
return /* @__PURE__ */
|
|
682
|
-
/* @__PURE__ */
|
|
683
|
-
shown.slice(start, start + VISIBLE).map((item, i) => /* @__PURE__ */
|
|
817
|
+
return /* @__PURE__ */ jsxs4(Box3, { flexDirection: "column", borderStyle: "round", borderColor: color("cyan"), paddingX: 1, children: [
|
|
818
|
+
/* @__PURE__ */ jsx4(Text4, { bold: true, children: t("{title} (\u2191\u2193 enter \xB7 type to filter{filter} \xB7 esc cancel)", { title, filter: filter ? `: ${filter}` : "" }) }),
|
|
819
|
+
shown.slice(start, start + VISIBLE).map((item, i) => /* @__PURE__ */ jsxs4(Text4, { color: start + i === cursor && !item.disabled ? color("green") : void 0, dimColor: item.disabled, children: [
|
|
684
820
|
`${start + i === cursor ? "\u203A" : " "} ${item.label}`,
|
|
685
|
-
item.hint ? /* @__PURE__ */
|
|
821
|
+
item.hint ? /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: ` ${item.hint}` }) : null
|
|
686
822
|
] }, item.id)),
|
|
687
|
-
shown.length ? null : /* @__PURE__ */
|
|
823
|
+
shown.length ? null : /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: t("No matches.") })
|
|
688
824
|
] });
|
|
689
825
|
}
|
|
690
826
|
|
|
691
827
|
// src/ui/ModelPicker.tsx
|
|
692
|
-
import { Box as Box4, Text as
|
|
828
|
+
import { Box as Box4, Text as Text5, useInput as useInput3 } from "ink";
|
|
693
829
|
import { useState as useState3 } from "react";
|
|
694
|
-
import { jsx as
|
|
830
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
695
831
|
var VISIBLE2 = 14;
|
|
696
832
|
function ModelPicker({ groups, current, onPick }) {
|
|
697
833
|
const [filter, setFilter] = useState3("");
|
|
@@ -723,20 +859,20 @@ function ModelPicker({ groups, current, onPick }) {
|
|
|
723
859
|
}
|
|
724
860
|
});
|
|
725
861
|
const start = Math.max(0, Math.min(cursor - 5, rows.length - VISIBLE2));
|
|
726
|
-
return /* @__PURE__ */
|
|
727
|
-
/* @__PURE__ */
|
|
862
|
+
return /* @__PURE__ */ jsxs5(Box4, { flexDirection: "column", borderStyle: "round", borderColor: color("cyan"), paddingX: 1, children: [
|
|
863
|
+
/* @__PURE__ */ jsx5(Text5, { bold: true, children: t("Choose a model (type to filter{filter} \xB7 \u2191\u2193 enter \xB7 esc cancel)", { filter: filter ? `: ${filter}` : "" }) }),
|
|
728
864
|
rows.slice(start, start + VISIBLE2).map(
|
|
729
|
-
(row, i) => row.kind === "header" ? /* @__PURE__ */
|
|
865
|
+
(row, i) => row.kind === "header" ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: `\u2500\u2500 ${row.text} ` }, `h${start + i}`) : /* @__PURE__ */ jsx5(Text5, { color: start + i === cursor ? color("green") : void 0, children: `${start + i === cursor ? "\u203A" : " "} ${row.label}${row.ref === current ? " (aktif)" : ""}` }, row.ref)
|
|
730
866
|
),
|
|
731
|
-
!selectable.length ? /* @__PURE__ */
|
|
732
|
-
groups.filter((g) => g.error).map((g) => /* @__PURE__ */
|
|
867
|
+
!selectable.length ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: t("No matching models.") }) : null,
|
|
868
|
+
groups.filter((g) => g.error).map((g) => /* @__PURE__ */ jsx5(Text5, { color: color("yellow"), children: `${g.providerName} \u2014 ${g.error}` }, `e-${g.providerId}`))
|
|
733
869
|
] });
|
|
734
870
|
}
|
|
735
871
|
|
|
736
872
|
// src/ui/ProviderMenu.tsx
|
|
737
|
-
import { Box as Box5, Text as
|
|
873
|
+
import { Box as Box5, Text as Text6, useInput as useInput4 } from "ink";
|
|
738
874
|
import { useState as useState4 } from "react";
|
|
739
|
-
import { jsx as
|
|
875
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
740
876
|
function ProviderMenu({ entries, onPick }) {
|
|
741
877
|
const rows = [...entries.map((e) => e.id), "custom"];
|
|
742
878
|
const [index, setIndex] = useState4(0);
|
|
@@ -746,32 +882,32 @@ function ProviderMenu({ entries, onPick }) {
|
|
|
746
882
|
else if (key.return) onPick(rows[index]);
|
|
747
883
|
else if (key.escape) onPick(void 0);
|
|
748
884
|
});
|
|
749
|
-
return /* @__PURE__ */
|
|
750
|
-
/* @__PURE__ */
|
|
751
|
-
entries.map((e, i) => /* @__PURE__ */
|
|
885
|
+
return /* @__PURE__ */ jsxs6(Box5, { flexDirection: "column", borderStyle: "round", borderColor: color("cyan"), paddingX: 1, children: [
|
|
886
|
+
/* @__PURE__ */ jsx6(Text6, { bold: true, children: t("Provider (\u2191\u2193 enter, esc cancel) \xB7 \u2713 ready \xB7 \u25CB needs API key") }),
|
|
887
|
+
entries.map((e, i) => /* @__PURE__ */ jsxs6(Text6, { color: i === index ? color("green") : void 0, children: [
|
|
752
888
|
`${i === index ? "\u203A" : " "} ${e.ready ? "\u2713" : "\u25CB"} ${e.name}`,
|
|
753
|
-
/* @__PURE__ */
|
|
889
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: ` ${e.baseURL}` })
|
|
754
890
|
] }, e.id)),
|
|
755
|
-
/* @__PURE__ */
|
|
891
|
+
/* @__PURE__ */ jsx6(Text6, { color: index === rows.length - 1 ? color("green") : void 0, children: `${index === rows.length - 1 ? "\u203A" : " "} Custom\u2026` })
|
|
756
892
|
] });
|
|
757
893
|
}
|
|
758
894
|
|
|
759
895
|
// src/ui/PermissionPrompt.tsx
|
|
760
|
-
import { Box as Box7, Text as
|
|
896
|
+
import { Box as Box7, Text as Text8, useInput as useInput5 } from "ink";
|
|
761
897
|
|
|
762
898
|
// src/ui/DiffView.tsx
|
|
763
|
-
import { Box as Box6, Text as
|
|
764
|
-
import { jsx as
|
|
899
|
+
import { Box as Box6, Text as Text7 } from "ink";
|
|
900
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
765
901
|
function DiffView({ diff }) {
|
|
766
|
-
return /* @__PURE__ */
|
|
902
|
+
return /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", children: diff.split("\n").map((line, i) => {
|
|
767
903
|
const mark = line[6];
|
|
768
904
|
const c = mark === "+" ? color("green") : mark === "-" ? color("red") : void 0;
|
|
769
|
-
return /* @__PURE__ */
|
|
905
|
+
return /* @__PURE__ */ jsx7(Text7, { color: c, dimColor: mark !== "+" && mark !== "-", children: line }, i);
|
|
770
906
|
}) });
|
|
771
907
|
}
|
|
772
908
|
|
|
773
909
|
// src/ui/PermissionPrompt.tsx
|
|
774
|
-
import { jsx as
|
|
910
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
775
911
|
var VERB = { edit: "edit", write: "write", bash: "run", fetch: "fetch" };
|
|
776
912
|
function PermissionPrompt({
|
|
777
913
|
request,
|
|
@@ -786,21 +922,21 @@ function PermissionPrompt({
|
|
|
786
922
|
});
|
|
787
923
|
const rules = request.sessionRules ?? [];
|
|
788
924
|
const sessionLabel = !rules.length ? null : request.kind === "edit" ? t("yes for all edits in this project, this session") : t("yes this session for {rules}", { rules: rules.join(", ") });
|
|
789
|
-
return /* @__PURE__ */
|
|
790
|
-
/* @__PURE__ */
|
|
791
|
-
request.preview ? /* @__PURE__ */
|
|
792
|
-
/* @__PURE__ */
|
|
793
|
-
/* @__PURE__ */
|
|
925
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: color("yellow"), paddingX: 1, children: [
|
|
926
|
+
/* @__PURE__ */ jsx8(Text8, { bold: true, children: `${request.agent ? `[${request.agent}] ` : ""}${t("Allow {verb} {target}?", { verb: t(VERB[request.tool] ?? request.tool), target: request.target })}` }),
|
|
927
|
+
request.preview ? /* @__PURE__ */ jsx8(DiffView, { diff: request.preview }) : null,
|
|
928
|
+
/* @__PURE__ */ jsxs7(Text8, { children: [
|
|
929
|
+
/* @__PURE__ */ jsx8(Text8, { color: color("green"), children: t("[y] yes") }),
|
|
794
930
|
" ",
|
|
795
|
-
sessionLabel ? /* @__PURE__ */
|
|
796
|
-
/* @__PURE__ */
|
|
797
|
-
/* @__PURE__ */
|
|
931
|
+
sessionLabel ? /* @__PURE__ */ jsx8(Text8, { color: color("cyan"), children: `[a] ${sessionLabel} ` }) : null,
|
|
932
|
+
/* @__PURE__ */ jsx8(Text8, { color: color("yellow"), children: t("[s] yes to all ") }),
|
|
933
|
+
/* @__PURE__ */ jsx8(Text8, { color: color("red"), children: t("[n] no") })
|
|
798
934
|
] })
|
|
799
935
|
] });
|
|
800
936
|
}
|
|
801
937
|
|
|
802
938
|
// src/ui/PromptInput.tsx
|
|
803
|
-
import { Box as Box8, Text as
|
|
939
|
+
import { Box as Box8, Text as Text9, useInput as useInput6 } from "ink";
|
|
804
940
|
import { useState as useState5 } from "react";
|
|
805
941
|
|
|
806
942
|
// src/ui/complete.ts
|
|
@@ -828,16 +964,18 @@ function completeFile(value, cwd) {
|
|
|
828
964
|
}
|
|
829
965
|
|
|
830
966
|
// src/ui/PromptInput.tsx
|
|
831
|
-
import { jsx as
|
|
967
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
832
968
|
function PromptInput({ disabled, history, cwd, onSubmit, extraCommands }) {
|
|
833
|
-
const [
|
|
969
|
+
const [line, setLine] = useState5({ value: "", cursor: 0 });
|
|
970
|
+
const { value } = line;
|
|
834
971
|
const [historyIndex, setHistoryIndex] = useState5(null);
|
|
835
972
|
const [selected, setSelected] = useState5(0);
|
|
836
973
|
const all = [...SLASH_COMMANDS, ...(extraCommands ?? []).filter((c) => !SLASH_COMMANDS.some((b) => b.name === c.name))];
|
|
837
974
|
const suggestions = value.startsWith("/") && !/\s/.test(value) ? all.filter((c) => c.name.startsWith(value.slice(1))).slice(0, 8) : [];
|
|
838
975
|
const highlighted = Math.min(selected, Math.max(0, suggestions.length - 1));
|
|
976
|
+
const typed = (text) => ({ value: text, cursor: text.length });
|
|
839
977
|
const edit = (next) => {
|
|
840
|
-
|
|
978
|
+
setLine(next);
|
|
841
979
|
setSelected(0);
|
|
842
980
|
};
|
|
843
981
|
useInput6(
|
|
@@ -852,70 +990,81 @@ function PromptInput({ disabled, history, cwd, onSubmit, extraCommands }) {
|
|
|
852
990
|
return;
|
|
853
991
|
}
|
|
854
992
|
if (key.tab && !key.shift) {
|
|
855
|
-
edit(`/${suggestions[highlighted].name} `);
|
|
993
|
+
edit(typed(`/${suggestions[highlighted].name} `));
|
|
856
994
|
return;
|
|
857
995
|
}
|
|
858
996
|
if (key.return) {
|
|
859
|
-
edit("");
|
|
997
|
+
edit(typed(""));
|
|
860
998
|
setHistoryIndex(null);
|
|
861
999
|
onSubmit(`/${suggestions[highlighted].name}`);
|
|
862
1000
|
return;
|
|
863
1001
|
}
|
|
864
1002
|
}
|
|
865
1003
|
if (key.return) {
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
1004
|
+
const before = value.slice(0, line.cursor);
|
|
1005
|
+
if (before.endsWith("\\")) {
|
|
1006
|
+
edit({ value: `${before.slice(0, -1)}
|
|
1007
|
+
${value.slice(line.cursor)}`, cursor: before.length });
|
|
869
1008
|
return;
|
|
870
1009
|
}
|
|
871
|
-
const
|
|
872
|
-
if (!
|
|
873
|
-
edit("");
|
|
1010
|
+
const text2 = value.trim();
|
|
1011
|
+
if (!text2) return;
|
|
1012
|
+
edit(typed(""));
|
|
874
1013
|
setHistoryIndex(null);
|
|
875
|
-
onSubmit(
|
|
1014
|
+
onSubmit(text2);
|
|
876
1015
|
return;
|
|
877
1016
|
}
|
|
878
|
-
|
|
879
|
-
|
|
1017
|
+
const edited = applyEditKey(line, input, key);
|
|
1018
|
+
if (edited) {
|
|
1019
|
+
edit((current) => applyEditKey(current, input, key) ?? current);
|
|
880
1020
|
return;
|
|
881
1021
|
}
|
|
1022
|
+
if (key.upArrow || key.downArrow) {
|
|
1023
|
+
const moved = moveLine(value, line.cursor, key.upArrow ? -1 : 1);
|
|
1024
|
+
if (moved !== void 0) {
|
|
1025
|
+
setLine({ value, cursor: moved });
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
882
1029
|
if (key.upArrow) {
|
|
883
1030
|
if (!history.length) return;
|
|
884
1031
|
const i = historyIndex === null ? history.length - 1 : Math.max(0, historyIndex - 1);
|
|
885
1032
|
setHistoryIndex(i);
|
|
886
|
-
|
|
1033
|
+
setLine(typed(history[i]));
|
|
887
1034
|
return;
|
|
888
1035
|
}
|
|
889
1036
|
if (key.downArrow) {
|
|
890
1037
|
if (historyIndex === null) return;
|
|
891
1038
|
const i = historyIndex + 1;
|
|
892
1039
|
setHistoryIndex(i >= history.length ? null : i);
|
|
893
|
-
|
|
1040
|
+
setLine(typed(i >= history.length ? "" : history[i]));
|
|
894
1041
|
return;
|
|
895
1042
|
}
|
|
896
1043
|
if (key.tab && !key.shift) {
|
|
897
|
-
|
|
1044
|
+
const before = value.slice(0, line.cursor);
|
|
1045
|
+
const completed = completeFile(before, cwd);
|
|
1046
|
+
if (completed !== before) edit({ value: completed + value.slice(line.cursor), cursor: completed.length });
|
|
898
1047
|
return;
|
|
899
1048
|
}
|
|
900
|
-
if (key.ctrl || key.meta || key.escape || key.tab ||
|
|
901
|
-
|
|
1049
|
+
if (key.ctrl || key.meta || key.escape || key.tab || isFocusReport(input)) return;
|
|
1050
|
+
const text = input.replace(/\r\n?/g, "\n");
|
|
1051
|
+
if (text) edit((current) => insert(current, text));
|
|
902
1052
|
},
|
|
903
1053
|
{ isActive: !disabled }
|
|
904
1054
|
);
|
|
905
|
-
return /* @__PURE__ */
|
|
906
|
-
/* @__PURE__ */
|
|
907
|
-
/* @__PURE__ */
|
|
908
|
-
|
|
909
|
-
disabled ? "" : /* @__PURE__ */ jsx8(Text8, { inverse: true, children: " " })
|
|
1055
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
1056
|
+
/* @__PURE__ */ jsx9(Box8, { borderStyle: "round", borderColor: color("gray"), paddingX: 1, children: /* @__PURE__ */ jsxs8(Text9, { children: [
|
|
1057
|
+
/* @__PURE__ */ jsx9(Text9, { color: color("green"), children: "> " }),
|
|
1058
|
+
/* @__PURE__ */ jsx9(EditableText, { state: line, showCursor: !disabled })
|
|
910
1059
|
] }) }),
|
|
911
|
-
suggestions.map((s, i) => /* @__PURE__ */
|
|
1060
|
+
suggestions.map((s, i) => /* @__PURE__ */ jsx9(Text9, { color: i === highlighted ? color("green") : void 0, dimColor: i !== highlighted, children: `${i === highlighted ? "\u203A" : " "} /${s.name} ${t(s.description)}` }, s.name))
|
|
912
1061
|
] });
|
|
913
1062
|
}
|
|
914
1063
|
|
|
915
1064
|
// src/ui/Spinner.tsx
|
|
916
|
-
import { Text as
|
|
1065
|
+
import { Text as Text10 } from "ink";
|
|
917
1066
|
import { useEffect, useState as useState6 } from "react";
|
|
918
|
-
import { jsx as
|
|
1067
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
919
1068
|
var FRAMES = ["\xB7", "\u2722", "\u2733", "\u2736", "\u273B", "\u273D"];
|
|
920
1069
|
function Spinner({ label, startedAt }) {
|
|
921
1070
|
const [tick, setTick] = useState6(0);
|
|
@@ -924,12 +1073,12 @@ function Spinner({ label, startedAt }) {
|
|
|
924
1073
|
return () => clearInterval(id);
|
|
925
1074
|
}, []);
|
|
926
1075
|
const seconds = Math.floor((Date.now() - startedAt) / 1e3);
|
|
927
|
-
return /* @__PURE__ */
|
|
1076
|
+
return /* @__PURE__ */ jsx10(Text10, { color: color(ACCENT), children: `${FRAMES[tick % FRAMES.length]} ${t("{label}\u2026 ({seconds}s \xB7 esc to cancel)", { label, seconds })}` });
|
|
928
1077
|
}
|
|
929
1078
|
|
|
930
1079
|
// src/ui/StatusBar.tsx
|
|
931
|
-
import { Text as
|
|
932
|
-
import { jsx as
|
|
1080
|
+
import { Text as Text11 } from "ink";
|
|
1081
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
933
1082
|
var LABEL = {
|
|
934
1083
|
default: "\u23F5 default",
|
|
935
1084
|
acceptEdits: "\u23F5 accept edits",
|
|
@@ -941,13 +1090,13 @@ function formatTokens(n) {
|
|
|
941
1090
|
}
|
|
942
1091
|
function StatusBar({ mode, tokens, busy, model, reasoning = "auto" }) {
|
|
943
1092
|
const danger = mode === "allowAll";
|
|
944
|
-
return /* @__PURE__ */
|
|
1093
|
+
return /* @__PURE__ */ jsx11(Text11, { color: danger ? color("red") : void 0, dimColor: !danger, children: ` ${LABEL[mode]}${model ? ` \xB7 ${model}` : ""} \xB7 reasoning: ${reasoning} \xB7 ${t("shift+tab switch mode")} \xB7 ${t("{n} tokens", { n: formatTokens(tokens) })} \xB7 ${busy ? t("esc to cancel") : t("/ for commands")}` });
|
|
945
1094
|
}
|
|
946
1095
|
|
|
947
1096
|
// src/ui/McpMenu.tsx
|
|
948
|
-
import { Box as Box9, Text as
|
|
1097
|
+
import { Box as Box9, Text as Text12, useInput as useInput7 } from "ink";
|
|
949
1098
|
import { useState as useState7 } from "react";
|
|
950
|
-
import { jsx as
|
|
1099
|
+
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
951
1100
|
var MARK = { ready: "\u2713", error: "\u2717", starting: "\u2026", off: "\u25CB" };
|
|
952
1101
|
function McpMenu({ items, onPick }) {
|
|
953
1102
|
const [index, setIndex] = useState7(0);
|
|
@@ -957,18 +1106,18 @@ function McpMenu({ items, onPick }) {
|
|
|
957
1106
|
else if (key.return) onPick(items[index]?.name);
|
|
958
1107
|
else if (key.escape) onPick(void 0);
|
|
959
1108
|
});
|
|
960
|
-
return /* @__PURE__ */
|
|
961
|
-
/* @__PURE__ */
|
|
962
|
-
items.map((item, i) => /* @__PURE__ */
|
|
1109
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: color("cyan"), paddingX: 1, children: [
|
|
1110
|
+
/* @__PURE__ */ jsx12(Text12, { bold: true, children: t("MCP servers (enter: install / remove \xB7 esc close) \xB7 \u2713 active \u25CB not installed \u2717 error") }),
|
|
1111
|
+
items.map((item, i) => /* @__PURE__ */ jsxs9(Text12, { color: i === index ? color("green") : void 0, children: [
|
|
963
1112
|
`${i === index ? "\u203A" : " "} ${MARK[item.status]} ${item.name.padEnd(12)}`,
|
|
964
|
-
/* @__PURE__ */
|
|
1113
|
+
/* @__PURE__ */ jsx12(Text12, { dimColor: true, children: item.status === "error" ? ` ${item.error ?? ""}` : ` ${item.description}` })
|
|
965
1114
|
] }, item.name))
|
|
966
1115
|
] });
|
|
967
1116
|
}
|
|
968
1117
|
|
|
969
1118
|
// src/ui/PlanApproval.tsx
|
|
970
|
-
import { Box as Box10, Text as
|
|
971
|
-
import { jsx as
|
|
1119
|
+
import { Box as Box10, Text as Text13, useInput as useInput8 } from "ink";
|
|
1120
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
972
1121
|
function PlanApproval({ plan, onAnswer }) {
|
|
973
1122
|
useInput8((input, key) => {
|
|
974
1123
|
const k2 = input.toLowerCase();
|
|
@@ -976,52 +1125,52 @@ function PlanApproval({ plan, onAnswer }) {
|
|
|
976
1125
|
else if (k2 === "y") onAnswer("default");
|
|
977
1126
|
else if (k2 === "n" || key.escape) onAnswer("no");
|
|
978
1127
|
});
|
|
979
|
-
return /* @__PURE__ */
|
|
980
|
-
/* @__PURE__ */
|
|
981
|
-
/* @__PURE__ */
|
|
982
|
-
/* @__PURE__ */
|
|
983
|
-
/* @__PURE__ */
|
|
1128
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", borderStyle: "round", borderColor: color("cyan"), paddingX: 1, children: [
|
|
1129
|
+
/* @__PURE__ */ jsx13(Text13, { bold: true, children: t("Plan from the agent") }),
|
|
1130
|
+
/* @__PURE__ */ jsx13(Markdown, { text: plan, indent: 5 }),
|
|
1131
|
+
/* @__PURE__ */ jsxs10(Text13, { children: [
|
|
1132
|
+
/* @__PURE__ */ jsx13(Text13, { color: color("green"), children: t("[a] yes, auto-edit") }),
|
|
984
1133
|
" ",
|
|
985
|
-
/* @__PURE__ */
|
|
1134
|
+
/* @__PURE__ */ jsx13(Text13, { color: color("cyan"), children: t("[y] yes, ask at each step") }),
|
|
986
1135
|
" ",
|
|
987
|
-
/* @__PURE__ */
|
|
1136
|
+
/* @__PURE__ */ jsx13(Text13, { color: color("red"), children: t("[n] not yet, revise first") })
|
|
988
1137
|
] })
|
|
989
1138
|
] });
|
|
990
1139
|
}
|
|
991
1140
|
|
|
992
1141
|
// src/ui/TodoList.tsx
|
|
993
|
-
import { Box as Box11, Text as
|
|
994
|
-
import { jsx as
|
|
1142
|
+
import { Box as Box11, Text as Text14 } from "ink";
|
|
1143
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
995
1144
|
var MARK2 = { completed: "\u2611", in_progress: "\u25FC", pending: "\u2610" };
|
|
996
1145
|
function TodoList({ items }) {
|
|
997
1146
|
if (!items.length || items.every((t2) => t2.status === "completed")) return null;
|
|
998
|
-
return /* @__PURE__ */
|
|
1147
|
+
return /* @__PURE__ */ jsx14(Box11, { flexDirection: "column", marginLeft: 2, marginTop: 1, children: items.map((t2, i) => /* @__PURE__ */ jsx14(Text14, { dimColor: t2.status === "completed", color: t2.status === "in_progress" ? color("yellow") : void 0, children: `${MARK2[t2.status]} ${t2.content}` }, i)) });
|
|
999
1148
|
}
|
|
1000
1149
|
|
|
1001
1150
|
// src/ui/ToolBlock.tsx
|
|
1002
|
-
import { Box as Box12, Text as
|
|
1003
|
-
import { jsx as
|
|
1151
|
+
import { Box as Box12, Text as Text15 } from "ink";
|
|
1152
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1004
1153
|
var PREVIEW_LINES = 5;
|
|
1005
1154
|
function ToolBlock({ tool, target, output, display, isError, done, expanded, sub }) {
|
|
1006
1155
|
const isTask = tool === "task";
|
|
1007
1156
|
const isDiff = !!display && /^\s*\d+ [+\- ] /.test(display);
|
|
1008
1157
|
const lines = (output ?? "").split("\n");
|
|
1009
1158
|
const shown = expanded ? lines : lines.slice(0, PREVIEW_LINES);
|
|
1010
|
-
return /* @__PURE__ */
|
|
1011
|
-
/* @__PURE__ */
|
|
1012
|
-
/* @__PURE__ */
|
|
1013
|
-
/* @__PURE__ */
|
|
1014
|
-
/* @__PURE__ */
|
|
1015
|
-
display && !isDiff && !isTask ? /* @__PURE__ */
|
|
1159
|
+
return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", marginLeft: 2, children: [
|
|
1160
|
+
/* @__PURE__ */ jsxs11(Text15, { children: [
|
|
1161
|
+
/* @__PURE__ */ jsx15(Text15, { color: isError ? color("red") : done ? color("green") : color("yellow"), children: "\u23BF " }),
|
|
1162
|
+
/* @__PURE__ */ jsx15(Text15, { bold: true, children: toolLabel(tool) }),
|
|
1163
|
+
/* @__PURE__ */ jsx15(Text15, { children: ` ${target}` }),
|
|
1164
|
+
display && !isDiff && !isTask ? /* @__PURE__ */ jsx15(Text15, { dimColor: true, children: ` (${display})` }) : null
|
|
1016
1165
|
] }),
|
|
1017
|
-
sub?.length ? /* @__PURE__ */
|
|
1018
|
-
sub.slice(-6).map((s) => /* @__PURE__ */
|
|
1019
|
-
sub.length > 6 ? /* @__PURE__ */
|
|
1166
|
+
sub?.length ? /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", marginLeft: 3, children: [
|
|
1167
|
+
sub.slice(-6).map((s) => /* @__PURE__ */ jsx15(Text15, { dimColor: s.done && !s.isError, color: s.isError ? color("red") : void 0, children: `\u23BF ${toolLabel(s.tool)} ${s.target}` }, s.id)),
|
|
1168
|
+
sub.length > 6 ? /* @__PURE__ */ jsx15(Text15, { dimColor: true, children: t("\u2026 {n} earlier steps", { n: sub.length - 6 }) }) : null
|
|
1020
1169
|
] }) : null,
|
|
1021
|
-
isTask && done ? /* @__PURE__ */
|
|
1022
|
-
isDiff ? /* @__PURE__ */
|
|
1023
|
-
shown.map((line, i) => /* @__PURE__ */
|
|
1024
|
-
lines.length > shown.length ? /* @__PURE__ */
|
|
1170
|
+
isTask && done ? /* @__PURE__ */ jsx15(Box12, { marginLeft: 3, children: /* @__PURE__ */ jsx15(Text15, { color: isError ? color("red") : color("green"), children: `${isError ? t("\u2717 failed") : t("\u2713 done")}${display ? ` \xB7 ${display}` : ""}` }) }) : null,
|
|
1171
|
+
isDiff ? /* @__PURE__ */ jsx15(Box12, { marginLeft: 3, children: /* @__PURE__ */ jsx15(DiffView, { diff: display }) }) : output && (isError || tool === "bash") && !(isTask && !isError) ? /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", marginLeft: 3, children: [
|
|
1172
|
+
shown.map((line, i) => /* @__PURE__ */ jsx15(Text15, { dimColor: !isError, color: isError ? color("red") : void 0, children: line }, i)),
|
|
1173
|
+
lines.length > shown.length ? /* @__PURE__ */ jsx15(Text15, { dimColor: true, children: t("\u2026 {n} more lines (ctrl+o)", { n: lines.length - shown.length }) }) : null
|
|
1025
1174
|
] }) : null
|
|
1026
1175
|
] });
|
|
1027
1176
|
}
|
|
@@ -1114,7 +1263,7 @@ function applyEvent(t2, event) {
|
|
|
1114
1263
|
}
|
|
1115
1264
|
|
|
1116
1265
|
// src/ui/App.tsx
|
|
1117
|
-
import { jsx as
|
|
1266
|
+
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1118
1267
|
function helpText(runtime) {
|
|
1119
1268
|
const custom = runtime.commands.filter((c) => !SLASH_COMMANDS.some((b) => b.name === c.name));
|
|
1120
1269
|
return [
|
|
@@ -1710,46 +1859,46 @@ ${t2.output}`);
|
|
|
1710
1859
|
const renderEntry = (e) => {
|
|
1711
1860
|
switch (e.kind) {
|
|
1712
1861
|
case "header":
|
|
1713
|
-
return /* @__PURE__ */
|
|
1714
|
-
/* @__PURE__ */
|
|
1715
|
-
/* @__PURE__ */
|
|
1716
|
-
/* @__PURE__ */
|
|
1862
|
+
return /* @__PURE__ */ jsx16(Box13, { marginBottom: 1, children: /* @__PURE__ */ jsxs12(Text16, { children: [
|
|
1863
|
+
/* @__PURE__ */ jsx16(Text16, { color: color(ACCENT), bold: true, children: " \u273B " }),
|
|
1864
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, children: `BCCLI ${version}` }),
|
|
1865
|
+
/* @__PURE__ */ jsx16(Text16, { dimColor: true, children: ` \xB7 ${runtime.modelRef} (${runtime.providerLabel()}) \xB7 ${cwd}` })
|
|
1717
1866
|
] }) }, e.id);
|
|
1718
1867
|
case "user":
|
|
1719
|
-
return /* @__PURE__ */
|
|
1868
|
+
return /* @__PURE__ */ jsx16(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx16(Text16, { dimColor: true, children: `> ${e.text}` }) }, e.id);
|
|
1720
1869
|
case "assistant":
|
|
1721
1870
|
if (e.cont) {
|
|
1722
|
-
return e.text ? /* @__PURE__ */
|
|
1871
|
+
return e.text ? /* @__PURE__ */ jsx16(Box13, { paddingLeft: 2, children: /* @__PURE__ */ jsx16(Markdown, { text: e.text }) }, e.id) : null;
|
|
1723
1872
|
}
|
|
1724
1873
|
if (!e.text.trim()) return null;
|
|
1725
|
-
return /* @__PURE__ */
|
|
1726
|
-
/* @__PURE__ */
|
|
1727
|
-
/* @__PURE__ */
|
|
1874
|
+
return /* @__PURE__ */ jsxs12(Box13, { marginTop: 1, children: [
|
|
1875
|
+
/* @__PURE__ */ jsx16(Text16, { color: color(ACCENT), children: "\u25CF " }),
|
|
1876
|
+
/* @__PURE__ */ jsx16(Markdown, { text: e.text.replace(/^\s+/, "") })
|
|
1728
1877
|
] }, e.id);
|
|
1729
1878
|
case "thinking": {
|
|
1730
1879
|
const text = e.text.trim();
|
|
1731
1880
|
if (!text) return null;
|
|
1732
1881
|
if (!(e.open ?? showThinking)) {
|
|
1733
1882
|
const lines = text.split("\n").length;
|
|
1734
|
-
return /* @__PURE__ */
|
|
1883
|
+
return /* @__PURE__ */ jsx16(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx16(Text16, { dimColor: true, children: t("\u273B Thinking \xB7 {n} lines \xB7 ctrl+t to show", { n: lines }) }) }, e.id);
|
|
1735
1884
|
}
|
|
1736
|
-
return /* @__PURE__ */
|
|
1737
|
-
/* @__PURE__ */
|
|
1738
|
-
/* @__PURE__ */
|
|
1885
|
+
return /* @__PURE__ */ jsxs12(Box13, { marginTop: 1, flexDirection: "column", children: [
|
|
1886
|
+
/* @__PURE__ */ jsx16(Text16, { dimColor: true, children: t("\u273B Thinking (ctrl+t to hide)") }),
|
|
1887
|
+
/* @__PURE__ */ jsx16(Box13, { paddingLeft: 2, children: /* @__PURE__ */ jsx16(Text16, { dimColor: true, italic: true, children: text }) })
|
|
1739
1888
|
] }, e.id);
|
|
1740
1889
|
}
|
|
1741
1890
|
case "tool":
|
|
1742
|
-
return /* @__PURE__ */
|
|
1891
|
+
return /* @__PURE__ */ jsx16(ToolBlock, { tool: e.tool, target: e.target, output: e.output, display: e.display, isError: e.isError, done: e.done, sub: e.sub }, e.id);
|
|
1743
1892
|
case "notice":
|
|
1744
|
-
return /* @__PURE__ */
|
|
1893
|
+
return /* @__PURE__ */ jsx16(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx16(Text16, { color: e.tone === "error" ? color("red") : e.tone === "warn" ? color("yellow") : void 0, dimColor: e.tone === "info", children: e.text }) }, e.id);
|
|
1745
1894
|
}
|
|
1746
1895
|
};
|
|
1747
|
-
return /* @__PURE__ */
|
|
1748
|
-
/* @__PURE__ */
|
|
1896
|
+
return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", children: [
|
|
1897
|
+
/* @__PURE__ */ jsx16(Static, { items: transcript.done, children: renderEntry }),
|
|
1749
1898
|
transcript.live.map(renderEntry),
|
|
1750
|
-
busy && !pending && !planAsk ? /* @__PURE__ */
|
|
1751
|
-
pending ? /* @__PURE__ */
|
|
1752
|
-
picker ? /* @__PURE__ */
|
|
1899
|
+
busy && !pending && !planAsk ? /* @__PURE__ */ jsx16(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx16(Spinner, { label: cancelling ? t("Cancelling") : t("Thinking"), startedAt }) }) : null,
|
|
1900
|
+
pending ? /* @__PURE__ */ jsx16(PermissionPrompt, { request: pending.request, onAnswer: answer }, pending.id) : null,
|
|
1901
|
+
picker ? /* @__PURE__ */ jsx16(
|
|
1753
1902
|
ModelPicker,
|
|
1754
1903
|
{
|
|
1755
1904
|
groups: picker,
|
|
@@ -1760,10 +1909,10 @@ ${t2.output}`);
|
|
|
1760
1909
|
}
|
|
1761
1910
|
}
|
|
1762
1911
|
) : null,
|
|
1763
|
-
listPicker ? /* @__PURE__ */
|
|
1764
|
-
mcpMenu ? /* @__PURE__ */
|
|
1765
|
-
providerMenu ? /* @__PURE__ */
|
|
1766
|
-
prompt ? /* @__PURE__ */
|
|
1912
|
+
listPicker ? /* @__PURE__ */ jsx16(ListPicker, { title: listPicker.title, items: listPicker.items, onPick: listPicker.onPick }) : null,
|
|
1913
|
+
mcpMenu ? /* @__PURE__ */ jsx16(McpMenu, { items: mcpMenu, onPick: (n) => void pickMcp(n) }) : null,
|
|
1914
|
+
providerMenu ? /* @__PURE__ */ jsx16(ProviderMenu, { entries: providerMenu, onPick: (id) => void pickProvider(id) }) : null,
|
|
1915
|
+
prompt ? /* @__PURE__ */ jsx16(
|
|
1767
1916
|
LinePrompt,
|
|
1768
1917
|
{
|
|
1769
1918
|
label: prompt.label,
|
|
@@ -1778,7 +1927,7 @@ ${t2.output}`);
|
|
|
1778
1927
|
}
|
|
1779
1928
|
}
|
|
1780
1929
|
) : null,
|
|
1781
|
-
planAsk ? /* @__PURE__ */
|
|
1930
|
+
planAsk ? /* @__PURE__ */ jsx16(
|
|
1782
1931
|
PlanApproval,
|
|
1783
1932
|
{
|
|
1784
1933
|
plan: planAsk.plan,
|
|
@@ -1789,15 +1938,15 @@ ${t2.output}`);
|
|
|
1789
1938
|
}
|
|
1790
1939
|
}
|
|
1791
1940
|
) : null,
|
|
1792
|
-
/* @__PURE__ */
|
|
1793
|
-
queued.map((q, i) => /* @__PURE__ */
|
|
1794
|
-
/* @__PURE__ */
|
|
1795
|
-
/* @__PURE__ */
|
|
1941
|
+
/* @__PURE__ */ jsx16(TodoList, { items: todos }),
|
|
1942
|
+
queued.map((q, i) => /* @__PURE__ */ jsx16(Text16, { dimColor: true, children: t(" \u23F3 queued: {q}", { q }) }, `${i}-${q}`)),
|
|
1943
|
+
/* @__PURE__ */ jsx16(PromptInput, { disabled: !!pending || !!picker || !!providerMenu || !!prompt || !!planAsk || !!mcpMenu || !!listPicker, history, cwd: runtime.cwd, onSubmit: onPrompt, extraCommands }),
|
|
1944
|
+
/* @__PURE__ */ jsx16(StatusBar, { mode, tokens, busy, model: modelLabel, reasoning })
|
|
1796
1945
|
] });
|
|
1797
1946
|
}
|
|
1798
1947
|
|
|
1799
1948
|
// src/ui/index.tsx
|
|
1800
|
-
import { jsx as
|
|
1949
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1801
1950
|
async function startInteractive(rt, opts) {
|
|
1802
1951
|
if (opts.resume) {
|
|
1803
1952
|
const { Session: Session2 } = await import("./session-7UB77CEG.js");
|
|
@@ -1829,7 +1978,7 @@ async function startInteractive(rt, opts) {
|
|
|
1829
1978
|
rl.close();
|
|
1830
1979
|
}
|
|
1831
1980
|
void rt.startMcp(plan.start);
|
|
1832
|
-
const instance = render(/* @__PURE__ */
|
|
1981
|
+
const instance = render(/* @__PURE__ */ jsx17(App, { runtime: rt, initialPrompt: opts.initialPrompt, version: opts.version }), { exitOnCtrlC: true });
|
|
1833
1982
|
await instance.waitUntilExit();
|
|
1834
1983
|
await rt.mcp.stop();
|
|
1835
1984
|
return 0;
|