@zhongqian97-code/ecode 0.5.56 → 0.5.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -814,7 +814,7 @@ if (rawArgs[0] === "web") {
|
|
|
814
814
|
webAutoApprove = true;
|
|
815
815
|
}
|
|
816
816
|
}
|
|
817
|
-
const { buildServer, generateAccessToken } = await import("./web-
|
|
817
|
+
const { buildServer, generateAccessToken } = await import("./web-3CS3TO2E.js");
|
|
818
818
|
const token = finalConfig.webToken ?? generateAccessToken();
|
|
819
819
|
const manager = new SessionManager(finalConfig);
|
|
820
820
|
const __webDirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -923,7 +923,7 @@ Node.js 16/18 \u8BF7\u4F7F\u7528 --web \u6216 --pipe \u6A21\u5F0F\u3002
|
|
|
923
923
|
);
|
|
924
924
|
process.exit(1);
|
|
925
925
|
}
|
|
926
|
-
const { App, React, render, createStdinFilter } = await import("./ui-
|
|
926
|
+
const { App, React, render, createStdinFilter } = await import("./ui-STSJVDXD.js");
|
|
927
927
|
const stdinFilter = process.stdin.isTTY ? createStdinFilter(process.stdin) : process.stdin;
|
|
928
928
|
render(
|
|
929
929
|
React.createElement(App, { config: finalConfig, version: VERSION, autoMode, registry, trustedSkillDirs, initialMessages, stdinFilter }),
|
|
@@ -200,6 +200,7 @@ function StatusBar({
|
|
|
200
200
|
import { Box as Box2, Text as Text2 } from "ink";
|
|
201
201
|
|
|
202
202
|
// src/ui/messageLines.ts
|
|
203
|
+
import stringWidth from "string-width";
|
|
203
204
|
var TOOL_RESULT_MAX_LINES = 3;
|
|
204
205
|
function wrapText(text, terminalWidth) {
|
|
205
206
|
const logicalLines = text.split("\n");
|
|
@@ -210,9 +211,20 @@ function wrapText(text, terminalWidth) {
|
|
|
210
211
|
result.push("");
|
|
211
212
|
continue;
|
|
212
213
|
}
|
|
213
|
-
|
|
214
|
-
|
|
214
|
+
let chunk = "";
|
|
215
|
+
let chunkW = 0;
|
|
216
|
+
for (const ch of line) {
|
|
217
|
+
const w = stringWidth(ch);
|
|
218
|
+
if (chunkW + w > terminalWidth && chunk.length > 0) {
|
|
219
|
+
result.push(chunk);
|
|
220
|
+
chunk = ch;
|
|
221
|
+
chunkW = w;
|
|
222
|
+
} else {
|
|
223
|
+
chunk += ch;
|
|
224
|
+
chunkW += w;
|
|
225
|
+
}
|
|
215
226
|
}
|
|
227
|
+
if (chunk.length > 0) result.push(chunk);
|
|
216
228
|
}
|
|
217
229
|
return result;
|
|
218
230
|
}
|
|
@@ -853,6 +865,28 @@ ${blocks.join("\n\n")}`;
|
|
|
853
865
|
${contextSection}` : contextSection;
|
|
854
866
|
}
|
|
855
867
|
|
|
868
|
+
// src/ui/mouseCoords.ts
|
|
869
|
+
var STATUS_BAR_ROWS = 1;
|
|
870
|
+
function computeVisibleWindow(totalLines, scrollOffset, historyMaxHeight) {
|
|
871
|
+
const end = Math.max(0, Math.min(totalLines, totalLines - scrollOffset));
|
|
872
|
+
const initialStart = Math.max(0, end - historyMaxHeight);
|
|
873
|
+
const hasScrollIndicator = initialStart > 0 && historyMaxHeight > 1;
|
|
874
|
+
const start = hasScrollIndicator ? Math.max(0, end - (historyMaxHeight - 1)) : initialStart;
|
|
875
|
+
const visibleCount = (hasScrollIndicator ? 1 : 0) + (end - start);
|
|
876
|
+
return { start, end, visibleCount, hasScrollIndicator };
|
|
877
|
+
}
|
|
878
|
+
function mouseRowToLineIndex(opts) {
|
|
879
|
+
if (opts.visibleCount <= 0) return null;
|
|
880
|
+
const bottomRows = STATUS_BAR_ROWS + opts.skillAcRows + opts.fileAcRows + opts.selectedItemsRows + opts.inputRows;
|
|
881
|
+
const innerBoxHeight = opts.terminalRows - bottomRows;
|
|
882
|
+
const chTopRow = innerBoxHeight - opts.visibleCount;
|
|
883
|
+
const chBottomRow = innerBoxHeight - 1;
|
|
884
|
+
if (opts.mouseRow < chTopRow || opts.mouseRow > chBottomRow) return null;
|
|
885
|
+
const indicatorOffset = opts.hasScrollIndicator ? 1 : 0;
|
|
886
|
+
if (opts.mouseRow < chTopRow + indicatorOffset) return null;
|
|
887
|
+
return opts.mouseRow - chTopRow - indicatorOffset;
|
|
888
|
+
}
|
|
889
|
+
|
|
856
890
|
// src/ui/App.tsx
|
|
857
891
|
import { homedir as homedir2 } from "os";
|
|
858
892
|
import { join as join5 } from "path";
|
|
@@ -2439,6 +2473,12 @@ function App({ config, version, autoMode = false, registry, trustedSkillDirs = [
|
|
|
2439
2473
|
historyMaxHeightRef.current = historyMaxHeight;
|
|
2440
2474
|
const selectionStateRef = useRef2(selectionState);
|
|
2441
2475
|
selectionStateRef.current = selectionState;
|
|
2476
|
+
const inputRowsRef = useRef2(1);
|
|
2477
|
+
const skillAcRowsRef = useRef2(0);
|
|
2478
|
+
const fileAcRowsRef = useRef2(0);
|
|
2479
|
+
const selectedItemsRowsRef = useRef2(0);
|
|
2480
|
+
const terminalRowsRef = useRef2((stdout == null ? void 0 : stdout.rows) ?? 24);
|
|
2481
|
+
terminalRowsRef.current = (stdout == null ? void 0 : stdout.rows) ?? 24;
|
|
2442
2482
|
const pendingConfirmRef = useRef2(null);
|
|
2443
2483
|
const abortControllerRef = useRef2(null);
|
|
2444
2484
|
const llmRef = useRef2(llmClient ?? createProvider(resolveActiveProfile(config)));
|
|
@@ -2520,13 +2560,22 @@ function App({ config, version, autoMode = false, registry, trustedSkillDirs = [
|
|
|
2520
2560
|
}
|
|
2521
2561
|
return;
|
|
2522
2562
|
}
|
|
2523
|
-
const
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
const lineIdx =
|
|
2529
|
-
|
|
2563
|
+
const window = computeVisibleWindow(
|
|
2564
|
+
totalLinesRef.current,
|
|
2565
|
+
scrollOffsetRef.current,
|
|
2566
|
+
historyMaxHeightRef.current
|
|
2567
|
+
);
|
|
2568
|
+
const lineIdx = mouseRowToLineIndex({
|
|
2569
|
+
mouseRow: e.row,
|
|
2570
|
+
terminalRows: terminalRowsRef.current,
|
|
2571
|
+
inputRows: inputRowsRef.current,
|
|
2572
|
+
skillAcRows: skillAcRowsRef.current,
|
|
2573
|
+
fileAcRows: fileAcRowsRef.current,
|
|
2574
|
+
selectedItemsRows: selectedItemsRowsRef.current,
|
|
2575
|
+
visibleCount: window.visibleCount,
|
|
2576
|
+
hasScrollIndicator: window.hasScrollIndicator
|
|
2577
|
+
});
|
|
2578
|
+
if (lineIdx === null) return;
|
|
2530
2579
|
const pt = { row: lineIdx, col: e.col };
|
|
2531
2580
|
if (e.type === "leftDown") setSelectionState(startSelection(selectionStateRef.current, pt));
|
|
2532
2581
|
else if (e.type === "leftDrag") setSelectionState(updateSelection(selectionStateRef.current, pt));
|
|
@@ -2541,11 +2590,8 @@ function App({ config, version, autoMode = false, registry, trustedSkillDirs = [
|
|
|
2541
2590
|
if (selectionState.dragging || !selectionState.anchor || !selectionState.focus) return;
|
|
2542
2591
|
const visible = messages.filter((m) => m.role !== "system");
|
|
2543
2592
|
const allLines = visible.flatMap((msg) => messageToLines(msg, expandTools, (stdout == null ? void 0 : stdout.columns) ?? 0));
|
|
2544
|
-
const
|
|
2545
|
-
const
|
|
2546
|
-
const histH = historyMaxHeight;
|
|
2547
|
-
const start = Math.max(0, end - histH);
|
|
2548
|
-
const lineTexts = allLines.slice(start, end).map((l) => l.text);
|
|
2593
|
+
const window = computeVisibleWindow(allLines.length, scrollOffset, historyMaxHeight);
|
|
2594
|
+
const lineTexts = allLines.slice(window.start, window.end).map((l) => l.text);
|
|
2549
2595
|
const text = extractSelectedText(lineTexts, selectionState);
|
|
2550
2596
|
if (text && stdout) {
|
|
2551
2597
|
const b64 = Buffer.from(text, "utf8").toString("base64");
|
|
@@ -2999,6 +3045,7 @@ function App({ config, version, autoMode = false, registry, trustedSkillDirs = [
|
|
|
2999
3045
|
} else {
|
|
3000
3046
|
historyIndexRef.current = -1;
|
|
3001
3047
|
}
|
|
3048
|
+
inputRowsRef.current = Math.max(1, text.split("\n").length);
|
|
3002
3049
|
if (status !== "awaiting_confirm") {
|
|
3003
3050
|
setAcState((prev) => handleInputChange(prev, text));
|
|
3004
3051
|
setFileAcState((prev) => handleInputChange2(prev, text));
|
|
@@ -3006,6 +3053,10 @@ function App({ config, version, autoMode = false, registry, trustedSkillDirs = [
|
|
|
3006
3053
|
}, [status]);
|
|
3007
3054
|
const skillSuggestions = registry ? computeSuggestions(registry.list(), acState) : [];
|
|
3008
3055
|
const acOpen = isOpen(acState, skillSuggestions);
|
|
3056
|
+
const facOpen = isOpen2(fileAcState, fileSuggestions);
|
|
3057
|
+
skillAcRowsRef.current = acOpen ? skillSuggestions.length + 2 : 0;
|
|
3058
|
+
fileAcRowsRef.current = facOpen ? fileSuggestions.length + 2 : 0;
|
|
3059
|
+
selectedItemsRowsRef.current = selectedItems.length > 0 ? 1 : 0;
|
|
3009
3060
|
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", height: "100%", children: [
|
|
3010
3061
|
/* @__PURE__ */ jsx6(Box6, { flexGrow: 1, flexDirection: "column", justifyContent: "flex-end", children: /* @__PURE__ */ jsx6(
|
|
3011
3062
|
ConversationHistory,
|
|
@@ -3041,7 +3092,7 @@ function App({ config, version, autoMode = false, registry, trustedSkillDirs = [
|
|
|
3041
3092
|
{
|
|
3042
3093
|
suggestions: fileSuggestions,
|
|
3043
3094
|
selectedIndex: fileAcState.selectedIndex,
|
|
3044
|
-
isOpen:
|
|
3095
|
+
isOpen: facOpen
|
|
3045
3096
|
}
|
|
3046
3097
|
),
|
|
3047
3098
|
selectedItems.length > 0 && /* @__PURE__ */ jsx6(Box6, { paddingLeft: 1, children: /* @__PURE__ */ jsxs6(Text6, { color: "cyan", dimColor: true, children: [
|
|
@@ -221,6 +221,15 @@ function generateAdminHtml(version) {
|
|
|
221
221
|
font-size: 12px;
|
|
222
222
|
overflow: hidden;
|
|
223
223
|
margin: 4px 0;
|
|
224
|
+
/* #messages \u662F flex column \u5BB9\u5668\uFF0Cflex item \u9ED8\u8BA4 flex-shrink:1\u3002
|
|
225
|
+
* .tool-box \u6709 overflow:hidden \u4F1A\u8BA9 min-height \u9ED8\u8BA4\u5F52 0\uFF08CSS Flexbox \u89C4\u8303\uFF09\uFF0C
|
|
226
|
+
* \u7D2F\u79EF\u591A\u4E2A tool-box \u65F6\u6574\u5217\u88AB\u6324\u538B\uFF0Cbody \u88AB\u88C1\u6389\u5BFC\u81F4"\u6846\u9AD8\u5EA6\u53D8\u6210\u4E00\u6761\u7EBF"\u3002
|
|
227
|
+
* flex-shrink:0 \u5F3A\u5236\u4FDD\u7559\u81EA\u7136\u9AD8\u5EA6\uFF0C\u7531 #messages \u7684 overflow-y:auto \u6EDA\u52A8\u3002 */
|
|
228
|
+
flex-shrink: 0;
|
|
229
|
+
}
|
|
230
|
+
.thinking-block,
|
|
231
|
+
.msg {
|
|
232
|
+
flex-shrink: 0;
|
|
224
233
|
}
|
|
225
234
|
.tool-box-header {
|
|
226
235
|
background: #21262d;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhongqian97-code/ecode",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.58",
|
|
4
4
|
"description": "A minimal Claude Code clone with REPL interface and bash tool calling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "zhongqian97-code",
|
|
@@ -49,7 +49,8 @@
|
|
|
49
49
|
"fastify": "^5.8.5",
|
|
50
50
|
"ink": "^7.0.2",
|
|
51
51
|
"openai": "^4.0.0",
|
|
52
|
-
"react": "^19.2.5"
|
|
52
|
+
"react": "^19.2.5",
|
|
53
|
+
"string-width": "^8.2.1"
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
55
56
|
"@playwright/test": "^1.60.0",
|