dskcode 0.1.22 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -785,15 +785,6 @@ function renderApp(node) {
785
785
  import { Text } from "ink";
786
786
  import InkSpinner from "ink-spinner";
787
787
  import { jsx, jsxs } from "react/jsx-runtime";
788
- function Spinner({ type = "dots", label }) {
789
- return /* @__PURE__ */ jsxs(Text, { children: [
790
- /* @__PURE__ */ jsx(Text, { color: "cyan", children: /* @__PURE__ */ jsx(InkSpinner, { type }) }),
791
- label ? /* @__PURE__ */ jsxs(Text, { children: [
792
- " ",
793
- label
794
- ] }) : null
795
- ] });
796
- }
797
788
 
798
789
  // src/ui/StatusMessage.tsx
799
790
  import { Box, Text as Text2 } from "ink";
@@ -814,7 +805,7 @@ var LOGO_LINES = [
814
805
  ];
815
806
 
816
807
  // src/ui/ChatSession.tsx
817
- import { Box as Box8, Text as Text9, useInput, Static } from "ink";
808
+ import { Box as Box8, Text as Text10, useInput, Static } from "ink";
818
809
  import TextInput from "ink-text-input";
819
810
  import { useEffect as useEffect3, useState as useState3, useCallback as useCallback2, useMemo, useRef as useRef2 } from "react";
820
811
 
@@ -850,7 +841,7 @@ function useDoubleCtrlC(onExit) {
850
841
  import InkSpinner2 from "ink-spinner";
851
842
 
852
843
  // src/ui/AssistantMessage.tsx
853
- import { Box as Box4, Text as Text5 } from "ink";
844
+ import { Box as Box4, Text as Text6 } from "ink";
854
845
 
855
846
  // src/provider/cost-tracker.ts
856
847
  import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
@@ -1256,8 +1247,82 @@ function formatUsageSummary(usage) {
1256
1247
  return summary;
1257
1248
  }
1258
1249
 
1250
+ // src/ui/HighlightedText.tsx
1251
+ import { Text as Text5 } from "ink";
1252
+ import { jsx as jsx4 } from "react/jsx-runtime";
1253
+ function parseBoldPairs(text) {
1254
+ const segments = [];
1255
+ let current = 0;
1256
+ while (current < text.length) {
1257
+ const openIdx = text.indexOf("**", current);
1258
+ if (openIdx === -1) {
1259
+ segments.push({ text: text.slice(current), type: "plain" });
1260
+ break;
1261
+ }
1262
+ if (openIdx > current) {
1263
+ segments.push({ text: text.slice(current, openIdx), type: "plain" });
1264
+ }
1265
+ const closeIdx = text.indexOf("**", openIdx + 2);
1266
+ if (closeIdx === -1) {
1267
+ segments.push({ text: text.slice(openIdx), type: "plain" });
1268
+ break;
1269
+ }
1270
+ segments.push({ text: text.slice(openIdx + 2, closeIdx), type: "bold" });
1271
+ current = closeIdx + 2;
1272
+ }
1273
+ return segments;
1274
+ }
1275
+ function parseCodePairs(segments) {
1276
+ const result = [];
1277
+ for (const seg of segments) {
1278
+ if (seg.type !== "plain") {
1279
+ result.push(seg);
1280
+ continue;
1281
+ }
1282
+ let current = 0;
1283
+ const text = seg.text;
1284
+ while (current < text.length) {
1285
+ const openIdx = text.indexOf("`", current);
1286
+ if (openIdx === -1) {
1287
+ result.push({ text: text.slice(current), type: "plain" });
1288
+ break;
1289
+ }
1290
+ if (openIdx > current) {
1291
+ result.push({ text: text.slice(current, openIdx), type: "plain" });
1292
+ }
1293
+ const closeIdx = text.indexOf("`", openIdx + 1);
1294
+ if (closeIdx === -1) {
1295
+ result.push({ text: text.slice(openIdx), type: "plain" });
1296
+ break;
1297
+ }
1298
+ result.push({ text: text.slice(openIdx + 1, closeIdx), type: "code" });
1299
+ current = closeIdx + 1;
1300
+ }
1301
+ }
1302
+ return result;
1303
+ }
1304
+ var CODE_COLOR = "#00BFFF";
1305
+ var BOLD_COLOR = "#A855F7";
1306
+ function HighlightedText({ children: text }) {
1307
+ const boldSegments = parseBoldPairs(text);
1308
+ const segments = parseCodePairs(boldSegments);
1309
+ const isSimple = segments.length === 1 && segments[0].type === "plain";
1310
+ if (isSimple) {
1311
+ return /* @__PURE__ */ jsx4(Text5, { wrap: "wrap", children: text });
1312
+ }
1313
+ return /* @__PURE__ */ jsx4(Text5, { wrap: "wrap", children: segments.map((seg, i) => {
1314
+ if (seg.type === "code") {
1315
+ return /* @__PURE__ */ jsx4(Text5, { color: CODE_COLOR, children: seg.text }, i);
1316
+ }
1317
+ if (seg.type === "bold") {
1318
+ return /* @__PURE__ */ jsx4(Text5, { color: BOLD_COLOR, children: seg.text }, i);
1319
+ }
1320
+ return seg.text;
1321
+ }) });
1322
+ }
1323
+
1259
1324
  // src/ui/AssistantMessage.tsx
1260
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1325
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1261
1326
  function formatElapsed(ms) {
1262
1327
  if (ms < 1e3) return `${ms}ms`;
1263
1328
  const seconds = (ms / 1e3).toFixed(1);
@@ -1277,33 +1342,33 @@ function AssistantMessage({
1277
1342
  }
1278
1343
  return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
1279
1344
  /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", children: [
1280
- /* @__PURE__ */ jsx4(Box4, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx4(Text5, { bold: true, color: "#ff00ff", children: "\u{1F916}" }) }),
1345
+ /* @__PURE__ */ jsx5(Box4, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx5(Text6, { bold: true, color: "#ff00ff", children: "\u{1F916}" }) }),
1281
1346
  /* @__PURE__ */ jsxs4(Box4, { flexGrow: 1, flexDirection: "column", children: [
1282
- content && /* @__PURE__ */ jsx4(Text5, { wrap: "wrap", children: content }),
1283
- isStreaming && !content && /* @__PURE__ */ jsx4(Text5, { color: "#888888", children: "..." })
1347
+ content && /* @__PURE__ */ jsx5(HighlightedText, { children: content }),
1348
+ isStreaming && !content && /* @__PURE__ */ jsx5(Text6, { color: "#888888", children: "..." })
1284
1349
  ] })
1285
1350
  ] }),
1286
- toolCalls && toolCalls.length > 0 && /* @__PURE__ */ jsx4(Box4, { flexDirection: "column", children: toolCalls.map((tc, i) => /* @__PURE__ */ jsx4(ToolCallBlock, { call: tc }, tc.id ?? i)) }),
1351
+ toolCalls && toolCalls.length > 0 && /* @__PURE__ */ jsx5(Box4, { flexDirection: "column", children: toolCalls.map((tc, i) => /* @__PURE__ */ jsx5(ToolCallBlock, { call: tc }, tc.id ?? i)) }),
1287
1352
  !isStreaming && (usage || elapsed !== void 0) && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, marginLeft: 3, children: [
1288
- /* @__PURE__ */ jsx4(Text5, { color: "#555555", children: "\u2500".repeat(36) }),
1353
+ /* @__PURE__ */ jsx5(Text6, { color: "#555555", children: "\u2500".repeat(36) }),
1289
1354
  /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", gap: 2, children: [
1290
- cost !== void 0 && cost > 0 && /* @__PURE__ */ jsxs4(Text5, { color: "yellow", children: [
1355
+ cost !== void 0 && cost > 0 && /* @__PURE__ */ jsxs4(Text6, { color: "yellow", children: [
1291
1356
  "\u{1F4B0} \u672C\u6B21 ",
1292
1357
  formatMoney(cost)
1293
1358
  ] }),
1294
- elapsed !== void 0 && /* @__PURE__ */ jsxs4(Text5, { color: "cyan", children: [
1359
+ elapsed !== void 0 && /* @__PURE__ */ jsxs4(Text6, { color: "cyan", children: [
1295
1360
  "\u{1F550} ",
1296
1361
  formatElapsed(elapsed)
1297
1362
  ] }),
1298
- usage && /* @__PURE__ */ jsx4(Text5, { color: "#888888", children: formatUsageSummary(usage) })
1363
+ usage && /* @__PURE__ */ jsx5(Text6, { color: "#888888", children: formatUsageSummary(usage) })
1299
1364
  ] })
1300
1365
  ] })
1301
1366
  ] });
1302
1367
  }
1303
1368
 
1304
1369
  // src/ui/DiffPreview.tsx
1305
- import { Box as Box5, Text as Text6 } from "ink";
1306
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1370
+ import { Box as Box5, Text as Text7 } from "ink";
1371
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1307
1372
  function DiffPreview({ diff }) {
1308
1373
  const { patch, additions, deletions, existedBefore, filePath } = diff;
1309
1374
  if (!patch || patch.length === 0) {
@@ -1313,13 +1378,13 @@ function DiffPreview({ diff }) {
1313
1378
  const fileName = filePath.replace(/\\/g, "/").split("/").pop() ?? filePath;
1314
1379
  return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
1315
1380
  /* @__PURE__ */ jsxs5(Box5, { flexDirection: "row", gap: 1, children: [
1316
- /* @__PURE__ */ jsxs5(Text6, { bold: true, color: "#00ffff", children: [
1381
+ /* @__PURE__ */ jsxs5(Text7, { bold: true, color: "#00ffff", children: [
1317
1382
  "\u{1F4DD} ",
1318
1383
  existedBefore ? "\u4FEE\u6539" : "\u65B0\u5EFA",
1319
1384
  ":"
1320
1385
  ] }),
1321
- /* @__PURE__ */ jsx5(Text6, { bold: true, children: fileName }),
1322
- /* @__PURE__ */ jsxs5(Text6, { color: "#555555", children: [
1386
+ /* @__PURE__ */ jsx6(Text7, { bold: true, children: fileName }),
1387
+ /* @__PURE__ */ jsxs5(Text7, { color: "#555555", children: [
1323
1388
  "(+",
1324
1389
  additions,
1325
1390
  " -",
@@ -1327,7 +1392,7 @@ function DiffPreview({ diff }) {
1327
1392
  ")"
1328
1393
  ] })
1329
1394
  ] }),
1330
- /* @__PURE__ */ jsx5(Box5, { flexDirection: "column", marginLeft: 2, children: lines.filter((line) => !line.startsWith("---") && !line.startsWith("+++")).map((line, i) => /* @__PURE__ */ jsx5(DiffLine, { line }, i)) })
1395
+ /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", marginLeft: 2, children: lines.filter((line) => !line.startsWith("---") && !line.startsWith("+++")).map((line, i) => /* @__PURE__ */ jsx6(DiffLine, { line }, i)) })
1331
1396
  ] });
1332
1397
  }
1333
1398
  function DiffLine({ line }) {
@@ -1335,20 +1400,20 @@ function DiffLine({ line }) {
1335
1400
  return null;
1336
1401
  }
1337
1402
  if (line.startsWith("@@")) {
1338
- return /* @__PURE__ */ jsx5(Text6, { color: "#00cccc", children: line });
1403
+ return /* @__PURE__ */ jsx6(Text7, { color: "#00cccc", children: line });
1339
1404
  }
1340
1405
  if (line.startsWith("+")) {
1341
- return /* @__PURE__ */ jsx5(Text6, { color: "#22c55e", children: line });
1406
+ return /* @__PURE__ */ jsx6(Text7, { color: "#22c55e", children: line });
1342
1407
  }
1343
1408
  if (line.startsWith("-")) {
1344
- return /* @__PURE__ */ jsx5(Text6, { color: "#ef4444", children: line });
1409
+ return /* @__PURE__ */ jsx6(Text7, { color: "#ef4444", children: line });
1345
1410
  }
1346
- return /* @__PURE__ */ jsx5(Text6, { color: "#6b7280", children: line });
1411
+ return /* @__PURE__ */ jsx6(Text7, { color: "#6b7280", children: line });
1347
1412
  }
1348
1413
 
1349
1414
  // src/ui/SkillSelector.tsx
1350
- import { Box as Box6, Text as Text7 } from "ink";
1351
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1415
+ import { Box as Box6, Text as Text8 } from "ink";
1416
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1352
1417
  var HIGHLIGHT_COLOR = "#00bfff";
1353
1418
  function SkillSelector({ skills, input, selectedIndex }) {
1354
1419
  const match = input.match(/(?:^|\s)\/([^/]*)$/);
@@ -1359,18 +1424,18 @@ function SkillSelector({ skills, input, selectedIndex }) {
1359
1424
  if (query && matched.length > 0 && matched.some((s) => s.name.toLowerCase() === query)) return null;
1360
1425
  if (matched.length === 0) return null;
1361
1426
  return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginLeft: 4, marginTop: 1, children: [
1362
- /* @__PURE__ */ jsx6(Text7, { color: "#808080", dimColor: true, children: "\u652F\u6301\u7684 Skill\uFF1A" }),
1363
- matched.map((skill, i) => /* @__PURE__ */ jsx6(Box6, { children: /* @__PURE__ */ jsxs6(Text7, { color: i === selectedIndex ? HIGHLIGHT_COLOR : "#808080", children: [
1427
+ /* @__PURE__ */ jsx7(Text8, { color: "#808080", dimColor: true, children: "\u652F\u6301\u7684 Skill\uFF1A" }),
1428
+ matched.map((skill, i) => /* @__PURE__ */ jsx7(Box6, { children: /* @__PURE__ */ jsxs6(Text8, { color: i === selectedIndex ? HIGHLIGHT_COLOR : "#808080", children: [
1364
1429
  i === selectedIndex ? " \u203A " : " ",
1365
1430
  skill.name
1366
1431
  ] }) }, skill.name)),
1367
- /* @__PURE__ */ jsx6(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx6(Text7, { color: "#808080", dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Tab \u8865\u5168" }) })
1432
+ /* @__PURE__ */ jsx7(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text8, { color: "#808080", dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Tab \u8865\u5168" }) })
1368
1433
  ] });
1369
1434
  }
1370
1435
 
1371
1436
  // src/ui/FileSelector.tsx
1372
- import { Box as Box7, Text as Text8 } from "ink";
1373
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1437
+ import { Box as Box7, Text as Text9 } from "ink";
1438
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1374
1439
  var HIGHLIGHT_COLOR2 = "#00ff41";
1375
1440
  function FileSelector({ files, input, selectedIndex }) {
1376
1441
  const match = input.match(/(?:^|\s)@([^@]*)$/);
@@ -1381,12 +1446,12 @@ function FileSelector({ files, input, selectedIndex }) {
1381
1446
  if (query && matched.some((f) => f.toLowerCase() === query)) return null;
1382
1447
  if (matched.length === 0) return null;
1383
1448
  return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginLeft: 4, marginTop: 1, children: [
1384
- /* @__PURE__ */ jsx7(Text8, { color: "#808080", dimColor: true, children: "\u9879\u76EE\u6587\u4EF6\uFF1A" }),
1385
- matched.map((file, i) => /* @__PURE__ */ jsx7(Box7, { children: /* @__PURE__ */ jsxs7(Text8, { color: i === selectedIndex ? HIGHLIGHT_COLOR2 : "#808080", children: [
1449
+ /* @__PURE__ */ jsx8(Text9, { color: "#808080", dimColor: true, children: "\u9879\u76EE\u6587\u4EF6\uFF1A" }),
1450
+ matched.map((file, i) => /* @__PURE__ */ jsx8(Box7, { children: /* @__PURE__ */ jsxs7(Text9, { color: i === selectedIndex ? HIGHLIGHT_COLOR2 : "#808080", children: [
1386
1451
  i === selectedIndex ? " \u203A " : " ",
1387
1452
  file
1388
1453
  ] }) }, file)),
1389
- /* @__PURE__ */ jsx7(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text8, { color: "#808080", dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Tab \u8865\u5168" }) })
1454
+ /* @__PURE__ */ jsx8(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text9, { color: "#808080", dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Tab \u8865\u5168" }) })
1390
1455
  ] });
1391
1456
  }
1392
1457
 
@@ -1479,102 +1544,55 @@ var AlwaysAllowGate = class {
1479
1544
  }
1480
1545
  };
1481
1546
 
1482
- // src/agent/extra-prompt.ts
1483
- var EXTRA_PROMPT = [
1484
- "\u3010\u7EC8\u7AEF\u8F93\u51FA\u7EA6\u675F\u3011",
1485
- "",
1486
- "\u4F60\u7684\u56DE\u590D\u5C06\u76F4\u63A5\u6E32\u67D3\u5728\u7528\u6237\u7EC8\u7AEF\u7684\u547D\u4EE4\u884C\u754C\u9762\u4E2D\uFF0C\u4E0D\u652F\u6301 Markdown \u6E32\u67D3\u3002",
1487
- "\u8BF7\u4E25\u683C\u9075\u5B88\u4EE5\u4E0B\u683C\u5F0F\u89C4\u5219\u3002",
1488
- "",
1489
- "\u4E00\u3001\u7981\u6B62\u4F7F\u7528\u7684\u7B26\u53F7",
1490
- " - \u4E0D\u8981\u4F7F\u7528 Markdown \u6807\u9898\u7B26\u53F7\uFF08\u5355\u72EC\u6216\u8FDE\u7EED\u7684\u4E95\u53F7\uFF09",
1491
- " - \u4E0D\u8981\u4F7F\u7528\u7C97\u4F53\u6216\u659C\u4F53\u7B26\u53F7\uFF08\u661F\u53F7\u3001\u4E0B\u5212\u7EBF\uFF09",
1492
- " - \u4E0D\u8981\u4F7F\u7528\u4EE3\u7801\u5757\u6807\u8BB0\uFF08\u8FDE\u7EED\u4E09\u4E2A\u53CD\u5F15\u53F7\uFF09",
1493
- " - \u4E0D\u8981\u4F7F\u7528\u5757\u5F15\u7528\u7B26\u53F7\uFF08\u5927\u4E8E\u53F7\uFF09",
1494
- " - \u4E0D\u8981\u4F7F\u7528\u5206\u9694\u7EBF\uFF08\u8FDE\u7EED\u4E09\u4E2A\u51CF\u53F7\u6216\u661F\u53F7\uFF09",
1495
- " - \u4E0D\u8981\u4F7F\u7528\u884C\u5185\u4EE3\u7801\u6807\u8BB0\uFF08\u5355\u4E2A\u53CD\u5F15\u53F7\uFF09",
1496
- "",
1497
- "\u4E8C\u3001\u63A8\u8350\u7684\u7EC4\u7EC7\u65B9\u5F0F",
1498
- ' - \u7528\u7EAF\u6587\u5B57\u63CF\u8FF0\u5C42\u7EA7\uFF0C\u4F8B\u5982"\u7B2C\u4E00\u70B9"\u3001"\u7B2C\u4E8C\u70B9"\u66FF\u4EE3\u6807\u9898\u7B26\u53F7',
1499
- " - \u7528 emoji \u7B26\u53F7\u505A\u89C6\u89C9\u6807\u8BB0\uFF08\u5982 \u{1F4CC} \u{1F4E6} \u{1F4DD} \u26A0\uFE0F \u7B49\uFF09",
1500
- " - \u7528\u6570\u5B57\u5E8F\u53F7\uFF081. 2. 3.\uFF09\u7EC4\u7EC7\u5217\u8868",
1501
- " - \u4EE3\u7801\u793A\u4F8B\u7528\u7F29\u8FDB\uFF08\u6BCF\u884C\u524D\u52A0 4 \u4E2A\u7A7A\u683C\uFF09\u66FF\u4EE3\u4EE3\u7801\u5757\u6807\u8BB0",
1502
- " - \u6587\u4EF6\u8DEF\u5F84\u3001\u547D\u4EE4\u3001\u53D8\u91CF\u540D\u76F4\u63A5\u4E66\u5199\uFF0C\u4E0D\u8981\u7528\u4EFB\u4F55\u7B26\u53F7\u5305\u88F9",
1503
- "",
1504
- "\u4E09\u3001\u6B63\u786E\u683C\u5F0F\u793A\u4F8B",
1505
- "",
1506
- " \u7B2C\u4E00\u70B9\uFF1A\u4F18\u5316\u6570\u636E\u5E93\u67E5\u8BE2",
1507
- " 1. \u6DFB\u52A0\u7D22\u5F15\u5230 user_id \u5B57\u6BB5",
1508
- " 2. \u7528\u8FDE\u63A5\u6C60\u66FF\u4EE3\u77ED\u8FDE\u63A5",
1509
- "",
1510
- " \u4EE3\u7801\u793A\u4F8B\uFF1A",
1511
- " const pool = new Pool({ max: 20 });",
1512
- ' await pool.query("SELECT * FROM users");',
1513
- "",
1514
- " \u8F93\u51FA\u63D0\u793A\uFF1A",
1515
- " \u{1F4CC} \u4F18\u5316\u524D\uFF1A\u67E5\u8BE2\u8017\u65F6 3.2 \u79D2",
1516
- "",
1517
- "\u56DB\u3001\u9519\u8BEF\u683C\u5F0F\u793A\u4F8B\uFF08\u7981\u6B62\u8FD9\u6837\u5199\uFF09",
1518
- "",
1519
- " \u4E95\u53F7\u4E32 \u4F18\u5316\u6570\u636E\u5E93\u67E5\u8BE2\uFF08\u8FD9\u662F\u9519\u8BEF\u7684\uFF09",
1520
- " \u661F\u53F7 \u6DFB\u52A0\u7D22\u5F15\u5230 user_id \u5B57\u6BB5\uFF08\u8FD9\u662F\u9519\u8BEF\u7684\uFF09",
1521
- " \u4E09\u4E2A\u53CD\u5F15\u53F7\u5F00\u59CB\u6216\u7ED3\u675F\uFF08\u8FD9\u662F\u9519\u8BEF\u7684\uFF09",
1522
- "",
1523
- "\u6CE8\u610F\uFF1A\u4E0A\u8FF0\u793A\u4F8B\u4E2D\u7684\u9519\u8BEF\u5199\u6CD5\u4EC5\u4F5C\u4E3A\u8BF4\u660E\uFF0C\u4F60\u7684\u56DE\u590D\u4E2D\u4E0D\u8981\u51FA\u73B0\u8FD9\u4E9B\u683C\u5F0F\u3002"
1524
- ].join("\n");
1525
-
1526
1547
  // src/agent/system-prompt.ts
1527
- function buildSystemPrompt(opts) {
1528
- const sections = [];
1529
- sections.push(`\u4F60\u662F dskcode\uFF0C\u4E00\u4E2A\u57FA\u4E8E DeepSeek \u7684 AI \u7F16\u7A0B\u52A9\u624B\uFF0C\u8FD0\u884C\u5728\u7528\u6237\u7EC8\u7AEF\u4E2D\u3002\u4F60\u7684\u804C\u8D23\u662F\u5E2E\u52A9\u5F00\u53D1\u8005\u7F16\u5199\u3001\u7406\u89E3\u3001\u8C03\u8BD5\u548C\u91CD\u6784\u4EE3\u7801\u3002
1548
+ import Handlebars from "handlebars";
1549
+
1550
+ // src/agent/prompts/system-prompt.hbs
1551
+ var system_prompt_default = '\u4F60\u662F dskcode\uFF0C\u4E00\u4E2A\u57FA\u4E8E DeepSeek \u7684 AI \u7F16\u7A0B\u52A9\u624B\uFF0C\u8FD0\u884C\u5728\u7528\u6237\u7EC8\u7AEF\u4E2D\u3002\u4F60\u7684\u804C\u8D23\u662F\u5E2E\u52A9\u5F00\u53D1\u8005\u7F16\u5199\u3001\u7406\u89E3\u3001\u8C03\u8BD5\u548C\u91CD\u6784\u4EE3\u7801\u3002\r\n\r\n## \u6838\u5FC3\u539F\u5219\r\n- \u56DE\u7B54\u4F7F\u7528\u4E2D\u6587\uFF0C\u4EE3\u7801\u6807\u8BC6\u7B26\u4FDD\u6301\u82F1\u6587\r\n- \u63D0\u4F9B\u51C6\u786E\u3001\u5B9E\u7528\u3001\u53EF\u64CD\u4F5C\u7684\u5EFA\u8BAE\r\n- \u5BF9\u4E0D\u786E\u5B9A\u7684\u5185\u5BB9\u660E\u786E\u6807\u6CE8\uFF0C\u4E0D\u7F16\u9020\u4E8B\u5B9E\r\n- \u4EE3\u7801\u793A\u4F8B\u4FDD\u6301\u7B80\u6D01\uFF0C\u9644\u5E26\u5FC5\u8981\u7684\u6CE8\u91CA\r\n\r\n## \u5DE5\u4F5C\u6D41\u7A0B\r\n\r\n\u4F60\u5904\u4E8E\u4E00\u4E2A\u5DE5\u5177\u8C03\u7528\u5FAA\u73AF\u4E2D\uFF1A\r\n1. \u6536\u5230\u7528\u6237\u8BF7\u6C42\r\n2. \u8C03\u7528\u5DE5\u5177\u83B7\u53D6\u4FE1\u606F\u6216\u4FEE\u6539\u6587\u4EF6\r\n3. \u5DE5\u5177\u7ED3\u679C\u8FD4\u56DE\u7ED9\u4F60\r\n4. \u6839\u636E\u7ED3\u679C\u51B3\u5B9A\u4E0B\u4E00\u6B65\uFF08\u7EE7\u7EED\u8C03\u7528\u5DE5\u5177\u6216\u7ED9\u51FA\u6700\u7EC8\u56DE\u7B54\uFF09\r\n5. \u4E00\u8F6E\u6700\u591A {{maxToolRounds}} \u6B21\u5DE5\u5177\u8C03\u7528\r\n\r\n## \u5DE5\u5177\u4F7F\u7528\u7B56\u7565\r\n\r\n{{#if tools}}\r\n\u5F53\u524D\u53EF\u7528\u7684\u5DE5\u5177\uFF1A\r\n{{#each tools}}\r\n- **{{name}}**\uFF1A{{description}}{{#if params}}\uFF08\u53C2\u6570\uFF1A{{params}}\uFF09{{/if}}\r\n{{/each}}\r\n\r\n\u4F7F\u7528\u539F\u5219\uFF1A\r\n- **\u5148\u641C\u7D22\u518D\u8BFB\u53D6** \u2014 \u4E0D\u786E\u5B9A\u76EE\u6807\u4F4D\u7F6E\u65F6\u5148\u7528 grep/glob \u5B9A\u4F4D\uFF0C\u518D\u7528 read_file \u8BFB\u53D6\r\n- **\u5148\u8BFB\u53D6\u518D\u4FEE\u6539** \u2014 \u7F16\u8F91\u6587\u4EF6\u524D\u5148 read_file \u786E\u8BA4\u5F53\u524D\u5185\u5BB9\r\n- **\u6279\u91CF\u64CD\u4F5C\u4E00\u6B21\u5B8C\u6210** \u2014 \u540C\u4E00\u6587\u4EF6\u7684\u591A\u5904\u6539\u52A8\u5728\u5355\u6B21 edit_file \u4E2D\u5B8C\u6210\r\n- **\u5DE5\u5177\u51FA\u9519\u65F6** \u2014 \u5206\u6790\u9519\u8BEF\u539F\u56E0\uFF08\u8DEF\u5F84\u4E0D\u5BF9\uFF1F\u683C\u5F0F\u4E0D\u5BF9\uFF1F\u6743\u9650\u4E0D\u8DB3\uFF1F\uFF09\uFF0C\u4FEE\u6B63\u540E\u91CD\u8BD5\uFF0C\u4E0D\u8981\u91CD\u590D\u76F8\u540C\u7684\u9519\u8BEF\u8C03\u7528\r\n- **\u5BA1\u614E\u6267\u884C** \u2014 bash \u6267\u884C\u5371\u9669\u547D\u4EE4\uFF08rm -rf\u3001\u5F3A\u5236\u5199\u5165\u7B49\uFF09\u524D\u5148\u786E\u8BA4\r\n{{/if}}\r\n\r\n{{#if projectContext}}\r\n## \u9879\u76EE\u4E0A\u4E0B\u6587\r\n\r\n{{projectContext}}\r\n{{/if}}\r\n\r\n## \u56DE\u7B54\u683C\u5F0F\r\n\r\n\u7EC8\u7AEF\u4E0D\u652F\u6301 Markdown \u6E32\u67D3\u3002\u56DE\u590D\u683C\u5F0F\u8981\u6C42\uFF1A\r\n\r\n- \u7528 emoji \u505A\u89C6\u89C9\u6807\u8BB0\uFF08\u{1F4CC} \u8981\u70B9 \u26A0\uFE0F \u6CE8\u610F \u{1F4DD} \u5F85\u529E \u2705 \u5B8C\u6210\uFF09\r\n- \u7528\u6570\u5B57\u5E8F\u53F7\u6216\u77ED\u6A2A\u7EBF\u7EC4\u7EC7\u5217\u8868\r\n- \u4EE3\u7801\u6807\u8BC6\u7B26\u3001\u6587\u4EF6\u8DEF\u5F84\u3001\u7C7B\u578B\u540D\u7528\u5355\u4E2A\u53CD\u5F15\u53F7 ` \u5305\u88F9\uFF0C\u4F1A\u88AB\u81EA\u52A8\u9AD8\u4EAE\r\n- \u5F3A\u8C03\u5185\u5BB9\u7528 **\u52A0\u7C97** \u5305\u88F9\uFF0C\u4F1A\u88AB\u81EA\u52A8\u9AD8\u4EAE\r\n- \u591A\u884C\u4EE3\u7801\u7528\u7F29\u8FDB 4 \u4E2A\u7A7A\u683C\u8868\u793A\uFF0C\u4E0D\u8981\u7528\u4E09\u53CD\u5F15\u53F7\u4EE3\u7801\u5757\r\n- \u6BB5\u843D\u95F4\u7528\u7A7A\u884C\u5206\u9694\uFF0C\u4E0D\u8981\u7528\u6807\u9898\u7B26\u53F7\r\n\r\n\u6B63\u786E\u793A\u4F8B\uFF1A\r\n\r\n\u{1F4CC} \u9700\u8981\u4FEE\u6539\u4E24\u4E2A\u5730\u65B9\uFF1A\r\n1. \u7B2C 12 \u884C\u7684 `interface FileDiff` \u6539\u4E3A `interface Diff`\r\n2. \u7B2C 432 \u884C\u7684 `): FileDiff` \u6539\u4E3A `): Diff`\r\n\r\n \u4EE3\u7801\u793A\u4F8B\uFF1A\r\n const pool = new Pool({ max: 20 });\r\n await pool.query("SELECT * FROM users");\r\n\r\n## \u884C\u4E3A\u7EA6\u675F\r\n- \u5982\u679C\u7528\u6237\u8BF7\u6C42\u4E0D\u660E\u786E\uFF0C\u4E3B\u52A8\u8BE2\u95EE\u6F84\u6E05\r\n- \u5BF9\u4E0D\u786E\u5B9A\u7684\u4FE1\u606F\u660E\u786E\u6807\u6CE8\uFF0C\u4E0D\u7F16\u9020\u4E8B\u5B9E\r\n- \u4E0D\u6267\u884C\u53EF\u80FD\u9020\u6210\u4E0D\u53EF\u9006\u635F\u5BB3\u7684\u64CD\u4F5C\uFF08\u5982 rm -rf\uFF09\uFF0C\u9664\u975E\u7528\u6237\u660E\u786E\u9010\u6761\u786E\u8BA4\r\n- \u5DE5\u5177\u8C03\u7528\u8FD4\u56DE\u9519\u8BEF\u65F6\uFF0C\u5148\u5206\u6790\u539F\u56E0\u518D\u91CD\u8BD5\uFF0C\u4E0D\u8981\u76F2\u76EE\u91CD\u8BD5\r\n\r\n## \u5F53\u524D\u6A21\u578B\r\n- \u6A21\u578B\uFF1A{{model}}\r\n\r\n## \u65F6\u95F4\u4E0A\u4E0B\u6587\r\n- \u5F53\u524D\u65E5\u671F\uFF1A{{date}}\r\n- \u5F53\u524D\u65F6\u95F4\uFF1A{{time}}\r\n- \u5DE5\u4F5C\u76EE\u5F55\uFF1A{{cwd}}\r\n';
1552
+
1553
+ // src/agent/prompts/plan-prompt.hbs
1554
+ var plan_prompt_default = "\u4F60\u662F dskcode\uFF0C\u5F53\u524D\u5DE5\u4F5C\u5728**\u8BA1\u5212\u6A21\u5F0F\uFF08Plan Mode\uFF09**\u3002\r\n\r\n\u5728\u6B64\u6A21\u5F0F\u4E0B\uFF0C**\u4F60\u53EA\u80FD\u8BFB\u53D6\u548C\u5206\u6790\u4EE3\u7801\uFF0C\u4E0D\u80FD\u6267\u884C\u4EFB\u4F55\u4FEE\u6539\u64CD\u4F5C**\u3002\u4F60\u7684\u804C\u8D23\u662F\u5E2E\u52A9\u7528\u6237\u7406\u89E3\u4EE3\u7801\u3001\u8BBE\u8BA1\u67B6\u6784\u3001\u89C4\u5212\u4EFB\u52A1\u3001\u8BC4\u4F30\u65B9\u6848\u3002\r\n\r\n## \u6838\u5FC3\u539F\u5219\r\n- \u56DE\u7B54\u4F7F\u7528\u4E2D\u6587\uFF0C\u4EE3\u7801\u6807\u8BC6\u7B26\u4FDD\u6301\u82F1\u6587\r\n- \u63D0\u4F9B\u51C6\u786E\u3001\u5B9E\u7528\u3001\u53EF\u64CD\u4F5C\u7684\u5EFA\u8BAE\r\n- \u5BF9\u4E0D\u786E\u5B9A\u7684\u5185\u5BB9\u660E\u786E\u6807\u6CE8\uFF0C\u4E0D\u7F16\u9020\u4E8B\u5B9E\r\n- **\u7EDD\u4E0D\u6267\u884C\u4EFB\u4F55\u5199\u64CD\u4F5C** \u2014 \u4F60\u53EA\u80FD\u8BFB\u53D6\u548C\u5206\u6790\r\n\r\n## \u5DE5\u4F5C\u6D41\u7A0B\r\n1. \u6536\u5230\u7528\u6237\u8BF7\u6C42\r\n2. \u4F7F\u7528\u8BFB\u5DE5\u5177\uFF08read-file, grep, glob, ls, fetch\uFF09\u63A2\u7D22\u4EE3\u7801\u5E93\r\n3. \u6839\u636E\u53D1\u73B0\u7684\u4FE1\u606F\u63D0\u4F9B\u7ED3\u6784\u5316\u7684\u5206\u6790\u6216\u8BA1\u5212\r\n4. \u5DE5\u5177\u8FD4\u56DE\u51FA\u9519\u65F6\u5206\u6790\u539F\u56E0\u5E76\u4FEE\u6B63\u540E\u91CD\u8BD5\r\n5. \u5B8C\u6210\u540E\u8F93\u51FA\u6700\u7EC8\u5206\u6790\u7ED3\u679C\r\n\r\n## \u5DE5\u5177\u9650\u5236\r\n**\u4F60\u53EA\u80FD\u4F7F\u7528\u8BFB\u5DE5\u5177**\uFF0C\u4E0D\u80FD\u4F7F\u7528\u4EFB\u4F55\u5199\u5DE5\u5177\uFF08write-file, edit-file, multi-edit, delete-range, bash\uFF09\u3002\r\n\u5982\u679C\u7528\u6237\u8BF7\u6C42\u4FEE\u6539\u4EE3\u7801\uFF0C\u8BF7\uFF1A\r\n- \u63D0\u4F9B\u4FEE\u6539\u5EFA\u8BAE\u548C\u65B9\u6848\r\n- \u6307\u51FA\u9700\u8981\u4FEE\u6539\u7684\u6587\u4EF6\u548C\u4F4D\u7F6E\r\n- \u89E3\u91CA\u4FEE\u6539\u7684\u5F71\u54CD\r\n- \u4F46\u4E0D\u6267\u884C\u4EFB\u4F55\u4FEE\u6539\r\n\r\n## \u8BA1\u5212\u8F93\u51FA\u683C\u5F0F\r\n\r\n\u5F53\u7528\u6237\u8BF7\u6C42\u8BA1\u5212/\u65B9\u6848\u65F6\uFF0C\u5EFA\u8BAE\u6309\u7167\u4EE5\u4E0B\u7ED3\u6784\u7EC4\u7EC7\u8F93\u51FA\uFF1A\r\n\r\n\u{1F4CB} **\u6982\u8FF0**\r\n 1-2 \u53E5\u8BDD\u8BF4\u660E\u8981\u505A\u4EC0\u4E48\u4EE5\u53CA\u4E3A\u4EC0\u4E48\u8981\u505A\r\n\r\n\u{1F50D} **\u73B0\u72B6\u5206\u6790**\r\n \u5F53\u524D\u4EE3\u7801\u7684\u7EC4\u7EC7\u7ED3\u6784\u548C\u5173\u952E\u53D1\u73B0\r\n\r\n\u26A1 **\u5F71\u54CD\u8303\u56F4**\r\n \u54EA\u4E9B\u6587\u4EF6/\u6A21\u5757\u4F1A\u53D7\u5230\u5F71\u54CD\r\n\r\n\u{1F4DD} **\u5B9E\u65BD\u6B65\u9AA4**\r\n 1. \u7B2C\u4E00\u6B65\uFF08\u6587\u4EF6\u8DEF\u5F84/\u53D8\u66F4\u8BF4\u660E\uFF09\r\n 2. \u7B2C\u4E8C\u6B65\uFF08\u6587\u4EF6\u8DEF\u5F84/\u53D8\u66F4\u8BF4\u660E\uFF09\r\n 3. ...\r\n\r\n\u26A0\uFE0F **\u98CE\u9669\u4E0E\u6CE8\u610F\u4E8B\u9879**\r\n \u53EF\u80FD\u7684\u98CE\u9669\u70B9\u3001\u4F9D\u8D56\u5173\u7CFB\u3001\u56DE\u9000\u7B56\u7565\r\n\r\n## \u56DE\u7B54\u683C\u5F0F\r\n\r\n\u7EC8\u7AEF\u4E0D\u652F\u6301 Markdown \u6E32\u67D3\u3002\u56DE\u590D\u683C\u5F0F\u8981\u6C42\uFF1A\r\n- \u7528 emoji \u505A\u89C6\u89C9\u6807\u8BB0\r\n- \u7528\u6570\u5B57\u5E8F\u53F7\u6216\u77ED\u6A2A\u7EBF\u7EC4\u7EC7\u5217\u8868\r\n- \u4EE3\u7801\u6807\u8BC6\u7B26\u3001\u6587\u4EF6\u8DEF\u5F84\u7528\u5355\u4E2A\u53CD\u5F15\u53F7 ` \u5305\u88F9\r\n- \u591A\u884C\u4EE3\u7801\u7528\u7F29\u8FDB 4 \u4E2A\u7A7A\u683C\u8868\u793A\r\n- \u6BB5\u843D\u95F4\u7528\u7A7A\u884C\u5206\u9694\r\n\r\n## \u5F53\u524D\u6A21\u578B\r\n- \u6A21\u578B\uFF1A{{model}}\r\n\r\n## \u65F6\u95F4\u4E0A\u4E0B\u6587\r\n- \u5F53\u524D\u65E5\u671F\uFF1A{{date}}\r\n- \u5F53\u524D\u65F6\u95F4\uFF1A{{time}}\r\n- \u5DE5\u4F5C\u76EE\u5F55\uFF1A{{cwd}}\r\n";
1530
1555
 
1531
- ## \u6838\u5FC3\u539F\u5219
1532
- - \u56DE\u7B54\u4F7F\u7528\u4E2D\u6587\uFF0C\u4EE3\u7801\u6807\u8BC6\u7B26\u4FDD\u6301\u82F1\u6587
1533
- - \u63D0\u4F9B\u51C6\u786E\u3001\u5B9E\u7528\u3001\u53EF\u64CD\u4F5C\u7684\u5EFA\u8BAE
1534
- - \u5BF9\u4E0D\u786E\u5B9A\u7684\u5185\u5BB9\u660E\u786E\u6807\u6CE8\uFF0C\u4E0D\u7F16\u9020\u4E8B\u5B9E
1535
- - \u4EE3\u7801\u793A\u4F8B\u4FDD\u6301\u7B80\u6D01\uFF0C\u9644\u5E26\u5FC5\u8981\u7684\u6CE8\u91CA`);
1536
- sections.push(`## \u5F53\u524D\u6A21\u578B
1537
- - \u6A21\u578B\uFF1A${opts.model}`);
1556
+ // src/agent/system-prompt.ts
1557
+ var compiledTemplate = Handlebars.compile(system_prompt_default);
1558
+ var compiledPlanTemplate = Handlebars.compile(plan_prompt_default);
1559
+ function formatTools(tools) {
1560
+ return tools.map((t) => {
1561
+ const params = t.parameters && Object.keys(t.parameters.properties ?? {}).join(", ");
1562
+ return {
1563
+ name: t.name,
1564
+ description: t.description,
1565
+ params: params || void 0
1566
+ };
1567
+ });
1568
+ }
1569
+ function buildTemplateVars(opts) {
1538
1570
  const now = /* @__PURE__ */ new Date();
1539
- const dateStr = now.toLocaleDateString("zh-CN", {
1571
+ const date = now.toLocaleDateString("zh-CN", {
1540
1572
  year: "numeric",
1541
1573
  month: "long",
1542
1574
  day: "numeric",
1543
1575
  weekday: "long"
1544
1576
  });
1545
- const timeStr = now.toLocaleTimeString("zh-CN", {
1577
+ const time = now.toLocaleTimeString("zh-CN", {
1546
1578
  hour: "2-digit",
1547
1579
  minute: "2-digit"
1548
1580
  });
1549
- sections.push(`## \u65F6\u95F4\u4E0A\u4E0B\u6587
1550
- - \u5F53\u524D\u65E5\u671F\uFF1A${dateStr}
1551
- - \u5F53\u524D\u65F6\u95F4\uFF1A${timeStr}
1552
- - \u5DE5\u4F5C\u76EE\u5F55\uFF1A${opts.cwd}`);
1553
- if (opts.tools && opts.tools.length > 0) {
1554
- const toolLines = opts.tools.map((t) => {
1555
- const paramInfo = t.parameters ? Object.keys(t.parameters.properties ?? {}).join(", ") : "";
1556
- return `- **${t.name}**\uFF1A${t.description}${paramInfo ? `\uFF08\u53C2\u6570\uFF1A${paramInfo}\uFF09` : ""}`;
1557
- }).join("\n");
1558
- sections.push(`## \u53EF\u7528\u5DE5\u5177
1559
-
1560
- \u4F60\u53EF\u4EE5\u901A\u8FC7\u5DE5\u5177\u8C03\u7528\u6267\u884C\u64CD\u4F5C\u3002\u5F53\u524D\u53EF\u7528\u7684\u5DE5\u5177\uFF1A
1561
-
1562
- ${toolLines}
1563
-
1564
- \u8C03\u7528\u5DE5\u5177\u65F6\uFF0C\u8BF7\u4F7F\u7528\u6807\u51C6 function_call \u683C\u5F0F\u3002\u5DE5\u5177\u5C06\u7531\u7CFB\u7EDF\u6267\u884C\u5E76\u8FD4\u56DE\u7ED3\u679C\u3002`);
1565
- }
1566
- if (opts.projectContext) {
1567
- sections.push(`## \u9879\u76EE\u4E0A\u4E0B\u6587
1568
-
1569
- ${opts.projectContext}`);
1570
- }
1571
- sections.push(`## \u884C\u4E3A\u7EA6\u675F
1572
- - \u5982\u679C\u7528\u6237\u8BF7\u6C42\u4E0D\u660E\u786E\uFF0C\u8BF7\u4E3B\u52A8\u8BE2\u95EE\u6F84\u6E05
1573
- - \u6D89\u53CA\u6587\u4EF6\u64CD\u4F5C\u65F6\uFF0C\u5148\u786E\u8BA4\u6587\u4EF6\u8DEF\u5F84
1574
- - \u4E0D\u6267\u884C\u53EF\u80FD\u9020\u6210\u4E0D\u53EF\u9006\u635F\u5BB3\u7684\u64CD\u4F5C\uFF08\u5982 rm -rf\uFF09\u9664\u975E\u7528\u6237\u660E\u786E\u786E\u8BA4
1575
- - \u5F53\u5DE5\u5177\u8C03\u7528\u8FD4\u56DE\u9519\u8BEF\u65F6\uFF0C\u5206\u6790\u539F\u56E0\u5E76\u5C1D\u8BD5\u4FEE\u590D`);
1576
- sections.push(EXTRA_PROMPT);
1577
- return sections.join("\n\n");
1581
+ return {
1582
+ model: opts.model,
1583
+ maxToolRounds: opts.maxToolRounds,
1584
+ cwd: opts.cwd,
1585
+ date,
1586
+ time,
1587
+ tools: opts.tools ? formatTools(opts.tools) : void 0,
1588
+ projectContext: opts.projectContext ?? void 0
1589
+ };
1590
+ }
1591
+ function buildSystemPrompt(opts) {
1592
+ return compiledTemplate(buildTemplateVars(opts));
1593
+ }
1594
+ function buildPlanSystemPrompt(opts) {
1595
+ return compiledPlanTemplate(buildTemplateVars(opts));
1578
1596
  }
1579
1597
 
1580
1598
  // src/tool/registry.ts
@@ -1753,6 +1771,8 @@ var Session = class {
1753
1771
  #abortController = new AbortController();
1754
1772
  // 风暴检测:记录每轮的工具调用错误
1755
1773
  #stormRecords = [];
1774
+ /** 当前会话模式:code(代码模式)或 plan(计划模式) */
1775
+ #mode = "code";
1756
1776
  constructor(provider, tools = [], costTracker, options) {
1757
1777
  this.#provider = provider;
1758
1778
  if (tools instanceof ToolRegistry) {
@@ -1791,6 +1811,15 @@ var Session = class {
1791
1811
  get toolRegistry() {
1792
1812
  return this.#toolRegistry;
1793
1813
  }
1814
+ /** 获取当前会话模式 */
1815
+ get mode() {
1816
+ return this.#mode;
1817
+ }
1818
+ /** 切换会话模式,返回新模式 */
1819
+ setMode(mode) {
1820
+ this.#mode = mode;
1821
+ return this.#mode;
1822
+ }
1794
1823
  // -------------------------------------------------------------------------
1795
1824
  // 流式对话 — Agent 主循环
1796
1825
  // -------------------------------------------------------------------------
@@ -2058,15 +2087,23 @@ ${item.result.diff.patch}`;
2058
2087
  }));
2059
2088
  const opts = {
2060
2089
  model: this.#provider.model(),
2090
+ maxToolRounds: this.#options.maxToolRounds,
2061
2091
  tools: toolDescs.length > 0 ? toolDescs : void 0,
2062
2092
  projectContext: this.#options.projectContext ?? void 0,
2063
2093
  cwd: this.#options.cwd
2064
2094
  };
2095
+ if (this.#mode === "plan") {
2096
+ return buildPlanSystemPrompt(opts);
2097
+ }
2065
2098
  return buildSystemPrompt(opts);
2066
2099
  }
2067
- /** 将注册的工具转为 ToolDefinition 格式(预留给 function calling) */
2100
+ /**
2101
+ * 将注册的工具转为 ToolDefinition 格式(预留给 function calling)。
2102
+ * 计划模式下只返回读工具,禁止非读工具暴露给 LLM。
2103
+ */
2068
2104
  #buildToolDefinitions() {
2069
- return this.#toolRegistry.list().map((t) => ({
2105
+ const tools = this.#mode === "plan" ? this.#toolRegistry.listReadTools() : this.#toolRegistry.list();
2106
+ return tools.map((t) => ({
2070
2107
  type: "function",
2071
2108
  function: {
2072
2109
  name: t.name,
@@ -3529,7 +3566,13 @@ function getGradientColors(text, phase, stops) {
3529
3566
  }
3530
3567
 
3531
3568
  // src/ui/ChatSession.tsx
3532
- import { Fragment, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
3569
+ import { Fragment, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
3570
+ var PHASE_CONFIG = {
3571
+ thinking: { icon: "\u{1F9E0}", label: "\u601D\u8003\u4E2D", color: "#ff9800" },
3572
+ generating: { icon: "\u2728", label: "\u751F\u6210\u4E2D", color: "#00ff41" },
3573
+ calling_tools: { icon: "\u{1F6E0}", label: "\u8C03\u7528\u5DE5\u5177", color: "#f59e0b" },
3574
+ executing_tools: { icon: "\u26A1", label: "\u6267\u884C\u5DE5\u5177", color: "#00ffff" }
3575
+ };
3533
3576
  var commandRegistry = /* @__PURE__ */ new Map();
3534
3577
  function registerCommand(name, cmd) {
3535
3578
  commandRegistry.set(name, cmd);
@@ -3557,6 +3600,8 @@ registerCommand("/thinking", { desc: "\u5207\u6362\u6DF1\u5EA6\u601D\u8003\u6A21
3557
3600
  registerCommand("/effort", { desc: "\u5207\u6362\u63A8\u7406\u7B49\u7EA7 High/Max", handler: () => ({ kind: "text", content: "\u8BF7\u76F4\u63A5\u8F93\u5165 /effort \u5207\u6362" }) });
3558
3601
  registerCommand("/game", { desc: "\u542F\u52A8\u6E38\u620F", handler: () => ({ kind: "navigate", target: "game" }) });
3559
3602
  registerCommand("/stock", { desc: "\u67E5\u770B\u80A1\u7968\u884C\u60C5", handler: () => ({ kind: "navigate", target: "stock" }) });
3603
+ registerCommand("/plan", { desc: "\u5207\u6362\u4E3A\u8BA1\u5212\u6A21\u5F0F\uFF08Shift+Tab\uFF09", handler: () => ({ kind: "text", content: "\u8F93\u5165 /plan \u6216\u6309 Shift+Tab \u5207\u6362\u4E3A\u8BA1\u5212\u6A21\u5F0F" }) });
3604
+ registerCommand("/code", { desc: "\u5207\u6362\u56DE\u4EE3\u7801\u6A21\u5F0F\uFF08Shift+Tab\uFF09", handler: () => ({ kind: "text", content: "\u8F93\u5165 /code \u6216\u6309 Shift+Tab \u5207\u6362\u56DE\u4EE3\u7801\u6A21\u5F0F" }) });
3560
3605
  var STREAMING_PLACEHOLDERS = [
3561
3606
  "\u8BA9\u5B50\u5F39\u98DE\u4E00\u4F1A\u513F...",
3562
3607
  "\u9A6C\u4E0A\u5C31\u597D...",
@@ -3599,6 +3644,7 @@ function ChatSession({
3599
3644
  const [balanceLoading, setBalanceLoading] = useState3(false);
3600
3645
  const [todayCost, setTodayCost] = useState3(null);
3601
3646
  const [isStreaming, setIsStreaming] = useState3(false);
3647
+ const [streamingPhase, setStreamingPhase] = useState3(null);
3602
3648
  const [streamingPlaceholder, setStreamingPlaceholder] = useState3("");
3603
3649
  const [idlePlaceholder, setIdlePlaceholder] = useState3(() => pickRandom(IDLE_PLACEHOLDERS));
3604
3650
  const [gradientColors, setGradientColors] = useState3([]);
@@ -3613,6 +3659,7 @@ function ChatSession({
3613
3659
  const [activeModel, setActiveModel] = useState3(model);
3614
3660
  const [streamingModel, setStreamingModel] = useState3(void 0);
3615
3661
  const [streamError, setStreamError] = useState3(void 0);
3662
+ const [sessionMode, setSessionMode] = useState3("code");
3616
3663
  const [thinkingEnabled, setThinkingEnabled] = useState3(true);
3617
3664
  const [thinkingEffort, setThinkingEffort] = useState3("high");
3618
3665
  const [responseFormat, setResponseFormat] = useState3("text");
@@ -3770,11 +3817,28 @@ function ChatSession({
3770
3817
  }
3771
3818
  return;
3772
3819
  }
3820
+ if (key.shift && key.tab) {
3821
+ if (!isStreaming) {
3822
+ const newMode = sessionMode === "plan" ? "code" : "plan";
3823
+ setSessionMode(newMode);
3824
+ sessionRef.current?.setMode(newMode);
3825
+ setToolChoice(void 0);
3826
+ sessionRef.current?.reset();
3827
+ setDisplayMessages((prev) => [
3828
+ ...prev,
3829
+ {
3830
+ role: "assistant",
3831
+ content: newMode === "plan" ? "\u{1F4CB} \u5DF2\u5207\u6362\u4E3A **\u8BA1\u5212\u6A21\u5F0F**\uFF08Shift+Tab\uFF09\n\n\u5728\u6B64\u6A21\u5F0F\u4E0B\uFF0C\u6211\u53EA\u80FD\u8BFB\u53D6\u548C\u5206\u6790\u4EE3\u7801\uFF0C\u4E0D\u4F1A\u6267\u884C\u4EFB\u4F55\u4FEE\u6539\u3002" : "\u{1F6E0} \u5DF2\u5207\u6362\u4E3A **\u4EE3\u7801\u6A21\u5F0F**\uFF08Shift+Tab\uFF09\n\n\u73B0\u5728\u53EF\u4EE5\u6B63\u5E38\u8BFB\u53D6\u548C\u4FEE\u6539\u4EE3\u7801\u4E86\u3002"
3832
+ }
3833
+ ]);
3834
+ }
3835
+ return;
3836
+ }
3773
3837
  if (!input && !isStreaming && _input) {
3774
3838
  setInput(_input);
3775
3839
  }
3776
3840
  },
3777
- [selectingModel, modelSelectIndex, modelOptions, activeModel, isStreaming, handleCtrlC, input, skills, skillSelectIndex, fileSelectIndex, getFilteredSkills, getFilteredFiles]
3841
+ [selectingModel, modelSelectIndex, modelOptions, activeModel, isStreaming, handleCtrlC, input, skills, skillSelectIndex, fileSelectIndex, getFilteredSkills, getFilteredFiles, sessionMode, setSessionMode]
3778
3842
  )
3779
3843
  );
3780
3844
  useEffect3(() => {
@@ -3926,6 +3990,48 @@ function ChatSession({
3926
3990
  setInput("");
3927
3991
  return;
3928
3992
  }
3993
+ if (cmdLower === "/plan") {
3994
+ if (sessionMode === "plan") {
3995
+ setDisplayMessages((prev) => [
3996
+ ...prev,
3997
+ { role: "user", content: trimmed },
3998
+ { role: "assistant", content: "\u5DF2\u7ECF\u5728\u8BA1\u5212\u6A21\u5F0F\u4E2D\u3002\u8F93\u5165 /code \u5207\u56DE\u4EE3\u7801\u6A21\u5F0F\u3002" }
3999
+ ]);
4000
+ } else {
4001
+ setSessionMode("plan");
4002
+ sessionRef.current?.setMode("plan");
4003
+ setToolChoice(void 0);
4004
+ setDisplayMessages((prev) => [
4005
+ ...prev,
4006
+ { role: "user", content: trimmed },
4007
+ { role: "assistant", content: "\u{1F4CB} \u5DF2\u5207\u6362\u4E3A **\u8BA1\u5212\u6A21\u5F0F**\n\n\u5728\u6B64\u6A21\u5F0F\u4E0B\uFF0C\u6211\u53EA\u80FD\u8BFB\u53D6\u548C\u5206\u6790\u4EE3\u7801\uFF0C\u4E0D\u4F1A\u6267\u884C\u4EFB\u4F55\u4FEE\u6539\u3002\n\u8F93\u5165 /code \u5207\u56DE\u4EE3\u7801\u6A21\u5F0F\u3002" }
4008
+ ]);
4009
+ sessionRef.current?.reset();
4010
+ }
4011
+ setInput("");
4012
+ return;
4013
+ }
4014
+ if (cmdLower === "/code") {
4015
+ if (sessionMode === "code") {
4016
+ setDisplayMessages((prev) => [
4017
+ ...prev,
4018
+ { role: "user", content: trimmed },
4019
+ { role: "assistant", content: "\u5DF2\u7ECF\u5728\u4EE3\u7801\u6A21\u5F0F\u4E2D\u3002\u8F93\u5165 /plan \u5207\u56DE\u8BA1\u5212\u6A21\u5F0F\u3002" }
4020
+ ]);
4021
+ } else {
4022
+ setSessionMode("code");
4023
+ sessionRef.current?.setMode("code");
4024
+ setToolChoice(void 0);
4025
+ setDisplayMessages((prev) => [
4026
+ ...prev,
4027
+ { role: "user", content: trimmed },
4028
+ { role: "assistant", content: "\u{1F6E0} \u5DF2\u5207\u6362\u4E3A **\u4EE3\u7801\u6A21\u5F0F**\n\n\u73B0\u5728\u53EF\u4EE5\u6B63\u5E38\u8BFB\u53D6\u548C\u4FEE\u6539\u4EE3\u7801\u4E86\u3002\n\u8F93\u5165 /plan \u5207\u6362\u4E3A\u8BA1\u5212\u6A21\u5F0F\uFF08\u53EA\u8BFB\u5206\u6790\uFF09\u3002" }
4029
+ ]);
4030
+ sessionRef.current?.reset();
4031
+ }
4032
+ setInput("");
4033
+ return;
4034
+ }
3929
4035
  if (cmdLower === "/tools") {
3930
4036
  const next = toolChoice === void 0 ? "none" : toolChoice === "none" ? "required" : toolChoice === "required" ? "auto" : void 0;
3931
4037
  setToolChoice(next);
@@ -3994,6 +4100,7 @@ function ChatSession({
3994
4100
  ]);
3995
4101
  setInput("");
3996
4102
  setIsStreaming(true);
4103
+ setStreamingPhase("thinking");
3997
4104
  setStreamingPlaceholder(pickRandom(STREAMING_PLACEHOLDERS));
3998
4105
  setCurrentContent("");
3999
4106
  setCurrentToolCalls([]);
@@ -4022,6 +4129,7 @@ function ChatSession({
4022
4129
  if (abortController.signal.aborted) break;
4023
4130
  switch (event.type) {
4024
4131
  case "text_delta":
4132
+ setStreamingPhase("generating");
4025
4133
  setCurrentContent((prev) => {
4026
4134
  const next = prev + event.content;
4027
4135
  currentContentRef.current = next;
@@ -4029,6 +4137,7 @@ function ChatSession({
4029
4137
  });
4030
4138
  break;
4031
4139
  case "tool_calls":
4140
+ setStreamingPhase("calling_tools");
4032
4141
  setCurrentToolCalls((prev) => {
4033
4142
  const next = [...prev, ...event.calls];
4034
4143
  currentToolCallsRef.current = next;
@@ -4036,6 +4145,8 @@ function ChatSession({
4036
4145
  });
4037
4146
  break;
4038
4147
  case "tool_result":
4148
+ setStreamingPhase("executing_tools");
4149
+ setTimeout(() => setStreamingPhase("thinking"), 300);
4039
4150
  setCurrentContent("");
4040
4151
  currentContentRef.current = "";
4041
4152
  setCurrentToolCalls([]);
@@ -4078,6 +4189,7 @@ function ChatSession({
4078
4189
  streamErrorRef.current = msg;
4079
4190
  } finally {
4080
4191
  setIsStreaming(false);
4192
+ setStreamingPhase(null);
4081
4193
  setIdlePlaceholder(pickRandom(IDLE_PLACEHOLDERS));
4082
4194
  abortRef.current = null;
4083
4195
  const finContent = currentContentRef.current;
@@ -4102,7 +4214,7 @@ function ChatSession({
4102
4214
  ]);
4103
4215
  }
4104
4216
  }
4105
- }, [onLaunchGame, onLaunchStock, currentContent, currentToolCalls, skills, skillSelectIndex, getFilteredSkills, thinkingEnabled, thinkingEffort, responseFormat, toolChoice, activeModel]);
4217
+ }, [onLaunchGame, onLaunchStock, currentContent, currentToolCalls, skills, skillSelectIndex, getFilteredSkills, thinkingEnabled, thinkingEffort, responseFormat, toolChoice, activeModel, sessionMode]);
4106
4218
  useEffect3(() => {
4107
4219
  if (!isStreaming && externalCostTracker) {
4108
4220
  setTodayCost(externalCostTracker.todayTotalCost);
@@ -4110,33 +4222,34 @@ function ChatSession({
4110
4222
  }, [isStreaming, externalCostTracker]);
4111
4223
  return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingLeft: 1, paddingRight: 1, children: [
4112
4224
  !hasConversationStarted && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", marginBottom: 1, children: [
4113
- /* @__PURE__ */ jsx8(Box8, { flexDirection: "column", marginRight: 4, children: LOGO_LINES.map((line, i) => {
4225
+ /* @__PURE__ */ jsx9(Box8, { flexDirection: "column", marginRight: 4, children: LOGO_LINES.map((line, i) => {
4114
4226
  const colorIndex = (i + offset) % CYBER_PALETTE.length;
4115
- return /* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsx8(Text9, { bold: true, color: CYBER_PALETTE[colorIndex], children: line }) }, i);
4227
+ return /* @__PURE__ */ jsx9(Box8, { children: /* @__PURE__ */ jsx9(Text10, { bold: true, color: CYBER_PALETTE[colorIndex], children: line }) }, i);
4116
4228
  }) }),
4117
4229
  /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", justifyContent: "center", children: [
4118
- /* @__PURE__ */ jsxs8(Text9, { color: "#00ff41", children: [
4230
+ /* @__PURE__ */ jsxs8(Text10, { color: "#00ff41", children: [
4119
4231
  " \u2714 ",
4120
4232
  "\u5DF2\u5C31\u7EEA ",
4121
4233
  skillCount,
4122
4234
  " \u4E2A Skill"
4123
4235
  ] }),
4124
- /* @__PURE__ */ jsxs8(Text9, { color: "#00ffff", children: [
4236
+ /* @__PURE__ */ jsxs8(Text10, { color: "#00ffff", children: [
4125
4237
  " \u2139 ",
4126
4238
  "\u5DF2\u5C31\u7EEA ",
4127
4239
  toolCount,
4128
4240
  " \u4E2A\u5DE5\u5177"
4129
4241
  ] }),
4130
- /* @__PURE__ */ jsxs8(Text9, { color: "#00ffff", children: [
4242
+ /* @__PURE__ */ jsxs8(Text10, { color: "#00ffff", children: [
4131
4243
  " \u{1F527} \u6A21\u578B ",
4132
4244
  SUPPORTED_MODELS[activeModel]?.displayName ?? activeModel
4133
4245
  ] }),
4134
- thinkingEnabled && /* @__PURE__ */ jsxs8(Text9, { color: "#ff9800", children: [
4246
+ thinkingEnabled && /* @__PURE__ */ jsxs8(Text10, { color: "#ff9800", children: [
4135
4247
  " \u{1F9E0} \u6DF1\u5EA6\u601D\u8003 ",
4136
4248
  thinkingEffort === "max" ? "Max" : "High"
4137
4249
  ] }),
4138
- responseFormat === "json_object" && /* @__PURE__ */ jsx8(Text9, { color: "#4caf50", children: " \u{1F4C4} JSON" }),
4139
- toolChoice !== void 0 && /* @__PURE__ */ jsxs8(Text9, { color: "#e91e63", children: [
4250
+ sessionMode === "plan" && /* @__PURE__ */ jsx9(Text10, { color: "#ff69b4", bold: true, children: " \u{1F4CB} \u8BA1\u5212\u6A21\u5F0F" }),
4251
+ responseFormat === "json_object" && /* @__PURE__ */ jsx9(Text10, { color: "#4caf50", children: " \u{1F4C4} JSON" }),
4252
+ toolChoice !== void 0 && /* @__PURE__ */ jsxs8(Text10, { color: "#e91e63", children: [
4140
4253
  " \u{1F6E0} ",
4141
4254
  toolChoice === "none" ? "\u7981\u6B62\u5DE5\u5177" : toolChoice === "required" ? "\u5F3A\u5236\u5DE5\u5177" : ""
4142
4255
  ] }),
@@ -4144,24 +4257,24 @@ function ChatSession({
4144
4257
  const tip = cmdTips[cmdTipIndex % cmdTips.length];
4145
4258
  if (!tip) return null;
4146
4259
  const text = `${tip.name} ${tip.desc}`;
4147
- return /* @__PURE__ */ jsxs8(Text9, { children: [
4148
- /* @__PURE__ */ jsx8(Text9, { color: "#808080", children: " \u{1F4A1} " }),
4149
- cmdTipGradientColors.length > 0 ? text.split("").map((ch, i) => /* @__PURE__ */ jsx8(Text9, { color: cmdTipGradientColors[i] || void 0, children: ch }, i)) : /* @__PURE__ */ jsx8(Text9, { color: "#808080", children: text })
4260
+ return /* @__PURE__ */ jsxs8(Text10, { children: [
4261
+ /* @__PURE__ */ jsx9(Text10, { color: "#808080", children: " \u{1F4A1} " }),
4262
+ cmdTipGradientColors.length > 0 ? text.split("").map((ch, i) => /* @__PURE__ */ jsx9(Text10, { color: cmdTipGradientColors[i] || void 0, children: ch }, i)) : /* @__PURE__ */ jsx9(Text10, { color: "#808080", children: text })
4150
4263
  ] });
4151
4264
  })(),
4152
- verbose ? /* @__PURE__ */ jsx8(Text9, { color: "#ff1493", children: " \u26A1 Verbose" }) : null
4265
+ verbose ? /* @__PURE__ */ jsx9(Text10, { color: "#ff1493", children: " \u26A1 Verbose" }) : null
4153
4266
  ] }),
4154
4267
  /* @__PURE__ */ jsxs8(Box8, { flexGrow: 1, flexDirection: "column", justifyContent: "center", alignItems: "flex-end", children: [
4155
- balanceLoading && balance === null ? /* @__PURE__ */ jsx8(Text9, { color: "yellow", children: " \u23F3 \u67E5\u8BE2\u4F59\u989D..." }) : balance !== null ? /* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", children: [
4156
- /* @__PURE__ */ jsx8(Text9, { color: "yellow", children: "\u{1F4B0} " }),
4157
- /* @__PURE__ */ jsxs8(Text9, { color: "yellow", children: [
4268
+ balanceLoading && balance === null ? /* @__PURE__ */ jsx9(Text10, { color: "yellow", children: " \u23F3 \u67E5\u8BE2\u4F59\u989D..." }) : balance !== null ? /* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", children: [
4269
+ /* @__PURE__ */ jsx9(Text10, { color: "yellow", children: "\u{1F4B0} " }),
4270
+ /* @__PURE__ */ jsxs8(Text10, { color: "yellow", children: [
4158
4271
  "\u4F59\u989D \xA5",
4159
4272
  balance.toFixed(2)
4160
4273
  ] })
4161
4274
  ] }) : null,
4162
4275
  todayCost !== null ? /* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", children: [
4163
- /* @__PURE__ */ jsx8(Text9, { color: "cyan", children: "\u{1F4CA} " }),
4164
- /* @__PURE__ */ jsxs8(Text9, { color: "cyan", children: [
4276
+ /* @__PURE__ */ jsx9(Text10, { color: "cyan", children: "\u{1F4CA} " }),
4277
+ /* @__PURE__ */ jsxs8(Text10, { color: "cyan", children: [
4165
4278
  "\u4ECA\u65E5 \xA5",
4166
4279
  todayCost.toFixed(2)
4167
4280
  ] })
@@ -4169,24 +4282,24 @@ function ChatSession({
4169
4282
  ] })
4170
4283
  ] }),
4171
4284
  /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
4172
- /* @__PURE__ */ jsx8(Static, { items: displayMessages, children: (msg, i) => {
4285
+ /* @__PURE__ */ jsx9(Static, { items: displayMessages, children: (msg, i) => {
4173
4286
  if (msg.role === "user") {
4174
4287
  return /* @__PURE__ */ jsxs8(Box8, { marginTop: 1, children: [
4175
- /* @__PURE__ */ jsx8(Box8, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx8(Text9, { bold: true, color: "#00ff41", children: "\u{1F464}" }) }),
4176
- /* @__PURE__ */ jsx8(Box8, { flexGrow: 1, children: /* @__PURE__ */ jsx8(Text9, { wrap: "wrap", children: msg.content }) })
4288
+ /* @__PURE__ */ jsx9(Box8, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx9(Text10, { bold: true, color: "#00ff41", children: "\u{1F464}" }) }),
4289
+ /* @__PURE__ */ jsx9(Box8, { flexGrow: 1, children: /* @__PURE__ */ jsx9(Text10, { wrap: "wrap", children: msg.content }) })
4177
4290
  ] }, i);
4178
4291
  }
4179
4292
  if (msg.role === "tool") {
4180
4293
  return /* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexDirection: "column", children: [
4181
4294
  /* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", children: [
4182
- /* @__PURE__ */ jsx8(Box8, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx8(Text9, { bold: true, color: "#f59e0b", children: "\u{1F527}" }) }),
4183
- /* @__PURE__ */ jsx8(Box8, { flexGrow: 1, children: /* @__PURE__ */ jsx8(Text9, { wrap: "wrap", children: msg.content }) })
4295
+ /* @__PURE__ */ jsx9(Box8, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx9(Text10, { bold: true, color: "#f59e0b", children: "\u{1F527}" }) }),
4296
+ /* @__PURE__ */ jsx9(Box8, { flexGrow: 1, children: /* @__PURE__ */ jsx9(Text10, { wrap: "wrap", children: msg.content }) })
4184
4297
  ] }),
4185
- msg.diff && /* @__PURE__ */ jsx8(DiffPreview, { diff: msg.diff })
4298
+ msg.diff && /* @__PURE__ */ jsx9(DiffPreview, { diff: msg.diff })
4186
4299
  ] }, i);
4187
4300
  }
4188
4301
  const detail = msg.assistantDetail;
4189
- return /* @__PURE__ */ jsx8(
4302
+ return /* @__PURE__ */ jsx9(
4190
4303
  AssistantMessage,
4191
4304
  {
4192
4305
  content: msg.content,
@@ -4200,7 +4313,7 @@ function ChatSession({
4200
4313
  i
4201
4314
  );
4202
4315
  } }, staticKey),
4203
- isStreaming && /* @__PURE__ */ jsx8(
4316
+ isStreaming && /* @__PURE__ */ jsx9(
4204
4317
  AssistantMessage,
4205
4318
  {
4206
4319
  content: currentContent,
@@ -4208,16 +4321,15 @@ function ChatSession({
4208
4321
  isStreaming: true
4209
4322
  }
4210
4323
  ),
4211
- isStreaming && !currentContent && currentToolCalls.length === 0 && /* @__PURE__ */ jsx8(Box8, { marginTop: 1, marginLeft: 4, children: /* @__PURE__ */ jsx8(Spinner, { type: "dots", label: "\u601D\u8003\u4E2D..." }) }),
4212
- !isStreaming && streamError && /* @__PURE__ */ jsx8(Box8, { marginTop: 1, marginLeft: 3, children: /* @__PURE__ */ jsxs8(Text9, { color: "red", children: [
4324
+ !isStreaming && streamError && /* @__PURE__ */ jsx9(Box8, { marginTop: 1, marginLeft: 3, children: /* @__PURE__ */ jsxs8(Text10, { color: "red", children: [
4213
4325
  "\u26A0 ",
4214
4326
  streamError
4215
4327
  ] }) })
4216
4328
  ] }),
4217
4329
  selectingModel ? /* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexDirection: "column", children: [
4218
- /* @__PURE__ */ jsx8(Text9, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }),
4330
+ /* @__PURE__ */ jsx9(Text10, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }),
4219
4331
  /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
4220
- /* @__PURE__ */ jsx8(Text9, { bold: true, color: "#00ffff", children: "\u9009\u62E9\u6A21\u578B\uFF1A" }),
4332
+ /* @__PURE__ */ jsx9(Text10, { bold: true, color: "#00ffff", children: "\u9009\u62E9\u6A21\u578B\uFF1A" }),
4221
4333
  modelOptions.map((id, i) => {
4222
4334
  const meta = SUPPORTED_MODELS[id];
4223
4335
  const isCurrent = id === activeModel;
@@ -4226,7 +4338,7 @@ function ChatSession({
4226
4338
  const suffix = isCurrent ? " (\u5F53\u524D)" : "";
4227
4339
  return /* @__PURE__ */ jsxs8(Box8, { children: [
4228
4340
  /* @__PURE__ */ jsxs8(
4229
- Text9,
4341
+ Text10,
4230
4342
  {
4231
4343
  color: isSelected ? "#00ff41" : void 0,
4232
4344
  bold: isSelected,
@@ -4237,34 +4349,42 @@ function ChatSession({
4237
4349
  ]
4238
4350
  }
4239
4351
  ),
4240
- isSelected && /* @__PURE__ */ jsxs8(Text9, { color: "#808080", children: [
4352
+ isSelected && /* @__PURE__ */ jsxs8(Text10, { color: "#808080", children: [
4241
4353
  " \u2014 ",
4242
4354
  id
4243
4355
  ] })
4244
4356
  ] }, id);
4245
4357
  }),
4246
- /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text9, { color: "#808080", dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Enter \u786E\u8BA4 \xB7 Esc \u53D6\u6D88" }) })
4358
+ /* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text10, { color: "#808080", dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Enter \u786E\u8BA4 \xB7 Esc \u53D6\u6D88" }) })
4247
4359
  ] }),
4248
- /* @__PURE__ */ jsx8(Text9, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) })
4360
+ /* @__PURE__ */ jsx9(Text10, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) })
4249
4361
  ] }) : /* @__PURE__ */ jsxs8(Fragment, { children: [
4250
- /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: hasConversationStarted && (balance !== null || sessionCost > 0 || isStreaming) ? /* @__PURE__ */ jsxs8(Text9, { color: "#00ffff", dimColor: true, children: [
4251
- "\u2500".repeat(Math.max(dividerWidth - 35, 10)),
4252
- balance !== null && /* @__PURE__ */ jsxs8(Text9, { color: "yellow", children: [
4362
+ (hasConversationStarted || sessionMode === "plan") && isStreaming && streamingPhase ? /* @__PURE__ */ jsx9(Box8, { marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ jsxs8(Text10, { bold: true, color: PHASE_CONFIG[streamingPhase].color, children: [
4363
+ PHASE_CONFIG[streamingPhase].icon,
4364
+ " ",
4365
+ PHASE_CONFIG[streamingPhase].label,
4366
+ " ",
4367
+ /* @__PURE__ */ jsx9(InkSpinner2, { type: "dots" })
4368
+ ] }) }) : null,
4369
+ /* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: hasConversationStarted || sessionMode === "plan" ? /* @__PURE__ */ jsxs8(Text10, { color: sessionMode === "plan" ? "#ff69b4" : "#00ffff", dimColor: sessionMode !== "plan", children: [
4370
+ /* @__PURE__ */ jsx9(Text10, { children: sessionMode === "plan" ? "\u2500".repeat(Math.max(dividerWidth - 48, 1)) : "\u2500".repeat(Math.max(dividerWidth - 35, 10)) }),
4371
+ balance !== null && /* @__PURE__ */ jsxs8(Text10, { color: "yellow", children: [
4253
4372
  " \u{1F4B0} \u4F59\u989D \xA5",
4254
4373
  balance.toFixed(2)
4255
4374
  ] }),
4256
- isStreaming ? /* @__PURE__ */ jsxs8(Text9, { color: "cyan", children: [
4375
+ isStreaming ? /* @__PURE__ */ jsxs8(Text10, { color: "cyan", children: [
4257
4376
  " \u{1F4CA} \u672C\u6B21 \xA5",
4258
4377
  sessionCost > 0 ? sessionCost.toFixed(4) + " " : "",
4259
- /* @__PURE__ */ jsx8(InkSpinner2, { type: "dots" })
4260
- ] }) : sessionCost > 0 ? /* @__PURE__ */ jsxs8(Text9, { color: "cyan", children: [
4378
+ /* @__PURE__ */ jsx9(InkSpinner2, { type: "dots" })
4379
+ ] }) : sessionCost > 0 ? /* @__PURE__ */ jsxs8(Text10, { color: "cyan", children: [
4261
4380
  " \u{1F4CA} \u672C\u6B21 \xA5",
4262
4381
  sessionCost.toFixed(4)
4263
- ] }) : null
4264
- ] }) : /* @__PURE__ */ jsx8(Text9, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }) }),
4382
+ ] }) : null,
4383
+ sessionMode === "plan" && /* @__PURE__ */ jsx9(Text10, { color: "#ff69b4", bold: true, children: " \u{1F4CB} \u8BA1\u5212\u6A21\u5F0F" })
4384
+ ] }) : /* @__PURE__ */ jsx9(Text10, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }) }),
4265
4385
  /* @__PURE__ */ jsxs8(Box8, { children: [
4266
- /* @__PURE__ */ jsx8(Box8, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx8(Text9, { bold: true, color: "#00ff41", children: "\u26A1" }) }),
4267
- /* @__PURE__ */ jsx8(Box8, { flexGrow: 1, children: !input && !isStreaming && idlePlaceholder && gradientColors.length > 0 ? /* @__PURE__ */ jsx8(Text9, { children: idlePlaceholder.split("").map((ch, i) => /* @__PURE__ */ jsx8(Text9, { color: gradientColors[i] ?? void 0, children: ch }, i)) }) : !input && isStreaming && streamingPlaceholder && streamingGradientColors.length > 0 ? /* @__PURE__ */ jsx8(Text9, { children: streamingPlaceholder.split("").map((ch, i) => /* @__PURE__ */ jsx8(Text9, { color: streamingGradientColors[i] ?? void 0, children: ch }, i)) }) : /* @__PURE__ */ jsx8(
4386
+ /* @__PURE__ */ jsx9(Box8, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx9(Text10, { bold: true, color: "#00ff41", children: "\u26A1" }) }),
4387
+ /* @__PURE__ */ jsx9(Box8, { flexGrow: 1, children: !input && !isStreaming && idlePlaceholder && gradientColors.length > 0 ? /* @__PURE__ */ jsx9(Text10, { children: idlePlaceholder.split("").map((ch, i) => /* @__PURE__ */ jsx9(Text10, { color: gradientColors[i] ?? void 0, children: ch }, i)) }) : !input && isStreaming && streamingPlaceholder && streamingGradientColors.length > 0 ? /* @__PURE__ */ jsx9(Text10, { children: streamingPlaceholder.split("").map((ch, i) => /* @__PURE__ */ jsx9(Text10, { color: streamingGradientColors[i] ?? void 0, children: ch }, i)) }) : /* @__PURE__ */ jsx9(
4268
4388
  TextInput,
4269
4389
  {
4270
4390
  value: input,
@@ -4275,19 +4395,19 @@ function ChatSession({
4275
4395
  inputKey
4276
4396
  ) })
4277
4397
  ] }),
4278
- /* @__PURE__ */ jsx8(Box8, { children: /* @__PURE__ */ jsx8(Text9, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }) }),
4279
- /* @__PURE__ */ jsx8(SkillSelector, { skills, input, selectedIndex: skillSelectIndex }),
4280
- /* @__PURE__ */ jsx8(FileSelector, { files, input, selectedIndex: fileSelectIndex })
4398
+ /* @__PURE__ */ jsx9(Box8, { children: /* @__PURE__ */ jsx9(Text10, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }) }),
4399
+ /* @__PURE__ */ jsx9(SkillSelector, { skills, input, selectedIndex: skillSelectIndex }),
4400
+ /* @__PURE__ */ jsx9(FileSelector, { files, input, selectedIndex: fileSelectIndex })
4281
4401
  ] }),
4282
- doubleCtrlC && !isStreaming && /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text9, { color: "#ff1493", bold: true, children: " \u26A0 \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA dskcode" }) }),
4283
- isStreaming && /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text9, { color: "yellow", dimColor: true, children: " \u63D0\u793A\uFF1A\u6309 Ctrl+C \u53D6\u6D88\u5F53\u524D\u8BF7\u6C42" }) })
4402
+ doubleCtrlC && !isStreaming && /* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text10, { color: "#ff1493", bold: true, children: " \u26A0 \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA dskcode" }) }),
4403
+ isStreaming && /* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text10, { color: "yellow", dimColor: true, children: " \u63D0\u793A\uFF1A\u6309 Ctrl+C \u53D6\u6D88\u5F53\u524D\u8BF7\u6C42" }) })
4284
4404
  ] });
4285
4405
  }
4286
4406
 
4287
4407
  // src/ui/GamePicker.tsx
4288
- import { Box as Box9, Text as Text10, useInput as useInput2 } from "ink";
4408
+ import { Box as Box9, Text as Text11, useInput as useInput2 } from "ink";
4289
4409
  import { useState as useState4, useCallback as useCallback3 } from "react";
4290
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
4410
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
4291
4411
  function GamePicker({ games, onSelect, onExit, onBackToChat }) {
4292
4412
  const [selectedIndex, setSelectedIndex] = useState4(0);
4293
4413
  const exitAction = onBackToChat ?? onExit ?? (() => process.exit(0));
@@ -4316,17 +4436,17 @@ function GamePicker({ games, onSelect, onExit, onBackToChat }) {
4316
4436
  )
4317
4437
  );
4318
4438
  return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
4319
- /* @__PURE__ */ jsx9(Box9, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Text10, { bold: true, color: "#00ffff", children: "\u{1F3AE} \u6E38\u620F\u5217\u8868" }) }),
4320
- /* @__PURE__ */ jsx9(Box9, { flexDirection: "column", children: games.map((game, index) => {
4439
+ /* @__PURE__ */ jsx10(Box9, { marginBottom: 1, children: /* @__PURE__ */ jsx10(Text11, { bold: true, color: "#00ffff", children: "\u{1F3AE} \u6E38\u620F\u5217\u8868" }) }),
4440
+ /* @__PURE__ */ jsx10(Box9, { flexDirection: "column", children: games.map((game, index) => {
4321
4441
  const isSelected = index === selectedIndex;
4322
4442
  return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "row", children: [
4323
- /* @__PURE__ */ jsx9(Box9, { width: 3, flexShrink: 0, children: isSelected ? /* @__PURE__ */ jsx9(Text10, { bold: true, color: "#00ff41", children: "\u25B8 " }) : /* @__PURE__ */ jsx9(Text10, { children: " " }) }),
4324
- /* @__PURE__ */ jsx9(Box9, { width: 20, flexShrink: 0, children: /* @__PURE__ */ jsx9(Text10, { bold: true, color: isSelected ? "#00ff41" : "#ffffff", children: game.name }) }),
4325
- /* @__PURE__ */ jsx9(Box9, { children: /* @__PURE__ */ jsx9(Text10, { color: "#888888", children: game.description }) })
4443
+ /* @__PURE__ */ jsx10(Box9, { width: 3, flexShrink: 0, children: isSelected ? /* @__PURE__ */ jsx10(Text11, { bold: true, color: "#00ff41", children: "\u25B8 " }) : /* @__PURE__ */ jsx10(Text11, { children: " " }) }),
4444
+ /* @__PURE__ */ jsx10(Box9, { width: 20, flexShrink: 0, children: /* @__PURE__ */ jsx10(Text11, { bold: true, color: isSelected ? "#00ff41" : "#ffffff", children: game.name }) }),
4445
+ /* @__PURE__ */ jsx10(Box9, { children: /* @__PURE__ */ jsx10(Text11, { color: "#888888", children: game.description }) })
4326
4446
  ] }, game.id);
4327
4447
  }) }),
4328
- /* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text10, { dimColor: true, children: " \u2191/\u2193 \u9009\u62E9 Enter \u542F\u52A8 q \u8FD4\u56DE" }) }),
4329
- doubleCtrlC && /* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text10, { color: "#ff1493", bold: true, children: " \u26A0 \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA dskcode" }) })
4448
+ /* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text11, { dimColor: true, children: " \u2191/\u2193 \u9009\u62E9 Enter \u542F\u52A8 q \u8FD4\u56DE" }) }),
4449
+ doubleCtrlC && /* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text11, { color: "#ff1493", bold: true, children: " \u26A0 \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA dskcode" }) })
4330
4450
  ] });
4331
4451
  }
4332
4452
 
@@ -4343,9 +4463,9 @@ function listGames() {
4343
4463
  }
4344
4464
 
4345
4465
  // src/game/brick-breaker/index.tsx
4346
- import { Box as Box10, Text as Text11, useInput as useInput3, render as render2 } from "ink";
4466
+ import { Box as Box10, Text as Text12, useInput as useInput3, render as render2 } from "ink";
4347
4467
  import { useState as useState5, useEffect as useEffect4, useRef as useRef3, useCallback as useCallback4 } from "react";
4348
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
4468
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
4349
4469
  var GAME_WIDTH = 40;
4350
4470
  var GAME_HEIGHT = 18;
4351
4471
  var PADDLE_WIDTH = 9;
@@ -4537,47 +4657,47 @@ function BrickBreakerGame({ onExit: _onExit }) {
4537
4657
  void tick2;
4538
4658
  return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
4539
4659
  /* @__PURE__ */ jsxs10(Box10, { flexDirection: "row", children: [
4540
- /* @__PURE__ */ jsx10(Box10, { width: 20, children: /* @__PURE__ */ jsxs10(Text11, { children: [
4660
+ /* @__PURE__ */ jsx11(Box10, { width: 20, children: /* @__PURE__ */ jsxs10(Text12, { children: [
4541
4661
  "\u5173\u5361 ",
4542
4662
  s.level,
4543
4663
  ": ",
4544
- /* @__PURE__ */ jsx10(Text11, { color: "cyan", children: def.desc })
4664
+ /* @__PURE__ */ jsx11(Text12, { color: "cyan", children: def.desc })
4545
4665
  ] }) }),
4546
- /* @__PURE__ */ jsx10(Box10, { width: 12, children: /* @__PURE__ */ jsxs10(Text11, { children: [
4666
+ /* @__PURE__ */ jsx11(Box10, { width: 12, children: /* @__PURE__ */ jsxs10(Text12, { children: [
4547
4667
  "\u5206\u6570: ",
4548
- /* @__PURE__ */ jsx10(Text11, { color: "yellow", children: String(s.score).padStart(3, "0") })
4668
+ /* @__PURE__ */ jsx11(Text12, { color: "yellow", children: String(s.score).padStart(3, "0") })
4549
4669
  ] }) }),
4550
- /* @__PURE__ */ jsx10(Box10, { width: 12, children: /* @__PURE__ */ jsxs10(Text11, { children: [
4670
+ /* @__PURE__ */ jsx11(Box10, { width: 12, children: /* @__PURE__ */ jsxs10(Text12, { children: [
4551
4671
  "\u751F\u547D: ",
4552
- /* @__PURE__ */ jsx10(Text11, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) })
4672
+ /* @__PURE__ */ jsx11(Text12, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) })
4553
4673
  ] }) }),
4554
- /* @__PURE__ */ jsx10(Box10, { width: 10, children: /* @__PURE__ */ jsxs10(Text11, { children: [
4674
+ /* @__PURE__ */ jsx11(Box10, { width: 10, children: /* @__PURE__ */ jsxs10(Text12, { children: [
4555
4675
  "\u7816\u5757: ",
4556
- /* @__PURE__ */ jsx10(Text11, { color: "cyan", children: aliveCount })
4676
+ /* @__PURE__ */ jsx11(Text12, { color: "cyan", children: aliveCount })
4557
4677
  ] }) }),
4558
- /* @__PURE__ */ jsx10(Box10, { children: /* @__PURE__ */ jsxs10(Text11, { color: s.paused ? "gray" : "green", children: [
4678
+ /* @__PURE__ */ jsx11(Box10, { children: /* @__PURE__ */ jsxs10(Text12, { color: s.paused ? "gray" : "green", children: [
4559
4679
  "[",
4560
4680
  s.paused ? "\u6682\u505C" : "\u8FD0\u884C\u4E2D",
4561
4681
  "]"
4562
4682
  ] }) })
4563
4683
  ] }),
4564
4684
  /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
4565
- /* @__PURE__ */ jsxs10(Text11, { children: [
4685
+ /* @__PURE__ */ jsxs10(Text12, { children: [
4566
4686
  "\u250C",
4567
4687
  "\u2500".repeat(GAME_WIDTH),
4568
4688
  "\u2510"
4569
4689
  ] }),
4570
- /* @__PURE__ */ jsx10(Text11, { children: selectingLevel ? " \x1B[90m\u9009\u62E9\u5173\u5361\u540E\u5F00\u59CB...\x1B[0m" : board }),
4571
- /* @__PURE__ */ jsxs10(Text11, { children: [
4690
+ /* @__PURE__ */ jsx11(Text12, { children: selectingLevel ? " \x1B[90m\u9009\u62E9\u5173\u5361\u540E\u5F00\u59CB...\x1B[0m" : board }),
4691
+ /* @__PURE__ */ jsxs10(Text12, { children: [
4572
4692
  "\u2514",
4573
4693
  "\u2500".repeat(GAME_WIDTH),
4574
4694
  "\u2518"
4575
4695
  ] })
4576
4696
  ] }),
4577
4697
  selectingLevel && /* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
4578
- /* @__PURE__ */ jsx10(Text11, { bold: true, color: "yellow", children: "\u9009\u62E9\u5173\u5361" }),
4579
- /* @__PURE__ */ jsx10(Box10, { flexDirection: "row", flexWrap: "wrap", children: LEVELS.map((lv, i) => /* @__PURE__ */ jsx10(Box10, { width: 22, children: /* @__PURE__ */ jsxs10(Text11, { children: [
4580
- /* @__PURE__ */ jsx10(Text11, { color: initialLevel === i + 1 ? "green" : "white", children: i + 1 === 10 ? "0" : String(i + 1) }),
4698
+ /* @__PURE__ */ jsx11(Text12, { bold: true, color: "yellow", children: "\u9009\u62E9\u5173\u5361" }),
4699
+ /* @__PURE__ */ jsx11(Box10, { flexDirection: "row", flexWrap: "wrap", children: LEVELS.map((lv, i) => /* @__PURE__ */ jsx11(Box10, { width: 22, children: /* @__PURE__ */ jsxs10(Text12, { children: [
4700
+ /* @__PURE__ */ jsx11(Text12, { color: initialLevel === i + 1 ? "green" : "white", children: i + 1 === 10 ? "0" : String(i + 1) }),
4581
4701
  ". ",
4582
4702
  lv.desc,
4583
4703
  " (",
@@ -4586,16 +4706,16 @@ function BrickBreakerGame({ onExit: _onExit }) {
4586
4706
  lv.cols,
4587
4707
  ")"
4588
4708
  ] }) }, i)) }),
4589
- /* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text11, { dimColor: true, children: "\u6309\u6570\u5B57\u9009\u5173 q \u9000\u51FA" }) })
4709
+ /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text12, { dimColor: true, children: "\u6309\u6570\u5B57\u9009\u5173 q \u9000\u51FA" }) })
4590
4710
  ] }),
4591
4711
  !selectingLevel && (s.gameOver || s.win) && /* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
4592
- /* @__PURE__ */ jsx10(Text11, { bold: true, color: s.gameOver ? "red" : "green", children: s.gameOver ? "\u6E38\u620F\u7ED3\u675F\uFF01" : "\u606D\u559C\u901A\u5173\uFF01" }),
4593
- /* @__PURE__ */ jsxs10(Text11, { children: [
4712
+ /* @__PURE__ */ jsx11(Text12, { bold: true, color: s.gameOver ? "red" : "green", children: s.gameOver ? "\u6E38\u620F\u7ED3\u675F\uFF01" : "\u606D\u559C\u901A\u5173\uFF01" }),
4713
+ /* @__PURE__ */ jsxs10(Text12, { children: [
4594
4714
  " \u5206\u6570: ",
4595
- /* @__PURE__ */ jsx10(Text11, { color: "yellow", children: s.score })
4715
+ /* @__PURE__ */ jsx11(Text12, { color: "yellow", children: s.score })
4596
4716
  ] })
4597
4717
  ] }),
4598
- !selectingLevel && /* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: s.gameOver || s.win ? /* @__PURE__ */ jsx10(Text11, { dimColor: true, children: "\u2190 \u2192 \u79FB\u52A8 r \u91CD\u5F00 l \u9009\u5173 q \u9000\u51FA" }) : /* @__PURE__ */ jsx10(Text11, { dimColor: true, children: "\u2190 \u2192 \u79FB\u52A8 p \u6682\u505C q \u9000\u51FA" }) })
4718
+ !selectingLevel && /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: s.gameOver || s.win ? /* @__PURE__ */ jsx11(Text12, { dimColor: true, children: "\u2190 \u2192 \u79FB\u52A8 r \u91CD\u5F00 l \u9009\u5173 q \u9000\u51FA" }) : /* @__PURE__ */ jsx11(Text12, { dimColor: true, children: "\u2190 \u2192 \u79FB\u52A8 p \u6682\u505C q \u9000\u51FA" }) })
4599
4719
  ] });
4600
4720
  }
4601
4721
  var brick_breaker_default = {
@@ -4605,7 +4725,7 @@ var brick_breaker_default = {
4605
4725
  play: async () => {
4606
4726
  await new Promise((resolve2) => {
4607
4727
  const { unmount } = render2(
4608
- /* @__PURE__ */ jsx10(BrickBreakerGame, { onExit: () => {
4728
+ /* @__PURE__ */ jsx11(BrickBreakerGame, { onExit: () => {
4609
4729
  unmount();
4610
4730
  resolve2();
4611
4731
  } })
@@ -4615,9 +4735,9 @@ var brick_breaker_default = {
4615
4735
  };
4616
4736
 
4617
4737
  // src/game/coder-check/index.tsx
4618
- import { Box as Box11, Text as Text12, useInput as useInput4, render as render3 } from "ink";
4738
+ import { Box as Box11, Text as Text13, useInput as useInput4, render as render3 } from "ink";
4619
4739
  import { useState as useState6, useEffect as useEffect5, useRef as useRef4, useCallback as useCallback5 } from "react";
4620
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
4740
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
4621
4741
  var GAME_W = 66;
4622
4742
  var GAME_H = 20;
4623
4743
  var SCORE_H = 6;
@@ -5089,43 +5209,43 @@ function CoderCheck({ onExit: _onExit }) {
5089
5209
  const view = buildGameView(s, scoreLines, scoreColor, s.message);
5090
5210
  void tick2;
5091
5211
  return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, children: [
5092
- /* @__PURE__ */ jsx11(Box11, { flexDirection: "row", children: /* @__PURE__ */ jsxs11(Text12, { children: [
5212
+ /* @__PURE__ */ jsx12(Box11, { flexDirection: "row", children: /* @__PURE__ */ jsxs11(Text13, { children: [
5093
5213
  "\u751F\u547D ",
5094
- /* @__PURE__ */ jsx11(Text12, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) }),
5214
+ /* @__PURE__ */ jsx12(Text13, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) }),
5095
5215
  " ",
5096
5216
  "\u901F\u5EA6 ",
5097
- /* @__PURE__ */ jsxs11(Text12, { color: "cyan", children: [
5217
+ /* @__PURE__ */ jsxs11(Text13, { color: "cyan", children: [
5098
5218
  "Lv.",
5099
5219
  Math.floor(s.speed * 10)
5100
5220
  ] })
5101
5221
  ] }) }),
5102
- !s.gameOver && s.target && /* @__PURE__ */ jsx11(Box11, { marginTop: 1, children: /* @__PURE__ */ jsxs11(Text12, { children: [
5222
+ !s.gameOver && s.target && /* @__PURE__ */ jsx12(Box11, { marginTop: 1, children: /* @__PURE__ */ jsxs11(Text13, { children: [
5103
5223
  "\u6253\u5B57: ",
5104
- /* @__PURE__ */ jsx11(Text12, { color: "green", children: s.typed }),
5105
- /* @__PURE__ */ jsx11(Text12, { color: "white", children: s.target.slice(s.typed.length) })
5224
+ /* @__PURE__ */ jsx12(Text13, { color: "green", children: s.typed }),
5225
+ /* @__PURE__ */ jsx12(Text13, { color: "white", children: s.target.slice(s.typed.length) })
5106
5226
  ] }) }),
5107
5227
  /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", marginTop: 1, children: [
5108
- /* @__PURE__ */ jsxs11(Text12, { children: [
5228
+ /* @__PURE__ */ jsxs11(Text13, { children: [
5109
5229
  "\u250C",
5110
5230
  "\u2500".repeat(GAME_W),
5111
5231
  "\u2510"
5112
5232
  ] }),
5113
- view.map((row, i) => /* @__PURE__ */ jsx11(Text12, { children: `\u2502${row}\u2502` }, i)),
5114
- /* @__PURE__ */ jsxs11(Text12, { children: [
5233
+ view.map((row, i) => /* @__PURE__ */ jsx12(Text13, { children: `\u2502${row}\u2502` }, i)),
5234
+ /* @__PURE__ */ jsxs11(Text13, { children: [
5115
5235
  "\u2514",
5116
5236
  "\u2500".repeat(GAME_W),
5117
5237
  "\u2518"
5118
5238
  ] })
5119
5239
  ] }),
5120
5240
  s.gameOver && /* @__PURE__ */ jsxs11(Box11, { marginTop: 1, children: [
5121
- /* @__PURE__ */ jsx11(Text12, { bold: true, color: "red", children: "\u6E38\u620F\u7ED3\u675F\uFF01" }),
5122
- /* @__PURE__ */ jsxs11(Text12, { children: [
5241
+ /* @__PURE__ */ jsx12(Text13, { bold: true, color: "red", children: "\u6E38\u620F\u7ED3\u675F\uFF01" }),
5242
+ /* @__PURE__ */ jsxs11(Text13, { children: [
5123
5243
  " \u5F97\u5206: ",
5124
- /* @__PURE__ */ jsx11(Text12, { color: "yellow", children: s.score }),
5244
+ /* @__PURE__ */ jsx12(Text13, { color: "yellow", children: s.score }),
5125
5245
  " r \u91CD\u5F00 q \u9000\u51FA"
5126
5246
  ] })
5127
5247
  ] }),
5128
- /* @__PURE__ */ jsx11(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text12, { dimColor: true, children: "\u6253\u5B57\u6D88\u9664\u5355\u8BCD \u7A7A\u683C/Ctrl+P\u6682\u505C Ctrl+Q\u9000\u51FA" }) })
5248
+ /* @__PURE__ */ jsx12(Box11, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: "\u6253\u5B57\u6D88\u9664\u5355\u8BCD \u7A7A\u683C/Ctrl+P\u6682\u505C Ctrl+Q\u9000\u51FA" }) })
5129
5249
  ] });
5130
5250
  }
5131
5251
  var coder_check_default = {
@@ -5135,7 +5255,7 @@ var coder_check_default = {
5135
5255
  play: async () => {
5136
5256
  await new Promise((resolve2) => {
5137
5257
  const { unmount } = render3(
5138
- /* @__PURE__ */ jsx11(CoderCheck, { onExit: () => {
5258
+ /* @__PURE__ */ jsx12(CoderCheck, { onExit: () => {
5139
5259
  unmount();
5140
5260
  resolve2();
5141
5261
  } })
@@ -5515,12 +5635,12 @@ import { render as render4 } from "ink";
5515
5635
  import chalk5 from "chalk";
5516
5636
 
5517
5637
  // src/stock/StockList.tsx
5518
- import { Box as Box12, Text as Text13, useInput as useInput5 } from "ink";
5638
+ import { Box as Box12, Text as Text14, useInput as useInput5 } from "ink";
5519
5639
  import { useState as useState7, useCallback as useCallback6, useEffect as useEffect6 } from "react";
5520
5640
  import asciichart from "asciichart";
5521
5641
  import os from "os";
5522
5642
  import { join as join7 } from "path";
5523
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
5643
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
5524
5644
  var SETTINGS_PATH = join7(os.homedir(), ".dskcode", "settings.json");
5525
5645
  function toFileUrl(p) {
5526
5646
  const norm = p.replace(/\\/g, "/");
@@ -5731,61 +5851,61 @@ function StockList({ codes, onExit, onBackToChat }) {
5731
5851
  );
5732
5852
  if (detailView) {
5733
5853
  if (detailLoading) {
5734
- return /* @__PURE__ */ jsx12(Box12, { paddingLeft: 1, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: " \u27F3 \u52A0\u8F7D\u5206\u65F6\u6570\u636E..." }) });
5854
+ return /* @__PURE__ */ jsx13(Box12, { paddingLeft: 1, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: " \u27F3 \u52A0\u8F7D\u5206\u65F6\u6570\u636E..." }) });
5735
5855
  }
5736
5856
  return renderDetail(detailView, () => setDetailView(null), detailPrices ?? void 0, detailCountdown, currentTime);
5737
5857
  }
5738
5858
  const cp2 = (c) => dimMode ? { dimColor: true } : { color: c };
5739
5859
  return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
5740
5860
  /* @__PURE__ */ jsxs12(Box12, { marginBottom: 1, justifyContent: "space-between", children: [
5741
- /* @__PURE__ */ jsx12(Text13, { bold: true, ...cp2("#00ffff"), children: " \u{1F4C8} \u81EA\u9009\u80A1\u76D1\u63A7" }),
5742
- /* @__PURE__ */ jsxs12(Text13, { dimColor: true, children: [
5861
+ /* @__PURE__ */ jsx13(Text14, { bold: true, ...cp2("#00ffff"), children: " \u{1F4C8} \u81EA\u9009\u80A1\u76D1\u63A7" }),
5862
+ /* @__PURE__ */ jsxs12(Text14, { dimColor: true, children: [
5743
5863
  " \u{1F550} ",
5744
5864
  currentTime
5745
5865
  ] }),
5746
- /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: loading ? " \u27F3 \u5237\u65B0\u4E2D..." : ` ${countdown}s \u540E\u81EA\u52A8\u5237\u65B0` })
5866
+ /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: loading ? " \u27F3 \u5237\u65B0\u4E2D..." : ` ${countdown}s \u540E\u81EA\u52A8\u5237\u65B0` })
5747
5867
  ] }),
5748
5868
  /* @__PURE__ */ jsxs12(Box12, { children: [
5749
- /* @__PURE__ */ jsx12(Box12, { width: 3 }),
5750
- /* @__PURE__ */ jsx12(Box12, { width: 9, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: "\u4EE3\u7801" }) }),
5751
- /* @__PURE__ */ jsx12(Box12, { width: 16, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: "\u540D\u79F0" }) }),
5752
- /* @__PURE__ */ jsx12(Box12, { width: 12, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: "\u6700\u65B0\u4EF7" }) }),
5753
- /* @__PURE__ */ jsx12(Box12, { width: 12, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: "\u6DA8\u8DCC\u5E45" }) }),
5754
- /* @__PURE__ */ jsx12(Box12, { width: 12, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: "\u6DA8\u8DCC\u989D" }) }),
5755
- /* @__PURE__ */ jsx12(Box12, { width: 12, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: "\u6700\u9AD8" }) }),
5756
- /* @__PURE__ */ jsx12(Box12, { width: 12, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: "\u6700\u4F4E" }) }),
5757
- /* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: "\u6210\u4EA4\u989D" }) })
5869
+ /* @__PURE__ */ jsx13(Box12, { width: 3 }),
5870
+ /* @__PURE__ */ jsx13(Box12, { width: 9, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u4EE3\u7801" }) }),
5871
+ /* @__PURE__ */ jsx13(Box12, { width: 16, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u540D\u79F0" }) }),
5872
+ /* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6700\u65B0\u4EF7" }) }),
5873
+ /* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6DA8\u8DCC\u5E45" }) }),
5874
+ /* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6DA8\u8DCC\u989D" }) }),
5875
+ /* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6700\u9AD8" }) }),
5876
+ /* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6700\u4F4E" }) }),
5877
+ /* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6210\u4EA4\u989D" }) })
5758
5878
  ] }),
5759
- /* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: " " + "\u2500".repeat(100) }) }),
5760
- /* @__PURE__ */ jsx12(Box12, { flexDirection: "column", children: stocks.map((stock, index) => {
5879
+ /* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: " " + "\u2500".repeat(100) }) }),
5880
+ /* @__PURE__ */ jsx13(Box12, { flexDirection: "column", children: stocks.map((stock, index) => {
5761
5881
  const isSelected = index === selectedIndex;
5762
5882
  const isUp = stock.changePercent >= 0;
5763
5883
  const color = isUp ? "#ff1493" : "#00ff41";
5764
5884
  return /* @__PURE__ */ jsxs12(Box12, { children: [
5765
- /* @__PURE__ */ jsx12(Box12, { width: 3, flexShrink: 0, children: isSelected ? /* @__PURE__ */ jsx12(Text13, { bold: true, ...cp2("#00ffff"), children: "\u25B8 " }) : /* @__PURE__ */ jsx12(Text13, { children: " " }) }),
5766
- /* @__PURE__ */ jsx12(Box12, { width: 9, children: /* @__PURE__ */ jsx12(Text13, { bold: true, ...cp2(isSelected ? "#00ffff" : "#ffffff"), children: stock.code }) }),
5767
- /* @__PURE__ */ jsx12(Box12, { width: 16, children: /* @__PURE__ */ jsx12(Text13, { ...cp2(isSelected ? "#ffffff" : "#cccccc"), children: stock.name }) }),
5768
- /* @__PURE__ */ jsx12(Box12, { width: 12, children: /* @__PURE__ */ jsx12(Text13, { bold: true, ...cp2(color), children: formatPrice(stock.price) }) }),
5769
- /* @__PURE__ */ jsx12(Box12, { width: 12, children: /* @__PURE__ */ jsxs12(Text13, { ...cp2(color), children: [
5885
+ /* @__PURE__ */ jsx13(Box12, { width: 3, flexShrink: 0, children: isSelected ? /* @__PURE__ */ jsx13(Text14, { bold: true, ...cp2("#00ffff"), children: "\u25B8 " }) : /* @__PURE__ */ jsx13(Text14, { children: " " }) }),
5886
+ /* @__PURE__ */ jsx13(Box12, { width: 9, children: /* @__PURE__ */ jsx13(Text14, { bold: true, ...cp2(isSelected ? "#00ffff" : "#ffffff"), children: stock.code }) }),
5887
+ /* @__PURE__ */ jsx13(Box12, { width: 16, children: /* @__PURE__ */ jsx13(Text14, { ...cp2(isSelected ? "#ffffff" : "#cccccc"), children: stock.name }) }),
5888
+ /* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { bold: true, ...cp2(color), children: formatPrice(stock.price) }) }),
5889
+ /* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsxs12(Text14, { ...cp2(color), children: [
5770
5890
  isUp ? "+" : "",
5771
5891
  stock.changePercent.toFixed(2),
5772
5892
  "%"
5773
5893
  ] }) }),
5774
- /* @__PURE__ */ jsx12(Box12, { width: 12, children: /* @__PURE__ */ jsxs12(Text13, { ...cp2(color), children: [
5894
+ /* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsxs12(Text14, { ...cp2(color), children: [
5775
5895
  isUp ? "+" : "",
5776
5896
  stock.changeAmount.toFixed(3)
5777
5897
  ] }) }),
5778
- /* @__PURE__ */ jsx12(Box12, { width: 12, children: /* @__PURE__ */ jsx12(Text13, { ...cp2("#cccccc"), children: formatPrice(stock.high) }) }),
5779
- /* @__PURE__ */ jsx12(Box12, { width: 12, children: /* @__PURE__ */ jsx12(Text13, { ...cp2("#888888"), children: formatPrice(stock.low) }) }),
5780
- /* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsx12(Text13, { ...cp2("#888888"), children: formatAmount(stock.amount) }) })
5898
+ /* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { ...cp2("#cccccc"), children: formatPrice(stock.high) }) }),
5899
+ /* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { ...cp2("#888888"), children: formatPrice(stock.low) }) }),
5900
+ /* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsx13(Text14, { ...cp2("#888888"), children: formatAmount(stock.amount) }) })
5781
5901
  ] }, stock.code);
5782
5902
  }) }),
5783
- /* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: ` \u2191/\u2193 \u9009\u62E9 Enter \u8BE6\u60C5 r \u624B\u52A8\u5237\u65B0 h \u7F6E\u7070/\u6062\u590D q \u8FD4\u56DE` }) }),
5903
+ /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: ` \u2191/\u2193 \u9009\u62E9 Enter \u8BE6\u60C5 r \u624B\u52A8\u5237\u65B0 h \u7F6E\u7070/\u6062\u590D q \u8FD4\u56DE` }) }),
5784
5904
  /* @__PURE__ */ jsxs12(Box12, { children: [
5785
- /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: ` \u6700\u540E\u66F4\u65B0: ${lastUpdate} \u7F16\u8F91\u81EA\u9009\u80A1: ` }),
5786
- /* @__PURE__ */ jsx12(Text13, { ...cp2("#c792ea"), children: osc8Link(toFileUrl(SETTINGS_PATH), SETTINGS_PATH) })
5905
+ /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: ` \u6700\u540E\u66F4\u65B0: ${lastUpdate} \u7F16\u8F91\u81EA\u9009\u80A1: ` }),
5906
+ /* @__PURE__ */ jsx13(Text14, { ...cp2("#c792ea"), children: osc8Link(toFileUrl(SETTINGS_PATH), SETTINGS_PATH) })
5787
5907
  ] }),
5788
- doubleCtrlC && /* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text13, { bold: true, ...cp2("#ff1493"), children: " \u26A0 \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA dskcode" }) })
5908
+ doubleCtrlC && /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text14, { bold: true, ...cp2("#ff1493"), children: " \u26A0 \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA dskcode" }) })
5789
5909
  ] });
5790
5910
  }
5791
5911
  function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
@@ -5806,30 +5926,30 @@ function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
5806
5926
  return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingLeft: 1, children: [
5807
5927
  /* @__PURE__ */ jsxs12(Box12, { marginBottom: 1, justifyContent: "space-between", children: [
5808
5928
  /* @__PURE__ */ jsxs12(Box12, { children: [
5809
- /* @__PURE__ */ jsxs12(Text13, { bold: true, color: "#00ffff", children: [
5929
+ /* @__PURE__ */ jsxs12(Text14, { bold: true, color: "#00ffff", children: [
5810
5930
  " \u{1F4CA} ",
5811
5931
  stock.name,
5812
5932
  " "
5813
5933
  ] }),
5814
- /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: stock.code }),
5815
- currentTime && /* @__PURE__ */ jsxs12(Text13, { dimColor: true, children: [
5934
+ /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: stock.code }),
5935
+ currentTime && /* @__PURE__ */ jsxs12(Text14, { dimColor: true, children: [
5816
5936
  " \u{1F550} ",
5817
5937
  currentTime
5818
5938
  ] })
5819
5939
  ] }),
5820
- /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: `${countdown}s \u540E\u5237\u65B0` })
5940
+ /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: `${countdown}s \u540E\u5237\u65B0` })
5821
5941
  ] }),
5822
5942
  /* @__PURE__ */ jsxs12(Box12, { children: [
5823
- /* @__PURE__ */ jsx12(Box12, { width: 16, children: /* @__PURE__ */ jsx12(Text13, { bold: true, color: "#888888", children: "\u5F53\u524D\u4EF7" }) }),
5824
- /* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsxs12(Text13, { bold: true, color: colorCode, children: [
5943
+ /* @__PURE__ */ jsx13(Box12, { width: 16, children: /* @__PURE__ */ jsx13(Text14, { bold: true, color: "#888888", children: "\u5F53\u524D\u4EF7" }) }),
5944
+ /* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsxs12(Text14, { bold: true, color: colorCode, children: [
5825
5945
  arrow,
5826
5946
  " ",
5827
5947
  formatPrice(stock.price)
5828
5948
  ] }) })
5829
5949
  ] }),
5830
5950
  /* @__PURE__ */ jsxs12(Box12, { children: [
5831
- /* @__PURE__ */ jsx12(Box12, { width: 16, children: /* @__PURE__ */ jsx12(Text13, { color: "#888888", children: "\u6DA8\u8DCC\u5E45" }) }),
5832
- /* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsxs12(Text13, { color: colorCode, children: [
5951
+ /* @__PURE__ */ jsx13(Box12, { width: 16, children: /* @__PURE__ */ jsx13(Text14, { color: "#888888", children: "\u6DA8\u8DCC\u5E45" }) }),
5952
+ /* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsxs12(Text14, { color: colorCode, children: [
5833
5953
  isUp ? "+" : "",
5834
5954
  stock.changePercent.toFixed(2),
5835
5955
  "%",
@@ -5838,8 +5958,8 @@ function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
5838
5958
  stock.changeAmount.toFixed(3)
5839
5959
  ] }) })
5840
5960
  ] }),
5841
- chartLines.length > 0 && /* @__PURE__ */ jsx12(Box12, { marginTop: 1, flexDirection: "column", children: chartLines.map((line, i) => /* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsx12(Text13, { color: colorCode, children: line || " " }) }, i)) }),
5842
- /* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: " Space/q \u8FD4\u56DE\u5217\u8868" }) })
5961
+ chartLines.length > 0 && /* @__PURE__ */ jsx13(Box12, { marginTop: 1, flexDirection: "column", children: chartLines.map((line, i) => /* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsx13(Text14, { color: colorCode, children: line || " " }) }, i)) }),
5962
+ /* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: " Space/q \u8FD4\u56DE\u5217\u8868" }) })
5843
5963
  ] });
5844
5964
  }
5845
5965
 
@@ -5924,7 +6044,7 @@ async function scanProjectFiles(baseDir, dir) {
5924
6044
  }
5925
6045
 
5926
6046
  // src/cli/index.tsx
5927
- import { jsx as jsx13 } from "react/jsx-runtime";
6047
+ import { jsx as jsx14 } from "react/jsx-runtime";
5928
6048
  var SUBCOMMANDS = ["chat", "run", "setup", "init", "completion", "game", "stock"];
5929
6049
  function createCli() {
5930
6050
  const program2 = new Command();
@@ -5970,7 +6090,7 @@ function createCli() {
5970
6090
  );
5971
6091
  const model = defaultProvider?.model ?? "deepseek-v4-flash";
5972
6092
  const chatApp = renderApp(
5973
- /* @__PURE__ */ jsx13(
6093
+ /* @__PURE__ */ jsx14(
5974
6094
  ChatSession,
5975
6095
  {
5976
6096
  skillCount,
@@ -5988,7 +6108,7 @@ function createCli() {
5988
6108
  initGames();
5989
6109
  const games = listGames();
5990
6110
  const { unmount } = render4(
5991
- /* @__PURE__ */ jsx13(
6111
+ /* @__PURE__ */ jsx14(
5992
6112
  GamePicker,
5993
6113
  {
5994
6114
  games,
@@ -6012,7 +6132,7 @@ function createCli() {
6012
6132
  setImmediate(() => {
6013
6133
  const defaultStockCodes = ctx?.config.stock?.symbols?.map((s) => s.code) ?? ["sh000001", "sz399006", "sh601688"];
6014
6134
  const stockApp = renderApp(
6015
- /* @__PURE__ */ jsx13(
6135
+ /* @__PURE__ */ jsx14(
6016
6136
  StockList,
6017
6137
  {
6018
6138
  codes: defaultStockCodes,
@@ -6099,7 +6219,7 @@ compdef _dskcode_completion dskcode`);
6099
6219
  const freshResult = await loadAndValidate();
6100
6220
  const codeList = codes && codes.length > 0 ? codes : freshResult.config.stock?.symbols?.map((s) => s.code) ?? ["sh000001", "sz399006", "sh601688"];
6101
6221
  const app = renderApp(
6102
- /* @__PURE__ */ jsx13(
6222
+ /* @__PURE__ */ jsx14(
6103
6223
  StockList,
6104
6224
  {
6105
6225
  codes: codeList,
@@ -6128,7 +6248,7 @@ compdef _dskcode_completion dskcode`);
6128
6248
  }
6129
6249
  const selectedGame = await new Promise((resolve2) => {
6130
6250
  const { unmount } = render4(
6131
- /* @__PURE__ */ jsx13(
6251
+ /* @__PURE__ */ jsx14(
6132
6252
  GamePicker,
6133
6253
  {
6134
6254
  games,