(phase, { sessionId = state.currentSessionId, reason = '', force = false } = {})
| 181 | } |
| 182 | |
| 183 | function setTurnState(phase, { sessionId = state.currentSessionId, reason = '', force = false } = {}) { |
| 184 | const normalizedPhase = phase === 'running' ? 'running' : 'idle'; |
| 185 | const normalizedSessionId = sessionId || null; |
| 186 | const changed = force || |
| 187 | state.turnState.phase !== normalizedPhase || |
| 188 | state.turnState.sessionId !== normalizedSessionId; |
| 189 | |
| 190 | if (!changed) return false; |
| 191 | |
| 192 | state.turnState = { |
| 193 | phase: normalizedPhase, |
| 194 | sessionId: normalizedSessionId, |
| 195 | version: ++state.turnStateVersion, |
| 196 | updatedAt: Date.now(), |
| 197 | reason, |
| 198 | }; |
| 199 | |
| 200 | const modeReason = reason || `turn_state:${normalizedPhase}`; |
| 201 | if (normalizedPhase !== 'running' && state.turnApprovalFloorMode) { |
| 202 | clearTurnApprovalFloorMode(modeReason); |
| 203 | } else { |
| 204 | recomputeEffectiveApprovalMode(modeReason); |
| 205 | } |
| 206 | |
| 207 | log(`Turn state -> phase=${state.turnState.phase} session=${state.turnState.sessionId ?? 'null'} version=${state.turnState.version}${reason ? ` reason=${reason}` : ''}`); |
| 208 | broadcast(getTurnStatePayload()); |
| 209 | return true; |
| 210 | } |
| 211 | |
| 212 | function emitInterrupt(source) { |
| 213 | const interruptEvent = { |
no test coverage detected