feat: centralized PTY-scoped session state, sync engine debug panel, lifecycle states, WS monitor

- Refactor session state to use ptySessionId as primary key across all components
- Add SessionStateManager with PTY-scoped hook processing, approval tracking, notifications
- Add sync-engine debug panel (AgentStatesSection, HookTimelineSection, TerminalRegistrySection, WsMonitorSection)
- Add useLifecycleStates composable for continuous state chips (session, responding, tool, subagent, compacting)
- Add WS monitor endpoint and composable for real-time connection health
- Enhance SessionLifecycleStatus with animated state chips and badge counts
- Enhance SystemMessage with expanded content and better formatting
- Update hooks (approval-permission, approval-plan, notify) with pty_session injection
- Update approval system to derive pending lists from PTY-scoped state
- Update ChatContainer with PTY-derived agent status and lifecycle events
- Update AgentBadge with PTY-scoped status colors
- Improve PiP window, approval window, and loading window handling
This commit is contained in:
2026-02-24 20:10:31 -06:00
parent cfb58c3a9f
commit 25bca2625b
36 changed files with 2526 additions and 550 deletions

View File

@@ -13,9 +13,14 @@ try {
} catch {
Add-Content $logFile "[$ts] [PERM] WARN: stdin not valid JSON"
}
$url = 'http://localhost:4101/api/hooks-approval/permission'
$sep = '?'
$pty = $env:AGENT_UI_PTY_SESSION
if ($pty) { $url += "${sep}pty_session=$pty"; $sep = '&' }
if ($agent -and $agent -ne 'local') { $url += "${sep}agent=$agent" }
try {
Add-Content $logFile "[$ts] [PERM] POSTing to backend..."
$r = Invoke-RestMethod -Uri 'http://localhost:4101/api/hooks-approval/permission' -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 125
$r = Invoke-RestMethod -Uri $url -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 125
$ts2 = Get-Date -Format "HH:mm:ss.fff"
if ($r -and $r.hookSpecificOutput) {
$out = $r | ConvertTo-Json -Depth 10 -Compress

View File

@@ -15,9 +15,14 @@ if ($j.permission_mode -ne 'plan' -or $j.stop_hook_active) {
Add-Content $logFile "[$ts] [PLAN] Skipping (not plan mode or stop_hook_active)"
exit 0
}
$url = 'http://localhost:4101/api/hooks-approval/plan'
$sep = '?'
$pty = $env:AGENT_UI_PTY_SESSION
if ($pty) { $url += "${sep}pty_session=$pty"; $sep = '&' }
if ($agent -and $agent -ne 'local') { $url += "${sep}agent=$agent" }
try {
Add-Content $logFile "[$ts] [PLAN] POSTing to backend..."
$r = Invoke-RestMethod -Uri 'http://localhost:4101/api/hooks-approval/plan' -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 125
$r = Invoke-RestMethod -Uri $url -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 125
$ts2 = Get-Date -Format "HH:mm:ss.fff"
if ($r -and $r.decision) {
$out = $r | ConvertTo-Json -Depth 10 -Compress

View File

@@ -2,10 +2,14 @@
# Usage: powershell -NoProfile -File hooks/notify.ps1 [agent]
# If agent is specified, passes ?agent=<name> so the backend knows the source.
# If omitted, the backend auto-detects from session_id/transcript_path.
# Reads AGENT_UI_PTY_SESSION env var (injected by PTY spawn) to identify the terminal.
param([string]$agent = "")
$b = [Console]::In.ReadToEnd()
$url = 'http://localhost:4101/api/claude-hook'
if ($agent) { $url += "?agent=$agent" }
$sep = '?'
if ($agent) { $url += "${sep}agent=$agent"; $sep = '&' }
$pty = $env:AGENT_UI_PTY_SESSION
if ($pty) { $url += "${sep}pty_session=$pty" }
try {
Invoke-RestMethod -Uri $url -Method POST -Body $b -ContentType 'application/json' -TimeoutSec 3 | Out-Null
} catch {}