@atlasharness/atlascode 0.1.37 → 0.1.38
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 +98 -36
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -419883,6 +419883,7 @@ __export(exports_sessionStorage, {
|
|
|
419883
419883
|
loadAllSubagentTranscriptsFromDisk: () => loadAllSubagentTranscriptsFromDisk,
|
|
419884
419884
|
loadFullLog: () => loadFullLog,
|
|
419885
419885
|
loadMessageLogs: () => loadMessageLogs,
|
|
419886
|
+
loadSameRepoAllMessageLogs: () => loadSameRepoAllMessageLogs,
|
|
419886
419887
|
loadSameRepoMessageLogs: () => loadSameRepoMessageLogs,
|
|
419887
419888
|
loadSameRepoMessageLogsProgressive: () => loadSameRepoMessageLogsProgressive,
|
|
419888
419889
|
loadTranscriptFile: () => loadTranscriptFile2,
|
|
@@ -421829,6 +421830,21 @@ async function loadSameRepoMessageLogsProgressive(worktreePaths, limit, initialE
|
|
|
421829
421830
|
});
|
|
421830
421831
|
return { logs, allStatLogs, nextIndex };
|
|
421831
421832
|
}
|
|
421833
|
+
async function loadSameRepoAllMessageLogs(worktreePaths) {
|
|
421834
|
+
const r = await loadSameRepoMessageLogsProgressive(worktreePaths);
|
|
421835
|
+
let logs = r.logs;
|
|
421836
|
+
let nextIndex = r.nextIndex;
|
|
421837
|
+
while (nextIndex < r.allStatLogs.length) {
|
|
421838
|
+
const more = await enrichLogs(r.allStatLogs, nextIndex, INITIAL_ENRICH_COUNT);
|
|
421839
|
+
logs = logs.concat(more.logs);
|
|
421840
|
+
nextIndex = more.nextIndex;
|
|
421841
|
+
}
|
|
421842
|
+
logs = sortLogs2(logs);
|
|
421843
|
+
logs.forEach((l, i) => {
|
|
421844
|
+
l.value = i;
|
|
421845
|
+
});
|
|
421846
|
+
return logs;
|
|
421847
|
+
}
|
|
421832
421848
|
async function getStatOnlyLogsForWorktrees(worktreePaths, limit) {
|
|
421833
421849
|
const projectsDir = getProjectsDir3();
|
|
421834
421850
|
if (worktreePaths.length <= 1) {
|
|
@@ -422027,7 +422043,7 @@ async function getSessionFilesWithMtime(projectDir) {
|
|
|
422027
422043
|
sessionFilesMap.set(sessionId, {
|
|
422028
422044
|
path: filePath,
|
|
422029
422045
|
mtime: st.mtime.getTime(),
|
|
422030
|
-
|
|
422046
|
+
birthtime: st.birthtime.getTime(),
|
|
422031
422047
|
size: st.size
|
|
422032
422048
|
});
|
|
422033
422049
|
} catch {
|
|
@@ -422138,10 +422154,18 @@ async function readLiteMetadata(filePath, fileSize, buf) {
|
|
|
422138
422154
|
const { head, tail } = await readHeadAndTail(filePath, fileSize, buf);
|
|
422139
422155
|
if (!head)
|
|
422140
422156
|
return { firstPrompt: "", isSidechain: false };
|
|
422141
|
-
const
|
|
422157
|
+
const firstLine = head.split(`
|
|
422158
|
+
`, 1)[0] ?? "";
|
|
422159
|
+
const isSidechain = firstLine.includes('"isSidechain":true') || firstLine.includes('"isSidechain": true');
|
|
422142
422160
|
const projectPath = extractJsonStringField(head, "cwd");
|
|
422143
422161
|
const teamName = extractJsonStringField(head, "teamName");
|
|
422144
422162
|
const agentSetting = extractJsonStringField(head, "agentSetting");
|
|
422163
|
+
const lastTimestamp = extractLastJsonStringField2(tail, "timestamp");
|
|
422164
|
+
const firstTimestamp = extractJsonStringField(head, "timestamp");
|
|
422165
|
+
const modeRaw = extractLastJsonStringField2(tail, "mode");
|
|
422166
|
+
const mode = modeRaw === "coordinator" || modeRaw === "normal" ? modeRaw : undefined;
|
|
422167
|
+
const agentName = extractLastJsonStringField2(tail, "agentName");
|
|
422168
|
+
const agentColor = extractLastJsonStringField2(tail, "agentColor");
|
|
422145
422169
|
const firstPrompt = extractLastJsonStringField2(tail, "lastPrompt") || extractFirstPromptFromChunk(head) || extractJsonStringFieldPrefix(head, "content", 200) || extractJsonStringFieldPrefix(head, "text", 200) || "";
|
|
422146
422170
|
const customTitle = extractLastJsonStringField2(tail, "customTitle") ?? extractLastJsonStringField2(head, "customTitle") ?? extractLastJsonStringField2(tail, "aiTitle") ?? extractLastJsonStringField2(head, "aiTitle");
|
|
422147
422171
|
const summary = extractLastJsonStringField2(tail, "summary");
|
|
@@ -422177,7 +422201,12 @@ async function readLiteMetadata(filePath, fileSize, buf) {
|
|
|
422177
422201
|
worktreeName,
|
|
422178
422202
|
prNumber,
|
|
422179
422203
|
prUrl,
|
|
422180
|
-
prRepository
|
|
422204
|
+
prRepository,
|
|
422205
|
+
firstTimestamp,
|
|
422206
|
+
lastTimestamp,
|
|
422207
|
+
mode,
|
|
422208
|
+
agentName,
|
|
422209
|
+
agentColor
|
|
422181
422210
|
};
|
|
422182
422211
|
}
|
|
422183
422212
|
function extractFirstPromptFromChunk(chunk) {
|
|
@@ -422300,7 +422329,7 @@ async function getSessionFilesLite(projectDir, limit, projectPath) {
|
|
|
422300
422329
|
isLite: true,
|
|
422301
422330
|
fullPath: fileInfo.path,
|
|
422302
422331
|
value: 0,
|
|
422303
|
-
created: new Date(fileInfo.
|
|
422332
|
+
created: new Date(fileInfo.birthtime),
|
|
422304
422333
|
modified: new Date(fileInfo.mtime),
|
|
422305
422334
|
firstPrompt: "",
|
|
422306
422335
|
messageCount: 0,
|
|
@@ -422316,6 +422345,12 @@ async function getSessionFilesLite(projectDir, limit, projectPath) {
|
|
|
422316
422345
|
});
|
|
422317
422346
|
return sorted;
|
|
422318
422347
|
}
|
|
422348
|
+
function parseLiteTimestamp(iso) {
|
|
422349
|
+
if (!iso)
|
|
422350
|
+
return;
|
|
422351
|
+
const d = new Date(iso);
|
|
422352
|
+
return Number.isNaN(d.getTime()) ? undefined : d;
|
|
422353
|
+
}
|
|
422319
422354
|
async function enrichLog(log, readBuf) {
|
|
422320
422355
|
if (!log.isLite || !log.fullPath)
|
|
422321
422356
|
return log;
|
|
@@ -422331,10 +422366,15 @@ async function enrichLog(log, readBuf) {
|
|
|
422331
422366
|
summary: meta.summary,
|
|
422332
422367
|
tag: meta.tag,
|
|
422333
422368
|
agentSetting: meta.agentSetting,
|
|
422369
|
+
mode: meta.mode,
|
|
422370
|
+
agentName: meta.agentName,
|
|
422371
|
+
agentColor: meta.agentColor,
|
|
422334
422372
|
prNumber: meta.prNumber,
|
|
422335
422373
|
prUrl: meta.prUrl,
|
|
422336
422374
|
prRepository: meta.prRepository,
|
|
422337
422375
|
projectPath: meta.projectPath ?? log.projectPath,
|
|
422376
|
+
created: parseLiteTimestamp(meta.firstTimestamp) ?? log.created,
|
|
422377
|
+
modified: parseLiteTimestamp(meta.lastTimestamp) ?? log.modified,
|
|
422338
422378
|
worktreeSession: meta.worktreeName ? {
|
|
422339
422379
|
worktreeName: meta.worktreeName,
|
|
422340
422380
|
originalCwd: "",
|
|
@@ -473564,6 +473604,26 @@ function formatShortActive(date) {
|
|
|
473564
473604
|
const min = String(date.getMinutes()).padStart(2, "0");
|
|
473565
473605
|
return `${m}/${d} ${h}:${min}`;
|
|
473566
473606
|
}
|
|
473607
|
+
function formatActive(date, now) {
|
|
473608
|
+
const ageMs = now - date.getTime();
|
|
473609
|
+
const m = Math.floor(ageMs / 60000);
|
|
473610
|
+
if (m < 1)
|
|
473611
|
+
return "now";
|
|
473612
|
+
if (m < 60)
|
|
473613
|
+
return `${m}m`;
|
|
473614
|
+
const h = Math.floor(m / 60);
|
|
473615
|
+
if (h < 24)
|
|
473616
|
+
return `${h}h`;
|
|
473617
|
+
const d = Math.floor(h / 24);
|
|
473618
|
+
if (d < 7)
|
|
473619
|
+
return `${d}d`;
|
|
473620
|
+
return formatShortActive(date);
|
|
473621
|
+
}
|
|
473622
|
+
function formatCreated(date) {
|
|
473623
|
+
const m = date.getMonth() + 1;
|
|
473624
|
+
const d = date.getDate();
|
|
473625
|
+
return `${m}/${d}/${date.getFullYear()}`;
|
|
473626
|
+
}
|
|
473567
473627
|
function SessionTreeScreen({ onBack, onResume }) {
|
|
473568
473628
|
const [logs, setLogs] = React134.useState([]);
|
|
473569
473629
|
const [loading, setLoading] = React134.useState(true);
|
|
@@ -473585,16 +473645,7 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473585
473645
|
const loadLogs = React134.useCallback(async () => {
|
|
473586
473646
|
const wt = getCurrentWorktreeSession2();
|
|
473587
473647
|
const paths = wt ? [wt.worktreePath] : [getOriginalCwd()];
|
|
473588
|
-
|
|
473589
|
-
for (const log of l) {
|
|
473590
|
-
if (log.customTitle || !log.sessionId)
|
|
473591
|
-
continue;
|
|
473592
|
-
const auto = deriveAutoTitle(log);
|
|
473593
|
-
if (auto && log.fullPath) {
|
|
473594
|
-
log.customTitle = auto;
|
|
473595
|
-
saveCustomTitle(log.sessionId, auto, log.fullPath, "auto");
|
|
473596
|
-
}
|
|
473597
|
-
}
|
|
473648
|
+
const l = await loadSameRepoAllMessageLogs(paths);
|
|
473598
473649
|
for (const log of l) {
|
|
473599
473650
|
if (log.messageCount === 0 && log.fullPath) {
|
|
473600
473651
|
const meta = getSessionFileMeta(log);
|
|
@@ -473610,15 +473661,6 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473610
473661
|
setLogs(l);
|
|
473611
473662
|
setLoading(false);
|
|
473612
473663
|
}, []);
|
|
473613
|
-
function deriveAutoTitle(log) {
|
|
473614
|
-
const raw = log.firstPrompt ?? log.summary ?? "";
|
|
473615
|
-
if (!raw.trim())
|
|
473616
|
-
return null;
|
|
473617
|
-
const cleaned = raw.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
|
|
473618
|
-
if (!cleaned)
|
|
473619
|
-
return null;
|
|
473620
|
-
return truncateToVisibleWidth(cleaned, 24);
|
|
473621
|
-
}
|
|
473622
473664
|
React134.useEffect(() => {
|
|
473623
473665
|
loadLogs();
|
|
473624
473666
|
return () => {
|
|
@@ -473769,10 +473811,12 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473769
473811
|
const CURSOR_W = 2;
|
|
473770
473812
|
const ICON_W = 2;
|
|
473771
473813
|
const NAME_W = NARROW ? 20 : 28;
|
|
473814
|
+
const CREATED_W = 11;
|
|
473772
473815
|
const ACTIVE_W = 11;
|
|
473773
473816
|
const BRANCH_W = 12;
|
|
473774
473817
|
const MSG_W = 5;
|
|
473775
473818
|
const GAP = 1;
|
|
473819
|
+
const showCreated = !NARROW;
|
|
473776
473820
|
const showBranch = !NARROW;
|
|
473777
473821
|
const showMsg = !NARROW;
|
|
473778
473822
|
const HEADER_ROWS = NARROW ? 4 : 4;
|
|
@@ -473783,6 +473827,10 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473783
473827
|
const endIdx = Math.min(logs.length, startIdx + visibleRows);
|
|
473784
473828
|
let fixedW = CURSOR_W + ICON_W + NAME_W + ACTIVE_W;
|
|
473785
473829
|
let gapCount = 3;
|
|
473830
|
+
if (showCreated) {
|
|
473831
|
+
fixedW += CREATED_W;
|
|
473832
|
+
gapCount++;
|
|
473833
|
+
}
|
|
473786
473834
|
if (showBranch) {
|
|
473787
473835
|
fixedW += BRANCH_W;
|
|
473788
473836
|
gapCount++;
|
|
@@ -473792,7 +473840,8 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473792
473840
|
gapCount++;
|
|
473793
473841
|
}
|
|
473794
473842
|
fixedW += gapCount * GAP;
|
|
473795
|
-
const headerLine = " " + " " + padToVisibleWidth("名称", NAME_W) + " " + padToVisibleWidth("最近活跃", ACTIVE_W) + (showBranch ? " " + padToVisibleWidth("分支", BRANCH_W) : "") + (showMsg ? " " + padLeftToVisibleWidth("消息", MSG_W) : "");
|
|
473843
|
+
const headerLine = " " + " " + padToVisibleWidth("名称", NAME_W) + " " + (showCreated ? padToVisibleWidth("创建", CREATED_W) + " " : "") + padToVisibleWidth("最近活跃", ACTIVE_W) + (showBranch ? " " + padToVisibleWidth("分支", BRANCH_W) : "") + (showMsg ? " " + padLeftToVisibleWidth("消息", MSG_W) : "");
|
|
473844
|
+
const nowMs = Date.now();
|
|
473796
473845
|
return /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedBox_default, {
|
|
473797
473846
|
flexDirection: "column",
|
|
473798
473847
|
paddingX: 2,
|
|
@@ -473824,23 +473873,16 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473824
473873
|
const cursor = isSelected ? "» " : isFocused ? "> " : " ";
|
|
473825
473874
|
const statusIcon = isSelected || isCurrent ? "● " : "○ ";
|
|
473826
473875
|
const title = truncateToVisibleWidth(getLogDisplayTitle(log) || "untitled", NAME_W);
|
|
473827
|
-
const
|
|
473876
|
+
const created = formatCreated(log.created);
|
|
473877
|
+
const active = formatActive(log.modified, nowMs);
|
|
473828
473878
|
const branch = log.gitBranch ? truncateToVisibleWidth(log.gitBranch, BRANCH_W) : "—";
|
|
473829
473879
|
const msgCount = String(cached?.messageCount ?? log.messageCount ?? 0);
|
|
473830
|
-
let line = cursor + statusIcon + padToVisibleWidth(title, NAME_W) + " " + padToVisibleWidth(active, ACTIVE_W);
|
|
473880
|
+
let line = cursor + statusIcon + padToVisibleWidth(title, NAME_W) + " " + (showCreated ? padToVisibleWidth(created, CREATED_W) + " " : "") + padToVisibleWidth(active, ACTIVE_W);
|
|
473831
473881
|
if (showBranch)
|
|
473832
473882
|
line += " " + padToVisibleWidth(branch, BRANCH_W);
|
|
473833
473883
|
if (showMsg)
|
|
473834
473884
|
line += " " + padLeftToVisibleWidth(msgCount, MSG_W);
|
|
473835
473885
|
let flags = "";
|
|
473836
|
-
if (isBranch)
|
|
473837
|
-
flags += " (Branch)";
|
|
473838
|
-
if (isCurrent)
|
|
473839
|
-
flags += " (current)";
|
|
473840
|
-
if (log.tag)
|
|
473841
|
-
flags += ` #${log.tag}`;
|
|
473842
|
-
if (log.agentSetting)
|
|
473843
|
-
flags += ` @${log.agentSetting}`;
|
|
473844
473886
|
let statusColor;
|
|
473845
473887
|
if (rowState === "confirm") {
|
|
473846
473888
|
flags += " [f 确认 fork]";
|
|
@@ -473855,12 +473897,22 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473855
473897
|
flags += " ✗ fork 失败";
|
|
473856
473898
|
statusColor = "red";
|
|
473857
473899
|
}
|
|
473900
|
+
if (isBranch)
|
|
473901
|
+
flags += " (Branch)";
|
|
473902
|
+
if (isCurrent)
|
|
473903
|
+
flags += " (current)";
|
|
473904
|
+
if (log.tag)
|
|
473905
|
+
flags += ` #${log.tag}`;
|
|
473906
|
+
if (log.agentSetting)
|
|
473907
|
+
flags += ` @${log.agentSetting}`;
|
|
473908
|
+
if (log.mode === "coordinator")
|
|
473909
|
+
flags += " [C]";
|
|
473858
473910
|
const maxFlags = termCols - 2 - fixedW;
|
|
473859
473911
|
if (visibleWidth(flags) > maxFlags) {
|
|
473860
473912
|
flags = truncateToVisibleWidth(flags, maxFlags);
|
|
473861
473913
|
}
|
|
473862
473914
|
line += " " + flags;
|
|
473863
|
-
const color = rowStateObj && rowStateObj.kind !== "idle" ? statusColor : isSelected ? "magentaBright" : isFocused ? "cyan" :
|
|
473915
|
+
const color = rowStateObj && rowStateObj.kind !== "idle" ? statusColor : isSelected ? "magentaBright" : isFocused ? "cyan" : AGENT_ROW_COLOR[log.agentColor ?? ""];
|
|
473864
473916
|
return /* @__PURE__ */ jsx_dev_runtime424.jsxDEV(ThemedBox_default, {
|
|
473865
473917
|
noSelect: true,
|
|
473866
473918
|
onClick: () => handleRowClick(i),
|
|
@@ -473899,7 +473951,7 @@ function SessionTreeScreen({ onBack, onResume }) {
|
|
|
473899
473951
|
]
|
|
473900
473952
|
}, undefined, true, undefined, this);
|
|
473901
473953
|
}
|
|
473902
|
-
var React134, jsx_dev_runtime424;
|
|
473954
|
+
var React134, jsx_dev_runtime424, AGENT_ROW_COLOR;
|
|
473903
473955
|
var init_SessionTreeScreen = __esm(() => {
|
|
473904
473956
|
init_ink2();
|
|
473905
473957
|
init_sessionStorage();
|
|
@@ -473910,6 +473962,16 @@ var init_SessionTreeScreen = __esm(() => {
|
|
|
473910
473962
|
init_branch();
|
|
473911
473963
|
React134 = __toESM(require_react(), 1);
|
|
473912
473964
|
jsx_dev_runtime424 = __toESM(require_jsx_dev_runtime(), 1);
|
|
473965
|
+
AGENT_ROW_COLOR = {
|
|
473966
|
+
red: "red",
|
|
473967
|
+
blue: "blue",
|
|
473968
|
+
green: "green",
|
|
473969
|
+
yellow: "yellow",
|
|
473970
|
+
purple: "magenta",
|
|
473971
|
+
orange: "yellow",
|
|
473972
|
+
pink: "magenta",
|
|
473973
|
+
cyan: "cyan"
|
|
473974
|
+
};
|
|
473913
473975
|
});
|
|
473914
473976
|
|
|
473915
473977
|
// src/tui/components/DebugPanel/debugEventBuffer.ts
|
package/package.json
CHANGED