* fix(daemon): defer startup-command flush past shell raw-mode switch
When launching an agent (e.g. `claude`) through the quick-launch menu,
the command name appeared twice in the terminal — once from kernel
echo, once from readline's prompt redraw. The daemon session was
flushing its pre-ready stdin queue the moment the OSC 777 shell-ready
marker arrived, but that marker fires from precmd_functions /
PROMPT_COMMAND — before the shell draws its prompt and before
zle/readline flips the PTY into raw mode. Writing while ECHO was still
on produced the visible duplicate.
Mirror the gating already used by the non-daemon path
(local-pty-shell-ready.ts::writeStartupCommandWhenShellReady): wait
for the next data chunk after the marker (the prompt draw) plus a
short 30ms delay, with a 50ms wall-clock fallback for the case where
the prompt arrives in the same chunk as the marker.
This regression became visible after #1025 made the shell-ready
wrappers persist reliably — previously the marker was often missed
and the 15s fallback path fired long after the shell was already in
raw mode, masking the race.
* refactor(daemon): extract PostReadyFlushGate out of Session
Factor the post-ready flush gating out of Session into its own class in
post-ready-flush-gate.ts. Session's only responsibility is now to
arm() the gate on shell-ready, notifyData() on subsequent PTY data,
and clear() on teardown. Removes the max-lines oxlint-disable added in
the previous commit and puts the timing behavior behind focused unit
tests.
No behavior change — kept as a separate refactor commit from the
behavior fix for reviewability.
* fix(daemon): keep queueing writes while post-ready flush gate is pending
Codex review caught an ordering regression: once transitionToReady()
sets _shellState to 'ready', any Session.write() that arrives during
the 30–50ms gate window was being written directly to the subprocess,
bypassing the still-unflushed preReadyStdinQueue. That let late input
race ahead of the buffered startup command.
Expose PostReadyFlushGate.isPending and continue queuing while the gate
is armed so queued writes drain in their original order before any
fresh input reaches the subprocess.
Tighten sidebar fonts/icons (Tasks label, WORKSPACES section, search) and
collapse the task page close button into the source-filter row so the top
chrome forms one compact band.
Detect when the running build is itself a prerelease (e.g. 1.3.17-rc.1)
and auto-enable the RC feed in setupAutoUpdater. Without this, the
default generic /releases/latest/download/ feed only advertises stable
releases, so "Check for Updates" from a prerelease build could never
find the next RC (e.g. 1.3.17-rc.2) unless the user knew to Shift-click.
- Removes single-repo-only constraint on new-issue button
- Adds repo selector to new-issue dialog when multiple repos selected
- Defaults to first selected repo when dialog opens
- Handles edge case where user changes repo selection while dialog open
The update card stayed pinned to the bottom-right for the entire
`downloading` / `downloaded` / `error` lifecycle with no minimize
affordance, and the X on downloaded/error persistently dismissed the
version — which silently orphaned in-flight downloads. Add an always-on
status-bar segment that surfaces progress / ready / error state, plus an
ephemeral `updateCardCollapsed` flag that the card's new minimize button
and Escape key set in those three phases. The flag is renderer-only and
resets on every phase transition so a collapsed `downloading` cannot
bury the `downloaded` / `error` that follows.
- Symlink delete/rename now preserve the link entry (new `preserveSymlink`
option on resolveAuthorizedPath) instead of operating on the target.
- File-explorer delete force-saves dirty editors before trashing so undo
restores the user's latest edits, not stale disk content.
- Thread `recursive` through preload → SSH provider so remote directory
delete works end-to-end.
- Remote deletes now confirm (permanent `rm`, no Trash) and the toast
reflects that no Trash/Recycle Bin is involved.
- Codex managed-home check canonicalizes the storage root before the
prefix compare so macOS `/private/var` paths stop being rejected.
- Add http-link-routing module to centralize link opening logic
- Refactor terminal, markdown, and editor link handlers to use openHttpLink
- Update browser settings to reflect new cross-component link routing
- Inject store accessor to avoid circular import issues
Replaces the `stable` + optional `version` inputs with explicit
`rc | patch | minor | major` choices. Stable kinds are always computed
off the latest published stable release (ignoring intermediate RCs), so
there's nothing to type and no way to pick a version that regresses
electron-updater.
The stable-must-strictly-increase guard stays in place for patch/minor/
major. RC behavior is unchanged — continues an active series or starts
a new one on the next patch.
* docs(electron-skill): harden playwright-cli usage against alias and port collisions
Prefer `command playwright-cli` to bypass user shell aliases that can leak
flags (e.g., `--persistent`) into subcommands. Add guidance to probe a free
CDP port before launching and verify the attached target is the intended
worktree, since stale dev servers on 9333 cause silent mis-attachment.
* docs(electron-skill): trim verbose CDP sections
Trashing is reversible (OS trash + in-app undo), so the extra prompt
is noise. The file explorer now directly moves the file to Trash /
Recycle Bin and shows an auto-dismissing bottom-right toast.
Port VSCode's two-detector pattern (MIT): the existing path pass handles
tokens with a `/`, and a new bare-word pass emits tentative candidates
for whitespace-separated filenames so `ls` output becomes clickable.
The provider's existing `pathExists` check filters candidates that
don't resolve against the terminal's cwd.
Also fix an off-by-one in the xterm link range — `parsed.endIndex` is
the exclusive string-slice end, but xterm's `IBufferRange.end.x` is
1-based inclusive, so `+1` was including the trailing whitespace cell
of column-padded output ("package.json ").