feat(quick-pane): merge constrained agent window

This commit is contained in:
2026-08-25 18:34:29 +02:00
16 changed files with 760 additions and 9 deletions
+23 -5
View File
@@ -304,7 +304,9 @@ export function createAgentRegistry({
version: 2,
migrated: true,
directories: [...managedWorktrees].sort(),
runtimes: [...runtimesByRuntimeId.values()].map((runtime) => ({
runtimes: [...runtimesByRuntimeId.values()]
.filter((runtime) => !runtime.ephemeral)
.map((runtime) => ({
runtimeId: runtime.runtimeId,
worktreePath: runtime.worktreePath,
...(runtime.sessionPath ? { sessionPath: runtime.sessionPath } : {}),
@@ -321,7 +323,7 @@ export function createAgentRegistry({
}
function addWorktreeRuntime(runtime) {
managedWorktrees.add(runtime.worktreePath);
if (!runtime.ephemeral) managedWorktrees.add(runtime.worktreePath);
let runtimes = runtimesByWorktreePath.get(runtime.worktreePath);
if (!runtimes) {
runtimes = new Set();
@@ -556,6 +558,7 @@ export function createAgentRegistry({
sessionPath,
sessionId,
legacyDefault = false,
ephemeral = false,
openedAt = new Date().toISOString(),
}) {
return {
@@ -566,6 +569,7 @@ export function createAgentRegistry({
sessionPath,
sessionId,
legacyDefault,
ephemeral,
openedAt,
state: "starting",
stateVersion: 0,
@@ -701,13 +705,16 @@ export function createAgentRegistry({
sessionPath,
sessionId,
legacyDefault = false,
ephemeral = false,
openedAt,
},
{ restore = false } = {},
) {
if (stopping) throw new Error("agent registry is stopping");
const canonicalPath = await realpath(worktreePath);
const sessionDir = sessionDirectoryFor(sessionRoot, canonicalPath);
const sessionDir = ephemeral
? path.join(sessionRoot, "quick", runtimeId)
: sessionDirectoryFor(sessionRoot, canonicalPath);
await mkdir(sessionDir, { recursive: true, mode: SESSION_DIRECTORY_MODE });
await chmod(sessionDir, SESSION_DIRECTORY_MODE);
let ownedPath;
@@ -739,6 +746,7 @@ export function createAgentRegistry({
sessionPath: ownedPath,
sessionId,
legacyDefault,
ephemeral,
openedAt,
});
if (stopping) throw new Error("agent registry is stopping");
@@ -760,7 +768,7 @@ export function createAgentRegistry({
});
try {
await launch(runtime);
await persistWorkspace();
if (!runtime.ephemeral) await persistWorkspace();
publishWorkspace("runtime_opened", runtime, {
runtime: publicRuntime(runtime),
});
@@ -949,7 +957,7 @@ export function createAgentRegistry({
// Remove desired-open/UI intent now, but retain the session lease until
// the old child can no longer write to its JSONL file.
unindexRuntime(runtime, { releaseSessionLease: false });
await persistWorkspace();
if (!runtime.ephemeral) await persistWorkspace();
runtime.stopped = true;
runtime.supervisor?.stop();
let stopConfirmed = true;
@@ -977,6 +985,8 @@ export function createAgentRegistry({
}
}
if (stopConfirmed) releaseClosedSessionLease(runtime);
if (runtime.ephemeral && stopConfirmed)
await rm(runtime.sessionDir, { recursive: true, force: true }).catch(() => {});
runtime.state = "stopped";
publishWorkspace("runtime_closed", runtime, {
runtimeId: runtime.runtimeId,
@@ -1183,10 +1193,18 @@ export function createAgentRegistry({
async createSessionRuntime(worktreePath) {
return openRuntime({ worktreePath });
},
async createQuickRuntime(worktreePath) {
return openRuntime({ worktreePath, ephemeral: true });
},
async openSessionRuntime(worktreePath, sessionPath) {
return openRuntime({ worktreePath, sessionPath });
},
closeSessionRuntime: closeRuntime,
async closeQuickRuntime(runtimeId) {
const runtime = getRuntime(runtimeId);
if (!runtime.ephemeral) throw new Error("runtime is not a quick runtime");
return closeRuntime(runtimeId);
},
listAgents() {
return [...runtimesByAgentId.values()]
.map(publicAgent)
+8
View File
@@ -46,6 +46,12 @@ export async function startBridgeService({
request.payload.worktreePath,
),
};
case "create_quick_runtime":
return {
runtime: await registry.createQuickRuntime(
request.payload.worktreePath,
),
};
case "open_session_runtime":
return {
runtime: await registry.openSessionRuntime(
@@ -55,6 +61,8 @@ export async function startBridgeService({
};
case "close_session_runtime":
return registry.closeSessionRuntime(request.payload.runtimeId);
case "close_quick_runtime":
return registry.closeQuickRuntime(request.payload.runtimeId);
case "list_directory_sessions":
return {
sessions: await registry.listDirectorySessions(
+2
View File
@@ -12,8 +12,10 @@ const requestOperations = new Map([
["get_workspace", { agent: false, payload: "none" }],
["get_workspace_summary", { agent: false, payload: "none" }],
["create_session_runtime", { agent: false, payload: "worktree" }],
["create_quick_runtime", { agent: false, payload: "worktree" }],
["open_session_runtime", { agent: false, payload: "worktreeSession" }],
["close_session_runtime", { agent: false, payload: "runtime" }],
["close_quick_runtime", { agent: false, payload: "runtime" }],
["list_directory_sessions", { agent: false, payload: "worktree" }],
["get_session_runtime_snapshot", { agent: false, payload: "runtime" }],
["subscribe_workspace", { agent: false, payload: "cursor" }],