Skip to content

Fix plugin agent hibernation registration - #6991

Closed
austinywang wants to merge 18 commits into
mainfrom
issue-5502-agent-hibernation-opencode-plugin-agents-don
Closed

austinywang wants to merge 18 commits into
mainfrom
issue-5502-agent-hibernation-opencode-plugin-agents-don

Conversation

@austinywang

@austinywang austinywang commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #5502\n\n## Summary\n- add no-surface plugin hook regressions for OpenCode, Pi, and Amp\n- allow plugin session hooks to run with workspace/socket cmux context when CMUX_SURFACE_ID is absent\n- wire OpenCode and Amp plugin install tests into the focused CLI regression lane\n\n## Validation\n- python3 -m py_compile tests/test_opencode_plugin_install.py tests/test_pi_extension_install.py tests/test_amp_extension_install.py\n- git diff --check HEAD~2..HEAD\n- reproduced red state before the fix with existing CLI: OpenCode/Pi no-surface plugin tests failed before production changes; Amp skipped locally because node is unavailable\n\nNo local dev build or xcodebuild run per request.


Summary by cubic

Fixes #5502 by correcting plugin agent hibernation across OpenCode, Pi, and Amp. Hooks now run only with a socket (CMUX_SOCKET_PATH or CMUX_SOCKET) plus a surface or workspace; Pi feed telemetry stays surface‑scoped.

  • Bug Fixes
    • Align gates with the CLI across OpenCode/Amp/Pi: require a socket + CMUX_SURFACE_ID or CMUX_WORKSPACE_ID (drop CMUX_PANEL_ID). Surface resume bindings still require CMUX_SURFACE_ID. Pi: sendHook returns false on skip; surfaceTargetArgs requires a socket; sendFeed requires socket + surface. Accept legacy CMUX_SOCKET.
    • Tests/CI: Isolate no‑socket phases by popping CMUX_SOCKET_PATH/CMUX_SOCKET and assert silence. Pi adds a surface‑but‑no‑socket regression (no hooks, no resume set/clear) and a workspace‑only with socket phase (session hooks OK, resume/feed skipped). CI runs OpenCode → Pi → Amp.

Written for commit 6844484. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes

    • Updated hook/feed dispatch so hooks and related routing actions only occur when socket context is available (socket path set) along with at least one routing identifier (surface/workspace), improving PI extension behavior in no-socket/no-surface scenarios.
    • Improved extension install behavior checks for Amp, OpenCode, and Pi when socket context is missing or present.
  • Tests

    • Expanded macOS CI regression coverage by adding OpenCode and Amp install tests, running in order: opencode → pi → amp.
    • Strengthened install tests with negative “no-socket/no-surface” validations before asserting normal behavior once socket context is provided.

@vercel

vercel Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jul 5, 2026 3:47am
cmux-staging Building Building Preview, Comment Jul 5, 2026 3:47am

@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown
🚥 Pre-merge checks | ✅ 24 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (24 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes align with #5502 by tightening plugin hook/session gating and adding regression coverage for OpenCode, Pi, and Amp.
Out of Scope Changes check ✅ Passed All changes relate to plugin hibernation registration, regression tests, or the focused CLI lane, with no clear unrelated additions.
Cmux Swift Actor Isolation ✅ Passed Only embedded TypeScript gate changes and tests; no Swift actor isolation annotations, Sendable ref types, or UI store access were added or worsened.
Cmux Swift Blocking Runtime ✅ Passed PASS: changed Swift only tightens env gating in sendHook/sendFeed/surfaceTargetArgs; no new semaphores, waits, sleeps, syncs, or locks were added.
Cmux Browser Automation Off-Main ✅ Passed PASS: The PR only changes plugin hook gating/tests; it doesn't modify browser.* routing, mainActor/processV2Command, or the socket-worker browser policy files.
Cmux Expensive Synchronous Load ✅ Passed Only hook-gating env checks changed; no added RestorableAgentSessionIndex.load()/JSONL/transcript scans or main-actor loads in touched paths.
Cmux Cache Substitution Correctness ✅ Passed Diff only changes hook/env gating and tests; no fresh authoritative read was swapped for a cached value in any persistence/history/undo/snapshot path.
Cmux No Hacky Sleeps ✅ Passed PASS: The only waits are in test scaffolding and CI YAML; the runtime TS changes just tighten env gating and add no fixed sleeps/timers.
Cmux Algorithmic Complexity ✅ Passed Production changes only add fixed-size env-key gating; no nested scans, rescans, or hot-path sorts/filters were introduced.
Cmux Swift Concurrency ✅ Passed Touched Swift blocks only tightened env gating in embedded TS; no new DispatchQueue/Combine/completion-handler/fire-and-forget Task patterns were introduced.
Cmux Swift @Concurrent ✅ Passed Touched Swift files only change embedded TypeScript strings; no Swift @concurrent, nonisolated async, or actor-isolated async call sites were introduced.
Cmux Swift File And Package Boundaries ✅ Passed PASS: cmux.swift is a 34k-line existing oversized file, and the Swift diff is a one-line gate change; Amp/Pi files are small generated plugin sources, not boundary-sprawling app logic.
Cmux Swiftpm Lockfiles ✅ Passed The PR changes only touch tests/workflow logic; no Package.swift, Package.resolved, .gitignore, or Xcode project lockfile paths are in the diff, so the rule isn’t violated.
Cmux Swift Logging ✅ Passed Touched Swift production changes only adjust socket/workspace gating; no added print/debugPrint/dump/NSLog or mis-scoped Logger in runtime code.
Cmux User-Facing Error Privacy ✅ Passed Diff only tightens socket/surface gating and adds tests; it doesn’t introduce new user-facing error/output text or expose sensitive internals.
Cmux Full Internationalization ✅ Passed Production diffs only change hook/socket gating on env vars; no new user-facing text, catalogs, web messages, or locale files were added.
Cmux Swiftui State Layout ✅ Passed Touched files are CLI/test code; no SwiftUI imports or new ObservableObject/@Published/GeometryReader/list-row state patterns appear in the diff.
Cmux Architecture Rethink ✅ Passed PASS: The diff only tightens hook gating on CMUX_SOCKET_PATH + scope IDs and adds test-only no-socket checks; no new timing, locks, observers, or split ownership appeared.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed Touched Swift files only change hook/socket routing and tests; no NSWindow/NSPanel/NSWindowController/WindowGroup code or cmuxAuxiliaryWindowIdentifiers changes were introduced.
Cmux Source Artifacts ✅ Passed All touched paths are intentional source/test/workflow files; none are logs, temp dirs, caches, build output, or other source-control artifacts.
Cmux No Test Or Debug Seam In Production Source ✅ Passed No added production-source lines introduce debug/test-only seams; diff only adds normal helpers/feature gating and leaves pre-existing debug utilities untouched.
Cmux No Ambient Global State ✅ Passed Changes only tweak existing CMUXCLI constants and embedded TS gating; no new file-scope funcs, mutable globals, or singletons were introduced.
Title check ✅ Passed The title is concise and relevant to the main fix, though it omits the OpenCode/Pi/Amp scope.
Description check ✅ Passed The description covers the summary and validation, but it misses the template's Demo Video, Review Trigger, and Checklist sections.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-5502-agent-hibernation-opencode-plugin-agents-don

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixes plugin agent hibernation registration (#5502) by expanding the hook-dispatch guards across OpenCode, Pi, and Amp so that session hooks fire whenever a socket (CMUX_SOCKET_PATH or legacy CMUX_SOCKET) and at least one routing identity (CMUX_SURFACE_ID or CMUX_WORKSPACE_ID) are present — not only when a surface id exists. Pi's sendFeed and surfaceTargetArgs keep their tighter surface requirement to avoid no-op subprocess overhead per tool event in workspace-only contexts.

  • Guard alignment (cmux.swift, CMUXCLI+AmpExtension.swift, CMUXCLI+PiExtensionSourcePart2.swift): All three sendHook functions now gate on socket ∧ (surface ∨ workspace); Pi's surfaceTargetArgs adds a socket pre-check; sendFeed keeps socket ∧ surface.
  • Pi return-value fix: sendHook now returns false on every skip path, so the if (ok && sessionId) ensureResumeBinding(...) call-site correctly skips the surface binding when hooks are suppressed or routing context is absent.
  • Test and CI coverage: No-socket/no-surface regression scenarios added for all three plugins; OpenCode and Amp wired into the focused CLI regression lane alongside Pi.

Confidence Score: 5/5

Safe to merge — all three plugin hook guards are now consistent, the Pi return-value fix is correctly threaded through callers, and the double-layer protection (sendHook gate + surfaceTargetArgs gate) keeps surface resume bindings from firing in no-socket and no-surface scenarios.

The guard logic is symmetric across all three plugins and matches the stated invariant (socket ∧ routing-id). The Pi sendHook return-value change from true to false on skip is safe: ensureResumeBinding has its own CMUX_PI_HOOKS_DISABLED and surfaceTargetArgs guards, so the observable behavior for the disabled case is unchanged; the socket/no-surface paths are now guarded at both layers. The new regression tests cover surface-no-socket, workspace-no-socket, and workspace-with-socket scenarios end-to-end.

No files require special attention.

Important Files Changed

Filename Overview
CLI/CMUXCLI+PiExtensionSourcePart2.swift Guard corrected to socket+routing-id; surfaceTargetArgs adds socket pre-check; sendHook return value changed from true to false on skip, correctly preventing ensureResumeBinding from being called when hooks are suppressed; sendFeed stays surface-scoped.
CLI/cmux.swift OpenCode sendHook guard updated from surface-only to socket+(surface
CLI/CMUXCLI+AmpExtension.swift Amp sendHook guard updated to socket+(surface
tests/test_pi_extension_install.py Comprehensive regression suite added: surface-no-socket (silence), workspace-no-socket (silence), workspace-socket (session hooks fire, surface resume/feed skipped). Uses existing wait_for_text helper for async log assertions.
tests/test_amp_extension_install.py No-socket regression phase added before the full run; uses a 1-second poll loop for the absence check (test-only scaffolding, acceptable); workspace context replaces surface context for the full run.
tests/test_opencode_plugin_install.py No-socket regression phase added; checks for spurious cmux invocations immediately after subprocess returns (consistent with synchronous bun runner), then sets CMUX_SOCKET_PATH for the full workspace-context run.
.github/workflows/ci.yml OpenCode and Amp plugin tests wired into the focused CLI regression lane (opencode → pi → amp); both tests already handle missing runtimes gracefully via early SKIP returns.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[sendHook called] --> B{HOOKS_DISABLED=1?}
    B -- yes --> SKIP[return false / void\nno cmux subprocess]
    B -- no --> C{CMUX_SOCKET_PATH\nor CMUX_SOCKET set?}
    C -- no --> SKIP
    C -- yes --> D{CMUX_SURFACE_ID\nor CMUX_WORKSPACE_ID set?}
    D -- no --> SKIP
    D -- yes --> E{sessionId present?}
    E -- no --> SKIP
    E -- yes --> F[spawn cmux hooks subcommand\nreturn true / void]

    F --> G{caller: ok && sessionId?}
    G -- Pi session-start --> H{surfaceTargetArgs:\nsocket present?}
    H -- no --> NOSURFACE[skip resume binding]
    H -- yes --> I{CMUX_SURFACE_ID set?}
    I -- no --> NOSURFACE
    I -- yes --> J[cmux surface resume set]

    subgraph sendFeed [sendFeed — always surface-scoped]
        SF1{socket present?} -- no --> SFskip[return]
        SF1 -- yes --> SF2{CMUX_SURFACE_ID set?}
        SF2 -- no --> SFskip
        SF2 -- yes --> SF3[spawn cmux hooks feed]
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[sendHook called] --> B{HOOKS_DISABLED=1?}
    B -- yes --> SKIP[return false / void\nno cmux subprocess]
    B -- no --> C{CMUX_SOCKET_PATH\nor CMUX_SOCKET set?}
    C -- no --> SKIP
    C -- yes --> D{CMUX_SURFACE_ID\nor CMUX_WORKSPACE_ID set?}
    D -- no --> SKIP
    D -- yes --> E{sessionId present?}
    E -- no --> SKIP
    E -- yes --> F[spawn cmux hooks subcommand\nreturn true / void]

    F --> G{caller: ok && sessionId?}
    G -- Pi session-start --> H{surfaceTargetArgs:\nsocket present?}
    H -- no --> NOSURFACE[skip resume binding]
    H -- yes --> I{CMUX_SURFACE_ID set?}
    I -- no --> NOSURFACE
    I -- yes --> J[cmux surface resume set]

    subgraph sendFeed [sendFeed — always surface-scoped]
        SF1{socket present?} -- no --> SFskip[return]
        SF1 -- yes --> SF2{CMUX_SURFACE_ID set?}
        SF2 -- no --> SFskip
        SF2 -- yes --> SF3[spawn cmux hooks feed]
    end
Loading

Reviews (16): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

Comment thread CLI/CMUXCLI+AmpExtension.swift Outdated
Comment thread CLI/cmux.swift Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLI/CMUXCLI`+AmpExtension.swift:
- Line 117: The no-surface fallback gate in CMUXCLI+AmpExtension currently
allows spawning hooks with only partial CMUX context, which can route sessions
without a reliable target. Update the guard around the fallback so it requires
CMUX_SOCKET_PATH together with a scoped identity such as CMUX_WORKSPACE_ID or
CMUX_PANEL_ID before proceeding, and keep the fail-closed behavior when the
socket is missing. Use the existing CMUXCLI+AmpExtension fallback check to
locate the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6b865cd3-9b63-4799-b3a2-fc34031f2cac

📥 Commits

Reviewing files that changed from the base of the PR and between 015afa6 and d0bf087.

📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • CLI/CMUXCLI+AmpExtension.swift
  • CLI/cmux.swift
  • tests/test_amp_extension_install.py
  • tests/test_opencode_plugin_install.py
  • tests/test_pi_extension_install.py

Comment thread CLI/CMUXCLI+AmpExtension.swift Outdated
…gents-don

Resolve conflicts from main's #7008 (Pi hook integration rewrite):
- CLI/cmux.swift: take main's side; the Pi extension now lives in
  CMUXCLI+PiExtension*.swift. Branch's OpenCode no-surface gate is preserved.
- CLI/CMUXCLI+PiExtensionSourcePart2.swift: re-port the branch's gate change
  onto main's new Pi extension. sendHook/sendFeed now route when
  CMUX_SOCKET_PATH plus one scoped identity (surface/panel/workspace) is
  present; surface-scoped resume bindings stay gated on CMUX_SURFACE_ID.
- tests/test_pi_extension_install.py: keep main's comprehensive surface-based
  coverage intact and add a self-contained no-surface phase (workspace-only)
  asserting hooks register with a socket, stay silent without one, and skip
  surface-scoped resume bindings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLI/CMUXCLI`+PiExtensionSourcePart2.swift:
- Around line 5-10: The sendHook function currently returns true on skip paths,
which incorrectly signals success even when no hook was sent. Update sendHook in
CMUXCLI+PiExtensionSourcePart2 to return false for the early-exit cases (hooks
disabled, missing socket/routing keys, missing sessionId), so callers can
distinguish dropped hooks from successful sends. This will prevent follow-up
logic like ensureResumeBinding and cmux_notification_routed from running when
nothing was actually routed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9e9634ac-b33f-4fe7-9e1f-3797b9708709

📥 Commits

Reviewing files that changed from the base of the PR and between d0bf087 and 84ca297.

📒 Files selected for processing (7)
  • .github/workflows/ci.yml
  • CLI/CMUXCLI+AmpExtension.swift
  • CLI/CMUXCLI+PiExtensionSourcePart2.swift
  • CLI/cmux.swift
  • tests/test_amp_extension_install.py
  • tests/test_opencode_plugin_install.py
  • tests/test_pi_extension_install.py
💤 Files with no reviewable changes (3)
  • tests/test_pi_extension_install.py
  • tests/test_opencode_plugin_install.py
  • tests/test_amp_extension_install.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/ci.yml

Comment thread CLI/CMUXCLI+PiExtensionSourcePart2.swift Outdated
austinywang and others added 2 commits June 29, 2026 19:05
CodeRabbit (PR #6991): sendHook returned true on every early-exit skip, so a
session_start skipped for a missing socket still ran ensureResumeBinding and
emitted a surface-scoped "surface resume set" without a socket, and a dropped
notification could mark cmux_notification_routed. Return false on skip so the
ok-gated resume binding and notification-routed flag only apply when the hook
was actually routed.

Add a Pi regression: with a surface but no socket, assert the extension does
not set a surface resume binding and routes no session hook.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
autoreview (PR #6991): session_shutdown's clearResumeBinding only checked for a
surface target, so a process with CMUX_SURFACE_ID but no CMUX_SOCKET_PATH still
ran `cmux --json surface resume clear ...`, which could route to the default or
wrong tagged cmux socket. Gate the shared surfaceTargetArgs helper on
CMUX_SOCKET_PATH so both ensureResumeBinding and clearResumeBinding stay inert
without a socket — consistent with sendHook/sendFeed.

Strengthen the surface-but-no-socket regression to assert the extension stays
completely silent (no session hook, no surface resume set or clear).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLI/CMUXCLI`+PiExtensionSourcePart2.swift:
- Around line 6-7: The routing guard in CMUXCLI+PiExtensionSourcePart2 is now
allowing CMUX_PANEL_ID, but the CLI target resolution in cmux.swift still only
falls back for CMUX_SURFACE_ID and CMUX_WORKSPACE_ID, creating a false-success
path for panel-only setups. Update the hook target resolution used by runCmux()
/ hooks fallback so it also recognizes CMUX_PANEL_ID, or remove CMUX_PANEL_ID
from the gating predicates in sendHook()/sendFeed() until that end-to-end
contract exists. Keep the guard and the CLI resolution logic aligned around the
same target identifiers.

In `@tests/test_pi_extension_install.py`:
- Around line 299-303: The “no socket” test envs are still inheriting
CMUX_SOCKET_PATH from check_env, so they may accidentally follow the
socket-present path. In the test setup around the surface_no_socket_env and
workspace_no_socket_env branches, explicitly remove CMUX_SOCKET_PATH from each
copied env before launching Bun, so the intended skip-path behavior is isolated
from ambient process state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 463d2ac7-62cd-4cc6-bde1-24c221c42a85

📥 Commits

Reviewing files that changed from the base of the PR and between 84ca297 and eb85977.

📒 Files selected for processing (2)
  • CLI/CMUXCLI+PiExtensionSourcePart2.swift
  • tests/test_pi_extension_install.py

Comment thread CLI/CMUXCLI+PiExtensionSourcePart2.swift Outdated
Comment thread tests/test_pi_extension_install.py
austinywang and others added 4 commits June 29, 2026 19:36
…no-socket tests

CodeRabbit (PR #6991):
- The CLI hook routing (cmux.swift `command == "hooks"`) no-ops unless
  CMUX_SURFACE_ID or CMUX_WORKSPACE_ID resolves a target; it never honors
  CMUX_PANEL_ID. Drop CMUX_PANEL_ID from the Amp/OpenCode/Pi sendHook/sendFeed
  guards so a panel-only process does not observe a false-success no-op route.
- The Pi no-socket regressions copied os.environ via check_env, so an ambient
  CMUX_SOCKET_PATH would silently exercise the socket-present path. Explicitly
  pop CMUX_SOCKET_PATH in both no-socket envs so the skip path is deterministic.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
autoreview (PR #6991): the Amp and OpenCode no-socket regressions build
check_env from os.environ and only removed surface/panel ids, so an ambient
CMUX_SOCKET_PATH (e.g. running the suite inside a cmux pane) made the no-socket
phase exercise the socket-present path and fail the "invoked cmux without
CMUX_SOCKET_PATH" assertion. Pop CMUX_SOCKET_PATH before the no-socket run, matching
the Pi test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
autoreview (PR #6991): sendFeed was broadened to workspace-only contexts, but
runFeedHook in cmux.swift no-ops (`print("{}")`) unless CMUX_SURFACE_ID is set.
A no-surface hibernated Pi agent would then spawn a cmux subprocess per tool
start/end that records nothing — wasteful on a hot path. Require socket + surface
for sendFeed (session hooks stay workspace-routable; only feed needs a surface).

Assert in the no-surface regression that feed telemetry does not fire without a
surface.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ract

autoreview (PR #6991): the guards required CMUX_SOCKET_PATH specifically, but
CLISocketEnvironment.socketPath resolves CMUX_SOCKET_PATH ?? CMUX_SOCKET and the
Pi env allowlist preserves CMUX_SOCKET. An agent in a legacy environment with
only CMUX_SOCKET would silently drop all Amp/OpenCode/Pi session hooks and Pi
resume bindings. Accept (CMUX_SOCKET_PATH || CMUX_SOCKET) in sendHook, sendFeed,
and surfaceTargetArgs so the guard matches what the CLI can actually route.

Also pop legacy CMUX_SOCKET alongside CMUX_SOCKET_PATH in the no-socket test
phases so the regressions stay deterministic regardless of the caller env.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@austinywang

Copy link
Copy Markdown
Contributor Author

Addressing CodeRabbit's docstring coverage warning: this PR only changes generated plugin hook snippets, focused CI wiring, and regression tests for hook routing. It does not introduce a new public API/docstring surface, and the CodeRabbit status check is passing, so no docstring changes are needed for this PR.

@lawrencecchen lawrencecchen added the stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening. label Sep 23, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in cmux backlog Sep 23, 2026

This branch was successfully deployed

1 active deployment
Preview – cmux — 6844484d Deployed Jul 5, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agent Hibernation: opencode (plugin agents) don't always register a restorable session

3 participants