feat(v0.6): per-project detail view — branch/worktrees + active sessions
Clicking a project's name opens an in-app detail view (back button returns to the grid) with: - header: name, path, branch, dirty - Branch / Worktrees: each `git worktree list` entry (branch or detached@head, main/current/locked/prunable tags, path) — a single-worktree repo shows its branch; a multi-worktree repo shows them all - Active sessions (N): detailed rows (status, devices watching, started-ago) with Open + Kill - the Claude/Codex/VS Code launcher row Backend: src/http/worktrees.ts (parseWorktrees pure + listWorktrees via execFile, no shell, best-effort); buildProjectDetail(cfg, path, liveSessions) in projects.ts (validates absolute existing dir, reuses branch/dirty/session helpers, uncached — detail is on-demand and wants fresh state); read-only GET /projects/detail?path= (no Origin guard, like /projects; 400 missing / 404 invalid). Types: WorktreeInfo, ProjectDetail. Frontend: detail view + navigation in projects.ts (grid<->detail), project name becomes a link, Kill via DELETE /live-sessions/:id. Tests +21 (452 total): worktree parser, buildProjectDetail (validation, non-git, session merge, real git-init worktree), renderProjectDetail. worktrees.ts 100% / projects.ts 93.8% cov. Verified in-browser: opened a Claude session, then the detail showed its branch+worktree and the live session with Open/Kill.
This commit is contained in:
23
src/types.ts
23
src/types.ts
@@ -223,6 +223,29 @@ export interface ProjectInfo {
|
||||
sessions: ProjectSessionRef[]; // running sessions in this project (1:N; may be empty)
|
||||
}
|
||||
|
||||
/** One entry from `git worktree list --porcelain` (project detail view). */
|
||||
export interface WorktreeInfo {
|
||||
path: string; // worktree absolute path
|
||||
branch?: string; // branch name (refs/heads/x → x); undefined when detached
|
||||
head?: string; // short HEAD sha
|
||||
isMain: boolean; // the repo's primary worktree (listed first)
|
||||
isCurrent: boolean; // this worktree is the requested project path
|
||||
locked?: boolean; // `git worktree lock`ed
|
||||
prunable?: boolean; // git considers it prunable (gone working tree)
|
||||
}
|
||||
|
||||
/** Detailed view of one project: branch/worktrees + its running sessions.
|
||||
* impl: src/http/projects.ts buildProjectDetail(cfg, path, liveSessions). */
|
||||
export interface ProjectDetail {
|
||||
name: string;
|
||||
path: string;
|
||||
isGit: boolean;
|
||||
branch?: string;
|
||||
dirty?: boolean;
|
||||
worktrees: WorktreeInfo[]; // empty for a non-git dir
|
||||
sessions: ProjectSessionRef[]; // running sessions under this path (fresh)
|
||||
}
|
||||
|
||||
export interface SessionManager {
|
||||
handleAttach(
|
||||
ws: WebSocketLike,
|
||||
|
||||
Reference in New Issue
Block a user