@kmugalkhod/lightcode 0.10.0 → 0.11.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/cli.js +464 -266
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -124,7 +124,7 @@ var init_logger = __esm(() => {
|
|
|
124
124
|
});
|
|
125
125
|
|
|
126
126
|
// packages/shared/src/version.ts
|
|
127
|
-
var lightcodeVersion = "0.
|
|
127
|
+
var lightcodeVersion = "0.11.0";
|
|
128
128
|
|
|
129
129
|
// packages/shared/src/index.ts
|
|
130
130
|
var productName = "Lightcode";
|
|
@@ -577,11 +577,11 @@ var init_help_overlay = __esm(() => {
|
|
|
577
577
|
init_keymap();
|
|
578
578
|
init_cli_theme();
|
|
579
579
|
screenHints = [
|
|
580
|
-
{ context: "Chat", hint: "Tab/Ctrl+T switch mode
|
|
581
|
-
{ context: "Chat", hint: "Ctrl+O expand tool output
|
|
582
|
-
{ context: "IDE", hint: "F2 IDE layout (Explorer \xB7 Editor \xB7 Chat)
|
|
583
|
-
{ context: "Copy", hint: "Ctrl+Y copy mode (\u2191/\u2193 pick, Enter copy, c code)
|
|
584
|
-
{ context: "Sessions", hint: "Enter resume
|
|
580
|
+
{ context: "Chat", hint: "Tab/Ctrl+T switch mode \xB7 @ attach files \xB7 /compact, /undo actions" },
|
|
581
|
+
{ context: "Chat", hint: "Ctrl+O expand tool output \xB7 Ctrl+R show reasoning \xB7 Enter send \xB7 Ctrl+Enter newline" },
|
|
582
|
+
{ context: "IDE", hint: "F2 IDE layout (Explorer \xB7 Editor \xB7 Chat) \xB7 Tab focus Explorer \xB7 \u2192/Enter open file \xB7 e edit, Ctrl+S save \xB7 [ ] tabs" },
|
|
583
|
+
{ context: "Copy", hint: "Ctrl+Y copy mode (\u2191/\u2193 pick, Enter copy, c code) \xB7 /copy [last|code|all]" },
|
|
584
|
+
{ context: "Sessions", hint: "Enter resume \xB7 r rename \xB7 f fork \xB7 / filter \xB7 e export (.md) \xB7 d delete" }
|
|
585
585
|
];
|
|
586
586
|
});
|
|
587
587
|
|
|
@@ -595,7 +595,7 @@ function getSlashPageRoutes(query = "") {
|
|
|
595
595
|
return getNavigationRoutes();
|
|
596
596
|
}
|
|
597
597
|
return getNavigationRoutes().filter((route) => {
|
|
598
|
-
return route.
|
|
598
|
+
return route.shortcut.replace(/^\//, "").toLowerCase().startsWith(normalizedQuery) || route.label.toLowerCase().includes(normalizedQuery);
|
|
599
599
|
});
|
|
600
600
|
}
|
|
601
601
|
function getPathFromAction(action) {
|
|
@@ -807,7 +807,7 @@ function CommandPalette({ query, setQuery, selectedIndex }) {
|
|
|
807
807
|
gap: 2,
|
|
808
808
|
children: [
|
|
809
809
|
/* @__PURE__ */ jsxDEV2(PaletteHint, {
|
|
810
|
-
text: "
|
|
810
|
+
text: "\u2191/\u2193",
|
|
811
811
|
description: "navigate"
|
|
812
812
|
}, undefined, false, undefined, this),
|
|
813
813
|
/* @__PURE__ */ jsxDEV2(PaletteHint, {
|
|
@@ -942,6 +942,33 @@ var init_command_palette = __esm(() => {
|
|
|
942
942
|
init_cli_theme();
|
|
943
943
|
});
|
|
944
944
|
|
|
945
|
+
// apps/cli/src/ui/cli-theme-capabilities.ts
|
|
946
|
+
function isUtf8Locale(env) {
|
|
947
|
+
const locale = env.LC_ALL || env.LC_CTYPE || env.LANG || "";
|
|
948
|
+
if (!locale) {
|
|
949
|
+
return true;
|
|
950
|
+
}
|
|
951
|
+
return /utf-?8/i.test(locale);
|
|
952
|
+
}
|
|
953
|
+
function detectTerminalCapabilities(env = process.env) {
|
|
954
|
+
const noColor = Boolean(env.NO_COLOR);
|
|
955
|
+
const dumbTerm = env.TERM === "dumb";
|
|
956
|
+
return {
|
|
957
|
+
color: !noColor && !dumbTerm,
|
|
958
|
+
unicode: isUtf8Locale(env),
|
|
959
|
+
reducedMotion: Boolean(env.NO_COLOR || env.LIGHTCODE_REDUCED_MOTION)
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
function resolveGlyphs(caps) {
|
|
963
|
+
return caps.unicode ? glyphs.unicode : glyphs.ascii;
|
|
964
|
+
}
|
|
965
|
+
var terminalCapabilities, activeGlyphs;
|
|
966
|
+
var init_cli_theme_capabilities = __esm(() => {
|
|
967
|
+
init_cli_theme();
|
|
968
|
+
terminalCapabilities = detectTerminalCapabilities();
|
|
969
|
+
activeGlyphs = resolveGlyphs(terminalCapabilities);
|
|
970
|
+
});
|
|
971
|
+
|
|
945
972
|
// apps/cli/src/commands/slash-page-menu.tsx
|
|
946
973
|
import { jsxDEV as jsxDEV3 } from "@opentui/react/jsx-dev-runtime";
|
|
947
974
|
function SlashPageMenu({
|
|
@@ -949,7 +976,7 @@ function SlashPageMenu({
|
|
|
949
976
|
selectedIndex,
|
|
950
977
|
routes
|
|
951
978
|
}) {
|
|
952
|
-
const normalizedQuery = query.trim();
|
|
979
|
+
const normalizedQuery = query.trim().replace(/^\//, "");
|
|
953
980
|
const isFiltering = normalizedQuery.length > 0;
|
|
954
981
|
return /* @__PURE__ */ jsxDEV3("box", {
|
|
955
982
|
width: "100%",
|
|
@@ -966,7 +993,7 @@ function SlashPageMenu({
|
|
|
966
993
|
}, undefined, false, undefined, this) : routes.map((route, index) => /* @__PURE__ */ jsxDEV3(MenuItem, {
|
|
967
994
|
route,
|
|
968
995
|
selected: index === selectedIndex
|
|
969
|
-
}, route.
|
|
996
|
+
}, route.shortcut, false, undefined, this))
|
|
970
997
|
}, undefined, false, undefined, this),
|
|
971
998
|
/* @__PURE__ */ jsxDEV3("box", {
|
|
972
999
|
flexDirection: "row",
|
|
@@ -979,22 +1006,14 @@ function SlashPageMenu({
|
|
|
979
1006
|
children: [
|
|
980
1007
|
/* @__PURE__ */ jsxDEV3("text", {
|
|
981
1008
|
fg: cliTheme.overlay.footerText,
|
|
982
|
-
children: isFiltering ? `
|
|
1009
|
+
children: isFiltering ? `"${normalizedQuery}" \xB7 ${routes.length} result${routes.length !== 1 ? "s" : ""}` : `${routes.length} page${routes.length !== 1 ? "s" : ""}`
|
|
983
1010
|
}, undefined, false, undefined, this),
|
|
984
1011
|
/* @__PURE__ */ jsxDEV3("box", {
|
|
985
1012
|
flexGrow: 1
|
|
986
1013
|
}, undefined, false, undefined, this),
|
|
987
1014
|
/* @__PURE__ */ jsxDEV3("text", {
|
|
988
1015
|
...typeRole("caption"),
|
|
989
|
-
children: "Enter open
|
|
990
|
-
}, undefined, false, undefined, this),
|
|
991
|
-
/* @__PURE__ */ jsxDEV3("text", {
|
|
992
|
-
...typeRole("emphasis"),
|
|
993
|
-
children: "Up/Down"
|
|
994
|
-
}, undefined, false, undefined, this),
|
|
995
|
-
/* @__PURE__ */ jsxDEV3("text", {
|
|
996
|
-
...typeRole("caption"),
|
|
997
|
-
children: " select | Esc close"
|
|
1016
|
+
children: "\u2191/\u2193 select \xB7 Enter open \xB7 Esc close"
|
|
998
1017
|
}, undefined, false, undefined, this)
|
|
999
1018
|
]
|
|
1000
1019
|
}, undefined, true, undefined, this)
|
|
@@ -1014,13 +1033,14 @@ function MenuItem({ route, selected }) {
|
|
|
1014
1033
|
/* @__PURE__ */ jsxDEV3("text", {
|
|
1015
1034
|
width: 2,
|
|
1016
1035
|
fg: selected ? cliTheme.overlay.selectedBorder : cliTheme.text.muted,
|
|
1017
|
-
children: selected ?
|
|
1036
|
+
children: selected ? activeGlyphs.roleUser : " "
|
|
1018
1037
|
}, undefined, false, undefined, this),
|
|
1019
1038
|
/* @__PURE__ */ jsxDEV3("box", {
|
|
1020
1039
|
backgroundColor: cliTheme.overlay.badgeBackground,
|
|
1021
1040
|
paddingX: 1,
|
|
1022
1041
|
paddingY: 0,
|
|
1023
1042
|
marginRight: 1,
|
|
1043
|
+
flexShrink: 0,
|
|
1024
1044
|
children: /* @__PURE__ */ jsxDEV3("text", {
|
|
1025
1045
|
fg: cliTheme.overlay.badgeText,
|
|
1026
1046
|
children: [
|
|
@@ -1030,12 +1050,18 @@ function MenuItem({ route, selected }) {
|
|
|
1030
1050
|
}, undefined, true, undefined, this)
|
|
1031
1051
|
}, undefined, false, undefined, this),
|
|
1032
1052
|
/* @__PURE__ */ jsxDEV3("text", {
|
|
1053
|
+
wrapMode: "none",
|
|
1054
|
+
truncate: true,
|
|
1055
|
+
flexShrink: 0,
|
|
1033
1056
|
fg: selected ? cliTheme.overlay.selectedRowText : cliTheme.text.primary,
|
|
1034
1057
|
attributes: selected ? TextAttributes.BOLD : TextAttributes.NONE,
|
|
1035
1058
|
marginRight: 2,
|
|
1036
1059
|
children: route.label
|
|
1037
1060
|
}, undefined, false, undefined, this),
|
|
1038
1061
|
/* @__PURE__ */ jsxDEV3("text", {
|
|
1062
|
+
wrapMode: "none",
|
|
1063
|
+
truncate: true,
|
|
1064
|
+
flexShrink: 1,
|
|
1039
1065
|
fg: selected ? cliTheme.overlay.selectedRowText : cliTheme.overlay.description,
|
|
1040
1066
|
children: route.description
|
|
1041
1067
|
}, undefined, false, undefined, this)
|
|
@@ -1076,6 +1102,7 @@ function EmptyState({ query }) {
|
|
|
1076
1102
|
var init_slash_page_menu = __esm(() => {
|
|
1077
1103
|
init_cli_theme();
|
|
1078
1104
|
init_cli_theme();
|
|
1105
|
+
init_cli_theme_capabilities();
|
|
1079
1106
|
});
|
|
1080
1107
|
|
|
1081
1108
|
// packages/ai/src/constants.ts
|
|
@@ -8759,7 +8786,7 @@ function filterChatSlashActions(query) {
|
|
|
8759
8786
|
if (!normalized) {
|
|
8760
8787
|
return chatSlashActions;
|
|
8761
8788
|
}
|
|
8762
|
-
return chatSlashActions.filter((action) => action.shortcut.replace(/^\//, "").toLowerCase().
|
|
8789
|
+
return chatSlashActions.filter((action) => action.shortcut.replace(/^\//, "").toLowerCase().startsWith(normalized) || action.label.toLowerCase().includes(normalized));
|
|
8763
8790
|
}
|
|
8764
8791
|
var chatSlashActions;
|
|
8765
8792
|
var init_chat_slash_actions = __esm(() => {
|
|
@@ -8814,18 +8841,27 @@ var init_chat_slash_actions = __esm(() => {
|
|
|
8814
8841
|
label: "Permission mode",
|
|
8815
8842
|
description: "Switch permission level: read-only, workspace-write, or danger-full-access",
|
|
8816
8843
|
shortcut: "/permission",
|
|
8844
|
+
availableOnHome: true,
|
|
8817
8845
|
run: async () => {}
|
|
8818
8846
|
}
|
|
8819
8847
|
];
|
|
8820
8848
|
});
|
|
8821
8849
|
|
|
8822
8850
|
// apps/cli/src/commands/slash-menu-items.ts
|
|
8823
|
-
function getSlashMenuItems(query, {
|
|
8851
|
+
function getSlashMenuItems(query, { host }) {
|
|
8824
8852
|
const routes = getSlashPageRoutes(query);
|
|
8825
|
-
if (
|
|
8853
|
+
if (host === "other") {
|
|
8826
8854
|
return routes;
|
|
8827
8855
|
}
|
|
8828
|
-
|
|
8856
|
+
const actions = filterChatSlashActions(query).filter((action) => host === "chat" || action.availableOnHome);
|
|
8857
|
+
const seenShortcuts = new Set;
|
|
8858
|
+
return [...actions, ...routes].filter((item) => {
|
|
8859
|
+
if (seenShortcuts.has(item.shortcut)) {
|
|
8860
|
+
return false;
|
|
8861
|
+
}
|
|
8862
|
+
seenShortcuts.add(item.shortcut);
|
|
8863
|
+
return true;
|
|
8864
|
+
});
|
|
8829
8865
|
}
|
|
8830
8866
|
var init_slash_menu_items = __esm(() => {
|
|
8831
8867
|
init_route_registry();
|
|
@@ -10327,7 +10363,6 @@ function ChatInteractionPopup({
|
|
|
10327
10363
|
const [customAnswer, setCustomAnswer] = useState2("");
|
|
10328
10364
|
const [validationMessage, setValidationMessage] = useState2(null);
|
|
10329
10365
|
const submitVerb = submitLabel.toLowerCase();
|
|
10330
|
-
const hintLabel = onCancel ? `Up/Down select | Enter ${submitVerb} | Esc dismiss` : `Up/Down select | Enter ${submitVerb}`;
|
|
10331
10366
|
const rows = useMemo2(() => {
|
|
10332
10367
|
const optionRows = options.map((option) => ({
|
|
10333
10368
|
value: option.value,
|
|
@@ -10348,10 +10383,18 @@ function ChatInteractionPopup({
|
|
|
10348
10383
|
}
|
|
10349
10384
|
];
|
|
10350
10385
|
}, [allowCustomResponse, options]);
|
|
10386
|
+
const inputOnly = options.length === 0 && allowCustomResponse;
|
|
10387
|
+
const visibleRows = inputOnly ? [] : rows;
|
|
10351
10388
|
const safeSelectedIndex = Math.min(selectedIndex, Math.max(rows.length - 1, 0));
|
|
10352
10389
|
const selectedRow = rows[safeSelectedIndex];
|
|
10353
10390
|
const requiresCustomResponse = Boolean(selectedRow?.isCustom || selectedRow && requireCustomResponseForValues.includes(selectedRow.value));
|
|
10354
|
-
const canShowInput =
|
|
10391
|
+
const canShowInput = inputOnly || requiresCustomResponse;
|
|
10392
|
+
const hintLabel = [
|
|
10393
|
+
visibleRows.length > 1 ? "\u2191/\u2193 select" : null,
|
|
10394
|
+
visibleRows.length > 1 ? "1-9 pick" : null,
|
|
10395
|
+
`Enter ${submitVerb}`,
|
|
10396
|
+
onCancel ? "Esc dismiss" : null
|
|
10397
|
+
].filter(Boolean).join(" \xB7 ");
|
|
10355
10398
|
const submitCurrentSelection = () => {
|
|
10356
10399
|
if (!selectedRow && !canShowInput) {
|
|
10357
10400
|
return;
|
|
@@ -10359,14 +10402,14 @@ function ChatInteractionPopup({
|
|
|
10359
10402
|
if (canShowInput) {
|
|
10360
10403
|
const answer = customAnswer.trim();
|
|
10361
10404
|
if (answer.length === 0) {
|
|
10362
|
-
setValidationMessage("
|
|
10405
|
+
setValidationMessage(selectedRow && !selectedRow.isCustom && !inputOnly ? "This choice needs a short note \u2014 type it below." : "Type an answer first, then press Enter.");
|
|
10363
10406
|
return;
|
|
10364
10407
|
}
|
|
10365
10408
|
setValidationMessage(null);
|
|
10366
10409
|
onSubmit({
|
|
10367
10410
|
answer,
|
|
10368
|
-
selectedOption: selectedRow && !selectedRow.isCustom ? selectedRow.label : undefined,
|
|
10369
|
-
selectedValue: selectedRow && !selectedRow.isCustom ? selectedRow.value : undefined,
|
|
10411
|
+
selectedOption: selectedRow && !selectedRow.isCustom && !inputOnly ? selectedRow.label : undefined,
|
|
10412
|
+
selectedValue: selectedRow && !selectedRow.isCustom && !inputOnly ? selectedRow.value : undefined,
|
|
10370
10413
|
source: selectedRow?.isCustom || !selectedRow || requiresCustomResponse ? "custom" : "option"
|
|
10371
10414
|
});
|
|
10372
10415
|
return;
|
|
@@ -10379,6 +10422,10 @@ function ChatInteractionPopup({
|
|
|
10379
10422
|
source: "option"
|
|
10380
10423
|
});
|
|
10381
10424
|
};
|
|
10425
|
+
const selectRow = (index) => {
|
|
10426
|
+
setValidationMessage(null);
|
|
10427
|
+
setSelectedIndex(Math.min(Math.max(index, 0), Math.max(rows.length - 1, 0)));
|
|
10428
|
+
};
|
|
10382
10429
|
useKeyboard((keyEvent) => {
|
|
10383
10430
|
if (rows.length === 0 && !canShowInput) {
|
|
10384
10431
|
if (isEscapeKey(keyEvent.name.toLowerCase()) && onCancel) {
|
|
@@ -10392,15 +10439,33 @@ function ChatInteractionPopup({
|
|
|
10392
10439
|
if (isDownKey(keyName)) {
|
|
10393
10440
|
keyEvent.preventDefault();
|
|
10394
10441
|
keyEvent.stopPropagation();
|
|
10395
|
-
|
|
10396
|
-
setSelectedIndex((currentIndex) => Math.min(currentIndex + 1, Math.max(rows.length - 1, 0)));
|
|
10442
|
+
selectRow(safeSelectedIndex + 1);
|
|
10397
10443
|
return;
|
|
10398
10444
|
}
|
|
10399
10445
|
if (isUpKey(keyName)) {
|
|
10400
10446
|
keyEvent.preventDefault();
|
|
10401
10447
|
keyEvent.stopPropagation();
|
|
10402
|
-
|
|
10403
|
-
|
|
10448
|
+
selectRow(safeSelectedIndex - 1);
|
|
10449
|
+
return;
|
|
10450
|
+
}
|
|
10451
|
+
if (!canShowInput && visibleRows.length > 1 && /^[1-9]$/.test(keyName)) {
|
|
10452
|
+
const index = Number(keyName) - 1;
|
|
10453
|
+
if (index < rows.length) {
|
|
10454
|
+
keyEvent.preventDefault();
|
|
10455
|
+
keyEvent.stopPropagation();
|
|
10456
|
+
selectRow(index);
|
|
10457
|
+
const row = rows[index];
|
|
10458
|
+
const needsInput = row.isCustom || requireCustomResponseForValues.includes(row.value);
|
|
10459
|
+
if (!needsInput) {
|
|
10460
|
+
setValidationMessage(null);
|
|
10461
|
+
onSubmit({
|
|
10462
|
+
answer: row.label,
|
|
10463
|
+
selectedOption: row.label,
|
|
10464
|
+
selectedValue: row.value,
|
|
10465
|
+
source: "option"
|
|
10466
|
+
});
|
|
10467
|
+
}
|
|
10468
|
+
}
|
|
10404
10469
|
return;
|
|
10405
10470
|
}
|
|
10406
10471
|
if (isEnterKey(keyName)) {
|
|
@@ -10421,23 +10486,35 @@ function ChatInteractionPopup({
|
|
|
10421
10486
|
borderStyle: borderStyleFor.modal,
|
|
10422
10487
|
borderColor: cliTheme.borders.active,
|
|
10423
10488
|
backgroundColor: cliTheme.surfaces.panel,
|
|
10424
|
-
paddingX:
|
|
10489
|
+
paddingX: 2,
|
|
10425
10490
|
paddingY: 1,
|
|
10426
10491
|
gap: 1,
|
|
10427
10492
|
children: [
|
|
10428
|
-
/* @__PURE__ */ jsxDEV6("
|
|
10429
|
-
|
|
10430
|
-
|
|
10431
|
-
|
|
10493
|
+
/* @__PURE__ */ jsxDEV6("box", {
|
|
10494
|
+
width: "100%",
|
|
10495
|
+
flexDirection: "row",
|
|
10496
|
+
justifyContent: "space-between",
|
|
10497
|
+
children: [
|
|
10498
|
+
/* @__PURE__ */ jsxDEV6("text", {
|
|
10499
|
+
...typeRole("title"),
|
|
10500
|
+
children: title
|
|
10501
|
+
}, undefined, false, undefined, this),
|
|
10502
|
+
/* @__PURE__ */ jsxDEV6("text", {
|
|
10503
|
+
fg: cliTheme.text.muted,
|
|
10504
|
+
children: submitLabel
|
|
10505
|
+
}, undefined, false, undefined, this)
|
|
10506
|
+
]
|
|
10507
|
+
}, undefined, true, undefined, this),
|
|
10432
10508
|
/* @__PURE__ */ jsxDEV6("text", {
|
|
10433
10509
|
fg: cliTheme.text.primary,
|
|
10434
10510
|
children: question
|
|
10435
10511
|
}, undefined, false, undefined, this),
|
|
10436
|
-
|
|
10512
|
+
visibleRows.length > 0 ? /* @__PURE__ */ jsxDEV6("box", {
|
|
10437
10513
|
width: "100%",
|
|
10438
10514
|
flexDirection: "column",
|
|
10439
|
-
children:
|
|
10440
|
-
const
|
|
10515
|
+
children: visibleRows.map((row, index) => {
|
|
10516
|
+
const selected = index === safeSelectedIndex;
|
|
10517
|
+
const rowColors = getOverlayRowColors(selected);
|
|
10441
10518
|
return /* @__PURE__ */ jsxDEV6("box", {
|
|
10442
10519
|
width: "100%",
|
|
10443
10520
|
flexDirection: "column",
|
|
@@ -10445,17 +10522,32 @@ function ChatInteractionPopup({
|
|
|
10445
10522
|
backgroundColor: rowColors.backgroundColor,
|
|
10446
10523
|
children: [
|
|
10447
10524
|
/* @__PURE__ */ jsxDEV6("text", {
|
|
10448
|
-
fg: rowColors.primaryTextColor,
|
|
10525
|
+
fg: selected ? cliTheme.accent.primary : rowColors.primaryTextColor,
|
|
10449
10526
|
children: [
|
|
10450
|
-
|
|
10451
|
-
|
|
10452
|
-
|
|
10527
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
10528
|
+
children: selected ? `${activeGlyphs.roleUser} ` : " "
|
|
10529
|
+
}, undefined, false, undefined, this),
|
|
10530
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
10531
|
+
fg: selected ? cliTheme.accent.primary : cliTheme.text.muted,
|
|
10532
|
+
children: [
|
|
10533
|
+
index + 1,
|
|
10534
|
+
".",
|
|
10535
|
+
" "
|
|
10536
|
+
]
|
|
10537
|
+
}, undefined, true, undefined, this),
|
|
10538
|
+
/* @__PURE__ */ jsxDEV6("span", {
|
|
10539
|
+
fg: rowColors.primaryTextColor,
|
|
10540
|
+
children: row.label
|
|
10541
|
+
}, undefined, false, undefined, this)
|
|
10453
10542
|
]
|
|
10454
10543
|
}, undefined, true, undefined, this),
|
|
10455
10544
|
row.description ? /* @__PURE__ */ jsxDEV6("text", {
|
|
10456
|
-
|
|
10457
|
-
children:
|
|
10458
|
-
|
|
10545
|
+
fg: rowColors.secondaryTextColor,
|
|
10546
|
+
children: [
|
|
10547
|
+
" ",
|
|
10548
|
+
row.description
|
|
10549
|
+
]
|
|
10550
|
+
}, undefined, true, undefined, this) : null
|
|
10459
10551
|
]
|
|
10460
10552
|
}, row.value, true, undefined, this);
|
|
10461
10553
|
})
|
|
@@ -10465,16 +10557,19 @@ function ChatInteractionPopup({
|
|
|
10465
10557
|
flexDirection: "column",
|
|
10466
10558
|
gap: 1,
|
|
10467
10559
|
children: [
|
|
10468
|
-
selectedRow && !selectedRow.isCustom ? /* @__PURE__ */ jsxDEV6("text", {
|
|
10560
|
+
selectedRow && !selectedRow.isCustom && !inputOnly ? /* @__PURE__ */ jsxDEV6("text", {
|
|
10469
10561
|
fg: cliTheme.text.secondary,
|
|
10470
|
-
children: "
|
|
10562
|
+
children: "Add a short note to continue:"
|
|
10471
10563
|
}, undefined, false, undefined, this) : null,
|
|
10472
10564
|
/* @__PURE__ */ jsxDEV6("input", {
|
|
10473
10565
|
value: customAnswer,
|
|
10474
|
-
|
|
10566
|
+
onInput: (value) => {
|
|
10475
10567
|
setValidationMessage(null);
|
|
10476
10568
|
setCustomAnswer(value ?? "");
|
|
10477
10569
|
},
|
|
10570
|
+
onSubmit: () => {
|
|
10571
|
+
submitCurrentSelection();
|
|
10572
|
+
},
|
|
10478
10573
|
placeholder,
|
|
10479
10574
|
width: "100%",
|
|
10480
10575
|
focused: true,
|
|
@@ -10487,27 +10582,17 @@ function ChatInteractionPopup({
|
|
|
10487
10582
|
fg: cliTheme.semantic.warning,
|
|
10488
10583
|
children: validationMessage
|
|
10489
10584
|
}, undefined, false, undefined, this) : null,
|
|
10490
|
-
/* @__PURE__ */ jsxDEV6("
|
|
10491
|
-
|
|
10492
|
-
|
|
10493
|
-
|
|
10494
|
-
children: [
|
|
10495
|
-
/* @__PURE__ */ jsxDEV6("text", {
|
|
10496
|
-
...typeRole("caption"),
|
|
10497
|
-
children: hintLabel
|
|
10498
|
-
}, undefined, false, undefined, this),
|
|
10499
|
-
/* @__PURE__ */ jsxDEV6("text", {
|
|
10500
|
-
fg: cliTheme.text.secondary,
|
|
10501
|
-
children: submitLabel
|
|
10502
|
-
}, undefined, false, undefined, this)
|
|
10503
|
-
]
|
|
10504
|
-
}, undefined, true, undefined, this)
|
|
10585
|
+
/* @__PURE__ */ jsxDEV6("text", {
|
|
10586
|
+
...typeRole("caption"),
|
|
10587
|
+
children: hintLabel
|
|
10588
|
+
}, undefined, false, undefined, this)
|
|
10505
10589
|
]
|
|
10506
10590
|
}, undefined, true, undefined, this);
|
|
10507
10591
|
}
|
|
10508
10592
|
var customOptionValue = "__custom_answer__";
|
|
10509
10593
|
var init_chat_interaction_popup = __esm(() => {
|
|
10510
10594
|
init_cli_theme();
|
|
10595
|
+
init_cli_theme_capabilities();
|
|
10511
10596
|
});
|
|
10512
10597
|
|
|
10513
10598
|
// apps/cli/src/components/chat/chat-message-error-part.tsx
|
|
@@ -10850,33 +10935,6 @@ var init_chat_message_text_part = __esm(() => {
|
|
|
10850
10935
|
markdownSyntaxStyle = codeSyntaxStyle;
|
|
10851
10936
|
});
|
|
10852
10937
|
|
|
10853
|
-
// apps/cli/src/ui/cli-theme-capabilities.ts
|
|
10854
|
-
function isUtf8Locale(env) {
|
|
10855
|
-
const locale = env.LC_ALL || env.LC_CTYPE || env.LANG || "";
|
|
10856
|
-
if (!locale) {
|
|
10857
|
-
return true;
|
|
10858
|
-
}
|
|
10859
|
-
return /utf-?8/i.test(locale);
|
|
10860
|
-
}
|
|
10861
|
-
function detectTerminalCapabilities(env = process.env) {
|
|
10862
|
-
const noColor = Boolean(env.NO_COLOR);
|
|
10863
|
-
const dumbTerm = env.TERM === "dumb";
|
|
10864
|
-
return {
|
|
10865
|
-
color: !noColor && !dumbTerm,
|
|
10866
|
-
unicode: isUtf8Locale(env),
|
|
10867
|
-
reducedMotion: Boolean(env.NO_COLOR || env.LIGHTCODE_REDUCED_MOTION)
|
|
10868
|
-
};
|
|
10869
|
-
}
|
|
10870
|
-
function resolveGlyphs(caps) {
|
|
10871
|
-
return caps.unicode ? glyphs.unicode : glyphs.ascii;
|
|
10872
|
-
}
|
|
10873
|
-
var terminalCapabilities, activeGlyphs;
|
|
10874
|
-
var init_cli_theme_capabilities = __esm(() => {
|
|
10875
|
-
init_cli_theme();
|
|
10876
|
-
terminalCapabilities = detectTerminalCapabilities();
|
|
10877
|
-
activeGlyphs = resolveGlyphs(terminalCapabilities);
|
|
10878
|
-
});
|
|
10879
|
-
|
|
10880
10938
|
// apps/cli/src/components/chat/chat-diff-card.tsx
|
|
10881
10939
|
import { jsxDEV as jsxDEV11 } from "@opentui/react/jsx-dev-runtime";
|
|
10882
10940
|
function collapseDiff(diff, maxLines) {
|
|
@@ -13404,7 +13462,6 @@ function PermissionModeSelector({
|
|
|
13404
13462
|
onClose
|
|
13405
13463
|
}) {
|
|
13406
13464
|
const [selectedIndex, setSelectedIndex] = useState11(0);
|
|
13407
|
-
const [keyboardActive, setKeyboardActive] = useState11(false);
|
|
13408
13465
|
useEffect7(() => {
|
|
13409
13466
|
if (currentMode) {
|
|
13410
13467
|
const currentIndex = permissionModes.findIndex((m) => m.mode === currentMode);
|
|
@@ -13421,17 +13478,21 @@ function PermissionModeSelector({
|
|
|
13421
13478
|
onClose();
|
|
13422
13479
|
return;
|
|
13423
13480
|
}
|
|
13481
|
+
if (keyName === "tab" || keyEvent.sequence === "\t") {
|
|
13482
|
+
keyEvent.preventDefault();
|
|
13483
|
+
keyEvent.stopPropagation();
|
|
13484
|
+
setSelectedIndex((current) => keyEvent.shift ? (current - 1 + permissionModes.length) % permissionModes.length : (current + 1) % permissionModes.length);
|
|
13485
|
+
return;
|
|
13486
|
+
}
|
|
13424
13487
|
if (isDownKey(keyName)) {
|
|
13425
13488
|
keyEvent.preventDefault();
|
|
13426
13489
|
keyEvent.stopPropagation();
|
|
13427
|
-
setKeyboardActive(true);
|
|
13428
13490
|
setSelectedIndex((current) => Math.min(current + 1, permissionModes.length - 1));
|
|
13429
13491
|
return;
|
|
13430
13492
|
}
|
|
13431
13493
|
if (isUpKey(keyName)) {
|
|
13432
13494
|
keyEvent.preventDefault();
|
|
13433
13495
|
keyEvent.stopPropagation();
|
|
13434
|
-
setKeyboardActive(true);
|
|
13435
13496
|
setSelectedIndex((current) => Math.max(current - 1, 0));
|
|
13436
13497
|
return;
|
|
13437
13498
|
}
|
|
@@ -13467,7 +13528,7 @@ function PermissionModeSelector({
|
|
|
13467
13528
|
}, undefined, false, undefined, this),
|
|
13468
13529
|
/* @__PURE__ */ jsxDEV21("text", {
|
|
13469
13530
|
fg: cliTheme.overlay.footerText,
|
|
13470
|
-
children: "
|
|
13531
|
+
children: "Tab/\u2191/\u2193 select \xB7 Enter confirm \xB7 Esc cancel"
|
|
13471
13532
|
}, undefined, false, undefined, this)
|
|
13472
13533
|
]
|
|
13473
13534
|
}, undefined, true, undefined, this),
|
|
@@ -13476,16 +13537,13 @@ function PermissionModeSelector({
|
|
|
13476
13537
|
paddingY: 1,
|
|
13477
13538
|
children: permissionModes.map((modeOption, index) => {
|
|
13478
13539
|
const isSelected = index === selectedIndex;
|
|
13479
|
-
const rowColors = getOverlayRowColors(isSelected
|
|
13540
|
+
const rowColors = getOverlayRowColors(isSelected);
|
|
13480
13541
|
return /* @__PURE__ */ jsxDEV21("box", {
|
|
13481
13542
|
width: "100%",
|
|
13482
13543
|
flexDirection: "column",
|
|
13483
13544
|
paddingX: 2,
|
|
13484
13545
|
paddingY: 1,
|
|
13485
13546
|
backgroundColor: rowColors.backgroundColor,
|
|
13486
|
-
borderStyle: "single",
|
|
13487
|
-
border: isSelected ? ["left"] : undefined,
|
|
13488
|
-
borderColor: isSelected ? cliTheme.accent.primary : cliTheme.overlay.border,
|
|
13489
13547
|
children: [
|
|
13490
13548
|
/* @__PURE__ */ jsxDEV21("box", {
|
|
13491
13549
|
width: "100%",
|
|
@@ -13496,7 +13554,7 @@ function PermissionModeSelector({
|
|
|
13496
13554
|
width: 3,
|
|
13497
13555
|
fg: isSelected ? cliTheme.accent.primary : cliTheme.text.muted,
|
|
13498
13556
|
attributes: TextAttributes3.BOLD,
|
|
13499
|
-
children: isSelected ?
|
|
13557
|
+
children: isSelected ? `${activeGlyphs.roleUser} ` : " "
|
|
13500
13558
|
}, undefined, false, undefined, this),
|
|
13501
13559
|
/* @__PURE__ */ jsxDEV21("text", {
|
|
13502
13560
|
fg: isSelected ? cliTheme.overlay.selectedRowText : cliTheme.text.primary,
|
|
@@ -13524,7 +13582,8 @@ function PermissionModeSelector({
|
|
|
13524
13582
|
fg: modeOption.mode === "danger-full-access" ? cliTheme.semantic.error : cliTheme.text.muted,
|
|
13525
13583
|
attributes: TextAttributes3.DIM,
|
|
13526
13584
|
children: [
|
|
13527
|
-
|
|
13585
|
+
activeGlyphs.bullet,
|
|
13586
|
+
" ",
|
|
13528
13587
|
risk
|
|
13529
13588
|
]
|
|
13530
13589
|
}, risk, true, undefined, this))
|
|
@@ -13563,6 +13622,7 @@ function PermissionModeSelector({
|
|
|
13563
13622
|
var permissionModes;
|
|
13564
13623
|
var init_permission_mode_selector = __esm(() => {
|
|
13565
13624
|
init_cli_theme();
|
|
13625
|
+
init_cli_theme_capabilities();
|
|
13566
13626
|
permissionModes = [
|
|
13567
13627
|
{
|
|
13568
13628
|
mode: "read-only",
|
|
@@ -13678,6 +13738,16 @@ function fuzzyScore(query, candidate) {
|
|
|
13678
13738
|
previousMatchIndex = foundIndex;
|
|
13679
13739
|
candidateIndex = foundIndex + 1;
|
|
13680
13740
|
}
|
|
13741
|
+
const substringIndex = normalizedCandidate.indexOf(normalizedQuery);
|
|
13742
|
+
if (substringIndex !== -1) {
|
|
13743
|
+
score += 8 + normalizedQuery.length * 2;
|
|
13744
|
+
if (substringIndex === 0 || BOUNDARY_CHARS.has(normalizedCandidate[substringIndex - 1])) {
|
|
13745
|
+
score += 4;
|
|
13746
|
+
}
|
|
13747
|
+
if (substringIndex > normalizedCandidate.lastIndexOf("/")) {
|
|
13748
|
+
score += 4;
|
|
13749
|
+
}
|
|
13750
|
+
}
|
|
13681
13751
|
return score - candidate.length / 100;
|
|
13682
13752
|
}
|
|
13683
13753
|
function fuzzyFilter(query, candidates, limit = 6) {
|
|
@@ -13863,8 +13933,11 @@ function ChatTextArea({
|
|
|
13863
13933
|
if (mentionMatches.length === 0) {
|
|
13864
13934
|
return;
|
|
13865
13935
|
}
|
|
13866
|
-
if (event.name === "tab") {
|
|
13936
|
+
if (event.name === "tab" || isEnterLike) {
|
|
13867
13937
|
event.preventDefault();
|
|
13938
|
+
if (isEnterLike) {
|
|
13939
|
+
lastManualNewlineAt.current = Date.now();
|
|
13940
|
+
}
|
|
13868
13941
|
acceptMention(mentionMatches[selectedMentionIndex]);
|
|
13869
13942
|
} else if (event.name === "down") {
|
|
13870
13943
|
event.preventDefault();
|
|
@@ -13939,11 +14012,11 @@ function ChatTextArea({
|
|
|
13939
14012
|
fg: index === selectedMentionIndex ? cliTheme.overlay.selectedRowText : cliTheme.text.secondary,
|
|
13940
14013
|
bg: index === selectedMentionIndex ? cliTheme.overlay.selectedRowBackground : undefined,
|
|
13941
14014
|
attributes: index === selectedMentionIndex ? TextAttributes4.BOLD : TextAttributes4.NONE,
|
|
13942
|
-
children: `${index === selectedMentionIndex ?
|
|
14015
|
+
children: `${index === selectedMentionIndex ? `${activeGlyphs.roleUser} ` : " "}${mentionPath}`
|
|
13943
14016
|
}, mentionPath, false, undefined, this)),
|
|
13944
14017
|
/* @__PURE__ */ jsxDEV22("text", {
|
|
13945
14018
|
...typeRole("caption"),
|
|
13946
|
-
children: "
|
|
14019
|
+
children: "\u2191/\u2193 select \xB7 Enter attach \xB7 Esc dismiss"
|
|
13947
14020
|
}, undefined, false, undefined, this)
|
|
13948
14021
|
]
|
|
13949
14022
|
}, undefined, true, undefined, this) : null,
|
|
@@ -13990,6 +14063,7 @@ var trailingMentionPattern, textareaKeyBindings;
|
|
|
13990
14063
|
var init_chat_text_area = __esm(() => {
|
|
13991
14064
|
init_cli_theme();
|
|
13992
14065
|
init_cli_theme();
|
|
14066
|
+
init_cli_theme_capabilities();
|
|
13993
14067
|
init_clipboard_image();
|
|
13994
14068
|
init_fuzzy_match();
|
|
13995
14069
|
init_image_attachments();
|
|
@@ -14127,80 +14201,53 @@ function getApprovalDescription(approval) {
|
|
|
14127
14201
|
function ChatToolApprovalCard({
|
|
14128
14202
|
approvals,
|
|
14129
14203
|
onResolve,
|
|
14130
|
-
onResolveAll
|
|
14204
|
+
onResolveAll,
|
|
14205
|
+
hasDraftText = false
|
|
14131
14206
|
}) {
|
|
14132
14207
|
const [selectedIndex, setSelectedIndex] = useState13(0);
|
|
14133
|
-
const [keyboardActive, setKeyboardActive] = useState13(false);
|
|
14134
14208
|
const safeSelectedIndex = Math.min(selectedIndex, Math.max(approvals.length - 1, 0));
|
|
14135
14209
|
useEffect9(() => {
|
|
14136
14210
|
setSelectedIndex((currentIndex) => Math.min(currentIndex, Math.max(approvals.length - 1, 0)));
|
|
14137
14211
|
}, [approvals.length]);
|
|
14138
14212
|
useKeyboard3((keyEvent) => {
|
|
14139
|
-
if (approvals.length === 0) {
|
|
14213
|
+
if (approvals.length === 0 || hasDraftText) {
|
|
14140
14214
|
return;
|
|
14141
14215
|
}
|
|
14142
14216
|
const keyName = keyEvent.name.toLowerCase();
|
|
14143
14217
|
if (isDownKey(keyName)) {
|
|
14144
14218
|
keyEvent.preventDefault();
|
|
14145
14219
|
keyEvent.stopPropagation();
|
|
14146
|
-
if (!keyboardActive) {
|
|
14147
|
-
setKeyboardActive(true);
|
|
14148
|
-
setSelectedIndex(0);
|
|
14149
|
-
return;
|
|
14150
|
-
}
|
|
14151
|
-
setKeyboardActive(true);
|
|
14152
14220
|
setSelectedIndex((currentIndex) => Math.min(currentIndex + 1, approvals.length - 1));
|
|
14153
14221
|
return;
|
|
14154
14222
|
}
|
|
14155
14223
|
if (isUpKey(keyName)) {
|
|
14156
14224
|
keyEvent.preventDefault();
|
|
14157
14225
|
keyEvent.stopPropagation();
|
|
14158
|
-
if (!keyboardActive) {
|
|
14159
|
-
setKeyboardActive(true);
|
|
14160
|
-
setSelectedIndex(0);
|
|
14161
|
-
return;
|
|
14162
|
-
}
|
|
14163
|
-
setKeyboardActive(true);
|
|
14164
14226
|
setSelectedIndex((currentIndex) => Math.max(currentIndex - 1, 0));
|
|
14165
14227
|
return;
|
|
14166
14228
|
}
|
|
14167
|
-
if (!keyboardActive) {
|
|
14168
|
-
return;
|
|
14169
|
-
}
|
|
14170
14229
|
if (isEnterKey(keyName)) {
|
|
14171
14230
|
keyEvent.preventDefault();
|
|
14172
14231
|
keyEvent.stopPropagation();
|
|
14173
14232
|
onResolve("approve", safeSelectedIndex);
|
|
14174
|
-
return;
|
|
14175
|
-
}
|
|
14176
|
-
if (keyName === "d") {
|
|
14177
|
-
keyEvent.preventDefault();
|
|
14178
|
-
keyEvent.stopPropagation();
|
|
14179
|
-
onResolve("deny", safeSelectedIndex);
|
|
14180
|
-
return;
|
|
14181
|
-
}
|
|
14182
|
-
if (keyName === "a") {
|
|
14183
|
-
keyEvent.preventDefault();
|
|
14184
|
-
keyEvent.stopPropagation();
|
|
14185
|
-
onResolveAll("approve");
|
|
14186
|
-
return;
|
|
14187
|
-
}
|
|
14188
|
-
if (isEscapeKey(keyName)) {
|
|
14189
|
-
keyEvent.preventDefault();
|
|
14190
|
-
keyEvent.stopPropagation();
|
|
14191
|
-
setKeyboardActive(false);
|
|
14192
14233
|
}
|
|
14193
14234
|
});
|
|
14194
14235
|
if (approvals.length === 0) {
|
|
14195
14236
|
return null;
|
|
14196
14237
|
}
|
|
14238
|
+
const hint = hasDraftText ? "Finish your reply below \u2014 approve/deny commands work there" : [
|
|
14239
|
+
approvals.length > 1 ? "\u2191/\u2193 select" : null,
|
|
14240
|
+
"Enter approve",
|
|
14241
|
+
"type deny to reject",
|
|
14242
|
+
approvals.length > 1 ? "approve all / deny all" : null
|
|
14243
|
+
].filter(Boolean).join(" \xB7 ");
|
|
14197
14244
|
return /* @__PURE__ */ jsxDEV24("box", {
|
|
14198
14245
|
width: "100%",
|
|
14199
14246
|
flexDirection: "column",
|
|
14200
14247
|
borderStyle: "single",
|
|
14201
|
-
borderColor:
|
|
14248
|
+
borderColor: cliTheme.semantic.warning,
|
|
14202
14249
|
backgroundColor: cliTheme.surfaces.panel,
|
|
14203
|
-
paddingX:
|
|
14250
|
+
paddingX: 2,
|
|
14204
14251
|
paddingY: 1,
|
|
14205
14252
|
gap: 1,
|
|
14206
14253
|
children: [
|
|
@@ -14212,11 +14259,14 @@ function ChatToolApprovalCard({
|
|
|
14212
14259
|
/* @__PURE__ */ jsxDEV24("text", {
|
|
14213
14260
|
fg: cliTheme.semantic.warning,
|
|
14214
14261
|
attributes: typeRole("title").attributes,
|
|
14215
|
-
children:
|
|
14216
|
-
|
|
14262
|
+
children: [
|
|
14263
|
+
activeGlyphs.toolApproval,
|
|
14264
|
+
" Tool access request"
|
|
14265
|
+
]
|
|
14266
|
+
}, undefined, true, undefined, this),
|
|
14217
14267
|
/* @__PURE__ */ jsxDEV24("text", {
|
|
14218
|
-
fg:
|
|
14219
|
-
children:
|
|
14268
|
+
fg: cliTheme.text.muted,
|
|
14269
|
+
children: approvals.length === 1 ? "1 pending" : `${approvals.length} pending`
|
|
14220
14270
|
}, undefined, false, undefined, this)
|
|
14221
14271
|
]
|
|
14222
14272
|
}, undefined, true, undefined, this),
|
|
@@ -14224,7 +14274,8 @@ function ChatToolApprovalCard({
|
|
|
14224
14274
|
width: "100%",
|
|
14225
14275
|
flexDirection: "column",
|
|
14226
14276
|
children: approvals.map((approval, index) => {
|
|
14227
|
-
const
|
|
14277
|
+
const selected = index === safeSelectedIndex;
|
|
14278
|
+
const rowColors = getOverlayRowColors(selected);
|
|
14228
14279
|
const target = truncateInline2(getApprovalTarget(approval));
|
|
14229
14280
|
return /* @__PURE__ */ jsxDEV24("box", {
|
|
14230
14281
|
width: "100%",
|
|
@@ -14234,46 +14285,51 @@ function ChatToolApprovalCard({
|
|
|
14234
14285
|
children: [
|
|
14235
14286
|
/* @__PURE__ */ jsxDEV24("text", {
|
|
14236
14287
|
fg: rowColors.primaryTextColor,
|
|
14237
|
-
attributes:
|
|
14288
|
+
attributes: selected ? TextAttributes6.BOLD : TextAttributes6.NONE,
|
|
14238
14289
|
children: [
|
|
14239
|
-
|
|
14240
|
-
|
|
14241
|
-
|
|
14242
|
-
|
|
14243
|
-
|
|
14244
|
-
|
|
14290
|
+
/* @__PURE__ */ jsxDEV24("span", {
|
|
14291
|
+
fg: selected ? cliTheme.accent.primary : cliTheme.text.muted,
|
|
14292
|
+
children: [
|
|
14293
|
+
selected ? `${activeGlyphs.roleUser} ` : " ",
|
|
14294
|
+
index + 1,
|
|
14295
|
+
".",
|
|
14296
|
+
" "
|
|
14297
|
+
]
|
|
14298
|
+
}, undefined, true, undefined, this),
|
|
14299
|
+
/* @__PURE__ */ jsxDEV24("span", {
|
|
14300
|
+
children: approval.toolName
|
|
14301
|
+
}, undefined, false, undefined, this),
|
|
14302
|
+
/* @__PURE__ */ jsxDEV24("span", {
|
|
14303
|
+
fg: rowColors.secondaryTextColor,
|
|
14304
|
+
children: [
|
|
14305
|
+
" ",
|
|
14306
|
+
target
|
|
14307
|
+
]
|
|
14308
|
+
}, undefined, true, undefined, this)
|
|
14245
14309
|
]
|
|
14246
14310
|
}, undefined, true, undefined, this),
|
|
14247
14311
|
/* @__PURE__ */ jsxDEV24("text", {
|
|
14248
14312
|
fg: rowColors.secondaryTextColor,
|
|
14249
14313
|
attributes: TextAttributes6.DIM,
|
|
14250
|
-
children:
|
|
14251
|
-
|
|
14314
|
+
children: [
|
|
14315
|
+
" ",
|
|
14316
|
+
getApprovalDescription(approval)
|
|
14317
|
+
]
|
|
14318
|
+
}, undefined, true, undefined, this)
|
|
14252
14319
|
]
|
|
14253
14320
|
}, approval.toolCallId, true, undefined, this);
|
|
14254
14321
|
})
|
|
14255
14322
|
}, undefined, false, undefined, this),
|
|
14256
|
-
/* @__PURE__ */ jsxDEV24("
|
|
14257
|
-
|
|
14258
|
-
|
|
14259
|
-
|
|
14260
|
-
children: [
|
|
14261
|
-
/* @__PURE__ */ jsxDEV24("text", {
|
|
14262
|
-
fg: cliTheme.text.muted,
|
|
14263
|
-
attributes: TextAttributes6.DIM,
|
|
14264
|
-
children: keyboardActive ? "Enter approve | d deny | a approve all | Esc release focus" : "Down focus card | or type approve/deny below"
|
|
14265
|
-
}, undefined, false, undefined, this),
|
|
14266
|
-
/* @__PURE__ */ jsxDEV24("text", {
|
|
14267
|
-
fg: cliTheme.text.secondary,
|
|
14268
|
-
children: "approve/deny also works in reply"
|
|
14269
|
-
}, undefined, false, undefined, this)
|
|
14270
|
-
]
|
|
14271
|
-
}, undefined, true, undefined, this)
|
|
14323
|
+
/* @__PURE__ */ jsxDEV24("text", {
|
|
14324
|
+
...typeRole("caption"),
|
|
14325
|
+
children: hint
|
|
14326
|
+
}, undefined, false, undefined, this)
|
|
14272
14327
|
]
|
|
14273
14328
|
}, undefined, true, undefined, this);
|
|
14274
14329
|
}
|
|
14275
14330
|
var init_chat_tool_approval_card = __esm(() => {
|
|
14276
14331
|
init_cli_theme();
|
|
14332
|
+
init_cli_theme_capabilities();
|
|
14277
14333
|
init_text_utils();
|
|
14278
14334
|
init_cli_theme();
|
|
14279
14335
|
});
|
|
@@ -14659,6 +14715,53 @@ var init_file_mentions = __esm(() => {
|
|
|
14659
14715
|
};
|
|
14660
14716
|
});
|
|
14661
14717
|
|
|
14718
|
+
// apps/cli/src/utils/workspace-files.ts
|
|
14719
|
+
import { readdir as readdir3 } from "fs/promises";
|
|
14720
|
+
import path18 from "path";
|
|
14721
|
+
async function listWorkspaceFiles(root, limit = 3000) {
|
|
14722
|
+
const files = [];
|
|
14723
|
+
const queue = [root];
|
|
14724
|
+
while (queue.length > 0 && files.length < limit) {
|
|
14725
|
+
const directory = queue.shift();
|
|
14726
|
+
let entries;
|
|
14727
|
+
try {
|
|
14728
|
+
entries = await readdir3(directory, { withFileTypes: true });
|
|
14729
|
+
} catch {
|
|
14730
|
+
continue;
|
|
14731
|
+
}
|
|
14732
|
+
entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
14733
|
+
for (const entry of entries) {
|
|
14734
|
+
if (entry.name.startsWith(".") || ignoredDirectoryNames2.has(entry.name)) {
|
|
14735
|
+
continue;
|
|
14736
|
+
}
|
|
14737
|
+
const absolutePath = path18.join(directory, entry.name);
|
|
14738
|
+
if (entry.isDirectory()) {
|
|
14739
|
+
queue.push(absolutePath);
|
|
14740
|
+
} else if (entry.isFile()) {
|
|
14741
|
+
files.push(path18.relative(root, absolutePath).replaceAll("\\", "/"));
|
|
14742
|
+
if (files.length >= limit) {
|
|
14743
|
+
break;
|
|
14744
|
+
}
|
|
14745
|
+
}
|
|
14746
|
+
}
|
|
14747
|
+
}
|
|
14748
|
+
return files;
|
|
14749
|
+
}
|
|
14750
|
+
var ignoredDirectoryNames2;
|
|
14751
|
+
var init_workspace_files = __esm(() => {
|
|
14752
|
+
ignoredDirectoryNames2 = new Set([
|
|
14753
|
+
".git",
|
|
14754
|
+
".next",
|
|
14755
|
+
".turbo",
|
|
14756
|
+
".vercel",
|
|
14757
|
+
"coverage",
|
|
14758
|
+
"dist",
|
|
14759
|
+
"node_modules",
|
|
14760
|
+
"out",
|
|
14761
|
+
"target"
|
|
14762
|
+
]);
|
|
14763
|
+
});
|
|
14764
|
+
|
|
14662
14765
|
// apps/cli/src/screens/chat-screen.tsx
|
|
14663
14766
|
import { useKeyboard as useKeyboard4, useRenderer, useTerminalDimensions } from "@opentui/react";
|
|
14664
14767
|
import { useCallback as useCallback7, useEffect as useEffect13, useMemo as useMemo8, useRef as useRef7, useState as useState17 } from "react";
|
|
@@ -14737,11 +14840,13 @@ function ChatScreen() {
|
|
|
14737
14840
|
const [contextState, setContextState] = useState17(null);
|
|
14738
14841
|
const [actionNotice, setActionNotice] = useState17(null);
|
|
14739
14842
|
const [permissionSelectorOpen, setPermissionSelectorOpen] = useState17(false);
|
|
14843
|
+
const [draftHasText, setDraftHasText] = useState17(false);
|
|
14740
14844
|
const slashRoutes = getSlashMenuItems(slashMenuQuery, {
|
|
14741
|
-
|
|
14845
|
+
host: "chat"
|
|
14742
14846
|
});
|
|
14743
14847
|
const selectedSlashRouteIndex = Math.min(slashMenuSelected, Math.max(slashRoutes.length - 1, 0));
|
|
14744
14848
|
const syncSlashMenuFromInput = useCallback7((text) => {
|
|
14849
|
+
setDraftHasText(text.trim().length > 0);
|
|
14745
14850
|
const firstLine = text.split(/\r?\n/, 1)[0] ?? "";
|
|
14746
14851
|
if (!firstLine.startsWith("/")) {
|
|
14747
14852
|
if (slashMenuOpen) {
|
|
@@ -14893,10 +14998,9 @@ function ChatScreen() {
|
|
|
14893
14998
|
let cancelled = false;
|
|
14894
14999
|
async function loadMentionCandidates() {
|
|
14895
15000
|
try {
|
|
14896
|
-
const
|
|
14897
|
-
const output = await executeGlobSearch2({ pattern: "**/*", maxResults: 200 }, createWorkspaceContext2(process.cwd()));
|
|
15001
|
+
const files = await listWorkspaceFiles(process.cwd());
|
|
14898
15002
|
if (!cancelled) {
|
|
14899
|
-
setMentionCandidates(
|
|
15003
|
+
setMentionCandidates(files);
|
|
14900
15004
|
}
|
|
14901
15005
|
} catch {}
|
|
14902
15006
|
}
|
|
@@ -14961,29 +15065,29 @@ function ChatScreen() {
|
|
|
14961
15065
|
const [activeFilePath, setActiveFilePath] = useState17(null);
|
|
14962
15066
|
const openFileContent = useFileContent(activeFilePath, process.cwd(), fileReloadToken);
|
|
14963
15067
|
const isEditingFile = panelMode === "edit";
|
|
14964
|
-
const openFileTab = useCallback7((
|
|
14965
|
-
setOpenFiles((current) => current.includes(
|
|
14966
|
-
setActiveFilePath(
|
|
15068
|
+
const openFileTab = useCallback7((path19) => {
|
|
15069
|
+
setOpenFiles((current) => current.includes(path19) ? current : [...current, path19].slice(-MAX_OPEN_TABS));
|
|
15070
|
+
setActiveFilePath(path19);
|
|
14967
15071
|
}, []);
|
|
14968
15072
|
useEffect13(() => {
|
|
14969
15073
|
if (fileTree.openFilePath) {
|
|
14970
15074
|
openFileTab(fileTree.openFilePath);
|
|
14971
15075
|
}
|
|
14972
15076
|
}, [fileTree.openFilePath, openFileTab]);
|
|
14973
|
-
const selectFileTab = useCallback7((
|
|
15077
|
+
const selectFileTab = useCallback7((path19) => {
|
|
14974
15078
|
setPanelMode("browse");
|
|
14975
|
-
setActiveFilePath(
|
|
15079
|
+
setActiveFilePath(path19);
|
|
14976
15080
|
}, []);
|
|
14977
|
-
const closeFileTab = useCallback7((
|
|
15081
|
+
const closeFileTab = useCallback7((path19) => {
|
|
14978
15082
|
setPanelMode("browse");
|
|
14979
15083
|
setOpenFiles((current) => {
|
|
14980
|
-
const index = current.indexOf(
|
|
15084
|
+
const index = current.indexOf(path19);
|
|
14981
15085
|
if (index === -1) {
|
|
14982
15086
|
return current;
|
|
14983
15087
|
}
|
|
14984
|
-
const next = current.filter((file) => file !==
|
|
15088
|
+
const next = current.filter((file) => file !== path19);
|
|
14985
15089
|
setActiveFilePath((active) => {
|
|
14986
|
-
if (active !==
|
|
15090
|
+
if (active !== path19) {
|
|
14987
15091
|
return active;
|
|
14988
15092
|
}
|
|
14989
15093
|
return next[index] ?? next[index - 1] ?? null;
|
|
@@ -15066,13 +15170,13 @@ function ChatScreen() {
|
|
|
15066
15170
|
setPanelFocused(false);
|
|
15067
15171
|
}
|
|
15068
15172
|
}, [panelVisible]);
|
|
15069
|
-
const selectChangedPath = useCallback7((
|
|
15070
|
-
setSelectedChangedPath(
|
|
15173
|
+
const selectChangedPath = useCallback7((path19) => {
|
|
15174
|
+
setSelectedChangedPath(path19);
|
|
15071
15175
|
setChangedSelectionPinned(true);
|
|
15072
15176
|
}, []);
|
|
15073
|
-
const openChangedFile = useCallback7((
|
|
15074
|
-
selectChangedPath(
|
|
15075
|
-
openFileTab(
|
|
15177
|
+
const openChangedFile = useCallback7((path19) => {
|
|
15178
|
+
selectChangedPath(path19);
|
|
15179
|
+
openFileTab(path19);
|
|
15076
15180
|
}, [selectChangedPath, openFileTab]);
|
|
15077
15181
|
const moveChangedSelection = useCallback7((delta) => {
|
|
15078
15182
|
if (changesFiles.length === 0) {
|
|
@@ -15445,7 +15549,7 @@ function ChatScreen() {
|
|
|
15445
15549
|
}
|
|
15446
15550
|
const isCtrlY = keyName === "y" && keyEvent.ctrl && !keyEvent.meta && !keyEvent.super && !keyEvent.hyper && !keyEvent.shift;
|
|
15447
15551
|
if (isCtrlY) {
|
|
15448
|
-
if (!isSessionIdValid || hasBlockingPopup || slashMenuOpen || copyableMessages.length === 0) {
|
|
15552
|
+
if (!isSessionIdValid || hasBlockingPopup || slashMenuOpen || permissionSelectorOpen || copyableMessages.length === 0) {
|
|
15449
15553
|
return;
|
|
15450
15554
|
}
|
|
15451
15555
|
keyEvent.preventDefault();
|
|
@@ -15459,7 +15563,7 @@ function ChatScreen() {
|
|
|
15459
15563
|
if (!isPlainTab && !isCtrlT) {
|
|
15460
15564
|
return;
|
|
15461
15565
|
}
|
|
15462
|
-
if (!isSessionIdValid || hasBlockingPopup || slashMenuOpen) {
|
|
15566
|
+
if (!isSessionIdValid || hasBlockingPopup || slashMenuOpen || permissionSelectorOpen) {
|
|
15463
15567
|
return;
|
|
15464
15568
|
}
|
|
15465
15569
|
keyEvent.preventDefault();
|
|
@@ -15487,8 +15591,8 @@ function ChatScreen() {
|
|
|
15487
15591
|
}, undefined, false, undefined, this) : null,
|
|
15488
15592
|
inputArea: /* @__PURE__ */ jsxDEV27(ChatTextArea, {
|
|
15489
15593
|
placeholder: isLoading ? "Waiting for response..." : "Reply... (@ to attach files)",
|
|
15490
|
-
focused: canTypeInChat && !copyModeOpen && !panelFocused && !isEditingFile,
|
|
15491
|
-
disabled: !canTypeInChat || copyModeOpen || panelFocused || isEditingFile,
|
|
15594
|
+
focused: canTypeInChat && !copyModeOpen && !permissionSelectorOpen && !panelFocused && !isEditingFile,
|
|
15595
|
+
disabled: !canTypeInChat || copyModeOpen || permissionSelectorOpen || panelFocused || isEditingFile,
|
|
15492
15596
|
slashMenuOpen,
|
|
15493
15597
|
mentionCandidates,
|
|
15494
15598
|
onTextChange: syncSlashMenuFromInput,
|
|
@@ -15531,7 +15635,7 @@ function ChatScreen() {
|
|
|
15531
15635
|
wrapMode: "none",
|
|
15532
15636
|
truncate: true,
|
|
15533
15637
|
fg: cliTheme.text.muted,
|
|
15534
|
-
children: "
|
|
15638
|
+
children: "Enter approve \xB7 type deny to reject \xB7 or reply"
|
|
15535
15639
|
}, undefined, false, undefined, this) : hasBlockingPopup ? /* @__PURE__ */ jsxDEV27("text", {
|
|
15536
15640
|
wrapMode: "none",
|
|
15537
15641
|
truncate: true,
|
|
@@ -15541,7 +15645,7 @@ function ChatScreen() {
|
|
|
15541
15645
|
wrapMode: "none",
|
|
15542
15646
|
truncate: true,
|
|
15543
15647
|
fg: cliTheme.text.muted,
|
|
15544
|
-
children: "
|
|
15648
|
+
children: "\u2191/\u2193 select \xB7 Enter open \xB7 Esc close"
|
|
15545
15649
|
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV27("text", {
|
|
15546
15650
|
wrapMode: "none",
|
|
15547
15651
|
truncate: true,
|
|
@@ -15651,7 +15755,8 @@ function ChatScreen() {
|
|
|
15651
15755
|
pendingApprovals.length > 0 ? /* @__PURE__ */ jsxDEV27(ChatToolApprovalCard, {
|
|
15652
15756
|
approvals: pendingApprovals,
|
|
15653
15757
|
onResolve: resolveToolApproval,
|
|
15654
|
-
onResolveAll: resolveAllToolApprovals
|
|
15758
|
+
onResolveAll: resolveAllToolApprovals,
|
|
15759
|
+
hasDraftText: draftHasText
|
|
15655
15760
|
}, undefined, false, undefined, this) : null,
|
|
15656
15761
|
todos.length > 0 ? /* @__PURE__ */ jsxDEV27(ChatTodoStatusCard, {
|
|
15657
15762
|
todos
|
|
@@ -15881,6 +15986,7 @@ var init_chat_screen = __esm(() => {
|
|
|
15881
15986
|
init_file_mentions();
|
|
15882
15987
|
init_markdown_code();
|
|
15883
15988
|
init_text_utils();
|
|
15989
|
+
init_workspace_files();
|
|
15884
15990
|
init_badge();
|
|
15885
15991
|
planConfirmationAcceptKeywords = [
|
|
15886
15992
|
"yes",
|
|
@@ -16550,7 +16656,7 @@ var init_home_ascii_art = __esm(() => {
|
|
|
16550
16656
|
|
|
16551
16657
|
// apps/cli/src/components/home-text-area.tsx
|
|
16552
16658
|
import { useKeyboard as useKeyboard6 } from "@opentui/react";
|
|
16553
|
-
import { useState as useState19 } from "react";
|
|
16659
|
+
import { useEffect as useEffect15, useState as useState19 } from "react";
|
|
16554
16660
|
import { useNavigate as useNavigate2 } from "react-router";
|
|
16555
16661
|
import { jsxDEV as jsxDEV30 } from "@opentui/react/jsx-dev-runtime";
|
|
16556
16662
|
function HomeTextArea() {
|
|
@@ -16562,14 +16668,27 @@ function HomeTextArea() {
|
|
|
16562
16668
|
slashMenuSelected,
|
|
16563
16669
|
setSlashMenuSelected,
|
|
16564
16670
|
openSlashMenu,
|
|
16565
|
-
closeSlashMenu
|
|
16671
|
+
closeSlashMenu,
|
|
16672
|
+
requestedChatActionId,
|
|
16673
|
+
clearRequestedChatAction
|
|
16566
16674
|
} = useAppState();
|
|
16567
16675
|
const [sessionCreateError, setSessionCreateError] = useState19(null);
|
|
16568
16676
|
const [isCreatingSession, setIsCreatingSession] = useState19(false);
|
|
16569
16677
|
const [mode, setMode] = useState19(defaultCodingAgentMode);
|
|
16570
|
-
const
|
|
16678
|
+
const [permissionMode, setPermissionMode] = useState19(undefined);
|
|
16679
|
+
const [permissionSelectorOpen, setPermissionSelectorOpen] = useState19(false);
|
|
16680
|
+
const slashRoutes = getSlashMenuItems(slashMenuQuery, { host: "home" });
|
|
16571
16681
|
const selectedIndex = Math.min(slashMenuSelected, Math.max(slashRoutes.length - 1, 0));
|
|
16572
16682
|
const modeDefinition = codingAgentModes[mode];
|
|
16683
|
+
useEffect15(() => {
|
|
16684
|
+
if (!requestedChatActionId) {
|
|
16685
|
+
return;
|
|
16686
|
+
}
|
|
16687
|
+
clearRequestedChatAction();
|
|
16688
|
+
if (requestedChatActionId === "permission") {
|
|
16689
|
+
setPermissionSelectorOpen(true);
|
|
16690
|
+
}
|
|
16691
|
+
}, [clearRequestedChatAction, requestedChatActionId]);
|
|
16573
16692
|
const syncSlashMenuFromInput = (text) => {
|
|
16574
16693
|
const firstLine = text.split(/\r?\n/, 1)[0] ?? "";
|
|
16575
16694
|
if (!firstLine.startsWith("/")) {
|
|
@@ -16588,7 +16707,7 @@ function HomeTextArea() {
|
|
|
16588
16707
|
const keyName = keyEvent.name.toLowerCase();
|
|
16589
16708
|
const isPlainTab = (keyName === "tab" || keyEvent.sequence === "\t") && !keyEvent.ctrl && !keyEvent.meta && !keyEvent.super && !keyEvent.hyper && !keyEvent.shift;
|
|
16590
16709
|
const isCtrlT = keyName === "t" && keyEvent.ctrl && !keyEvent.meta && !keyEvent.super && !keyEvent.hyper && !keyEvent.shift;
|
|
16591
|
-
if (!isPlainTab && !isCtrlT || slashMenuOpen || isCreatingSession) {
|
|
16710
|
+
if (!isPlainTab && !isCtrlT || slashMenuOpen || permissionSelectorOpen || isCreatingSession) {
|
|
16592
16711
|
return;
|
|
16593
16712
|
}
|
|
16594
16713
|
keyEvent.preventDefault();
|
|
@@ -16606,7 +16725,8 @@ function HomeTextArea() {
|
|
|
16606
16725
|
const response = await client.sessions.$post({
|
|
16607
16726
|
json: {
|
|
16608
16727
|
cwd: process.cwd(),
|
|
16609
|
-
mode
|
|
16728
|
+
mode,
|
|
16729
|
+
permissionMode
|
|
16610
16730
|
}
|
|
16611
16731
|
});
|
|
16612
16732
|
if (!response.ok) {
|
|
@@ -16621,7 +16741,8 @@ function HomeTextArea() {
|
|
|
16621
16741
|
state: {
|
|
16622
16742
|
input: text,
|
|
16623
16743
|
skipHistoryLoad: true,
|
|
16624
|
-
mode
|
|
16744
|
+
mode,
|
|
16745
|
+
permissionMode
|
|
16625
16746
|
}
|
|
16626
16747
|
});
|
|
16627
16748
|
} catch (sessionCreateFailure) {
|
|
@@ -16642,11 +16763,18 @@ function HomeTextArea() {
|
|
|
16642
16763
|
allowEmpty: true,
|
|
16643
16764
|
trimOnSubmit: false,
|
|
16644
16765
|
placeholder: 'Ask anything... "What is the tech stack of this project?"',
|
|
16645
|
-
focused: !isCreatingSession,
|
|
16646
|
-
disabled: isCreatingSession,
|
|
16766
|
+
focused: !isCreatingSession && !permissionSelectorOpen,
|
|
16767
|
+
disabled: isCreatingSession || permissionSelectorOpen,
|
|
16647
16768
|
slashMenuOpen,
|
|
16648
16769
|
onTextChange: syncSlashMenuFromInput,
|
|
16649
|
-
beforeInput:
|
|
16770
|
+
beforeInput: permissionSelectorOpen ? /* @__PURE__ */ jsxDEV30(PermissionModeSelector, {
|
|
16771
|
+
currentMode: permissionMode,
|
|
16772
|
+
onSelect: (newMode) => {
|
|
16773
|
+
setPermissionMode(newMode);
|
|
16774
|
+
setPermissionSelectorOpen(false);
|
|
16775
|
+
},
|
|
16776
|
+
onClose: () => setPermissionSelectorOpen(false)
|
|
16777
|
+
}, undefined, false, undefined, this) : slashMenuOpen ? /* @__PURE__ */ jsxDEV30(SlashPageMenu, {
|
|
16650
16778
|
query: slashMenuQuery,
|
|
16651
16779
|
selectedIndex,
|
|
16652
16780
|
routes: slashRoutes
|
|
@@ -16671,7 +16799,14 @@ function HomeTextArea() {
|
|
|
16671
16799
|
/* @__PURE__ */ jsxDEV30("span", {
|
|
16672
16800
|
fg: cliTheme.text.muted,
|
|
16673
16801
|
children: " mode"
|
|
16674
|
-
}, undefined, false, undefined, this)
|
|
16802
|
+
}, undefined, false, undefined, this),
|
|
16803
|
+
permissionMode ? /* @__PURE__ */ jsxDEV30("span", {
|
|
16804
|
+
fg: permissionMode === "danger-full-access" ? cliTheme.semantic.warning : cliTheme.text.muted,
|
|
16805
|
+
children: [
|
|
16806
|
+
" \xB7 ",
|
|
16807
|
+
permissionMode
|
|
16808
|
+
]
|
|
16809
|
+
}, undefined, true, undefined, this) : null
|
|
16675
16810
|
]
|
|
16676
16811
|
}, undefined, true, undefined, this)
|
|
16677
16812
|
]
|
|
@@ -16689,21 +16824,22 @@ function HomeTextArea() {
|
|
|
16689
16824
|
}
|
|
16690
16825
|
var init_home_text_area = __esm(() => {
|
|
16691
16826
|
init_src2();
|
|
16827
|
+
init_slash_menu_items();
|
|
16692
16828
|
init_slash_page_menu();
|
|
16693
16829
|
init_client();
|
|
16694
16830
|
init_chat_text_area();
|
|
16695
|
-
|
|
16831
|
+
init_permission_mode_selector();
|
|
16696
16832
|
init_app_state();
|
|
16697
16833
|
init_cli_theme();
|
|
16698
16834
|
init_text_utils();
|
|
16699
16835
|
});
|
|
16700
16836
|
|
|
16701
16837
|
// apps/cli/src/components/server-status.tsx
|
|
16702
|
-
import { useEffect as
|
|
16838
|
+
import { useEffect as useEffect16, useState as useState20 } from "react";
|
|
16703
16839
|
import { jsxDEV as jsxDEV31 } from "@opentui/react/jsx-dev-runtime";
|
|
16704
16840
|
function ServerStatus() {
|
|
16705
16841
|
const [status, setStatus] = useState20("checking");
|
|
16706
|
-
|
|
16842
|
+
useEffect16(() => {
|
|
16707
16843
|
let cancelled = false;
|
|
16708
16844
|
async function checkServer2() {
|
|
16709
16845
|
try {
|
|
@@ -16764,7 +16900,7 @@ var init_home_screen = __esm(() => {
|
|
|
16764
16900
|
|
|
16765
16901
|
// apps/cli/src/screens/model-screen.tsx
|
|
16766
16902
|
import { useKeyboard as useKeyboard7 } from "@opentui/react";
|
|
16767
|
-
import { useCallback as useCallback9, useEffect as
|
|
16903
|
+
import { useCallback as useCallback9, useEffect as useEffect17, useState as useState21 } from "react";
|
|
16768
16904
|
import { jsxDEV as jsxDEV33 } from "@opentui/react/jsx-dev-runtime";
|
|
16769
16905
|
function ModelScreen() {
|
|
16770
16906
|
const [isLoading, setIsLoading] = useState21(true);
|
|
@@ -16786,7 +16922,7 @@ function ModelScreen() {
|
|
|
16786
16922
|
setIsLoading(false);
|
|
16787
16923
|
}
|
|
16788
16924
|
}, []);
|
|
16789
|
-
|
|
16925
|
+
useEffect17(() => {
|
|
16790
16926
|
loadModelConfig();
|
|
16791
16927
|
}, [loadModelConfig]);
|
|
16792
16928
|
useKeyboard7((keyEvent) => {
|
|
@@ -16920,7 +17056,7 @@ var init_model_screen = __esm(() => {
|
|
|
16920
17056
|
// apps/cli/src/components/chat/model-selector.tsx
|
|
16921
17057
|
import { TextAttributes as TextAttributes8 } from "@opentui/core";
|
|
16922
17058
|
import { useKeyboard as useKeyboard8 } from "@opentui/react";
|
|
16923
|
-
import { useEffect as
|
|
17059
|
+
import { useEffect as useEffect18, useMemo as useMemo10, useState as useState22 } from "react";
|
|
16924
17060
|
import { jsxDEV as jsxDEV34 } from "@opentui/react/jsx-dev-runtime";
|
|
16925
17061
|
function formatContextLength(contextLength) {
|
|
16926
17062
|
if (!contextLength) {
|
|
@@ -16936,7 +17072,7 @@ function ModelSelector({ onClose, notify }) {
|
|
|
16936
17072
|
const [isApplying, setIsApplying] = useState22(false);
|
|
16937
17073
|
const [filter, setFilter] = useState22("");
|
|
16938
17074
|
const [selectedIndex, setSelectedIndex] = useState22(0);
|
|
16939
|
-
|
|
17075
|
+
useEffect18(() => {
|
|
16940
17076
|
let cancelled = false;
|
|
16941
17077
|
async function loadModels() {
|
|
16942
17078
|
try {
|
|
@@ -16978,7 +17114,7 @@ function ModelSelector({ onClose, notify }) {
|
|
|
16978
17114
|
}
|
|
16979
17115
|
return models.filter((model) => model.id.toLowerCase().includes(normalized) || model.name.toLowerCase().includes(normalized));
|
|
16980
17116
|
}, [filter, models]);
|
|
16981
|
-
|
|
17117
|
+
useEffect18(() => {
|
|
16982
17118
|
setSelectedIndex((current) => Math.min(current, Math.max(filteredModels.length - 1, 0)));
|
|
16983
17119
|
}, [filteredModels.length]);
|
|
16984
17120
|
const applyModel = async (model) => {
|
|
@@ -17069,7 +17205,7 @@ function ModelSelector({ onClose, notify }) {
|
|
|
17069
17205
|
}, undefined, false, undefined, this),
|
|
17070
17206
|
/* @__PURE__ */ jsxDEV34("text", {
|
|
17071
17207
|
fg: cliTheme.overlay.footerText,
|
|
17072
|
-
children: "type to filter
|
|
17208
|
+
children: "type to filter \xB7 \u2191/\u2193 select \xB7 Enter confirm \xB7 Esc cancel"
|
|
17073
17209
|
}, undefined, false, undefined, this)
|
|
17074
17210
|
]
|
|
17075
17211
|
}, undefined, true, undefined, this),
|
|
@@ -17121,7 +17257,7 @@ function ModelSelector({ onClose, notify }) {
|
|
|
17121
17257
|
width: 2,
|
|
17122
17258
|
fg: isSelected ? cliTheme.accent.primary : cliTheme.text.muted,
|
|
17123
17259
|
attributes: TextAttributes8.BOLD,
|
|
17124
|
-
children: isSelected ?
|
|
17260
|
+
children: isSelected ? activeGlyphs.roleUser : " "
|
|
17125
17261
|
}, undefined, false, undefined, this),
|
|
17126
17262
|
/* @__PURE__ */ jsxDEV34("text", {
|
|
17127
17263
|
fg: isSelected ? cliTheme.overlay.selectedRowText : cliTheme.text.primary,
|
|
@@ -17131,7 +17267,7 @@ function ModelSelector({ onClose, notify }) {
|
|
|
17131
17267
|
/* @__PURE__ */ jsxDEV34("text", {
|
|
17132
17268
|
fg: cliTheme.text.muted,
|
|
17133
17269
|
marginLeft: 2,
|
|
17134
|
-
children: `${formatContextLength(model.contextLength)}${model.supportsTools ? "
|
|
17270
|
+
children: `${formatContextLength(model.contextLength)}${model.supportsTools ? " \xB7 tools" : ""}${model.supportsReasoning ? " \xB7 reasoning" : ""}`
|
|
17135
17271
|
}, undefined, false, undefined, this),
|
|
17136
17272
|
model.id === currentModel && /* @__PURE__ */ jsxDEV34("text", {
|
|
17137
17273
|
fg: cliTheme.accent.primary,
|
|
@@ -17146,7 +17282,7 @@ function ModelSelector({ onClose, notify }) {
|
|
|
17146
17282
|
marginTop: 1,
|
|
17147
17283
|
children: /* @__PURE__ */ jsxDEV34("text", {
|
|
17148
17284
|
fg: cliTheme.overlay.footerText,
|
|
17149
|
-
children: `${filteredModels.length} model${filteredModels.length === 1 ? "" : "s"}${isApplying ? "
|
|
17285
|
+
children: `${filteredModels.length} model${filteredModels.length === 1 ? "" : "s"}${isApplying ? " \xB7 switching..." : ""}`
|
|
17150
17286
|
}, undefined, false, undefined, this)
|
|
17151
17287
|
}, undefined, false, undefined, this)
|
|
17152
17288
|
]
|
|
@@ -17158,6 +17294,7 @@ var maxVisibleRows = 8;
|
|
|
17158
17294
|
var init_model_selector = __esm(() => {
|
|
17159
17295
|
init_client();
|
|
17160
17296
|
init_cli_theme();
|
|
17297
|
+
init_cli_theme_capabilities();
|
|
17161
17298
|
});
|
|
17162
17299
|
|
|
17163
17300
|
// apps/cli/src/screens/model-select-screen.tsx
|
|
@@ -17199,13 +17336,13 @@ var init_model_select_screen = __esm(() => {
|
|
|
17199
17336
|
import { useKeyboard as useKeyboard9 } from "@opentui/react";
|
|
17200
17337
|
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
17201
17338
|
import os5 from "os";
|
|
17202
|
-
import
|
|
17339
|
+
import path19 from "path";
|
|
17203
17340
|
import { useCallback as useCallback10, useState as useState24 } from "react";
|
|
17204
17341
|
import { useNavigate as useNavigate4 } from "react-router";
|
|
17205
17342
|
import { jsxDEV as jsxDEV36 } from "@opentui/react/jsx-dev-runtime";
|
|
17206
17343
|
function getUserSettingsPath() {
|
|
17207
17344
|
const configured = process.env.LIGHTCODE_USER_CONFIG?.trim();
|
|
17208
|
-
return configured ??
|
|
17345
|
+
return configured ?? path19.join(os5.homedir(), ".lightcode", "settings.json");
|
|
17209
17346
|
}
|
|
17210
17347
|
function mergeUserSettings(update) {
|
|
17211
17348
|
const settingsPath = getUserSettingsPath();
|
|
@@ -17218,7 +17355,7 @@ function mergeUserSettings(update) {
|
|
|
17218
17355
|
}
|
|
17219
17356
|
} catch {}
|
|
17220
17357
|
}
|
|
17221
|
-
mkdirSync5(
|
|
17358
|
+
mkdirSync5(path19.dirname(settingsPath), { recursive: true });
|
|
17222
17359
|
writeFileSync3(settingsPath, `${JSON.stringify({ ...existing, ...update }, null, 2)}
|
|
17223
17360
|
`, "utf8");
|
|
17224
17361
|
return settingsPath;
|
|
@@ -17360,7 +17497,7 @@ function OnboardingScreen() {
|
|
|
17360
17497
|
children: [
|
|
17361
17498
|
/* @__PURE__ */ jsxDEV36("text", {
|
|
17362
17499
|
fg: index === selectedIndex ? cliTheme.accent.primary : cliTheme.text.muted,
|
|
17363
|
-
children: index === selectedIndex ?
|
|
17500
|
+
children: index === selectedIndex ? activeGlyphs.roleUser : " "
|
|
17364
17501
|
}, undefined, false, undefined, this),
|
|
17365
17502
|
/* @__PURE__ */ jsxDEV36("text", {
|
|
17366
17503
|
fg: index === selectedIndex ? cliTheme.overlay.selectedRowText : cliTheme.text.primary,
|
|
@@ -17376,7 +17513,7 @@ function OnboardingScreen() {
|
|
|
17376
17513
|
/* @__PURE__ */ jsxDEV36("text", {
|
|
17377
17514
|
fg: cliTheme.text.muted,
|
|
17378
17515
|
attributes: TextAttributes.DIM,
|
|
17379
|
-
children: "
|
|
17516
|
+
children: "\u2191/\u2193 select \xB7 Enter continue"
|
|
17380
17517
|
}, undefined, false, undefined, this)
|
|
17381
17518
|
]
|
|
17382
17519
|
}, undefined, true, undefined, this) : null,
|
|
@@ -17543,8 +17680,8 @@ var init_onboarding_screen = __esm(() => {
|
|
|
17543
17680
|
});
|
|
17544
17681
|
|
|
17545
17682
|
// apps/cli/src/screens/session-list-screen.tsx
|
|
17546
|
-
import { useKeyboard as useKeyboard10 } from "@opentui/react";
|
|
17547
|
-
import { useCallback as useCallback11, useEffect as
|
|
17683
|
+
import { useKeyboard as useKeyboard10, useTerminalDimensions as useTerminalDimensions2 } from "@opentui/react";
|
|
17684
|
+
import { useCallback as useCallback11, useEffect as useEffect19, useMemo as useMemo11, useState as useState25 } from "react";
|
|
17548
17685
|
import { useNavigate as useNavigate5 } from "react-router";
|
|
17549
17686
|
import { jsxDEV as jsxDEV37 } from "@opentui/react/jsx-dev-runtime";
|
|
17550
17687
|
function getSessionLabel(session) {
|
|
@@ -17572,6 +17709,12 @@ function SessionListScreen() {
|
|
|
17572
17709
|
const safeSelectedIndex = Math.min(selectedIndex, Math.max(visibleSessions.length - 1, 0));
|
|
17573
17710
|
const selectedSession = visibleSessions[safeSelectedIndex] ?? null;
|
|
17574
17711
|
const inputActive = filterOpen || renamingSessionId !== null;
|
|
17712
|
+
const { height: terminalHeight } = useTerminalDimensions2();
|
|
17713
|
+
const maxVisibleRows2 = Math.max(5, terminalHeight - 12);
|
|
17714
|
+
const windowStart = Math.max(0, Math.min(safeSelectedIndex - Math.floor(maxVisibleRows2 / 2), visibleSessions.length - maxVisibleRows2));
|
|
17715
|
+
const windowedSessions = visibleSessions.slice(windowStart, windowStart + maxVisibleRows2);
|
|
17716
|
+
const hiddenAbove = windowStart;
|
|
17717
|
+
const hiddenBelow = Math.max(0, visibleSessions.length - (windowStart + windowedSessions.length));
|
|
17575
17718
|
const applyLoadedSessions = useCallback11((loadedSessions, droppedCount) => {
|
|
17576
17719
|
setSessions(loadedSessions);
|
|
17577
17720
|
setSelectedIndex((currentIndex) => Math.min(currentIndex, Math.max(loadedSessions.length - 1, 0)));
|
|
@@ -17724,7 +17867,7 @@ function SessionListScreen() {
|
|
|
17724
17867
|
setActionMessage(getErrorMessage(error, "Unable to rename session."));
|
|
17725
17868
|
}
|
|
17726
17869
|
}, [loadSessions]);
|
|
17727
|
-
|
|
17870
|
+
useEffect19(() => {
|
|
17728
17871
|
loadSessions();
|
|
17729
17872
|
}, [loadSessions]);
|
|
17730
17873
|
useKeyboard10((keyEvent) => {
|
|
@@ -17811,9 +17954,9 @@ function SessionListScreen() {
|
|
|
17811
17954
|
});
|
|
17812
17955
|
const footerText = useMemo11(() => {
|
|
17813
17956
|
if (sessions.length === 0) {
|
|
17814
|
-
return `u refresh
|
|
17957
|
+
return `u refresh \xB7 l resume latest \xB7 ${BACK_SHORTCUT_LABEL} back`;
|
|
17815
17958
|
}
|
|
17816
|
-
return "Enter resume
|
|
17959
|
+
return "Enter resume \xB7 r rename \xB7 f fork \xB7 / filter \xB7 e export \xB7 d delete \xB7 u refresh";
|
|
17817
17960
|
}, [sessions.length]);
|
|
17818
17961
|
return /* @__PURE__ */ jsxDEV37("box", {
|
|
17819
17962
|
width: "100%",
|
|
@@ -17847,7 +17990,7 @@ function SessionListScreen() {
|
|
|
17847
17990
|
paddingX: 1,
|
|
17848
17991
|
children: /* @__PURE__ */ jsxDEV37("text", {
|
|
17849
17992
|
fg: cliTheme.accent.primary,
|
|
17850
|
-
children: `Filter: "${filterQuery}" (${visibleSessions.length} match${visibleSessions.length === 1 ? "" : "es"})
|
|
17993
|
+
children: `Filter: "${filterQuery}" (${visibleSessions.length} match${visibleSessions.length === 1 ? "" : "es"}) \xB7 Esc clears`
|
|
17851
17994
|
}, undefined, false, undefined, this)
|
|
17852
17995
|
}, undefined, false, undefined, this) : null,
|
|
17853
17996
|
/* @__PURE__ */ jsxDEV37("box", {
|
|
@@ -17864,7 +18007,7 @@ function SessionListScreen() {
|
|
|
17864
18007
|
/* @__PURE__ */ jsxDEV37("text", {
|
|
17865
18008
|
fg: cliTheme.accent.primary,
|
|
17866
18009
|
attributes: TextAttributes.BOLD,
|
|
17867
|
-
children: sessions.length === 0 ?
|
|
18010
|
+
children: sessions.length === 0 ? `${activeGlyphs.roleAssistant} No sessions yet` : "No matches"
|
|
17868
18011
|
}, undefined, false, undefined, this),
|
|
17869
18012
|
/* @__PURE__ */ jsxDEV37("text", {
|
|
17870
18013
|
fg: cliTheme.text.muted,
|
|
@@ -17872,43 +18015,79 @@ function SessionListScreen() {
|
|
|
17872
18015
|
}, undefined, false, undefined, this)
|
|
17873
18016
|
]
|
|
17874
18017
|
}, undefined, true, undefined, this) : null,
|
|
17875
|
-
|
|
18018
|
+
hiddenAbove > 0 ? /* @__PURE__ */ jsxDEV37("box", {
|
|
18019
|
+
paddingX: 1,
|
|
18020
|
+
flexShrink: 0,
|
|
18021
|
+
children: /* @__PURE__ */ jsxDEV37("text", {
|
|
18022
|
+
fg: cliTheme.text.muted,
|
|
18023
|
+
attributes: TextAttributes.DIM,
|
|
18024
|
+
children: `\u2191 ${hiddenAbove} more`
|
|
18025
|
+
}, undefined, false, undefined, this)
|
|
18026
|
+
}, undefined, false, undefined, this) : null,
|
|
18027
|
+
windowedSessions.map((session, windowIndex) => {
|
|
18028
|
+
const index = windowStart + windowIndex;
|
|
17876
18029
|
const isSelected = index === safeSelectedIndex;
|
|
17877
18030
|
const rowColors = getOverlayRowColors(isSelected);
|
|
17878
18031
|
const selectedForDelete = pendingDeleteId === session.id;
|
|
17879
18032
|
return /* @__PURE__ */ jsxDEV37("box", {
|
|
17880
18033
|
flexDirection: "column",
|
|
17881
18034
|
paddingX: 1,
|
|
18035
|
+
flexShrink: 0,
|
|
17882
18036
|
backgroundColor: rowColors.backgroundColor,
|
|
17883
18037
|
children: [
|
|
17884
18038
|
/* @__PURE__ */ jsxDEV37("box", {
|
|
17885
18039
|
flexDirection: "row",
|
|
17886
18040
|
justifyContent: "space-between",
|
|
17887
18041
|
children: [
|
|
18042
|
+
/* @__PURE__ */ jsxDEV37("box", {
|
|
18043
|
+
flexShrink: 1,
|
|
18044
|
+
height: 1,
|
|
18045
|
+
overflow: "hidden",
|
|
18046
|
+
children: /* @__PURE__ */ jsxDEV37("text", {
|
|
18047
|
+
wrapMode: "none",
|
|
18048
|
+
truncate: true,
|
|
18049
|
+
fg: selectedForDelete ? cliTheme.semantic.error : rowColors.primaryTextColor,
|
|
18050
|
+
attributes: TextAttributes.BOLD,
|
|
18051
|
+
children: [
|
|
18052
|
+
isSelected ? `${activeGlyphs.roleUser} ` : " ",
|
|
18053
|
+
index + 1,
|
|
18054
|
+
". ",
|
|
18055
|
+
truncateInline2(getSessionLabel(session), 64)
|
|
18056
|
+
]
|
|
18057
|
+
}, undefined, true, undefined, this)
|
|
18058
|
+
}, undefined, false, undefined, this),
|
|
17888
18059
|
/* @__PURE__ */ jsxDEV37("text", {
|
|
17889
|
-
|
|
17890
|
-
|
|
17891
|
-
|
|
17892
|
-
index + 1,
|
|
17893
|
-
". ",
|
|
17894
|
-
truncateInline2(getSessionLabel(session), 64)
|
|
17895
|
-
]
|
|
17896
|
-
}, undefined, true, undefined, this),
|
|
17897
|
-
/* @__PURE__ */ jsxDEV37("text", {
|
|
18060
|
+
wrapMode: "none",
|
|
18061
|
+
truncate: true,
|
|
18062
|
+
flexShrink: 0,
|
|
17898
18063
|
fg: rowColors.secondaryTextColor,
|
|
17899
18064
|
attributes: TextAttributes.DIM,
|
|
17900
|
-
children: `${session.messageCount} msgs
|
|
18065
|
+
children: `${session.messageCount} msgs \xB7 ${session.mode} \xB7 ${formatDate2(session.updatedAt)}`
|
|
17901
18066
|
}, undefined, false, undefined, this)
|
|
17902
18067
|
]
|
|
17903
18068
|
}, undefined, true, undefined, this),
|
|
17904
18069
|
isSelected && session.latestUserPromptPreview ? /* @__PURE__ */ jsxDEV37("text", {
|
|
18070
|
+
wrapMode: "none",
|
|
18071
|
+
truncate: true,
|
|
17905
18072
|
fg: rowColors.secondaryTextColor,
|
|
17906
18073
|
attributes: TextAttributes.DIM,
|
|
17907
|
-
children:
|
|
17908
|
-
|
|
18074
|
+
children: [
|
|
18075
|
+
" ",
|
|
18076
|
+
truncateInline2(session.latestUserPromptPreview, 110)
|
|
18077
|
+
]
|
|
18078
|
+
}, undefined, true, undefined, this) : null
|
|
17909
18079
|
]
|
|
17910
18080
|
}, session.id, true, undefined, this);
|
|
17911
|
-
})
|
|
18081
|
+
}),
|
|
18082
|
+
hiddenBelow > 0 ? /* @__PURE__ */ jsxDEV37("box", {
|
|
18083
|
+
paddingX: 1,
|
|
18084
|
+
flexShrink: 0,
|
|
18085
|
+
children: /* @__PURE__ */ jsxDEV37("text", {
|
|
18086
|
+
fg: cliTheme.text.muted,
|
|
18087
|
+
attributes: TextAttributes.DIM,
|
|
18088
|
+
children: `\u2193 ${hiddenBelow} more`
|
|
18089
|
+
}, undefined, false, undefined, this)
|
|
18090
|
+
}, undefined, false, undefined, this) : null
|
|
17912
18091
|
]
|
|
17913
18092
|
}, undefined, true, undefined, this),
|
|
17914
18093
|
actionMessage ? /* @__PURE__ */ jsxDEV37("box", {
|
|
@@ -17933,7 +18112,7 @@ function SessionListScreen() {
|
|
|
17933
18112
|
children: /* @__PURE__ */ jsxDEV37("text", {
|
|
17934
18113
|
fg: cliTheme.text.muted,
|
|
17935
18114
|
attributes: TextAttributes.DIM,
|
|
17936
|
-
children: inputActive ? "Enter confirm
|
|
18115
|
+
children: inputActive ? "Enter confirm \xB7 Esc cancel" : footerText
|
|
17937
18116
|
}, undefined, false, undefined, this)
|
|
17938
18117
|
}, undefined, false, undefined, this)
|
|
17939
18118
|
]
|
|
@@ -17946,15 +18125,16 @@ var init_session_list_screen = __esm(() => {
|
|
|
17946
18125
|
init_keymap();
|
|
17947
18126
|
init_export_session_markdown();
|
|
17948
18127
|
init_chat_text_area();
|
|
18128
|
+
init_cli_theme_capabilities();
|
|
17949
18129
|
init_cli_theme();
|
|
17950
18130
|
init_text_utils();
|
|
17951
18131
|
});
|
|
17952
18132
|
|
|
17953
18133
|
// apps/cli/src/hooks/use-config-badge.ts
|
|
17954
|
-
import { useEffect as
|
|
18134
|
+
import { useEffect as useEffect20, useState as useState26 } from "react";
|
|
17955
18135
|
function useConfigBadge(refreshNonce = 0) {
|
|
17956
18136
|
const [state, setState] = useState26({ status: "loading" });
|
|
17957
|
-
|
|
18137
|
+
useEffect20(() => {
|
|
17958
18138
|
let cancelled = false;
|
|
17959
18139
|
async function loadConfig() {
|
|
17960
18140
|
try {
|
|
@@ -18021,7 +18201,7 @@ __export(exports_app, {
|
|
|
18021
18201
|
App: () => App
|
|
18022
18202
|
});
|
|
18023
18203
|
import { useKeyboard as useKeyboard11, useRenderer as useRenderer2 } from "@opentui/react";
|
|
18024
|
-
import { useEffect as
|
|
18204
|
+
import { useEffect as useEffect21, useRef as useRef8, useState as useState27 } from "react";
|
|
18025
18205
|
import { MemoryRouter, Navigate, Route, Routes, useLocation as useLocation3, useNavigate as useNavigate6 } from "react-router";
|
|
18026
18206
|
import { jsxDEV as jsxDEV39 } from "@opentui/react/jsx-dev-runtime";
|
|
18027
18207
|
function getCurrentViewLabel(pathname) {
|
|
@@ -18071,6 +18251,7 @@ function AppContent() {
|
|
|
18071
18251
|
closePalette,
|
|
18072
18252
|
slashMenuOpen,
|
|
18073
18253
|
slashMenuQuery,
|
|
18254
|
+
setSlashMenuQuery,
|
|
18074
18255
|
slashMenuSelected,
|
|
18075
18256
|
setSlashMenuSelected,
|
|
18076
18257
|
openSlashMenu,
|
|
@@ -18115,7 +18296,7 @@ function AppContent() {
|
|
|
18115
18296
|
ctrlCArmedRef.current = true;
|
|
18116
18297
|
showCtrlCNotice("Press Ctrl+C again to exit");
|
|
18117
18298
|
};
|
|
18118
|
-
|
|
18299
|
+
useEffect21(() => {
|
|
18119
18300
|
return () => {
|
|
18120
18301
|
if (ctrlCTimerRef.current) {
|
|
18121
18302
|
clearTimeout(ctrlCTimerRef.current);
|
|
@@ -18127,9 +18308,9 @@ function AppContent() {
|
|
|
18127
18308
|
const inChatSession = location.pathname.startsWith("/sessions/");
|
|
18128
18309
|
const inputHostsSlashMenu = location.pathname === "/" || location.pathname === "/home" || inChatSession;
|
|
18129
18310
|
const handleAction = (action) => {
|
|
18130
|
-
const
|
|
18131
|
-
if (
|
|
18132
|
-
navigate(
|
|
18311
|
+
const path20 = getPathFromAction(action);
|
|
18312
|
+
if (path20) {
|
|
18313
|
+
navigate(path20);
|
|
18133
18314
|
return;
|
|
18134
18315
|
}
|
|
18135
18316
|
switch (action) {
|
|
@@ -18140,7 +18321,9 @@ function AppContent() {
|
|
|
18140
18321
|
openPalette();
|
|
18141
18322
|
break;
|
|
18142
18323
|
case "system:slashPalette":
|
|
18143
|
-
|
|
18324
|
+
if (!inputHostsSlashMenu) {
|
|
18325
|
+
openSlashMenu();
|
|
18326
|
+
}
|
|
18144
18327
|
break;
|
|
18145
18328
|
case "system:back":
|
|
18146
18329
|
if (canGoBack) {
|
|
@@ -18171,8 +18354,9 @@ function AppContent() {
|
|
|
18171
18354
|
}
|
|
18172
18355
|
};
|
|
18173
18356
|
const filteredCommands = searchCommands(paletteQuery.trim());
|
|
18357
|
+
const slashMenuHost = inChatSession ? "chat" : location.pathname === "/" || location.pathname === "/home" ? "home" : "other";
|
|
18174
18358
|
const filteredSlashRoutes = getSlashMenuItems(slashMenuQuery, {
|
|
18175
|
-
|
|
18359
|
+
host: slashMenuHost
|
|
18176
18360
|
});
|
|
18177
18361
|
const selectedSlashRouteIndex = Math.min(slashMenuSelected, Math.max(filteredSlashRoutes.length - 1, 0));
|
|
18178
18362
|
const isDownKey2 = (keyEvent) => isDownKey(keyEvent.name, { vim: false });
|
|
@@ -18202,10 +18386,24 @@ function AppContent() {
|
|
|
18202
18386
|
};
|
|
18203
18387
|
const handleSlashMenuKeyDown = (keyEvent) => {
|
|
18204
18388
|
const maxIndex = filteredSlashRoutes.length - 1;
|
|
18205
|
-
if (
|
|
18206
|
-
|
|
18207
|
-
|
|
18208
|
-
|
|
18389
|
+
if (!inputHostsSlashMenu) {
|
|
18390
|
+
if (isBackspaceKey2(keyEvent)) {
|
|
18391
|
+
captureKeyEvent(keyEvent);
|
|
18392
|
+
if (slashMenuQuery.trim().length <= 1) {
|
|
18393
|
+
closeSlashMenu();
|
|
18394
|
+
} else {
|
|
18395
|
+
setSlashMenuQuery((query) => query.length > 1 ? query.slice(0, -1) : query);
|
|
18396
|
+
setSlashMenuSelected(0);
|
|
18397
|
+
}
|
|
18398
|
+
return;
|
|
18399
|
+
}
|
|
18400
|
+
const typed = keyEvent.sequence ?? "";
|
|
18401
|
+
if (typed.length === 1 && typed >= " " && typed !== "\x7F" && !keyEvent.ctrl && !isEnterKey2(keyEvent) && !isEscapeKey2(keyEvent) && !isUpKey2(keyEvent) && !isDownKey2(keyEvent)) {
|
|
18402
|
+
captureKeyEvent(keyEvent);
|
|
18403
|
+
setSlashMenuQuery((query) => query + typed);
|
|
18404
|
+
setSlashMenuSelected(0);
|
|
18405
|
+
return;
|
|
18406
|
+
}
|
|
18209
18407
|
}
|
|
18210
18408
|
if (maxIndex < 0) {
|
|
18211
18409
|
if (isEscapeKey2(keyEvent)) {
|
|
@@ -18271,17 +18469,17 @@ function AppContent() {
|
|
|
18271
18469
|
});
|
|
18272
18470
|
const configBadge = useConfigBadge(configRefreshNonce);
|
|
18273
18471
|
const needsOnboarding = configBadge.status === "available" && configBadge.missingCredentialHints.length > 0;
|
|
18274
|
-
|
|
18472
|
+
useEffect21(() => {
|
|
18275
18473
|
if (needsOnboarding && location.pathname !== "/onboarding") {
|
|
18276
18474
|
navigate("/onboarding");
|
|
18277
18475
|
}
|
|
18278
18476
|
}, [location.pathname, navigate, needsOnboarding]);
|
|
18279
18477
|
const getFooterStatus = () => {
|
|
18280
18478
|
if (slashMenuOpen) {
|
|
18281
|
-
return "Slash pages
|
|
18479
|
+
return "Slash pages \xB7 \u2191/\u2193 select \xB7 Enter open \xB7 Esc close";
|
|
18282
18480
|
}
|
|
18283
|
-
const backHint = canGoBack ? `Esc/${BACK_SHORTCUT_LABEL}
|
|
18284
|
-
return backHint + "/
|
|
18481
|
+
const backHint = canGoBack ? `Esc/${BACK_SHORTCUT_LABEL} back \xB7 ` : "";
|
|
18482
|
+
return backHint + "/ pages \xB7 Ctrl+P commands \xB7 F1 help \xB7 Ctrl+C quit";
|
|
18285
18483
|
};
|
|
18286
18484
|
return /* @__PURE__ */ jsxDEV39("box", {
|
|
18287
18485
|
flexDirection: "column",
|