fork of prime agent with changes i want but are not upstreamable probqbly (and some fixes)

add built-in herdr integration (#360) master

* feat(coding-agent): add built-in herdr integration Herdr cannot detect Prime Agent panes: its process detection only knows the legacy "pi" binary name, and its "herdr integration install pi" writes to ~/.pi/agent/extensions which Prime Agent does not read. Ship the pi lifecycle-reporter as a built-in extension factory loaded for every session. It reports working/idle/blocked and session refs to Herdr's unix socket and releases the pane on shutdown, using the agent label "prime-agent" (verified accepted and displayed by herdr 0.7.0 against a live pane). The factory captures HERDR_* env per invocation, so daemon sessions pick up their own pane identity inside the client-env window, and it is a no-op outside Herdr or when the user has installed Herdr's own file-based integration. * fix(coding-agent): keep herdr seq monotonic across sessions and release only on quit Herdr guards pane.report_agent with a per-source monotonic seq and silently drops lower-seq reports (verified live: ok response, state unchanged). Seeding seq per factory instance meant a successor session after /new, resume, fork, or reload could restart below the predecessor's counter, so all its reports were dropped and the pane stuck at working. - move the seq counter to module scope and clamp it to max(prev + 1, now*1000) so it never regresses across instances - release the pane only on quit; on session replacement the successor re-reports immediately and a racing release could clear it - report idle immediately on agent_end when no messages are queued; keep the debounce only when queued follow-ups restart the loop * fix(coding-agent): address herdr integration review findings - unsubscribe the shared-bus herdr:blocked listener on session_shutdown; the event bus survives reloads and session replacements, so a leaked listener kept stale instances reporting with captured pane identity - move the file-based integration check into createAgentSessionServices using the same extension dirs the loader discovers from, so agentDir overrides are honored - stop treating the legacy ~/.pi/agent path as an active reporter; Prime Agent never loads extensions from there, so deferring to it left panes with no reporter at all * fix(coding-agent): scope herdr reporter to its own session and recheck deferral on reload - bind the reporter to the first session that starts and ignore events from other sessions sharing the closure; inline RLM children reuse the parent's resource loader, so a subagent's turns flipped the pane state and a subagent quit released the pane while the parent was running - skip the built-in reporter entirely for subagent runtimes (rlmDepth > 0), which share the parent's HERDR_* pane identity - re-check for Herdr's file-based integration on every factory invocation instead of once at service creation, so installing it and running /reload hands the pane over without both reporters active - also match herdr-agent-state.js for compiled installs * fix(coding-agent): make quit release the final write to the herdr socket releaseAgent now stops new reports, drops the queued state, and awaits the in-flight drain before sending pane.release_agent, so a late report cannot land after the release and reclaim the pane for an exited agent. * fix(coding-agent): seed working state when the reporter starts mid-turn Daemon-driven reloads and extension ctx.reload() are not gated on idle, so a fresh reporter's session_start could publish idle while the agent was still streaming, and the agentActive guard then swallowed the turn's real end transition. session_start now seeds agentActive from ctx.isIdle(). * fix(coding-agent): settle the retry hold when a blocked event cancels its timer A herdr:blocked event during the retry-hold window cancelled the retry timer but left retryHoldActive set, so after the block lifted the pane reported working forever. The blocked handler now settles the hold to failureBlocked, matching what the cancelled timer would have done. * fix(coding-agent): do not defer to file-based herdr reporter under noExtensions With noExtensions the loader never scans the extension dirs, so a file-based herdr-agent-state there never becomes an active reporter; deferring to it left the pane with no reporter at all. * fix(coding-agent): hold working for every error end instead of a pattern subset The agent's auto-retry treats nearly all provider errors as retryable and runs after extension agent_end, so an error the reporter's pattern list missed flipped the pane to idle while a retry was pending. Drop the pattern list and hold working for any error end; a retry's agent_start keeps the pane working, and with no retry the grace window settles it to blocked with the error message. * fix(coding-agent): silence replaced reporter instances on non-quit shutdown A replaced instance kept its report queue armed after reload/new/resume shutdowns; a late report carrying the process-wide seq could outrank and stomp the successor's state. Non-quit shutdowns now set released and drop the queued state so the old instance goes quiet. * fix(coding-agent): make noExtensions disable the built-in herdr reporter noExtensions is a full opt-out: inline factories deliberately bypass it for embedder-supplied extensions, but the built-in reporter should respect it so --no-extensions leaves nothing extension-driven running. * fix(coding-agent): defer to the file-based herdr reporter only when it loaded Deferral now consults the resource loader's actually-loaded extension paths (late-bound, per factory invocation) instead of raw disk existence, so a herdr-agent-state file disabled via settings overrides or outside the discovery dirs no longer silences the built-in reporter and leaves the pane with no reporter.


Author kt Committer GitHub Date Commit ecd32905 Parent 4aa06023