@atlasharness/atlascode 0.1.38 → 0.1.39
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/cli.js +395 -89
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -135054,10 +135054,13 @@ function applyColor(text, color) {
|
|
|
135054
135054
|
}
|
|
135055
135055
|
return colorize(text, color, "foreground");
|
|
135056
135056
|
}
|
|
135057
|
-
var CHALK_BOOSTED_FOR_XTERMJS, CHALK_CLAMPED_FOR_TMUX, RGB_REGEX, ANSI_REGEX, colorize = (str, color, type) => {
|
|
135057
|
+
var CHALK_BOOSTED_FOR_XTERMJS, CHALK_CLAMPED_FOR_TMUX, RGB_REGEX, ANSI_REGEX, BARE_ANSI_COLOR_NAMES, colorize = (str, color, type) => {
|
|
135058
135058
|
if (!color) {
|
|
135059
135059
|
return str;
|
|
135060
135060
|
}
|
|
135061
|
+
if (BARE_ANSI_COLOR_NAMES.has(color)) {
|
|
135062
|
+
return colorize(str, `ansi:${color}`, type);
|
|
135063
|
+
}
|
|
135061
135064
|
if (color.startsWith("ansi:")) {
|
|
135062
135065
|
const value = color.substring("ansi:".length);
|
|
135063
135066
|
switch (value) {
|
|
@@ -135124,6 +135127,24 @@ var init_colorize = __esm(() => {
|
|
|
135124
135127
|
CHALK_CLAMPED_FOR_TMUX = clampChalkLevelForTmux();
|
|
135125
135128
|
RGB_REGEX = /^rgb\(\s?(\d+),\s?(\d+),\s?(\d+)\s?\)$/;
|
|
135126
135129
|
ANSI_REGEX = /^ansi256\(\s?(\d+)\s?\)$/;
|
|
135130
|
+
BARE_ANSI_COLOR_NAMES = new Set([
|
|
135131
|
+
"black",
|
|
135132
|
+
"red",
|
|
135133
|
+
"green",
|
|
135134
|
+
"yellow",
|
|
135135
|
+
"blue",
|
|
135136
|
+
"magenta",
|
|
135137
|
+
"cyan",
|
|
135138
|
+
"white",
|
|
135139
|
+
"blackBright",
|
|
135140
|
+
"redBright",
|
|
135141
|
+
"greenBright",
|
|
135142
|
+
"yellowBright",
|
|
135143
|
+
"blueBright",
|
|
135144
|
+
"magentaBright",
|
|
135145
|
+
"cyanBright",
|
|
135146
|
+
"whiteBright"
|
|
135147
|
+
]);
|
|
135127
135148
|
});
|
|
135128
135149
|
|
|
135129
135150
|
// src/tui/utils/earlyInput.ts
|
|
@@ -159664,7 +159685,14 @@ function resolveColor2(color, theme) {
|
|
|
159664
159685
|
if (color.startsWith("rgb(") || color.startsWith("#") || color.startsWith("ansi256(") || color.startsWith("ansi:")) {
|
|
159665
159686
|
return color;
|
|
159666
159687
|
}
|
|
159667
|
-
|
|
159688
|
+
const themed = theme[color];
|
|
159689
|
+
if (themed !== undefined) {
|
|
159690
|
+
return themed;
|
|
159691
|
+
}
|
|
159692
|
+
if (BARE_ANSI_COLOR_NAMES.has(color)) {
|
|
159693
|
+
return color;
|
|
159694
|
+
}
|
|
159695
|
+
return;
|
|
159668
159696
|
}
|
|
159669
159697
|
function ThemedText(t0) {
|
|
159670
159698
|
const $ = import_compiler_runtime7.c(10);
|
|
@@ -159723,6 +159751,7 @@ function ThemedText(t0) {
|
|
|
159723
159751
|
var import_compiler_runtime7, import_react12, jsx_dev_runtime10, TextHoverColorContext;
|
|
159724
159752
|
var init_ThemedText = __esm(() => {
|
|
159725
159753
|
init_Text();
|
|
159754
|
+
init_colorize();
|
|
159726
159755
|
init_theme();
|
|
159727
159756
|
init_ThemeProvider();
|
|
159728
159757
|
import_compiler_runtime7 = __toESM(require_compiler_runtime(), 1);
|
|
@@ -419856,6 +419885,7 @@ __export(exports_sessionStorage, {
|
|
|
419856
419885
|
clearAgentTranscriptSubdir: () => clearAgentTranscriptSubdir2,
|
|
419857
419886
|
clearSessionMessagesCache: () => clearSessionMessagesCache2,
|
|
419858
419887
|
clearSessionMetadata: () => clearSessionMetadata2,
|
|
419888
|
+
countVisibleMessages: () => countVisibleMessages2,
|
|
419859
419889
|
enrichLogs: () => enrichLogs,
|
|
419860
419890
|
extractTeammateTranscriptsFromTasks: () => extractTeammateTranscriptsFromTasks,
|
|
419861
419891
|
getAgentTranscript: () => getAgentTranscript,
|
|
@@ -473624,14 +473654,187 @@ function formatCreated(date) {
|
|
|
473624
473654
|
const d = date.getDate();
|
|
473625
473655
|
return `${m}/${d}/${date.getFullYear()}`;
|
|
473626
473656
|
}
|
|
473627
|
-
function
|
|
473657
|
+
function computeColumnLayout(termCols) {
|
|
473658
|
+
const NAME_MIN = 16;
|
|
473659
|
+
const ACTIVE_SLOT = 12;
|
|
473660
|
+
const CREATED_SLOT = 12;
|
|
473661
|
+
const BRANCH_SLOT = 13;
|
|
473662
|
+
const MSG_SLOT = 6;
|
|
473663
|
+
const LEFT = 4;
|
|
473664
|
+
const PAD = 4;
|
|
473665
|
+
const budget = termCols - PAD - LEFT - ACTIVE_SLOT;
|
|
473666
|
+
let showCreated = true;
|
|
473667
|
+
let showBranch = true;
|
|
473668
|
+
let showMsg = true;
|
|
473669
|
+
if (budget < NAME_MIN + CREATED_SLOT + BRANCH_SLOT + MSG_SLOT) {
|
|
473670
|
+
showMsg = false;
|
|
473671
|
+
if (budget < NAME_MIN + CREATED_SLOT + BRANCH_SLOT) {
|
|
473672
|
+
showBranch = false;
|
|
473673
|
+
if (budget < NAME_MIN + CREATED_SLOT) {
|
|
473674
|
+
showCreated = false;
|
|
473675
|
+
}
|
|
473676
|
+
}
|
|
473677
|
+
}
|
|
473678
|
+
let optional = 0;
|
|
473679
|
+
if (showCreated)
|
|
473680
|
+
optional += CREATED_SLOT;
|
|
473681
|
+
if (showBranch)
|
|
473682
|
+
optional += BRANCH_SLOT;
|
|
473683
|
+
if (showMsg)
|
|
473684
|
+
optional += MSG_SLOT;
|
|
473685
|
+
const flagsSlot = Math.round(budget * 0.3);
|
|
473686
|
+
const nameW = Math.max(NAME_MIN, budget - optional - flagsSlot);
|
|
473687
|
+
return { nameW, showCreated, showBranch, showMsg };
|
|
473688
|
+
}
|
|
473689
|
+
function agentColorToThemeColor(agentColor, theme) {
|
|
473690
|
+
const field = agentColor ? AGENT_COLOR_THEME_FIELD[agentColor] : undefined;
|
|
473691
|
+
return field ? theme[field] : undefined;
|
|
473692
|
+
}
|
|
473693
|
+
function agentRowColors(log, isSelected, isFocused, isCurrent, theme) {
|
|
473694
|
+
const identity = agentColorToThemeColor(log.agentColor, theme);
|
|
473695
|
+
const rowColor = isSelected ? "magentaBright" : isFocused ? "cyan" : identity;
|
|
473696
|
+
const dotGlyph = identity || isSelected || isCurrent ? "● " : "○ ";
|
|
473697
|
+
const dotColor = isSelected ? "magentaBright" : identity !== undefined ? identity : isCurrent ? "cyan" : undefined;
|
|
473698
|
+
return { rowColor, dotColor, dotGlyph };
|
|
473699
|
+
}
|
|
473700
|
+
function buildActionRow(state, title) {
|
|
473701
|
+
switch (state.kind) {
|
|
473702
|
+
case "confirm":
|
|
473703
|
+
return { text: `✋ ${title} · [再按 f 确认 fork · 3s 自动取消]`, color: "yellow" };
|
|
473704
|
+
case "forking":
|
|
473705
|
+
return { text: `→ forking ${title}…`, color: "yellow" };
|
|
473706
|
+
case "done":
|
|
473707
|
+
return { text: `✓ 已创建分支 ${title}`, color: "green" };
|
|
473708
|
+
case "error":
|
|
473709
|
+
return { text: `✗ fork 失败 · ${state.message}`, color: "red" };
|
|
473710
|
+
case "idle":
|
|
473711
|
+
default:
|
|
473712
|
+
return { text: SESSION_ROW_HINT };
|
|
473713
|
+
}
|
|
473714
|
+
}
|
|
473715
|
+
function rowSlotCost(idx, expandedIdx) {
|
|
473716
|
+
return idx === expandedIdx ? 2 : 1;
|
|
473717
|
+
}
|
|
473718
|
+
function slotPrefix(idx, expandedIdx, count) {
|
|
473719
|
+
const n = Math.min(Math.max(idx, 0), count);
|
|
473720
|
+
let slots = n;
|
|
473721
|
+
if (expandedIdx !== null && expandedIdx < n)
|
|
473722
|
+
slots += 1;
|
|
473723
|
+
return slots;
|
|
473724
|
+
}
|
|
473725
|
+
function computeRenderWindow(count, offset, expandedIdx, visibleRows) {
|
|
473726
|
+
if (count <= 0)
|
|
473727
|
+
return { start: 0, end: 0 };
|
|
473728
|
+
const start = Math.max(0, Math.min(offset, count - 1));
|
|
473729
|
+
let end = start;
|
|
473730
|
+
let slots = 0;
|
|
473731
|
+
while (end < count) {
|
|
473732
|
+
const cost = rowSlotCost(end, expandedIdx);
|
|
473733
|
+
if (slots + cost > visibleRows)
|
|
473734
|
+
break;
|
|
473735
|
+
slots += cost;
|
|
473736
|
+
end += 1;
|
|
473737
|
+
}
|
|
473738
|
+
return { start, end };
|
|
473739
|
+
}
|
|
473740
|
+
function clampWindowToCursor(focusedIdx, offset, expandedIdx, visibleRows, count) {
|
|
473741
|
+
if (count <= 0 || visibleRows <= 0)
|
|
473742
|
+
return 0;
|
|
473743
|
+
const cursor = Math.max(0, Math.min(focusedIdx, count - 1));
|
|
473744
|
+
let off = Math.max(0, Math.min(offset, count - 1));
|
|
473745
|
+
for (let guard = 0;guard <= count + 1; guard++) {
|
|
473746
|
+
const cStart = slotPrefix(cursor, expandedIdx, count);
|
|
473747
|
+
if (cStart < slotPrefix(off, expandedIdx, count))
|
|
473748
|
+
return cursor;
|
|
473749
|
+
const win = computeRenderWindow(count, off, expandedIdx, visibleRows);
|
|
473750
|
+
const cEnd = cStart + rowSlotCost(cursor, expandedIdx);
|
|
473751
|
+
if (cEnd <= slotPrefix(win.end, expandedIdx, count))
|
|
473752
|
+
return off;
|
|
473753
|
+
off += 1;
|
|
473754
|
+
}
|
|
473755
|
+
return Math.max(0, count - 1);
|
|
473756
|
+
}
|
|
473757
|
+
function getSummaryLine(log) {
|
|
473758
|
+
const s = (log.summary ?? "").trim();
|
|
473759
|
+
if (s)
|
|
473760
|
+
return s;
|
|
473761
|
+
const fp = log.firstPrompt ? stripDisplayTagsAllowEmpty(log.firstPrompt) : "";
|
|
473762
|
+
if (fp)
|
|
473763
|
+
return fp;
|
|
473764
|
+
return "(无摘要)";
|
|
473765
|
+
}
|
|
473766
|
+
function nextSortKey(current) {
|
|
473767
|
+
const i = SESSION_SORT_KEYS.indexOf(current);
|
|
473768
|
+
return SESSION_SORT_KEYS[(i + 1) % SESSION_SORT_KEYS.length];
|
|
473769
|
+
}
|
|
473770
|
+
function sortLogsBy(logs, key) {
|
|
473771
|
+
const out = [...logs];
|
|
473772
|
+
switch (key) {
|
|
473773
|
+
case "modified":
|
|
473774
|
+
out.sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
473775
|
+
break;
|
|
473776
|
+
case "created":
|
|
473777
|
+
out.sort((a, b) => b.created.getTime() - a.created.getTime());
|
|
473778
|
+
break;
|
|
473779
|
+
case "messages":
|
|
473780
|
+
out.sort((a, b) => (b.messageCount ?? 0) - (a.messageCount ?? 0));
|
|
473781
|
+
break;
|
|
473782
|
+
case "title":
|
|
473783
|
+
out.sort((a, b) => getLogDisplayTitle(a).localeCompare(getLogDisplayTitle(b)));
|
|
473784
|
+
break;
|
|
473785
|
+
}
|
|
473786
|
+
return out;
|
|
473787
|
+
}
|
|
473788
|
+
function filterLogs(logs, query) {
|
|
473789
|
+
const q = query.trim().toLowerCase();
|
|
473790
|
+
if (!q)
|
|
473791
|
+
return logs;
|
|
473792
|
+
return logs.filter((l) => [
|
|
473793
|
+
getLogDisplayTitle(l),
|
|
473794
|
+
l.summary ?? "",
|
|
473795
|
+
l.firstPrompt ?? "",
|
|
473796
|
+
l.gitBranch ?? "",
|
|
473797
|
+
l.tag ?? "",
|
|
473798
|
+
l.agentSetting ?? "",
|
|
473799
|
+
l.sessionId ?? ""
|
|
473800
|
+
].join(" ").toLowerCase().includes(q));
|
|
473801
|
+
}
|
|
473802
|
+
function makeLru(max) {
|
|
473803
|
+
const m = new Map;
|
|
473804
|
+
return {
|
|
473805
|
+
get: (k) => m.get(k),
|
|
473806
|
+
set: (k, v) => {
|
|
473807
|
+
if (m.has(k))
|
|
473808
|
+
m.delete(k);
|
|
473809
|
+
m.set(k, v);
|
|
473810
|
+
if (m.size > max) {
|
|
473811
|
+
const oldest = m.keys().next().value;
|
|
473812
|
+
if (oldest !== undefined)
|
|
473813
|
+
m.delete(oldest);
|
|
473814
|
+
}
|
|
473815
|
+
},
|
|
473816
|
+
has: (k) => m.has(k)
|
|
473817
|
+
};
|
|
473818
|
+
}
|
|
473819
|
+
function SessionTreeScreen({
|
|
473820
|
+
onBack,
|
|
473821
|
+
onResume,
|
|
473822
|
+
onAgenticSearch
|
|
473823
|
+
}) {
|
|
473628
473824
|
const [logs, setLogs] = React134.useState([]);
|
|
473629
473825
|
const [loading, setLoading] = React134.useState(true);
|
|
473630
473826
|
const [focusedIdx, setFocusedIdx] = React134.useState(0);
|
|
473631
473827
|
const [selectedIdx, setSelectedIdx] = React134.useState(null);
|
|
473632
473828
|
const [rowStates, setRowStates] = React134.useState(new Map);
|
|
473633
|
-
const [bottomMessage, setBottomMessage] = React134.useState(null);
|
|
473634
473829
|
const [scrollOffset, setScrollOffset] = React134.useState(0);
|
|
473830
|
+
const [expanded, setExpanded] = React134.useState(false);
|
|
473831
|
+
const expandedIdx = expanded ? focusedIdx : null;
|
|
473832
|
+
const [searchMode, setSearchMode] = React134.useState(false);
|
|
473833
|
+
const [query, setQuery] = React134.useState("");
|
|
473834
|
+
const [sortKey, setSortKey] = React134.useState("modified");
|
|
473835
|
+
const [agenticResults, setAgenticResults] = React134.useState(null);
|
|
473836
|
+
const exactCountCacheRef = React134.useRef(makeLru(64));
|
|
473837
|
+
const [, bumpExactCounts] = React134.useReducer((x) => x + 1, 0);
|
|
473635
473838
|
const confirmTimerRef = React134.useRef(null);
|
|
473636
473839
|
const forkInFlightRef = React134.useRef(false);
|
|
473637
473840
|
const fileMetaCacheRef = React134.useRef(new Map);
|
|
@@ -473692,7 +473895,6 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473692
473895
|
} catch (err) {
|
|
473693
473896
|
const message = err instanceof Error ? err.message : String(err);
|
|
473694
473897
|
setRowState(target.sessionId, { kind: "error", message });
|
|
473695
|
-
setBottomMessage(message);
|
|
473696
473898
|
setTimeout(() => setRowState(target.sessionId, { kind: "idle" }), 2000);
|
|
473697
473899
|
} finally {
|
|
473698
473900
|
forkInFlightRef.current = false;
|
|
@@ -473702,41 +473904,90 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473702
473904
|
setFocusedIdx(idx);
|
|
473703
473905
|
setSelectedIdx(null);
|
|
473704
473906
|
}
|
|
473705
|
-
|
|
473706
|
-
|
|
473707
|
-
|
|
473708
|
-
|
|
473709
|
-
|
|
473710
|
-
|
|
473711
|
-
|
|
473712
|
-
|
|
473713
|
-
|
|
473907
|
+
const computeViewLogs = React134.useCallback((base, q, sk, agentic) => {
|
|
473908
|
+
const local = q ? filterLogs(base, q) : base;
|
|
473909
|
+
const chosen = agentic && local.length === 0 ? agentic : local;
|
|
473910
|
+
return sortLogsBy(chosen, sk);
|
|
473911
|
+
}, []);
|
|
473912
|
+
const ensureExactCount = React134.useCallback(async (log) => {
|
|
473913
|
+
const sid = log.sessionId ?? "";
|
|
473914
|
+
if (!sid)
|
|
473915
|
+
return;
|
|
473916
|
+
if (exactCountCacheRef.current.has(sid))
|
|
473917
|
+
return;
|
|
473918
|
+
try {
|
|
473919
|
+
const full = isLiteLog(log) ? await loadFullLog(log) : log;
|
|
473920
|
+
exactCountCacheRef.current.set(sid, countVisibleMessages2(full.messages));
|
|
473921
|
+
bumpExactCounts();
|
|
473922
|
+
} catch {}
|
|
473923
|
+
}, [bumpExactCounts]);
|
|
473714
473924
|
use_input_default((input, key, event) => {
|
|
473715
473925
|
if (loading)
|
|
473716
473926
|
return;
|
|
473717
|
-
const
|
|
473927
|
+
const view = computeViewLogs(logs, query, sortKey, agenticResults);
|
|
473928
|
+
if (searchMode) {
|
|
473929
|
+
if (key.backspace) {
|
|
473930
|
+
setQuery((q) => q.slice(0, -1));
|
|
473931
|
+
setAgenticResults(null);
|
|
473932
|
+
setFocusedIdx(0);
|
|
473933
|
+
} else if (key.escape || input === "/") {
|
|
473934
|
+
setSearchMode(false);
|
|
473935
|
+
setQuery("");
|
|
473936
|
+
setAgenticResults(null);
|
|
473937
|
+
setFocusedIdx(0);
|
|
473938
|
+
} else if (key.return) {
|
|
473939
|
+
if (onAgenticSearch && query.trim()) {
|
|
473940
|
+
const localCount = filterLogs(logs, query).length;
|
|
473941
|
+
if (localCount === 0) {
|
|
473942
|
+
onAgenticSearch(query, logs).then((r) => setAgenticResults(r)).catch(() => {});
|
|
473943
|
+
}
|
|
473944
|
+
}
|
|
473945
|
+
} else if (input.length === 1 && !key.ctrl && !key.meta && !key.backspace && !key.return && !key.escape && input >= " ") {
|
|
473946
|
+
setQuery((q) => q + input);
|
|
473947
|
+
setAgenticResults(null);
|
|
473948
|
+
setFocusedIdx(0);
|
|
473949
|
+
}
|
|
473950
|
+
event.stopImmediatePropagation();
|
|
473951
|
+
return;
|
|
473952
|
+
}
|
|
473953
|
+
const current = view[focusedIdx];
|
|
473718
473954
|
if (!current)
|
|
473719
473955
|
return;
|
|
473720
473956
|
const state = rowStates.get(current.sessionId ?? "")?.kind ?? "idle";
|
|
473721
473957
|
if (state === "forking")
|
|
473722
473958
|
return;
|
|
473959
|
+
if (input === "/") {
|
|
473960
|
+
setSearchMode(true);
|
|
473961
|
+
setQuery("");
|
|
473962
|
+
setAgenticResults(null);
|
|
473963
|
+
setFocusedIdx(0);
|
|
473964
|
+
event.stopImmediatePropagation();
|
|
473965
|
+
return;
|
|
473966
|
+
} else if (input === "s") {
|
|
473967
|
+
setSortKey((sk) => nextSortKey(sk));
|
|
473968
|
+
setFocusedIdx(0);
|
|
473969
|
+
setScrollOffset(0);
|
|
473970
|
+
event.stopImmediatePropagation();
|
|
473971
|
+
return;
|
|
473972
|
+
}
|
|
473723
473973
|
const termRows = process.stdout.rows ?? 24;
|
|
473724
|
-
const HEADER_ROWS = 3;
|
|
473725
|
-
const FOOTER_ROWS = 2;
|
|
473726
473974
|
const visibleRows = Math.max(1, termRows - HEADER_ROWS - FOOTER_ROWS);
|
|
473975
|
+
const clamp = (next, off) => clampWindowToCursor(next, off, expandedIdx, visibleRows, view.length);
|
|
473727
473976
|
if (key.upArrow || key.wheelUp) {
|
|
473728
473977
|
setSelectedIdx(null);
|
|
473729
473978
|
setFocusedIdx((i) => {
|
|
473730
473979
|
const next = Math.max(0, i - 1);
|
|
473731
|
-
setScrollOffset((off) =>
|
|
473980
|
+
setScrollOffset((off) => clamp(next, off));
|
|
473981
|
+
ensureExactCount(view[next]);
|
|
473732
473982
|
return next;
|
|
473733
473983
|
});
|
|
473734
473984
|
event.stopImmediatePropagation();
|
|
473735
473985
|
} else if (key.downArrow || key.wheelDown) {
|
|
473736
473986
|
setSelectedIdx(null);
|
|
473737
473987
|
setFocusedIdx((i) => {
|
|
473738
|
-
const next = Math.min(
|
|
473739
|
-
setScrollOffset((off) =>
|
|
473988
|
+
const next = Math.min(view.length - 1, i + 1);
|
|
473989
|
+
setScrollOffset((off) => clamp(next, off));
|
|
473990
|
+
ensureExactCount(view[next]);
|
|
473740
473991
|
return next;
|
|
473741
473992
|
});
|
|
473742
473993
|
event.stopImmediatePropagation();
|
|
@@ -473744,18 +473995,23 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473744
473995
|
setSelectedIdx(null);
|
|
473745
473996
|
setFocusedIdx((i) => {
|
|
473746
473997
|
const next = Math.max(0, i - visibleRows);
|
|
473747
|
-
setScrollOffset((off) =>
|
|
473998
|
+
setScrollOffset((off) => clamp(next, off));
|
|
473999
|
+
ensureExactCount(view[next]);
|
|
473748
474000
|
return next;
|
|
473749
474001
|
});
|
|
473750
474002
|
event.stopImmediatePropagation();
|
|
473751
474003
|
} else if (key.pageDown) {
|
|
473752
474004
|
setSelectedIdx(null);
|
|
473753
474005
|
setFocusedIdx((i) => {
|
|
473754
|
-
const next = Math.min(
|
|
473755
|
-
setScrollOffset((off) =>
|
|
474006
|
+
const next = Math.min(view.length - 1, i + visibleRows);
|
|
474007
|
+
setScrollOffset((off) => clamp(next, off));
|
|
474008
|
+
ensureExactCount(view[next]);
|
|
473756
474009
|
return next;
|
|
473757
474010
|
});
|
|
473758
474011
|
event.stopImmediatePropagation();
|
|
474012
|
+
} else if (input === "x") {
|
|
474013
|
+
setExpanded((e) => e ? false : visibleRows >= 2);
|
|
474014
|
+
event.stopImmediatePropagation();
|
|
473759
474015
|
} else if (key.escape || input === "q") {
|
|
473760
474016
|
onBack();
|
|
473761
474017
|
event.stopImmediatePropagation();
|
|
@@ -473805,26 +474061,26 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473805
474061
|
}, undefined, true, undefined, this);
|
|
473806
474062
|
}
|
|
473807
474063
|
const currentSessionId = getSessionId();
|
|
474064
|
+
const viewLogs = computeViewLogs(logs, query, sortKey, agenticResults);
|
|
473808
474065
|
const termCols = process.stdout.columns ?? 100;
|
|
473809
474066
|
const termRows = process.stdout.rows ?? 24;
|
|
473810
|
-
const
|
|
474067
|
+
const layout = computeColumnLayout(termCols);
|
|
473811
474068
|
const CURSOR_W = 2;
|
|
473812
474069
|
const ICON_W = 2;
|
|
473813
|
-
const NAME_W =
|
|
474070
|
+
const NAME_W = layout.nameW;
|
|
473814
474071
|
const CREATED_W = 11;
|
|
473815
474072
|
const ACTIVE_W = 11;
|
|
473816
474073
|
const BRANCH_W = 12;
|
|
473817
474074
|
const MSG_W = 5;
|
|
473818
474075
|
const GAP = 1;
|
|
473819
|
-
const showCreated =
|
|
473820
|
-
const showBranch =
|
|
473821
|
-
const showMsg =
|
|
473822
|
-
const HEADER_ROWS = NARROW ? 4 : 4;
|
|
473823
|
-
const FOOTER_ROWS = 2;
|
|
474076
|
+
const showCreated = layout.showCreated;
|
|
474077
|
+
const showBranch = layout.showBranch;
|
|
474078
|
+
const showMsg = layout.showMsg;
|
|
473824
474079
|
const visibleRows = Math.max(1, termRows - HEADER_ROWS - FOOTER_ROWS);
|
|
473825
|
-
const effectiveOffset = Math.min(scrollOffset, Math.max(0,
|
|
473826
|
-
const
|
|
473827
|
-
const
|
|
474080
|
+
const effectiveOffset = Math.min(scrollOffset, Math.max(0, viewLogs.length - visibleRows));
|
|
474081
|
+
const win = computeRenderWindow(viewLogs.length, effectiveOffset, expandedIdx, visibleRows);
|
|
474082
|
+
const startIdx = win.start;
|
|
474083
|
+
const endIdx = win.end;
|
|
473828
474084
|
let fixedW = CURSOR_W + ICON_W + NAME_W + ACTIVE_W;
|
|
473829
474085
|
let gapCount = 3;
|
|
473830
474086
|
if (showCreated) {
|
|
@@ -473840,8 +474096,31 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473840
474096
|
gapCount++;
|
|
473841
474097
|
}
|
|
473842
474098
|
fixedW += gapCount * GAP;
|
|
473843
|
-
const
|
|
474099
|
+
const sortIndicator = ` · 排序:${SESSION_SORT_LABELS[sortKey]}`;
|
|
474100
|
+
const filterIndicator = query ? ` · 过滤:"${query}"` : "";
|
|
474101
|
+
const headerLine = truncateToVisibleWidth(" " + " " + padToVisibleWidth("名称", NAME_W) + " " + (showCreated ? padToVisibleWidth("创建", CREATED_W) + " " : "") + padToVisibleWidth("最近活跃", ACTIVE_W) + (showBranch ? " " + padToVisibleWidth("分支", BRANCH_W) : "") + (showMsg ? " " + padLeftToVisibleWidth("消息", MSG_W) : "") + sortIndicator + filterIndicator, Math.max(10, termCols - 4));
|
|
473844
474102
|
const nowMs = Date.now();
|
|
474103
|
+
const theme = getTheme(resolveThemeSetting(getGlobalConfig().theme));
|
|
474104
|
+
const STATE_PRIORITY = {
|
|
474105
|
+
forking: 4,
|
|
474106
|
+
confirm: 3,
|
|
474107
|
+
done: 2,
|
|
474108
|
+
error: 1,
|
|
474109
|
+
idle: 0
|
|
474110
|
+
};
|
|
474111
|
+
let activeState = { kind: "idle" };
|
|
474112
|
+
let activeSid = "";
|
|
474113
|
+
for (const [sid, s] of rowStates) {
|
|
474114
|
+
if (STATE_PRIORITY[s.kind] > STATE_PRIORITY[activeState.kind]) {
|
|
474115
|
+
activeState = s;
|
|
474116
|
+
activeSid = sid;
|
|
474117
|
+
}
|
|
474118
|
+
}
|
|
474119
|
+
const actionLog = activeSid ? logs.find((l) => l.sessionId === activeSid) : undefined;
|
|
474120
|
+
const actionRow = buildActionRow(activeState, actionLog ? getLogDisplayTitle(actionLog) || "untitled" : "untitled");
|
|
474121
|
+
const searchActionText = searchMode ? `搜索:"${query}"${onAgenticSearch ? " · enter 触发语义搜索" : ""} · esc 退出` : undefined;
|
|
474122
|
+
const actionText = truncateToVisibleWidth(searchActionText ?? actionRow.text, Math.max(10, termCols - 4));
|
|
474123
|
+
const actionColor = searchMode ? "cyan" : actionRow.color;
|
|
473845
474124
|
return /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedBox_default, {
|
|
473846
474125
|
flexDirection: "column",
|
|
473847
474126
|
paddingX: 2,
|
|
@@ -473868,35 +474147,20 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473868
474147
|
const isCurrent = sid === currentSessionId;
|
|
473869
474148
|
const cached = fileMetaCacheRef.current.get(sid);
|
|
473870
474149
|
const isBranch = cached?.isBranch ?? false;
|
|
473871
|
-
const rowState = rowStates.get(sid)?.kind ?? "idle";
|
|
473872
|
-
const rowStateObj = rowStates.get(sid);
|
|
473873
474150
|
const cursor = isSelected ? "» " : isFocused ? "> " : " ";
|
|
473874
|
-
const
|
|
474151
|
+
const { rowColor, dotColor, dotGlyph } = agentRowColors(log, isSelected, isFocused, isCurrent, theme);
|
|
473875
474152
|
const title = truncateToVisibleWidth(getLogDisplayTitle(log) || "untitled", NAME_W);
|
|
473876
474153
|
const created = formatCreated(log.created);
|
|
473877
474154
|
const active = formatActive(log.modified, nowMs);
|
|
473878
474155
|
const branch = log.gitBranch ? truncateToVisibleWidth(log.gitBranch, BRANCH_W) : "—";
|
|
473879
|
-
const
|
|
473880
|
-
|
|
474156
|
+
const exactCount = exactCountCacheRef.current.get(sid);
|
|
474157
|
+
const msgCount = String(exactCount ?? cached?.messageCount ?? log.messageCount ?? 0);
|
|
474158
|
+
let line = cursor + dotGlyph + padToVisibleWidth(title, NAME_W) + " " + (showCreated ? padToVisibleWidth(created, CREATED_W) + " " : "") + padToVisibleWidth(active, ACTIVE_W);
|
|
473881
474159
|
if (showBranch)
|
|
473882
474160
|
line += " " + padToVisibleWidth(branch, BRANCH_W);
|
|
473883
474161
|
if (showMsg)
|
|
473884
474162
|
line += " " + padLeftToVisibleWidth(msgCount, MSG_W);
|
|
473885
474163
|
let flags = "";
|
|
473886
|
-
let statusColor;
|
|
473887
|
-
if (rowState === "confirm") {
|
|
473888
|
-
flags += " [f 确认 fork]";
|
|
473889
|
-
statusColor = "yellow";
|
|
473890
|
-
} else if (rowState === "forking") {
|
|
473891
|
-
flags += " → forking…";
|
|
473892
|
-
statusColor = "yellow";
|
|
473893
|
-
} else if (rowState === "done") {
|
|
473894
|
-
flags += " ✓ 已创建分支";
|
|
473895
|
-
statusColor = "green";
|
|
473896
|
-
} else if (rowState === "error") {
|
|
473897
|
-
flags += " ✗ fork 失败";
|
|
473898
|
-
statusColor = "red";
|
|
473899
|
-
}
|
|
473900
474164
|
if (isBranch)
|
|
473901
474165
|
flags += " (Branch)";
|
|
473902
474166
|
if (isCurrent)
|
|
@@ -473907,70 +474171,112 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473907
474171
|
flags += ` @${log.agentSetting}`;
|
|
473908
474172
|
if (log.mode === "coordinator")
|
|
473909
474173
|
flags += " [C]";
|
|
474174
|
+
if (log.prNumber)
|
|
474175
|
+
flags += ` [PR #${log.prNumber}]`;
|
|
474176
|
+
if (log.fileSize)
|
|
474177
|
+
flags += ` (${formatFileSize3(log.fileSize)})`;
|
|
474178
|
+
if (log.worktreeSession?.worktreeName) {
|
|
474179
|
+
flags += ` [wt:${log.worktreeSession.worktreeName}]`;
|
|
474180
|
+
}
|
|
473910
474181
|
const maxFlags = termCols - 2 - fixedW;
|
|
473911
474182
|
if (visibleWidth(flags) > maxFlags) {
|
|
473912
474183
|
flags = truncateToVisibleWidth(flags, maxFlags);
|
|
473913
474184
|
}
|
|
473914
474185
|
line += " " + flags;
|
|
473915
|
-
const
|
|
473916
|
-
return /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(
|
|
473917
|
-
|
|
473918
|
-
|
|
473919
|
-
|
|
473920
|
-
|
|
473921
|
-
|
|
473922
|
-
|
|
473923
|
-
|
|
473924
|
-
|
|
473925
|
-
|
|
474186
|
+
const summaryLine = " └ " + truncateToVisibleWidth(getSummaryLine(log), termCols - 4 - 6);
|
|
474187
|
+
return /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(React134.Fragment, {
|
|
474188
|
+
children: [
|
|
474189
|
+
/* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedBox_default, {
|
|
474190
|
+
noSelect: true,
|
|
474191
|
+
onClick: () => handleRowClick(i),
|
|
474192
|
+
children: /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedBox_default, {
|
|
474193
|
+
flexDirection: "row",
|
|
474194
|
+
noSelect: true,
|
|
474195
|
+
children: [
|
|
474196
|
+
/* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedText, {
|
|
474197
|
+
color: rowColor,
|
|
474198
|
+
bold: isFocused || isSelected,
|
|
474199
|
+
children: line.slice(0, 2)
|
|
474200
|
+
}, undefined, false, undefined, this),
|
|
474201
|
+
/* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedText, {
|
|
474202
|
+
color: dotColor,
|
|
474203
|
+
bold: isFocused || isSelected,
|
|
474204
|
+
children: line.slice(2, 4)
|
|
474205
|
+
}, undefined, false, undefined, this),
|
|
474206
|
+
/* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedText, {
|
|
474207
|
+
color: rowColor,
|
|
474208
|
+
bold: isFocused || isSelected,
|
|
474209
|
+
wrap: "truncate",
|
|
474210
|
+
children: line.slice(4)
|
|
474211
|
+
}, undefined, false, undefined, this)
|
|
474212
|
+
]
|
|
474213
|
+
}, undefined, true, undefined, this)
|
|
474214
|
+
}, undefined, false, undefined, this),
|
|
474215
|
+
i === expandedIdx && /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedBox_default, {
|
|
474216
|
+
noSelect: true,
|
|
474217
|
+
children: /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedText, {
|
|
474218
|
+
dimColor: true,
|
|
474219
|
+
wrap: "truncate",
|
|
474220
|
+
children: summaryLine
|
|
474221
|
+
}, undefined, false, undefined, this)
|
|
474222
|
+
}, undefined, false, undefined, this)
|
|
474223
|
+
]
|
|
474224
|
+
}, sid || i, true, undefined, this);
|
|
473926
474225
|
}),
|
|
473927
|
-
|
|
474226
|
+
viewLogs.length === 0 && /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedText, {
|
|
473928
474227
|
dimColor: true,
|
|
473929
|
-
children: "No sessions found"
|
|
474228
|
+
children: query ? `No sessions match "${query}"` : "No sessions found"
|
|
473930
474229
|
}, undefined, false, undefined, this)
|
|
473931
474230
|
]
|
|
473932
474231
|
}, undefined, true, undefined, this),
|
|
473933
474232
|
/* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedBox_default, {
|
|
473934
474233
|
marginTop: 1,
|
|
473935
474234
|
children: /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedText, {
|
|
473936
|
-
|
|
473937
|
-
|
|
473938
|
-
}, undefined, false, undefined, this)
|
|
473939
|
-
}, undefined, false, undefined, this),
|
|
473940
|
-
bottomMessage && /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedBox_default, {
|
|
473941
|
-
marginTop: 1,
|
|
473942
|
-
children: /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedText, {
|
|
473943
|
-
color: "red",
|
|
474235
|
+
color: actionColor,
|
|
474236
|
+
dimColor: !actionColor,
|
|
473944
474237
|
wrap: "truncate",
|
|
473945
|
-
children:
|
|
473946
|
-
|
|
473947
|
-
bottomMessage
|
|
473948
|
-
]
|
|
473949
|
-
}, undefined, true, undefined, this)
|
|
474238
|
+
children: actionText
|
|
474239
|
+
}, undefined, false, undefined, this)
|
|
473950
474240
|
}, undefined, false, undefined, this)
|
|
473951
474241
|
]
|
|
473952
474242
|
}, undefined, true, undefined, this);
|
|
473953
474243
|
}
|
|
473954
|
-
var React134, jsx_dev_runtime424,
|
|
474244
|
+
var React134, jsx_dev_runtime424, AGENT_COLOR_THEME_FIELD, SESSION_ROW_HINT = "\uD83D\uDDB1 点击移动光标 · 滚轮/↑↓ 滚动 · enter 选中/进入 · f fork · x 摘要 · q 返回", SESSION_SORT_KEYS, SESSION_SORT_LABELS, HEADER_ROWS = 4, FOOTER_ROWS = 2;
|
|
473955
474245
|
var init_SessionTreeScreen = __esm(() => {
|
|
473956
474246
|
init_ink2();
|
|
474247
|
+
init_config6();
|
|
474248
|
+
init_format2();
|
|
474249
|
+
init_theme();
|
|
473957
474250
|
init_sessionStorage();
|
|
473958
474251
|
init_worktree4();
|
|
473959
474252
|
init_bootstrap();
|
|
473960
474253
|
init_log5();
|
|
474254
|
+
init_displayTags();
|
|
473961
474255
|
init_sessionStorage();
|
|
473962
474256
|
init_branch();
|
|
473963
474257
|
React134 = __toESM(require_react(), 1);
|
|
473964
474258
|
jsx_dev_runtime424 = __toESM(require_jsx_dev_runtime(), 1);
|
|
473965
|
-
|
|
473966
|
-
red: "
|
|
473967
|
-
blue: "
|
|
473968
|
-
green: "
|
|
473969
|
-
yellow: "
|
|
473970
|
-
purple: "
|
|
473971
|
-
orange: "
|
|
473972
|
-
pink: "
|
|
473973
|
-
cyan: "
|
|
474259
|
+
AGENT_COLOR_THEME_FIELD = {
|
|
474260
|
+
red: "red_FOR_SUBAGENTS_ONLY",
|
|
474261
|
+
blue: "blue_FOR_SUBAGENTS_ONLY",
|
|
474262
|
+
green: "green_FOR_SUBAGENTS_ONLY",
|
|
474263
|
+
yellow: "yellow_FOR_SUBAGENTS_ONLY",
|
|
474264
|
+
purple: "purple_FOR_SUBAGENTS_ONLY",
|
|
474265
|
+
orange: "orange_FOR_SUBAGENTS_ONLY",
|
|
474266
|
+
pink: "pink_FOR_SUBAGENTS_ONLY",
|
|
474267
|
+
cyan: "cyan_FOR_SUBAGENTS_ONLY"
|
|
474268
|
+
};
|
|
474269
|
+
SESSION_SORT_KEYS = [
|
|
474270
|
+
"modified",
|
|
474271
|
+
"created",
|
|
474272
|
+
"messages",
|
|
474273
|
+
"title"
|
|
474274
|
+
];
|
|
474275
|
+
SESSION_SORT_LABELS = {
|
|
474276
|
+
modified: "最近活跃",
|
|
474277
|
+
created: "创建",
|
|
474278
|
+
messages: "消息数",
|
|
474279
|
+
title: "名称"
|
|
473974
474280
|
};
|
|
473975
474281
|
});
|
|
473976
474282
|
|
package/package.json
CHANGED