feat(quick-pane): add constrained agent window

This commit is contained in:
2026-08-25 18:30:39 +02:00
parent 9f2c840ae7
commit 4f57114f19
16 changed files with 760 additions and 9 deletions
+23 -5
View File
@@ -309,7 +309,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 } : {}),
@@ -326,7 +328,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();
@@ -573,6 +575,7 @@ export function createAgentRegistry({
sessionPath,
sessionId,
legacyDefault = false,
ephemeral = false,
openedAt = new Date().toISOString(),
}) {
return {
@@ -583,6 +586,7 @@ export function createAgentRegistry({
sessionPath,
sessionId,
legacyDefault,
ephemeral,
openedAt,
state: "starting",
stateVersion: 0,
@@ -719,13 +723,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;
@@ -757,6 +764,7 @@ export function createAgentRegistry({
sessionPath: ownedPath,
sessionId,
legacyDefault,
ephemeral,
openedAt,
});
if (stopping) throw new Error("agent registry is stopping");
@@ -778,7 +786,7 @@ export function createAgentRegistry({
});
try {
await launch(runtime);
await persistWorkspace();
if (!runtime.ephemeral) await persistWorkspace();
publishWorkspace("runtime_opened", runtime, {
runtime: publicRuntime(runtime),
});
@@ -974,7 +982,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;
@@ -1002,6 +1010,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,
@@ -1206,10 +1216,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(