Resolve agent-detection.ts split-vs-monolith conflict by porting main's
Gemini/Pi title fixes (#5270 masquerade guard, isLegacyPiCompatibleTitle)
into the split module agent-title-core.ts; keep the compatibility barrel.
Flip terminalHiddenViewParking default OFF->ON (byte mode). The three
authority/gate/query flags stay false (no main emitter in this build).
Update the byte-mode guard test, docs, reliability gate, and e2e comments.
Co-authored-by: Orca <help@stably.ai>
shutdownCompletedAgentPaneForHibernation already unregisters live pane
handlers before pty.kill to prevent phantom notifications from the teardown
flush, but a parked tab's byte watcher rides the dispatcher sidecar that call
does not touch. Dispose it after a successful kill — deliberately not before:
a failed kill leaves the session running and it must keep its watcher.
This is the hibernation analog of the worktree-shutdown wiring and does not
exist in PR #7214 yet (worth adopting there); regression tests cover both the
success and kill-failure paths. Also: "afterwards" → "afterward" in the
parking doc (static analysis).
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
The header was adapted for the standalone extraction but two body sections
still called fact mode "(default)" and phases 3-5 "(all shipped)" — the exact
byte-mode-pinning confusion this PR guards against.
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
Extracts the self-contained "hidden-view parking" slice from PR #7214
(orca-performance) as a standalone fix for the Windows renderer OOM/hang
under multi-agent load (#7175 / STA-476): long-hidden terminal panes
unmount after a 30s hysteresis while a pane-less byte watcher keeps
bell/title/agent-completion side effects alive; reveal rides the existing
tab-move reattach path.
Byte mode only: no main-process side-effect emitter ships here, so
constants.ts pins terminalMainSideEffectAuthority / terminalHiddenDeliveryGate /
terminalModelQueryAuthority to false (the single intentional divergence from
#7214, reconciled by taking #7214's values when its emitter lands). The
parking kill switch terminalHiddenViewParking also ships default-OFF
(opt-in) until the memory win is confirmed in a soak.
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
* docs: add headless Linux server guide
* docs: add ldd/appimage-extract tip for diagnosing missing libraries
Salvaged from #6817 before closing it as a duplicate.
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Jinwoo-H <jinwoo@stably.ai>
Co-authored-by: Orca <help@stably.ai>
* docs(spec): manual network address entry for mobile pairing
* docs(plan): manual network address entry for mobile pairing
* docs(plan): fix two test-spec issues in Task 1
* feat(mobile-pairing): add parseManualNetworkAddress validator
* docs(plan): fix buildComboboxEntries filter rule
* feat(mobile-pairing): buildComboboxEntries for network interface combobox
* feat(mobile-pairing): combobox with manual address entry
* docs(spec): align buildComboboxEntries behavior with corrected plan
* fix(mobile-pairing): use text-destructive token for inline error
* fix(mobile-pairing): route Use row through translate() with i18next interpolation
* refactor(mobile-pairing): extract NetworkInterfaceCombobox shared by MobileHero and Settings section
The Popover + Command + manual-entry UX lived only in the Settings →
Mobile → Network Interface section. The mobile pairing screen
("Step 2 of 2 — Pair this computer") had its own copy of the same
Select-based dropdown that did not support manual address entry. A
user trying to pair with a Tailscale MagicDNS hostname from the
pairing screen could not enter it.
Extract the typeable combobox into a shared
`NetworkInterfaceCombobox` component. Both surfaces now render the
same Popover + Command with manual address entry, the `Use "..."`
row, the inline validation error, and the `(custom)` trigger label.
Settings keeps its own Generate QR button, Refresh + Tooltip, and
Tailnet accordion around the combobox. The pairing screen keeps its
existing layout (label + combobox + refresh icon).
Net deletion: ~160 lines. Net behavior gain: manual address entry is
now reachable from both surfaces, not only Settings.
* style(ui): give CommandInput a visible background so the search box is not lost
The Popover content above the CommandList renders the cmdk CommandInput
with only a thin bottom border. Against a white popover background it
visually disappears, especially in the mobile pairing screen where the
popover sits inside a dark phone mockup. Add a subtle `bg-muted/30` +
`py-1` so the input row is unambiguous, without changing the input's
shape or behavior.
* fix(mobile-pairing): drop cmdk CommandItem, use plain buttons inside Popover
In `pnpm dev` HMR cycle the cmdk CommandItem `onSelect` dispatch was
unreliable — clicking the item fired the synthetic event but the parent
React state never received it, so the trigger label never updated after
the user picked a manual address or a refreshed interface.
Replace the `Command` + `CommandItem` primitives inside
NetworkInterfaceCombobox with a native `<input>` + `<button>` list
wrapped by Radix `Popover`. The list now responds to the user's first
click without any intermediate effect that could be skipped in dev mode.
The combobox keeps the same props contract, the same placeholder, the
same inline validation, and the same `Use "<address>"` row at the
bottom of the list.
Update MobileNetworkInterfaceSection.test.tsx selectors from
`role=option` (cmdk's) to `role=button` so the integration test still
asserts the right element. All 479 feature tests still pass.
* debug(mobile-pairing): log handleSelect* invocations to confirm click path
* fix(mobile-pairing): commit on pointerdown to beat Radix Popover close race
In dev mode Radix Popover's close-on-pointerdown handler occasionally
fires before React's synthetic click dispatch reaches the option button,
so the parent's selectedAddress never updates after the user picks a
manual address. Bind the commit handler to pointerdown (synchronous,
before any pointer-up / click synthesis) and call event.preventDefault()
to avoid text-selection side effects. Keep onClick as a fallback so
keyboard / touch / programmatic-dispatch paths still work.
* fix(mobile-pairing): keep manually-typed addresses across network refresh
`selectRefreshedNetworkAddress` used to fall back to the first OS
interface whenever `currentAddress` wasn't in the OS-enumerated
list — so a user who typed a Tailscale MagicDNS name saw their
selection snap back to LAN every time `loadNetworkInterfaces`
returned. Treat manual entries as sticky by passing an
`isManual` flag from the caller; `selectRefreshedNetworkAddress`
now keeps the address when the caller says the user typed it.
`MobilePage` tracks `addressIsManual` alongside
`selectedAddress`: `handleAddressChange` flips it on when the
picked address is not in the OS list, and `loadNetworkInterfaces`
passes it through so refresh keeps the choice.
* chore(mobile-pairing): remove debug logs and sync new-combobox-listbox i18n key
* fix(mobile-pairing): address CodeRabbit review on manual-address lifecycle
Three real bugs from review, plus a regression test:
1. NetworkInterfaceCombobox in MobileHero was disabled when
`networkInterfaces.length === 0`, which locked users out of the
only path to type a manual address during a transient empty
discovery. Pass `disabled={false}` and let the combobox's
own empty-state copy explain the situation.
2. `selectRefreshedNetworkAddress` returned `undefined` whenever
`interfaces.length === 0`, even if the user had a manual
address and `currentAddressIsManual` was true. Keep the manual
address so a recovering discovery doesn't clobber it.
3. `loadNetworkInterfaces` could rewrite `selectedAddress` (e.g.
when a refresh swaps to a freshly-discovered tailnet) but never
updated `addressIsManual`, so the next refresh could revert
the user back to LAN. Re-derive `addressIsManual` from the
new address after every refresh.
Adds a regression test in
`mobile-network-interface-selection.test.ts` exercising the
empty-refresh + manual path.
* style(mobile-pairing): trim disabled-false comment to two lines
* refactor(mobile-pairing): replace typeable combobox with select + custom-address dialog
The Settings/MobileHero network selector used a Popover+search-input hybrid
that looked uneven and hid its validation error behind the open popover.
Replace it with a plain Select of discovered interfaces plus an
'Add custom address…' footer row that opens a small dialog for entering a
Tailscale hostname or static IP. Drops the 'MagicDNS' jargon for plainer
copy, keeps the '(custom)' trigger label, and routes all strings through
translate() with real es/ja/ko/zh translations. Removes the now-dead
buildComboboxEntries helper. Also adds the missing scrollbar-sleek class
the old list omitted (was failing pnpm lint).
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: ppw-stack <ppw-stack@users.noreply.github.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
* Add floating workspace contextual tour
Co-authored-by: Orca <help@stably.ai>
* Clarify floating workspace tour intro copy
Co-authored-by: Orca <help@stably.ai>
* Differentiate floating workspace tour steps instead of repeating examples
Co-authored-by: Orca <help@stably.ai>
* Lead floating workspace tour with the user benefit
Co-authored-by: Orca <help@stably.ai>
* Pitch floating workspace tour around cross-repo agents
Co-authored-by: Orca <help@stably.ai>
* Refine floating workspace tour step 1 copy
Co-authored-by: Orca <help@stably.ai>
* Anchor floating workspace tour step 2 on the minimize control
Co-authored-by: Orca <help@stably.ai>
* Restore floating workspace tour step 2
Co-authored-by: Orca <help@stably.ai>
* Anchor floating workspace tour steps on New Terminal and New Markdown Note
Co-authored-by: Orca <help@stably.ai>
* Retitle floating workspace tour step 2 as scratchpad
Co-authored-by: Orca <help@stably.ai>
* Add why-comments for tour selector fallback and placement flipping
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Orca <help@stably.ai>