xgen-dex-cli 1.7.2 → 1.9.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.
@@ -2,19 +2,19 @@ import {
2
2
  DexError,
3
3
  dataDirectory,
4
4
  publicError
5
- } from "./chunk-ULMEXJOR.js";
5
+ } from "./chunk-KY3K4GV4.js";
6
6
 
7
7
  // src/tui/index.tsx
8
8
  import { render } from "ink";
9
9
  import { stdin, stdout } from "node:process";
10
10
 
11
11
  // src/tui/app.tsx
12
- import { useCallback, useEffect as useEffect8, useState as useState11 } from "react";
13
- import { Box as Box10, Text as Text10, useApp as useApp2, useInput as useInput9 } from "ink";
12
+ import { useCallback, useEffect as useEffect9, useState as useState12 } from "react";
13
+ import { Box as Box11, Text as Text11, useApp as useApp2, useInput as useInput10 } from "ink";
14
14
 
15
15
  // src/tui/dashboard.tsx
16
- import { useEffect as useEffect6, useReducer, useRef as useRef3, useState as useState7 } from "react";
17
- import { Box as Box6, Text as Text6, useApp, useInput as useInput5 } from "ink";
16
+ import { useEffect as useEffect7, useReducer, useRef as useRef3, useState as useState8 } from "react";
17
+ import { Box as Box7, Text as Text7, useApp, useInput as useInput6 } from "ink";
18
18
 
19
19
  // src/tui/chat-state.ts
20
20
  var initialChatState = { messages: [], running: false };
@@ -917,8 +917,204 @@ function when(conversation) {
917
917
  return sameDay ? `\uC624\uB298 ${pad(date.getHours())}:${pad(date.getMinutes())}` : `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
918
918
  }
919
919
 
920
+ // src/tui/agent-create.tsx
921
+ import { useEffect as useEffect5, useMemo, useState as useState6 } from "react";
922
+ import { Box as Box6, Text as Text6, useInput as useInput5 } from "ink";
923
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
924
+ var ADVANCED_ORDER = [
925
+ "system_prompt",
926
+ "temperature",
927
+ "max_tokens",
928
+ "max_iterations",
929
+ "context_window",
930
+ "tool_exposure",
931
+ "enable_builtin_tools",
932
+ "enable_self_evolution",
933
+ "enable_delegation",
934
+ "enable_memory",
935
+ "enable_compaction",
936
+ "streaming",
937
+ "base_url"
938
+ ];
939
+ function advancedFields(settings) {
940
+ const rank = (id) => {
941
+ const i = ADVANCED_ORDER.indexOf(id);
942
+ return i === -1 ? ADVANCED_ORDER.length : i;
943
+ };
944
+ return [...settings].sort((a, b) => rank(a.id) - rank(b.id)).map((setting) => {
945
+ const type = (setting.type || "").toUpperCase();
946
+ if (type === "BOOL") return { key: setting.id, label: setting.label, kind: "toggle" };
947
+ if (setting.options && setting.options.length > 0) {
948
+ return {
949
+ key: setting.id,
950
+ label: setting.label,
951
+ kind: "choice",
952
+ choices: setting.options
953
+ };
954
+ }
955
+ return { key: setting.id, label: setting.label, kind: "text" };
956
+ });
957
+ }
958
+ function AgentCreateScreen(props) {
959
+ const [options, setOptions] = useState6();
960
+ const [loadError, setLoadError] = useState6();
961
+ const [values, setValues] = useState6({});
962
+ const [cursor, setCursor] = useState6(0);
963
+ const [advanced, setAdvanced] = useState6(false);
964
+ const [busy, setBusy] = useState6(false);
965
+ const [error, setError] = useState6();
966
+ useEffect5(() => {
967
+ let cancelled = false;
968
+ props.engine.agentCreateOptions(props.profile).then((data) => {
969
+ if (cancelled) return;
970
+ const provider = data.providers.find((p) => p.value === data.defaultProvider)?.value ?? data.providers[0]?.value ?? "";
971
+ const info = data.providers.find((p) => p.value === provider);
972
+ setOptions(data);
973
+ const seeded = {};
974
+ for (const setting of data.settings) seeded[setting.id] = setting.default;
975
+ setValues({
976
+ ...seeded,
977
+ ...data.defaults,
978
+ name: "",
979
+ provider,
980
+ model: info?.defaultModel || info?.models[0]?.value || ""
981
+ });
982
+ }).catch((err) => {
983
+ if (!cancelled) setLoadError(publicError(err).message);
984
+ });
985
+ return () => {
986
+ cancelled = true;
987
+ };
988
+ }, [props.engine, props.profile]);
989
+ const providerInfo = useMemo(
990
+ () => options?.providers.find((p) => p.value === values.provider),
991
+ [options, values.provider]
992
+ );
993
+ const fields = useMemo(() => {
994
+ if (!options) return [];
995
+ const base = [
996
+ { key: "name", label: "\uC774\uB984", kind: "text", hint: "\uC608: \uC601\uC5C5 \uB9AC\uC11C\uCE58 \uB3C4\uC6B0\uBBF8" },
997
+ {
998
+ key: "provider",
999
+ label: "AI \uC81C\uACF5\uC0AC",
1000
+ kind: "choice",
1001
+ choices: options.providers.map((p) => ({ value: p.value, label: p.label }))
1002
+ },
1003
+ { key: "model", label: "\uBAA8\uB378", kind: "choice", choices: providerInfo?.models ?? [] }
1004
+ ];
1005
+ return advanced ? [...base, ...advancedFields(options.settings)] : base;
1006
+ }, [options, providerInfo, advanced]);
1007
+ const active = fields[cursor];
1008
+ const name = String(values.name ?? "").trim();
1009
+ const setValue = (key, value) => {
1010
+ setValues((prev) => {
1011
+ if (key !== "provider") return { ...prev, [key]: value };
1012
+ const info = options?.providers.find((p) => p.value === value);
1013
+ return { ...prev, provider: value, model: info?.defaultModel || info?.models[0]?.value || "" };
1014
+ });
1015
+ };
1016
+ const cycle = (field, step) => {
1017
+ if (field.kind === "toggle") {
1018
+ setValue(field.key, !values[field.key]);
1019
+ return;
1020
+ }
1021
+ const choices = field.choices ?? [];
1022
+ if (choices.length === 0) return;
1023
+ const at = Math.max(0, choices.findIndex((c) => c.value === String(values[field.key] ?? "")));
1024
+ const next = (at + step + choices.length) % choices.length;
1025
+ setValue(field.key, choices[next].value);
1026
+ };
1027
+ const submit = async () => {
1028
+ if (!name || busy) return;
1029
+ setBusy(true);
1030
+ setError(void 0);
1031
+ try {
1032
+ const { name: _n, provider: _p, model: _m, ...settings } = values;
1033
+ const created = await props.engine.createAgent(
1034
+ {
1035
+ name,
1036
+ provider: String(values.provider ?? ""),
1037
+ model: String(values.model ?? ""),
1038
+ settings
1039
+ },
1040
+ props.profile
1041
+ );
1042
+ props.onCreated(created);
1043
+ } catch (err) {
1044
+ setError(publicError(err).message);
1045
+ } finally {
1046
+ setBusy(false);
1047
+ }
1048
+ };
1049
+ useInput5((input, key) => {
1050
+ const onText = active?.kind === "text";
1051
+ if (key.escape) {
1052
+ props.onCancel();
1053
+ return;
1054
+ }
1055
+ if (key.tab) {
1056
+ setAdvanced((v) => !v);
1057
+ return;
1058
+ }
1059
+ if (key.upArrow) {
1060
+ setCursor((c) => Math.max(0, c - 1));
1061
+ return;
1062
+ }
1063
+ if (key.downArrow) {
1064
+ setCursor((c) => Math.min(fields.length - 1, c + 1));
1065
+ return;
1066
+ }
1067
+ if (!active || onText) return;
1068
+ if (key.leftArrow) cycle(active, -1);
1069
+ else if (key.rightArrow) cycle(active, 1);
1070
+ else if (input === " " && !key.ctrl && !key.meta) cycle(active, 1);
1071
+ else if (key.return) void submit();
1072
+ });
1073
+ if (loadError) {
1074
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", padding: 1, children: [
1075
+ /* @__PURE__ */ jsx6(Text6, { color: "red", children: loadError }),
1076
+ /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Esc \uB85C \uB3CC\uC544\uAC11\uB2C8\uB2E4." })
1077
+ ] });
1078
+ }
1079
+ if (!options) {
1080
+ return /* @__PURE__ */ jsx6(Box6, { padding: 1, children: /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "\uBD88\uB7EC\uC624\uB294 \uC911..." }) });
1081
+ }
1082
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
1083
+ /* @__PURE__ */ jsx6(Text6, { bold: true, children: "\uC0C8 \uC5D0\uC774\uC804\uD2B8" }),
1084
+ /* @__PURE__ */ jsx6(Text6, { dimColor: true, wrap: "truncate-end", children: "\uC774\uB984\uACFC \uBAA8\uB378\uB9CC \uC815\uD558\uBA74 \uB429\uB2C8\uB2E4. \uB3C4\uAD6C\xB7\uAE30\uC5B5\xB7\uC790\uAE30\uC9C4\uD654\uB294 \uC774\uBBF8 \uC548\uC5D0 \uC788\uC2B5\uB2C8\uB2E4." }),
1085
+ /* @__PURE__ */ jsx6(Box6, { height: 1 }),
1086
+ fields.map((field, index) => {
1087
+ const focused = index === cursor;
1088
+ const raw = values[field.key];
1089
+ const shown = field.kind === "toggle" ? raw ? "\uCF2C" : "\uB054" : field.kind === "choice" ? field.choices?.find((c) => c.value === String(raw ?? ""))?.label ?? String(raw ?? "") : String(raw ?? "");
1090
+ return /* @__PURE__ */ jsxs6(Box6, { children: [
1091
+ /* @__PURE__ */ jsx6(Box6, { width: 24, flexShrink: 0, children: /* @__PURE__ */ jsxs6(Text6, { color: focused ? "cyan" : void 0, wrap: "truncate-end", children: [
1092
+ focused ? "\u203A" : " ",
1093
+ " ",
1094
+ field.label
1095
+ ] }) }),
1096
+ field.kind === "text" && focused ? /* @__PURE__ */ jsx6(
1097
+ ImeTextInput,
1098
+ {
1099
+ value: String(raw ?? ""),
1100
+ onChange: (v) => setValue(field.key, v),
1101
+ onSubmit: () => void submit(),
1102
+ focus: true,
1103
+ placeholder: field.hint ?? "",
1104
+ hangulMode: props.hangulMode,
1105
+ onHangulModeChange: props.onHangulModeChange
1106
+ }
1107
+ ) : /* @__PURE__ */ jsx6(Text6, { dimColor: !focused, wrap: "truncate-end", children: field.kind === "text" ? shown || field.hint || "" : `\u2039 ${shown} \u203A` })
1108
+ ] }, field.key);
1109
+ }),
1110
+ /* @__PURE__ */ jsx6(Box6, { height: 1 }),
1111
+ error ? /* @__PURE__ */ jsx6(Text6, { color: "red", children: error }) : null,
1112
+ /* @__PURE__ */ jsx6(Text6, { dimColor: true, wrap: "truncate-end", children: busy ? "\uB9CC\uB4DC\uB294 \uC911..." : `\u2191\u2193 \uC774\uB3D9 \xB7 \u2190\u2192 \uACE0\uB974\uAE30 \xB7 Tab ${advanced ? "\uC138\uBD80\uC124\uC815 \uC811\uAE30" : "\uC138\uBD80\uC124\uC815"} \xB7 Enter \uB9CC\uB4E4\uAE30 \xB7 Esc \uCDE8\uC18C` })
1113
+ ] });
1114
+ }
1115
+
920
1116
  // src/tui/use-terminal-size.ts
921
- import { useEffect as useEffect5, useState as useState6 } from "react";
1117
+ import { useEffect as useEffect6, useState as useState7 } from "react";
922
1118
  import { useStdout } from "ink";
923
1119
  function useTerminalSize() {
924
1120
  const { stdout: stdout2 } = useStdout();
@@ -927,8 +1123,8 @@ function useTerminalSize() {
927
1123
  const rows = stdout2.rows || 30;
928
1124
  return { columns, rows, wide: columns >= 88 };
929
1125
  };
930
- const [size, setSize] = useState6(read);
931
- useEffect5(() => {
1126
+ const [size, setSize] = useState7(read);
1127
+ useEffect6(() => {
932
1128
  const resize = () => setSize(read());
933
1129
  stdout2.on("resize", resize);
934
1130
  return () => {
@@ -939,18 +1135,22 @@ function useTerminalSize() {
939
1135
  }
940
1136
 
941
1137
  // src/tui/dashboard.tsx
942
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1138
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
943
1139
  function AgentSidebar(props) {
944
1140
  const radius = Math.max(3, Math.floor((props.height - 4) / 2));
945
1141
  const start = Math.max(0, props.cursor - radius);
946
1142
  const visible = props.agents.slice(start, start + radius * 2 + 1);
947
- return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", width: 30, borderStyle: "round", borderColor: props.focused ? "cyan" : "gray", paddingX: 1, children: [
948
- /* @__PURE__ */ jsx6(Text6, { bold: true, children: "Agents" }),
1143
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", width: 30, borderStyle: "round", borderColor: props.focused ? "cyan" : "gray", paddingX: 1, children: [
1144
+ /* @__PURE__ */ jsx7(Text7, { bold: true, children: "Agents" }),
1145
+ /* @__PURE__ */ jsxs7(Text7, { color: props.cursor === -1 && props.focused ? "cyan" : void 0, wrap: "truncate-end", children: [
1146
+ props.cursor === -1 ? "\u203A" : " ",
1147
+ " \uFF0B \uC0C8 \uC5D0\uC774\uC804\uD2B8"
1148
+ ] }),
949
1149
  visible.map((agent) => {
950
1150
  const index = props.agents.indexOf(agent);
951
1151
  const cursor = index === props.cursor;
952
1152
  const selected = agent.workflowId === props.selected;
953
- return /* @__PURE__ */ jsxs6(Text6, { color: cursor && props.focused ? "cyan" : void 0, wrap: "truncate-end", children: [
1153
+ return /* @__PURE__ */ jsxs7(Text7, { color: cursor && props.focused ? "cyan" : void 0, wrap: "truncate-end", children: [
954
1154
  cursor ? "\u203A" : " ",
955
1155
  " ",
956
1156
  selected ? "\u25CF" : "\u25CB",
@@ -958,7 +1158,7 @@ function AgentSidebar(props) {
958
1158
  agent.workflowName
959
1159
  ] }, agent.workflowId);
960
1160
  }),
961
- props.agents.length === 0 ? /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "\uC0AC\uC6A9 \uAC00\uB2A5\uD55C Agent\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." }) : null
1161
+ props.agents.length === 0 ? /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "\uC0AC\uC6A9 \uAC00\uB2A5\uD55C Agent\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." }) : null
962
1162
  ] });
963
1163
  }
964
1164
  function ChatPane(props) {
@@ -967,22 +1167,22 @@ function ChatPane(props) {
967
1167
  const height = box?.height ?? 1;
968
1168
  const lines = renderTranscript(props.messages, props.agent?.workflowName ?? "Agent", width);
969
1169
  const view = viewportOf(lines, height, props.scrollUp);
970
- useEffect6(() => {
1170
+ useEffect7(() => {
971
1171
  props.onViewport(lines.length, height);
972
1172
  }, [lines.length, height]);
973
- return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", flexGrow: 1, borderStyle: "round", borderColor: "blue", paddingX: 1, children: [
974
- /* @__PURE__ */ jsxs6(Box6, { children: [
975
- /* @__PURE__ */ jsx6(Text6, { bold: true, wrap: "truncate-end", children: props.agent?.workflowName ?? "Agent\uB97C \uC120\uD0DD\uD558\uC138\uC694" }),
976
- view.below > 0 ? /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
1173
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", flexGrow: 1, borderStyle: "round", borderColor: "blue", paddingX: 1, children: [
1174
+ /* @__PURE__ */ jsxs7(Box7, { children: [
1175
+ /* @__PURE__ */ jsx7(Text7, { bold: true, wrap: "truncate-end", children: props.agent?.workflowName ?? "Agent\uB97C \uC120\uD0DD\uD558\uC138\uC694" }),
1176
+ view.below > 0 ? /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
977
1177
  " \xB7 \u2193",
978
1178
  view.below,
979
1179
  "\uC904"
980
1180
  ] }) : null
981
1181
  ] }),
982
- /* @__PURE__ */ jsxs6(Box6, { ref, flexDirection: "column", flexGrow: 1, overflow: "hidden", children: [
983
- view.lines.length === 0 ? /* @__PURE__ */ jsx6(Text6, { dimColor: true, wrap: "truncate-end", children: props.agent ? "\uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD574 \uB300\uD654\uB97C \uC2DC\uC791\uD558\uC138\uC694." : "\uC67C\uCABD\uC5D0\uC11C Agent\uB97C \uC120\uD0DD\uD558\uC138\uC694." }) : null,
984
- view.lines.map((line) => /* @__PURE__ */ jsx6(
985
- Text6,
1182
+ /* @__PURE__ */ jsxs7(Box7, { ref, flexDirection: "column", flexGrow: 1, overflow: "hidden", children: [
1183
+ view.lines.length === 0 ? /* @__PURE__ */ jsx7(Text7, { dimColor: true, wrap: "truncate-end", children: props.agent ? "\uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD574 \uB300\uD654\uB97C \uC2DC\uC791\uD558\uC138\uC694." : "\uC67C\uCABD\uC5D0\uC11C Agent\uB97C \uC120\uD0DD\uD558\uC138\uC694." }) : null,
1184
+ view.lines.map((line) => /* @__PURE__ */ jsx7(
1185
+ Text7,
986
1186
  {
987
1187
  wrap: "truncate-end",
988
1188
  bold: line.role === "label",
@@ -993,17 +1193,17 @@ function ChatPane(props) {
993
1193
  line.key
994
1194
  ))
995
1195
  ] }),
996
- props.status ? /* @__PURE__ */ jsxs6(Text6, { color: "yellow", wrap: "truncate-end", children: [
1196
+ props.status ? /* @__PURE__ */ jsxs7(Text7, { color: "yellow", wrap: "truncate-end", children: [
997
1197
  "\u25C6 ",
998
1198
  props.status
999
1199
  ] }) : null
1000
1200
  ] });
1001
1201
  }
1002
1202
  function Composer(props) {
1003
- return /* @__PURE__ */ jsxs6(Box6, { borderStyle: "round", borderColor: props.focused ? "cyan" : "gray", paddingX: 1, children: [
1004
- /* @__PURE__ */ jsx6(Text6, { color: props.hangulMode ? "yellow" : void 0, dimColor: !props.hangulMode, children: props.hangulMode ? "\uD55C" : "EN" }),
1005
- /* @__PURE__ */ jsx6(Text6, { color: "cyan", children: " \u203A " }),
1006
- props.disabled ? /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "\uC751\uB2F5\uC744 \uAE30\uB2E4\uB9AC\uB294 \uC911..." }) : /* @__PURE__ */ jsx6(
1203
+ return /* @__PURE__ */ jsxs7(Box7, { borderStyle: "round", borderColor: props.focused ? "cyan" : "gray", paddingX: 1, children: [
1204
+ /* @__PURE__ */ jsx7(Text7, { color: props.hangulMode ? "yellow" : void 0, dimColor: !props.hangulMode, children: props.hangulMode ? "\uD55C" : "EN" }),
1205
+ /* @__PURE__ */ jsx7(Text7, { color: "cyan", children: " \u203A " }),
1206
+ props.disabled ? /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "\uC751\uB2F5\uC744 \uAE30\uB2E4\uB9AC\uB294 \uC911..." }) : /* @__PURE__ */ jsx7(
1007
1207
  ImeTextInput,
1008
1208
  {
1009
1209
  value: props.value,
@@ -1021,24 +1221,25 @@ function Dashboard(props) {
1021
1221
  const { exit } = useApp();
1022
1222
  const size = useTerminalSize();
1023
1223
  const bodyHeight = Math.max(12, size.rows - 5);
1024
- const [focus, setFocus] = useState7("agents");
1025
- const [cursor, setCursor] = useState7(0);
1026
- const [selected, setSelected] = useState7(() => {
1224
+ const [focus, setFocus] = useState8("agents");
1225
+ const [cursor, setCursor] = useState8(0);
1226
+ const [creatingAgent, setCreatingAgent] = useState8(false);
1227
+ const [selected, setSelected] = useState8(() => {
1027
1228
  const first = props.session.agents[0];
1028
1229
  return first ? { workflowId: first.workflowId, workflowName: first.workflowName } : void 0;
1029
1230
  });
1030
- const [input, setInput] = useState7("");
1231
+ const [input, setInput] = useState8("");
1031
1232
  const [chat, dispatch] = useReducer(chatReducer, initialChatState);
1032
- const [palette, setPalette] = useState7(false);
1033
- const [history, setHistory] = useState7(false);
1034
- const [start, setStart] = useState7();
1035
- const [scrollUp, setScrollUp] = useState7(0);
1036
- const [hangulMode, setHangulMode] = useState7(props.preferences?.hangulMode ?? false);
1233
+ const [palette, setPalette] = useState8(false);
1234
+ const [history, setHistory] = useState8(false);
1235
+ const [start, setStart] = useState8();
1236
+ const [scrollUp, setScrollUp] = useState8(0);
1237
+ const [hangulMode, setHangulMode] = useState8(props.preferences?.hangulMode ?? false);
1037
1238
  const changeHangulMode = (enabled) => {
1038
1239
  setHangulMode(enabled);
1039
1240
  props.preferences?.onHangulModeChange?.(enabled);
1040
1241
  };
1041
- useEffect6(
1242
+ useEffect7(
1042
1243
  () => props.preferences?.onModeKey?.(
1043
1244
  () => setHangulMode((current) => {
1044
1245
  props.preferences?.onHangulModeChange?.(!current);
@@ -1048,10 +1249,14 @@ function Dashboard(props) {
1048
1249
  [props.preferences]
1049
1250
  );
1050
1251
  const viewport = useRef3({ lineCount: 0, height: 0 });
1051
- const [starting, setStarting] = useState7(false);
1252
+ const [starting, setStarting] = useState8(false);
1052
1253
  const controller = useRef3(null);
1053
- useEffect6(() => () => controller.current?.abort(), []);
1254
+ useEffect7(() => () => controller.current?.abort(), []);
1054
1255
  const selectAgent = async () => {
1256
+ if (cursor === -1) {
1257
+ setCreatingAgent(true);
1258
+ return;
1259
+ }
1055
1260
  const agent = props.session.agents[cursor];
1056
1261
  if (!agent || chat.running || starting) return;
1057
1262
  const ref = { workflowId: agent.workflowId, workflowName: agent.workflowName };
@@ -1136,7 +1341,7 @@ function Dashboard(props) {
1136
1341
  const limit = maximumScroll(lineCount, height);
1137
1342
  setScrollUp((current) => Math.min(limit, Math.max(0, current - direction * step)));
1138
1343
  };
1139
- useInput5(
1344
+ useInput6(
1140
1345
  (keyInput, key) => {
1141
1346
  if (key.ctrl && keyInput === "k") setPalette(true);
1142
1347
  else if (key.ctrl && keyInput === "p") {
@@ -1151,14 +1356,14 @@ function Dashboard(props) {
1151
1356
  else if (key.escape && chat.running) cancelTurn();
1152
1357
  else if (key.escape) setFocus("agents");
1153
1358
  else if (key.tab) setFocus((current) => current === "agents" ? "composer" : "agents");
1154
- else if (focus === "agents" && key.upArrow) setCursor((current) => Math.max(0, current - 1));
1359
+ else if (focus === "agents" && key.upArrow) setCursor((current) => Math.max(-1, current - 1));
1155
1360
  else if (focus === "agents" && key.downArrow && props.session.agents.length > 0) {
1156
1361
  setCursor((current) => Math.min(props.session.agents.length - 1, current + 1));
1157
1362
  } else if (focus === "agents" && key.return) void selectAgent();
1158
1363
  },
1159
1364
  // 갈림길·팔레트·이력 화면이 떠 있으면 그 화면이 키를 갖는다 — 여기서도 받으면
1160
1365
  // 방향키 하나가 두 곳에서 움직인다.
1161
- { isActive: !palette && !history && !start }
1366
+ { isActive: !palette && !history && !start && !creatingAgent }
1162
1367
  );
1163
1368
  const paletteActions = [
1164
1369
  { id: "new", label: "\uC0C8 \uB300\uD654", run: newConversation },
@@ -1191,10 +1396,25 @@ function Dashboard(props) {
1191
1396
  { id: "quit", label: "\uC885\uB8CC", run: exit }
1192
1397
  ];
1193
1398
  let body;
1194
- if (palette) {
1195
- body = /* @__PURE__ */ jsx6(CommandPalette, { actions: paletteActions, onCancel: () => setPalette(false) });
1399
+ if (creatingAgent) {
1400
+ body = /* @__PURE__ */ jsx7(
1401
+ AgentCreateScreen,
1402
+ {
1403
+ engine: props.engine,
1404
+ profile: props.session.profile,
1405
+ hangulMode,
1406
+ onHangulModeChange: changeHangulMode,
1407
+ onCancel: () => setCreatingAgent(false),
1408
+ onCreated: (agent) => {
1409
+ setCreatingAgent(false);
1410
+ openNewChat(agent);
1411
+ }
1412
+ }
1413
+ );
1414
+ } else if (palette) {
1415
+ body = /* @__PURE__ */ jsx7(CommandPalette, { actions: paletteActions, onCancel: () => setPalette(false) });
1196
1416
  } else if (history) {
1197
- body = /* @__PURE__ */ jsx6(
1417
+ body = /* @__PURE__ */ jsx7(
1198
1418
  HistoryScreen,
1199
1419
  {
1200
1420
  engine: props.engine,
@@ -1204,7 +1424,7 @@ function Dashboard(props) {
1204
1424
  }
1205
1425
  );
1206
1426
  } else {
1207
- const sidebar = /* @__PURE__ */ jsx6(
1427
+ const sidebar = /* @__PURE__ */ jsx7(
1208
1428
  AgentSidebar,
1209
1429
  {
1210
1430
  agents: props.session.agents,
@@ -1214,7 +1434,7 @@ function Dashboard(props) {
1214
1434
  height: bodyHeight
1215
1435
  }
1216
1436
  );
1217
- const conversation = start ? /* @__PURE__ */ jsx6(
1437
+ const conversation = start ? /* @__PURE__ */ jsx7(
1218
1438
  StartPanel,
1219
1439
  {
1220
1440
  engine: props.engine,
@@ -1228,8 +1448,8 @@ function Dashboard(props) {
1228
1448
  setFocus("agents");
1229
1449
  }
1230
1450
  }
1231
- ) : /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", flexGrow: 1, children: [
1232
- /* @__PURE__ */ jsx6(
1451
+ ) : /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", flexGrow: 1, children: [
1452
+ /* @__PURE__ */ jsx7(
1233
1453
  ChatPane,
1234
1454
  {
1235
1455
  agent: selected,
@@ -1241,7 +1461,7 @@ function Dashboard(props) {
1241
1461
  }
1242
1462
  }
1243
1463
  ),
1244
- /* @__PURE__ */ jsx6(
1464
+ /* @__PURE__ */ jsx7(
1245
1465
  Composer,
1246
1466
  {
1247
1467
  value: input,
@@ -1254,13 +1474,13 @@ function Dashboard(props) {
1254
1474
  }
1255
1475
  )
1256
1476
  ] });
1257
- body = size.wide ? /* @__PURE__ */ jsxs6(Box6, { height: bodyHeight, children: [
1477
+ body = size.wide ? /* @__PURE__ */ jsxs7(Box7, { height: bodyHeight, children: [
1258
1478
  sidebar,
1259
1479
  conversation
1260
- ] }) : focus === "agents" ? /* @__PURE__ */ jsx6(Box6, { height: bodyHeight, children: sidebar }) : /* @__PURE__ */ jsx6(Box6, { height: bodyHeight, children: conversation });
1480
+ ] }) : focus === "agents" ? /* @__PURE__ */ jsx7(Box7, { height: bodyHeight, children: sidebar }) : /* @__PURE__ */ jsx7(Box7, { height: bodyHeight, children: conversation });
1261
1481
  }
1262
- return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
1263
- /* @__PURE__ */ jsx6(
1482
+ return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
1483
+ /* @__PURE__ */ jsx7(
1264
1484
  Header,
1265
1485
  {
1266
1486
  profile: props.session.profile,
@@ -1269,7 +1489,7 @@ function Dashboard(props) {
1269
1489
  }
1270
1490
  ),
1271
1491
  body,
1272
- /* @__PURE__ */ jsx6(
1492
+ /* @__PURE__ */ jsx7(
1273
1493
  Footer,
1274
1494
  {
1275
1495
  mode: hangulMode ? "\uD55C" : "EN",
@@ -1280,14 +1500,14 @@ function Dashboard(props) {
1280
1500
  }
1281
1501
 
1282
1502
  // src/tui/login-screen.tsx
1283
- import { useState as useState8 } from "react";
1284
- import { Box as Box7, Text as Text7, useInput as useInput6 } from "ink";
1285
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1503
+ import { useState as useState9 } from "react";
1504
+ import { Box as Box8, Text as Text8, useInput as useInput7 } from "ink";
1505
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1286
1506
  function LoginScreen(props) {
1287
- const [email, setEmail] = useState8("");
1288
- const [password, setPassword] = useState8("");
1289
- const [focus, setFocus] = useState8("email");
1290
- useInput6(
1507
+ const [email, setEmail] = useState9("");
1508
+ const [password, setPassword] = useState9("");
1509
+ const [focus, setFocus] = useState9("email");
1510
+ useInput7(
1291
1511
  (input, key) => {
1292
1512
  if (key.tab) setFocus((current) => current === "email" ? "password" : "email");
1293
1513
  if (key.ctrl && input === "p") props.onProfiles();
@@ -1306,17 +1526,17 @@ function LoginScreen(props) {
1306
1526
  props.onSubmit(email.trim(), secret);
1307
1527
  }
1308
1528
  };
1309
- return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
1310
- /* @__PURE__ */ jsx7(Header, { profile: props.profile, connected: false }),
1311
- /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "blue", padding: 1, children: [
1312
- /* @__PURE__ */ jsx7(Text7, { bold: true, children: "\uB85C\uADF8\uC778" }),
1313
- /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
1529
+ return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
1530
+ /* @__PURE__ */ jsx8(Header, { profile: props.profile, connected: false }),
1531
+ /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "blue", padding: 1, children: [
1532
+ /* @__PURE__ */ jsx8(Text8, { bold: true, children: "\uB85C\uADF8\uC778" }),
1533
+ /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
1314
1534
  props.serverUrl,
1315
1535
  " ",
1316
- /* @__PURE__ */ jsx7(Text7, { color: "cyan", children: "(Ctrl+E \uBC14\uAFB8\uAE30)" })
1536
+ /* @__PURE__ */ jsx8(Text8, { color: "cyan", children: "(Ctrl+E \uBC14\uAFB8\uAE30)" })
1317
1537
  ] }),
1318
- /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginTop: 1, children: [
1319
- /* @__PURE__ */ jsx7(
1538
+ /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
1539
+ /* @__PURE__ */ jsx8(
1320
1540
  FormField,
1321
1541
  {
1322
1542
  label: "Email",
@@ -1327,7 +1547,7 @@ function LoginScreen(props) {
1327
1547
  placeholder: "me@corp.com"
1328
1548
  }
1329
1549
  ),
1330
- /* @__PURE__ */ jsx7(
1550
+ /* @__PURE__ */ jsx8(
1331
1551
  FormField,
1332
1552
  {
1333
1553
  label: "Password",
@@ -1339,25 +1559,25 @@ function LoginScreen(props) {
1339
1559
  }
1340
1560
  )
1341
1561
  ] }),
1342
- props.busy ? /* @__PURE__ */ jsx7(Loading, { label: "\uB85C\uADF8\uC778\uD558\uB294 \uC911..." }) : null,
1343
- props.error ? /* @__PURE__ */ jsx7(Notice, { error: true, children: props.error }) : null
1562
+ props.busy ? /* @__PURE__ */ jsx8(Loading, { label: "\uB85C\uADF8\uC778\uD558\uB294 \uC911..." }) : null,
1563
+ props.error ? /* @__PURE__ */ jsx8(Notice, { error: true, children: props.error }) : null
1344
1564
  ] }),
1345
- /* @__PURE__ */ jsx7(Footer, { text: "Tab \uC774\uB3D9 \xB7 Enter \uB85C\uADF8\uC778 \xB7 Ctrl+E \uC11C\uBC84 \xB7 Ctrl+P \uD504\uB85C\uD544 \xB7 Ctrl+Q \uC885\uB8CC" })
1565
+ /* @__PURE__ */ jsx8(Footer, { text: "Tab \uC774\uB3D9 \xB7 Enter \uB85C\uADF8\uC778 \xB7 Ctrl+E \uC11C\uBC84 \xB7 Ctrl+P \uD504\uB85C\uD544 \xB7 Ctrl+Q \uC885\uB8CC" })
1346
1566
  ] });
1347
1567
  }
1348
1568
 
1349
1569
  // src/tui/profile-screen.tsx
1350
- import { useEffect as useEffect7, useState as useState9 } from "react";
1351
- import { Box as Box8, Text as Text8, useInput as useInput7 } from "ink";
1352
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1570
+ import { useEffect as useEffect8, useState as useState10 } from "react";
1571
+ import { Box as Box9, Text as Text9, useInput as useInput8 } from "ink";
1572
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1353
1573
  function ProfileScreen(props) {
1354
- const [cursor, setCursor] = useState9(Math.max(0, props.profiles.findIndex((profile) => profile.current)));
1355
- const [creating, setCreating] = useState9(false);
1356
- const [focus, setFocus] = useState9("name");
1357
- const [name, setName] = useState9("");
1358
- const [serverUrl, setServerUrl] = useState9("");
1359
- useEffect7(() => setCursor((current) => Math.min(current, Math.max(0, props.profiles.length - 1))), [props.profiles]);
1360
- useInput7(
1574
+ const [cursor, setCursor] = useState10(Math.max(0, props.profiles.findIndex((profile) => profile.current)));
1575
+ const [creating, setCreating] = useState10(false);
1576
+ const [focus, setFocus] = useState10("name");
1577
+ const [name, setName] = useState10("");
1578
+ const [serverUrl, setServerUrl] = useState10("");
1579
+ useEffect8(() => setCursor((current) => Math.min(current, Math.max(0, props.profiles.length - 1))), [props.profiles]);
1580
+ useInput8(
1361
1581
  (input, key) => {
1362
1582
  if (key.escape) {
1363
1583
  if (creating) setCreating(false);
@@ -1387,12 +1607,12 @@ function ProfileScreen(props) {
1387
1607
  }
1388
1608
  if (name.trim() && serverUrl.trim()) props.onCreate(name.trim(), serverUrl.trim());
1389
1609
  };
1390
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
1391
- /* @__PURE__ */ jsx8(Header, {}),
1392
- /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1, children: [
1393
- /* @__PURE__ */ jsx8(Text8, { bold: true, children: creating ? "\uC0C8 \uD504\uB85C\uD544" : "\uD504\uB85C\uD544 \uC804\uD658" }),
1394
- creating ? /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
1395
- /* @__PURE__ */ jsx8(
1610
+ return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
1611
+ /* @__PURE__ */ jsx9(Header, {}),
1612
+ /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1, children: [
1613
+ /* @__PURE__ */ jsx9(Text9, { bold: true, children: creating ? "\uC0C8 \uD504\uB85C\uD544" : "\uD504\uB85C\uD544 \uC804\uD658" }),
1614
+ creating ? /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", marginTop: 1, children: [
1615
+ /* @__PURE__ */ jsx9(
1396
1616
  FormField,
1397
1617
  {
1398
1618
  label: "Name",
@@ -1403,7 +1623,7 @@ function ProfileScreen(props) {
1403
1623
  placeholder: "corp"
1404
1624
  }
1405
1625
  ),
1406
- /* @__PURE__ */ jsx8(
1626
+ /* @__PURE__ */ jsx9(
1407
1627
  FormField,
1408
1628
  {
1409
1629
  label: "Server URL",
@@ -1414,8 +1634,8 @@ function ProfileScreen(props) {
1414
1634
  placeholder: "https://xgen.example.com"
1415
1635
  }
1416
1636
  )
1417
- ] }) : /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
1418
- props.profiles.map((profile, index) => /* @__PURE__ */ jsxs8(Text8, { color: index === cursor ? "cyan" : void 0, children: [
1637
+ ] }) : /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", marginTop: 1, children: [
1638
+ props.profiles.map((profile, index) => /* @__PURE__ */ jsxs9(Text9, { color: index === cursor ? "cyan" : void 0, children: [
1419
1639
  index === cursor ? "\u203A" : " ",
1420
1640
  " ",
1421
1641
  profile.current ? "\u25CF" : "\u25CB",
@@ -1423,14 +1643,14 @@ function ProfileScreen(props) {
1423
1643
  profile.name,
1424
1644
  " \xB7",
1425
1645
  " ",
1426
- /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: profile.serverUrl })
1646
+ /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: profile.serverUrl })
1427
1647
  ] }, profile.name)),
1428
- props.profiles.length === 0 ? /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "\uC800\uC7A5\uB41C \uD504\uB85C\uD544\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." }) : null
1648
+ props.profiles.length === 0 ? /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "\uC800\uC7A5\uB41C \uD504\uB85C\uD544\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." }) : null
1429
1649
  ] }),
1430
- props.busy ? /* @__PURE__ */ jsx8(Loading, { label: "\uD504\uB85C\uD544\uC744 \uC804\uD658\uD558\uB294 \uC911..." }) : null,
1431
- props.error ? /* @__PURE__ */ jsx8(Notice, { error: true, children: props.error }) : null
1650
+ props.busy ? /* @__PURE__ */ jsx9(Loading, { label: "\uD504\uB85C\uD544\uC744 \uC804\uD658\uD558\uB294 \uC911..." }) : null,
1651
+ props.error ? /* @__PURE__ */ jsx9(Notice, { error: true, children: props.error }) : null
1432
1652
  ] }),
1433
- /* @__PURE__ */ jsx8(
1653
+ /* @__PURE__ */ jsx9(
1434
1654
  Footer,
1435
1655
  {
1436
1656
  text: creating ? "Tab \uC774\uB3D9 \xB7 Enter \uC800\uC7A5 \xB7 Esc \uB4A4\uB85C" : "\u2191\u2193 \uC774\uB3D9 \xB7 Enter \uC120\uD0DD \xB7 N \uC0C8 \uD504\uB85C\uD544 \xB7 Esc \uB2EB\uAE30"
@@ -1440,24 +1660,24 @@ function ProfileScreen(props) {
1440
1660
  }
1441
1661
 
1442
1662
  // src/tui/server-screen.tsx
1443
- import { useState as useState10 } from "react";
1444
- import { Box as Box9, Text as Text9, useInput as useInput8 } from "ink";
1445
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1663
+ import { useState as useState11 } from "react";
1664
+ import { Box as Box10, Text as Text10, useInput as useInput9 } from "ink";
1665
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1446
1666
  function ServerScreen(props) {
1447
- const [serverUrl, setServerUrl] = useState10(props.initialValue ?? "");
1667
+ const [serverUrl, setServerUrl] = useState11(props.initialValue ?? "");
1448
1668
  const editing = props.initialValue !== void 0;
1449
- useInput8(
1669
+ useInput9(
1450
1670
  (_input, key) => {
1451
1671
  if (key.escape) props.onCancel?.();
1452
1672
  },
1453
1673
  { isActive: !props.busy && !!props.onCancel }
1454
1674
  );
1455
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
1456
- /* @__PURE__ */ jsx9(Header, { profile: props.profile, connected: false }),
1457
- /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "blue", padding: 1, children: [
1458
- /* @__PURE__ */ jsx9(Text9, { bold: true, children: editing ? "\uC11C\uBC84 \uC8FC\uC18C \uBC14\uAFB8\uAE30" : "\uCC98\uC74C \uC624\uC168\uAD70\uC694" }),
1459
- /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "\uC5F0\uACB0\uD560 XGEN Gateway \uC8FC\uC18C\uB97C \uC785\uB825\uD558\uC138\uC694." }),
1460
- /* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(
1675
+ return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
1676
+ /* @__PURE__ */ jsx10(Header, { profile: props.profile, connected: false }),
1677
+ /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "blue", padding: 1, children: [
1678
+ /* @__PURE__ */ jsx10(Text10, { bold: true, children: editing ? "\uC11C\uBC84 \uC8FC\uC18C \uBC14\uAFB8\uAE30" : "\uCC98\uC74C \uC624\uC168\uAD70\uC694" }),
1679
+ /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "\uC5F0\uACB0\uD560 XGEN Gateway \uC8FC\uC18C\uB97C \uC785\uB825\uD558\uC138\uC694." }),
1680
+ /* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx10(
1461
1681
  FormField,
1462
1682
  {
1463
1683
  label: "Server URL",
@@ -1468,11 +1688,11 @@ function ServerScreen(props) {
1468
1688
  placeholder: "xgen.example.com"
1469
1689
  }
1470
1690
  ) }),
1471
- /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "https:// \uB294 \uC0DD\uB7B5\uD574\uB3C4 \uB429\uB2C8\uB2E4." }),
1472
- props.busy ? /* @__PURE__ */ jsx9(Loading, { label: "\uC11C\uBC84 \uD504\uB85C\uD544\uC744 \uC800\uC7A5\uD558\uB294 \uC911..." }) : null,
1473
- props.error ? /* @__PURE__ */ jsx9(Notice, { error: true, children: props.error }) : null
1691
+ /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "https:// \uB294 \uC0DD\uB7B5\uD574\uB3C4 \uB429\uB2C8\uB2E4." }),
1692
+ props.busy ? /* @__PURE__ */ jsx10(Loading, { label: "\uC11C\uBC84 \uD504\uB85C\uD544\uC744 \uC800\uC7A5\uD558\uB294 \uC911..." }) : null,
1693
+ props.error ? /* @__PURE__ */ jsx10(Notice, { error: true, children: props.error }) : null
1474
1694
  ] }),
1475
- /* @__PURE__ */ jsx9(
1695
+ /* @__PURE__ */ jsx10(
1476
1696
  Footer,
1477
1697
  {
1478
1698
  text: props.onCancel ? "Enter \uC800\uC7A5 \xB7 Esc \uCDE8\uC18C \xB7 Ctrl+Q \uC885\uB8CC" : "Enter \uACC4\uC18D \xB7 Ctrl+Q \uC885\uB8CC"
@@ -1482,20 +1702,20 @@ function ServerScreen(props) {
1482
1702
  }
1483
1703
 
1484
1704
  // src/tui/app.tsx
1485
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1705
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1486
1706
  function App({
1487
1707
  engine,
1488
1708
  preferences
1489
1709
  }) {
1490
1710
  const { exit } = useApp2();
1491
- const [route, setRoute] = useState11("boot");
1492
- const [session, setSession] = useState11();
1493
- const [profiles, setProfiles] = useState11([]);
1494
- const [loginTarget, setLoginTarget] = useState11();
1495
- const [editingServer, setEditingServer] = useState11();
1496
- const [busy, setBusy] = useState11(false);
1497
- const [error, setError] = useState11();
1498
- useInput9((input, key) => {
1711
+ const [route, setRoute] = useState12("boot");
1712
+ const [session, setSession] = useState12();
1713
+ const [profiles, setProfiles] = useState12([]);
1714
+ const [loginTarget, setLoginTarget] = useState12();
1715
+ const [editingServer, setEditingServer] = useState12();
1716
+ const [busy, setBusy] = useState12(false);
1717
+ const [error, setError] = useState12();
1718
+ useInput10((input, key) => {
1499
1719
  if (key.ctrl && input === "q") exit();
1500
1720
  });
1501
1721
  const bootstrap = useCallback(
@@ -1545,7 +1765,7 @@ function App({
1545
1765
  },
1546
1766
  [engine]
1547
1767
  );
1548
- useEffect8(() => {
1768
+ useEffect9(() => {
1549
1769
  void bootstrap();
1550
1770
  }, [bootstrap]);
1551
1771
  const configure = async (serverUrl) => {
@@ -1620,14 +1840,14 @@ function App({
1620
1840
  }
1621
1841
  };
1622
1842
  if (route === "boot") {
1623
- return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
1624
- /* @__PURE__ */ jsx10(Header, {}),
1625
- /* @__PURE__ */ jsx10(Loading, { label: "Dex\uB97C \uC900\uBE44\uD558\uB294 \uC911..." }),
1626
- /* @__PURE__ */ jsx10(Footer, { text: "Ctrl+Q \uC885\uB8CC" })
1843
+ return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
1844
+ /* @__PURE__ */ jsx11(Header, {}),
1845
+ /* @__PURE__ */ jsx11(Loading, { label: "Dex\uB97C \uC900\uBE44\uD558\uB294 \uC911..." }),
1846
+ /* @__PURE__ */ jsx11(Footer, { text: "Ctrl+Q \uC885\uB8CC" })
1627
1847
  ] });
1628
1848
  }
1629
1849
  if (route === "server") {
1630
- return /* @__PURE__ */ jsx10(
1850
+ return /* @__PURE__ */ jsx11(
1631
1851
  ServerScreen,
1632
1852
  {
1633
1853
  initialValue: editingServer?.serverUrl,
@@ -1644,7 +1864,7 @@ function App({
1644
1864
  );
1645
1865
  }
1646
1866
  if (route === "login" && loginTarget) {
1647
- return /* @__PURE__ */ jsx10(
1867
+ return /* @__PURE__ */ jsx11(
1648
1868
  LoginScreen,
1649
1869
  {
1650
1870
  profile: loginTarget.profile,
@@ -1662,7 +1882,7 @@ function App({
1662
1882
  );
1663
1883
  }
1664
1884
  if (route === "profiles") {
1665
- return /* @__PURE__ */ jsx10(
1885
+ return /* @__PURE__ */ jsx11(
1666
1886
  ProfileScreen,
1667
1887
  {
1668
1888
  profiles,
@@ -1675,7 +1895,7 @@ function App({
1675
1895
  );
1676
1896
  }
1677
1897
  if (route === "dashboard" && session) {
1678
- return /* @__PURE__ */ jsx10(
1898
+ return /* @__PURE__ */ jsx11(
1679
1899
  Dashboard,
1680
1900
  {
1681
1901
  preferences,
@@ -1686,16 +1906,16 @@ function App({
1686
1906
  }
1687
1907
  );
1688
1908
  }
1689
- return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
1690
- /* @__PURE__ */ jsx10(Header, {}),
1691
- /* @__PURE__ */ jsx10(Notice, { error: true, children: error ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4." }),
1692
- /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "\uC11C\uBC84\uC640 \uD0A4\uCCB4\uC778 \uC0C1\uD0DC\uB97C \uD655\uC778\uD55C \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694." }),
1693
- /* @__PURE__ */ jsx10(Footer, { text: "R \uB2E4\uC2DC \uC2DC\uB3C4 \xB7 Ctrl+Q \uC885\uB8CC" }),
1694
- /* @__PURE__ */ jsx10(RetryInput, { onRetry: () => void bootstrap() })
1909
+ return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
1910
+ /* @__PURE__ */ jsx11(Header, {}),
1911
+ /* @__PURE__ */ jsx11(Notice, { error: true, children: error ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4." }),
1912
+ /* @__PURE__ */ jsx11(Text11, { dimColor: true, children: "\uC11C\uBC84\uC640 \uD0A4\uCCB4\uC778 \uC0C1\uD0DC\uB97C \uD655\uC778\uD55C \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694." }),
1913
+ /* @__PURE__ */ jsx11(Footer, { text: "R \uB2E4\uC2DC \uC2DC\uB3C4 \xB7 Ctrl+Q \uC885\uB8CC" }),
1914
+ /* @__PURE__ */ jsx11(RetryInput, { onRetry: () => void bootstrap() })
1695
1915
  ] });
1696
1916
  }
1697
1917
  function RetryInput({ onRetry }) {
1698
- useInput9((input) => {
1918
+ useInput10((input) => {
1699
1919
  if (input.toLowerCase() === "r") onRetry();
1700
1920
  });
1701
1921
  return null;
@@ -1899,7 +2119,7 @@ function createKeySignal() {
1899
2119
  }
1900
2120
 
1901
2121
  // src/tui/index.tsx
1902
- import { jsx as jsx11 } from "react/jsx-runtime";
2122
+ import { jsx as jsx12 } from "react/jsx-runtime";
1903
2123
  async function runTui(engine) {
1904
2124
  let screen = createScreenGuard(stdout);
1905
2125
  const restore = () => screen.restore();
@@ -1917,7 +2137,7 @@ async function runTui(engine) {
1917
2137
  screen.enter();
1918
2138
  try {
1919
2139
  const instance = render(
1920
- /* @__PURE__ */ jsx11(
2140
+ /* @__PURE__ */ jsx12(
1921
2141
  App,
1922
2142
  {
1923
2143
  engine,
@@ -1965,4 +2185,4 @@ async function runTui(engine) {
1965
2185
  export {
1966
2186
  runTui
1967
2187
  };
1968
- //# sourceMappingURL=tui-VLPJMWUK.js.map
2188
+ //# sourceMappingURL=tui-WG5AIWUR.js.map