fix: Project action terminal lifecycle (#3287)

* fix(terminal): make command sessions own action lifecycle

* fix(ui): reconcile project action terminal state

* feat(ui): show running project actions in terminal tabs

* feat(ui): run project actions from linked worktrees

* fix(ui): guard project action reconciliation

* fix(ui): scope project action preview fallback

* fix(ui): default project actions to worktrees

* fix(ui): reveal project action terminals

* fix(ui): retain terminal output after snapshot replay

* fix(ui): restore running action terminals on revisit
This commit is contained in:
Matt Visnovsky
2026-09-05 12:04:36 +03:00
committed by GitHub
parent 58dfc789a2
commit 4e0eed717d
53 changed files with 5194 additions and 608 deletions
+14 -6
View File
@@ -24,7 +24,7 @@ const resolveProjectFromWorktreeDirectory = (
projects: ProjectEntry[],
availableWorktreesByProject: Map<string, WorktreeMetadata[]>,
directory: string | null,
): ProjectEntry | null => {
): { project: ProjectEntry; matchedWorktreePathLength: number } | null => {
const nd = normalizeProjectPath(directory);
if (!nd) return null;
let matchedWorktree: WorktreeMetadata | null = null;
@@ -47,9 +47,9 @@ const resolveProjectFromWorktreeDirectory = (
.filter((v): v is string => Boolean(v));
for (const c of candidates) {
const exact = projects.find((p) => normalizeProjectPath(p.path) === c) ?? null;
if (exact) return exact;
if (exact) return { project: exact, matchedWorktreePathLength: bestLen };
const nested = resolveProjectForDirectory(projects, c);
if (nested) return nested;
if (nested) return { project: nested, matchedWorktreePathLength: bestLen };
}
return null;
};
@@ -58,6 +58,14 @@ export const resolveProjectForSessionDirectory = (
projects: ProjectEntry[],
availableWorktreesByProject: Map<string, WorktreeMetadata[]>,
directory: string | null,
): ProjectEntry | null =>
resolveProjectForDirectory(projects, directory) ??
resolveProjectFromWorktreeDirectory(projects, availableWorktreesByProject, directory);
): ProjectEntry | null => {
const directProject = resolveProjectForDirectory(projects, directory);
const worktreeResolution = resolveProjectFromWorktreeDirectory(projects, availableWorktreesByProject, directory);
if (!directProject) return worktreeResolution?.project ?? null;
if (!worktreeResolution) return directProject;
const directPathLength = normalizeProjectPath(directProject.path)?.length ?? 0;
return worktreeResolution.matchedWorktreePathLength > directPathLength
? worktreeResolution.project
: directProject;
};