LearnNewsExamplesServices
Frontmatter
id12406
titleBridge-daemon: address the default (argless) Claude instance by absence of --user-data-dir
stateClosed
labels
aiarchitecture
assignees[]
createdAtJun 3, 2026, 3:25 AM
updatedAtJun 7, 2026, 7:18 PM
githubUrlhttps://github.com/neomjs/neo/issues/12406
authorneo-opus-ada
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 3, 2026, 3:49 AM

Bridge-daemon: address the default (argless) Claude instance by absence of --user-data-dir

neo-opus-ada
neo-opus-ada commented on Jun 3, 2026, 3:25 AM

Context

#12399 added instance-addressable wake routing via --user-data-dir for same-bundle harnesses, but implemented only the "instance WITH a given userDataDir" half (instanceResolver.resolveInstancePid). The macOS default app instance is started without --user-data-dir (hard operator constraint: the default Claude Desktop must launch as the normal macOS app, or the OS app/menu-bar toolbar integration breaks — it can never carry the flag).

The Problem

When two same-bundle instances run — the default (@neo-opus-ada) + a --user-data-dir-launched sibling (@neo-opus-grace) — a wake whose subscription has no userDataDir (the default) falls through to tell application "Claude" to activate + first process whose frontmost is true, which is ambiguous across the two windows. Default wakes can land in the sibling window. Verified live 2026-06-03 during 2-instance bring-up.

The Fix

The default instance is uniquely identifiable by the absence of --user-data-dir. Add the complement resolver — zero flag on the default:

  • resolveDefaultInstancePid({appName, psOutput}) → the appName main process (bundle /<appName>.app/Contents/MacOS/, excluding Helper/Framework/crashpad) that carries no --user-data-dir. Only disambiguates when ≥2 mains exist and exactly one is arg-less; otherwise null (caller keeps the legacy activate path — safe, single-instance behavior unchanged).
  • daemon deliverDigest no-userDataDir branch: resolve the default pid and raise THAT process by unix id when it can be uniquely identified; otherwise keep the legacy single-instance activate path.

Contract Ledger

Surface Source of Authority Behavior Fallback Evidence
instanceResolver this ticket / #12399 new resolveDefaultInstancePid (argless-main resolution) null → legacy activate unit
daemon no-userDataDir branch wake-delivery contract route default wake to argless instance when a sibling exists legacy activate when single-instance unit + live
default instance launch operator toolbar constraint NEVER carries --user-data-dir n/a n/a

Acceptance Criteria

  • AC1: resolveDefaultInstancePid returns the argless main pid when one default + N arg'd siblings exist; null when single-instance or >1 argless mains.
  • AC2: daemon routes a no-userDataDir wake to the argless instance by pid when a sibling (arg'd) instance is present; preserves the legacy activate path when single-instance.
  • AC3: unit coverage (2-instance default+sibling → default pid; single-instance → null; helper-process exclusion; injected-exec wrapper).
  • AC4: the default instance requires no --user-data-dir (toolbar constraint upheld).

Related

  • Follow-up to #12399 (the with-arg half); pairs with #12402 (live L3 validation).
  • Origin: live wake mis-routing during 2-instance bring-up, 2026-06-03.
tobiu closed this issue on Jun 3, 2026, 3:49 AM
tobiu referenced in commit e932d26 - "fix(ai): route default instance wakes by absence of --user-data-dir (#12407) on Jun 3, 2026, 3:49 AM