fix(core): derive activity from runtime probe, not terminal status (#1081)
Previously, sessions with terminal statuses (merged, done, killed, etc.) had their activity unconditionally set to "exited" without checking if the agent process was actually still running. This caused the dashboard to show incorrect activity state for sessions where the PR was merged but the agent was still alive in tmux. Now the runtime liveness check runs first for all sessions, and activity is derived from the actual process state via getActivityState(). Terminal status no longer forces activity to "exited". Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
ff9bb76e63
commit
b88b664dbb
|
|
@ -880,13 +880,9 @@ export function createSessionManager(deps: SessionManagerDeps): OpenCodeSessionM
|
|||
plugins: ReturnType<typeof resolvePlugins>,
|
||||
handleFromMetadata: boolean,
|
||||
): Promise<void> {
|
||||
// Skip all subprocess/IO work for sessions already known to be terminal.
|
||||
if (TERMINAL_SESSION_STATUSES.has(session.status)) {
|
||||
session.activity = "exited";
|
||||
return;
|
||||
}
|
||||
|
||||
// Check runtime liveness — but only if the handle came from metadata.
|
||||
// Check runtime liveness first — regardless of session status.
|
||||
// This fixes #1081: terminal statuses (merged, done, etc.) should not force
|
||||
// activity to "exited" if the agent process is still alive.
|
||||
// Fabricated handles (constructed as fallback for external sessions) should
|
||||
// NOT override status to "killed" — we don't know if the session ever had
|
||||
// a tmux session, and we'd clobber meaningful statuses like "pr_open".
|
||||
|
|
@ -894,7 +890,11 @@ export function createSessionManager(deps: SessionManagerDeps): OpenCodeSessionM
|
|||
try {
|
||||
const alive = await plugins.runtime.isAlive(session.runtimeHandle);
|
||||
if (!alive) {
|
||||
session.status = "killed";
|
||||
// Process is confirmed dead — set activity to exited.
|
||||
// Only update status to "killed" if not already in a terminal state.
|
||||
if (!TERMINAL_SESSION_STATUSES.has(session.status)) {
|
||||
session.status = "killed";
|
||||
}
|
||||
session.activity = "exited";
|
||||
return;
|
||||
}
|
||||
|
|
@ -903,10 +903,12 @@ export function createSessionManager(deps: SessionManagerDeps): OpenCodeSessionM
|
|||
}
|
||||
}
|
||||
|
||||
// Detect activity independently of runtime handle.
|
||||
// Detect activity independently of runtime handle and session status.
|
||||
// Activity detection reads JSONL files on disk — it only needs workspacePath,
|
||||
// not a runtime handle. Gating on runtimeHandle caused sessions created by
|
||||
// external scripts (which don't store runtimeHandle) to always show "unknown".
|
||||
// This now runs for ALL sessions, including terminal statuses, so a merged
|
||||
// session with a live agent shows accurate activity (ready/idle/waiting_input).
|
||||
if (plugins.agent) {
|
||||
try {
|
||||
const detected = await plugins.agent.getActivityState(session, config.readyThresholdMs);
|
||||
|
|
|
|||
Loading…
Reference in New Issue