(job)
| 1000 | return undefined |
| 1001 | } |
| 1002 | |
| 1003 | async function sessionStatusType(client, sessionID, directory, options = {}) { |
| 1004 | const cached = sessionStatuses.get(sessionID) |
| 1005 | const seenAt = sessionStatusSeenAt.get(sessionID) || 0 |
| 1006 | |
| 1007 | // Idle is safe to trust until OpenCode tells us otherwise. Busy/retry is only |
| 1008 | // trusted briefly: OpenCode custom commands such as /loop-status create their |
| 1009 | // own short assistant turn, and some TUI builds do not always emit the final |
| 1010 | // idle event after that turn. If we cache busy forever, due loop work can get |
| 1011 | // stuck at "due in every idle" until the user types another command. |
| 1012 | if (cached === "idle") return cached |
| 1013 | if (cached && now() - seenAt < SESSION_STATUS_CACHE_MS) return cached |
| 1014 | |
| 1015 | const live = await readLiveSessionStatus(client, sessionID, directory) |
| 1016 | if (live?.type) { |
| 1017 | // Some OpenCode 1.15.x TUI builds can leave session.status at busy after a |
| 1018 | // plugin-injected turn until the next user command touches the session. |
| 1019 | // When the only reason we still think the session is busy is our own stale |
| 1020 | // active-run guard, recover instead of waiting for another manual command. |
| 1021 | if ((live.type === "busy" || live.type === "retry") && options.recoverStaleActive !== false && staleActiveRun(sessionID)) { |
| 1022 | sessionStatuses.set(sessionID, "idle") |
| 1023 | sessionStatusSeenAt.set(sessionID, now()) |
| 1024 | return "idle" |
| 1025 | } |
| 1026 | sessionStatuses.set(sessionID, live.type) |
| 1027 | sessionStatusSeenAt.set(sessionID, now()) |
| 1028 | return live.type |
| 1029 | } |
| 1030 | |
| 1031 | const fallback = activeRuns.has(sessionID) && !staleActiveRun(sessionID) ? "busy" : "idle" |
no test coverage detected