mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-03 14:09:42 +02:00
feat(sessions): show the git worktree on session rows
Closes #266. Sessions from different worktrees of the same repo were indistinguishable in the Resume list, Cmd+K and search — the row showed a session name and a case label, nothing about which worktree it ran in. Claude Code already stamps "cwd" and "gitBranch" on every user/assistant record, and writes a worktree-state record naming the worktree when the session was started through its own worktree feature. scanProjectDir() already buffers the head of every transcript for prompt extraction, so extractTranscriptGitInfo() parses buffers that are already in memory: no extra file reads, no git subprocess. (Measured on this machine: a git rev-parse per directory costs 482ms for 35 rows; parsing the existing buffers costs nothing.) cwd is taken from the first record that carries it, since a session's cwd does not move. gitBranch is taken from the last, since a branch genuinely changes mid-session. The badge requires a worktree NAME. An earlier revision rendered whenever a branch was known, which put a badge on all 35 rows of a real history -- "master" on every ordinary session, burying the ten rows the badge exists to distinguish. A hand-made `git worktree add` therefore gets no badge rather than a guessed name; Claude's own <repo>/.claude/worktrees/<name> layout is recognised from the path when no worktree-state record is present. worktreeName and gitBranch join the filterAndPaginate haystack so the session manager can search by them. panels-ui re-projects the unified item into a 5-field record before rendering, so the new fields are carried there explicitly -- omitting that silently drops them from Cmd+K only. Also prefers the transcript cwd over decodeProjectKey()'s stat-walked guess, which falls back to $HOME when nothing resolves (#265). Note that path is currently LATENT, not active: on the install this was developed against, every project key whose directory is gone has zero transcripts and so produces no row at all. The transcript value is used because it is authoritative and non-lossy, not because a live bug was reproduced. Verified against a real 35-session history on an isolated CODEMAN_INSTANCE: 10 of 36 rows badged, history row count unchanged at 35 (nothing dropped), no page errors. 129 tests pass across the new suite plus the unified service, unified route and session route suites. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016uTqt8ttmsBLXbm5JFHis3
This commit is contained in:
co-authored by
Claude Opus 5
parent
c942bb5dfb
commit
aa35c1a0c4
@@ -32,6 +32,12 @@ export type UnifiedSessionItem = {
|
||||
lastPrompt?: string;
|
||||
sizeBytes?: number;
|
||||
projectKey?: string;
|
||||
/** Git branch recorded in the transcript (#266). */
|
||||
gitBranch?: string;
|
||||
/** Linked-worktree name, when the session ran in one (#266). */
|
||||
worktreeName?: string;
|
||||
/** Main repo root a worktree belongs to (#266). */
|
||||
worktreeRepo?: string;
|
||||
remote?: boolean;
|
||||
/** Pinned to the top of the session manager list (COD-139). */
|
||||
pinned?: boolean;
|
||||
@@ -90,6 +96,9 @@ export type HistoryInput = {
|
||||
/** Most recent user prompt from the transcript (COD-145). */
|
||||
lastPrompt?: string;
|
||||
projectKey?: string;
|
||||
gitBranch?: string;
|
||||
worktreeName?: string;
|
||||
worktreeRepo?: string;
|
||||
};
|
||||
|
||||
/** Mux process-stat view. */
|
||||
@@ -163,6 +172,9 @@ export function mergeUnifiedSessions(sources: UnifiedSources): UnifiedSessionIte
|
||||
overwrite(item, 'firstPrompt', h.firstPrompt);
|
||||
overwrite(item, 'lastPrompt', h.lastPrompt);
|
||||
overwrite(item, 'projectKey', h.projectKey);
|
||||
overwrite(item, 'gitBranch', h.gitBranch);
|
||||
overwrite(item, 'worktreeName', h.worktreeName);
|
||||
overwrite(item, 'worktreeRepo', h.worktreeRepo);
|
||||
const ms = Date.parse(h.lastModified);
|
||||
if (!Number.isNaN(ms) && item.lastActivityAt === undefined) item.lastActivityAt = ms;
|
||||
}
|
||||
@@ -346,7 +358,7 @@ export function filterAndPaginate(
|
||||
const q = (opts.q ?? '').trim().toLowerCase();
|
||||
const filtered = q
|
||||
? items.filter((it) => {
|
||||
const hay = [it.name, it.firstPrompt, it.lastPrompt, it.workingDir, it.sessionId]
|
||||
const hay = [it.name, it.firstPrompt, it.lastPrompt, it.workingDir, it.sessionId, it.worktreeName, it.gitBranch]
|
||||
.filter((v): v is string => typeof v === 'string')
|
||||
.join(' ')
|
||||
.toLowerCase();
|
||||
|
||||
Reference in New Issue
Block a user