dskcode 0.1.38 → 0.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +990 -233
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -805,9 +805,9 @@ var LOGO_LINES = [
|
|
|
805
805
|
];
|
|
806
806
|
|
|
807
807
|
// src/ui/ChatSession.tsx
|
|
808
|
-
import { Box as
|
|
808
|
+
import { Box as Box12, Text as Text13, useInput, Static } from "ink";
|
|
809
809
|
import TextInput from "ink-text-input";
|
|
810
|
-
import { useEffect as useEffect5, useState as useState5, useCallback as useCallback2, useMemo, useRef as useRef4 } from "react";
|
|
810
|
+
import { useEffect as useEffect5, useState as useState5, useCallback as useCallback2, useMemo as useMemo2, useRef as useRef4 } from "react";
|
|
811
811
|
|
|
812
812
|
// src/ui/useDoubleCtrlC.ts
|
|
813
813
|
import { useState as useState2, useCallback, useEffect as useEffect2, useRef } from "react";
|
|
@@ -838,7 +838,7 @@ function useDoubleCtrlC(onExit) {
|
|
|
838
838
|
}
|
|
839
839
|
|
|
840
840
|
// src/ui/ChatSession.tsx
|
|
841
|
-
import
|
|
841
|
+
import InkSpinner4 from "ink-spinner";
|
|
842
842
|
|
|
843
843
|
// src/ui/AssistantMessage.tsx
|
|
844
844
|
import { Box as Box5, Text as Text6 } from "ink";
|
|
@@ -1981,10 +1981,214 @@ function TodoListPanel({ items }) {
|
|
|
1981
1981
|
] });
|
|
1982
1982
|
}
|
|
1983
1983
|
|
|
1984
|
+
// src/ui/CompactionProgress.tsx
|
|
1985
|
+
import { Box as Box10, Text as Text11 } from "ink";
|
|
1986
|
+
import InkSpinner3 from "ink-spinner";
|
|
1987
|
+
import { useMemo } from "react";
|
|
1988
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1989
|
+
function estimateProgress(state) {
|
|
1990
|
+
if (state.phase === "idle") return 0;
|
|
1991
|
+
if (state.phase === "done") return 100;
|
|
1992
|
+
if (state.phase === "error") return 100;
|
|
1993
|
+
const p = state.progress;
|
|
1994
|
+
if (!p) return 5;
|
|
1995
|
+
if (p.type === "start") {
|
|
1996
|
+
return 10;
|
|
1997
|
+
}
|
|
1998
|
+
if (p.type === "summary_delta") {
|
|
1999
|
+
const ratio = Math.min(p.totalSoFar.length / 800, 1);
|
|
2000
|
+
return Math.min(10 + ratio * 80, 90);
|
|
2001
|
+
}
|
|
2002
|
+
if (p.type === "fallback") {
|
|
2003
|
+
return 95;
|
|
2004
|
+
}
|
|
2005
|
+
return 5;
|
|
2006
|
+
}
|
|
2007
|
+
function phaseLabel(state) {
|
|
2008
|
+
if (state.phase === "error") {
|
|
2009
|
+
return { icon: "\u2717", text: "\u538B\u7F29\u51FA\u9519", color: "#ff6347" };
|
|
2010
|
+
}
|
|
2011
|
+
if (state.phase === "done") {
|
|
2012
|
+
if (state.strategy === "fallback") {
|
|
2013
|
+
return { icon: "\u2714", text: "\u538B\u7F29\u5B8C\u6210\uFF08\u672C\u5730\u515C\u5E95\uFF09", color: "#ff9800" };
|
|
2014
|
+
}
|
|
2015
|
+
return { icon: "\u2714", text: "\u538B\u7F29\u5B8C\u6210", color: "#00ff41" };
|
|
2016
|
+
}
|
|
2017
|
+
const p = state.progress;
|
|
2018
|
+
if (!p) {
|
|
2019
|
+
return { icon: "\u280B", text: "\u51C6\u5907\u538B\u7F29...", color: "#00ffff" };
|
|
2020
|
+
}
|
|
2021
|
+
if (p.type === "start") {
|
|
2022
|
+
return { icon: "\u280B", text: `\u51C6\u5907\u6458\u8981 ${p.droppedTurns} \u4E2A\u65E7\u56DE\u5408...`, color: "#00ffff" };
|
|
2023
|
+
}
|
|
2024
|
+
if (p.type === "summary_delta") {
|
|
2025
|
+
return { icon: "\u280B", text: "\u8C03\u7528 LLM \u751F\u6210\u6458\u8981...", color: "#00ffff" };
|
|
2026
|
+
}
|
|
2027
|
+
if (p.type === "fallback") {
|
|
2028
|
+
return { icon: "\u26A0", text: `LLM \u6458\u8981\u5931\u8D25\uFF0C\u4F7F\u7528\u672C\u5730\u515C\u5E95\uFF1A${p.reason}`, color: "#ff9800" };
|
|
2029
|
+
}
|
|
2030
|
+
return { icon: "\u280B", text: "\u538B\u7F29\u4E2D...", color: "#00ffff" };
|
|
2031
|
+
}
|
|
2032
|
+
function ProgressBar({ percent, color }) {
|
|
2033
|
+
const WIDTH = 24;
|
|
2034
|
+
const filled = Math.round(percent / 100 * WIDTH);
|
|
2035
|
+
const empty = WIDTH - filled;
|
|
2036
|
+
return /* @__PURE__ */ jsxs10(Text11, { children: [
|
|
2037
|
+
/* @__PURE__ */ jsx10(Text11, { color, children: "\u2588".repeat(filled) }),
|
|
2038
|
+
/* @__PURE__ */ jsx10(Text11, { color: "#444444", children: "\u2591".repeat(empty) }),
|
|
2039
|
+
/* @__PURE__ */ jsxs10(Text11, { color, children: [
|
|
2040
|
+
" ",
|
|
2041
|
+
percent.toFixed(0),
|
|
2042
|
+
"%"
|
|
2043
|
+
] })
|
|
2044
|
+
] });
|
|
2045
|
+
}
|
|
2046
|
+
function PhaseSteps({ state }) {
|
|
2047
|
+
const step = (() => {
|
|
2048
|
+
if (state.phase === "idle") return 0;
|
|
2049
|
+
if (state.phase === "error") {
|
|
2050
|
+
const p2 = state.progress;
|
|
2051
|
+
if (p2?.type === "summary_delta" || p2?.type === "start") return 1;
|
|
2052
|
+
return 2;
|
|
2053
|
+
}
|
|
2054
|
+
if (state.phase === "done") return 3;
|
|
2055
|
+
const p = state.progress;
|
|
2056
|
+
if (!p || p.type === "start") return 0;
|
|
2057
|
+
if (p.type === "summary_delta") return 1;
|
|
2058
|
+
if (p.type === "fallback") return 2;
|
|
2059
|
+
return 2;
|
|
2060
|
+
})();
|
|
2061
|
+
const labels = ["\u542F\u52A8", "LLM \u6458\u8981", "\u5E94\u7528\u538B\u7F29", "\u5B8C\u6210"];
|
|
2062
|
+
return /* @__PURE__ */ jsx10(Box10, { children: labels.map((label, i) => {
|
|
2063
|
+
const isCurrent = i === step;
|
|
2064
|
+
const isDone = i < step;
|
|
2065
|
+
const marker = isDone ? "\u2713" : isCurrent ? "\u25B8" : "\xB7";
|
|
2066
|
+
const color = isDone ? "#00ff41" : isCurrent ? "#00ffff" : "#444444";
|
|
2067
|
+
return /* @__PURE__ */ jsxs10(Box10, { marginRight: 1, children: [
|
|
2068
|
+
/* @__PURE__ */ jsxs10(Text11, { color, children: [
|
|
2069
|
+
marker,
|
|
2070
|
+
" ",
|
|
2071
|
+
label
|
|
2072
|
+
] }),
|
|
2073
|
+
i < labels.length - 1 && /* @__PURE__ */ jsx10(Text11, { color: "#444444", children: " \u2192 " })
|
|
2074
|
+
] }, label);
|
|
2075
|
+
}) });
|
|
2076
|
+
}
|
|
2077
|
+
function SummaryPreview({ text, contentWidth }) {
|
|
2078
|
+
const MAX_LINES = 4;
|
|
2079
|
+
const MAX_LINE_WIDTH = Math.max(contentWidth - 6, 20);
|
|
2080
|
+
if (!text) {
|
|
2081
|
+
return /* @__PURE__ */ jsx10(Text11, { dimColor: true, children: " (\u7B49\u5F85 LLM \u8F93\u51FA...)" });
|
|
2082
|
+
}
|
|
2083
|
+
const lines = wrapByWidth2(text, MAX_LINE_WIDTH);
|
|
2084
|
+
const kept = lines.slice(-MAX_LINES);
|
|
2085
|
+
return /* @__PURE__ */ jsx10(Box10, { flexDirection: "column", children: kept.map((line, i) => /* @__PURE__ */ jsxs10(Text11, { dimColor: true, children: [
|
|
2086
|
+
" ",
|
|
2087
|
+
line
|
|
2088
|
+
] }, i)) });
|
|
2089
|
+
}
|
|
2090
|
+
function wrapByWidth2(text, maxWidth) {
|
|
2091
|
+
if (text === "") return [];
|
|
2092
|
+
if (maxWidth <= 0) return [text];
|
|
2093
|
+
const result = [];
|
|
2094
|
+
for (const para of text.split("\n")) {
|
|
2095
|
+
if (para.length === 0) {
|
|
2096
|
+
result.push("");
|
|
2097
|
+
continue;
|
|
2098
|
+
}
|
|
2099
|
+
let buf = "";
|
|
2100
|
+
let bufWidth = 0;
|
|
2101
|
+
for (const ch of para) {
|
|
2102
|
+
const cp2 = ch.codePointAt(0);
|
|
2103
|
+
const w = cp2 > 11904 ? 2 : 1;
|
|
2104
|
+
if (bufWidth + w > maxWidth && buf.length > 0) {
|
|
2105
|
+
result.push(buf);
|
|
2106
|
+
buf = ch;
|
|
2107
|
+
bufWidth = w;
|
|
2108
|
+
} else {
|
|
2109
|
+
buf += ch;
|
|
2110
|
+
bufWidth += w;
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
if (buf.length > 0) result.push(buf);
|
|
2114
|
+
}
|
|
2115
|
+
return result;
|
|
2116
|
+
}
|
|
2117
|
+
function fmtNum(n) {
|
|
2118
|
+
return n.toLocaleString();
|
|
2119
|
+
}
|
|
2120
|
+
function CompactionProgress({ state, contentWidth }) {
|
|
2121
|
+
const percent = useMemo(() => estimateProgress(state), [state]);
|
|
2122
|
+
const phase = useMemo(() => phaseLabel(state), [state]);
|
|
2123
|
+
const summaryText = state.progress?.type === "summary_delta" ? state.progress.totalSoFar : state.progress?.type === "fallback" ? state.progress.fallbackSummary : state.phase === "done" && state.strategy === "summary" ? "" : "";
|
|
2124
|
+
const finalSummary = state.phase === "done" && state.strategy === "summary" ? state.progress?.type === "summary_delta" ? state.progress.totalSoFar : "" : summaryText;
|
|
2125
|
+
const titleColor = state.phase === "error" ? "#ff6347" : "#00ffff";
|
|
2126
|
+
return /* @__PURE__ */ jsx10(Box10, { flexDirection: "column", marginTop: 1, children: /* @__PURE__ */ jsxs10(Box10, { flexDirection: "row", children: [
|
|
2127
|
+
/* @__PURE__ */ jsx10(Box10, { width: 1, backgroundColor: "#9b59b6", flexShrink: 0 }),
|
|
2128
|
+
/* @__PURE__ */ jsxs10(Box10, { flexGrow: 1, paddingLeft: 1, flexDirection: "column", children: [
|
|
2129
|
+
/* @__PURE__ */ jsxs10(Box10, { children: [
|
|
2130
|
+
/* @__PURE__ */ jsx10(Text11, { bold: true, color: titleColor, children: "\u{1F5DC} \u4E0A\u4E0B\u6587\u538B\u7F29" }),
|
|
2131
|
+
/* @__PURE__ */ jsx10(Box10, { flexGrow: 1 }),
|
|
2132
|
+
state.phase === "running" && /* @__PURE__ */ jsxs10(Text11, { color: phase.color, children: [
|
|
2133
|
+
/* @__PURE__ */ jsx10(InkSpinner3, { type: "dots" }),
|
|
2134
|
+
" ",
|
|
2135
|
+
phase.text
|
|
2136
|
+
] }),
|
|
2137
|
+
state.phase === "done" && /* @__PURE__ */ jsxs10(Text11, { color: phase.color, children: [
|
|
2138
|
+
phase.icon,
|
|
2139
|
+
" ",
|
|
2140
|
+
phase.text
|
|
2141
|
+
] }),
|
|
2142
|
+
state.phase === "error" && /* @__PURE__ */ jsxs10(Text11, { color: phase.color, children: [
|
|
2143
|
+
phase.icon,
|
|
2144
|
+
" ",
|
|
2145
|
+
phase.text
|
|
2146
|
+
] })
|
|
2147
|
+
] }),
|
|
2148
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
2149
|
+
/* @__PURE__ */ jsx10(Text11, { color: "#808080", children: "\u8FDB\u5EA6: " }),
|
|
2150
|
+
/* @__PURE__ */ jsx10(ProgressBar, { percent, color: state.phase === "error" ? "#ff6347" : phase.color })
|
|
2151
|
+
] }),
|
|
2152
|
+
/* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx10(PhaseSteps, { state }) }),
|
|
2153
|
+
(state.beforeTokens !== void 0 || state.droppedTurns !== void 0) && /* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
2154
|
+
state.droppedTurns !== void 0 && /* @__PURE__ */ jsxs10(Text11, { color: "#00ff41", children: [
|
|
2155
|
+
"\u{1F4CA} \u56DE\u5408: ",
|
|
2156
|
+
state.droppedTurns,
|
|
2157
|
+
" \u6298\u53E0 \u2192 ",
|
|
2158
|
+
state.keptTurns ?? 0,
|
|
2159
|
+
" \u4FDD\u7559"
|
|
2160
|
+
] }),
|
|
2161
|
+
state.beforeTokens !== void 0 && /* @__PURE__ */ jsxs10(Text11, { color: "#ff9800", children: [
|
|
2162
|
+
"\u{1F4E6} token: ",
|
|
2163
|
+
fmtNum(state.beforeTokens),
|
|
2164
|
+
state.afterTokens !== void 0 && /* @__PURE__ */ jsxs10(Fragment2, { children: [
|
|
2165
|
+
" \u2192 ",
|
|
2166
|
+
/* @__PURE__ */ jsx10(Text11, { color: "#00ff41", bold: true, children: fmtNum(state.afterTokens) }),
|
|
2167
|
+
/* @__PURE__ */ jsxs10(Text11, { color: "#808080", children: [
|
|
2168
|
+
" (\u8282\u7701 ",
|
|
2169
|
+
((state.beforeTokens - state.afterTokens) / Math.max(state.beforeTokens, 1) * 100).toFixed(1),
|
|
2170
|
+
"%)"
|
|
2171
|
+
] })
|
|
2172
|
+
] })
|
|
2173
|
+
] })
|
|
2174
|
+
] }),
|
|
2175
|
+
(state.phase === "running" || state.phase === "done") && finalSummary && /* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
2176
|
+
/* @__PURE__ */ jsx10(Text11, { color: "#808080", children: "\u2504\u2504\u2504 LLM \u6458\u8981\u9884\u89C8 \u2504\u2504\u2504" }),
|
|
2177
|
+
/* @__PURE__ */ jsx10(SummaryPreview, { text: finalSummary, contentWidth })
|
|
2178
|
+
] }),
|
|
2179
|
+
state.phase === "done" && state.strategy === "fallback" && /* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text11, { color: "#ff9800", children: "\u26A0 LLM \u6458\u8981\u5931\u8D25\uFF0C\u4F7F\u7528\u672C\u5730\u515C\u5E95\u6458\u8981\u3002\u538B\u7F29\u5DF2\u751F\u6548\u4F46\u6458\u8981\u8D28\u91CF\u8F83\u4F4E\u3002" }) }),
|
|
2180
|
+
state.phase === "error" && state.errorMessage && /* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: /* @__PURE__ */ jsxs10(Text11, { color: "#ff6347", children: [
|
|
2181
|
+
"\u26A0 ",
|
|
2182
|
+
state.errorMessage
|
|
2183
|
+
] }) })
|
|
2184
|
+
] })
|
|
2185
|
+
] }) });
|
|
2186
|
+
}
|
|
2187
|
+
|
|
1984
2188
|
// package.json
|
|
1985
2189
|
var package_default = {
|
|
1986
2190
|
name: "dskcode",
|
|
1987
|
-
version: "0.1.
|
|
2191
|
+
version: "0.1.40",
|
|
1988
2192
|
repository: {
|
|
1989
2193
|
type: "git",
|
|
1990
2194
|
url: "git+https://github.com/Awu12277/deepseek-agent-cli/tree/main"
|
|
@@ -2267,6 +2471,239 @@ function buildApiMessages(systemPrompt, history) {
|
|
|
2267
2471
|
];
|
|
2268
2472
|
}
|
|
2269
2473
|
|
|
2474
|
+
// src/agent/compactor.ts
|
|
2475
|
+
var DEFAULT_AUTO_COMPACT_RATIO = 0.85;
|
|
2476
|
+
var DEFAULT_PRESERVE_ROUNDS = 6;
|
|
2477
|
+
var DEFAULT_MIN_TURNS_TO_COMPACT = 8;
|
|
2478
|
+
var SUMMARY_SENTINEL = "[history-summary]";
|
|
2479
|
+
var SUMMARY_SYSTEM_PROMPT = `\u4F60\u662F\u4E00\u4E2A\u4E13\u4E1A\u7684\u5BF9\u8BDD\u6458\u8981\u52A9\u624B\u3002\u4F60\u7684\u4EFB\u52A1\u662F\u628A\u591A\u8F6E\u5BF9\u8BDD\u5386\u53F2\u538B\u7F29\u6210\u7ED3\u6784\u5316\u4E2D\u6587\u6458\u8981\u3002
|
|
2480
|
+
|
|
2481
|
+
\u6458\u8981\u5FC5\u987B\u4FDD\u7559\u4EE5\u4E0B\u4FE1\u606F\uFF08\u6309\u91CD\u8981\u6027\u6392\u5E8F\uFF09\uFF1A
|
|
2482
|
+
1. \u7528\u6237\u7684\u6838\u5FC3\u76EE\u6807\u4E0E\u6700\u7EC8\u610F\u56FE
|
|
2483
|
+
2. \u5DF2\u5B8C\u6210\u7684\u5173\u952E\u51B3\u7B56\uFF08\u5982\u9009\u4E86\u54EA\u4E2A\u65B9\u6848\u3001\u6539\u4E86\u54EA\u4E9B\u6587\u4EF6\u3001\u4E3A\u4EC0\u4E48\u8FD9\u4E48\u6539\uFF09
|
|
2484
|
+
3. \u6D89\u53CA\u7684\u5177\u4F53\u6587\u4EF6\u8DEF\u5F84\uFF08\u7EDD\u5BF9/\u76F8\u5BF9\u8DEF\u5F84\u90FD\u8981\u4FDD\u7559\uFF09
|
|
2485
|
+
4. \u51FA\u73B0\u8FC7\u7684\u9519\u8BEF\u4FE1\u606F\u4E0E\u89E3\u51B3\u65B9\u6848
|
|
2486
|
+
5. \u5C1A\u672A\u5B8C\u6210\u7684\u5DE5\u4F5C / \u5F85\u529E\u4E8B\u9879
|
|
2487
|
+
6. \u91CD\u8981\u7684\u6280\u672F\u7EA6\u675F\uFF08\u5982"\u4E0D\u80FD\u7528 XX \u5E93"\uFF09
|
|
2488
|
+
|
|
2489
|
+
\u683C\u5F0F\u8981\u6C42\uFF1A
|
|
2490
|
+
- \u7528\u7EAF\u6587\u672C\uFF0C\u4E0D\u8981 markdown \u6807\u9898\u5206\u7EA7
|
|
2491
|
+
- \u6BCF\u6761\u4FE1\u606F\u72EC\u7ACB\u6210\u884C\uFF0C\u65B9\u4FBF\u540E\u7EED\u6309\u884C\u89E3\u6790
|
|
2492
|
+
- \u603B\u957F\u5EA6\u63A7\u5236\u5728 2000 \u5B57\u4EE5\u5185
|
|
2493
|
+
- \u4E0D\u9700\u8981\u5BA2\u5957\u8BDD\u3001\u4E0D\u9700\u8981"\u4EE5\u4E0B\u662F\u6458\u8981"\u7B49\u5F00\u5934
|
|
2494
|
+
`;
|
|
2495
|
+
var PER_MESSAGE_TEXT_LIMIT = 500;
|
|
2496
|
+
var FALLBACK_USER_PREVIEW = 60;
|
|
2497
|
+
function estimateMessageTokens2(msg) {
|
|
2498
|
+
let text = msg.content;
|
|
2499
|
+
if (msg.toolCalls) {
|
|
2500
|
+
for (const tc of msg.toolCalls) {
|
|
2501
|
+
text += tc.name + tc.arguments;
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
return estimateTokens(text) + 10;
|
|
2505
|
+
}
|
|
2506
|
+
function estimateMessagesTokens(messages) {
|
|
2507
|
+
let sum = 0;
|
|
2508
|
+
for (const m of messages) sum += estimateMessageTokens2(m);
|
|
2509
|
+
return sum;
|
|
2510
|
+
}
|
|
2511
|
+
function getContextStats(messages, contextWindow) {
|
|
2512
|
+
const estimatedTokens = estimateMessagesTokens(messages);
|
|
2513
|
+
const ratio = contextWindow > 0 ? estimatedTokens / contextWindow : 0;
|
|
2514
|
+
return {
|
|
2515
|
+
messageCount: messages.length,
|
|
2516
|
+
estimatedTokens,
|
|
2517
|
+
contextWindow,
|
|
2518
|
+
ratio,
|
|
2519
|
+
headroom: contextWindow - estimatedTokens
|
|
2520
|
+
};
|
|
2521
|
+
}
|
|
2522
|
+
function shouldAutoCompact(messages, opts) {
|
|
2523
|
+
const turns = groupIntoTurns(messages);
|
|
2524
|
+
const minTurns = opts.minTurnsToCompact ?? DEFAULT_MIN_TURNS_TO_COMPACT;
|
|
2525
|
+
if (turns.length < minTurns) return false;
|
|
2526
|
+
const ratio = opts.autoCompactRatio ?? DEFAULT_AUTO_COMPACT_RATIO;
|
|
2527
|
+
const stats = getContextStats(messages, opts.contextWindow);
|
|
2528
|
+
return stats.ratio >= ratio;
|
|
2529
|
+
}
|
|
2530
|
+
function turnsToPromptText(turns) {
|
|
2531
|
+
const lines = [];
|
|
2532
|
+
for (let i = 0; i < turns.length; i++) {
|
|
2533
|
+
const turn = turns[i];
|
|
2534
|
+
lines.push(`--- \u7B2C ${i + 1} \u56DE\u5408 ---`);
|
|
2535
|
+
for (const msg of turn) {
|
|
2536
|
+
const head = `[${msg.role}]`;
|
|
2537
|
+
const body = msg.content.length > PER_MESSAGE_TEXT_LIMIT ? msg.content.slice(0, PER_MESSAGE_TEXT_LIMIT) + `\u2026(\u5DF2\u622A\u65AD,\u539F\u957F ${msg.content.length})` : msg.content;
|
|
2538
|
+
lines.push(`${head} ${body}`);
|
|
2539
|
+
if (msg.toolCalls) {
|
|
2540
|
+
for (const tc of msg.toolCalls) {
|
|
2541
|
+
lines.push(` tool_call: ${tc.name}(${tc.arguments})`);
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
}
|
|
2546
|
+
return lines.join("\n");
|
|
2547
|
+
}
|
|
2548
|
+
function fallbackSummary(turns) {
|
|
2549
|
+
const lines = ["\u3010\u672C\u5730\u6458\u8981\uFF08LLM \u8C03\u7528\u5931\u8D25\u65F6\u515C\u5E95\uFF09\u3011"];
|
|
2550
|
+
for (let i = 0; i < turns.length; i++) {
|
|
2551
|
+
const turn = turns[i];
|
|
2552
|
+
const userMsg = turn.find((m) => m.role === "user");
|
|
2553
|
+
if (userMsg) {
|
|
2554
|
+
const preview = userMsg.content.slice(0, FALLBACK_USER_PREVIEW);
|
|
2555
|
+
lines.push(`\u56DE\u5408${i + 1} \u7528\u6237: ${preview}`);
|
|
2556
|
+
}
|
|
2557
|
+
const toolNames = /* @__PURE__ */ new Set();
|
|
2558
|
+
for (const m of turn) {
|
|
2559
|
+
if (m.toolCalls) for (const tc of m.toolCalls) toolNames.add(tc.name);
|
|
2560
|
+
}
|
|
2561
|
+
if (toolNames.size > 0) {
|
|
2562
|
+
lines.push(` \u8C03\u7528\u5DE5\u5177: ${[...toolNames].join(", ")}`);
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
return lines.join("\n");
|
|
2566
|
+
}
|
|
2567
|
+
async function summarizeOldTurns(oldTurns, opts) {
|
|
2568
|
+
if (oldTurns.length === 0) return "";
|
|
2569
|
+
const promptText = turnsToPromptText(oldTurns);
|
|
2570
|
+
try {
|
|
2571
|
+
const messages = [
|
|
2572
|
+
{ role: "system", content: SUMMARY_SYSTEM_PROMPT },
|
|
2573
|
+
{
|
|
2574
|
+
role: "user",
|
|
2575
|
+
content: `\u8BF7\u628A\u4EE5\u4E0B ${oldTurns.length} \u8F6E\u5BF9\u8BDD\u5386\u53F2\u538B\u7F29\u6210\u7ED3\u6784\u5316\u6458\u8981\uFF1A
|
|
2576
|
+
|
|
2577
|
+
${promptText}`
|
|
2578
|
+
}
|
|
2579
|
+
];
|
|
2580
|
+
const stream = opts.provider.chat(messages, {
|
|
2581
|
+
...opts.signal ? { signal: opts.signal } : {},
|
|
2582
|
+
// 摘要场景压低温度,输出更稳定
|
|
2583
|
+
temperature: 0.2
|
|
2584
|
+
});
|
|
2585
|
+
let summary = "";
|
|
2586
|
+
for await (const chunk of stream) {
|
|
2587
|
+
if (chunk.content) {
|
|
2588
|
+
summary += chunk.content;
|
|
2589
|
+
if (opts.onProgress) {
|
|
2590
|
+
try {
|
|
2591
|
+
opts.onProgress({
|
|
2592
|
+
type: "summary_delta",
|
|
2593
|
+
delta: chunk.content,
|
|
2594
|
+
totalSoFar: summary
|
|
2595
|
+
});
|
|
2596
|
+
} catch {
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
if (!summary.trim()) {
|
|
2602
|
+
const fb = fallbackSummary(oldTurns);
|
|
2603
|
+
if (opts.onProgress) {
|
|
2604
|
+
try {
|
|
2605
|
+
opts.onProgress({
|
|
2606
|
+
type: "fallback",
|
|
2607
|
+
reason: "LLM \u8FD4\u56DE\u7A7A\u5B57\u7B26\u4E32",
|
|
2608
|
+
fallbackSummary: fb
|
|
2609
|
+
});
|
|
2610
|
+
} catch {
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
return fb;
|
|
2614
|
+
}
|
|
2615
|
+
return summary.trim();
|
|
2616
|
+
} catch (err) {
|
|
2617
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
2618
|
+
const fb = fallbackSummary(oldTurns);
|
|
2619
|
+
if (opts.onProgress) {
|
|
2620
|
+
try {
|
|
2621
|
+
opts.onProgress({
|
|
2622
|
+
type: "fallback",
|
|
2623
|
+
reason: errMsg,
|
|
2624
|
+
fallbackSummary: fb
|
|
2625
|
+
});
|
|
2626
|
+
} catch {
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
return fb;
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
function buildSummaryMessage(summary) {
|
|
2633
|
+
return {
|
|
2634
|
+
role: "system",
|
|
2635
|
+
content: `${SUMMARY_SENTINEL}
|
|
2636
|
+
${summary}`
|
|
2637
|
+
};
|
|
2638
|
+
}
|
|
2639
|
+
async function compactContext(messages, opts) {
|
|
2640
|
+
const beforeTokens = estimateMessagesTokens(messages);
|
|
2641
|
+
const turns = groupIntoTurns(messages);
|
|
2642
|
+
const minTurns = opts.minTurnsToCompact ?? DEFAULT_MIN_TURNS_TO_COMPACT;
|
|
2643
|
+
const preserveRounds = opts.preserveRecentRounds ?? DEFAULT_PRESERVE_ROUNDS;
|
|
2644
|
+
if (turns.length < minTurns) {
|
|
2645
|
+
return {
|
|
2646
|
+
messages: messages.slice(),
|
|
2647
|
+
summary: "",
|
|
2648
|
+
droppedTurns: 0,
|
|
2649
|
+
keptTurns: turns.length,
|
|
2650
|
+
beforeTokens,
|
|
2651
|
+
afterTokens: beforeTokens
|
|
2652
|
+
};
|
|
2653
|
+
}
|
|
2654
|
+
if (turns.length <= preserveRounds) {
|
|
2655
|
+
return {
|
|
2656
|
+
messages: messages.slice(),
|
|
2657
|
+
summary: "",
|
|
2658
|
+
droppedTurns: 0,
|
|
2659
|
+
keptTurns: turns.length,
|
|
2660
|
+
beforeTokens,
|
|
2661
|
+
afterTokens: beforeTokens
|
|
2662
|
+
};
|
|
2663
|
+
}
|
|
2664
|
+
const splitAt = turns.length - preserveRounds;
|
|
2665
|
+
const oldTurns = turns.slice(0, splitAt);
|
|
2666
|
+
const keptTurns = turns.slice(splitAt);
|
|
2667
|
+
if (opts.onProgress) {
|
|
2668
|
+
try {
|
|
2669
|
+
opts.onProgress({
|
|
2670
|
+
type: "start",
|
|
2671
|
+
droppedTurns: oldTurns.length,
|
|
2672
|
+
beforeTokens
|
|
2673
|
+
});
|
|
2674
|
+
} catch {
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
const summary = await summarizeOldTurns(oldTurns, opts);
|
|
2678
|
+
const newMessages = [buildSummaryMessage(summary)];
|
|
2679
|
+
for (const turn of keptTurns) {
|
|
2680
|
+
for (const msg of turn) {
|
|
2681
|
+
newMessages.push(msg);
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
const afterTokens = estimateMessagesTokens(newMessages);
|
|
2685
|
+
if (opts.onProgress) {
|
|
2686
|
+
try {
|
|
2687
|
+
opts.onProgress({
|
|
2688
|
+
type: "done",
|
|
2689
|
+
droppedTurns: oldTurns.length,
|
|
2690
|
+
keptTurns: keptTurns.length,
|
|
2691
|
+
beforeTokens,
|
|
2692
|
+
afterTokens
|
|
2693
|
+
});
|
|
2694
|
+
} catch {
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
return {
|
|
2698
|
+
messages: newMessages,
|
|
2699
|
+
summary,
|
|
2700
|
+
droppedTurns: oldTurns.length,
|
|
2701
|
+
keptTurns: keptTurns.length,
|
|
2702
|
+
beforeTokens,
|
|
2703
|
+
afterTokens
|
|
2704
|
+
};
|
|
2705
|
+
}
|
|
2706
|
+
|
|
2270
2707
|
// src/tool/registry.ts
|
|
2271
2708
|
var ToolRegistry = class {
|
|
2272
2709
|
#tools = /* @__PURE__ */ new Map();
|
|
@@ -3716,13 +4153,17 @@ var Session = class _Session {
|
|
|
3716
4153
|
maxToolRounds: options?.maxToolRounds ?? 20,
|
|
3717
4154
|
reservedForOutput: options?.reservedForOutput ?? 4096,
|
|
3718
4155
|
preserveRecentRounds: options?.preserveRecentRounds ?? 10,
|
|
4156
|
+
autoCompactRatio: options?.autoCompactRatio ?? DEFAULT_AUTO_COMPACT_RATIO,
|
|
4157
|
+
preserveRecentRoundsOnCompact: options?.preserveRecentRoundsOnCompact ?? DEFAULT_PRESERVE_ROUNDS,
|
|
4158
|
+
minTurnsToCompact: options?.minTurnsToCompact ?? DEFAULT_MIN_TURNS_TO_COMPACT,
|
|
3719
4159
|
projectContext: options?.projectContext,
|
|
3720
4160
|
gate: options?.gate ?? new AlwaysAllowGate(),
|
|
3721
4161
|
writeRoots: options?.writeRoots ?? [options?.cwd ?? process.cwd()],
|
|
3722
4162
|
enableCheckpoint: options?.enableCheckpoint ?? true,
|
|
3723
4163
|
enableLog: options?.enableLog ?? true,
|
|
3724
4164
|
enableReflection: options?.enableReflection !== false,
|
|
3725
|
-
enableHarness: options?.enableHarness !== false
|
|
4165
|
+
enableHarness: options?.enableHarness !== false,
|
|
4166
|
+
enableAutoCompact: options?.enableAutoCompact !== false
|
|
3726
4167
|
};
|
|
3727
4168
|
this.#sessionId = options?.sessionId ?? SessionStore.newId();
|
|
3728
4169
|
this.#store = options?.store === false ? null : options?.store ?? new SessionStore();
|
|
@@ -3823,6 +4264,19 @@ var Session = class _Session {
|
|
|
3823
4264
|
} catch {
|
|
3824
4265
|
}
|
|
3825
4266
|
}
|
|
4267
|
+
if (this.#options.enableAutoCompact) {
|
|
4268
|
+
const compaction = await this.#maybeAutoCompact();
|
|
4269
|
+
if (compaction) {
|
|
4270
|
+
yield {
|
|
4271
|
+
type: "compaction",
|
|
4272
|
+
droppedTurns: compaction.droppedTurns,
|
|
4273
|
+
keptTurns: compaction.keptTurns,
|
|
4274
|
+
beforeTokens: compaction.beforeTokens,
|
|
4275
|
+
afterTokens: compaction.afterTokens,
|
|
4276
|
+
strategy: compaction.strategy
|
|
4277
|
+
};
|
|
4278
|
+
}
|
|
4279
|
+
}
|
|
3826
4280
|
const startTime = Date.now();
|
|
3827
4281
|
let toolRounds = 0;
|
|
3828
4282
|
const toolExecutor = this.#buildToolExecutor();
|
|
@@ -4077,6 +4531,79 @@ ${item.result.diff.patch}`;
|
|
|
4077
4531
|
this.#checkpoints.clear();
|
|
4078
4532
|
this.#lastRoundResults = null;
|
|
4079
4533
|
}
|
|
4534
|
+
// -------------------------------------------------------------------------
|
|
4535
|
+
// 上下文压缩(Compactor) — P0-1 实施
|
|
4536
|
+
// -------------------------------------------------------------------------
|
|
4537
|
+
/**
|
|
4538
|
+
* 获取当前上下文的统计信息(消息数、估算 token、占窗口比例)。
|
|
4539
|
+
* 用于 UI 状态栏展示和自动压缩阈值判断。
|
|
4540
|
+
*
|
|
4541
|
+
* @returns ContextStats;contextWindow 取自当前模型的 meta.contextWindow
|
|
4542
|
+
*
|
|
4543
|
+
* @pure 不修改任何状态
|
|
4544
|
+
*/
|
|
4545
|
+
getContextStats() {
|
|
4546
|
+
const meta = getModelMeta(this.#provider.model());
|
|
4547
|
+
return getContextStats(this.#messages, meta.contextWindow);
|
|
4548
|
+
}
|
|
4549
|
+
/**
|
|
4550
|
+
* 手动触发上下文压缩。
|
|
4551
|
+
* 与自动压缩逻辑复用同一个 compactContext();若回合数过少则返回空结果(droppedTurns=0)。
|
|
4552
|
+
* 可被 UI 的 /compact 命令调用。
|
|
4553
|
+
*
|
|
4554
|
+
* @param onProgress — 可选进度回调(UI 实时展示压缩进度)
|
|
4555
|
+
* @returns 压缩结果;droppedTurns=0 表示无实际压缩发生
|
|
4556
|
+
*
|
|
4557
|
+
* @sideEffect 可能调一次 provider.chat()(LLM 摘要);成功后改写 #messages
|
|
4558
|
+
*/
|
|
4559
|
+
async compact(onProgress) {
|
|
4560
|
+
const meta = getModelMeta(this.#provider.model());
|
|
4561
|
+
const result = await compactContext(this.#messages, {
|
|
4562
|
+
contextWindow: meta.contextWindow,
|
|
4563
|
+
autoCompactRatio: this.#options.autoCompactRatio,
|
|
4564
|
+
preserveRecentRounds: this.#options.preserveRecentRoundsOnCompact,
|
|
4565
|
+
minTurnsToCompact: this.#options.minTurnsToCompact,
|
|
4566
|
+
provider: this.#provider,
|
|
4567
|
+
signal: this.#abortController.signal,
|
|
4568
|
+
...onProgress ? { onProgress } : {}
|
|
4569
|
+
});
|
|
4570
|
+
if (result.droppedTurns > 0) {
|
|
4571
|
+
this.#messages.length = 0;
|
|
4572
|
+
for (const m of result.messages) this.#messages.push(m);
|
|
4573
|
+
this.#checkpoints.clear();
|
|
4574
|
+
this.#persist();
|
|
4575
|
+
}
|
|
4576
|
+
return result;
|
|
4577
|
+
}
|
|
4578
|
+
/**
|
|
4579
|
+
* chat() 入口调用的自动压缩检查。
|
|
4580
|
+
* 仅在 enableAutoCompact=true 且应自动压缩时执行;否则返回 null。
|
|
4581
|
+
* 策略与 compact() 相同;返回值额外补上 strategy("summary" | "fallback")供 chat 事件使用。
|
|
4582
|
+
*
|
|
4583
|
+
* @returns 压缩结果;未压缩时返回 null
|
|
4584
|
+
*
|
|
4585
|
+
* @sideEffect 同 compact()
|
|
4586
|
+
*/
|
|
4587
|
+
async #maybeAutoCompact() {
|
|
4588
|
+
const meta = getModelMeta(this.#provider.model());
|
|
4589
|
+
const opts = {
|
|
4590
|
+
contextWindow: meta.contextWindow,
|
|
4591
|
+
autoCompactRatio: this.#options.autoCompactRatio,
|
|
4592
|
+
preserveRecentRounds: this.#options.preserveRecentRoundsOnCompact,
|
|
4593
|
+
minTurnsToCompact: this.#options.minTurnsToCompact,
|
|
4594
|
+
provider: this.#provider,
|
|
4595
|
+
signal: this.#abortController.signal
|
|
4596
|
+
};
|
|
4597
|
+
if (!shouldAutoCompact(this.#messages, opts)) return null;
|
|
4598
|
+
const result = await compactContext(this.#messages, opts);
|
|
4599
|
+
if (result.droppedTurns === 0) return null;
|
|
4600
|
+
const strategy = result.summary.includes("\u672C\u5730\u6458\u8981") ? "fallback" : "summary";
|
|
4601
|
+
this.#messages.length = 0;
|
|
4602
|
+
for (const m of result.messages) this.#messages.push(m);
|
|
4603
|
+
this.#checkpoints.clear();
|
|
4604
|
+
this.#persist();
|
|
4605
|
+
return { ...result, strategy };
|
|
4606
|
+
}
|
|
4080
4607
|
/**
|
|
4081
4608
|
* 立即把当前状态写入持久化(不等 500ms debounce)。
|
|
4082
4609
|
* 用于 UI 上"立即保存"按钮或异常退出前的最后兜底。
|
|
@@ -5873,15 +6400,15 @@ var GRADIENT_ANIMATION = {
|
|
|
5873
6400
|
/** 空闲占位符动画:每帧相位步进(值越大流速越快) */
|
|
5874
6401
|
idlePhaseStep: 0.06,
|
|
5875
6402
|
/** 空闲占位符动画:帧间隔(ms) */
|
|
5876
|
-
idleInterval:
|
|
6403
|
+
idleInterval: 200,
|
|
5877
6404
|
/** 流式占位符动画:每帧相位步进 */
|
|
5878
|
-
streamingPhaseStep: 0.
|
|
6405
|
+
streamingPhaseStep: 0.2,
|
|
5879
6406
|
/** 流式占位符动画:帧间隔(ms) */
|
|
5880
|
-
streamingInterval:
|
|
6407
|
+
streamingInterval: 200,
|
|
5881
6408
|
/** 命令提示条动画:每帧相位步进 */
|
|
5882
|
-
cmdTipPhaseStep: 0.
|
|
6409
|
+
cmdTipPhaseStep: 0.2,
|
|
5883
6410
|
/** 命令提示条动画:帧间隔(ms) */
|
|
5884
|
-
cmdTipInterval:
|
|
6411
|
+
cmdTipInterval: 200
|
|
5885
6412
|
};
|
|
5886
6413
|
var SKIP_CHARS = /* @__PURE__ */ new Set([" ", "~", ".", "\u3002", "\uFF01", "\u{1F447}"]);
|
|
5887
6414
|
function lerpStopsToHex(t, stops) {
|
|
@@ -5913,9 +6440,9 @@ function joinReasoningSegments(segments) {
|
|
|
5913
6440
|
}
|
|
5914
6441
|
|
|
5915
6442
|
// src/ui/AnimatedLogo.tsx
|
|
5916
|
-
import { Box as
|
|
6443
|
+
import { Box as Box11, Text as Text12 } from "ink";
|
|
5917
6444
|
import { useEffect as useEffect4, useRef as useRef3, useState as useState4 } from "react";
|
|
5918
|
-
import { jsx as
|
|
6445
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5919
6446
|
var LOGO_LINES2 = [
|
|
5920
6447
|
" \u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2588 \u2588\u2584 \u2584\u2584",
|
|
5921
6448
|
" \u2584\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2584\u2584\u2580\u2588\u2588\u2588\u2580\u2580",
|
|
@@ -5944,14 +6471,14 @@ function AnimatedLogo({ panelWidth }) {
|
|
|
5944
6471
|
const leftClip = Math.max(0, -pos);
|
|
5945
6472
|
const rightClip = Math.max(0, pos + LOGO_WIDTH - panelWidth);
|
|
5946
6473
|
const padding = Math.max(0, pos);
|
|
5947
|
-
return /* @__PURE__ */
|
|
6474
|
+
return /* @__PURE__ */ jsx11(Box11, { flexDirection: "column", alignItems: "flex-start", children: LOGO_LINES2.map((line, i) => /* @__PURE__ */ jsxs11(Text12, { color: LOGO_COLOR, bold: true, children: [
|
|
5948
6475
|
" ".repeat(padding),
|
|
5949
6476
|
line.slice(leftClip, LOGO_WIDTH - rightClip)
|
|
5950
6477
|
] }, i)) });
|
|
5951
6478
|
}
|
|
5952
6479
|
|
|
5953
6480
|
// src/ui/ChatSession.tsx
|
|
5954
|
-
import { Fragment as
|
|
6481
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5955
6482
|
var PHASE_CONFIG = {
|
|
5956
6483
|
thinking: { icon: "\u{1F9E0}", label: "\u601D\u8003\u4E2D", color: "#ff9800" },
|
|
5957
6484
|
generating: { icon: "\u2728", label: "\u751F\u6210\u4E2D", color: "#00ff41" },
|
|
@@ -6026,6 +6553,13 @@ registerCommand("/rewind", {
|
|
|
6026
6553
|
content: "\u8BF7\u76F4\u63A5\u8F93\u5165 /rewind \u67E5\u770B\u53EF\u56DE\u9000\u7684\u68C0\u67E5\u70B9\u5217\u8868\uFF0C\u6216 /rewind <\u5E8F\u53F7> \u76F4\u63A5\u56DE\u9000\uFF081 = \u6700\u65B0\uFF0C2 = \u4E0A\u4E00\u6B21\uFF0C\u4F9D\u6B64\u7C7B\u63A8\uFF09"
|
|
6027
6554
|
})
|
|
6028
6555
|
});
|
|
6556
|
+
registerCommand("/compact", {
|
|
6557
|
+
desc: "\u538B\u7F29\u4E0A\u4E0B\u6587\uFF1A\u6458\u8981\u65E7\u56DE\u5408\u5E76\u4FDD\u7559\u6700\u8FD1 N \u8F6E",
|
|
6558
|
+
handler: () => ({
|
|
6559
|
+
kind: "text",
|
|
6560
|
+
content: "\u8BF7\u76F4\u63A5\u8F93\u5165 /compact \u624B\u52A8\u538B\u7F29\u4E0A\u4E0B\u6587\uFF08\u9700\u5F53\u524D\u4E0D\u5904\u4E8E\u751F\u6210\u4E2D\uFF09"
|
|
6561
|
+
})
|
|
6562
|
+
});
|
|
6029
6563
|
var STREAMING_PLACEHOLDERS = [
|
|
6030
6564
|
"\u8BA9\u5B50\u5F39\u98DE\u4E00\u4F1A\u513F...",
|
|
6031
6565
|
"\u9A6C\u4E0A\u5C31\u597D...",
|
|
@@ -6069,6 +6603,7 @@ function ChatSession({
|
|
|
6069
6603
|
const [balance, setBalance] = useState5(null);
|
|
6070
6604
|
const [balanceLoading, setBalanceLoading] = useState5(false);
|
|
6071
6605
|
const [todayCost, setTodayCost] = useState5(null);
|
|
6606
|
+
const [contextStats, setContextStats] = useState5(null);
|
|
6072
6607
|
const [isStreaming, setIsStreaming] = useState5(false);
|
|
6073
6608
|
const [streamingPhase, setStreamingPhase] = useState5(null);
|
|
6074
6609
|
const [streamingPlaceholder, setStreamingPlaceholder] = useState5("");
|
|
@@ -6099,7 +6634,7 @@ function ChatSession({
|
|
|
6099
6634
|
const [toolChoice, setToolChoice] = useState5(
|
|
6100
6635
|
void 0
|
|
6101
6636
|
);
|
|
6102
|
-
const sessionCost =
|
|
6637
|
+
const sessionCost = useMemo2(() => {
|
|
6103
6638
|
return displayMessages.reduce((sum, msg) => {
|
|
6104
6639
|
if (msg.assistantDetail?.cost) {
|
|
6105
6640
|
return sum + msg.assistantDetail.cost;
|
|
@@ -6128,6 +6663,12 @@ function ChatSession({
|
|
|
6128
6663
|
const [selectingModel, setSelectingModel] = useState5(false);
|
|
6129
6664
|
const [modelSelectIndex, setModelSelectIndex] = useState5(0);
|
|
6130
6665
|
const modelOptions = ["deepseek-v4-flash", "deepseek-v4-pro"];
|
|
6666
|
+
const [compactionState, setCompactionState] = useState5({
|
|
6667
|
+
phase: "idle",
|
|
6668
|
+
progress: null
|
|
6669
|
+
});
|
|
6670
|
+
const compactionSettleTimerRef = useRef4(null);
|
|
6671
|
+
const compactionStrategyRef = useRef4(void 0);
|
|
6131
6672
|
const sessionRef = useRef4(null);
|
|
6132
6673
|
const abortRef = useRef4(null);
|
|
6133
6674
|
const currentContentRef = useRef4("");
|
|
@@ -6148,7 +6689,33 @@ function ChatSession({
|
|
|
6148
6689
|
clearTimeout(rewindHintTimerRef.current);
|
|
6149
6690
|
rewindHintTimerRef.current = null;
|
|
6150
6691
|
}
|
|
6692
|
+
if (compactionSettleTimerRef.current) {
|
|
6693
|
+
clearTimeout(compactionSettleTimerRef.current);
|
|
6694
|
+
compactionSettleTimerRef.current = null;
|
|
6695
|
+
}
|
|
6696
|
+
};
|
|
6697
|
+
}, []);
|
|
6698
|
+
useEffect5(() => {
|
|
6699
|
+
const refresh = () => {
|
|
6700
|
+
const session = sessionRef.current;
|
|
6701
|
+
if (!session) {
|
|
6702
|
+
setContextStats(null);
|
|
6703
|
+
return;
|
|
6704
|
+
}
|
|
6705
|
+
try {
|
|
6706
|
+
const s = session.getContextStats();
|
|
6707
|
+
setContextStats({
|
|
6708
|
+
tokens: s.estimatedTokens,
|
|
6709
|
+
ratio: s.ratio,
|
|
6710
|
+
contextWindow: s.contextWindow
|
|
6711
|
+
});
|
|
6712
|
+
} catch {
|
|
6713
|
+
setContextStats(null);
|
|
6714
|
+
}
|
|
6151
6715
|
};
|
|
6716
|
+
refresh();
|
|
6717
|
+
const id = setInterval(refresh, 3e3);
|
|
6718
|
+
return () => clearInterval(id);
|
|
6152
6719
|
}, []);
|
|
6153
6720
|
useEffect5(() => {
|
|
6154
6721
|
if (todoHideTimerRef.current) {
|
|
@@ -6641,6 +7208,146 @@ function ChatSession({
|
|
|
6641
7208
|
setInput("");
|
|
6642
7209
|
return;
|
|
6643
7210
|
}
|
|
7211
|
+
if (cmdLower === "/compact") {
|
|
7212
|
+
if (isStreaming) {
|
|
7213
|
+
setDisplayMessages((prev) => [
|
|
7214
|
+
...prev,
|
|
7215
|
+
{ role: "user", content: trimmed },
|
|
7216
|
+
{ role: "assistant", content: "\u26A0 \u6B63\u5728\u751F\u6210\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5 /compact\u3002" }
|
|
7217
|
+
]);
|
|
7218
|
+
setInput("");
|
|
7219
|
+
return;
|
|
7220
|
+
}
|
|
7221
|
+
if (!sessionRef.current) {
|
|
7222
|
+
setDisplayMessages((prev) => [
|
|
7223
|
+
...prev,
|
|
7224
|
+
{ role: "user", content: trimmed },
|
|
7225
|
+
{ role: "assistant", content: "\u26A0 Session \u672A\u5C31\u7EEA\uFF0C\u65E0\u6CD5\u538B\u7F29\u3002" }
|
|
7226
|
+
]);
|
|
7227
|
+
setInput("");
|
|
7228
|
+
return;
|
|
7229
|
+
}
|
|
7230
|
+
setInput("");
|
|
7231
|
+
setDisplayMessages((prev) => [...prev, { role: "user", content: trimmed }]);
|
|
7232
|
+
setCompactionState({
|
|
7233
|
+
phase: "running",
|
|
7234
|
+
progress: null,
|
|
7235
|
+
beforeTokens: void 0,
|
|
7236
|
+
afterTokens: void 0,
|
|
7237
|
+
droppedTurns: void 0,
|
|
7238
|
+
keptTurns: void 0,
|
|
7239
|
+
strategy: void 0,
|
|
7240
|
+
errorMessage: void 0
|
|
7241
|
+
});
|
|
7242
|
+
try {
|
|
7243
|
+
const result = await sessionRef.current.compact(
|
|
7244
|
+
(event) => {
|
|
7245
|
+
setCompactionState((prev) => {
|
|
7246
|
+
if (event.type === "start") {
|
|
7247
|
+
return {
|
|
7248
|
+
...prev,
|
|
7249
|
+
phase: "running",
|
|
7250
|
+
progress: event,
|
|
7251
|
+
beforeTokens: event.beforeTokens,
|
|
7252
|
+
droppedTurns: event.droppedTurns
|
|
7253
|
+
};
|
|
7254
|
+
}
|
|
7255
|
+
if (event.type === "summary_delta") {
|
|
7256
|
+
return {
|
|
7257
|
+
...prev,
|
|
7258
|
+
phase: "running",
|
|
7259
|
+
progress: event
|
|
7260
|
+
};
|
|
7261
|
+
}
|
|
7262
|
+
if (event.type === "fallback") {
|
|
7263
|
+
compactionStrategyRef.current = "fallback";
|
|
7264
|
+
return {
|
|
7265
|
+
...prev,
|
|
7266
|
+
phase: "running",
|
|
7267
|
+
progress: event,
|
|
7268
|
+
strategy: "fallback"
|
|
7269
|
+
};
|
|
7270
|
+
}
|
|
7271
|
+
if (event.type === "done") {
|
|
7272
|
+
const finalStrategy = compactionStrategyRef.current === "fallback" ? "fallback" : "summary";
|
|
7273
|
+
compactionStrategyRef.current = finalStrategy;
|
|
7274
|
+
return {
|
|
7275
|
+
...prev,
|
|
7276
|
+
phase: "done",
|
|
7277
|
+
progress: event,
|
|
7278
|
+
droppedTurns: event.droppedTurns,
|
|
7279
|
+
keptTurns: event.keptTurns,
|
|
7280
|
+
beforeTokens: event.beforeTokens,
|
|
7281
|
+
afterTokens: event.afterTokens,
|
|
7282
|
+
strategy: finalStrategy
|
|
7283
|
+
};
|
|
7284
|
+
}
|
|
7285
|
+
return prev;
|
|
7286
|
+
});
|
|
7287
|
+
}
|
|
7288
|
+
);
|
|
7289
|
+
if (result.droppedTurns === 0) {
|
|
7290
|
+
setCompactionState((prev) => ({
|
|
7291
|
+
...prev,
|
|
7292
|
+
phase: "done",
|
|
7293
|
+
progress: prev.progress,
|
|
7294
|
+
droppedTurns: 0,
|
|
7295
|
+
keptTurns: result.keptTurns,
|
|
7296
|
+
beforeTokens: result.beforeTokens,
|
|
7297
|
+
afterTokens: result.afterTokens,
|
|
7298
|
+
strategy: void 0
|
|
7299
|
+
}));
|
|
7300
|
+
if (compactionSettleTimerRef.current) {
|
|
7301
|
+
clearTimeout(compactionSettleTimerRef.current);
|
|
7302
|
+
}
|
|
7303
|
+
compactionSettleTimerRef.current = setTimeout(() => {
|
|
7304
|
+
setCompactionState({ phase: "idle", progress: null });
|
|
7305
|
+
setDisplayMessages((prev) => [
|
|
7306
|
+
...prev,
|
|
7307
|
+
{
|
|
7308
|
+
role: "assistant",
|
|
7309
|
+
content: "\u2139 \u5F53\u524D\u5BF9\u8BDD\u592A\u77ED\uFF0C\u65E0\u9700\u538B\u7F29\uFF08\u5C11\u4E8E\u6700\u5C0F\u56DE\u5408\u6570 \u6216 \u90FD\u5728\u4FDD\u7559\u533A\u5185\uFF09\u3002"
|
|
7310
|
+
}
|
|
7311
|
+
]);
|
|
7312
|
+
}, 2500);
|
|
7313
|
+
} else {
|
|
7314
|
+
if (compactionSettleTimerRef.current) {
|
|
7315
|
+
clearTimeout(compactionSettleTimerRef.current);
|
|
7316
|
+
}
|
|
7317
|
+
compactionSettleTimerRef.current = setTimeout(() => {
|
|
7318
|
+
const ratioSaved = ((result.beforeTokens - result.afterTokens) / Math.max(result.beforeTokens, 1) * 100).toFixed(1);
|
|
7319
|
+
const strategyNote = compactionStrategyRef.current === "fallback" ? "\n\u26A0 \u6458\u8981\u4E3A\u672C\u5730\u5151\u5E95\uFF08LLM \u4E0D\u53EF\u7528\uFF09" : "";
|
|
7320
|
+
setCompactionState({ phase: "idle", progress: null });
|
|
7321
|
+
compactionStrategyRef.current = void 0;
|
|
7322
|
+
setDisplayMessages((prev) => [
|
|
7323
|
+
...prev,
|
|
7324
|
+
{
|
|
7325
|
+
role: "assistant",
|
|
7326
|
+
content: `\u2714 \u538B\u7F29\u5B8C\u6210\uFF1A${result.droppedTurns} \u56DE\u5408 \u2192 ${result.keptTurns} \u56DE\u5408\uFF08\u8282\u7701 ${ratioSaved}% token\uFF09${strategyNote}`
|
|
7327
|
+
}
|
|
7328
|
+
]);
|
|
7329
|
+
}, 4e3);
|
|
7330
|
+
}
|
|
7331
|
+
} catch (err) {
|
|
7332
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
7333
|
+
setCompactionState((prev) => ({
|
|
7334
|
+
...prev,
|
|
7335
|
+
phase: "error",
|
|
7336
|
+
errorMessage: msg
|
|
7337
|
+
}));
|
|
7338
|
+
if (compactionSettleTimerRef.current) {
|
|
7339
|
+
clearTimeout(compactionSettleTimerRef.current);
|
|
7340
|
+
}
|
|
7341
|
+
compactionSettleTimerRef.current = setTimeout(() => {
|
|
7342
|
+
setCompactionState({ phase: "idle", progress: null });
|
|
7343
|
+
setDisplayMessages((prev) => [
|
|
7344
|
+
...prev,
|
|
7345
|
+
{ role: "assistant", content: `\u26A0 \u538B\u7F29\u5931\u8D25\uFF1A${msg}` }
|
|
7346
|
+
]);
|
|
7347
|
+
}, 3e3);
|
|
7348
|
+
}
|
|
7349
|
+
return;
|
|
7350
|
+
}
|
|
6644
7351
|
if (cmdLower === "/model") {
|
|
6645
7352
|
const curIdx = modelOptions.indexOf(activeModel);
|
|
6646
7353
|
setModelSelectIndex(curIdx >= 0 ? curIdx : 0);
|
|
@@ -6829,6 +7536,12 @@ function ChatSession({
|
|
|
6829
7536
|
todoHideTimerRef.current = null;
|
|
6830
7537
|
}
|
|
6831
7538
|
setTodoPanelVisible(false);
|
|
7539
|
+
setCompactionState({ phase: "idle", progress: null });
|
|
7540
|
+
compactionStrategyRef.current = void 0;
|
|
7541
|
+
if (compactionSettleTimerRef.current) {
|
|
7542
|
+
clearTimeout(compactionSettleTimerRef.current);
|
|
7543
|
+
compactionSettleTimerRef.current = null;
|
|
7544
|
+
}
|
|
6832
7545
|
const session = sessionRef.current;
|
|
6833
7546
|
const abortController = new AbortController();
|
|
6834
7547
|
abortRef.current = abortController;
|
|
@@ -7002,108 +7715,104 @@ function ChatSession({
|
|
|
7002
7715
|
setTodayCost(externalCostTracker.todayTotalCost);
|
|
7003
7716
|
}
|
|
7004
7717
|
}, [isStreaming, externalCostTracker]);
|
|
7005
|
-
return /* @__PURE__ */
|
|
7006
|
-
/* @__PURE__ */
|
|
7007
|
-
/* @__PURE__ */
|
|
7008
|
-
|
|
7718
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingLeft: 1, paddingRight: 1, children: [
|
|
7719
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", flexGrow: 1, children: [
|
|
7720
|
+
/* @__PURE__ */ jsx12(
|
|
7721
|
+
Box12,
|
|
7009
7722
|
{
|
|
7010
7723
|
width: leftPanelWidth,
|
|
7011
7724
|
flexShrink: 0,
|
|
7012
7725
|
flexDirection: "column",
|
|
7013
|
-
children: /* @__PURE__ */
|
|
7014
|
-
|
|
7726
|
+
children: /* @__PURE__ */ jsx12(
|
|
7727
|
+
Box12,
|
|
7015
7728
|
{
|
|
7016
|
-
borderStyle: "single",
|
|
7017
|
-
borderColor: "#333333",
|
|
7018
7729
|
paddingX: 1,
|
|
7019
7730
|
flexDirection: "column",
|
|
7020
7731
|
flexGrow: 1,
|
|
7021
7732
|
justifyContent: !hasConversationStarted ? "center" : "flex-end",
|
|
7022
7733
|
children: !hasConversationStarted ? (
|
|
7023
7734
|
/* ===== 首页:Logo + 状态概况 ===== */
|
|
7024
|
-
/* @__PURE__ */
|
|
7735
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", alignItems: "center", children: [
|
|
7025
7736
|
LOGO_LINES.map((line, i) => {
|
|
7026
7737
|
const colorIndex = (i + offset) % CYBER_PALETTE.length;
|
|
7027
|
-
return /* @__PURE__ */
|
|
7738
|
+
return /* @__PURE__ */ jsx12(Text13, { bold: true, color: CYBER_PALETTE[colorIndex], children: line }, i);
|
|
7028
7739
|
}),
|
|
7029
|
-
/* @__PURE__ */
|
|
7740
|
+
/* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsxs12(Text13, { color: "#808080", children: [
|
|
7030
7741
|
"\u{1F4E6} v",
|
|
7031
7742
|
VERSION
|
|
7032
7743
|
] }) }),
|
|
7033
|
-
/* @__PURE__ */
|
|
7034
|
-
/* @__PURE__ */
|
|
7744
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", alignItems: "center", children: [
|
|
7745
|
+
/* @__PURE__ */ jsxs12(Text13, { color: "#00ff41", children: [
|
|
7035
7746
|
"\u2714 ",
|
|
7036
7747
|
skillCount,
|
|
7037
7748
|
" Skills"
|
|
7038
7749
|
] }),
|
|
7039
|
-
/* @__PURE__ */
|
|
7750
|
+
/* @__PURE__ */ jsxs12(Text13, { color: "#00ffff", children: [
|
|
7040
7751
|
"\u2139 ",
|
|
7041
7752
|
toolCount,
|
|
7042
7753
|
" \u5DE5\u5177"
|
|
7043
7754
|
] }),
|
|
7044
|
-
/* @__PURE__ */
|
|
7755
|
+
/* @__PURE__ */ jsxs12(Text13, { color: "#00ffff", children: [
|
|
7045
7756
|
"\u{1F527} ",
|
|
7046
7757
|
SUPPORTED_MODELS[activeModel]?.displayName ?? activeModel
|
|
7047
7758
|
] }),
|
|
7048
|
-
thinkingEnabled && /* @__PURE__ */
|
|
7759
|
+
thinkingEnabled && /* @__PURE__ */ jsxs12(Text13, { color: "#ff9800", children: [
|
|
7049
7760
|
"\u{1F9E0} \u6DF1\u5EA6\u601D\u8003 ",
|
|
7050
7761
|
thinkingEffort === "max" ? "Max" : "High"
|
|
7051
7762
|
] }),
|
|
7052
|
-
sessionMode === "plan" && /* @__PURE__ */
|
|
7763
|
+
sessionMode === "plan" && /* @__PURE__ */ jsx12(Text13, { color: "#ff69b4", bold: true, children: "\u{1F4CB} \u8BA1\u5212\u6A21\u5F0F" })
|
|
7053
7764
|
] }),
|
|
7054
|
-
/* @__PURE__ */
|
|
7055
|
-
balance !== null ? /* @__PURE__ */
|
|
7765
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", alignItems: "center", children: [
|
|
7766
|
+
balance !== null ? /* @__PURE__ */ jsxs12(Text13, { color: "yellow", children: [
|
|
7056
7767
|
"\u{1F4B0} \u4F59\u989D \xA5",
|
|
7057
7768
|
balance.toFixed(2)
|
|
7058
|
-
] }) : balanceLoading ? /* @__PURE__ */
|
|
7059
|
-
todayCost !== null && /* @__PURE__ */
|
|
7769
|
+
] }) : balanceLoading ? /* @__PURE__ */ jsx12(Text13, { color: "yellow", children: "\u23F3 \u67E5\u8BE2\u4F59\u989D..." }) : null,
|
|
7770
|
+
todayCost !== null && /* @__PURE__ */ jsxs12(Text13, { color: "cyan", children: [
|
|
7060
7771
|
"\u{1F4CA} \u4ECA\u65E5 \xA5",
|
|
7061
7772
|
todayCost.toFixed(2)
|
|
7062
7773
|
] })
|
|
7063
7774
|
] }),
|
|
7064
|
-
verbose && /* @__PURE__ */
|
|
7775
|
+
verbose && /* @__PURE__ */ jsx12(Text13, { color: "#ff1493", children: "\u26A1 Verbose" })
|
|
7065
7776
|
] })
|
|
7066
7777
|
) : hasReasoningPanel ? (
|
|
7067
|
-
/* =====
|
|
7068
|
-
/* @__PURE__ */
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
return kept.join("\n");
|
|
7079
|
-
})() })
|
|
7080
|
-
] })
|
|
7778
|
+
/* ===== 流式思考中(纯文本,无边框) ===== */
|
|
7779
|
+
/* @__PURE__ */ jsx12(Text13, { dimColor: true, wrap: "wrap", children: (() => {
|
|
7780
|
+
const full = joinReasoningSegments(currentReasoning);
|
|
7781
|
+
const maxContentLines = 11;
|
|
7782
|
+
const lines = full.split("\n");
|
|
7783
|
+
const kept = lines.slice(-maxContentLines);
|
|
7784
|
+
while (kept.length < maxContentLines) {
|
|
7785
|
+
kept.unshift("");
|
|
7786
|
+
}
|
|
7787
|
+
return kept.join("\n");
|
|
7788
|
+
})() })
|
|
7081
7789
|
) : (
|
|
7082
7790
|
/* ===== 对话中(无思考):会话状态面板 ===== */
|
|
7083
|
-
/* @__PURE__ */
|
|
7084
|
-
/* @__PURE__ */
|
|
7085
|
-
/* @__PURE__ */
|
|
7086
|
-
/* @__PURE__ */
|
|
7791
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", alignItems: "center", children: [
|
|
7792
|
+
/* @__PURE__ */ jsx12(Text13, { color: "#00ffff", bold: true, children: "\u{1F4AC} \u5BF9\u8BDD\u8FDB\u884C\u4E2D" }),
|
|
7793
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", alignItems: "center", children: [
|
|
7794
|
+
/* @__PURE__ */ jsxs12(Text13, { color: "#00ff41", children: [
|
|
7087
7795
|
"\u{1F4DD} \u6D88\u606F ",
|
|
7088
7796
|
displayMessages.length,
|
|
7089
7797
|
" \u6761"
|
|
7090
7798
|
] }),
|
|
7091
|
-
sessionCost > 0 && /* @__PURE__ */
|
|
7799
|
+
sessionCost > 0 && /* @__PURE__ */ jsxs12(Text13, { color: "cyan", children: [
|
|
7092
7800
|
"\u{1F4B0} \u4F1A\u8BDD \xA5",
|
|
7093
7801
|
sessionCost.toFixed(4)
|
|
7094
|
-
] })
|
|
7802
|
+
] }),
|
|
7803
|
+
contextStats && /* @__PURE__ */ jsx12(ContextUsageBar, { stats: contextStats })
|
|
7095
7804
|
] }),
|
|
7096
|
-
/* @__PURE__ */
|
|
7097
|
-
/* @__PURE__ */
|
|
7805
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", alignItems: "center", children: [
|
|
7806
|
+
/* @__PURE__ */ jsxs12(Text13, { color: "#808080", children: [
|
|
7098
7807
|
"\u{1F527} ",
|
|
7099
7808
|
SUPPORTED_MODELS[activeModel]?.displayName ?? activeModel
|
|
7100
7809
|
] }),
|
|
7101
|
-
thinkingEnabled && /* @__PURE__ */
|
|
7810
|
+
thinkingEnabled && /* @__PURE__ */ jsxs12(Text13, { color: "#ff9800", children: [
|
|
7102
7811
|
"\u{1F9E0} ",
|
|
7103
7812
|
thinkingEffort === "max" ? "Max" : "High"
|
|
7104
7813
|
] })
|
|
7105
7814
|
] }),
|
|
7106
|
-
balance !== null && /* @__PURE__ */
|
|
7815
|
+
balance !== null && /* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsxs12(Text13, { color: "yellow", children: [
|
|
7107
7816
|
"\u{1F4B0} \xA5",
|
|
7108
7817
|
balance.toFixed(2)
|
|
7109
7818
|
] }) })
|
|
@@ -7113,47 +7822,46 @@ function ChatSession({
|
|
|
7113
7822
|
)
|
|
7114
7823
|
}
|
|
7115
7824
|
),
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
|
|
7119
|
-
!hasConversationStarted && /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", alignItems: "flex-start", flexGrow: 1, paddingBottom: 1, children: [
|
|
7825
|
+
useMemo2(() => /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", flexGrow: 1, children: [
|
|
7826
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", flexGrow: 1, children: [
|
|
7827
|
+
!hasConversationStarted && /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", alignItems: "flex-start", flexGrow: 1, paddingBottom: 1, children: [
|
|
7120
7828
|
cmdTips.length > 0 && (() => {
|
|
7121
7829
|
const tip = cmdTips[cmdTipIndex % cmdTips.length];
|
|
7122
7830
|
if (!tip) return null;
|
|
7123
7831
|
const text = `${tip.name} ${tip.desc}`;
|
|
7124
|
-
return /* @__PURE__ */
|
|
7125
|
-
/* @__PURE__ */
|
|
7126
|
-
cmdTipGradientColors.length > 0 ? text.split("").map((ch, i) => /* @__PURE__ */
|
|
7832
|
+
return /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, alignSelf: "center", children: [
|
|
7833
|
+
/* @__PURE__ */ jsx12(Text13, { color: "#808080", children: "\u{1F4A1} " }),
|
|
7834
|
+
cmdTipGradientColors.length > 0 ? text.split("").map((ch, i) => /* @__PURE__ */ jsx12(Text13, { color: cmdTipGradientColors[i] || void 0, children: ch }, i)) : /* @__PURE__ */ jsx12(Text13, { color: "#808080", children: text })
|
|
7127
7835
|
] });
|
|
7128
7836
|
})(),
|
|
7129
|
-
/* @__PURE__ */
|
|
7130
|
-
/* @__PURE__ */
|
|
7837
|
+
/* @__PURE__ */ jsx12(Box12, { flexGrow: 1 }),
|
|
7838
|
+
/* @__PURE__ */ jsx12(AnimatedLogo, { panelWidth: rightContentWidth })
|
|
7131
7839
|
] }),
|
|
7132
|
-
/* @__PURE__ */
|
|
7133
|
-
/* @__PURE__ */
|
|
7840
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginTop: 1, children: [
|
|
7841
|
+
/* @__PURE__ */ jsx12(Static, { items: displayMessages, children: (msg, i) => {
|
|
7134
7842
|
if (msg.role === "user") {
|
|
7135
|
-
return /* @__PURE__ */
|
|
7136
|
-
/* @__PURE__ */
|
|
7137
|
-
/* @__PURE__ */
|
|
7138
|
-
/* @__PURE__ */
|
|
7139
|
-
/* @__PURE__ */
|
|
7843
|
+
return /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "row", children: [
|
|
7844
|
+
/* @__PURE__ */ jsx12(Box12, { width: 1, backgroundColor: "#FF8C00", flexShrink: 0 }),
|
|
7845
|
+
/* @__PURE__ */ jsx12(Box12, { flexGrow: 1, paddingLeft: 1, children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", children: [
|
|
7846
|
+
/* @__PURE__ */ jsx12(Box12, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx12(Text13, { bold: true, color: "#FF8C00", children: "\u{1F4AC}" }) }),
|
|
7847
|
+
/* @__PURE__ */ jsx12(Box12, { flexGrow: 1, children: /* @__PURE__ */ jsx12(Text13, { wrap: "wrap", children: msg.content }) })
|
|
7140
7848
|
] }) })
|
|
7141
7849
|
] }, i);
|
|
7142
7850
|
}
|
|
7143
7851
|
if (msg.role === "tool") {
|
|
7144
|
-
return /* @__PURE__ */
|
|
7145
|
-
/* @__PURE__ */
|
|
7146
|
-
/* @__PURE__ */
|
|
7147
|
-
/* @__PURE__ */
|
|
7148
|
-
/* @__PURE__ */
|
|
7149
|
-
/* @__PURE__ */
|
|
7852
|
+
return /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "row", children: [
|
|
7853
|
+
/* @__PURE__ */ jsx12(Box12, { width: 1, backgroundColor: "#666666", flexShrink: 0 }),
|
|
7854
|
+
/* @__PURE__ */ jsxs12(Box12, { flexGrow: 1, paddingLeft: 1, flexDirection: "column", children: [
|
|
7855
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", children: [
|
|
7856
|
+
/* @__PURE__ */ jsx12(Box12, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, children: "\u{1F527}" }) }),
|
|
7857
|
+
/* @__PURE__ */ jsx12(Box12, { flexGrow: 1, children: /* @__PURE__ */ jsx12(Text13, { dimColor: true, wrap: "wrap", children: msg.content }) })
|
|
7150
7858
|
] }),
|
|
7151
|
-
msg.diff && /* @__PURE__ */
|
|
7859
|
+
msg.diff && /* @__PURE__ */ jsx12(DiffPreview, { diff: msg.diff })
|
|
7152
7860
|
] })
|
|
7153
7861
|
] }, i);
|
|
7154
7862
|
}
|
|
7155
7863
|
const detail = msg.assistantDetail;
|
|
7156
|
-
return /* @__PURE__ */
|
|
7864
|
+
return /* @__PURE__ */ jsx12(
|
|
7157
7865
|
AssistantMessage,
|
|
7158
7866
|
{
|
|
7159
7867
|
content: msg.content,
|
|
@@ -7167,7 +7875,7 @@ function ChatSession({
|
|
|
7167
7875
|
i
|
|
7168
7876
|
);
|
|
7169
7877
|
} }, staticKey),
|
|
7170
|
-
isStreaming && /* @__PURE__ */
|
|
7878
|
+
isStreaming && /* @__PURE__ */ jsx12(
|
|
7171
7879
|
AssistantMessage,
|
|
7172
7880
|
{
|
|
7173
7881
|
content: currentContent,
|
|
@@ -7178,49 +7886,56 @@ function ChatSession({
|
|
|
7178
7886
|
model: _streamingModel
|
|
7179
7887
|
}
|
|
7180
7888
|
),
|
|
7181
|
-
|
|
7889
|
+
compactionState.phase !== "idle" && /* @__PURE__ */ jsx12(
|
|
7890
|
+
CompactionProgress,
|
|
7891
|
+
{
|
|
7892
|
+
state: compactionState,
|
|
7893
|
+
contentWidth: rightContentWidth
|
|
7894
|
+
}
|
|
7895
|
+
),
|
|
7896
|
+
!isStreaming && streamError && /* @__PURE__ */ jsx12(Box12, { marginTop: 1, marginLeft: 3, children: /* @__PURE__ */ jsxs12(Text13, { color: "red", children: [
|
|
7182
7897
|
"\u26A0 ",
|
|
7183
7898
|
streamError
|
|
7184
7899
|
] }) })
|
|
7185
7900
|
] }),
|
|
7186
|
-
todoPanelVisible && todoSnapshot.length > 0 && /* @__PURE__ */
|
|
7901
|
+
todoPanelVisible && todoSnapshot.length > 0 && /* @__PURE__ */ jsx12(TodoListPanel, { items: todoSnapshot })
|
|
7187
7902
|
] }),
|
|
7188
|
-
selectingModel ? /* @__PURE__ */
|
|
7189
|
-
/* @__PURE__ */
|
|
7190
|
-
/* @__PURE__ */
|
|
7191
|
-
/* @__PURE__ */
|
|
7903
|
+
selectingModel ? /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", children: [
|
|
7904
|
+
/* @__PURE__ */ jsx12(Text13, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(rightContentWidth) }),
|
|
7905
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginTop: 1, children: [
|
|
7906
|
+
/* @__PURE__ */ jsx12(Text13, { bold: true, color: "#00ffff", children: "\u9009\u62E9\u6A21\u578B\uFF1A" }),
|
|
7192
7907
|
modelOptions.map((id, i) => {
|
|
7193
7908
|
const meta = SUPPORTED_MODELS[id];
|
|
7194
7909
|
const isCurrent = id === activeModel;
|
|
7195
7910
|
const isSelected = i === modelSelectIndex;
|
|
7196
7911
|
const marker = isSelected ? " > " : " ";
|
|
7197
7912
|
const suffix = isCurrent ? " (\u5F53\u524D)" : "";
|
|
7198
|
-
return /* @__PURE__ */
|
|
7199
|
-
/* @__PURE__ */
|
|
7913
|
+
return /* @__PURE__ */ jsxs12(Box12, { children: [
|
|
7914
|
+
/* @__PURE__ */ jsxs12(Text13, { color: isSelected ? "#00ff41" : void 0, bold: isSelected, children: [
|
|
7200
7915
|
marker,
|
|
7201
7916
|
meta.displayName,
|
|
7202
7917
|
suffix
|
|
7203
7918
|
] }),
|
|
7204
|
-
isSelected && /* @__PURE__ */
|
|
7919
|
+
isSelected && /* @__PURE__ */ jsxs12(Text13, { color: "#808080", children: [
|
|
7205
7920
|
" \u2014 ",
|
|
7206
7921
|
id
|
|
7207
7922
|
] })
|
|
7208
7923
|
] }, id);
|
|
7209
7924
|
}),
|
|
7210
|
-
/* @__PURE__ */
|
|
7925
|
+
/* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text13, { color: "#808080", dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Enter \u786E\u8BA4 \xB7 Esc \u53D6\u6D88" }) })
|
|
7211
7926
|
] }),
|
|
7212
|
-
/* @__PURE__ */
|
|
7213
|
-
] }) : rewindSelecting ? /* @__PURE__ */
|
|
7214
|
-
/* @__PURE__ */
|
|
7215
|
-
/* @__PURE__ */
|
|
7216
|
-
/* @__PURE__ */
|
|
7927
|
+
/* @__PURE__ */ jsx12(Text13, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(rightContentWidth) })
|
|
7928
|
+
] }) : rewindSelecting ? /* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", children: [
|
|
7929
|
+
/* @__PURE__ */ jsx12(Text13, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(rightContentWidth) }),
|
|
7930
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginTop: 1, children: [
|
|
7931
|
+
/* @__PURE__ */ jsx12(Text13, { bold: true, color: "#ff9800", children: "\u9009\u62E9\u8981\u56DE\u9000\u7684\u68C0\u67E5\u70B9\uFF1A" }),
|
|
7217
7932
|
rewindList.map((cp2, i) => {
|
|
7218
7933
|
const isSelected = i === rewindSelectIndex;
|
|
7219
7934
|
const marker = isSelected ? " > " : " ";
|
|
7220
7935
|
const time = new Date(cp2.timestamp).toLocaleTimeString();
|
|
7221
7936
|
const preview = cp2.preview || "(\u7A7A)";
|
|
7222
7937
|
const tag = cp2.isGitRepo ? "" : " [\u975E git\uFF0C\u4EC5\u5BF9\u8BDD]";
|
|
7223
|
-
return /* @__PURE__ */
|
|
7938
|
+
return /* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsxs12(Text13, { color: isSelected ? "#ff9800" : void 0, bold: isSelected, children: [
|
|
7224
7939
|
marker,
|
|
7225
7940
|
"#",
|
|
7226
7941
|
i + 1,
|
|
@@ -7232,21 +7947,25 @@ function ChatSession({
|
|
|
7232
7947
|
"`"
|
|
7233
7948
|
] }) }, cp2.index);
|
|
7234
7949
|
}),
|
|
7235
|
-
/* @__PURE__ */
|
|
7950
|
+
/* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text13, { color: "#808080", dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Enter \u786E\u8BA4 \xB7 Esc \u53D6\u6D88" }) })
|
|
7236
7951
|
] }),
|
|
7237
|
-
/* @__PURE__ */
|
|
7238
|
-
] }) : /* @__PURE__ */
|
|
7239
|
-
(hasConversationStarted || sessionMode === "plan") && isStreaming && streamingPhase ? /* @__PURE__ */
|
|
7952
|
+
/* @__PURE__ */ jsx12(Text13, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(rightContentWidth) })
|
|
7953
|
+
] }) : /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
7954
|
+
(hasConversationStarted || sessionMode === "plan") && isStreaming && streamingPhase ? /* @__PURE__ */ jsx12(Box12, { marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ jsxs12(Text13, { bold: true, color: PHASE_CONFIG[streamingPhase].color, children: [
|
|
7240
7955
|
PHASE_CONFIG[streamingPhase].icon,
|
|
7241
7956
|
" ",
|
|
7242
7957
|
PHASE_CONFIG[streamingPhase].label,
|
|
7243
7958
|
" ",
|
|
7244
|
-
/* @__PURE__ */
|
|
7245
|
-
] }) }) : rewindHintPhase === "visible" ? /* @__PURE__ */
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7959
|
+
/* @__PURE__ */ jsx12(InkSpinner4, { type: "dots" })
|
|
7960
|
+
] }) }) : rewindHintPhase === "visible" ? /* @__PURE__ */ jsx12(Box12, { marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ jsx12(Text13, { color: "#808080", children: "\u21A9 /rewind 1 \u53EF\u64A4\u56DE\u672C\u6B21\u4FEE\u6539" }) }) : contextStats && contextStats.ratio > 0.85 ? /* @__PURE__ */ jsx12(Box12, { marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ jsxs12(Text13, { color: "#ff9800", children: [
|
|
7961
|
+
"\u{1F4DA} \u4E0A\u4E0B\u6587\u5DF2\u7528 ",
|
|
7962
|
+
(contextStats.ratio * 100).toFixed(0),
|
|
7963
|
+
"%\uFF0C\u8F93\u5165 /compact \u53EF\u624B\u52A8\u538B\u7F29"
|
|
7964
|
+
] }) }) : null,
|
|
7965
|
+
/* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text13, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(rightContentWidth) }) }),
|
|
7966
|
+
/* @__PURE__ */ jsxs12(Box12, { children: [
|
|
7967
|
+
/* @__PURE__ */ jsx12(Box12, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx12(Text13, { bold: true, color: "#00ff41", children: "\u26A1" }) }),
|
|
7968
|
+
/* @__PURE__ */ jsx12(Box12, { flexGrow: 1, children: !input && !isStreaming && idlePlaceholder && gradientColors.length > 0 ? /* @__PURE__ */ jsx12(Text13, { children: idlePlaceholder.split("").map((ch, i) => /* @__PURE__ */ jsx12(Text13, { color: gradientColors[i] ?? void 0, children: ch }, i)) }) : !input && isStreaming && streamingPlaceholder && streamingGradientColors.length > 0 ? /* @__PURE__ */ jsx12(Text13, { children: streamingPlaceholder.split("").map((ch, i) => /* @__PURE__ */ jsx12(Text13, { color: streamingGradientColors[i] ?? void 0, children: ch }, i)) }) : /* @__PURE__ */ jsx12(
|
|
7250
7969
|
TextInput,
|
|
7251
7970
|
{
|
|
7252
7971
|
value: input,
|
|
@@ -7257,9 +7976,9 @@ function ChatSession({
|
|
|
7257
7976
|
inputKey
|
|
7258
7977
|
) })
|
|
7259
7978
|
] }),
|
|
7260
|
-
/* @__PURE__ */
|
|
7261
|
-
/* @__PURE__ */
|
|
7262
|
-
/* @__PURE__ */
|
|
7979
|
+
/* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsx12(Text13, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(rightContentWidth) }) }),
|
|
7980
|
+
/* @__PURE__ */ jsx12(SkillSelector, { skills, input, selectedIndex: skillSelectIndex }),
|
|
7981
|
+
/* @__PURE__ */ jsx12(FileSelector, { files, input, selectedIndex: fileSelectIndex })
|
|
7263
7982
|
] })
|
|
7264
7983
|
] }), [
|
|
7265
7984
|
displayMessages,
|
|
@@ -7307,15 +8026,53 @@ function ChatSession({
|
|
|
7307
8026
|
doubleCtrlC
|
|
7308
8027
|
])
|
|
7309
8028
|
] }),
|
|
7310
|
-
doubleCtrlC && !isStreaming && /* @__PURE__ */
|
|
7311
|
-
isStreaming && /* @__PURE__ */
|
|
8029
|
+
doubleCtrlC && !isStreaming && /* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text13, { color: "#ff1493", bold: true, children: " \u26A0 \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA dskcode" }) }),
|
|
8030
|
+
isStreaming && /* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text13, { color: "yellow", dimColor: true, children: " \u63D0\u793A\uFF1A\u6309 Ctrl+C \u53D6\u6D88\u5F53\u524D\u8BF7\u6C42" }) })
|
|
8031
|
+
] });
|
|
8032
|
+
}
|
|
8033
|
+
var CONTEXT_BAR_WIDTH = 12;
|
|
8034
|
+
function classifyContextRatio(ratio) {
|
|
8035
|
+
if (ratio >= 0.85) return "danger";
|
|
8036
|
+
if (ratio >= 0.6) return "warning";
|
|
8037
|
+
return "safe";
|
|
8038
|
+
}
|
|
8039
|
+
function contextLevelColor(level) {
|
|
8040
|
+
switch (level) {
|
|
8041
|
+
case "danger":
|
|
8042
|
+
return "#ff6347";
|
|
8043
|
+
// 红色
|
|
8044
|
+
case "warning":
|
|
8045
|
+
return "#ffcc00";
|
|
8046
|
+
// 黄色
|
|
8047
|
+
case "safe":
|
|
8048
|
+
return "#00ff41";
|
|
8049
|
+
}
|
|
8050
|
+
}
|
|
8051
|
+
function ContextUsageBar({
|
|
8052
|
+
stats
|
|
8053
|
+
}) {
|
|
8054
|
+
const level = classifyContextRatio(stats.ratio);
|
|
8055
|
+
const color = contextLevelColor(level);
|
|
8056
|
+
const filled = Math.min(
|
|
8057
|
+
CONTEXT_BAR_WIDTH,
|
|
8058
|
+
// 只要 ratio > 0 就至少 1 格 █,避免“占用极少”时空条被误读为“未使用”
|
|
8059
|
+
Math.max(stats.ratio > 0 ? 1 : 0, Math.round(stats.ratio * CONTEXT_BAR_WIDTH))
|
|
8060
|
+
);
|
|
8061
|
+
const empty = CONTEXT_BAR_WIDTH - filled;
|
|
8062
|
+
return /* @__PURE__ */ jsxs12(Text13, { color, children: [
|
|
8063
|
+
"\u{1F4DA} ",
|
|
8064
|
+
/* @__PURE__ */ jsx12(Text13, { color, children: "\u2588".repeat(filled) }),
|
|
8065
|
+
/* @__PURE__ */ jsx12(Text13, { color: "#444444", children: "\u2591".repeat(empty) }),
|
|
8066
|
+
" ",
|
|
8067
|
+
(stats.ratio * 100).toFixed(1),
|
|
8068
|
+
"%"
|
|
7312
8069
|
] });
|
|
7313
8070
|
}
|
|
7314
8071
|
|
|
7315
8072
|
// src/ui/GamePicker.tsx
|
|
7316
|
-
import { Box as
|
|
8073
|
+
import { Box as Box13, Text as Text14, useInput as useInput2 } from "ink";
|
|
7317
8074
|
import { useState as useState6, useCallback as useCallback3 } from "react";
|
|
7318
|
-
import { jsx as
|
|
8075
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
7319
8076
|
function GamePicker({ games, onSelect, onExit, onBackToChat }) {
|
|
7320
8077
|
const [selectedIndex, setSelectedIndex] = useState6(0);
|
|
7321
8078
|
const exitAction = onBackToChat ?? onExit ?? (() => process.exit(0));
|
|
@@ -7343,18 +8100,18 @@ function GamePicker({ games, onSelect, onExit, onBackToChat }) {
|
|
|
7343
8100
|
[games, selectedIndex, onSelect, onExit, onBackToChat, handleCtrlC]
|
|
7344
8101
|
)
|
|
7345
8102
|
);
|
|
7346
|
-
return /* @__PURE__ */
|
|
7347
|
-
/* @__PURE__ */
|
|
7348
|
-
/* @__PURE__ */
|
|
8103
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
|
|
8104
|
+
/* @__PURE__ */ jsx13(Box13, { marginBottom: 1, children: /* @__PURE__ */ jsx13(Text14, { bold: true, color: "#00ffff", children: "\u{1F3AE} \u6E38\u620F\u5217\u8868" }) }),
|
|
8105
|
+
/* @__PURE__ */ jsx13(Box13, { flexDirection: "column", children: games.map((game, index) => {
|
|
7349
8106
|
const isSelected = index === selectedIndex;
|
|
7350
|
-
return /* @__PURE__ */
|
|
7351
|
-
/* @__PURE__ */
|
|
7352
|
-
/* @__PURE__ */
|
|
7353
|
-
/* @__PURE__ */
|
|
8107
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", children: [
|
|
8108
|
+
/* @__PURE__ */ jsx13(Box13, { width: 3, flexShrink: 0, children: isSelected ? /* @__PURE__ */ jsx13(Text14, { bold: true, color: "#00ff41", children: "\u25B8 " }) : /* @__PURE__ */ jsx13(Text14, { children: " " }) }),
|
|
8109
|
+
/* @__PURE__ */ jsx13(Box13, { width: 20, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text14, { bold: true, color: isSelected ? "#00ff41" : "#ffffff", children: game.name }) }),
|
|
8110
|
+
/* @__PURE__ */ jsx13(Box13, { children: /* @__PURE__ */ jsx13(Text14, { color: "#888888", children: game.description }) })
|
|
7354
8111
|
] }, game.id);
|
|
7355
8112
|
}) }),
|
|
7356
|
-
/* @__PURE__ */
|
|
7357
|
-
doubleCtrlC && /* @__PURE__ */
|
|
8113
|
+
/* @__PURE__ */ jsx13(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: " \u2191/\u2193 \u9009\u62E9 Enter \u542F\u52A8 q \u8FD4\u56DE" }) }),
|
|
8114
|
+
doubleCtrlC && /* @__PURE__ */ jsx13(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text14, { color: "#ff1493", bold: true, children: " \u26A0 \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA dskcode" }) })
|
|
7358
8115
|
] });
|
|
7359
8116
|
}
|
|
7360
8117
|
|
|
@@ -7371,9 +8128,9 @@ function listGames() {
|
|
|
7371
8128
|
}
|
|
7372
8129
|
|
|
7373
8130
|
// src/game/brick-breaker/index.tsx
|
|
7374
|
-
import { Box as
|
|
8131
|
+
import { Box as Box14, Text as Text15, useInput as useInput3, render as render2 } from "ink";
|
|
7375
8132
|
import { useState as useState7, useEffect as useEffect6, useRef as useRef5, useCallback as useCallback4 } from "react";
|
|
7376
|
-
import { jsx as
|
|
8133
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
7377
8134
|
var GAME_WIDTH = 40;
|
|
7378
8135
|
var GAME_HEIGHT = 18;
|
|
7379
8136
|
var PADDLE_WIDTH = 9;
|
|
@@ -7563,49 +8320,49 @@ function BrickBreakerGame({ onExit: _onExit }) {
|
|
|
7563
8320
|
const board = buildBoard(s);
|
|
7564
8321
|
const def = getLevel(s.level);
|
|
7565
8322
|
void tick2;
|
|
7566
|
-
return /* @__PURE__ */
|
|
7567
|
-
/* @__PURE__ */
|
|
7568
|
-
/* @__PURE__ */
|
|
8323
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
|
|
8324
|
+
/* @__PURE__ */ jsxs14(Box14, { flexDirection: "row", children: [
|
|
8325
|
+
/* @__PURE__ */ jsx14(Box14, { width: 20, children: /* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7569
8326
|
"\u5173\u5361 ",
|
|
7570
8327
|
s.level,
|
|
7571
8328
|
": ",
|
|
7572
|
-
/* @__PURE__ */
|
|
8329
|
+
/* @__PURE__ */ jsx14(Text15, { color: "cyan", children: def.desc })
|
|
7573
8330
|
] }) }),
|
|
7574
|
-
/* @__PURE__ */
|
|
8331
|
+
/* @__PURE__ */ jsx14(Box14, { width: 12, children: /* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7575
8332
|
"\u5206\u6570: ",
|
|
7576
|
-
/* @__PURE__ */
|
|
8333
|
+
/* @__PURE__ */ jsx14(Text15, { color: "yellow", children: String(s.score).padStart(3, "0") })
|
|
7577
8334
|
] }) }),
|
|
7578
|
-
/* @__PURE__ */
|
|
8335
|
+
/* @__PURE__ */ jsx14(Box14, { width: 12, children: /* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7579
8336
|
"\u751F\u547D: ",
|
|
7580
|
-
/* @__PURE__ */
|
|
8337
|
+
/* @__PURE__ */ jsx14(Text15, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) })
|
|
7581
8338
|
] }) }),
|
|
7582
|
-
/* @__PURE__ */
|
|
8339
|
+
/* @__PURE__ */ jsx14(Box14, { width: 10, children: /* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7583
8340
|
"\u7816\u5757: ",
|
|
7584
|
-
/* @__PURE__ */
|
|
8341
|
+
/* @__PURE__ */ jsx14(Text15, { color: "cyan", children: aliveCount })
|
|
7585
8342
|
] }) }),
|
|
7586
|
-
/* @__PURE__ */
|
|
8343
|
+
/* @__PURE__ */ jsx14(Box14, { children: /* @__PURE__ */ jsxs14(Text15, { color: s.paused ? "gray" : "green", children: [
|
|
7587
8344
|
"[",
|
|
7588
8345
|
s.paused ? "\u6682\u505C" : "\u8FD0\u884C\u4E2D",
|
|
7589
8346
|
"]"
|
|
7590
8347
|
] }) })
|
|
7591
8348
|
] }),
|
|
7592
|
-
/* @__PURE__ */
|
|
7593
|
-
/* @__PURE__ */
|
|
8349
|
+
/* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
|
|
8350
|
+
/* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7594
8351
|
"\u250C",
|
|
7595
8352
|
"\u2500".repeat(GAME_WIDTH),
|
|
7596
8353
|
"\u2510"
|
|
7597
8354
|
] }),
|
|
7598
|
-
/* @__PURE__ */
|
|
7599
|
-
/* @__PURE__ */
|
|
8355
|
+
/* @__PURE__ */ jsx14(Text15, { children: selectingLevel ? " \x1B[90m\u9009\u62E9\u5173\u5361\u540E\u5F00\u59CB...\x1B[0m" : board }),
|
|
8356
|
+
/* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7600
8357
|
"\u2514",
|
|
7601
8358
|
"\u2500".repeat(GAME_WIDTH),
|
|
7602
8359
|
"\u2518"
|
|
7603
8360
|
] })
|
|
7604
8361
|
] }),
|
|
7605
|
-
selectingLevel && /* @__PURE__ */
|
|
7606
|
-
/* @__PURE__ */
|
|
7607
|
-
/* @__PURE__ */
|
|
7608
|
-
/* @__PURE__ */
|
|
8362
|
+
selectingLevel && /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, flexDirection: "column", children: [
|
|
8363
|
+
/* @__PURE__ */ jsx14(Text15, { bold: true, color: "yellow", children: "\u9009\u62E9\u5173\u5361" }),
|
|
8364
|
+
/* @__PURE__ */ jsx14(Box14, { flexDirection: "row", flexWrap: "wrap", children: LEVELS.map((lv, i) => /* @__PURE__ */ jsx14(Box14, { width: 22, children: /* @__PURE__ */ jsxs14(Text15, { children: [
|
|
8365
|
+
/* @__PURE__ */ jsx14(Text15, { color: initialLevel === i + 1 ? "green" : "white", children: i + 1 === 10 ? "0" : String(i + 1) }),
|
|
7609
8366
|
". ",
|
|
7610
8367
|
lv.desc,
|
|
7611
8368
|
" (",
|
|
@@ -7614,16 +8371,16 @@ function BrickBreakerGame({ onExit: _onExit }) {
|
|
|
7614
8371
|
lv.cols,
|
|
7615
8372
|
")"
|
|
7616
8373
|
] }) }, i)) }),
|
|
7617
|
-
/* @__PURE__ */
|
|
8374
|
+
/* @__PURE__ */ jsx14(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text15, { dimColor: true, children: "\u6309\u6570\u5B57\u9009\u5173 q \u9000\u51FA" }) })
|
|
7618
8375
|
] }),
|
|
7619
|
-
!selectingLevel && (s.gameOver || s.win) && /* @__PURE__ */
|
|
7620
|
-
/* @__PURE__ */
|
|
7621
|
-
/* @__PURE__ */
|
|
8376
|
+
!selectingLevel && (s.gameOver || s.win) && /* @__PURE__ */ jsxs14(Box14, { marginTop: 1, children: [
|
|
8377
|
+
/* @__PURE__ */ jsx14(Text15, { bold: true, color: s.gameOver ? "red" : "green", children: s.gameOver ? "\u6E38\u620F\u7ED3\u675F\uFF01" : "\u606D\u559C\u901A\u5173\uFF01" }),
|
|
8378
|
+
/* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7622
8379
|
" \u5206\u6570: ",
|
|
7623
|
-
/* @__PURE__ */
|
|
8380
|
+
/* @__PURE__ */ jsx14(Text15, { color: "yellow", children: s.score })
|
|
7624
8381
|
] })
|
|
7625
8382
|
] }),
|
|
7626
|
-
!selectingLevel && /* @__PURE__ */
|
|
8383
|
+
!selectingLevel && /* @__PURE__ */ jsx14(Box14, { marginTop: 1, children: s.gameOver || s.win ? /* @__PURE__ */ jsx14(Text15, { dimColor: true, children: "\u2190 \u2192 \u79FB\u52A8 r \u91CD\u5F00 l \u9009\u5173 q \u9000\u51FA" }) : /* @__PURE__ */ jsx14(Text15, { dimColor: true, children: "\u2190 \u2192 \u79FB\u52A8 p \u6682\u505C q \u9000\u51FA" }) })
|
|
7627
8384
|
] });
|
|
7628
8385
|
}
|
|
7629
8386
|
var brick_breaker_default = {
|
|
@@ -7633,7 +8390,7 @@ var brick_breaker_default = {
|
|
|
7633
8390
|
play: async () => {
|
|
7634
8391
|
await new Promise((resolve2) => {
|
|
7635
8392
|
const { unmount } = render2(
|
|
7636
|
-
/* @__PURE__ */
|
|
8393
|
+
/* @__PURE__ */ jsx14(BrickBreakerGame, { onExit: () => {
|
|
7637
8394
|
unmount();
|
|
7638
8395
|
resolve2();
|
|
7639
8396
|
} })
|
|
@@ -7643,9 +8400,9 @@ var brick_breaker_default = {
|
|
|
7643
8400
|
};
|
|
7644
8401
|
|
|
7645
8402
|
// src/game/coder-check/index.tsx
|
|
7646
|
-
import { Box as
|
|
8403
|
+
import { Box as Box15, Text as Text16, useInput as useInput4, render as render3 } from "ink";
|
|
7647
8404
|
import { useState as useState8, useEffect as useEffect7, useRef as useRef6, useCallback as useCallback5 } from "react";
|
|
7648
|
-
import { jsx as
|
|
8405
|
+
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
7649
8406
|
var GAME_W = 66;
|
|
7650
8407
|
var GAME_H = 20;
|
|
7651
8408
|
var SCORE_H = 6;
|
|
@@ -8116,44 +8873,44 @@ function CoderCheck({ onExit: _onExit }) {
|
|
|
8116
8873
|
const scoreLines = buildScoreLines(scoreStr);
|
|
8117
8874
|
const view = buildGameView(s, scoreLines, scoreColor, s.message);
|
|
8118
8875
|
void tick2;
|
|
8119
|
-
return /* @__PURE__ */
|
|
8120
|
-
/* @__PURE__ */
|
|
8876
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", paddingX: 1, children: [
|
|
8877
|
+
/* @__PURE__ */ jsx15(Box15, { flexDirection: "row", children: /* @__PURE__ */ jsxs15(Text16, { children: [
|
|
8121
8878
|
"\u751F\u547D ",
|
|
8122
|
-
/* @__PURE__ */
|
|
8879
|
+
/* @__PURE__ */ jsx15(Text16, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) }),
|
|
8123
8880
|
" ",
|
|
8124
8881
|
"\u901F\u5EA6 ",
|
|
8125
|
-
/* @__PURE__ */
|
|
8882
|
+
/* @__PURE__ */ jsxs15(Text16, { color: "cyan", children: [
|
|
8126
8883
|
"Lv.",
|
|
8127
8884
|
Math.floor(s.speed * 10)
|
|
8128
8885
|
] })
|
|
8129
8886
|
] }) }),
|
|
8130
|
-
!s.gameOver && s.target && /* @__PURE__ */
|
|
8887
|
+
!s.gameOver && s.target && /* @__PURE__ */ jsx15(Box15, { marginTop: 1, children: /* @__PURE__ */ jsxs15(Text16, { children: [
|
|
8131
8888
|
"\u6253\u5B57: ",
|
|
8132
|
-
/* @__PURE__ */
|
|
8133
|
-
/* @__PURE__ */
|
|
8889
|
+
/* @__PURE__ */ jsx15(Text16, { color: "green", children: s.typed }),
|
|
8890
|
+
/* @__PURE__ */ jsx15(Text16, { color: "white", children: s.target.slice(s.typed.length) })
|
|
8134
8891
|
] }) }),
|
|
8135
|
-
/* @__PURE__ */
|
|
8136
|
-
/* @__PURE__ */
|
|
8892
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", marginTop: 1, children: [
|
|
8893
|
+
/* @__PURE__ */ jsxs15(Text16, { children: [
|
|
8137
8894
|
"\u250C",
|
|
8138
8895
|
"\u2500".repeat(GAME_W),
|
|
8139
8896
|
"\u2510"
|
|
8140
8897
|
] }),
|
|
8141
|
-
view.map((row, i) => /* @__PURE__ */
|
|
8142
|
-
/* @__PURE__ */
|
|
8898
|
+
view.map((row, i) => /* @__PURE__ */ jsx15(Text16, { children: `\u2502${row}\u2502` }, i)),
|
|
8899
|
+
/* @__PURE__ */ jsxs15(Text16, { children: [
|
|
8143
8900
|
"\u2514",
|
|
8144
8901
|
"\u2500".repeat(GAME_W),
|
|
8145
8902
|
"\u2518"
|
|
8146
8903
|
] })
|
|
8147
8904
|
] }),
|
|
8148
|
-
s.gameOver && /* @__PURE__ */
|
|
8149
|
-
/* @__PURE__ */
|
|
8150
|
-
/* @__PURE__ */
|
|
8905
|
+
s.gameOver && /* @__PURE__ */ jsxs15(Box15, { marginTop: 1, children: [
|
|
8906
|
+
/* @__PURE__ */ jsx15(Text16, { bold: true, color: "red", children: "\u6E38\u620F\u7ED3\u675F\uFF01" }),
|
|
8907
|
+
/* @__PURE__ */ jsxs15(Text16, { children: [
|
|
8151
8908
|
" \u5F97\u5206: ",
|
|
8152
|
-
/* @__PURE__ */
|
|
8909
|
+
/* @__PURE__ */ jsx15(Text16, { color: "yellow", children: s.score }),
|
|
8153
8910
|
" r \u91CD\u5F00 q \u9000\u51FA"
|
|
8154
8911
|
] })
|
|
8155
8912
|
] }),
|
|
8156
|
-
/* @__PURE__ */
|
|
8913
|
+
/* @__PURE__ */ jsx15(Box15, { marginTop: 1, children: /* @__PURE__ */ jsx15(Text16, { dimColor: true, children: "\u6253\u5B57\u6D88\u9664\u5355\u8BCD \u7A7A\u683C/Ctrl+P\u6682\u505C Ctrl+Q\u9000\u51FA" }) })
|
|
8157
8914
|
] });
|
|
8158
8915
|
}
|
|
8159
8916
|
var coder_check_default = {
|
|
@@ -8163,7 +8920,7 @@ var coder_check_default = {
|
|
|
8163
8920
|
play: async () => {
|
|
8164
8921
|
await new Promise((resolve2) => {
|
|
8165
8922
|
const { unmount } = render3(
|
|
8166
|
-
/* @__PURE__ */
|
|
8923
|
+
/* @__PURE__ */ jsx15(CoderCheck, { onExit: () => {
|
|
8167
8924
|
unmount();
|
|
8168
8925
|
resolve2();
|
|
8169
8926
|
} })
|
|
@@ -8543,12 +9300,12 @@ import { render as render4 } from "ink";
|
|
|
8543
9300
|
import chalk5 from "chalk";
|
|
8544
9301
|
|
|
8545
9302
|
// src/stock/StockList.tsx
|
|
8546
|
-
import { Box as
|
|
8547
|
-
import { useState as useState9, useCallback as useCallback6, useEffect as useEffect8, useMemo as
|
|
9303
|
+
import { Box as Box16, Text as Text17, useInput as useInput5 } from "ink";
|
|
9304
|
+
import { useState as useState9, useCallback as useCallback6, useEffect as useEffect8, useMemo as useMemo3 } from "react";
|
|
8548
9305
|
import asciichart from "asciichart";
|
|
8549
9306
|
import os from "os";
|
|
8550
9307
|
import { join as join10 } from "path";
|
|
8551
|
-
import { jsx as
|
|
9308
|
+
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
8552
9309
|
var SETTINGS_PATH = join10(os.homedir(), ".dskcode", "settings.json");
|
|
8553
9310
|
function toFileUrl(p) {
|
|
8554
9311
|
const norm = p.replace(/\\/g, "/");
|
|
@@ -8665,7 +9422,7 @@ function StockList({ codes, onExit, onBackToChat }) {
|
|
|
8665
9422
|
);
|
|
8666
9423
|
const [dimMode, setDimMode] = useState9(false);
|
|
8667
9424
|
const [sortOrder, setSortOrder] = useState9("default");
|
|
8668
|
-
const sortedStocks =
|
|
9425
|
+
const sortedStocks = useMemo3(() => {
|
|
8669
9426
|
if (sortOrder === "default") return stocks;
|
|
8670
9427
|
return [...stocks].toSorted(
|
|
8671
9428
|
(a, b) => sortOrder === "desc" ? b.changePercent - a.changePercent : a.changePercent - b.changePercent
|
|
@@ -8767,64 +9524,64 @@ function StockList({ codes, onExit, onBackToChat }) {
|
|
|
8767
9524
|
);
|
|
8768
9525
|
if (detailView) {
|
|
8769
9526
|
if (detailLoading) {
|
|
8770
|
-
return /* @__PURE__ */
|
|
9527
|
+
return /* @__PURE__ */ jsx16(Box16, { paddingLeft: 1, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: " \u27F3 \u52A0\u8F7D\u5206\u65F6\u6570\u636E..." }) });
|
|
8771
9528
|
}
|
|
8772
9529
|
return renderDetail(detailView, () => setDetailView(null), detailPrices ?? void 0, detailCountdown, currentTime);
|
|
8773
9530
|
}
|
|
8774
9531
|
const cp2 = (c) => dimMode ? { dimColor: true } : { color: c };
|
|
8775
|
-
return /* @__PURE__ */
|
|
8776
|
-
/* @__PURE__ */
|
|
8777
|
-
/* @__PURE__ */
|
|
8778
|
-
/* @__PURE__ */
|
|
9532
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
9533
|
+
/* @__PURE__ */ jsxs16(Box16, { marginBottom: 1, justifyContent: "space-between", children: [
|
|
9534
|
+
/* @__PURE__ */ jsx16(Text17, { bold: true, ...cp2("#00ffff"), children: " \u{1F4C8} \u81EA\u9009\u80A1\u76D1\u63A7" }),
|
|
9535
|
+
/* @__PURE__ */ jsxs16(Text17, { dimColor: true, children: [
|
|
8779
9536
|
" \u{1F550} ",
|
|
8780
9537
|
currentTime
|
|
8781
9538
|
] }),
|
|
8782
|
-
/* @__PURE__ */
|
|
9539
|
+
/* @__PURE__ */ jsx16(Text17, { dimColor: true, children: loading ? " \u27F3 \u5237\u65B0\u4E2D..." : ` ${countdown}s \u540E\u81EA\u52A8\u5237\u65B0` })
|
|
8783
9540
|
] }),
|
|
8784
|
-
/* @__PURE__ */
|
|
8785
|
-
/* @__PURE__ */
|
|
8786
|
-
/* @__PURE__ */
|
|
8787
|
-
/* @__PURE__ */
|
|
8788
|
-
/* @__PURE__ */
|
|
8789
|
-
/* @__PURE__ */
|
|
9541
|
+
/* @__PURE__ */ jsxs16(Box16, { children: [
|
|
9542
|
+
/* @__PURE__ */ jsx16(Box16, { width: 3 }),
|
|
9543
|
+
/* @__PURE__ */ jsx16(Box16, { width: 9, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: "\u4EE3\u7801" }) }),
|
|
9544
|
+
/* @__PURE__ */ jsx16(Box16, { width: 16, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: "\u540D\u79F0" }) }),
|
|
9545
|
+
/* @__PURE__ */ jsx16(Box16, { width: 12, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: "\u6700\u65B0\u4EF7" }) }),
|
|
9546
|
+
/* @__PURE__ */ jsx16(Box16, { width: 12, children: /* @__PURE__ */ jsxs16(Text17, { dimColor: true, children: [
|
|
8790
9547
|
"\u6DA8\u8DCC\u5E45",
|
|
8791
9548
|
sortOrder === "desc" ? " \u25BC" : sortOrder === "asc" ? " \u25B2" : ""
|
|
8792
9549
|
] }) }),
|
|
8793
|
-
/* @__PURE__ */
|
|
8794
|
-
/* @__PURE__ */
|
|
8795
|
-
/* @__PURE__ */
|
|
8796
|
-
/* @__PURE__ */
|
|
9550
|
+
/* @__PURE__ */ jsx16(Box16, { width: 12, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: "\u6DA8\u8DCC\u989D" }) }),
|
|
9551
|
+
/* @__PURE__ */ jsx16(Box16, { width: 12, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: "\u6700\u9AD8" }) }),
|
|
9552
|
+
/* @__PURE__ */ jsx16(Box16, { width: 12, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: "\u6700\u4F4E" }) }),
|
|
9553
|
+
/* @__PURE__ */ jsx16(Box16, { children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: "\u6210\u4EA4\u989D" }) })
|
|
8797
9554
|
] }),
|
|
8798
|
-
/* @__PURE__ */
|
|
8799
|
-
/* @__PURE__ */
|
|
9555
|
+
/* @__PURE__ */ jsx16(Box16, { children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: " " + "\u2500".repeat(100) }) }),
|
|
9556
|
+
/* @__PURE__ */ jsx16(Box16, { flexDirection: "column", children: sortedStocks.map((stock, index) => {
|
|
8800
9557
|
const isSelected = index === selectedIndex;
|
|
8801
9558
|
const isUp = stock.changePercent >= 0;
|
|
8802
9559
|
const color = isUp ? "#ff1493" : "#00ff41";
|
|
8803
|
-
return /* @__PURE__ */
|
|
8804
|
-
/* @__PURE__ */
|
|
8805
|
-
/* @__PURE__ */
|
|
8806
|
-
/* @__PURE__ */
|
|
8807
|
-
/* @__PURE__ */
|
|
8808
|
-
/* @__PURE__ */
|
|
9560
|
+
return /* @__PURE__ */ jsxs16(Box16, { children: [
|
|
9561
|
+
/* @__PURE__ */ jsx16(Box16, { width: 3, flexShrink: 0, children: isSelected ? /* @__PURE__ */ jsx16(Text17, { bold: true, ...cp2("#00ffff"), children: "\u25B8 " }) : /* @__PURE__ */ jsx16(Text17, { children: " " }) }),
|
|
9562
|
+
/* @__PURE__ */ jsx16(Box16, { width: 9, children: /* @__PURE__ */ jsx16(Text17, { bold: true, ...cp2(isSelected ? "#00ffff" : "#ffffff"), children: stock.code }) }),
|
|
9563
|
+
/* @__PURE__ */ jsx16(Box16, { width: 16, children: /* @__PURE__ */ jsx16(Text17, { ...cp2(isSelected ? "#ffffff" : "#cccccc"), children: stock.name }) }),
|
|
9564
|
+
/* @__PURE__ */ jsx16(Box16, { width: 12, children: /* @__PURE__ */ jsx16(Text17, { bold: true, ...cp2(color), children: formatPrice(stock.price) }) }),
|
|
9565
|
+
/* @__PURE__ */ jsx16(Box16, { width: 12, children: /* @__PURE__ */ jsxs16(Text17, { ...cp2(color), children: [
|
|
8809
9566
|
isUp ? "+" : "",
|
|
8810
9567
|
stock.changePercent.toFixed(2),
|
|
8811
9568
|
"%"
|
|
8812
9569
|
] }) }),
|
|
8813
|
-
/* @__PURE__ */
|
|
9570
|
+
/* @__PURE__ */ jsx16(Box16, { width: 12, children: /* @__PURE__ */ jsxs16(Text17, { ...cp2(color), children: [
|
|
8814
9571
|
isUp ? "+" : "",
|
|
8815
9572
|
stock.changeAmount.toFixed(3)
|
|
8816
9573
|
] }) }),
|
|
8817
|
-
/* @__PURE__ */
|
|
8818
|
-
/* @__PURE__ */
|
|
8819
|
-
/* @__PURE__ */
|
|
9574
|
+
/* @__PURE__ */ jsx16(Box16, { width: 12, children: /* @__PURE__ */ jsx16(Text17, { ...cp2("#cccccc"), children: formatPrice(stock.high) }) }),
|
|
9575
|
+
/* @__PURE__ */ jsx16(Box16, { width: 12, children: /* @__PURE__ */ jsx16(Text17, { ...cp2("#888888"), children: formatPrice(stock.low) }) }),
|
|
9576
|
+
/* @__PURE__ */ jsx16(Box16, { children: /* @__PURE__ */ jsx16(Text17, { ...cp2("#888888"), children: formatAmount(stock.amount) }) })
|
|
8820
9577
|
] }, stock.code);
|
|
8821
9578
|
}) }),
|
|
8822
|
-
/* @__PURE__ */
|
|
8823
|
-
/* @__PURE__ */
|
|
8824
|
-
/* @__PURE__ */
|
|
8825
|
-
/* @__PURE__ */
|
|
9579
|
+
/* @__PURE__ */ jsx16(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: ` \u2191/\u2193 \u9009\u62E9 Enter \u8BE6\u60C5 r \u624B\u52A8\u5237\u65B0 o \u6392\u5E8F h \u7F6E\u7070/\u6062\u590D q \u8FD4\u56DE` }) }),
|
|
9580
|
+
/* @__PURE__ */ jsxs16(Box16, { children: [
|
|
9581
|
+
/* @__PURE__ */ jsx16(Text17, { dimColor: true, children: ` \u6700\u540E\u66F4\u65B0: ${lastUpdate} \u7F16\u8F91\u81EA\u9009\u80A1: ` }),
|
|
9582
|
+
/* @__PURE__ */ jsx16(Text17, { ...cp2("#c792ea"), children: osc8Link(toFileUrl(SETTINGS_PATH), SETTINGS_PATH) })
|
|
8826
9583
|
] }),
|
|
8827
|
-
doubleCtrlC && /* @__PURE__ */
|
|
9584
|
+
doubleCtrlC && /* @__PURE__ */ jsx16(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx16(Text17, { bold: true, ...cp2("#ff1493"), children: " \u26A0 \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA dskcode" }) })
|
|
8828
9585
|
] });
|
|
8829
9586
|
}
|
|
8830
9587
|
function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
|
|
@@ -8842,33 +9599,33 @@ function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
|
|
|
8842
9599
|
raw = raw.replaceAll("\u256D", "\u250C").replaceAll("\u256E", "\u2510").replaceAll("\u2570", "\u2514").replaceAll("\u256F", "\u2518");
|
|
8843
9600
|
chartLines = raw.split("\n");
|
|
8844
9601
|
}
|
|
8845
|
-
return /* @__PURE__ */
|
|
8846
|
-
/* @__PURE__ */
|
|
8847
|
-
/* @__PURE__ */
|
|
8848
|
-
/* @__PURE__ */
|
|
9602
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", paddingLeft: 1, children: [
|
|
9603
|
+
/* @__PURE__ */ jsxs16(Box16, { marginBottom: 1, justifyContent: "space-between", children: [
|
|
9604
|
+
/* @__PURE__ */ jsxs16(Box16, { children: [
|
|
9605
|
+
/* @__PURE__ */ jsxs16(Text17, { bold: true, color: "#00ffff", children: [
|
|
8849
9606
|
" \u{1F4CA} ",
|
|
8850
9607
|
stock.name,
|
|
8851
9608
|
" "
|
|
8852
9609
|
] }),
|
|
8853
|
-
/* @__PURE__ */
|
|
8854
|
-
currentTime && /* @__PURE__ */
|
|
9610
|
+
/* @__PURE__ */ jsx16(Text17, { dimColor: true, children: stock.code }),
|
|
9611
|
+
currentTime && /* @__PURE__ */ jsxs16(Text17, { dimColor: true, children: [
|
|
8855
9612
|
" \u{1F550} ",
|
|
8856
9613
|
currentTime
|
|
8857
9614
|
] })
|
|
8858
9615
|
] }),
|
|
8859
|
-
/* @__PURE__ */
|
|
9616
|
+
/* @__PURE__ */ jsx16(Text17, { dimColor: true, children: `${countdown}s \u540E\u5237\u65B0` })
|
|
8860
9617
|
] }),
|
|
8861
|
-
/* @__PURE__ */
|
|
8862
|
-
/* @__PURE__ */
|
|
8863
|
-
/* @__PURE__ */
|
|
9618
|
+
/* @__PURE__ */ jsxs16(Box16, { children: [
|
|
9619
|
+
/* @__PURE__ */ jsx16(Box16, { width: 16, children: /* @__PURE__ */ jsx16(Text17, { bold: true, color: "#888888", children: "\u5F53\u524D\u4EF7" }) }),
|
|
9620
|
+
/* @__PURE__ */ jsx16(Box16, { children: /* @__PURE__ */ jsxs16(Text17, { bold: true, color: colorCode, children: [
|
|
8864
9621
|
arrow,
|
|
8865
9622
|
" ",
|
|
8866
9623
|
formatPrice(stock.price)
|
|
8867
9624
|
] }) })
|
|
8868
9625
|
] }),
|
|
8869
|
-
/* @__PURE__ */
|
|
8870
|
-
/* @__PURE__ */
|
|
8871
|
-
/* @__PURE__ */
|
|
9626
|
+
/* @__PURE__ */ jsxs16(Box16, { children: [
|
|
9627
|
+
/* @__PURE__ */ jsx16(Box16, { width: 16, children: /* @__PURE__ */ jsx16(Text17, { color: "#888888", children: "\u6DA8\u8DCC\u5E45" }) }),
|
|
9628
|
+
/* @__PURE__ */ jsx16(Box16, { children: /* @__PURE__ */ jsxs16(Text17, { color: colorCode, children: [
|
|
8872
9629
|
isUp ? "+" : "",
|
|
8873
9630
|
stock.changePercent.toFixed(2),
|
|
8874
9631
|
"%",
|
|
@@ -8877,8 +9634,8 @@ function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
|
|
|
8877
9634
|
stock.changeAmount.toFixed(3)
|
|
8878
9635
|
] }) })
|
|
8879
9636
|
] }),
|
|
8880
|
-
chartLines.length > 0 && /* @__PURE__ */
|
|
8881
|
-
/* @__PURE__ */
|
|
9637
|
+
chartLines.length > 0 && /* @__PURE__ */ jsx16(Box16, { marginTop: 1, flexDirection: "column", children: chartLines.map((line, i) => /* @__PURE__ */ jsx16(Box16, { children: /* @__PURE__ */ jsx16(Text17, { color: colorCode, children: line || " " }) }, i)) }),
|
|
9638
|
+
/* @__PURE__ */ jsx16(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: " Space/q \u8FD4\u56DE\u5217\u8868" }) })
|
|
8882
9639
|
] });
|
|
8883
9640
|
}
|
|
8884
9641
|
|
|
@@ -8963,7 +9720,7 @@ async function scanProjectFiles(baseDir, dir) {
|
|
|
8963
9720
|
}
|
|
8964
9721
|
|
|
8965
9722
|
// src/cli/index.tsx
|
|
8966
|
-
import { jsx as
|
|
9723
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
8967
9724
|
var SUBCOMMANDS = ["chat", "run", "setup", "init", "completion", "game", "stock"];
|
|
8968
9725
|
function createCli() {
|
|
8969
9726
|
const program2 = new Command();
|
|
@@ -9065,7 +9822,7 @@ compdef _dskcode_completion dskcode`);
|
|
|
9065
9822
|
const freshResult = await loadAndValidate();
|
|
9066
9823
|
const codeList = codes && codes.length > 0 ? codes : freshResult.config.stock?.symbols?.map((s) => s.code) ?? ["sh000001", "sz399006", "sh601688"];
|
|
9067
9824
|
const app = renderApp(
|
|
9068
|
-
/* @__PURE__ */
|
|
9825
|
+
/* @__PURE__ */ jsx17(
|
|
9069
9826
|
StockList,
|
|
9070
9827
|
{
|
|
9071
9828
|
codes: codeList,
|
|
@@ -9094,7 +9851,7 @@ compdef _dskcode_completion dskcode`);
|
|
|
9094
9851
|
}
|
|
9095
9852
|
const selectedGame = await new Promise((resolve2) => {
|
|
9096
9853
|
const { unmount } = render4(
|
|
9097
|
-
/* @__PURE__ */
|
|
9854
|
+
/* @__PURE__ */ jsx17(
|
|
9098
9855
|
GamePicker,
|
|
9099
9856
|
{
|
|
9100
9857
|
games,
|
|
@@ -9134,7 +9891,7 @@ async function startChat(ctx, costTracker) {
|
|
|
9134
9891
|
);
|
|
9135
9892
|
const model = defaultProvider?.model ?? "deepseek-v4-flash";
|
|
9136
9893
|
const chatApp = renderApp(
|
|
9137
|
-
/* @__PURE__ */
|
|
9894
|
+
/* @__PURE__ */ jsx17(
|
|
9138
9895
|
ChatSession,
|
|
9139
9896
|
{
|
|
9140
9897
|
skillCount,
|
|
@@ -9152,7 +9909,7 @@ async function startChat(ctx, costTracker) {
|
|
|
9152
9909
|
initGames();
|
|
9153
9910
|
const games = listGames();
|
|
9154
9911
|
const { unmount } = render4(
|
|
9155
|
-
/* @__PURE__ */
|
|
9912
|
+
/* @__PURE__ */ jsx17(
|
|
9156
9913
|
GamePicker,
|
|
9157
9914
|
{
|
|
9158
9915
|
games,
|
|
@@ -9176,7 +9933,7 @@ async function startChat(ctx, costTracker) {
|
|
|
9176
9933
|
setImmediate(() => {
|
|
9177
9934
|
const defaultStockCodes = ctx?.config.stock?.symbols?.map((s) => s.code) ?? ["sh000001", "sz399006", "sh601688"];
|
|
9178
9935
|
const stockApp = renderApp(
|
|
9179
|
-
/* @__PURE__ */
|
|
9936
|
+
/* @__PURE__ */ jsx17(
|
|
9180
9937
|
StockList,
|
|
9181
9938
|
{
|
|
9182
9939
|
codes: defaultStockCodes,
|