dskcode 0.1.39 → 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 +975 -213
- 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 上"立即保存"按钮或异常退出前的最后兜底。
|
|
@@ -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,16 +7715,16 @@ 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
7729
|
paddingX: 1,
|
|
7017
7730
|
flexDirection: "column",
|
|
@@ -7019,51 +7732,51 @@ function ChatSession({
|
|
|
7019
7732
|
justifyContent: !hasConversationStarted ? "center" : "flex-end",
|
|
7020
7733
|
children: !hasConversationStarted ? (
|
|
7021
7734
|
/* ===== 首页:Logo + 状态概况 ===== */
|
|
7022
|
-
/* @__PURE__ */
|
|
7735
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", alignItems: "center", children: [
|
|
7023
7736
|
LOGO_LINES.map((line, i) => {
|
|
7024
7737
|
const colorIndex = (i + offset) % CYBER_PALETTE.length;
|
|
7025
|
-
return /* @__PURE__ */
|
|
7738
|
+
return /* @__PURE__ */ jsx12(Text13, { bold: true, color: CYBER_PALETTE[colorIndex], children: line }, i);
|
|
7026
7739
|
}),
|
|
7027
|
-
/* @__PURE__ */
|
|
7740
|
+
/* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsxs12(Text13, { color: "#808080", children: [
|
|
7028
7741
|
"\u{1F4E6} v",
|
|
7029
7742
|
VERSION
|
|
7030
7743
|
] }) }),
|
|
7031
|
-
/* @__PURE__ */
|
|
7032
|
-
/* @__PURE__ */
|
|
7744
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", alignItems: "center", children: [
|
|
7745
|
+
/* @__PURE__ */ jsxs12(Text13, { color: "#00ff41", children: [
|
|
7033
7746
|
"\u2714 ",
|
|
7034
7747
|
skillCount,
|
|
7035
7748
|
" Skills"
|
|
7036
7749
|
] }),
|
|
7037
|
-
/* @__PURE__ */
|
|
7750
|
+
/* @__PURE__ */ jsxs12(Text13, { color: "#00ffff", children: [
|
|
7038
7751
|
"\u2139 ",
|
|
7039
7752
|
toolCount,
|
|
7040
7753
|
" \u5DE5\u5177"
|
|
7041
7754
|
] }),
|
|
7042
|
-
/* @__PURE__ */
|
|
7755
|
+
/* @__PURE__ */ jsxs12(Text13, { color: "#00ffff", children: [
|
|
7043
7756
|
"\u{1F527} ",
|
|
7044
7757
|
SUPPORTED_MODELS[activeModel]?.displayName ?? activeModel
|
|
7045
7758
|
] }),
|
|
7046
|
-
thinkingEnabled && /* @__PURE__ */
|
|
7759
|
+
thinkingEnabled && /* @__PURE__ */ jsxs12(Text13, { color: "#ff9800", children: [
|
|
7047
7760
|
"\u{1F9E0} \u6DF1\u5EA6\u601D\u8003 ",
|
|
7048
7761
|
thinkingEffort === "max" ? "Max" : "High"
|
|
7049
7762
|
] }),
|
|
7050
|
-
sessionMode === "plan" && /* @__PURE__ */
|
|
7763
|
+
sessionMode === "plan" && /* @__PURE__ */ jsx12(Text13, { color: "#ff69b4", bold: true, children: "\u{1F4CB} \u8BA1\u5212\u6A21\u5F0F" })
|
|
7051
7764
|
] }),
|
|
7052
|
-
/* @__PURE__ */
|
|
7053
|
-
balance !== null ? /* @__PURE__ */
|
|
7765
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", alignItems: "center", children: [
|
|
7766
|
+
balance !== null ? /* @__PURE__ */ jsxs12(Text13, { color: "yellow", children: [
|
|
7054
7767
|
"\u{1F4B0} \u4F59\u989D \xA5",
|
|
7055
7768
|
balance.toFixed(2)
|
|
7056
|
-
] }) : balanceLoading ? /* @__PURE__ */
|
|
7057
|
-
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: [
|
|
7058
7771
|
"\u{1F4CA} \u4ECA\u65E5 \xA5",
|
|
7059
7772
|
todayCost.toFixed(2)
|
|
7060
7773
|
] })
|
|
7061
7774
|
] }),
|
|
7062
|
-
verbose && /* @__PURE__ */
|
|
7775
|
+
verbose && /* @__PURE__ */ jsx12(Text13, { color: "#ff1493", children: "\u26A1 Verbose" })
|
|
7063
7776
|
] })
|
|
7064
7777
|
) : hasReasoningPanel ? (
|
|
7065
7778
|
/* ===== 流式思考中(纯文本,无边框) ===== */
|
|
7066
|
-
/* @__PURE__ */
|
|
7779
|
+
/* @__PURE__ */ jsx12(Text13, { dimColor: true, wrap: "wrap", children: (() => {
|
|
7067
7780
|
const full = joinReasoningSegments(currentReasoning);
|
|
7068
7781
|
const maxContentLines = 11;
|
|
7069
7782
|
const lines = full.split("\n");
|
|
@@ -7075,30 +7788,31 @@ function ChatSession({
|
|
|
7075
7788
|
})() })
|
|
7076
7789
|
) : (
|
|
7077
7790
|
/* ===== 对话中(无思考):会话状态面板 ===== */
|
|
7078
|
-
/* @__PURE__ */
|
|
7079
|
-
/* @__PURE__ */
|
|
7080
|
-
/* @__PURE__ */
|
|
7081
|
-
/* @__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: [
|
|
7082
7795
|
"\u{1F4DD} \u6D88\u606F ",
|
|
7083
7796
|
displayMessages.length,
|
|
7084
7797
|
" \u6761"
|
|
7085
7798
|
] }),
|
|
7086
|
-
sessionCost > 0 && /* @__PURE__ */
|
|
7799
|
+
sessionCost > 0 && /* @__PURE__ */ jsxs12(Text13, { color: "cyan", children: [
|
|
7087
7800
|
"\u{1F4B0} \u4F1A\u8BDD \xA5",
|
|
7088
7801
|
sessionCost.toFixed(4)
|
|
7089
|
-
] })
|
|
7802
|
+
] }),
|
|
7803
|
+
contextStats && /* @__PURE__ */ jsx12(ContextUsageBar, { stats: contextStats })
|
|
7090
7804
|
] }),
|
|
7091
|
-
/* @__PURE__ */
|
|
7092
|
-
/* @__PURE__ */
|
|
7805
|
+
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", alignItems: "center", children: [
|
|
7806
|
+
/* @__PURE__ */ jsxs12(Text13, { color: "#808080", children: [
|
|
7093
7807
|
"\u{1F527} ",
|
|
7094
7808
|
SUPPORTED_MODELS[activeModel]?.displayName ?? activeModel
|
|
7095
7809
|
] }),
|
|
7096
|
-
thinkingEnabled && /* @__PURE__ */
|
|
7810
|
+
thinkingEnabled && /* @__PURE__ */ jsxs12(Text13, { color: "#ff9800", children: [
|
|
7097
7811
|
"\u{1F9E0} ",
|
|
7098
7812
|
thinkingEffort === "max" ? "Max" : "High"
|
|
7099
7813
|
] })
|
|
7100
7814
|
] }),
|
|
7101
|
-
balance !== null && /* @__PURE__ */
|
|
7815
|
+
balance !== null && /* @__PURE__ */ jsx12(Box12, { marginTop: 1, children: /* @__PURE__ */ jsxs12(Text13, { color: "yellow", children: [
|
|
7102
7816
|
"\u{1F4B0} \xA5",
|
|
7103
7817
|
balance.toFixed(2)
|
|
7104
7818
|
] }) })
|
|
@@ -7108,47 +7822,46 @@ function ChatSession({
|
|
|
7108
7822
|
)
|
|
7109
7823
|
}
|
|
7110
7824
|
),
|
|
7111
|
-
|
|
7112
|
-
|
|
7113
|
-
|
|
7114
|
-
!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: [
|
|
7115
7828
|
cmdTips.length > 0 && (() => {
|
|
7116
7829
|
const tip = cmdTips[cmdTipIndex % cmdTips.length];
|
|
7117
7830
|
if (!tip) return null;
|
|
7118
7831
|
const text = `${tip.name} ${tip.desc}`;
|
|
7119
|
-
return /* @__PURE__ */
|
|
7120
|
-
/* @__PURE__ */
|
|
7121
|
-
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 })
|
|
7122
7835
|
] });
|
|
7123
7836
|
})(),
|
|
7124
|
-
/* @__PURE__ */
|
|
7125
|
-
/* @__PURE__ */
|
|
7837
|
+
/* @__PURE__ */ jsx12(Box12, { flexGrow: 1 }),
|
|
7838
|
+
/* @__PURE__ */ jsx12(AnimatedLogo, { panelWidth: rightContentWidth })
|
|
7126
7839
|
] }),
|
|
7127
|
-
/* @__PURE__ */
|
|
7128
|
-
/* @__PURE__ */
|
|
7840
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginTop: 1, children: [
|
|
7841
|
+
/* @__PURE__ */ jsx12(Static, { items: displayMessages, children: (msg, i) => {
|
|
7129
7842
|
if (msg.role === "user") {
|
|
7130
|
-
return /* @__PURE__ */
|
|
7131
|
-
/* @__PURE__ */
|
|
7132
|
-
/* @__PURE__ */
|
|
7133
|
-
/* @__PURE__ */
|
|
7134
|
-
/* @__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 }) })
|
|
7135
7848
|
] }) })
|
|
7136
7849
|
] }, i);
|
|
7137
7850
|
}
|
|
7138
7851
|
if (msg.role === "tool") {
|
|
7139
|
-
return /* @__PURE__ */
|
|
7140
|
-
/* @__PURE__ */
|
|
7141
|
-
/* @__PURE__ */
|
|
7142
|
-
/* @__PURE__ */
|
|
7143
|
-
/* @__PURE__ */
|
|
7144
|
-
/* @__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 }) })
|
|
7145
7858
|
] }),
|
|
7146
|
-
msg.diff && /* @__PURE__ */
|
|
7859
|
+
msg.diff && /* @__PURE__ */ jsx12(DiffPreview, { diff: msg.diff })
|
|
7147
7860
|
] })
|
|
7148
7861
|
] }, i);
|
|
7149
7862
|
}
|
|
7150
7863
|
const detail = msg.assistantDetail;
|
|
7151
|
-
return /* @__PURE__ */
|
|
7864
|
+
return /* @__PURE__ */ jsx12(
|
|
7152
7865
|
AssistantMessage,
|
|
7153
7866
|
{
|
|
7154
7867
|
content: msg.content,
|
|
@@ -7162,7 +7875,7 @@ function ChatSession({
|
|
|
7162
7875
|
i
|
|
7163
7876
|
);
|
|
7164
7877
|
} }, staticKey),
|
|
7165
|
-
isStreaming && /* @__PURE__ */
|
|
7878
|
+
isStreaming && /* @__PURE__ */ jsx12(
|
|
7166
7879
|
AssistantMessage,
|
|
7167
7880
|
{
|
|
7168
7881
|
content: currentContent,
|
|
@@ -7173,49 +7886,56 @@ function ChatSession({
|
|
|
7173
7886
|
model: _streamingModel
|
|
7174
7887
|
}
|
|
7175
7888
|
),
|
|
7176
|
-
|
|
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: [
|
|
7177
7897
|
"\u26A0 ",
|
|
7178
7898
|
streamError
|
|
7179
7899
|
] }) })
|
|
7180
7900
|
] }),
|
|
7181
|
-
todoPanelVisible && todoSnapshot.length > 0 && /* @__PURE__ */
|
|
7901
|
+
todoPanelVisible && todoSnapshot.length > 0 && /* @__PURE__ */ jsx12(TodoListPanel, { items: todoSnapshot })
|
|
7182
7902
|
] }),
|
|
7183
|
-
selectingModel ? /* @__PURE__ */
|
|
7184
|
-
/* @__PURE__ */
|
|
7185
|
-
/* @__PURE__ */
|
|
7186
|
-
/* @__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" }),
|
|
7187
7907
|
modelOptions.map((id, i) => {
|
|
7188
7908
|
const meta = SUPPORTED_MODELS[id];
|
|
7189
7909
|
const isCurrent = id === activeModel;
|
|
7190
7910
|
const isSelected = i === modelSelectIndex;
|
|
7191
7911
|
const marker = isSelected ? " > " : " ";
|
|
7192
7912
|
const suffix = isCurrent ? " (\u5F53\u524D)" : "";
|
|
7193
|
-
return /* @__PURE__ */
|
|
7194
|
-
/* @__PURE__ */
|
|
7913
|
+
return /* @__PURE__ */ jsxs12(Box12, { children: [
|
|
7914
|
+
/* @__PURE__ */ jsxs12(Text13, { color: isSelected ? "#00ff41" : void 0, bold: isSelected, children: [
|
|
7195
7915
|
marker,
|
|
7196
7916
|
meta.displayName,
|
|
7197
7917
|
suffix
|
|
7198
7918
|
] }),
|
|
7199
|
-
isSelected && /* @__PURE__ */
|
|
7919
|
+
isSelected && /* @__PURE__ */ jsxs12(Text13, { color: "#808080", children: [
|
|
7200
7920
|
" \u2014 ",
|
|
7201
7921
|
id
|
|
7202
7922
|
] })
|
|
7203
7923
|
] }, id);
|
|
7204
7924
|
}),
|
|
7205
|
-
/* @__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" }) })
|
|
7206
7926
|
] }),
|
|
7207
|
-
/* @__PURE__ */
|
|
7208
|
-
] }) : rewindSelecting ? /* @__PURE__ */
|
|
7209
|
-
/* @__PURE__ */
|
|
7210
|
-
/* @__PURE__ */
|
|
7211
|
-
/* @__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" }),
|
|
7212
7932
|
rewindList.map((cp2, i) => {
|
|
7213
7933
|
const isSelected = i === rewindSelectIndex;
|
|
7214
7934
|
const marker = isSelected ? " > " : " ";
|
|
7215
7935
|
const time = new Date(cp2.timestamp).toLocaleTimeString();
|
|
7216
7936
|
const preview = cp2.preview || "(\u7A7A)";
|
|
7217
7937
|
const tag = cp2.isGitRepo ? "" : " [\u975E git\uFF0C\u4EC5\u5BF9\u8BDD]";
|
|
7218
|
-
return /* @__PURE__ */
|
|
7938
|
+
return /* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsxs12(Text13, { color: isSelected ? "#ff9800" : void 0, bold: isSelected, children: [
|
|
7219
7939
|
marker,
|
|
7220
7940
|
"#",
|
|
7221
7941
|
i + 1,
|
|
@@ -7227,21 +7947,25 @@ function ChatSession({
|
|
|
7227
7947
|
"`"
|
|
7228
7948
|
] }) }, cp2.index);
|
|
7229
7949
|
}),
|
|
7230
|
-
/* @__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" }) })
|
|
7231
7951
|
] }),
|
|
7232
|
-
/* @__PURE__ */
|
|
7233
|
-
] }) : /* @__PURE__ */
|
|
7234
|
-
(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: [
|
|
7235
7955
|
PHASE_CONFIG[streamingPhase].icon,
|
|
7236
7956
|
" ",
|
|
7237
7957
|
PHASE_CONFIG[streamingPhase].label,
|
|
7238
7958
|
" ",
|
|
7239
|
-
/* @__PURE__ */
|
|
7240
|
-
] }) }) : rewindHintPhase === "visible" ? /* @__PURE__ */
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
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(
|
|
7245
7969
|
TextInput,
|
|
7246
7970
|
{
|
|
7247
7971
|
value: input,
|
|
@@ -7252,9 +7976,9 @@ function ChatSession({
|
|
|
7252
7976
|
inputKey
|
|
7253
7977
|
) })
|
|
7254
7978
|
] }),
|
|
7255
|
-
/* @__PURE__ */
|
|
7256
|
-
/* @__PURE__ */
|
|
7257
|
-
/* @__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 })
|
|
7258
7982
|
] })
|
|
7259
7983
|
] }), [
|
|
7260
7984
|
displayMessages,
|
|
@@ -7302,15 +8026,53 @@ function ChatSession({
|
|
|
7302
8026
|
doubleCtrlC
|
|
7303
8027
|
])
|
|
7304
8028
|
] }),
|
|
7305
|
-
doubleCtrlC && !isStreaming && /* @__PURE__ */
|
|
7306
|
-
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
|
+
"%"
|
|
7307
8069
|
] });
|
|
7308
8070
|
}
|
|
7309
8071
|
|
|
7310
8072
|
// src/ui/GamePicker.tsx
|
|
7311
|
-
import { Box as
|
|
8073
|
+
import { Box as Box13, Text as Text14, useInput as useInput2 } from "ink";
|
|
7312
8074
|
import { useState as useState6, useCallback as useCallback3 } from "react";
|
|
7313
|
-
import { jsx as
|
|
8075
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
7314
8076
|
function GamePicker({ games, onSelect, onExit, onBackToChat }) {
|
|
7315
8077
|
const [selectedIndex, setSelectedIndex] = useState6(0);
|
|
7316
8078
|
const exitAction = onBackToChat ?? onExit ?? (() => process.exit(0));
|
|
@@ -7338,18 +8100,18 @@ function GamePicker({ games, onSelect, onExit, onBackToChat }) {
|
|
|
7338
8100
|
[games, selectedIndex, onSelect, onExit, onBackToChat, handleCtrlC]
|
|
7339
8101
|
)
|
|
7340
8102
|
);
|
|
7341
|
-
return /* @__PURE__ */
|
|
7342
|
-
/* @__PURE__ */
|
|
7343
|
-
/* @__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) => {
|
|
7344
8106
|
const isSelected = index === selectedIndex;
|
|
7345
|
-
return /* @__PURE__ */
|
|
7346
|
-
/* @__PURE__ */
|
|
7347
|
-
/* @__PURE__ */
|
|
7348
|
-
/* @__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 }) })
|
|
7349
8111
|
] }, game.id);
|
|
7350
8112
|
}) }),
|
|
7351
|
-
/* @__PURE__ */
|
|
7352
|
-
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" }) })
|
|
7353
8115
|
] });
|
|
7354
8116
|
}
|
|
7355
8117
|
|
|
@@ -7366,9 +8128,9 @@ function listGames() {
|
|
|
7366
8128
|
}
|
|
7367
8129
|
|
|
7368
8130
|
// src/game/brick-breaker/index.tsx
|
|
7369
|
-
import { Box as
|
|
8131
|
+
import { Box as Box14, Text as Text15, useInput as useInput3, render as render2 } from "ink";
|
|
7370
8132
|
import { useState as useState7, useEffect as useEffect6, useRef as useRef5, useCallback as useCallback4 } from "react";
|
|
7371
|
-
import { jsx as
|
|
8133
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
7372
8134
|
var GAME_WIDTH = 40;
|
|
7373
8135
|
var GAME_HEIGHT = 18;
|
|
7374
8136
|
var PADDLE_WIDTH = 9;
|
|
@@ -7558,49 +8320,49 @@ function BrickBreakerGame({ onExit: _onExit }) {
|
|
|
7558
8320
|
const board = buildBoard(s);
|
|
7559
8321
|
const def = getLevel(s.level);
|
|
7560
8322
|
void tick2;
|
|
7561
|
-
return /* @__PURE__ */
|
|
7562
|
-
/* @__PURE__ */
|
|
7563
|
-
/* @__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: [
|
|
7564
8326
|
"\u5173\u5361 ",
|
|
7565
8327
|
s.level,
|
|
7566
8328
|
": ",
|
|
7567
|
-
/* @__PURE__ */
|
|
8329
|
+
/* @__PURE__ */ jsx14(Text15, { color: "cyan", children: def.desc })
|
|
7568
8330
|
] }) }),
|
|
7569
|
-
/* @__PURE__ */
|
|
8331
|
+
/* @__PURE__ */ jsx14(Box14, { width: 12, children: /* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7570
8332
|
"\u5206\u6570: ",
|
|
7571
|
-
/* @__PURE__ */
|
|
8333
|
+
/* @__PURE__ */ jsx14(Text15, { color: "yellow", children: String(s.score).padStart(3, "0") })
|
|
7572
8334
|
] }) }),
|
|
7573
|
-
/* @__PURE__ */
|
|
8335
|
+
/* @__PURE__ */ jsx14(Box14, { width: 12, children: /* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7574
8336
|
"\u751F\u547D: ",
|
|
7575
|
-
/* @__PURE__ */
|
|
8337
|
+
/* @__PURE__ */ jsx14(Text15, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) })
|
|
7576
8338
|
] }) }),
|
|
7577
|
-
/* @__PURE__ */
|
|
8339
|
+
/* @__PURE__ */ jsx14(Box14, { width: 10, children: /* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7578
8340
|
"\u7816\u5757: ",
|
|
7579
|
-
/* @__PURE__ */
|
|
8341
|
+
/* @__PURE__ */ jsx14(Text15, { color: "cyan", children: aliveCount })
|
|
7580
8342
|
] }) }),
|
|
7581
|
-
/* @__PURE__ */
|
|
8343
|
+
/* @__PURE__ */ jsx14(Box14, { children: /* @__PURE__ */ jsxs14(Text15, { color: s.paused ? "gray" : "green", children: [
|
|
7582
8344
|
"[",
|
|
7583
8345
|
s.paused ? "\u6682\u505C" : "\u8FD0\u884C\u4E2D",
|
|
7584
8346
|
"]"
|
|
7585
8347
|
] }) })
|
|
7586
8348
|
] }),
|
|
7587
|
-
/* @__PURE__ */
|
|
7588
|
-
/* @__PURE__ */
|
|
8349
|
+
/* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
|
|
8350
|
+
/* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7589
8351
|
"\u250C",
|
|
7590
8352
|
"\u2500".repeat(GAME_WIDTH),
|
|
7591
8353
|
"\u2510"
|
|
7592
8354
|
] }),
|
|
7593
|
-
/* @__PURE__ */
|
|
7594
|
-
/* @__PURE__ */
|
|
8355
|
+
/* @__PURE__ */ jsx14(Text15, { children: selectingLevel ? " \x1B[90m\u9009\u62E9\u5173\u5361\u540E\u5F00\u59CB...\x1B[0m" : board }),
|
|
8356
|
+
/* @__PURE__ */ jsxs14(Text15, { children: [
|
|
7595
8357
|
"\u2514",
|
|
7596
8358
|
"\u2500".repeat(GAME_WIDTH),
|
|
7597
8359
|
"\u2518"
|
|
7598
8360
|
] })
|
|
7599
8361
|
] }),
|
|
7600
|
-
selectingLevel && /* @__PURE__ */
|
|
7601
|
-
/* @__PURE__ */
|
|
7602
|
-
/* @__PURE__ */
|
|
7603
|
-
/* @__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) }),
|
|
7604
8366
|
". ",
|
|
7605
8367
|
lv.desc,
|
|
7606
8368
|
" (",
|
|
@@ -7609,16 +8371,16 @@ function BrickBreakerGame({ onExit: _onExit }) {
|
|
|
7609
8371
|
lv.cols,
|
|
7610
8372
|
")"
|
|
7611
8373
|
] }) }, i)) }),
|
|
7612
|
-
/* @__PURE__ */
|
|
8374
|
+
/* @__PURE__ */ jsx14(Box14, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text15, { dimColor: true, children: "\u6309\u6570\u5B57\u9009\u5173 q \u9000\u51FA" }) })
|
|
7613
8375
|
] }),
|
|
7614
|
-
!selectingLevel && (s.gameOver || s.win) && /* @__PURE__ */
|
|
7615
|
-
/* @__PURE__ */
|
|
7616
|
-
/* @__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: [
|
|
7617
8379
|
" \u5206\u6570: ",
|
|
7618
|
-
/* @__PURE__ */
|
|
8380
|
+
/* @__PURE__ */ jsx14(Text15, { color: "yellow", children: s.score })
|
|
7619
8381
|
] })
|
|
7620
8382
|
] }),
|
|
7621
|
-
!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" }) })
|
|
7622
8384
|
] });
|
|
7623
8385
|
}
|
|
7624
8386
|
var brick_breaker_default = {
|
|
@@ -7628,7 +8390,7 @@ var brick_breaker_default = {
|
|
|
7628
8390
|
play: async () => {
|
|
7629
8391
|
await new Promise((resolve2) => {
|
|
7630
8392
|
const { unmount } = render2(
|
|
7631
|
-
/* @__PURE__ */
|
|
8393
|
+
/* @__PURE__ */ jsx14(BrickBreakerGame, { onExit: () => {
|
|
7632
8394
|
unmount();
|
|
7633
8395
|
resolve2();
|
|
7634
8396
|
} })
|
|
@@ -7638,9 +8400,9 @@ var brick_breaker_default = {
|
|
|
7638
8400
|
};
|
|
7639
8401
|
|
|
7640
8402
|
// src/game/coder-check/index.tsx
|
|
7641
|
-
import { Box as
|
|
8403
|
+
import { Box as Box15, Text as Text16, useInput as useInput4, render as render3 } from "ink";
|
|
7642
8404
|
import { useState as useState8, useEffect as useEffect7, useRef as useRef6, useCallback as useCallback5 } from "react";
|
|
7643
|
-
import { jsx as
|
|
8405
|
+
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
7644
8406
|
var GAME_W = 66;
|
|
7645
8407
|
var GAME_H = 20;
|
|
7646
8408
|
var SCORE_H = 6;
|
|
@@ -8111,44 +8873,44 @@ function CoderCheck({ onExit: _onExit }) {
|
|
|
8111
8873
|
const scoreLines = buildScoreLines(scoreStr);
|
|
8112
8874
|
const view = buildGameView(s, scoreLines, scoreColor, s.message);
|
|
8113
8875
|
void tick2;
|
|
8114
|
-
return /* @__PURE__ */
|
|
8115
|
-
/* @__PURE__ */
|
|
8876
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", paddingX: 1, children: [
|
|
8877
|
+
/* @__PURE__ */ jsx15(Box15, { flexDirection: "row", children: /* @__PURE__ */ jsxs15(Text16, { children: [
|
|
8116
8878
|
"\u751F\u547D ",
|
|
8117
|
-
/* @__PURE__ */
|
|
8879
|
+
/* @__PURE__ */ jsx15(Text16, { color: "red", children: "\u2665".repeat(Math.max(0, s.lives)) }),
|
|
8118
8880
|
" ",
|
|
8119
8881
|
"\u901F\u5EA6 ",
|
|
8120
|
-
/* @__PURE__ */
|
|
8882
|
+
/* @__PURE__ */ jsxs15(Text16, { color: "cyan", children: [
|
|
8121
8883
|
"Lv.",
|
|
8122
8884
|
Math.floor(s.speed * 10)
|
|
8123
8885
|
] })
|
|
8124
8886
|
] }) }),
|
|
8125
|
-
!s.gameOver && s.target && /* @__PURE__ */
|
|
8887
|
+
!s.gameOver && s.target && /* @__PURE__ */ jsx15(Box15, { marginTop: 1, children: /* @__PURE__ */ jsxs15(Text16, { children: [
|
|
8126
8888
|
"\u6253\u5B57: ",
|
|
8127
|
-
/* @__PURE__ */
|
|
8128
|
-
/* @__PURE__ */
|
|
8889
|
+
/* @__PURE__ */ jsx15(Text16, { color: "green", children: s.typed }),
|
|
8890
|
+
/* @__PURE__ */ jsx15(Text16, { color: "white", children: s.target.slice(s.typed.length) })
|
|
8129
8891
|
] }) }),
|
|
8130
|
-
/* @__PURE__ */
|
|
8131
|
-
/* @__PURE__ */
|
|
8892
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", marginTop: 1, children: [
|
|
8893
|
+
/* @__PURE__ */ jsxs15(Text16, { children: [
|
|
8132
8894
|
"\u250C",
|
|
8133
8895
|
"\u2500".repeat(GAME_W),
|
|
8134
8896
|
"\u2510"
|
|
8135
8897
|
] }),
|
|
8136
|
-
view.map((row, i) => /* @__PURE__ */
|
|
8137
|
-
/* @__PURE__ */
|
|
8898
|
+
view.map((row, i) => /* @__PURE__ */ jsx15(Text16, { children: `\u2502${row}\u2502` }, i)),
|
|
8899
|
+
/* @__PURE__ */ jsxs15(Text16, { children: [
|
|
8138
8900
|
"\u2514",
|
|
8139
8901
|
"\u2500".repeat(GAME_W),
|
|
8140
8902
|
"\u2518"
|
|
8141
8903
|
] })
|
|
8142
8904
|
] }),
|
|
8143
|
-
s.gameOver && /* @__PURE__ */
|
|
8144
|
-
/* @__PURE__ */
|
|
8145
|
-
/* @__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: [
|
|
8146
8908
|
" \u5F97\u5206: ",
|
|
8147
|
-
/* @__PURE__ */
|
|
8909
|
+
/* @__PURE__ */ jsx15(Text16, { color: "yellow", children: s.score }),
|
|
8148
8910
|
" r \u91CD\u5F00 q \u9000\u51FA"
|
|
8149
8911
|
] })
|
|
8150
8912
|
] }),
|
|
8151
|
-
/* @__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" }) })
|
|
8152
8914
|
] });
|
|
8153
8915
|
}
|
|
8154
8916
|
var coder_check_default = {
|
|
@@ -8158,7 +8920,7 @@ var coder_check_default = {
|
|
|
8158
8920
|
play: async () => {
|
|
8159
8921
|
await new Promise((resolve2) => {
|
|
8160
8922
|
const { unmount } = render3(
|
|
8161
|
-
/* @__PURE__ */
|
|
8923
|
+
/* @__PURE__ */ jsx15(CoderCheck, { onExit: () => {
|
|
8162
8924
|
unmount();
|
|
8163
8925
|
resolve2();
|
|
8164
8926
|
} })
|
|
@@ -8538,12 +9300,12 @@ import { render as render4 } from "ink";
|
|
|
8538
9300
|
import chalk5 from "chalk";
|
|
8539
9301
|
|
|
8540
9302
|
// src/stock/StockList.tsx
|
|
8541
|
-
import { Box as
|
|
8542
|
-
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";
|
|
8543
9305
|
import asciichart from "asciichart";
|
|
8544
9306
|
import os from "os";
|
|
8545
9307
|
import { join as join10 } from "path";
|
|
8546
|
-
import { jsx as
|
|
9308
|
+
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
8547
9309
|
var SETTINGS_PATH = join10(os.homedir(), ".dskcode", "settings.json");
|
|
8548
9310
|
function toFileUrl(p) {
|
|
8549
9311
|
const norm = p.replace(/\\/g, "/");
|
|
@@ -8660,7 +9422,7 @@ function StockList({ codes, onExit, onBackToChat }) {
|
|
|
8660
9422
|
);
|
|
8661
9423
|
const [dimMode, setDimMode] = useState9(false);
|
|
8662
9424
|
const [sortOrder, setSortOrder] = useState9("default");
|
|
8663
|
-
const sortedStocks =
|
|
9425
|
+
const sortedStocks = useMemo3(() => {
|
|
8664
9426
|
if (sortOrder === "default") return stocks;
|
|
8665
9427
|
return [...stocks].toSorted(
|
|
8666
9428
|
(a, b) => sortOrder === "desc" ? b.changePercent - a.changePercent : a.changePercent - b.changePercent
|
|
@@ -8762,64 +9524,64 @@ function StockList({ codes, onExit, onBackToChat }) {
|
|
|
8762
9524
|
);
|
|
8763
9525
|
if (detailView) {
|
|
8764
9526
|
if (detailLoading) {
|
|
8765
|
-
return /* @__PURE__ */
|
|
9527
|
+
return /* @__PURE__ */ jsx16(Box16, { paddingLeft: 1, children: /* @__PURE__ */ jsx16(Text17, { dimColor: true, children: " \u27F3 \u52A0\u8F7D\u5206\u65F6\u6570\u636E..." }) });
|
|
8766
9528
|
}
|
|
8767
9529
|
return renderDetail(detailView, () => setDetailView(null), detailPrices ?? void 0, detailCountdown, currentTime);
|
|
8768
9530
|
}
|
|
8769
9531
|
const cp2 = (c) => dimMode ? { dimColor: true } : { color: c };
|
|
8770
|
-
return /* @__PURE__ */
|
|
8771
|
-
/* @__PURE__ */
|
|
8772
|
-
/* @__PURE__ */
|
|
8773
|
-
/* @__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: [
|
|
8774
9536
|
" \u{1F550} ",
|
|
8775
9537
|
currentTime
|
|
8776
9538
|
] }),
|
|
8777
|
-
/* @__PURE__ */
|
|
9539
|
+
/* @__PURE__ */ jsx16(Text17, { dimColor: true, children: loading ? " \u27F3 \u5237\u65B0\u4E2D..." : ` ${countdown}s \u540E\u81EA\u52A8\u5237\u65B0` })
|
|
8778
9540
|
] }),
|
|
8779
|
-
/* @__PURE__ */
|
|
8780
|
-
/* @__PURE__ */
|
|
8781
|
-
/* @__PURE__ */
|
|
8782
|
-
/* @__PURE__ */
|
|
8783
|
-
/* @__PURE__ */
|
|
8784
|
-
/* @__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: [
|
|
8785
9547
|
"\u6DA8\u8DCC\u5E45",
|
|
8786
9548
|
sortOrder === "desc" ? " \u25BC" : sortOrder === "asc" ? " \u25B2" : ""
|
|
8787
9549
|
] }) }),
|
|
8788
|
-
/* @__PURE__ */
|
|
8789
|
-
/* @__PURE__ */
|
|
8790
|
-
/* @__PURE__ */
|
|
8791
|
-
/* @__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" }) })
|
|
8792
9554
|
] }),
|
|
8793
|
-
/* @__PURE__ */
|
|
8794
|
-
/* @__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) => {
|
|
8795
9557
|
const isSelected = index === selectedIndex;
|
|
8796
9558
|
const isUp = stock.changePercent >= 0;
|
|
8797
9559
|
const color = isUp ? "#ff1493" : "#00ff41";
|
|
8798
|
-
return /* @__PURE__ */
|
|
8799
|
-
/* @__PURE__ */
|
|
8800
|
-
/* @__PURE__ */
|
|
8801
|
-
/* @__PURE__ */
|
|
8802
|
-
/* @__PURE__ */
|
|
8803
|
-
/* @__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: [
|
|
8804
9566
|
isUp ? "+" : "",
|
|
8805
9567
|
stock.changePercent.toFixed(2),
|
|
8806
9568
|
"%"
|
|
8807
9569
|
] }) }),
|
|
8808
|
-
/* @__PURE__ */
|
|
9570
|
+
/* @__PURE__ */ jsx16(Box16, { width: 12, children: /* @__PURE__ */ jsxs16(Text17, { ...cp2(color), children: [
|
|
8809
9571
|
isUp ? "+" : "",
|
|
8810
9572
|
stock.changeAmount.toFixed(3)
|
|
8811
9573
|
] }) }),
|
|
8812
|
-
/* @__PURE__ */
|
|
8813
|
-
/* @__PURE__ */
|
|
8814
|
-
/* @__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) }) })
|
|
8815
9577
|
] }, stock.code);
|
|
8816
9578
|
}) }),
|
|
8817
|
-
/* @__PURE__ */
|
|
8818
|
-
/* @__PURE__ */
|
|
8819
|
-
/* @__PURE__ */
|
|
8820
|
-
/* @__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) })
|
|
8821
9583
|
] }),
|
|
8822
|
-
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" }) })
|
|
8823
9585
|
] });
|
|
8824
9586
|
}
|
|
8825
9587
|
function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
|
|
@@ -8837,33 +9599,33 @@ function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
|
|
|
8837
9599
|
raw = raw.replaceAll("\u256D", "\u250C").replaceAll("\u256E", "\u2510").replaceAll("\u2570", "\u2514").replaceAll("\u256F", "\u2518");
|
|
8838
9600
|
chartLines = raw.split("\n");
|
|
8839
9601
|
}
|
|
8840
|
-
return /* @__PURE__ */
|
|
8841
|
-
/* @__PURE__ */
|
|
8842
|
-
/* @__PURE__ */
|
|
8843
|
-
/* @__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: [
|
|
8844
9606
|
" \u{1F4CA} ",
|
|
8845
9607
|
stock.name,
|
|
8846
9608
|
" "
|
|
8847
9609
|
] }),
|
|
8848
|
-
/* @__PURE__ */
|
|
8849
|
-
currentTime && /* @__PURE__ */
|
|
9610
|
+
/* @__PURE__ */ jsx16(Text17, { dimColor: true, children: stock.code }),
|
|
9611
|
+
currentTime && /* @__PURE__ */ jsxs16(Text17, { dimColor: true, children: [
|
|
8850
9612
|
" \u{1F550} ",
|
|
8851
9613
|
currentTime
|
|
8852
9614
|
] })
|
|
8853
9615
|
] }),
|
|
8854
|
-
/* @__PURE__ */
|
|
9616
|
+
/* @__PURE__ */ jsx16(Text17, { dimColor: true, children: `${countdown}s \u540E\u5237\u65B0` })
|
|
8855
9617
|
] }),
|
|
8856
|
-
/* @__PURE__ */
|
|
8857
|
-
/* @__PURE__ */
|
|
8858
|
-
/* @__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: [
|
|
8859
9621
|
arrow,
|
|
8860
9622
|
" ",
|
|
8861
9623
|
formatPrice(stock.price)
|
|
8862
9624
|
] }) })
|
|
8863
9625
|
] }),
|
|
8864
|
-
/* @__PURE__ */
|
|
8865
|
-
/* @__PURE__ */
|
|
8866
|
-
/* @__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: [
|
|
8867
9629
|
isUp ? "+" : "",
|
|
8868
9630
|
stock.changePercent.toFixed(2),
|
|
8869
9631
|
"%",
|
|
@@ -8872,8 +9634,8 @@ function renderDetail(stock, _onBack, prices, countdown = 10, currentTime) {
|
|
|
8872
9634
|
stock.changeAmount.toFixed(3)
|
|
8873
9635
|
] }) })
|
|
8874
9636
|
] }),
|
|
8875
|
-
chartLines.length > 0 && /* @__PURE__ */
|
|
8876
|
-
/* @__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" }) })
|
|
8877
9639
|
] });
|
|
8878
9640
|
}
|
|
8879
9641
|
|
|
@@ -8958,7 +9720,7 @@ async function scanProjectFiles(baseDir, dir) {
|
|
|
8958
9720
|
}
|
|
8959
9721
|
|
|
8960
9722
|
// src/cli/index.tsx
|
|
8961
|
-
import { jsx as
|
|
9723
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
8962
9724
|
var SUBCOMMANDS = ["chat", "run", "setup", "init", "completion", "game", "stock"];
|
|
8963
9725
|
function createCli() {
|
|
8964
9726
|
const program2 = new Command();
|
|
@@ -9060,7 +9822,7 @@ compdef _dskcode_completion dskcode`);
|
|
|
9060
9822
|
const freshResult = await loadAndValidate();
|
|
9061
9823
|
const codeList = codes && codes.length > 0 ? codes : freshResult.config.stock?.symbols?.map((s) => s.code) ?? ["sh000001", "sz399006", "sh601688"];
|
|
9062
9824
|
const app = renderApp(
|
|
9063
|
-
/* @__PURE__ */
|
|
9825
|
+
/* @__PURE__ */ jsx17(
|
|
9064
9826
|
StockList,
|
|
9065
9827
|
{
|
|
9066
9828
|
codes: codeList,
|
|
@@ -9089,7 +9851,7 @@ compdef _dskcode_completion dskcode`);
|
|
|
9089
9851
|
}
|
|
9090
9852
|
const selectedGame = await new Promise((resolve2) => {
|
|
9091
9853
|
const { unmount } = render4(
|
|
9092
|
-
/* @__PURE__ */
|
|
9854
|
+
/* @__PURE__ */ jsx17(
|
|
9093
9855
|
GamePicker,
|
|
9094
9856
|
{
|
|
9095
9857
|
games,
|
|
@@ -9129,7 +9891,7 @@ async function startChat(ctx, costTracker) {
|
|
|
9129
9891
|
);
|
|
9130
9892
|
const model = defaultProvider?.model ?? "deepseek-v4-flash";
|
|
9131
9893
|
const chatApp = renderApp(
|
|
9132
|
-
/* @__PURE__ */
|
|
9894
|
+
/* @__PURE__ */ jsx17(
|
|
9133
9895
|
ChatSession,
|
|
9134
9896
|
{
|
|
9135
9897
|
skillCount,
|
|
@@ -9147,7 +9909,7 @@ async function startChat(ctx, costTracker) {
|
|
|
9147
9909
|
initGames();
|
|
9148
9910
|
const games = listGames();
|
|
9149
9911
|
const { unmount } = render4(
|
|
9150
|
-
/* @__PURE__ */
|
|
9912
|
+
/* @__PURE__ */ jsx17(
|
|
9151
9913
|
GamePicker,
|
|
9152
9914
|
{
|
|
9153
9915
|
games,
|
|
@@ -9171,7 +9933,7 @@ async function startChat(ctx, costTracker) {
|
|
|
9171
9933
|
setImmediate(() => {
|
|
9172
9934
|
const defaultStockCodes = ctx?.config.stock?.symbols?.map((s) => s.code) ?? ["sh000001", "sz399006", "sh601688"];
|
|
9173
9935
|
const stockApp = renderApp(
|
|
9174
|
-
/* @__PURE__ */
|
|
9936
|
+
/* @__PURE__ */ jsx17(
|
|
9175
9937
|
StockList,
|
|
9176
9938
|
{
|
|
9177
9939
|
codes: defaultStockCodes,
|