feat(coder): v2.6 Phase 3 — lifecycle hardening (idle evict, crash recovery, worktree reaper)
Idle TTL eviction per (chat,agent) + LRU cap (never a busy backend); pure lifecycle-decisions.ts (TDD). Crash recovery lifts openchamber's health-monitor + busy-aware-restart + stale-grace state machine into opencode-server.ts (+ port reclaim) and warm-acp.ts; opencode crash -> fresh sessions, ACP -> re-session/new. F.1 turn-guard + U.6 usage preserved (their tests pass). Orphan worktree reaper (1h grace, superset-style dirty/unpushed preflight, Paseo soft-delete) + close hooks + diff re-baseline after apply_pending. 35 new tests + DB-opt-in reconnect test; 215 coder tests pass; tsc + build clean. Completes v2.6. Follow-ups out of scope: apps/server close-hook caller, 3.7 DiffPanel staging hint, live smokes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
queueCreate,
|
||||
} from '../services/pending_changes.js';
|
||||
import { WriteGuardError } from '../services/write_guard.js';
|
||||
import { rebaselineWorktreeAfterApply } from '../services/worktrees.js';
|
||||
|
||||
const CreateBody = z.object({
|
||||
file_path: z.string().min(1),
|
||||
@@ -117,6 +118,15 @@ export function registerPendingRoutes(app: FastifyInstance, sql: Sql): void {
|
||||
}
|
||||
|
||||
const results = await applyAll(sql, sessionId, projectRoot);
|
||||
|
||||
// v2.6 Phase 3 (3.5): re-baseline the session worktree's diff to the applied
|
||||
// state, so the next external-agent turn diffs against applied-not-original
|
||||
// and doesn't re-surface the just-applied changes. Best-effort: a worktree
|
||||
// session may not exist (native-only chat), and a re-baseline hiccup must not
|
||||
// fail the apply the user just requested.
|
||||
if (results.some((r) => r.success)) {
|
||||
await rebaselineWorktreeAfterApply(sql, sessionId).catch(() => {});
|
||||
}
|
||||
return { results };
|
||||
},
|
||||
);
|
||||
@@ -136,6 +146,15 @@ export function registerPendingRoutes(app: FastifyInstance, sql: Sql): void {
|
||||
const result = await applyOne(sql, changeId, projectRoot);
|
||||
if (!result.success) {
|
||||
reply.code(422);
|
||||
} else {
|
||||
// v2.6 Phase 3 (3.5): re-baseline the session worktree after a successful
|
||||
// apply so the next external-agent turn diffs against applied-not-original.
|
||||
// Resolve the change's session; best-effort, never fails the apply.
|
||||
const sessRows = await sql<{ session_id: string }[]>`
|
||||
SELECT session_id FROM pending_changes WHERE id = ${changeId}
|
||||
`;
|
||||
const sessionId = sessRows[0]?.session_id;
|
||||
if (sessionId) await rebaselineWorktreeAfterApply(sql, sessionId).catch(() => {});
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user