dskcode 0.1.21 → 0.1.23
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/{chunk-BA7UJPKJ.js → chunk-I6HEIOSU.js} +242 -164
- package/dist/chunk-I6HEIOSU.js.map +1 -0
- package/dist/deepseek-YTT76XDE.js +7 -0
- package/dist/index.js +758 -592
- package/dist/index.js.map +1 -1
- package/package.json +9 -2
- package/dist/chunk-7QS2XBBX.js +0 -83
- package/dist/chunk-7QS2XBBX.js.map +0 -1
- package/dist/chunk-BA7UJPKJ.js.map +0 -1
- package/dist/deepseek-UJXV2D6K.js +0 -8
- package/dist/models-OL7DHYGK.js +0 -19
- package/dist/models-OL7DHYGK.js.map +0 -1
- /package/dist/{deepseek-UJXV2D6K.js.map → deepseek-YTT76XDE.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DeepSeekProvider,
|
|
4
|
-
ModelNotSupportedError
|
|
5
|
-
} from "./chunk-BA7UJPKJ.js";
|
|
6
|
-
import {
|
|
4
|
+
ModelNotSupportedError,
|
|
7
5
|
SUPPORTED_MODELS,
|
|
8
6
|
calculateCost,
|
|
9
7
|
estimateTokens,
|
|
10
8
|
getModelMeta,
|
|
11
9
|
isSupportedModel
|
|
12
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-I6HEIOSU.js";
|
|
13
11
|
|
|
14
12
|
// src/cli/index.tsx
|
|
15
13
|
import { Command } from "commander";
|
|
@@ -816,9 +814,9 @@ var LOGO_LINES = [
|
|
|
816
814
|
];
|
|
817
815
|
|
|
818
816
|
// src/ui/ChatSession.tsx
|
|
819
|
-
import { Box as Box8, Text as
|
|
817
|
+
import { Box as Box8, Text as Text10, useInput, Static } from "ink";
|
|
820
818
|
import TextInput from "ink-text-input";
|
|
821
|
-
import { useEffect as useEffect3, useState as useState3, useCallback as useCallback2, useRef as useRef2 } from "react";
|
|
819
|
+
import { useEffect as useEffect3, useState as useState3, useCallback as useCallback2, useMemo, useRef as useRef2 } from "react";
|
|
822
820
|
|
|
823
821
|
// src/ui/useDoubleCtrlC.ts
|
|
824
822
|
import { useState as useState2, useCallback, useEffect as useEffect2, useRef } from "react";
|
|
@@ -848,8 +846,11 @@ function useDoubleCtrlC(onExit) {
|
|
|
848
846
|
return { doubleCtrlC, handleCtrlC };
|
|
849
847
|
}
|
|
850
848
|
|
|
849
|
+
// src/ui/ChatSession.tsx
|
|
850
|
+
import InkSpinner2 from "ink-spinner";
|
|
851
|
+
|
|
851
852
|
// src/ui/AssistantMessage.tsx
|
|
852
|
-
import { Box as Box4, Text as
|
|
853
|
+
import { Box as Box4, Text as Text6 } from "ink";
|
|
853
854
|
|
|
854
855
|
// src/provider/cost-tracker.ts
|
|
855
856
|
import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
|
|
@@ -1255,8 +1256,82 @@ function formatUsageSummary(usage) {
|
|
|
1255
1256
|
return summary;
|
|
1256
1257
|
}
|
|
1257
1258
|
|
|
1259
|
+
// src/ui/HighlightedText.tsx
|
|
1260
|
+
import { Text as Text5 } from "ink";
|
|
1261
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1262
|
+
function parseBoldPairs(text) {
|
|
1263
|
+
const segments = [];
|
|
1264
|
+
let current = 0;
|
|
1265
|
+
while (current < text.length) {
|
|
1266
|
+
const openIdx = text.indexOf("**", current);
|
|
1267
|
+
if (openIdx === -1) {
|
|
1268
|
+
segments.push({ text: text.slice(current), type: "plain" });
|
|
1269
|
+
break;
|
|
1270
|
+
}
|
|
1271
|
+
if (openIdx > current) {
|
|
1272
|
+
segments.push({ text: text.slice(current, openIdx), type: "plain" });
|
|
1273
|
+
}
|
|
1274
|
+
const closeIdx = text.indexOf("**", openIdx + 2);
|
|
1275
|
+
if (closeIdx === -1) {
|
|
1276
|
+
segments.push({ text: text.slice(openIdx), type: "plain" });
|
|
1277
|
+
break;
|
|
1278
|
+
}
|
|
1279
|
+
segments.push({ text: text.slice(openIdx + 2, closeIdx), type: "bold" });
|
|
1280
|
+
current = closeIdx + 2;
|
|
1281
|
+
}
|
|
1282
|
+
return segments;
|
|
1283
|
+
}
|
|
1284
|
+
function parseCodePairs(segments) {
|
|
1285
|
+
const result = [];
|
|
1286
|
+
for (const seg of segments) {
|
|
1287
|
+
if (seg.type !== "plain") {
|
|
1288
|
+
result.push(seg);
|
|
1289
|
+
continue;
|
|
1290
|
+
}
|
|
1291
|
+
let current = 0;
|
|
1292
|
+
const text = seg.text;
|
|
1293
|
+
while (current < text.length) {
|
|
1294
|
+
const openIdx = text.indexOf("`", current);
|
|
1295
|
+
if (openIdx === -1) {
|
|
1296
|
+
result.push({ text: text.slice(current), type: "plain" });
|
|
1297
|
+
break;
|
|
1298
|
+
}
|
|
1299
|
+
if (openIdx > current) {
|
|
1300
|
+
result.push({ text: text.slice(current, openIdx), type: "plain" });
|
|
1301
|
+
}
|
|
1302
|
+
const closeIdx = text.indexOf("`", openIdx + 1);
|
|
1303
|
+
if (closeIdx === -1) {
|
|
1304
|
+
result.push({ text: text.slice(openIdx), type: "plain" });
|
|
1305
|
+
break;
|
|
1306
|
+
}
|
|
1307
|
+
result.push({ text: text.slice(openIdx + 1, closeIdx), type: "code" });
|
|
1308
|
+
current = closeIdx + 1;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
return result;
|
|
1312
|
+
}
|
|
1313
|
+
var CODE_COLOR = "#00BFFF";
|
|
1314
|
+
var BOLD_COLOR = "#A855F7";
|
|
1315
|
+
function HighlightedText({ children: text }) {
|
|
1316
|
+
const boldSegments = parseBoldPairs(text);
|
|
1317
|
+
const segments = parseCodePairs(boldSegments);
|
|
1318
|
+
const isSimple = segments.length === 1 && segments[0].type === "plain";
|
|
1319
|
+
if (isSimple) {
|
|
1320
|
+
return /* @__PURE__ */ jsx4(Text5, { wrap: "wrap", children: text });
|
|
1321
|
+
}
|
|
1322
|
+
return /* @__PURE__ */ jsx4(Text5, { wrap: "wrap", children: segments.map((seg, i) => {
|
|
1323
|
+
if (seg.type === "code") {
|
|
1324
|
+
return /* @__PURE__ */ jsx4(Text5, { color: CODE_COLOR, children: seg.text }, i);
|
|
1325
|
+
}
|
|
1326
|
+
if (seg.type === "bold") {
|
|
1327
|
+
return /* @__PURE__ */ jsx4(Text5, { color: BOLD_COLOR, children: seg.text }, i);
|
|
1328
|
+
}
|
|
1329
|
+
return seg.text;
|
|
1330
|
+
}) });
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1258
1333
|
// src/ui/AssistantMessage.tsx
|
|
1259
|
-
import { jsx as
|
|
1334
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1260
1335
|
function formatElapsed(ms) {
|
|
1261
1336
|
if (ms < 1e3) return `${ms}ms`;
|
|
1262
1337
|
const seconds = (ms / 1e3).toFixed(1);
|
|
@@ -1276,33 +1351,33 @@ function AssistantMessage({
|
|
|
1276
1351
|
}
|
|
1277
1352
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
1278
1353
|
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", children: [
|
|
1279
|
-
/* @__PURE__ */
|
|
1354
|
+
/* @__PURE__ */ jsx5(Box4, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx5(Text6, { bold: true, color: "#ff00ff", children: "\u{1F916}" }) }),
|
|
1280
1355
|
/* @__PURE__ */ jsxs4(Box4, { flexGrow: 1, flexDirection: "column", children: [
|
|
1281
|
-
content && /* @__PURE__ */
|
|
1282
|
-
isStreaming && !content && /* @__PURE__ */
|
|
1356
|
+
content && /* @__PURE__ */ jsx5(HighlightedText, { children: content }),
|
|
1357
|
+
isStreaming && !content && /* @__PURE__ */ jsx5(Text6, { color: "#888888", children: "..." })
|
|
1283
1358
|
] })
|
|
1284
1359
|
] }),
|
|
1285
|
-
toolCalls && toolCalls.length > 0 && /* @__PURE__ */
|
|
1360
|
+
toolCalls && toolCalls.length > 0 && /* @__PURE__ */ jsx5(Box4, { flexDirection: "column", children: toolCalls.map((tc, i) => /* @__PURE__ */ jsx5(ToolCallBlock, { call: tc }, tc.id ?? i)) }),
|
|
1286
1361
|
!isStreaming && (usage || elapsed !== void 0) && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, marginLeft: 3, children: [
|
|
1287
|
-
/* @__PURE__ */
|
|
1362
|
+
/* @__PURE__ */ jsx5(Text6, { color: "#555555", children: "\u2500".repeat(36) }),
|
|
1288
1363
|
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", gap: 2, children: [
|
|
1289
|
-
cost !== void 0 && cost > 0 && /* @__PURE__ */ jsxs4(
|
|
1364
|
+
cost !== void 0 && cost > 0 && /* @__PURE__ */ jsxs4(Text6, { color: "yellow", children: [
|
|
1290
1365
|
"\u{1F4B0} \u672C\u6B21 ",
|
|
1291
1366
|
formatMoney(cost)
|
|
1292
1367
|
] }),
|
|
1293
|
-
elapsed !== void 0 && /* @__PURE__ */ jsxs4(
|
|
1368
|
+
elapsed !== void 0 && /* @__PURE__ */ jsxs4(Text6, { color: "cyan", children: [
|
|
1294
1369
|
"\u{1F550} ",
|
|
1295
1370
|
formatElapsed(elapsed)
|
|
1296
1371
|
] }),
|
|
1297
|
-
usage && /* @__PURE__ */
|
|
1372
|
+
usage && /* @__PURE__ */ jsx5(Text6, { color: "#888888", children: formatUsageSummary(usage) })
|
|
1298
1373
|
] })
|
|
1299
1374
|
] })
|
|
1300
1375
|
] });
|
|
1301
1376
|
}
|
|
1302
1377
|
|
|
1303
1378
|
// src/ui/DiffPreview.tsx
|
|
1304
|
-
import { Box as Box5, Text as
|
|
1305
|
-
import { jsx as
|
|
1379
|
+
import { Box as Box5, Text as Text7 } from "ink";
|
|
1380
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1306
1381
|
function DiffPreview({ diff }) {
|
|
1307
1382
|
const { patch, additions, deletions, existedBefore, filePath } = diff;
|
|
1308
1383
|
if (!patch || patch.length === 0) {
|
|
@@ -1312,13 +1387,13 @@ function DiffPreview({ diff }) {
|
|
|
1312
1387
|
const fileName = filePath.replace(/\\/g, "/").split("/").pop() ?? filePath;
|
|
1313
1388
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
|
|
1314
1389
|
/* @__PURE__ */ jsxs5(Box5, { flexDirection: "row", gap: 1, children: [
|
|
1315
|
-
/* @__PURE__ */ jsxs5(
|
|
1390
|
+
/* @__PURE__ */ jsxs5(Text7, { bold: true, color: "#00ffff", children: [
|
|
1316
1391
|
"\u{1F4DD} ",
|
|
1317
1392
|
existedBefore ? "\u4FEE\u6539" : "\u65B0\u5EFA",
|
|
1318
1393
|
":"
|
|
1319
1394
|
] }),
|
|
1320
|
-
/* @__PURE__ */
|
|
1321
|
-
/* @__PURE__ */ jsxs5(
|
|
1395
|
+
/* @__PURE__ */ jsx6(Text7, { bold: true, children: fileName }),
|
|
1396
|
+
/* @__PURE__ */ jsxs5(Text7, { color: "#555555", children: [
|
|
1322
1397
|
"(+",
|
|
1323
1398
|
additions,
|
|
1324
1399
|
" -",
|
|
@@ -1326,7 +1401,7 @@ function DiffPreview({ diff }) {
|
|
|
1326
1401
|
")"
|
|
1327
1402
|
] })
|
|
1328
1403
|
] }),
|
|
1329
|
-
/* @__PURE__ */
|
|
1404
|
+
/* @__PURE__ */ jsx6(Box5, { flexDirection: "column", marginLeft: 2, children: lines.filter((line) => !line.startsWith("---") && !line.startsWith("+++")).map((line, i) => /* @__PURE__ */ jsx6(DiffLine, { line }, i)) })
|
|
1330
1405
|
] });
|
|
1331
1406
|
}
|
|
1332
1407
|
function DiffLine({ line }) {
|
|
@@ -1334,20 +1409,20 @@ function DiffLine({ line }) {
|
|
|
1334
1409
|
return null;
|
|
1335
1410
|
}
|
|
1336
1411
|
if (line.startsWith("@@")) {
|
|
1337
|
-
return /* @__PURE__ */
|
|
1412
|
+
return /* @__PURE__ */ jsx6(Text7, { color: "#00cccc", children: line });
|
|
1338
1413
|
}
|
|
1339
1414
|
if (line.startsWith("+")) {
|
|
1340
|
-
return /* @__PURE__ */
|
|
1415
|
+
return /* @__PURE__ */ jsx6(Text7, { color: "#22c55e", children: line });
|
|
1341
1416
|
}
|
|
1342
1417
|
if (line.startsWith("-")) {
|
|
1343
|
-
return /* @__PURE__ */
|
|
1418
|
+
return /* @__PURE__ */ jsx6(Text7, { color: "#ef4444", children: line });
|
|
1344
1419
|
}
|
|
1345
|
-
return /* @__PURE__ */
|
|
1420
|
+
return /* @__PURE__ */ jsx6(Text7, { color: "#6b7280", children: line });
|
|
1346
1421
|
}
|
|
1347
1422
|
|
|
1348
1423
|
// src/ui/SkillSelector.tsx
|
|
1349
|
-
import { Box as Box6, Text as
|
|
1350
|
-
import { jsx as
|
|
1424
|
+
import { Box as Box6, Text as Text8 } from "ink";
|
|
1425
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1351
1426
|
var HIGHLIGHT_COLOR = "#00bfff";
|
|
1352
1427
|
function SkillSelector({ skills, input, selectedIndex }) {
|
|
1353
1428
|
const match = input.match(/(?:^|\s)\/([^/]*)$/);
|
|
@@ -1358,18 +1433,18 @@ function SkillSelector({ skills, input, selectedIndex }) {
|
|
|
1358
1433
|
if (query && matched.length > 0 && matched.some((s) => s.name.toLowerCase() === query)) return null;
|
|
1359
1434
|
if (matched.length === 0) return null;
|
|
1360
1435
|
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginLeft: 4, marginTop: 1, children: [
|
|
1361
|
-
/* @__PURE__ */
|
|
1362
|
-
matched.map((skill, i) => /* @__PURE__ */
|
|
1436
|
+
/* @__PURE__ */ jsx7(Text8, { color: "#808080", dimColor: true, children: "\u652F\u6301\u7684 Skill\uFF1A" }),
|
|
1437
|
+
matched.map((skill, i) => /* @__PURE__ */ jsx7(Box6, { children: /* @__PURE__ */ jsxs6(Text8, { color: i === selectedIndex ? HIGHLIGHT_COLOR : "#808080", children: [
|
|
1363
1438
|
i === selectedIndex ? " \u203A " : " ",
|
|
1364
1439
|
skill.name
|
|
1365
1440
|
] }) }, skill.name)),
|
|
1366
|
-
/* @__PURE__ */
|
|
1441
|
+
/* @__PURE__ */ jsx7(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text8, { color: "#808080", dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Tab \u8865\u5168" }) })
|
|
1367
1442
|
] });
|
|
1368
1443
|
}
|
|
1369
1444
|
|
|
1370
1445
|
// src/ui/FileSelector.tsx
|
|
1371
|
-
import { Box as Box7, Text as
|
|
1372
|
-
import { jsx as
|
|
1446
|
+
import { Box as Box7, Text as Text9 } from "ink";
|
|
1447
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1373
1448
|
var HIGHLIGHT_COLOR2 = "#00ff41";
|
|
1374
1449
|
function FileSelector({ files, input, selectedIndex }) {
|
|
1375
1450
|
const match = input.match(/(?:^|\s)@([^@]*)$/);
|
|
@@ -1380,12 +1455,12 @@ function FileSelector({ files, input, selectedIndex }) {
|
|
|
1380
1455
|
if (query && matched.some((f) => f.toLowerCase() === query)) return null;
|
|
1381
1456
|
if (matched.length === 0) return null;
|
|
1382
1457
|
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginLeft: 4, marginTop: 1, children: [
|
|
1383
|
-
/* @__PURE__ */
|
|
1384
|
-
matched.map((file, i) => /* @__PURE__ */
|
|
1458
|
+
/* @__PURE__ */ jsx8(Text9, { color: "#808080", dimColor: true, children: "\u9879\u76EE\u6587\u4EF6\uFF1A" }),
|
|
1459
|
+
matched.map((file, i) => /* @__PURE__ */ jsx8(Box7, { children: /* @__PURE__ */ jsxs7(Text9, { color: i === selectedIndex ? HIGHLIGHT_COLOR2 : "#808080", children: [
|
|
1385
1460
|
i === selectedIndex ? " \u203A " : " ",
|
|
1386
1461
|
file
|
|
1387
1462
|
] }) }, file)),
|
|
1388
|
-
/* @__PURE__ */
|
|
1463
|
+
/* @__PURE__ */ jsx8(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text9, { color: "#808080", dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Tab \u8865\u5168" }) })
|
|
1389
1464
|
] });
|
|
1390
1465
|
}
|
|
1391
1466
|
|
|
@@ -1440,116 +1515,111 @@ function createProvider(config) {
|
|
|
1440
1515
|
return defaultRegistry.get(config.name, config);
|
|
1441
1516
|
}
|
|
1442
1517
|
|
|
1443
|
-
// src/
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
" \u4E95\u53F7\u4E32 \u4F18\u5316\u6570\u636E\u5E93\u67E5\u8BE2\uFF08\u8FD9\u662F\u9519\u8BEF\u7684\uFF09",
|
|
1481
|
-
" \u661F\u53F7 \u6DFB\u52A0\u7D22\u5F15\u5230 user_id \u5B57\u6BB5\uFF08\u8FD9\u662F\u9519\u8BEF\u7684\uFF09",
|
|
1482
|
-
" \u4E09\u4E2A\u53CD\u5F15\u53F7\u5F00\u59CB\u6216\u7ED3\u675F\uFF08\u8FD9\u662F\u9519\u8BEF\u7684\uFF09",
|
|
1483
|
-
"",
|
|
1484
|
-
"\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"
|
|
1485
|
-
].join("\n");
|
|
1518
|
+
// src/tool/types.ts
|
|
1519
|
+
function eraseTool(tool) {
|
|
1520
|
+
return {
|
|
1521
|
+
get name() {
|
|
1522
|
+
return tool.name;
|
|
1523
|
+
},
|
|
1524
|
+
get description() {
|
|
1525
|
+
return tool.description;
|
|
1526
|
+
},
|
|
1527
|
+
get kind() {
|
|
1528
|
+
return tool.kind;
|
|
1529
|
+
},
|
|
1530
|
+
get parameters() {
|
|
1531
|
+
return tool.parameters;
|
|
1532
|
+
},
|
|
1533
|
+
get supportsInputStreaming() {
|
|
1534
|
+
return tool.supportsInputStreaming ?? false;
|
|
1535
|
+
},
|
|
1536
|
+
get supportedProviders() {
|
|
1537
|
+
return tool.supportedProviders ?? [];
|
|
1538
|
+
},
|
|
1539
|
+
async execute(args, ctx) {
|
|
1540
|
+
return tool.execute(args, ctx);
|
|
1541
|
+
},
|
|
1542
|
+
initialTitle(args) {
|
|
1543
|
+
return tool.initialTitle?.(args) ?? `${tool.name}`;
|
|
1544
|
+
}
|
|
1545
|
+
};
|
|
1546
|
+
}
|
|
1547
|
+
function isReadOnly(kind) {
|
|
1548
|
+
return kind === "read" /* Read */;
|
|
1549
|
+
}
|
|
1550
|
+
var AlwaysAllowGate = class {
|
|
1551
|
+
check(_toolName, _args) {
|
|
1552
|
+
return true;
|
|
1553
|
+
}
|
|
1554
|
+
};
|
|
1486
1555
|
|
|
1487
1556
|
// src/agent/system-prompt.ts
|
|
1488
|
-
|
|
1489
|
-
const sections = [];
|
|
1490
|
-
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
|
|
1557
|
+
import Handlebars from "handlebars";
|
|
1491
1558
|
|
|
1492
|
-
|
|
1493
|
-
- \u56DE\u7B54\u4F7F\u7528\u4E2D\u6587\uFF0C\u4EE3\u7801\u6807\u8BC6\u7B26\u4FDD\u6301\u82F1\u6587
|
|
1494
|
-
|
|
1495
|
-
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1559
|
+
// src/agent/prompts/system-prompt.hbs
|
|
1560
|
+
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';
|
|
1561
|
+
|
|
1562
|
+
// src/agent/system-prompt.ts
|
|
1563
|
+
var compiledTemplate = Handlebars.compile(system_prompt_default);
|
|
1564
|
+
function formatTools(tools) {
|
|
1565
|
+
return tools.map((t) => {
|
|
1566
|
+
const params = t.parameters && Object.keys(t.parameters.properties ?? {}).join(", ");
|
|
1567
|
+
return {
|
|
1568
|
+
name: t.name,
|
|
1569
|
+
description: t.description,
|
|
1570
|
+
params: params || void 0
|
|
1571
|
+
};
|
|
1572
|
+
});
|
|
1573
|
+
}
|
|
1574
|
+
function buildSystemPrompt(opts) {
|
|
1499
1575
|
const now = /* @__PURE__ */ new Date();
|
|
1500
|
-
const
|
|
1576
|
+
const date = now.toLocaleDateString("zh-CN", {
|
|
1501
1577
|
year: "numeric",
|
|
1502
1578
|
month: "long",
|
|
1503
1579
|
day: "numeric",
|
|
1504
1580
|
weekday: "long"
|
|
1505
1581
|
});
|
|
1506
|
-
const
|
|
1582
|
+
const time = now.toLocaleTimeString("zh-CN", {
|
|
1507
1583
|
hour: "2-digit",
|
|
1508
1584
|
minute: "2-digit"
|
|
1509
1585
|
});
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
sections.push(`## \u53EF\u7528\u5DE5\u5177
|
|
1520
|
-
|
|
1521
|
-
\u4F60\u53EF\u4EE5\u901A\u8FC7\u5DE5\u5177\u8C03\u7528\u6267\u884C\u64CD\u4F5C\u3002\u5F53\u524D\u53EF\u7528\u7684\u5DE5\u5177\uFF1A
|
|
1522
|
-
|
|
1523
|
-
${toolLines}
|
|
1524
|
-
|
|
1525
|
-
\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`);
|
|
1526
|
-
}
|
|
1527
|
-
if (opts.projectContext) {
|
|
1528
|
-
sections.push(`## \u9879\u76EE\u4E0A\u4E0B\u6587
|
|
1529
|
-
|
|
1530
|
-
${opts.projectContext}`);
|
|
1531
|
-
}
|
|
1532
|
-
sections.push(`## \u884C\u4E3A\u7EA6\u675F
|
|
1533
|
-
- \u5982\u679C\u7528\u6237\u8BF7\u6C42\u4E0D\u660E\u786E\uFF0C\u8BF7\u4E3B\u52A8\u8BE2\u95EE\u6F84\u6E05
|
|
1534
|
-
- \u6D89\u53CA\u6587\u4EF6\u64CD\u4F5C\u65F6\uFF0C\u5148\u786E\u8BA4\u6587\u4EF6\u8DEF\u5F84
|
|
1535
|
-
- \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
|
|
1536
|
-
- \u5F53\u5DE5\u5177\u8C03\u7528\u8FD4\u56DE\u9519\u8BEF\u65F6\uFF0C\u5206\u6790\u539F\u56E0\u5E76\u5C1D\u8BD5\u4FEE\u590D`);
|
|
1537
|
-
sections.push(EXTRA_PROMPT);
|
|
1538
|
-
return sections.join("\n\n");
|
|
1586
|
+
return compiledTemplate({
|
|
1587
|
+
model: opts.model,
|
|
1588
|
+
maxToolRounds: opts.maxToolRounds,
|
|
1589
|
+
cwd: opts.cwd,
|
|
1590
|
+
date,
|
|
1591
|
+
time,
|
|
1592
|
+
tools: opts.tools ? formatTools(opts.tools) : void 0,
|
|
1593
|
+
projectContext: opts.projectContext ?? void 0
|
|
1594
|
+
});
|
|
1539
1595
|
}
|
|
1540
1596
|
|
|
1541
1597
|
// src/tool/registry.ts
|
|
1542
1598
|
var ToolRegistry = class {
|
|
1543
1599
|
#tools = /* @__PURE__ */ new Map();
|
|
1544
1600
|
#disabledNames;
|
|
1601
|
+
#featureFlagChecker;
|
|
1602
|
+
#provider;
|
|
1603
|
+
/** 所有已注册工具的名称列表(编译期等效) */
|
|
1604
|
+
static ALL_TOOL_NAMES = [];
|
|
1545
1605
|
constructor(opts) {
|
|
1546
1606
|
this.#disabledNames = new Set(opts?.disabledTools ?? []);
|
|
1607
|
+
this.#featureFlagChecker = opts?.featureFlagChecker ?? (() => true);
|
|
1608
|
+
this.#provider = opts?.provider;
|
|
1547
1609
|
}
|
|
1548
1610
|
/**
|
|
1549
|
-
*
|
|
1611
|
+
* 注册一个类型安全的 AgentTool。
|
|
1612
|
+
* 自动擦除类型参数后存储。
|
|
1550
1613
|
* 如果同名工具已存在则抛出错误。
|
|
1551
1614
|
*/
|
|
1552
1615
|
register(tool) {
|
|
1616
|
+
return this.registerErased(eraseTool(tool));
|
|
1617
|
+
}
|
|
1618
|
+
/**
|
|
1619
|
+
* 注册一个已经擦除类型 AnyAgentTool。
|
|
1620
|
+
* 如果同名工具已存在则抛出错误。
|
|
1621
|
+
*/
|
|
1622
|
+
registerErased(tool) {
|
|
1553
1623
|
if (this.#tools.has(tool.name)) {
|
|
1554
1624
|
throw new Error(`\u5DE5\u5177 "${tool.name}" \u5DF2\u6CE8\u518C\uFF0C\u4E0D\u80FD\u91CD\u590D\u6CE8\u518C`);
|
|
1555
1625
|
}
|
|
@@ -1561,7 +1631,7 @@ var ToolRegistry = class {
|
|
|
1561
1631
|
*/
|
|
1562
1632
|
registerAll(tools) {
|
|
1563
1633
|
for (const tool of tools) {
|
|
1564
|
-
this.
|
|
1634
|
+
this.registerErased(tool);
|
|
1565
1635
|
}
|
|
1566
1636
|
return this;
|
|
1567
1637
|
}
|
|
@@ -1572,25 +1642,44 @@ var ToolRegistry = class {
|
|
|
1572
1642
|
return this.#tools.delete(name);
|
|
1573
1643
|
}
|
|
1574
1644
|
/**
|
|
1575
|
-
*
|
|
1576
|
-
*
|
|
1645
|
+
* 按名称获取工具(未擦除类型版本,调用方自行断言类型)。
|
|
1646
|
+
* 如果工具被禁用、被 feature flag 拦截、或不支持当前 provider,返回 undefined。
|
|
1577
1647
|
*/
|
|
1578
1648
|
get(name) {
|
|
1579
|
-
if (this.#
|
|
1649
|
+
if (!this.#isToolEnabled(name)) return void 0;
|
|
1580
1650
|
return this.#tools.get(name);
|
|
1581
1651
|
}
|
|
1582
1652
|
/**
|
|
1583
1653
|
* 获取所有启用的工具列表。
|
|
1654
|
+
* 依次应用:禁用列表 → Feature Flag → Provider 过滤。
|
|
1584
1655
|
*/
|
|
1585
1656
|
list() {
|
|
1586
1657
|
const result = [];
|
|
1587
1658
|
for (const [name, tool] of this.#tools) {
|
|
1588
|
-
if (
|
|
1659
|
+
if (this.#isToolEnabled(name)) {
|
|
1589
1660
|
result.push(tool);
|
|
1590
1661
|
}
|
|
1591
1662
|
}
|
|
1592
1663
|
return result;
|
|
1593
1664
|
}
|
|
1665
|
+
/**
|
|
1666
|
+
* 按 ToolKind 分类获取工具列表。
|
|
1667
|
+
*/
|
|
1668
|
+
listByKind(kind) {
|
|
1669
|
+
return this.list().filter((t) => t.kind === kind);
|
|
1670
|
+
}
|
|
1671
|
+
/**
|
|
1672
|
+
* 获取读工具列表(可并行执行)。
|
|
1673
|
+
*/
|
|
1674
|
+
listReadTools() {
|
|
1675
|
+
return this.listByKind("read" /* Read */);
|
|
1676
|
+
}
|
|
1677
|
+
/**
|
|
1678
|
+
* 获取写工具列表(需串行执行)。
|
|
1679
|
+
*/
|
|
1680
|
+
listWriteTools() {
|
|
1681
|
+
return this.list().filter((t) => !isReadOnly(t.kind));
|
|
1682
|
+
}
|
|
1594
1683
|
/**
|
|
1595
1684
|
* 获取所有已注册的工具名称(含禁用的)。
|
|
1596
1685
|
*/
|
|
@@ -1604,10 +1693,10 @@ var ToolRegistry = class {
|
|
|
1604
1693
|
return this.#tools.has(name);
|
|
1605
1694
|
}
|
|
1606
1695
|
/**
|
|
1607
|
-
*
|
|
1696
|
+
* 检查工具是否已启用(注册 + 未禁用 + 通过 feature flag + 支持 provider)。
|
|
1608
1697
|
*/
|
|
1609
1698
|
isEnabled(name) {
|
|
1610
|
-
return this.#tools.has(name) &&
|
|
1699
|
+
return this.#tools.has(name) && this.#isToolEnabled(name);
|
|
1611
1700
|
}
|
|
1612
1701
|
/**
|
|
1613
1702
|
* 禁用一个工具。
|
|
@@ -1621,6 +1710,12 @@ var ToolRegistry = class {
|
|
|
1621
1710
|
enable(name) {
|
|
1622
1711
|
this.#disabledNames.delete(name);
|
|
1623
1712
|
}
|
|
1713
|
+
/**
|
|
1714
|
+
* 获取工具的分类语义。
|
|
1715
|
+
*/
|
|
1716
|
+
kindOf(name) {
|
|
1717
|
+
return this.#tools.get(name)?.kind;
|
|
1718
|
+
}
|
|
1624
1719
|
/**
|
|
1625
1720
|
* 执行指定工具。
|
|
1626
1721
|
*
|
|
@@ -1646,11 +1741,21 @@ var ToolRegistry = class {
|
|
|
1646
1741
|
};
|
|
1647
1742
|
}
|
|
1648
1743
|
}
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
//
|
|
1652
|
-
|
|
1653
|
-
|
|
1744
|
+
// ---------------------------------------------------------------------------
|
|
1745
|
+
// 内部方法
|
|
1746
|
+
// ---------------------------------------------------------------------------
|
|
1747
|
+
/**
|
|
1748
|
+
* 判断工具是否应该启用。
|
|
1749
|
+
* 依次检查:是否在禁用列表 → 是否通过 Feature Flag → 是否支持当前 Provider。
|
|
1750
|
+
*/
|
|
1751
|
+
#isToolEnabled(name) {
|
|
1752
|
+
const tool = this.#tools.get(name);
|
|
1753
|
+
if (!tool) return false;
|
|
1754
|
+
if (this.#disabledNames.has(name)) return false;
|
|
1755
|
+
if (!this.#featureFlagChecker(name)) return false;
|
|
1756
|
+
if (this.#provider && tool.supportedProviders.length > 0) {
|
|
1757
|
+
if (!tool.supportedProviders.includes(this.#provider)) return false;
|
|
1758
|
+
}
|
|
1654
1759
|
return true;
|
|
1655
1760
|
}
|
|
1656
1761
|
};
|
|
@@ -1718,7 +1823,7 @@ var Session = class {
|
|
|
1718
1823
|
* d. 如果没有工具调用 → 退出循环
|
|
1719
1824
|
* 3. yield done 事件
|
|
1720
1825
|
*/
|
|
1721
|
-
async *chat(userInput) {
|
|
1826
|
+
async *chat(userInput, opts) {
|
|
1722
1827
|
this.#messages.push({ role: "user", content: userInput });
|
|
1723
1828
|
const startTime = Date.now();
|
|
1724
1829
|
let toolRounds = 0;
|
|
@@ -1738,7 +1843,11 @@ var Session = class {
|
|
|
1738
1843
|
const toolDefs = this.#buildToolDefinitions();
|
|
1739
1844
|
const stream = this.#provider.chat(apiMessages, {
|
|
1740
1845
|
signal: this.#abortController.signal,
|
|
1741
|
-
tools: toolDefs.length > 0 ? toolDefs : void 0
|
|
1846
|
+
tools: toolDefs.length > 0 ? toolDefs : void 0,
|
|
1847
|
+
thinkingAllowed: opts?.thinkingAllowed,
|
|
1848
|
+
thinkingEffort: opts?.thinkingEffort,
|
|
1849
|
+
responseFormat: opts?.responseFormat,
|
|
1850
|
+
toolChoice: opts?.toolChoice
|
|
1742
1851
|
});
|
|
1743
1852
|
let accumulatedText = "";
|
|
1744
1853
|
let lastUsage;
|
|
@@ -1840,7 +1949,7 @@ ${item.result.diff.patch}`;
|
|
|
1840
1949
|
};
|
|
1841
1950
|
const allReadOnly = calls.every((tc) => {
|
|
1842
1951
|
const tool = this.#toolRegistry.get(tc.name);
|
|
1843
|
-
return tool
|
|
1952
|
+
return tool ? isReadOnly(tool.kind) : true;
|
|
1844
1953
|
});
|
|
1845
1954
|
if (allReadOnly && calls.length > 1) {
|
|
1846
1955
|
const MAX_PARALLEL = 8;
|
|
@@ -1894,11 +2003,11 @@ ${item.result.diff.patch}`;
|
|
|
1894
2003
|
record: { name: toolName, success: false, error: "GATE_DENIED", timestamp }
|
|
1895
2004
|
};
|
|
1896
2005
|
}
|
|
1897
|
-
if (!tool.
|
|
1898
|
-
const
|
|
1899
|
-
if (typeof
|
|
2006
|
+
if (!isReadOnly(tool.kind)) {
|
|
2007
|
+
const maybePreview = tool.preview;
|
|
2008
|
+
if (typeof maybePreview === "function") {
|
|
1900
2009
|
try {
|
|
1901
|
-
await
|
|
2010
|
+
await maybePreview(toolArgs, ctx);
|
|
1902
2011
|
} catch {
|
|
1903
2012
|
}
|
|
1904
2013
|
}
|
|
@@ -1966,6 +2075,7 @@ ${item.result.diff.patch}`;
|
|
|
1966
2075
|
}));
|
|
1967
2076
|
const opts = {
|
|
1968
2077
|
model: this.#provider.model(),
|
|
2078
|
+
maxToolRounds: this.#options.maxToolRounds,
|
|
1969
2079
|
tools: toolDescs.length > 0 ? toolDescs : void 0,
|
|
1970
2080
|
projectContext: this.#options.projectContext ?? void 0,
|
|
1971
2081
|
cwd: this.#options.cwd
|
|
@@ -2413,25 +2523,6 @@ async function writeFileWithEol(filePath, originalContent, newContent) {
|
|
|
2413
2523
|
import { readFile as readFile4, stat } from "fs/promises";
|
|
2414
2524
|
import { open } from "fs/promises";
|
|
2415
2525
|
import { relative as relative2 } from "path";
|
|
2416
|
-
var readFileSchema = {
|
|
2417
|
-
type: "object",
|
|
2418
|
-
properties: {
|
|
2419
|
-
path: {
|
|
2420
|
-
type: "string",
|
|
2421
|
-
description: "\u6587\u4EF6\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09"
|
|
2422
|
-
},
|
|
2423
|
-
startLine: {
|
|
2424
|
-
type: "number",
|
|
2425
|
-
description: "\u8D77\u59CB\u884C\u53F7\uFF08\u4ECE 1 \u5F00\u59CB\uFF09\uFF0C\u9ED8\u8BA4\u4E3A 1"
|
|
2426
|
-
},
|
|
2427
|
-
endLine: {
|
|
2428
|
-
type: "number",
|
|
2429
|
-
description: "\u7ED3\u675F\u884C\u53F7\uFF08\u5305\u542B\uFF09\uFF0C\u9ED8\u8BA4\u5230\u6587\u4EF6\u672B\u5C3E"
|
|
2430
|
-
}
|
|
2431
|
-
},
|
|
2432
|
-
required: ["path"],
|
|
2433
|
-
additionalProperties: false
|
|
2434
|
-
};
|
|
2435
2526
|
async function checkBinary(filePath) {
|
|
2436
2527
|
const fileHandle = await open(filePath, "r");
|
|
2437
2528
|
try {
|
|
@@ -2444,15 +2535,32 @@ async function checkBinary(filePath) {
|
|
|
2444
2535
|
}
|
|
2445
2536
|
var readFileTool = {
|
|
2446
2537
|
name: "read_file",
|
|
2538
|
+
kind: "read" /* Read */,
|
|
2447
2539
|
description: "\u8BFB\u53D6\u6307\u5B9A\u8DEF\u5F84\u7684\u6587\u4EF6\u5185\u5BB9\u3002\u652F\u6301\u884C\u53F7\u8303\u56F4\u9009\u62E9\uFF0C\u8F93\u51FA\u5E26\u884C\u53F7\u3002\u9002\u7528\u4E8E\u67E5\u770B\u6E90\u4EE3\u7801\u3001\u914D\u7F6E\u6587\u4EF6\u7B49\u6587\u672C\u6587\u4EF6\u3002\u81EA\u52A8\u62D2\u7EDD\u4E8C\u8FDB\u5236\u6587\u4EF6\u3002",
|
|
2448
|
-
parameters:
|
|
2449
|
-
|
|
2540
|
+
parameters: {
|
|
2541
|
+
type: "object",
|
|
2542
|
+
properties: {
|
|
2543
|
+
path: {
|
|
2544
|
+
type: "string",
|
|
2545
|
+
description: "\u6587\u4EF6\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09"
|
|
2546
|
+
},
|
|
2547
|
+
startLine: {
|
|
2548
|
+
type: "number",
|
|
2549
|
+
description: "\u8D77\u59CB\u884C\u53F7\uFF08\u4ECE 1 \u5F00\u59CB\uFF09\uFF0C\u9ED8\u8BA4\u4E3A 1"
|
|
2550
|
+
},
|
|
2551
|
+
endLine: {
|
|
2552
|
+
type: "number",
|
|
2553
|
+
description: "\u7ED3\u675F\u884C\u53F7\uFF08\u5305\u542B\uFF09\uFF0C\u9ED8\u8BA4\u5230\u6587\u4EF6\u672B\u5C3E"
|
|
2554
|
+
}
|
|
2555
|
+
},
|
|
2556
|
+
required: ["path"],
|
|
2557
|
+
additionalProperties: false
|
|
2558
|
+
},
|
|
2450
2559
|
async execute(args, ctx) {
|
|
2451
|
-
|
|
2452
|
-
if (!params?.path || typeof params.path !== "string") {
|
|
2560
|
+
if (!args?.path || typeof args.path !== "string") {
|
|
2453
2561
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 path", error: "INVALID_ARGS" };
|
|
2454
2562
|
}
|
|
2455
|
-
const filePath = resolvePath(
|
|
2563
|
+
const filePath = resolvePath(args.path, ctx.cwd);
|
|
2456
2564
|
try {
|
|
2457
2565
|
const fileStat = await stat(filePath);
|
|
2458
2566
|
const maxSize = 10 * 1024 * 1024;
|
|
@@ -2485,8 +2593,8 @@ var readFileTool = {
|
|
|
2485
2593
|
if (lines.length > 0 && lines[lines.length - 1] === "" && content.endsWith("\n")) {
|
|
2486
2594
|
lines.pop();
|
|
2487
2595
|
}
|
|
2488
|
-
const startLine = Math.max(1,
|
|
2489
|
-
const endLine =
|
|
2596
|
+
const startLine = Math.max(1, args.startLine ?? 1) - 1;
|
|
2597
|
+
const endLine = args.endLine ? Math.min(args.endLine, lines.length) : lines.length;
|
|
2490
2598
|
const selectedLines = lines.slice(startLine, endLine);
|
|
2491
2599
|
const lineNumWidth = String(endLine).length;
|
|
2492
2600
|
const result = selectedLines.map((line, i) => {
|
|
@@ -2518,35 +2626,33 @@ var readFileTool = {
|
|
|
2518
2626
|
// src/tool/builtins/write-file.ts
|
|
2519
2627
|
import { mkdir as mkdir4, readFile as readFile5 } from "fs/promises";
|
|
2520
2628
|
import { dirname, relative as relative3, basename } from "path";
|
|
2521
|
-
var writeFileSchema = {
|
|
2522
|
-
type: "object",
|
|
2523
|
-
properties: {
|
|
2524
|
-
path: {
|
|
2525
|
-
type: "string",
|
|
2526
|
-
description: "\u6587\u4EF6\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09"
|
|
2527
|
-
},
|
|
2528
|
-
content: {
|
|
2529
|
-
type: "string",
|
|
2530
|
-
description: "\u8981\u5199\u5165\u7684\u6587\u4EF6\u5185\u5BB9"
|
|
2531
|
-
}
|
|
2532
|
-
},
|
|
2533
|
-
required: ["path", "content"],
|
|
2534
|
-
additionalProperties: false
|
|
2535
|
-
};
|
|
2536
2629
|
var writeFileTool = {
|
|
2537
2630
|
name: "write_file",
|
|
2631
|
+
kind: "edit" /* Edit */,
|
|
2538
2632
|
description: "\u521B\u5EFA\u6216\u8986\u76D6\u6587\u4EF6\u3002\u5982\u679C\u7236\u76EE\u5F55\u4E0D\u5B58\u5728\u4F1A\u81EA\u52A8\u521B\u5EFA\u3002\u9002\u7528\u4E8E\u521B\u5EFA\u65B0\u6587\u4EF6\u6216\u5B8C\u5168\u66FF\u6362\u6587\u4EF6\u5185\u5BB9\u3002\u8BF7\u52FF\u7528\u6B64\u5DE5\u5177\u521B\u5EFA _temp_\u3001_debug_ \u7B49\u7528\u4E8E\u8BCA\u65AD/\u8C03\u8BD5\u7684\u4E34\u65F6\u6587\u4EF6\u2014\u2014\u5982\u9700\u8BCA\u65AD\u8BF7\u6539\u7528 bash \u5DE5\u5177\u5185\u8054\u811A\u672C\uFF08node -e\uFF09\u3002",
|
|
2539
|
-
parameters:
|
|
2540
|
-
|
|
2633
|
+
parameters: {
|
|
2634
|
+
type: "object",
|
|
2635
|
+
properties: {
|
|
2636
|
+
path: {
|
|
2637
|
+
type: "string",
|
|
2638
|
+
description: "\u6587\u4EF6\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09"
|
|
2639
|
+
},
|
|
2640
|
+
content: {
|
|
2641
|
+
type: "string",
|
|
2642
|
+
description: "\u8981\u5199\u5165\u7684\u6587\u4EF6\u5185\u5BB9"
|
|
2643
|
+
}
|
|
2644
|
+
},
|
|
2645
|
+
required: ["path", "content"],
|
|
2646
|
+
additionalProperties: false
|
|
2647
|
+
},
|
|
2541
2648
|
async execute(args, ctx) {
|
|
2542
|
-
|
|
2543
|
-
if (!params?.path || typeof params.path !== "string") {
|
|
2649
|
+
if (!args?.path || typeof args.path !== "string") {
|
|
2544
2650
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 path", error: "INVALID_ARGS" };
|
|
2545
2651
|
}
|
|
2546
|
-
if (
|
|
2652
|
+
if (args.content === void 0 || args.content === null) {
|
|
2547
2653
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 content", error: "INVALID_ARGS" };
|
|
2548
2654
|
}
|
|
2549
|
-
const filePath = resolvePath(
|
|
2655
|
+
const filePath = resolvePath(args.path, ctx.cwd);
|
|
2550
2656
|
try {
|
|
2551
2657
|
if (ctx.writeRoots && ctx.writeRoots.length > 0) {
|
|
2552
2658
|
const conf = await confine(ctx.writeRoots, filePath);
|
|
@@ -2562,7 +2668,7 @@ var writeFileTool = {
|
|
|
2562
2668
|
} catch {
|
|
2563
2669
|
}
|
|
2564
2670
|
await mkdir4(dirname(filePath), { recursive: true });
|
|
2565
|
-
const content = String(
|
|
2671
|
+
const content = String(args.content);
|
|
2566
2672
|
await writeFileWithEol(filePath, oldContent, content);
|
|
2567
2673
|
const diff = computeFileDiff(oldContent, content, filePath);
|
|
2568
2674
|
diff.existedBefore = existedBefore;
|
|
@@ -2592,42 +2698,40 @@ var writeFileTool = {
|
|
|
2592
2698
|
// src/tool/builtins/edit-file.ts
|
|
2593
2699
|
import { readFile as readFile6 } from "fs/promises";
|
|
2594
2700
|
import { basename as basename2 } from "path";
|
|
2595
|
-
var editFileSchema = {
|
|
2596
|
-
type: "object",
|
|
2597
|
-
properties: {
|
|
2598
|
-
path: {
|
|
2599
|
-
type: "string",
|
|
2600
|
-
description: "\u6587\u4EF6\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09"
|
|
2601
|
-
},
|
|
2602
|
-
old_text: {
|
|
2603
|
-
type: "string",
|
|
2604
|
-
description: "\u8981\u67E5\u627E\u7684\u539F\u59CB\u6587\u672C\uFF08\u7CBE\u786E\u5339\u914D\uFF09"
|
|
2605
|
-
},
|
|
2606
|
-
new_text: {
|
|
2607
|
-
type: "string",
|
|
2608
|
-
description: "\u66FF\u6362\u540E\u7684\u65B0\u6587\u672C"
|
|
2609
|
-
}
|
|
2610
|
-
},
|
|
2611
|
-
required: ["path", "old_text", "new_text"],
|
|
2612
|
-
additionalProperties: false
|
|
2613
|
-
};
|
|
2614
2701
|
var editFileTool = {
|
|
2615
2702
|
name: "edit_file",
|
|
2703
|
+
kind: "edit" /* Edit */,
|
|
2616
2704
|
description: "\u5BF9\u6587\u4EF6\u8FDB\u884C\u7CBE\u786E\u5B57\u7B26\u4E32\u66FF\u6362\u3002\u67E5\u627E\u6587\u4EF6\u4E2D\u7684 old_text \u5E76\u66FF\u6362\u4E3A new_text\u3002\u5982\u679C old_text \u51FA\u73B0\u591A\u6B21\u6216\u672A\u627E\u5230\u5219\u62A5\u9519\u3002\u9002\u7528\u4E8E\u5C0F\u8303\u56F4\u7CBE\u786E\u4FEE\u6539\u3002",
|
|
2617
|
-
parameters:
|
|
2618
|
-
|
|
2705
|
+
parameters: {
|
|
2706
|
+
type: "object",
|
|
2707
|
+
properties: {
|
|
2708
|
+
path: {
|
|
2709
|
+
type: "string",
|
|
2710
|
+
description: "\u6587\u4EF6\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09"
|
|
2711
|
+
},
|
|
2712
|
+
old_text: {
|
|
2713
|
+
type: "string",
|
|
2714
|
+
description: "\u8981\u67E5\u627E\u7684\u539F\u59CB\u6587\u672C\uFF08\u7CBE\u786E\u5339\u914D\uFF09"
|
|
2715
|
+
},
|
|
2716
|
+
new_text: {
|
|
2717
|
+
type: "string",
|
|
2718
|
+
description: "\u66FF\u6362\u540E\u7684\u65B0\u6587\u672C"
|
|
2719
|
+
}
|
|
2720
|
+
},
|
|
2721
|
+
required: ["path", "old_text", "new_text"],
|
|
2722
|
+
additionalProperties: false
|
|
2723
|
+
},
|
|
2619
2724
|
async execute(args, ctx) {
|
|
2620
|
-
|
|
2621
|
-
if (!params?.path || typeof params.path !== "string") {
|
|
2725
|
+
if (!args?.path || typeof args.path !== "string") {
|
|
2622
2726
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 path", error: "INVALID_ARGS" };
|
|
2623
2727
|
}
|
|
2624
|
-
if (typeof
|
|
2728
|
+
if (typeof args.old_text !== "string") {
|
|
2625
2729
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 old_text", error: "INVALID_ARGS" };
|
|
2626
2730
|
}
|
|
2627
|
-
if (typeof
|
|
2731
|
+
if (typeof args.new_text !== "string") {
|
|
2628
2732
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 new_text", error: "INVALID_ARGS" };
|
|
2629
2733
|
}
|
|
2630
|
-
const filePath = resolvePath(
|
|
2734
|
+
const filePath = resolvePath(args.path, ctx.cwd);
|
|
2631
2735
|
if (ctx.writeRoots && ctx.writeRoots.length > 0) {
|
|
2632
2736
|
const conf = await confine(ctx.writeRoots, filePath);
|
|
2633
2737
|
if (!conf.ok) {
|
|
@@ -2636,7 +2740,7 @@ var editFileTool = {
|
|
|
2636
2740
|
}
|
|
2637
2741
|
try {
|
|
2638
2742
|
const content = await readFile6(filePath, "utf-8");
|
|
2639
|
-
const firstIndex = content.indexOf(
|
|
2743
|
+
const firstIndex = content.indexOf(args.old_text);
|
|
2640
2744
|
if (firstIndex === -1) {
|
|
2641
2745
|
return {
|
|
2642
2746
|
success: false,
|
|
@@ -2644,7 +2748,7 @@ var editFileTool = {
|
|
|
2644
2748
|
error: "TEXT_NOT_FOUND"
|
|
2645
2749
|
};
|
|
2646
2750
|
}
|
|
2647
|
-
const secondIndex = content.indexOf(
|
|
2751
|
+
const secondIndex = content.indexOf(args.old_text, firstIndex + 1);
|
|
2648
2752
|
if (secondIndex !== -1) {
|
|
2649
2753
|
return {
|
|
2650
2754
|
success: false,
|
|
@@ -2652,14 +2756,14 @@ var editFileTool = {
|
|
|
2652
2756
|
error: "TEXT_MULTIPLE_MATCHES"
|
|
2653
2757
|
};
|
|
2654
2758
|
}
|
|
2655
|
-
const newContent = content.replace(
|
|
2759
|
+
const newContent = content.replace(args.old_text, args.new_text);
|
|
2656
2760
|
await writeFileWithEol(filePath, content, newContent);
|
|
2657
2761
|
const diff = computeFileDiff(content, newContent, filePath);
|
|
2658
2762
|
diff.existedBefore = true;
|
|
2659
2763
|
const beforeText = content.slice(0, firstIndex);
|
|
2660
2764
|
const startLine = beforeText.split("\n").length;
|
|
2661
|
-
const oldLines =
|
|
2662
|
-
const newLines =
|
|
2765
|
+
const oldLines = args.old_text.split("\n").length;
|
|
2766
|
+
const newLines = args.new_text.split("\n").length;
|
|
2663
2767
|
const diffSummary = `+${diff.additions} -${diff.deletions}`;
|
|
2664
2768
|
const summary = `\u{1F4DD} \u4FEE\u6539: ${basename2(filePath)} (+${diff.additions} -${diff.deletions})`;
|
|
2665
2769
|
return {
|
|
@@ -2685,45 +2789,43 @@ ${oldLines} \u884C \u2192 ${newLines} \u884C
|
|
|
2685
2789
|
// src/tool/builtins/multi-edit.ts
|
|
2686
2790
|
import { readFile as readFile7 } from "fs/promises";
|
|
2687
2791
|
import { basename as basename3 } from "path";
|
|
2688
|
-
var multiEditSchema = {
|
|
2689
|
-
type: "object",
|
|
2690
|
-
properties: {
|
|
2691
|
-
path: {
|
|
2692
|
-
type: "string",
|
|
2693
|
-
description: "\u6587\u4EF6\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09"
|
|
2694
|
-
},
|
|
2695
|
-
edits: {
|
|
2696
|
-
type: "array",
|
|
2697
|
-
description: "\u6709\u5E8F\u7684\u7F16\u8F91\u6B65\u9AA4\u5217\u8868\u3002\u6BCF\u4E2A\u6B65\u9AA4\u5305\u542B oldText\uFF08\u7CBE\u786E\u5339\u914D\uFF09\u3001newText\uFF08\u66FF\u6362\u5185\u5BB9\uFF09\u548C\u53EF\u9009\u7684 replaceAll\uFF08\u662F\u5426\u66FF\u6362\u6240\u6709\u5339\u914D\u9879\uFF09",
|
|
2698
|
-
items: {
|
|
2699
|
-
type: "object",
|
|
2700
|
-
properties: {
|
|
2701
|
-
oldText: { type: "string", description: "\u8981\u67E5\u627E\u7684\u539F\u59CB\u6587\u672C\uFF08\u7CBE\u786E\u5339\u914D\uFF09" },
|
|
2702
|
-
newText: { type: "string", description: "\u66FF\u6362\u540E\u7684\u65B0\u6587\u672C" },
|
|
2703
|
-
replaceAll: { type: "boolean", description: "\u662F\u5426\u66FF\u6362\u6240\u6709\u5339\u914D\u9879\uFF0C\u9ED8\u8BA4 false" }
|
|
2704
|
-
},
|
|
2705
|
-
required: ["oldText", "newText"],
|
|
2706
|
-
additionalProperties: false
|
|
2707
|
-
}
|
|
2708
|
-
}
|
|
2709
|
-
},
|
|
2710
|
-
required: ["path", "edits"],
|
|
2711
|
-
additionalProperties: false
|
|
2712
|
-
};
|
|
2713
2792
|
var multiEditTool = {
|
|
2714
2793
|
name: "multi_edit",
|
|
2794
|
+
kind: "edit" /* Edit */,
|
|
2715
2795
|
description: "\u5BF9\u6587\u4EF6\u8FDB\u884C\u539F\u5B50\u6279\u91CF\u66FF\u6362\u7F16\u8F91\u3002\u5728\u4E00\u4E2A\u8BF7\u6C42\u4E2D\u6267\u884C\u591A\u4E2A\u7CBE\u786E\u66FF\u6362\uFF0C\u4EFB\u4E00\u5931\u8D25\u5219\u5168\u90E8\u56DE\u6EDA\u3002\u652F\u6301 replaceAll \u53C2\u6570\u505A\u5168\u5C40\u66FF\u6362\u3002\u9002\u7528\u4E8E\u9700\u8981\u540C\u65F6\u4FEE\u6539\u6587\u4EF6\u591A\u5904\u7684\u573A\u666F\u3002",
|
|
2716
|
-
parameters:
|
|
2717
|
-
|
|
2796
|
+
parameters: {
|
|
2797
|
+
type: "object",
|
|
2798
|
+
properties: {
|
|
2799
|
+
path: {
|
|
2800
|
+
type: "string",
|
|
2801
|
+
description: "\u6587\u4EF6\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09"
|
|
2802
|
+
},
|
|
2803
|
+
edits: {
|
|
2804
|
+
type: "array",
|
|
2805
|
+
description: "\u6709\u5E8F\u7684\u7F16\u8F91\u6B65\u9AA4\u5217\u8868\u3002\u6BCF\u4E2A\u6B65\u9AA4\u5305\u542B oldText\uFF08\u7CBE\u786E\u5339\u914D\uFF09\u3001newText\uFF08\u66FF\u6362\u5185\u5BB9\uFF09\u548C\u53EF\u9009\u7684 replaceAll\uFF08\u662F\u5426\u66FF\u6362\u6240\u6709\u5339\u914D\u9879\uFF09",
|
|
2806
|
+
items: {
|
|
2807
|
+
type: "object",
|
|
2808
|
+
properties: {
|
|
2809
|
+
oldText: { type: "string", description: "\u8981\u67E5\u627E\u7684\u539F\u59CB\u6587\u672C\uFF08\u7CBE\u786E\u5339\u914D\uFF09" },
|
|
2810
|
+
newText: { type: "string", description: "\u66FF\u6362\u540E\u7684\u65B0\u6587\u672C" },
|
|
2811
|
+
replaceAll: { type: "boolean", description: "\u662F\u5426\u66FF\u6362\u6240\u6709\u5339\u914D\u9879\uFF0C\u9ED8\u8BA4 false" }
|
|
2812
|
+
},
|
|
2813
|
+
required: ["oldText", "newText"],
|
|
2814
|
+
additionalProperties: false
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
},
|
|
2818
|
+
required: ["path", "edits"],
|
|
2819
|
+
additionalProperties: false
|
|
2820
|
+
},
|
|
2718
2821
|
async execute(args, ctx) {
|
|
2719
|
-
|
|
2720
|
-
if (!params?.path || typeof params.path !== "string") {
|
|
2822
|
+
if (!args?.path || typeof args.path !== "string") {
|
|
2721
2823
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 path", error: "INVALID_ARGS" };
|
|
2722
2824
|
}
|
|
2723
|
-
if (!Array.isArray(
|
|
2825
|
+
if (!Array.isArray(args.edits) || args.edits.length === 0) {
|
|
2724
2826
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 edits\uFF08\u975E\u7A7A\u6570\u7EC4\uFF09", error: "INVALID_ARGS" };
|
|
2725
2827
|
}
|
|
2726
|
-
const filePath = resolvePath(
|
|
2828
|
+
const filePath = resolvePath(args.path, ctx.cwd);
|
|
2727
2829
|
if (ctx.writeRoots && ctx.writeRoots.length > 0) {
|
|
2728
2830
|
const conf = await confine(ctx.writeRoots, filePath);
|
|
2729
2831
|
if (!conf.ok) {
|
|
@@ -2733,8 +2835,8 @@ var multiEditTool = {
|
|
|
2733
2835
|
try {
|
|
2734
2836
|
const originalContent = await readFile7(filePath, "utf-8");
|
|
2735
2837
|
let currentContent = originalContent;
|
|
2736
|
-
for (let idx = 0; idx <
|
|
2737
|
-
const step =
|
|
2838
|
+
for (let idx = 0; idx < args.edits.length; idx++) {
|
|
2839
|
+
const step = args.edits[idx];
|
|
2738
2840
|
if (typeof step.oldText !== "string") {
|
|
2739
2841
|
return {
|
|
2740
2842
|
success: false,
|
|
@@ -2782,9 +2884,9 @@ var multiEditTool = {
|
|
|
2782
2884
|
return {
|
|
2783
2885
|
success: true,
|
|
2784
2886
|
data: `\u6587\u4EF6\u5DF2\u7F16\u8F91\uFF1A${filePath}
|
|
2785
|
-
\u5171\u6267\u884C ${
|
|
2887
|
+
\u5171\u6267\u884C ${args.edits.length} \u6B65\u66FF\u6362
|
|
2786
2888
|
\u53D8\u66F4\uFF1A+${diff.additions} -${diff.deletions}`,
|
|
2787
|
-
summary: `\u{1F4DD} \u4FEE\u6539: ${basename3(filePath)} (${
|
|
2889
|
+
summary: `\u{1F4DD} \u4FEE\u6539: ${basename3(filePath)} (${args.edits.length} \u6B65, +${diff.additions} -${diff.deletions})`,
|
|
2788
2890
|
diff
|
|
2789
2891
|
};
|
|
2790
2892
|
} catch (err) {
|
|
@@ -2801,29 +2903,6 @@ var multiEditTool = {
|
|
|
2801
2903
|
// src/tool/builtins/delete-range.ts
|
|
2802
2904
|
import { readFile as readFile8 } from "fs/promises";
|
|
2803
2905
|
import { basename as basename4 } from "path";
|
|
2804
|
-
var deleteRangeSchema = {
|
|
2805
|
-
type: "object",
|
|
2806
|
-
properties: {
|
|
2807
|
-
path: {
|
|
2808
|
-
type: "string",
|
|
2809
|
-
description: "\u6587\u4EF6\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09"
|
|
2810
|
-
},
|
|
2811
|
-
startAnchor: {
|
|
2812
|
-
type: "string",
|
|
2813
|
-
description: "\u5220\u9664\u8303\u56F4\u7684\u8D77\u59CB\u6807\u8BB0\u884C\u5185\u5BB9\uFF08\u5FC5\u987B\u5728\u6587\u4EF6\u4E2D\u552F\u4E00\uFF0C\u7CBE\u786E\u5339\u914D\u6574\u884C\uFF09"
|
|
2814
|
-
},
|
|
2815
|
-
endAnchor: {
|
|
2816
|
-
type: "string",
|
|
2817
|
-
description: "\u5220\u9664\u8303\u56F4\u7684\u7ED3\u675F\u6807\u8BB0\u884C\u5185\u5BB9\uFF08\u5FC5\u987B\u5728\u6587\u4EF6\u4E2D\u552F\u4E00\uFF0C\u7CBE\u786E\u5339\u914D\u6574\u884C\uFF0C\u987B\u5728 start_anchor \u4E4B\u540E\uFF09"
|
|
2818
|
-
},
|
|
2819
|
-
inclusive: {
|
|
2820
|
-
type: "boolean",
|
|
2821
|
-
description: "\u662F\u5426\u5305\u542B\u951A\u70B9\u884C\u672C\u8EAB\uFF0C\u9ED8\u8BA4 false\uFF08\u53EA\u5220\u9664\u4E24\u884C\u4E4B\u95F4\u7684\u5185\u5BB9\uFF09"
|
|
2822
|
-
}
|
|
2823
|
-
},
|
|
2824
|
-
required: ["path", "startAnchor", "endAnchor"],
|
|
2825
|
-
additionalProperties: false
|
|
2826
|
-
};
|
|
2827
2906
|
function findUniqueLine(lines, anchor, label) {
|
|
2828
2907
|
const matches = [];
|
|
2829
2908
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -2841,22 +2920,43 @@ function findUniqueLine(lines, anchor, label) {
|
|
|
2841
2920
|
}
|
|
2842
2921
|
var deleteRangeTool = {
|
|
2843
2922
|
name: "delete_range",
|
|
2923
|
+
kind: "edit" /* Edit */,
|
|
2844
2924
|
description: "\u5220\u9664\u6587\u4EF6\u4E2D\u4E24\u4E2A\u951A\u70B9\u884C\u4E4B\u95F4\u7684\u5185\u5BB9\u3002\u901A\u8FC7\u4E24\u4E2A\u552F\u4E00\u7684\u884C\u5185\u5BB9\u7CBE\u786E\u5B9A\u4F4D\u8303\u56F4\u3002\u9002\u7528\u4E8E\u5220\u9664\u65B9\u6CD5\u3001\u4EE3\u7801\u5757\u3001\u914D\u7F6E\u6BB5\u7B49\u3002",
|
|
2845
|
-
parameters:
|
|
2846
|
-
|
|
2925
|
+
parameters: {
|
|
2926
|
+
type: "object",
|
|
2927
|
+
properties: {
|
|
2928
|
+
path: {
|
|
2929
|
+
type: "string",
|
|
2930
|
+
description: "\u6587\u4EF6\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09"
|
|
2931
|
+
},
|
|
2932
|
+
startAnchor: {
|
|
2933
|
+
type: "string",
|
|
2934
|
+
description: "\u5220\u9664\u8303\u56F4\u7684\u8D77\u59CB\u6807\u8BB0\u884C\u5185\u5BB9\uFF08\u5FC5\u987B\u5728\u6587\u4EF6\u4E2D\u552F\u4E00\uFF0C\u7CBE\u786E\u5339\u914D\u6574\u884C\uFF09"
|
|
2935
|
+
},
|
|
2936
|
+
endAnchor: {
|
|
2937
|
+
type: "string",
|
|
2938
|
+
description: "\u5220\u9664\u8303\u56F4\u7684\u7ED3\u675F\u6807\u8BB0\u884C\u5185\u5BB9\uFF08\u5FC5\u987B\u5728\u6587\u4EF6\u4E2D\u552F\u4E00\uFF0C\u7CBE\u786E\u5339\u914D\u6574\u884C\uFF0C\u987B\u5728 start_anchor \u4E4B\u540E\uFF09"
|
|
2939
|
+
},
|
|
2940
|
+
inclusive: {
|
|
2941
|
+
type: "boolean",
|
|
2942
|
+
description: "\u662F\u5426\u5305\u542B\u951A\u70B9\u884C\u672C\u8EAB\uFF0C\u9ED8\u8BA4 false\uFF08\u53EA\u5220\u9664\u4E24\u884C\u4E4B\u95F4\u7684\u5185\u5BB9\uFF09"
|
|
2943
|
+
}
|
|
2944
|
+
},
|
|
2945
|
+
required: ["path", "startAnchor", "endAnchor"],
|
|
2946
|
+
additionalProperties: false
|
|
2947
|
+
},
|
|
2847
2948
|
async execute(args, ctx) {
|
|
2848
|
-
|
|
2849
|
-
if (!params?.path || typeof params.path !== "string") {
|
|
2949
|
+
if (!args?.path || typeof args.path !== "string") {
|
|
2850
2950
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 path", error: "INVALID_ARGS" };
|
|
2851
2951
|
}
|
|
2852
|
-
if (typeof
|
|
2952
|
+
if (typeof args.startAnchor !== "string") {
|
|
2853
2953
|
return { success: false, data: "\u7F3A\u5C11\u6709\u6548\u53C2\u6570 startAnchor", error: "INVALID_ARGS" };
|
|
2854
2954
|
}
|
|
2855
|
-
if (typeof
|
|
2955
|
+
if (typeof args.endAnchor !== "string") {
|
|
2856
2956
|
return { success: false, data: "\u7F3A\u5C11\u6709\u6548\u53C2\u6570 endAnchor", error: "INVALID_ARGS" };
|
|
2857
2957
|
}
|
|
2858
|
-
const filePath = resolvePath(
|
|
2859
|
-
const inclusive =
|
|
2958
|
+
const filePath = resolvePath(args.path, ctx.cwd);
|
|
2959
|
+
const inclusive = args.inclusive ?? false;
|
|
2860
2960
|
if (ctx.writeRoots && ctx.writeRoots.length > 0) {
|
|
2861
2961
|
const conf = await confine(ctx.writeRoots, filePath);
|
|
2862
2962
|
if (!conf.ok) {
|
|
@@ -2866,11 +2966,11 @@ var deleteRangeTool = {
|
|
|
2866
2966
|
try {
|
|
2867
2967
|
const content = await readFile8(filePath, "utf-8");
|
|
2868
2968
|
const lines = content.split("\n");
|
|
2869
|
-
const startResult = findUniqueLine(lines,
|
|
2969
|
+
const startResult = findUniqueLine(lines, args.startAnchor, "start_anchor");
|
|
2870
2970
|
if ("error" in startResult) {
|
|
2871
2971
|
return { success: false, data: startResult.error, error: "ANCHOR_NOT_FOUND" };
|
|
2872
2972
|
}
|
|
2873
|
-
const endResult = findUniqueLine(lines,
|
|
2973
|
+
const endResult = findUniqueLine(lines, args.endAnchor, "end_anchor");
|
|
2874
2974
|
if ("error" in endResult) {
|
|
2875
2975
|
return { success: false, data: endResult.error, error: "ANCHOR_NOT_FOUND" };
|
|
2876
2976
|
}
|
|
@@ -2921,36 +3021,33 @@ var deleteRangeTool = {
|
|
|
2921
3021
|
// src/tool/builtins/bash.ts
|
|
2922
3022
|
import process3 from "process";
|
|
2923
3023
|
var isWindows2 = process3.platform === "win32";
|
|
2924
|
-
var bashSchema = {
|
|
2925
|
-
type: "object",
|
|
2926
|
-
properties: {
|
|
2927
|
-
command: {
|
|
2928
|
-
type: "string",
|
|
2929
|
-
description: "\u8981\u6267\u884C\u7684 shell \u547D\u4EE4"
|
|
2930
|
-
},
|
|
2931
|
-
timeout: {
|
|
2932
|
-
type: "number",
|
|
2933
|
-
description: "\u6267\u884C\u8D85\u65F6\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09\uFF0C\u9ED8\u8BA4 30000"
|
|
2934
|
-
}
|
|
2935
|
-
},
|
|
2936
|
-
required: ["command"],
|
|
2937
|
-
additionalProperties: false
|
|
2938
|
-
};
|
|
2939
3024
|
var bashTool = {
|
|
2940
3025
|
name: "bash",
|
|
3026
|
+
kind: "other" /* Other */,
|
|
2941
3027
|
description: "\u5728 shell \u4E2D\u6267\u884C\u547D\u4EE4\u3002\u8FD4\u56DE\u6807\u51C6\u8F93\u51FA\u3001\u6807\u51C6\u9519\u8BEF\u548C\u9000\u51FA\u7801\u3002\u652F\u6301\u8D85\u65F6\u63A7\u5236\u548C\u4FE1\u53F7\u4E2D\u6B62\u3002\u9002\u7528\u4E8E\u8FD0\u884C\u6784\u5EFA\u3001\u6D4B\u8BD5\u3001Git \u64CD\u4F5C\u7B49\u547D\u4EE4\u3002",
|
|
2942
|
-
parameters:
|
|
2943
|
-
|
|
2944
|
-
|
|
3028
|
+
parameters: {
|
|
3029
|
+
type: "object",
|
|
3030
|
+
properties: {
|
|
3031
|
+
command: {
|
|
3032
|
+
type: "string",
|
|
3033
|
+
description: "\u8981\u6267\u884C\u7684 shell \u547D\u4EE4"
|
|
3034
|
+
},
|
|
3035
|
+
timeout: {
|
|
3036
|
+
type: "number",
|
|
3037
|
+
description: "\u6267\u884C\u8D85\u65F6\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09\uFF0C\u9ED8\u8BA4 30000"
|
|
3038
|
+
}
|
|
3039
|
+
},
|
|
3040
|
+
required: ["command"],
|
|
3041
|
+
additionalProperties: false
|
|
3042
|
+
},
|
|
2945
3043
|
async execute(args, ctx) {
|
|
2946
|
-
|
|
2947
|
-
if (!params?.command || typeof params.command !== "string") {
|
|
3044
|
+
if (!args?.command || typeof args.command !== "string") {
|
|
2948
3045
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 command", error: "INVALID_ARGS" };
|
|
2949
3046
|
}
|
|
2950
|
-
const timeout =
|
|
3047
|
+
const timeout = args.timeout ?? ctx.timeout ?? getDefaultTimeout();
|
|
2951
3048
|
try {
|
|
2952
3049
|
const shellCommand = isWindows2 ? "cmd" : "sh";
|
|
2953
|
-
const shellArgs = isWindows2 ? ["/c",
|
|
3050
|
+
const shellArgs = isWindows2 ? ["/c", args.command] : ["-c", args.command];
|
|
2954
3051
|
const result = await execCommand(
|
|
2955
3052
|
shellCommand,
|
|
2956
3053
|
shellArgs,
|
|
@@ -2958,7 +3055,6 @@ var bashTool = {
|
|
|
2958
3055
|
timeout,
|
|
2959
3056
|
ctx.signal,
|
|
2960
3057
|
true
|
|
2961
|
-
// isShellCommand — 已指定 shell 程序,不需要二次包装
|
|
2962
3058
|
);
|
|
2963
3059
|
const parts = [];
|
|
2964
3060
|
if (result.stdout) {
|
|
@@ -2970,7 +3066,7 @@ ${truncateOutput(result.stderr)}`);
|
|
|
2970
3066
|
}
|
|
2971
3067
|
const success = result.exitCode === 0;
|
|
2972
3068
|
const output = parts.length > 0 ? parts.join("\n") : "(\u65E0\u8F93\u51FA)";
|
|
2973
|
-
const cmdPreview =
|
|
3069
|
+
const cmdPreview = args.command.length > 60 ? args.command.slice(0, 57) + "..." : args.command;
|
|
2974
3070
|
const summary = `\u{1F527} $ ${cmdPreview}\uFF08exit ${result.exitCode ?? "\u672A\u77E5"}\uFF09`;
|
|
2975
3071
|
return {
|
|
2976
3072
|
success,
|
|
@@ -2993,21 +3089,6 @@ ${truncateOutput(result.stderr)}`);
|
|
|
2993
3089
|
// src/tool/builtins/glob.ts
|
|
2994
3090
|
import { readdir as readdir2, stat as stat2 } from "fs/promises";
|
|
2995
3091
|
import { join as join4, relative as relative4, isAbsolute as isAbsolute2 } from "path";
|
|
2996
|
-
var globSchema = {
|
|
2997
|
-
type: "object",
|
|
2998
|
-
properties: {
|
|
2999
|
-
pattern: {
|
|
3000
|
-
type: "string",
|
|
3001
|
-
description: "\u641C\u7D22\u6A21\u5F0F\uFF08\u652F\u6301 * \u548C ** \u901A\u914D\u7B26\uFF0C\u5982 **/*.ts\u3001src/**/*.test.ts\uFF09"
|
|
3002
|
-
},
|
|
3003
|
-
directory: {
|
|
3004
|
-
type: "string",
|
|
3005
|
-
description: "\u641C\u7D22\u7684\u8D77\u59CB\u76EE\u5F55\uFF0C\u9ED8\u8BA4\u4E3A\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55"
|
|
3006
|
-
}
|
|
3007
|
-
},
|
|
3008
|
-
required: ["pattern"],
|
|
3009
|
-
additionalProperties: false
|
|
3010
|
-
};
|
|
3011
3092
|
function globToRegex(pattern) {
|
|
3012
3093
|
let regexStr = pattern;
|
|
3013
3094
|
regexStr = regexStr.replace(/\*\*\//g, "<<GLOBSTAR_SLASH>>");
|
|
@@ -3044,16 +3125,29 @@ async function walkDir(dir, baseDir) {
|
|
|
3044
3125
|
}
|
|
3045
3126
|
var globTool = {
|
|
3046
3127
|
name: "glob",
|
|
3128
|
+
kind: "read" /* Read */,
|
|
3047
3129
|
description: "\u6309\u6A21\u5F0F\u641C\u7D22\u6587\u4EF6\u8DEF\u5F84\u3002\u652F\u6301 *\uFF08\u5339\u914D\u6587\u4EF6\u540D\u90E8\u5206\uFF09\u548C **\uFF08\u5339\u914D\u591A\u5C42\u76EE\u5F55\uFF09\u901A\u914D\u7B26\u3002\u81EA\u52A8\u8DF3\u8FC7 node_modules \u548C .git \u76EE\u5F55\u3002",
|
|
3048
|
-
parameters:
|
|
3049
|
-
|
|
3130
|
+
parameters: {
|
|
3131
|
+
type: "object",
|
|
3132
|
+
properties: {
|
|
3133
|
+
pattern: {
|
|
3134
|
+
type: "string",
|
|
3135
|
+
description: "\u641C\u7D22\u6A21\u5F0F\uFF08\u652F\u6301 * \u548C ** \u901A\u914D\u7B26\uFF0C\u5982 **/*.ts\u3001src/**/*.test.ts\uFF09"
|
|
3136
|
+
},
|
|
3137
|
+
directory: {
|
|
3138
|
+
type: "string",
|
|
3139
|
+
description: "\u641C\u7D22\u7684\u8D77\u59CB\u76EE\u5F55\uFF0C\u9ED8\u8BA4\u4E3A\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55"
|
|
3140
|
+
}
|
|
3141
|
+
},
|
|
3142
|
+
required: ["pattern"],
|
|
3143
|
+
additionalProperties: false
|
|
3144
|
+
},
|
|
3050
3145
|
async execute(args, ctx) {
|
|
3051
|
-
|
|
3052
|
-
if (!params?.pattern || typeof params.pattern !== "string") {
|
|
3146
|
+
if (!args?.pattern || typeof args.pattern !== "string") {
|
|
3053
3147
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 pattern", error: "INVALID_ARGS" };
|
|
3054
3148
|
}
|
|
3055
|
-
const searchDir =
|
|
3056
|
-
const regex = globToRegex(
|
|
3149
|
+
const searchDir = args.directory ? isAbsolute2(args.directory) ? args.directory : join4(ctx.cwd, args.directory) : ctx.cwd;
|
|
3150
|
+
const regex = globToRegex(args.pattern);
|
|
3057
3151
|
try {
|
|
3058
3152
|
const dirStat = await stat2(searchDir);
|
|
3059
3153
|
if (!dirStat.isDirectory()) {
|
|
@@ -3064,8 +3158,8 @@ var globTool = {
|
|
|
3064
3158
|
if (matched.length === 0) {
|
|
3065
3159
|
return {
|
|
3066
3160
|
success: true,
|
|
3067
|
-
data: `\u672A\u627E\u5230\u5339\u914D "${
|
|
3068
|
-
summary: `${
|
|
3161
|
+
data: `\u672A\u627E\u5230\u5339\u914D "${args.pattern}" \u7684\u6587\u4EF6`,
|
|
3162
|
+
summary: `${args.pattern} \u2192 0 \u4E2A\u6587\u4EF6`
|
|
3069
3163
|
};
|
|
3070
3164
|
}
|
|
3071
3165
|
const limit = 200;
|
|
@@ -3077,7 +3171,7 @@ var globTool = {
|
|
|
3077
3171
|
return {
|
|
3078
3172
|
success: true,
|
|
3079
3173
|
data: truncateOutput(output + suffix),
|
|
3080
|
-
summary: `${
|
|
3174
|
+
summary: `${args.pattern} \u2192 ${matched.length} \u4E2A\u6587\u4EF6`
|
|
3081
3175
|
};
|
|
3082
3176
|
} catch (err) {
|
|
3083
3177
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -3093,33 +3187,6 @@ var globTool = {
|
|
|
3093
3187
|
// src/tool/builtins/grep.ts
|
|
3094
3188
|
import { readdir as readdir3, readFile as readFile9, stat as stat3 } from "fs/promises";
|
|
3095
3189
|
import { join as join5, relative as relative5, isAbsolute as isAbsolute3 } from "path";
|
|
3096
|
-
var grepSchema = {
|
|
3097
|
-
type: "object",
|
|
3098
|
-
properties: {
|
|
3099
|
-
pattern: {
|
|
3100
|
-
type: "string",
|
|
3101
|
-
description: "\u6B63\u5219\u8868\u8FBE\u5F0F\u641C\u7D22\u6A21\u5F0F"
|
|
3102
|
-
},
|
|
3103
|
-
directory: {
|
|
3104
|
-
type: "string",
|
|
3105
|
-
description: "\u641C\u7D22\u7684\u76EE\u5F55\u8DEF\u5F84\uFF0C\u9ED8\u8BA4\u4E3A\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55"
|
|
3106
|
-
},
|
|
3107
|
-
include: {
|
|
3108
|
-
type: "string",
|
|
3109
|
-
description: "\u6587\u4EF6\u6269\u5C55\u540D\u8FC7\u6EE4\uFF08\u5982 ts\u3001json\uFF09\uFF0C\u4E0D\u542B\u70B9\u53F7"
|
|
3110
|
-
},
|
|
3111
|
-
case_sensitive: {
|
|
3112
|
-
type: "boolean",
|
|
3113
|
-
description: "\u662F\u5426\u5927\u5C0F\u5199\u654F\u611F\uFF0C\u9ED8\u8BA4 false"
|
|
3114
|
-
},
|
|
3115
|
-
max_files: {
|
|
3116
|
-
type: "number",
|
|
3117
|
-
description: "\u6700\u5927\u641C\u7D22\u6587\u4EF6\u6570\uFF0C\u9ED8\u8BA4 200"
|
|
3118
|
-
}
|
|
3119
|
-
},
|
|
3120
|
-
required: ["pattern"],
|
|
3121
|
-
additionalProperties: false
|
|
3122
|
-
};
|
|
3123
3190
|
async function collectFiles(dir, baseDir, extension, maxFiles = 200) {
|
|
3124
3191
|
const results = [];
|
|
3125
3192
|
let entries;
|
|
@@ -3147,24 +3214,49 @@ async function collectFiles(dir, baseDir, extension, maxFiles = 200) {
|
|
|
3147
3214
|
}
|
|
3148
3215
|
var grepTool = {
|
|
3149
3216
|
name: "grep",
|
|
3217
|
+
kind: "read" /* Read */,
|
|
3150
3218
|
description: "\u5728\u6587\u4EF6\u5185\u5BB9\u4E2D\u641C\u7D22\u6B63\u5219\u8868\u8FBE\u5F0F\u3002\u8FD4\u56DE\u5339\u914D\u884C\u7684\u6587\u4EF6\u8DEF\u5F84\u3001\u884C\u53F7\u548C\u5185\u5BB9\u3002\u652F\u6301\u5927\u5C0F\u5199\u654F\u611F\u3001\u6587\u4EF6\u6269\u5C55\u540D\u8FC7\u6EE4\u3002",
|
|
3151
|
-
parameters:
|
|
3152
|
-
|
|
3219
|
+
parameters: {
|
|
3220
|
+
type: "object",
|
|
3221
|
+
properties: {
|
|
3222
|
+
pattern: {
|
|
3223
|
+
type: "string",
|
|
3224
|
+
description: "\u6B63\u5219\u8868\u8FBE\u5F0F\u641C\u7D22\u6A21\u5F0F"
|
|
3225
|
+
},
|
|
3226
|
+
directory: {
|
|
3227
|
+
type: "string",
|
|
3228
|
+
description: "\u641C\u7D22\u7684\u76EE\u5F55\u8DEF\u5F84\uFF0C\u9ED8\u8BA4\u4E3A\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55"
|
|
3229
|
+
},
|
|
3230
|
+
include: {
|
|
3231
|
+
type: "string",
|
|
3232
|
+
description: "\u6587\u4EF6\u6269\u5C55\u540D\u8FC7\u6EE4\uFF08\u5982 ts\u3001json\uFF09\uFF0C\u4E0D\u542B\u70B9\u53F7"
|
|
3233
|
+
},
|
|
3234
|
+
case_sensitive: {
|
|
3235
|
+
type: "boolean",
|
|
3236
|
+
description: "\u662F\u5426\u5927\u5C0F\u5199\u654F\u611F\uFF0C\u9ED8\u8BA4 false"
|
|
3237
|
+
},
|
|
3238
|
+
max_files: {
|
|
3239
|
+
type: "number",
|
|
3240
|
+
description: "\u6700\u5927\u641C\u7D22\u6587\u4EF6\u6570\uFF0C\u9ED8\u8BA4 200"
|
|
3241
|
+
}
|
|
3242
|
+
},
|
|
3243
|
+
required: ["pattern"],
|
|
3244
|
+
additionalProperties: false
|
|
3245
|
+
},
|
|
3153
3246
|
async execute(args, ctx) {
|
|
3154
|
-
|
|
3155
|
-
if (!params?.pattern || typeof params.pattern !== "string") {
|
|
3247
|
+
if (!args?.pattern || typeof args.pattern !== "string") {
|
|
3156
3248
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 pattern", error: "INVALID_ARGS" };
|
|
3157
3249
|
}
|
|
3158
|
-
const searchDir =
|
|
3159
|
-
const maxFiles =
|
|
3250
|
+
const searchDir = args.directory ? isAbsolute3(args.directory) ? args.directory : join5(ctx.cwd, args.directory) : ctx.cwd;
|
|
3251
|
+
const maxFiles = args.max_files ?? 200;
|
|
3160
3252
|
try {
|
|
3161
|
-
const flags =
|
|
3162
|
-
const regex = new RegExp(
|
|
3253
|
+
const flags = args.case_sensitive ? "g" : "gi";
|
|
3254
|
+
const regex = new RegExp(args.pattern, flags);
|
|
3163
3255
|
const dirStat = await stat3(searchDir);
|
|
3164
3256
|
if (!dirStat.isDirectory()) {
|
|
3165
3257
|
return { success: false, data: `\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${searchDir}`, error: "NOT_DIRECTORY" };
|
|
3166
3258
|
}
|
|
3167
|
-
const files = await collectFiles(searchDir, searchDir,
|
|
3259
|
+
const files = await collectFiles(searchDir, searchDir, args.include, maxFiles);
|
|
3168
3260
|
const matches = [];
|
|
3169
3261
|
for (const filePath of files) {
|
|
3170
3262
|
try {
|
|
@@ -3190,13 +3282,13 @@ var grepTool = {
|
|
|
3190
3282
|
if (matches.length === 0) {
|
|
3191
3283
|
return {
|
|
3192
3284
|
success: true,
|
|
3193
|
-
data: `\u672A\u627E\u5230\u5339\u914D "${
|
|
3194
|
-
summary: `\u{1F50D} "${
|
|
3285
|
+
data: `\u672A\u627E\u5230\u5339\u914D "${args.pattern}" \u7684\u5185\u5BB9`,
|
|
3286
|
+
summary: `\u{1F50D} "${args.pattern}" \u2192 0 \u6761\u547D\u4E2D`
|
|
3195
3287
|
};
|
|
3196
3288
|
}
|
|
3197
3289
|
const output = matches.map((m) => `${m.file}:${m.line}: ${m.content}`).join("\n");
|
|
3198
3290
|
const fileSet = new Set(matches.map((m) => m.file));
|
|
3199
|
-
const summary = `\u{1F50D} "${
|
|
3291
|
+
const summary = `\u{1F50D} "${args.pattern}" \u2192 ${matches.length} \u6761\u547D\u4E2D / ${fileSet.size} \u4E2A\u6587\u4EF6`;
|
|
3200
3292
|
return {
|
|
3201
3293
|
success: true,
|
|
3202
3294
|
data: truncateOutput(output),
|
|
@@ -3216,30 +3308,28 @@ var grepTool = {
|
|
|
3216
3308
|
// src/tool/builtins/ls.ts
|
|
3217
3309
|
import { readdir as readdir4, stat as stat4 } from "fs/promises";
|
|
3218
3310
|
import { join as join6, relative as relative6 } from "path";
|
|
3219
|
-
var lsSchema = {
|
|
3220
|
-
type: "object",
|
|
3221
|
-
properties: {
|
|
3222
|
-
path: {
|
|
3223
|
-
type: "string",
|
|
3224
|
-
description: "\u76EE\u5F55\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09\uFF0C\u9ED8\u8BA4\u4E3A\u5F53\u524D\u76EE\u5F55"
|
|
3225
|
-
},
|
|
3226
|
-
all: {
|
|
3227
|
-
type: "boolean",
|
|
3228
|
-
description: "\u662F\u5426\u663E\u793A\u9690\u85CF\u6587\u4EF6\uFF08\u4EE5 . \u5F00\u5934\u7684\u6587\u4EF6\uFF09\uFF0C\u9ED8\u8BA4 false"
|
|
3229
|
-
}
|
|
3230
|
-
},
|
|
3231
|
-
required: [],
|
|
3232
|
-
additionalProperties: false
|
|
3233
|
-
};
|
|
3234
3311
|
var lsTool = {
|
|
3235
3312
|
name: "ls",
|
|
3313
|
+
kind: "read" /* Read */,
|
|
3236
3314
|
description: "\u5217\u51FA\u76EE\u5F55\u5185\u5BB9\u3002\u663E\u793A\u6761\u76EE\u7C7B\u578B\uFF08\u6587\u4EF6/\u76EE\u5F55/\u94FE\u63A5\uFF09\u548C\u5927\u5C0F\u3002\u53EF\u9009\u62E9\u662F\u5426\u663E\u793A\u9690\u85CF\u6587\u4EF6\u3002",
|
|
3237
|
-
parameters:
|
|
3238
|
-
|
|
3315
|
+
parameters: {
|
|
3316
|
+
type: "object",
|
|
3317
|
+
properties: {
|
|
3318
|
+
path: {
|
|
3319
|
+
type: "string",
|
|
3320
|
+
description: "\u76EE\u5F55\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09\uFF0C\u9ED8\u8BA4\u4E3A\u5F53\u524D\u76EE\u5F55"
|
|
3321
|
+
},
|
|
3322
|
+
all: {
|
|
3323
|
+
type: "boolean",
|
|
3324
|
+
description: "\u662F\u5426\u663E\u793A\u9690\u85CF\u6587\u4EF6\uFF08\u4EE5 . \u5F00\u5934\u7684\u6587\u4EF6\uFF09\uFF0C\u9ED8\u8BA4 false"
|
|
3325
|
+
}
|
|
3326
|
+
},
|
|
3327
|
+
required: [],
|
|
3328
|
+
additionalProperties: false
|
|
3329
|
+
},
|
|
3239
3330
|
async execute(args, ctx) {
|
|
3240
|
-
const
|
|
3241
|
-
const
|
|
3242
|
-
const showAll = params.all ?? false;
|
|
3331
|
+
const dirPath = args.path ? resolvePath(args.path, ctx.cwd) : ctx.cwd;
|
|
3332
|
+
const showAll = args.all ?? false;
|
|
3243
3333
|
try {
|
|
3244
3334
|
const entries = await readdir4(dirPath, { withFileTypes: true });
|
|
3245
3335
|
const lines = [];
|
|
@@ -3292,58 +3382,56 @@ ${lines.join("\n")}`),
|
|
|
3292
3382
|
};
|
|
3293
3383
|
|
|
3294
3384
|
// src/tool/builtins/fetch.ts
|
|
3295
|
-
var fetchSchema = {
|
|
3296
|
-
type: "object",
|
|
3297
|
-
properties: {
|
|
3298
|
-
url: {
|
|
3299
|
-
type: "string",
|
|
3300
|
-
description: "\u8BF7\u6C42\u7684 URL"
|
|
3301
|
-
},
|
|
3302
|
-
method: {
|
|
3303
|
-
type: "string",
|
|
3304
|
-
description: "HTTP \u65B9\u6CD5\uFF08GET\u3001POST\u3001PUT\u3001DELETE \u7B49\uFF09\uFF0C\u9ED8\u8BA4 GET"
|
|
3305
|
-
},
|
|
3306
|
-
headers: {
|
|
3307
|
-
type: "object",
|
|
3308
|
-
description: "\u8BF7\u6C42\u5934\u952E\u503C\u5BF9",
|
|
3309
|
-
additionalProperties: { type: "string" }
|
|
3310
|
-
},
|
|
3311
|
-
body: {
|
|
3312
|
-
type: "string",
|
|
3313
|
-
description: "\u8BF7\u6C42\u4F53\u5185\u5BB9\uFF08POST/PUT \u65F6\u4F7F\u7528\uFF09"
|
|
3314
|
-
},
|
|
3315
|
-
max_length: {
|
|
3316
|
-
type: "number",
|
|
3317
|
-
description: "\u54CD\u5E94\u5185\u5BB9\u6700\u5927\u957F\u5EA6\uFF08\u5B57\u7B26\uFF09\uFF0C\u9ED8\u8BA4 50000"
|
|
3318
|
-
}
|
|
3319
|
-
},
|
|
3320
|
-
required: ["url"],
|
|
3321
|
-
additionalProperties: false
|
|
3322
|
-
};
|
|
3323
3385
|
var fetchTool = {
|
|
3324
3386
|
name: "fetch",
|
|
3387
|
+
kind: "read" /* Read */,
|
|
3325
3388
|
description: "\u53D1\u8D77 HTTP \u8BF7\u6C42\u5E76\u8FD4\u56DE\u54CD\u5E94\u5185\u5BB9\u3002\u652F\u6301\u81EA\u5B9A\u4E49\u65B9\u6CD5\u548C\u8BF7\u6C42\u5934\u3002\u9002\u7528\u4E8E\u83B7\u53D6\u7F51\u9875\u5185\u5BB9\u3001API \u8C03\u7528\u7B49\u573A\u666F\u3002",
|
|
3326
|
-
parameters:
|
|
3327
|
-
|
|
3389
|
+
parameters: {
|
|
3390
|
+
type: "object",
|
|
3391
|
+
properties: {
|
|
3392
|
+
url: {
|
|
3393
|
+
type: "string",
|
|
3394
|
+
description: "\u8BF7\u6C42\u7684 URL"
|
|
3395
|
+
},
|
|
3396
|
+
method: {
|
|
3397
|
+
type: "string",
|
|
3398
|
+
description: "HTTP \u65B9\u6CD5\uFF08GET\u3001POST\u3001PUT\u3001DELETE \u7B49\uFF09\uFF0C\u9ED8\u8BA4 GET"
|
|
3399
|
+
},
|
|
3400
|
+
headers: {
|
|
3401
|
+
type: "object",
|
|
3402
|
+
description: "\u8BF7\u6C42\u5934\u952E\u503C\u5BF9",
|
|
3403
|
+
additionalProperties: { type: "string" }
|
|
3404
|
+
},
|
|
3405
|
+
body: {
|
|
3406
|
+
type: "string",
|
|
3407
|
+
description: "\u8BF7\u6C42\u4F53\u5185\u5BB9\uFF08POST/PUT \u65F6\u4F7F\u7528\uFF09"
|
|
3408
|
+
},
|
|
3409
|
+
max_length: {
|
|
3410
|
+
type: "number",
|
|
3411
|
+
description: "\u54CD\u5E94\u5185\u5BB9\u6700\u5927\u957F\u5EA6\uFF08\u5B57\u7B26\uFF09\uFF0C\u9ED8\u8BA4 50000"
|
|
3412
|
+
}
|
|
3413
|
+
},
|
|
3414
|
+
required: ["url"],
|
|
3415
|
+
additionalProperties: false
|
|
3416
|
+
},
|
|
3328
3417
|
async execute(args, ctx) {
|
|
3329
|
-
|
|
3330
|
-
if (!params?.url || typeof params.url !== "string") {
|
|
3418
|
+
if (!args?.url || typeof args.url !== "string") {
|
|
3331
3419
|
return { success: false, data: "\u7F3A\u5C11\u5FC5\u8981\u53C2\u6570 url", error: "INVALID_ARGS" };
|
|
3332
3420
|
}
|
|
3333
|
-
const method = (
|
|
3421
|
+
const method = (args.method ?? "GET").toUpperCase();
|
|
3334
3422
|
const timeout = 3e4;
|
|
3335
|
-
const maxLength =
|
|
3423
|
+
const maxLength = args.max_length ?? 5e4;
|
|
3336
3424
|
try {
|
|
3337
3425
|
const fetchOptions = {
|
|
3338
3426
|
method,
|
|
3339
|
-
headers:
|
|
3427
|
+
headers: args.headers ?? {},
|
|
3340
3428
|
signal: ctx.signal ?? AbortSignal.timeout(timeout)
|
|
3341
3429
|
};
|
|
3342
|
-
if (
|
|
3430
|
+
if (args.body && (method === "POST" || method === "PUT" || method === "PATCH")) {
|
|
3343
3431
|
fetchOptions.headers["Content-Type"] ??= "application/json";
|
|
3344
|
-
fetchOptions.body =
|
|
3432
|
+
fetchOptions.body = args.body;
|
|
3345
3433
|
}
|
|
3346
|
-
const response = await fetch(
|
|
3434
|
+
const response = await fetch(args.url, fetchOptions);
|
|
3347
3435
|
const contentType = response.headers.get("content-type") ?? "unknown";
|
|
3348
3436
|
const statusText = `${response.status} ${response.statusText}`;
|
|
3349
3437
|
let body;
|
|
@@ -3356,7 +3444,7 @@ var fetchTool = {
|
|
|
3356
3444
|
const header = `\u72B6\u6001: ${statusText}
|
|
3357
3445
|
\u5185\u5BB9\u7C7B\u578B: ${contentType}`;
|
|
3358
3446
|
const separator = body.length > 0 ? "\n---\n" : "";
|
|
3359
|
-
const urlPreview =
|
|
3447
|
+
const urlPreview = args.url.length > 60 ? args.url.slice(0, 57) + "..." : args.url;
|
|
3360
3448
|
const summary = `\u{1F310} ${method} ${urlPreview} \u2192 ${response.status}`;
|
|
3361
3449
|
return {
|
|
3362
3450
|
success: response.ok,
|
|
@@ -3383,16 +3471,16 @@ var fetchTool = {
|
|
|
3383
3471
|
|
|
3384
3472
|
// src/tool/builtins/index.ts
|
|
3385
3473
|
var builtinTools = [
|
|
3386
|
-
readFileTool,
|
|
3387
|
-
writeFileTool,
|
|
3388
|
-
editFileTool,
|
|
3389
|
-
multiEditTool,
|
|
3390
|
-
deleteRangeTool,
|
|
3391
|
-
bashTool,
|
|
3392
|
-
globTool,
|
|
3393
|
-
grepTool,
|
|
3394
|
-
lsTool,
|
|
3395
|
-
fetchTool
|
|
3474
|
+
eraseTool(readFileTool),
|
|
3475
|
+
eraseTool(writeFileTool),
|
|
3476
|
+
eraseTool(editFileTool),
|
|
3477
|
+
eraseTool(multiEditTool),
|
|
3478
|
+
eraseTool(deleteRangeTool),
|
|
3479
|
+
eraseTool(bashTool),
|
|
3480
|
+
eraseTool(globTool),
|
|
3481
|
+
eraseTool(grepTool),
|
|
3482
|
+
eraseTool(lsTool),
|
|
3483
|
+
eraseTool(fetchTool)
|
|
3396
3484
|
];
|
|
3397
3485
|
|
|
3398
3486
|
// src/utils/gradient.ts
|
|
@@ -3459,7 +3547,7 @@ function getGradientColors(text, phase, stops) {
|
|
|
3459
3547
|
}
|
|
3460
3548
|
|
|
3461
3549
|
// src/ui/ChatSession.tsx
|
|
3462
|
-
import { Fragment, jsx as
|
|
3550
|
+
import { Fragment, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3463
3551
|
var commandRegistry = /* @__PURE__ */ new Map();
|
|
3464
3552
|
function registerCommand(name, cmd) {
|
|
3465
3553
|
commandRegistry.set(name, cmd);
|
|
@@ -3483,6 +3571,8 @@ registerCommand("/help", {
|
|
|
3483
3571
|
registerCommand("/clear", { desc: "\u6E05\u7A7A\u5BF9\u8BDD\u5386\u53F2", handler: () => ({ kind: "clear" }) });
|
|
3484
3572
|
registerCommand("/version", { desc: "\u663E\u793A\u7248\u672C\u4FE1\u606F", handler: () => ({ kind: "text", content: "dskcode v0.1.10" }) });
|
|
3485
3573
|
registerCommand("/model", { desc: "\u5207\u6362\u6A21\u578B", handler: () => ({ kind: "text", content: "\u8BF7\u76F4\u63A5\u8F93\u5165 /model \u8FDB\u5165\u9009\u62E9\u754C\u9762" }) });
|
|
3574
|
+
registerCommand("/thinking", { desc: "\u5207\u6362\u6DF1\u5EA6\u601D\u8003\u6A21\u5F0F", handler: () => ({ kind: "text", content: "\u8BF7\u76F4\u63A5\u8F93\u5165 /thinking \u5207\u6362" }) });
|
|
3575
|
+
registerCommand("/effort", { desc: "\u5207\u6362\u63A8\u7406\u7B49\u7EA7 High/Max", handler: () => ({ kind: "text", content: "\u8BF7\u76F4\u63A5\u8F93\u5165 /effort \u5207\u6362" }) });
|
|
3486
3576
|
registerCommand("/game", { desc: "\u542F\u52A8\u6E38\u620F", handler: () => ({ kind: "navigate", target: "game" }) });
|
|
3487
3577
|
registerCommand("/stock", { desc: "\u67E5\u770B\u80A1\u7968\u884C\u60C5", handler: () => ({ kind: "navigate", target: "stock" }) });
|
|
3488
3578
|
var STREAMING_PLACEHOLDERS = [
|
|
@@ -3541,6 +3631,19 @@ function ChatSession({
|
|
|
3541
3631
|
const [activeModel, setActiveModel] = useState3(model);
|
|
3542
3632
|
const [streamingModel, setStreamingModel] = useState3(void 0);
|
|
3543
3633
|
const [streamError, setStreamError] = useState3(void 0);
|
|
3634
|
+
const [thinkingEnabled, setThinkingEnabled] = useState3(true);
|
|
3635
|
+
const [thinkingEffort, setThinkingEffort] = useState3("high");
|
|
3636
|
+
const [responseFormat, setResponseFormat] = useState3("text");
|
|
3637
|
+
const [toolChoice, setToolChoice] = useState3(void 0);
|
|
3638
|
+
const sessionCost = useMemo(() => {
|
|
3639
|
+
return displayMessages.reduce((sum, msg) => {
|
|
3640
|
+
if (msg.assistantDetail?.cost) {
|
|
3641
|
+
return sum + msg.assistantDetail.cost;
|
|
3642
|
+
}
|
|
3643
|
+
return sum;
|
|
3644
|
+
}, 0);
|
|
3645
|
+
}, [displayMessages]);
|
|
3646
|
+
const hasConversationStarted = displayMessages.length > 0;
|
|
3544
3647
|
const cmdTips = Array.from(getRegisteredCommands()).filter(([name]) => name !== "/exit" && name !== "/quit").map(([name, cmd]) => ({ name, desc: cmd.desc }));
|
|
3545
3648
|
const [cmdTipIndex, setCmdTipIndex] = useState3(0);
|
|
3546
3649
|
const [cmdTipGradientColors, setCmdTipGradientColors] = useState3([]);
|
|
@@ -3672,6 +3775,11 @@ function ChatSession({
|
|
|
3672
3775
|
return;
|
|
3673
3776
|
}
|
|
3674
3777
|
}
|
|
3778
|
+
if (selectingModel) {
|
|
3779
|
+
if (key.upArrow || key.downArrow) {
|
|
3780
|
+
}
|
|
3781
|
+
return;
|
|
3782
|
+
}
|
|
3675
3783
|
if (key.ctrl && _input === "c") {
|
|
3676
3784
|
if (isStreaming) {
|
|
3677
3785
|
abortRef.current?.abort();
|
|
@@ -3691,7 +3799,7 @@ function ChatSession({
|
|
|
3691
3799
|
if (cmdTips.length <= 1) return;
|
|
3692
3800
|
const timer = setInterval(() => {
|
|
3693
3801
|
setCmdTipIndex((prev) => (prev + 1) % cmdTips.length);
|
|
3694
|
-
},
|
|
3802
|
+
}, 2e3);
|
|
3695
3803
|
return () => clearInterval(timer);
|
|
3696
3804
|
}, [cmdTips.length]);
|
|
3697
3805
|
useEffect3(() => {
|
|
@@ -3738,7 +3846,7 @@ function ChatSession({
|
|
|
3738
3846
|
if (!apiKey || !baseUrl) return;
|
|
3739
3847
|
let cancelled = false;
|
|
3740
3848
|
setBalanceLoading(true);
|
|
3741
|
-
import("./deepseek-
|
|
3849
|
+
import("./deepseek-YTT76XDE.js").then(({ DeepSeekProvider: DeepSeekProvider2 }) => {
|
|
3742
3850
|
const provider = new DeepSeekProvider2({
|
|
3743
3851
|
apiKey,
|
|
3744
3852
|
baseUrl,
|
|
@@ -3807,14 +3915,48 @@ function ChatSession({
|
|
|
3807
3915
|
const trimmed = value.trim();
|
|
3808
3916
|
if (!trimmed) return;
|
|
3809
3917
|
if (trimmed.startsWith("/") && trimmed.length > 1) {
|
|
3810
|
-
|
|
3918
|
+
const cmdLower = trimmed.toLowerCase();
|
|
3919
|
+
if (cmdLower === "/model") {
|
|
3811
3920
|
const curIdx = modelOptions.indexOf(activeModel);
|
|
3812
3921
|
setModelSelectIndex(curIdx >= 0 ? curIdx : 0);
|
|
3813
3922
|
setSelectingModel(true);
|
|
3814
3923
|
setInput("");
|
|
3815
3924
|
return;
|
|
3816
3925
|
}
|
|
3817
|
-
|
|
3926
|
+
if (cmdLower === "/thinking") {
|
|
3927
|
+
setThinkingEnabled((prev) => !prev);
|
|
3928
|
+
setDisplayMessages((prev) => [
|
|
3929
|
+
...prev,
|
|
3930
|
+
{ role: "user", content: trimmed },
|
|
3931
|
+
{ role: "assistant", content: `\u6DF1\u5EA6\u601D\u8003\u5DF2${thinkingEnabled ? "\u5173\u95ED" : "\u5F00\u542F"}` }
|
|
3932
|
+
]);
|
|
3933
|
+
setInput("");
|
|
3934
|
+
return;
|
|
3935
|
+
}
|
|
3936
|
+
if (cmdLower === "/effort") {
|
|
3937
|
+
const next = thinkingEffort === "high" ? "max" : "high";
|
|
3938
|
+
setThinkingEffort(next);
|
|
3939
|
+
setDisplayMessages((prev) => [
|
|
3940
|
+
...prev,
|
|
3941
|
+
{ role: "user", content: trimmed },
|
|
3942
|
+
{ role: "assistant", content: `\u63A8\u7406\u7B49\u7EA7\u5DF2\u5207\u6362\u4E3A ${next === "high" ? "High" : "Max"}` }
|
|
3943
|
+
]);
|
|
3944
|
+
setInput("");
|
|
3945
|
+
return;
|
|
3946
|
+
}
|
|
3947
|
+
if (cmdLower === "/tools") {
|
|
3948
|
+
const next = toolChoice === void 0 ? "none" : toolChoice === "none" ? "required" : toolChoice === "required" ? "auto" : void 0;
|
|
3949
|
+
setToolChoice(next);
|
|
3950
|
+
const label = next === void 0 ? "\u81EA\u52A8\uFF08\u9ED8\u8BA4\uFF09" : next === "none" ? "\u7981\u6B62\u8C03\u7528" : next === "required" ? "\u5F3A\u5236\u8C03\u7528" : "\u81EA\u52A8\uFF08\u9ED8\u8BA4\uFF09";
|
|
3951
|
+
setDisplayMessages((prev) => [
|
|
3952
|
+
...prev,
|
|
3953
|
+
{ role: "user", content: trimmed },
|
|
3954
|
+
{ role: "assistant", content: `\u5DE5\u5177\u8C03\u7528\u7B56\u7565\u5DF2\u5207\u6362\u4E3A ${label}` }
|
|
3955
|
+
]);
|
|
3956
|
+
setInput("");
|
|
3957
|
+
return;
|
|
3958
|
+
}
|
|
3959
|
+
const cmd = commandRegistry.get(cmdLower);
|
|
3818
3960
|
if (cmd) {
|
|
3819
3961
|
const result = cmd.handler();
|
|
3820
3962
|
switch (result.kind) {
|
|
@@ -3889,7 +4031,12 @@ function ChatSession({
|
|
|
3889
4031
|
const abortController = new AbortController();
|
|
3890
4032
|
abortRef.current = abortController;
|
|
3891
4033
|
try {
|
|
3892
|
-
for await (const event of session.chat(trimmed
|
|
4034
|
+
for await (const event of session.chat(trimmed, {
|
|
4035
|
+
thinkingAllowed: thinkingEnabled || void 0,
|
|
4036
|
+
thinkingEffort: thinkingEnabled ? thinkingEffort : void 0,
|
|
4037
|
+
responseFormat: responseFormat !== "text" ? responseFormat : void 0,
|
|
4038
|
+
toolChoice
|
|
4039
|
+
})) {
|
|
3893
4040
|
if (abortController.signal.aborted) break;
|
|
3894
4041
|
switch (event.type) {
|
|
3895
4042
|
case "text_delta":
|
|
@@ -3927,6 +4074,11 @@ function ChatSession({
|
|
|
3927
4074
|
setStreamingModel(event.model);
|
|
3928
4075
|
currentUsageRef.current = event.usage;
|
|
3929
4076
|
currentModelRef.current = event.model;
|
|
4077
|
+
{
|
|
4078
|
+
const cost = calculateCost(event.usage, event.model);
|
|
4079
|
+
setCurrentCost(cost.totalCost);
|
|
4080
|
+
currentCostRef.current = cost.totalCost;
|
|
4081
|
+
}
|
|
3930
4082
|
break;
|
|
3931
4083
|
case "done":
|
|
3932
4084
|
setCurrentElapsed(event.elapsed);
|
|
@@ -3968,66 +4120,66 @@ function ChatSession({
|
|
|
3968
4120
|
]);
|
|
3969
4121
|
}
|
|
3970
4122
|
}
|
|
3971
|
-
}, [onLaunchGame, onLaunchStock, currentContent, currentToolCalls, skills, skillSelectIndex, getFilteredSkills]);
|
|
4123
|
+
}, [onLaunchGame, onLaunchStock, currentContent, currentToolCalls, skills, skillSelectIndex, getFilteredSkills, thinkingEnabled, thinkingEffort, responseFormat, toolChoice, activeModel]);
|
|
3972
4124
|
useEffect3(() => {
|
|
3973
4125
|
if (!isStreaming && externalCostTracker) {
|
|
3974
4126
|
setTodayCost(externalCostTracker.todayTotalCost);
|
|
3975
4127
|
}
|
|
3976
4128
|
}, [isStreaming, externalCostTracker]);
|
|
3977
|
-
useEffect3(() => {
|
|
3978
|
-
if (currentUsage && streamingModel && !currentCost) {
|
|
3979
|
-
import("./models-OL7DHYGK.js").then(({ calculateCost: calculateCost2 }) => {
|
|
3980
|
-
const cost = calculateCost2(currentUsage, streamingModel);
|
|
3981
|
-
setCurrentCost(cost.totalCost);
|
|
3982
|
-
currentCostRef.current = cost.totalCost;
|
|
3983
|
-
});
|
|
3984
|
-
}
|
|
3985
|
-
}, [currentUsage, streamingModel, currentCost]);
|
|
3986
4129
|
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingLeft: 1, paddingRight: 1, children: [
|
|
3987
|
-
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", marginBottom: 1, children: [
|
|
3988
|
-
/* @__PURE__ */
|
|
4130
|
+
!hasConversationStarted && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", marginBottom: 1, children: [
|
|
4131
|
+
/* @__PURE__ */ jsx9(Box8, { flexDirection: "column", marginRight: 4, children: LOGO_LINES.map((line, i) => {
|
|
3989
4132
|
const colorIndex = (i + offset) % CYBER_PALETTE.length;
|
|
3990
|
-
return /* @__PURE__ */
|
|
4133
|
+
return /* @__PURE__ */ jsx9(Box8, { children: /* @__PURE__ */ jsx9(Text10, { bold: true, color: CYBER_PALETTE[colorIndex], children: line }) }, i);
|
|
3991
4134
|
}) }),
|
|
3992
4135
|
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", justifyContent: "center", children: [
|
|
3993
|
-
/* @__PURE__ */ jsxs8(
|
|
4136
|
+
/* @__PURE__ */ jsxs8(Text10, { color: "#00ff41", children: [
|
|
3994
4137
|
" \u2714 ",
|
|
3995
4138
|
"\u5DF2\u5C31\u7EEA ",
|
|
3996
4139
|
skillCount,
|
|
3997
4140
|
" \u4E2A Skill"
|
|
3998
4141
|
] }),
|
|
3999
|
-
/* @__PURE__ */ jsxs8(
|
|
4142
|
+
/* @__PURE__ */ jsxs8(Text10, { color: "#00ffff", children: [
|
|
4000
4143
|
" \u2139 ",
|
|
4001
4144
|
"\u5DF2\u5C31\u7EEA ",
|
|
4002
4145
|
toolCount,
|
|
4003
4146
|
" \u4E2A\u5DE5\u5177"
|
|
4004
4147
|
] }),
|
|
4005
|
-
/* @__PURE__ */ jsxs8(
|
|
4148
|
+
/* @__PURE__ */ jsxs8(Text10, { color: "#00ffff", children: [
|
|
4006
4149
|
" \u{1F527} \u6A21\u578B ",
|
|
4007
4150
|
SUPPORTED_MODELS[activeModel]?.displayName ?? activeModel
|
|
4008
4151
|
] }),
|
|
4152
|
+
thinkingEnabled && /* @__PURE__ */ jsxs8(Text10, { color: "#ff9800", children: [
|
|
4153
|
+
" \u{1F9E0} \u6DF1\u5EA6\u601D\u8003 ",
|
|
4154
|
+
thinkingEffort === "max" ? "Max" : "High"
|
|
4155
|
+
] }),
|
|
4156
|
+
responseFormat === "json_object" && /* @__PURE__ */ jsx9(Text10, { color: "#4caf50", children: " \u{1F4C4} JSON" }),
|
|
4157
|
+
toolChoice !== void 0 && /* @__PURE__ */ jsxs8(Text10, { color: "#e91e63", children: [
|
|
4158
|
+
" \u{1F6E0} ",
|
|
4159
|
+
toolChoice === "none" ? "\u7981\u6B62\u5DE5\u5177" : toolChoice === "required" ? "\u5F3A\u5236\u5DE5\u5177" : ""
|
|
4160
|
+
] }),
|
|
4009
4161
|
cmdTips.length > 0 && (() => {
|
|
4010
4162
|
const tip = cmdTips[cmdTipIndex % cmdTips.length];
|
|
4011
4163
|
if (!tip) return null;
|
|
4012
4164
|
const text = `${tip.name} ${tip.desc}`;
|
|
4013
|
-
return /* @__PURE__ */ jsxs8(
|
|
4014
|
-
/* @__PURE__ */
|
|
4015
|
-
cmdTipGradientColors.length > 0 ? text.split("").map((ch, i) => /* @__PURE__ */
|
|
4165
|
+
return /* @__PURE__ */ jsxs8(Text10, { children: [
|
|
4166
|
+
/* @__PURE__ */ jsx9(Text10, { color: "#808080", children: " \u{1F4A1} " }),
|
|
4167
|
+
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 })
|
|
4016
4168
|
] });
|
|
4017
4169
|
})(),
|
|
4018
|
-
verbose ? /* @__PURE__ */
|
|
4170
|
+
verbose ? /* @__PURE__ */ jsx9(Text10, { color: "#ff1493", children: " \u26A1 Verbose" }) : null
|
|
4019
4171
|
] }),
|
|
4020
4172
|
/* @__PURE__ */ jsxs8(Box8, { flexGrow: 1, flexDirection: "column", justifyContent: "center", alignItems: "flex-end", children: [
|
|
4021
|
-
balanceLoading && balance === null ? /* @__PURE__ */
|
|
4022
|
-
/* @__PURE__ */
|
|
4023
|
-
/* @__PURE__ */ jsxs8(
|
|
4173
|
+
balanceLoading && balance === null ? /* @__PURE__ */ jsx9(Text10, { color: "yellow", children: " \u23F3 \u67E5\u8BE2\u4F59\u989D..." }) : balance !== null ? /* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", children: [
|
|
4174
|
+
/* @__PURE__ */ jsx9(Text10, { color: "yellow", children: "\u{1F4B0} " }),
|
|
4175
|
+
/* @__PURE__ */ jsxs8(Text10, { color: "yellow", children: [
|
|
4024
4176
|
"\u4F59\u989D \xA5",
|
|
4025
4177
|
balance.toFixed(2)
|
|
4026
4178
|
] })
|
|
4027
4179
|
] }) : null,
|
|
4028
4180
|
todayCost !== null ? /* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", children: [
|
|
4029
|
-
/* @__PURE__ */
|
|
4030
|
-
/* @__PURE__ */ jsxs8(
|
|
4181
|
+
/* @__PURE__ */ jsx9(Text10, { color: "cyan", children: "\u{1F4CA} " }),
|
|
4182
|
+
/* @__PURE__ */ jsxs8(Text10, { color: "cyan", children: [
|
|
4031
4183
|
"\u4ECA\u65E5 \xA5",
|
|
4032
4184
|
todayCost.toFixed(2)
|
|
4033
4185
|
] })
|
|
@@ -4035,24 +4187,24 @@ function ChatSession({
|
|
|
4035
4187
|
] })
|
|
4036
4188
|
] }),
|
|
4037
4189
|
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
|
|
4038
|
-
/* @__PURE__ */
|
|
4190
|
+
/* @__PURE__ */ jsx9(Static, { items: displayMessages, children: (msg, i) => {
|
|
4039
4191
|
if (msg.role === "user") {
|
|
4040
4192
|
return /* @__PURE__ */ jsxs8(Box8, { marginTop: 1, children: [
|
|
4041
|
-
/* @__PURE__ */
|
|
4042
|
-
/* @__PURE__ */
|
|
4193
|
+
/* @__PURE__ */ jsx9(Box8, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx9(Text10, { bold: true, color: "#00ff41", children: "\u{1F464}" }) }),
|
|
4194
|
+
/* @__PURE__ */ jsx9(Box8, { flexGrow: 1, children: /* @__PURE__ */ jsx9(Text10, { wrap: "wrap", children: msg.content }) })
|
|
4043
4195
|
] }, i);
|
|
4044
4196
|
}
|
|
4045
4197
|
if (msg.role === "tool") {
|
|
4046
4198
|
return /* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexDirection: "column", children: [
|
|
4047
4199
|
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", children: [
|
|
4048
|
-
/* @__PURE__ */
|
|
4049
|
-
/* @__PURE__ */
|
|
4200
|
+
/* @__PURE__ */ jsx9(Box8, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx9(Text10, { bold: true, color: "#f59e0b", children: "\u{1F527}" }) }),
|
|
4201
|
+
/* @__PURE__ */ jsx9(Box8, { flexGrow: 1, children: /* @__PURE__ */ jsx9(Text10, { wrap: "wrap", children: msg.content }) })
|
|
4050
4202
|
] }),
|
|
4051
|
-
msg.diff && /* @__PURE__ */
|
|
4203
|
+
msg.diff && /* @__PURE__ */ jsx9(DiffPreview, { diff: msg.diff })
|
|
4052
4204
|
] }, i);
|
|
4053
4205
|
}
|
|
4054
4206
|
const detail = msg.assistantDetail;
|
|
4055
|
-
return /* @__PURE__ */
|
|
4207
|
+
return /* @__PURE__ */ jsx9(
|
|
4056
4208
|
AssistantMessage,
|
|
4057
4209
|
{
|
|
4058
4210
|
content: msg.content,
|
|
@@ -4066,7 +4218,7 @@ function ChatSession({
|
|
|
4066
4218
|
i
|
|
4067
4219
|
);
|
|
4068
4220
|
} }, staticKey),
|
|
4069
|
-
isStreaming && /* @__PURE__ */
|
|
4221
|
+
isStreaming && /* @__PURE__ */ jsx9(
|
|
4070
4222
|
AssistantMessage,
|
|
4071
4223
|
{
|
|
4072
4224
|
content: currentContent,
|
|
@@ -4074,16 +4226,16 @@ function ChatSession({
|
|
|
4074
4226
|
isStreaming: true
|
|
4075
4227
|
}
|
|
4076
4228
|
),
|
|
4077
|
-
isStreaming && !currentContent && currentToolCalls.length === 0 && /* @__PURE__ */
|
|
4078
|
-
!isStreaming && streamError && /* @__PURE__ */
|
|
4229
|
+
isStreaming && !currentContent && currentToolCalls.length === 0 && /* @__PURE__ */ jsx9(Box8, { marginTop: 1, marginLeft: 4, children: /* @__PURE__ */ jsx9(Spinner, { type: "dots", label: "\u601D\u8003\u4E2D..." }) }),
|
|
4230
|
+
!isStreaming && streamError && /* @__PURE__ */ jsx9(Box8, { marginTop: 1, marginLeft: 3, children: /* @__PURE__ */ jsxs8(Text10, { color: "red", children: [
|
|
4079
4231
|
"\u26A0 ",
|
|
4080
4232
|
streamError
|
|
4081
4233
|
] }) })
|
|
4082
4234
|
] }),
|
|
4083
4235
|
selectingModel ? /* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexDirection: "column", children: [
|
|
4084
|
-
/* @__PURE__ */
|
|
4236
|
+
/* @__PURE__ */ jsx9(Text10, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }),
|
|
4085
4237
|
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", marginTop: 1, children: [
|
|
4086
|
-
/* @__PURE__ */
|
|
4238
|
+
/* @__PURE__ */ jsx9(Text10, { bold: true, color: "#00ffff", children: "\u9009\u62E9\u6A21\u578B\uFF1A" }),
|
|
4087
4239
|
modelOptions.map((id, i) => {
|
|
4088
4240
|
const meta = SUPPORTED_MODELS[id];
|
|
4089
4241
|
const isCurrent = id === activeModel;
|
|
@@ -4092,7 +4244,7 @@ function ChatSession({
|
|
|
4092
4244
|
const suffix = isCurrent ? " (\u5F53\u524D)" : "";
|
|
4093
4245
|
return /* @__PURE__ */ jsxs8(Box8, { children: [
|
|
4094
4246
|
/* @__PURE__ */ jsxs8(
|
|
4095
|
-
|
|
4247
|
+
Text10,
|
|
4096
4248
|
{
|
|
4097
4249
|
color: isSelected ? "#00ff41" : void 0,
|
|
4098
4250
|
bold: isSelected,
|
|
@@ -4103,20 +4255,34 @@ function ChatSession({
|
|
|
4103
4255
|
]
|
|
4104
4256
|
}
|
|
4105
4257
|
),
|
|
4106
|
-
isSelected && /* @__PURE__ */ jsxs8(
|
|
4258
|
+
isSelected && /* @__PURE__ */ jsxs8(Text10, { color: "#808080", children: [
|
|
4107
4259
|
" \u2014 ",
|
|
4108
4260
|
id
|
|
4109
4261
|
] })
|
|
4110
4262
|
] }, id);
|
|
4111
4263
|
}),
|
|
4112
|
-
/* @__PURE__ */
|
|
4264
|
+
/* @__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" }) })
|
|
4113
4265
|
] }),
|
|
4114
|
-
/* @__PURE__ */
|
|
4266
|
+
/* @__PURE__ */ jsx9(Text10, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) })
|
|
4115
4267
|
] }) : /* @__PURE__ */ jsxs8(Fragment, { children: [
|
|
4116
|
-
/* @__PURE__ */
|
|
4268
|
+
/* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: hasConversationStarted && (balance !== null || sessionCost > 0 || isStreaming) ? /* @__PURE__ */ jsxs8(Text10, { color: "#00ffff", dimColor: true, children: [
|
|
4269
|
+
"\u2500".repeat(Math.max(dividerWidth - 35, 10)),
|
|
4270
|
+
balance !== null && /* @__PURE__ */ jsxs8(Text10, { color: "yellow", children: [
|
|
4271
|
+
" \u{1F4B0} \u4F59\u989D \xA5",
|
|
4272
|
+
balance.toFixed(2)
|
|
4273
|
+
] }),
|
|
4274
|
+
isStreaming ? /* @__PURE__ */ jsxs8(Text10, { color: "cyan", children: [
|
|
4275
|
+
" \u{1F4CA} \u672C\u6B21 \xA5",
|
|
4276
|
+
sessionCost > 0 ? sessionCost.toFixed(4) + " " : "",
|
|
4277
|
+
/* @__PURE__ */ jsx9(InkSpinner2, { type: "dots" })
|
|
4278
|
+
] }) : sessionCost > 0 ? /* @__PURE__ */ jsxs8(Text10, { color: "cyan", children: [
|
|
4279
|
+
" \u{1F4CA} \u672C\u6B21 \xA5",
|
|
4280
|
+
sessionCost.toFixed(4)
|
|
4281
|
+
] }) : null
|
|
4282
|
+
] }) : /* @__PURE__ */ jsx9(Text10, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }) }),
|
|
4117
4283
|
/* @__PURE__ */ jsxs8(Box8, { children: [
|
|
4118
|
-
/* @__PURE__ */
|
|
4119
|
-
/* @__PURE__ */
|
|
4284
|
+
/* @__PURE__ */ jsx9(Box8, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx9(Text10, { bold: true, color: "#00ff41", children: "\u26A1" }) }),
|
|
4285
|
+
/* @__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(
|
|
4120
4286
|
TextInput,
|
|
4121
4287
|
{
|
|
4122
4288
|
value: input,
|
|
@@ -4127,19 +4293,19 @@ function ChatSession({
|
|
|
4127
4293
|
inputKey
|
|
4128
4294
|
) })
|
|
4129
4295
|
] }),
|
|
4130
|
-
/* @__PURE__ */
|
|
4131
|
-
/* @__PURE__ */
|
|
4132
|
-
/* @__PURE__ */
|
|
4296
|
+
/* @__PURE__ */ jsx9(Box8, { children: /* @__PURE__ */ jsx9(Text10, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }) }),
|
|
4297
|
+
/* @__PURE__ */ jsx9(SkillSelector, { skills, input, selectedIndex: skillSelectIndex }),
|
|
4298
|
+
/* @__PURE__ */ jsx9(FileSelector, { files, input, selectedIndex: fileSelectIndex })
|
|
4133
4299
|
] }),
|
|
4134
|
-
doubleCtrlC && !isStreaming && /* @__PURE__ */
|
|
4135
|
-
isStreaming && /* @__PURE__ */
|
|
4300
|
+
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" }) }),
|
|
4301
|
+
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" }) })
|
|
4136
4302
|
] });
|
|
4137
4303
|
}
|
|
4138
4304
|
|
|
4139
4305
|
// src/ui/GamePicker.tsx
|
|
4140
|
-
import { Box as Box9, Text as
|
|
4306
|
+
import { Box as Box9, Text as Text11, useInput as useInput2 } from "ink";
|
|
4141
4307
|
import { useState as useState4, useCallback as useCallback3 } from "react";
|
|
4142
|
-
import { jsx as
|
|
4308
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4143
4309
|
function GamePicker({ games, onSelect, onExit, onBackToChat }) {
|
|
4144
4310
|
const [selectedIndex, setSelectedIndex] = useState4(0);
|
|
4145
4311
|
const exitAction = onBackToChat ?? onExit ?? (() => process.exit(0));
|
|
@@ -4168,17 +4334,17 @@ function GamePicker({ games, onSelect, onExit, onBackToChat }) {
|
|
|
4168
4334
|
)
|
|
4169
4335
|
);
|
|
4170
4336
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
4171
|
-
/* @__PURE__ */
|
|
4172
|
-
/* @__PURE__ */
|
|
4337
|
+
/* @__PURE__ */ jsx10(Box9, { marginBottom: 1, children: /* @__PURE__ */ jsx10(Text11, { bold: true, color: "#00ffff", children: "\u{1F3AE} \u6E38\u620F\u5217\u8868" }) }),
|
|
4338
|
+
/* @__PURE__ */ jsx10(Box9, { flexDirection: "column", children: games.map((game, index) => {
|
|
4173
4339
|
const isSelected = index === selectedIndex;
|
|
4174
4340
|
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "row", children: [
|
|
4175
|
-
/* @__PURE__ */
|
|
4176
|
-
/* @__PURE__ */
|
|
4177
|
-
/* @__PURE__ */
|
|
4341
|
+
/* @__PURE__ */ jsx10(Box9, { width: 3, flexShrink: 0, children: isSelected ? /* @__PURE__ */ jsx10(Text11, { bold: true, color: "#00ff41", children: "\u25B8 " }) : /* @__PURE__ */ jsx10(Text11, { children: " " }) }),
|
|
4342
|
+
/* @__PURE__ */ jsx10(Box9, { width: 20, flexShrink: 0, children: /* @__PURE__ */ jsx10(Text11, { bold: true, color: isSelected ? "#00ff41" : "#ffffff", children: game.name }) }),
|
|
4343
|
+
/* @__PURE__ */ jsx10(Box9, { children: /* @__PURE__ */ jsx10(Text11, { color: "#888888", children: game.description }) })
|
|
4178
4344
|
] }, game.id);
|
|
4179
4345
|
}) }),
|
|
4180
|
-
/* @__PURE__ */
|
|
4181
|
-
doubleCtrlC && /* @__PURE__ */
|
|
4346
|
+
/* @__PURE__ */ jsx10(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text11, { dimColor: true, children: " \u2191/\u2193 \u9009\u62E9 Enter \u542F\u52A8 q \u8FD4\u56DE" }) }),
|
|
4347
|
+
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" }) })
|
|
4182
4348
|
] });
|
|
4183
4349
|
}
|
|
4184
4350
|
|
|
@@ -4195,9 +4361,9 @@ function listGames() {
|
|
|
4195
4361
|
}
|
|
4196
4362
|
|
|
4197
4363
|
// src/game/brick-breaker/index.tsx
|
|
4198
|
-
import { Box as Box10, Text as
|
|
4364
|
+
import { Box as Box10, Text as Text12, useInput as useInput3, render as render2 } from "ink";
|
|
4199
4365
|
import { useState as useState5, useEffect as useEffect4, useRef as useRef3, useCallback as useCallback4 } from "react";
|
|
4200
|
-
import { jsx as
|
|
4366
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4201
4367
|
var GAME_WIDTH = 40;
|
|
4202
4368
|
var GAME_HEIGHT = 18;
|
|
4203
4369
|
var PADDLE_WIDTH = 9;
|
|
@@ -4389,47 +4555,47 @@ function BrickBreakerGame({ onExit: _onExit }) {
|
|
|
4389
4555
|
void tick2;
|
|
4390
4556
|
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
|
|
4391
4557
|
/* @__PURE__ */ jsxs10(Box10, { flexDirection: "row", children: [
|
|
4392
|
-
/* @__PURE__ */
|
|
4558
|
+
/* @__PURE__ */ jsx11(Box10, { width: 20, children: /* @__PURE__ */ jsxs10(Text12, { children: [
|
|
4393
4559
|
"\u5173\u5361 ",
|
|
4394
4560
|
s.level,
|
|
4395
4561
|
": ",
|
|
4396
|
-
/* @__PURE__ */
|
|
4562
|
+
/* @__PURE__ */ jsx11(Text12, { color: "cyan", children: def.desc })
|
|
4397
4563
|
] }) }),
|
|
4398
|
-
/* @__PURE__ */
|
|
4564
|
+
/* @__PURE__ */ jsx11(Box10, { width: 12, children: /* @__PURE__ */ jsxs10(Text12, { children: [
|
|
4399
4565
|
"\u5206\u6570: ",
|
|
4400
|
-
/* @__PURE__ */
|
|
4566
|
+
/* @__PURE__ */ jsx11(Text12, { color: "yellow", children: String(s.score).padStart(3, "0") })
|
|
4401
4567
|
] }) }),
|
|
4402
|
-
/* @__PURE__ */
|
|
4568
|
+
/* @__PURE__ */ jsx11(Box10, { width: 12, children: /* @__PURE__ */ jsxs10(Text12, { children: [
|
|
4403
4569
|
"\u751F\u547D: ",
|
|
4404
|
-
/* @__PURE__ */
|
|
4570
|
+
/* @__PURE__ */ jsx11(Text12, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) })
|
|
4405
4571
|
] }) }),
|
|
4406
|
-
/* @__PURE__ */
|
|
4572
|
+
/* @__PURE__ */ jsx11(Box10, { width: 10, children: /* @__PURE__ */ jsxs10(Text12, { children: [
|
|
4407
4573
|
"\u7816\u5757: ",
|
|
4408
|
-
/* @__PURE__ */
|
|
4574
|
+
/* @__PURE__ */ jsx11(Text12, { color: "cyan", children: aliveCount })
|
|
4409
4575
|
] }) }),
|
|
4410
|
-
/* @__PURE__ */
|
|
4576
|
+
/* @__PURE__ */ jsx11(Box10, { children: /* @__PURE__ */ jsxs10(Text12, { color: s.paused ? "gray" : "green", children: [
|
|
4411
4577
|
"[",
|
|
4412
4578
|
s.paused ? "\u6682\u505C" : "\u8FD0\u884C\u4E2D",
|
|
4413
4579
|
"]"
|
|
4414
4580
|
] }) })
|
|
4415
4581
|
] }),
|
|
4416
4582
|
/* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
|
|
4417
|
-
/* @__PURE__ */ jsxs10(
|
|
4583
|
+
/* @__PURE__ */ jsxs10(Text12, { children: [
|
|
4418
4584
|
"\u250C",
|
|
4419
4585
|
"\u2500".repeat(GAME_WIDTH),
|
|
4420
4586
|
"\u2510"
|
|
4421
4587
|
] }),
|
|
4422
|
-
/* @__PURE__ */
|
|
4423
|
-
/* @__PURE__ */ jsxs10(
|
|
4588
|
+
/* @__PURE__ */ jsx11(Text12, { children: selectingLevel ? " \x1B[90m\u9009\u62E9\u5173\u5361\u540E\u5F00\u59CB...\x1B[0m" : board }),
|
|
4589
|
+
/* @__PURE__ */ jsxs10(Text12, { children: [
|
|
4424
4590
|
"\u2514",
|
|
4425
4591
|
"\u2500".repeat(GAME_WIDTH),
|
|
4426
4592
|
"\u2518"
|
|
4427
4593
|
] })
|
|
4428
4594
|
] }),
|
|
4429
4595
|
selectingLevel && /* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
4430
|
-
/* @__PURE__ */
|
|
4431
|
-
/* @__PURE__ */
|
|
4432
|
-
/* @__PURE__ */
|
|
4596
|
+
/* @__PURE__ */ jsx11(Text12, { bold: true, color: "yellow", children: "\u9009\u62E9\u5173\u5361" }),
|
|
4597
|
+
/* @__PURE__ */ jsx11(Box10, { flexDirection: "row", flexWrap: "wrap", children: LEVELS.map((lv, i) => /* @__PURE__ */ jsx11(Box10, { width: 22, children: /* @__PURE__ */ jsxs10(Text12, { children: [
|
|
4598
|
+
/* @__PURE__ */ jsx11(Text12, { color: initialLevel === i + 1 ? "green" : "white", children: i + 1 === 10 ? "0" : String(i + 1) }),
|
|
4433
4599
|
". ",
|
|
4434
4600
|
lv.desc,
|
|
4435
4601
|
" (",
|
|
@@ -4438,16 +4604,16 @@ function BrickBreakerGame({ onExit: _onExit }) {
|
|
|
4438
4604
|
lv.cols,
|
|
4439
4605
|
")"
|
|
4440
4606
|
] }) }, i)) }),
|
|
4441
|
-
/* @__PURE__ */
|
|
4607
|
+
/* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text12, { dimColor: true, children: "\u6309\u6570\u5B57\u9009\u5173 q \u9000\u51FA" }) })
|
|
4442
4608
|
] }),
|
|
4443
4609
|
!selectingLevel && (s.gameOver || s.win) && /* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
4444
|
-
/* @__PURE__ */
|
|
4445
|
-
/* @__PURE__ */ jsxs10(
|
|
4610
|
+
/* @__PURE__ */ jsx11(Text12, { bold: true, color: s.gameOver ? "red" : "green", children: s.gameOver ? "\u6E38\u620F\u7ED3\u675F\uFF01" : "\u606D\u559C\u901A\u5173\uFF01" }),
|
|
4611
|
+
/* @__PURE__ */ jsxs10(Text12, { children: [
|
|
4446
4612
|
" \u5206\u6570: ",
|
|
4447
|
-
/* @__PURE__ */
|
|
4613
|
+
/* @__PURE__ */ jsx11(Text12, { color: "yellow", children: s.score })
|
|
4448
4614
|
] })
|
|
4449
4615
|
] }),
|
|
4450
|
-
!selectingLevel && /* @__PURE__ */
|
|
4616
|
+
!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" }) })
|
|
4451
4617
|
] });
|
|
4452
4618
|
}
|
|
4453
4619
|
var brick_breaker_default = {
|
|
@@ -4457,7 +4623,7 @@ var brick_breaker_default = {
|
|
|
4457
4623
|
play: async () => {
|
|
4458
4624
|
await new Promise((resolve2) => {
|
|
4459
4625
|
const { unmount } = render2(
|
|
4460
|
-
/* @__PURE__ */
|
|
4626
|
+
/* @__PURE__ */ jsx11(BrickBreakerGame, { onExit: () => {
|
|
4461
4627
|
unmount();
|
|
4462
4628
|
resolve2();
|
|
4463
4629
|
} })
|
|
@@ -4467,9 +4633,9 @@ var brick_breaker_default = {
|
|
|
4467
4633
|
};
|
|
4468
4634
|
|
|
4469
4635
|
// src/game/coder-check/index.tsx
|
|
4470
|
-
import { Box as Box11, Text as
|
|
4636
|
+
import { Box as Box11, Text as Text13, useInput as useInput4, render as render3 } from "ink";
|
|
4471
4637
|
import { useState as useState6, useEffect as useEffect5, useRef as useRef4, useCallback as useCallback5 } from "react";
|
|
4472
|
-
import { jsx as
|
|
4638
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4473
4639
|
var GAME_W = 66;
|
|
4474
4640
|
var GAME_H = 20;
|
|
4475
4641
|
var SCORE_H = 6;
|
|
@@ -4941,43 +5107,43 @@ function CoderCheck({ onExit: _onExit }) {
|
|
|
4941
5107
|
const view = buildGameView(s, scoreLines, scoreColor, s.message);
|
|
4942
5108
|
void tick2;
|
|
4943
5109
|
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, children: [
|
|
4944
|
-
/* @__PURE__ */
|
|
5110
|
+
/* @__PURE__ */ jsx12(Box11, { flexDirection: "row", children: /* @__PURE__ */ jsxs11(Text13, { children: [
|
|
4945
5111
|
"\u751F\u547D ",
|
|
4946
|
-
/* @__PURE__ */
|
|
5112
|
+
/* @__PURE__ */ jsx12(Text13, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) }),
|
|
4947
5113
|
" ",
|
|
4948
5114
|
"\u901F\u5EA6 ",
|
|
4949
|
-
/* @__PURE__ */ jsxs11(
|
|
5115
|
+
/* @__PURE__ */ jsxs11(Text13, { color: "cyan", children: [
|
|
4950
5116
|
"Lv.",
|
|
4951
5117
|
Math.floor(s.speed * 10)
|
|
4952
5118
|
] })
|
|
4953
5119
|
] }) }),
|
|
4954
|
-
!s.gameOver && s.target && /* @__PURE__ */
|
|
5120
|
+
!s.gameOver && s.target && /* @__PURE__ */ jsx12(Box11, { marginTop: 1, children: /* @__PURE__ */ jsxs11(Text13, { children: [
|
|
4955
5121
|
"\u6253\u5B57: ",
|
|
4956
|
-
/* @__PURE__ */
|
|
4957
|
-
/* @__PURE__ */
|
|
5122
|
+
/* @__PURE__ */ jsx12(Text13, { color: "green", children: s.typed }),
|
|
5123
|
+
/* @__PURE__ */ jsx12(Text13, { color: "white", children: s.target.slice(s.typed.length) })
|
|
4958
5124
|
] }) }),
|
|
4959
5125
|
/* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", marginTop: 1, children: [
|
|
4960
|
-
/* @__PURE__ */ jsxs11(
|
|
5126
|
+
/* @__PURE__ */ jsxs11(Text13, { children: [
|
|
4961
5127
|
"\u250C",
|
|
4962
5128
|
"\u2500".repeat(GAME_W),
|
|
4963
5129
|
"\u2510"
|
|
4964
5130
|
] }),
|
|
4965
|
-
view.map((row, i) => /* @__PURE__ */
|
|
4966
|
-
/* @__PURE__ */ jsxs11(
|
|
5131
|
+
view.map((row, i) => /* @__PURE__ */ jsx12(Text13, { children: `\u2502${row}\u2502` }, i)),
|
|
5132
|
+
/* @__PURE__ */ jsxs11(Text13, { children: [
|
|
4967
5133
|
"\u2514",
|
|
4968
5134
|
"\u2500".repeat(GAME_W),
|
|
4969
5135
|
"\u2518"
|
|
4970
5136
|
] })
|
|
4971
5137
|
] }),
|
|
4972
5138
|
s.gameOver && /* @__PURE__ */ jsxs11(Box11, { marginTop: 1, children: [
|
|
4973
|
-
/* @__PURE__ */
|
|
4974
|
-
/* @__PURE__ */ jsxs11(
|
|
5139
|
+
/* @__PURE__ */ jsx12(Text13, { bold: true, color: "red", children: "\u6E38\u620F\u7ED3\u675F\uFF01" }),
|
|
5140
|
+
/* @__PURE__ */ jsxs11(Text13, { children: [
|
|
4975
5141
|
" \u5F97\u5206: ",
|
|
4976
|
-
/* @__PURE__ */
|
|
5142
|
+
/* @__PURE__ */ jsx12(Text13, { color: "yellow", children: s.score }),
|
|
4977
5143
|
" r \u91CD\u5F00 q \u9000\u51FA"
|
|
4978
5144
|
] })
|
|
4979
5145
|
] }),
|
|
4980
|
-
/* @__PURE__ */
|
|
5146
|
+
/* @__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" }) })
|
|
4981
5147
|
] });
|
|
4982
5148
|
}
|
|
4983
5149
|
var coder_check_default = {
|
|
@@ -4987,7 +5153,7 @@ var coder_check_default = {
|
|
|
4987
5153
|
play: async () => {
|
|
4988
5154
|
await new Promise((resolve2) => {
|
|
4989
5155
|
const { unmount } = render3(
|
|
4990
|
-
/* @__PURE__ */
|
|
5156
|
+
/* @__PURE__ */ jsx12(CoderCheck, { onExit: () => {
|
|
4991
5157
|
unmount();
|
|
4992
5158
|
resolve2();
|
|
4993
5159
|
} })
|
|
@@ -5367,12 +5533,12 @@ import { render as render4 } from "ink";
|
|
|
5367
5533
|
import chalk5 from "chalk";
|
|
5368
5534
|
|
|
5369
5535
|
// src/stock/StockList.tsx
|
|
5370
|
-
import { Box as Box12, Text as
|
|
5536
|
+
import { Box as Box12, Text as Text14, useInput as useInput5 } from "ink";
|
|
5371
5537
|
import { useState as useState7, useCallback as useCallback6, useEffect as useEffect6 } from "react";
|
|
5372
5538
|
import asciichart from "asciichart";
|
|
5373
5539
|
import os from "os";
|
|
5374
5540
|
import { join as join7 } from "path";
|
|
5375
|
-
import { jsx as
|
|
5541
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5376
5542
|
var SETTINGS_PATH = join7(os.homedir(), ".dskcode", "settings.json");
|
|
5377
5543
|
function toFileUrl(p) {
|
|
5378
5544
|
const norm = p.replace(/\\/g, "/");
|
|
@@ -5583,61 +5749,61 @@ function StockList({ codes, onExit, onBackToChat }) {
|
|
|
5583
5749
|
);
|
|
5584
5750
|
if (detailView) {
|
|
5585
5751
|
if (detailLoading) {
|
|
5586
|
-
return /* @__PURE__ */
|
|
5752
|
+
return /* @__PURE__ */ jsx13(Box12, { paddingLeft: 1, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: " \u27F3 \u52A0\u8F7D\u5206\u65F6\u6570\u636E..." }) });
|
|
5587
5753
|
}
|
|
5588
5754
|
return renderDetail(detailView, () => setDetailView(null), detailPrices ?? void 0, detailCountdown, currentTime);
|
|
5589
5755
|
}
|
|
5590
5756
|
const cp2 = (c) => dimMode ? { dimColor: true } : { color: c };
|
|
5591
5757
|
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
|
|
5592
5758
|
/* @__PURE__ */ jsxs12(Box12, { marginBottom: 1, justifyContent: "space-between", children: [
|
|
5593
|
-
/* @__PURE__ */
|
|
5594
|
-
/* @__PURE__ */ jsxs12(
|
|
5759
|
+
/* @__PURE__ */ jsx13(Text14, { bold: true, ...cp2("#00ffff"), children: " \u{1F4C8} \u81EA\u9009\u80A1\u76D1\u63A7" }),
|
|
5760
|
+
/* @__PURE__ */ jsxs12(Text14, { dimColor: true, children: [
|
|
5595
5761
|
" \u{1F550} ",
|
|
5596
5762
|
currentTime
|
|
5597
5763
|
] }),
|
|
5598
|
-
/* @__PURE__ */
|
|
5764
|
+
/* @__PURE__ */ jsx13(Text14, { dimColor: true, children: loading ? " \u27F3 \u5237\u65B0\u4E2D..." : ` ${countdown}s \u540E\u81EA\u52A8\u5237\u65B0` })
|
|
5599
5765
|
] }),
|
|
5600
5766
|
/* @__PURE__ */ jsxs12(Box12, { children: [
|
|
5601
|
-
/* @__PURE__ */
|
|
5602
|
-
/* @__PURE__ */
|
|
5603
|
-
/* @__PURE__ */
|
|
5604
|
-
/* @__PURE__ */
|
|
5605
|
-
/* @__PURE__ */
|
|
5606
|
-
/* @__PURE__ */
|
|
5607
|
-
/* @__PURE__ */
|
|
5608
|
-
/* @__PURE__ */
|
|
5609
|
-
/* @__PURE__ */
|
|
5767
|
+
/* @__PURE__ */ jsx13(Box12, { width: 3 }),
|
|
5768
|
+
/* @__PURE__ */ jsx13(Box12, { width: 9, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u4EE3\u7801" }) }),
|
|
5769
|
+
/* @__PURE__ */ jsx13(Box12, { width: 16, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u540D\u79F0" }) }),
|
|
5770
|
+
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6700\u65B0\u4EF7" }) }),
|
|
5771
|
+
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6DA8\u8DCC\u5E45" }) }),
|
|
5772
|
+
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6DA8\u8DCC\u989D" }) }),
|
|
5773
|
+
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6700\u9AD8" }) }),
|
|
5774
|
+
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6700\u4F4E" }) }),
|
|
5775
|
+
/* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6210\u4EA4\u989D" }) })
|
|
5610
5776
|
] }),
|
|
5611
|
-
/* @__PURE__ */
|
|
5612
|
-
/* @__PURE__ */
|
|
5777
|
+
/* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: " " + "\u2500".repeat(100) }) }),
|
|
5778
|
+
/* @__PURE__ */ jsx13(Box12, { flexDirection: "column", children: stocks.map((stock, index) => {
|
|
5613
5779
|
const isSelected = index === selectedIndex;
|
|
5614
5780
|
const isUp = stock.changePercent >= 0;
|
|
5615
5781
|
const color = isUp ? "#ff1493" : "#00ff41";
|
|
5616
5782
|
return /* @__PURE__ */ jsxs12(Box12, { children: [
|
|
5617
|
-
/* @__PURE__ */
|
|
5618
|
-
/* @__PURE__ */
|
|
5619
|
-
/* @__PURE__ */
|
|
5620
|
-
/* @__PURE__ */
|
|
5621
|
-
/* @__PURE__ */
|
|
5783
|
+
/* @__PURE__ */ jsx13(Box12, { width: 3, flexShrink: 0, children: isSelected ? /* @__PURE__ */ jsx13(Text14, { bold: true, ...cp2("#00ffff"), children: "\u25B8 " }) : /* @__PURE__ */ jsx13(Text14, { children: " " }) }),
|
|
5784
|
+
/* @__PURE__ */ jsx13(Box12, { width: 9, children: /* @__PURE__ */ jsx13(Text14, { bold: true, ...cp2(isSelected ? "#00ffff" : "#ffffff"), children: stock.code }) }),
|
|
5785
|
+
/* @__PURE__ */ jsx13(Box12, { width: 16, children: /* @__PURE__ */ jsx13(Text14, { ...cp2(isSelected ? "#ffffff" : "#cccccc"), children: stock.name }) }),
|
|
5786
|
+
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { bold: true, ...cp2(color), children: formatPrice(stock.price) }) }),
|
|
5787
|
+
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsxs12(Text14, { ...cp2(color), children: [
|
|
5622
5788
|
isUp ? "+" : "",
|
|
5623
5789
|
stock.changePercent.toFixed(2),
|
|
5624
5790
|
"%"
|
|
5625
5791
|
] }) }),
|
|
5626
|
-
/* @__PURE__ */
|
|
5792
|
+
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsxs12(Text14, { ...cp2(color), children: [
|
|
5627
5793
|
isUp ? "+" : "",
|
|
5628
5794
|
stock.changeAmount.toFixed(3)
|
|
5629
5795
|
] }) }),
|
|
5630
|
-
/* @__PURE__ */
|
|
5631
|
-
/* @__PURE__ */
|
|
5632
|
-
/* @__PURE__ */
|
|
5796
|
+
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { ...cp2("#cccccc"), children: formatPrice(stock.high) }) }),
|
|
5797
|
+
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { ...cp2("#888888"), children: formatPrice(stock.low) }) }),
|
|
5798
|
+
/* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsx13(Text14, { ...cp2("#888888"), children: formatAmount(stock.amount) }) })
|
|
5633
5799
|
] }, stock.code);
|
|
5634
5800
|
}) }),
|
|
5635
|
-
/* @__PURE__ */
|
|
5801
|
+
/* @__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` }) }),
|
|
5636
5802
|
/* @__PURE__ */ jsxs12(Box12, { children: [
|
|
5637
|
-
/* @__PURE__ */
|
|
5638
|
-
/* @__PURE__ */
|
|
5803
|
+
/* @__PURE__ */ jsx13(Text14, { dimColor: true, children: ` \u6700\u540E\u66F4\u65B0: ${lastUpdate} \u7F16\u8F91\u81EA\u9009\u80A1: ` }),
|
|
5804
|
+
/* @__PURE__ */ jsx13(Text14, { ...cp2("#c792ea"), children: osc8Link(toFileUrl(SETTINGS_PATH), SETTINGS_PATH) })
|
|
5639
5805
|
] }),
|
|
5640
|
-
doubleCtrlC && /* @__PURE__ */
|
|
5806
|
+
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" }) })
|
|
5641
5807
|
] });
|
|
5642
5808
|
}
|
|
5643
5809
|
function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
|
|
@@ -5658,30 +5824,30 @@ function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
|
|
|
5658
5824
|
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingLeft: 1, children: [
|
|
5659
5825
|
/* @__PURE__ */ jsxs12(Box12, { marginBottom: 1, justifyContent: "space-between", children: [
|
|
5660
5826
|
/* @__PURE__ */ jsxs12(Box12, { children: [
|
|
5661
|
-
/* @__PURE__ */ jsxs12(
|
|
5827
|
+
/* @__PURE__ */ jsxs12(Text14, { bold: true, color: "#00ffff", children: [
|
|
5662
5828
|
" \u{1F4CA} ",
|
|
5663
5829
|
stock.name,
|
|
5664
5830
|
" "
|
|
5665
5831
|
] }),
|
|
5666
|
-
/* @__PURE__ */
|
|
5667
|
-
currentTime && /* @__PURE__ */ jsxs12(
|
|
5832
|
+
/* @__PURE__ */ jsx13(Text14, { dimColor: true, children: stock.code }),
|
|
5833
|
+
currentTime && /* @__PURE__ */ jsxs12(Text14, { dimColor: true, children: [
|
|
5668
5834
|
" \u{1F550} ",
|
|
5669
5835
|
currentTime
|
|
5670
5836
|
] })
|
|
5671
5837
|
] }),
|
|
5672
|
-
/* @__PURE__ */
|
|
5838
|
+
/* @__PURE__ */ jsx13(Text14, { dimColor: true, children: `${countdown}s \u540E\u5237\u65B0` })
|
|
5673
5839
|
] }),
|
|
5674
5840
|
/* @__PURE__ */ jsxs12(Box12, { children: [
|
|
5675
|
-
/* @__PURE__ */
|
|
5676
|
-
/* @__PURE__ */
|
|
5841
|
+
/* @__PURE__ */ jsx13(Box12, { width: 16, children: /* @__PURE__ */ jsx13(Text14, { bold: true, color: "#888888", children: "\u5F53\u524D\u4EF7" }) }),
|
|
5842
|
+
/* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsxs12(Text14, { bold: true, color: colorCode, children: [
|
|
5677
5843
|
arrow,
|
|
5678
5844
|
" ",
|
|
5679
5845
|
formatPrice(stock.price)
|
|
5680
5846
|
] }) })
|
|
5681
5847
|
] }),
|
|
5682
5848
|
/* @__PURE__ */ jsxs12(Box12, { children: [
|
|
5683
|
-
/* @__PURE__ */
|
|
5684
|
-
/* @__PURE__ */
|
|
5849
|
+
/* @__PURE__ */ jsx13(Box12, { width: 16, children: /* @__PURE__ */ jsx13(Text14, { color: "#888888", children: "\u6DA8\u8DCC\u5E45" }) }),
|
|
5850
|
+
/* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsxs12(Text14, { color: colorCode, children: [
|
|
5685
5851
|
isUp ? "+" : "",
|
|
5686
5852
|
stock.changePercent.toFixed(2),
|
|
5687
5853
|
"%",
|
|
@@ -5690,8 +5856,8 @@ function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
|
|
|
5690
5856
|
stock.changeAmount.toFixed(3)
|
|
5691
5857
|
] }) })
|
|
5692
5858
|
] }),
|
|
5693
|
-
chartLines.length > 0 && /* @__PURE__ */
|
|
5694
|
-
/* @__PURE__ */
|
|
5859
|
+
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)) }),
|
|
5860
|
+
/* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: " Space/q \u8FD4\u56DE\u5217\u8868" }) })
|
|
5695
5861
|
] });
|
|
5696
5862
|
}
|
|
5697
5863
|
|
|
@@ -5776,7 +5942,7 @@ async function scanProjectFiles(baseDir, dir) {
|
|
|
5776
5942
|
}
|
|
5777
5943
|
|
|
5778
5944
|
// src/cli/index.tsx
|
|
5779
|
-
import { jsx as
|
|
5945
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
5780
5946
|
var SUBCOMMANDS = ["chat", "run", "setup", "init", "completion", "game", "stock"];
|
|
5781
5947
|
function createCli() {
|
|
5782
5948
|
const program2 = new Command();
|
|
@@ -5822,7 +5988,7 @@ function createCli() {
|
|
|
5822
5988
|
);
|
|
5823
5989
|
const model = defaultProvider?.model ?? "deepseek-v4-flash";
|
|
5824
5990
|
const chatApp = renderApp(
|
|
5825
|
-
/* @__PURE__ */
|
|
5991
|
+
/* @__PURE__ */ jsx14(
|
|
5826
5992
|
ChatSession,
|
|
5827
5993
|
{
|
|
5828
5994
|
skillCount,
|
|
@@ -5840,7 +6006,7 @@ function createCli() {
|
|
|
5840
6006
|
initGames();
|
|
5841
6007
|
const games = listGames();
|
|
5842
6008
|
const { unmount } = render4(
|
|
5843
|
-
/* @__PURE__ */
|
|
6009
|
+
/* @__PURE__ */ jsx14(
|
|
5844
6010
|
GamePicker,
|
|
5845
6011
|
{
|
|
5846
6012
|
games,
|
|
@@ -5864,7 +6030,7 @@ function createCli() {
|
|
|
5864
6030
|
setImmediate(() => {
|
|
5865
6031
|
const defaultStockCodes = ctx?.config.stock?.symbols?.map((s) => s.code) ?? ["sh000001", "sz399006", "sh601688"];
|
|
5866
6032
|
const stockApp = renderApp(
|
|
5867
|
-
/* @__PURE__ */
|
|
6033
|
+
/* @__PURE__ */ jsx14(
|
|
5868
6034
|
StockList,
|
|
5869
6035
|
{
|
|
5870
6036
|
codes: defaultStockCodes,
|
|
@@ -5951,7 +6117,7 @@ compdef _dskcode_completion dskcode`);
|
|
|
5951
6117
|
const freshResult = await loadAndValidate();
|
|
5952
6118
|
const codeList = codes && codes.length > 0 ? codes : freshResult.config.stock?.symbols?.map((s) => s.code) ?? ["sh000001", "sz399006", "sh601688"];
|
|
5953
6119
|
const app = renderApp(
|
|
5954
|
-
/* @__PURE__ */
|
|
6120
|
+
/* @__PURE__ */ jsx14(
|
|
5955
6121
|
StockList,
|
|
5956
6122
|
{
|
|
5957
6123
|
codes: codeList,
|
|
@@ -5980,7 +6146,7 @@ compdef _dskcode_completion dskcode`);
|
|
|
5980
6146
|
}
|
|
5981
6147
|
const selectedGame = await new Promise((resolve2) => {
|
|
5982
6148
|
const { unmount } = render4(
|
|
5983
|
-
/* @__PURE__ */
|
|
6149
|
+
/* @__PURE__ */ jsx14(
|
|
5984
6150
|
GamePicker,
|
|
5985
6151
|
{
|
|
5986
6152
|
games,
|