* fix(shell): OS open actions follow the file's owner, not the focused server
Every shell open request (openPath, openInFileManager, openInExternalEditor,
openFilePath, openFileUri) now carries the path's owning host. Main allows
only a local owner, plus the SSH editor launch when the owner is that same
SSH target, and no longer consults the focused server. The renderer reveal
and Open-in checks drop their focused-server check to match.
* test(e2e): name the owner on the local editor control open
* fix(explorer): Open in follows the catalog owner for folder and host-only SSH workspaces
The explorer toolbar and the source-control Open in menu took their SSH
connection from the repo row, which a folder workspace or a host-only SSH
repo does not have, so the route read as local. Both now derive the route
from the catalog-confirmed owner.
* fix(sidebar): Open in keeps the SSH target of folder and host-only SSH rows
The row resolver now returns the SSH connection it resolved alongside the
runtime owner, so a folder workspace or host-only SSH repo with no repo
connection no longer reads as local.
---------
Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
* feat(native-chat): attach several files from one picker selection
Picks over 256 files are rejected whole, matching the drop limit.
Fixes#23905
* refactor(native-chat): name the composer action for the files it now attaches
The hook still returned `pickAttachment` after it started attaching a
whole selection. Also records why the plural IPC handler sits next to the
singular one, matching its siblings in the same file.
* test(native-chat): cover the paperclip forwarding every picked path
The one line that makes the feature work — the composer handing the whole
picker result to attachExternalPaths — had no test; reverting it to
paths[0] kept every existing test green. Adds a hook test for the
multi-path, canceled, and wrong-pane cases, plus the missing canceled
case for the shell:pickAttachments handler.
* test(native-chat): exercise multi-pick through renderHook
* test(settings): preserve label fallback and verify Spanish copy
Keep latest main's missing-label fixture and restore its translation namespace after cleanup, so later tests still load real catalogs. Independently assert the shipped Spanish resource and rendered supported-agents label.
---------
Co-authored-by: Neil <neil@stably.ai>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
* perf(terminal): batch file-link existence checks on their owning host
* test(relay): allow additive filesystem capabilities
* fix(web): keep terminal file links working under batched existence checks
createShellApi omitted pathsExist, so withFallback answered the new batch
call with a truthy proxy resolving to undefined and the whole hover batch
rejected — dropping every link on lines with an out-of-worktree path.
* test(web): assert the shim without type assertions
---------
Co-authored-by: m4air <m4air@Mac.localdomain>
Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
Co-authored-by: Neil <neil@stably.ai>
* fix(win32): suppress Command Prompt window on IDE launches
- Prefer JetBrains GUI executables (`*64.exe`) over `.cmd` shims to avoid
console allocation (STA-3040).
- Use `start "" /B` when launching GUI apps via batch scripts; shims chain
through console helpers that allocate a visible prompt even with
`windowsHide`. `start /B` returns immediately, preventing the lingering window.
* fix(win32): suppress Command Prompt window on IDE launches
Prevent lingering Command Prompt windows when launching JetBrains IDEs
on Windows. Use `start "" /B cmd /d /c` so the nested shell exits with
the batch script, but only for JetBrains shims—VS Code and Cursor keep
the waiting form because `start` re-parses arguments and breaks remote
paths with spaces. Prefer colocated `*64.exe` executables beside the
resolved `.cmd` shim over PATH lookups to avoid stale installations.
* fix(win32): extend IDE launcher console suppression to direct paths
Support IDE paths stored directly in settings (e.g., idea.exe,
webstorm.cmd). Detect console idea.exe stubs alongside batch shims
for upgrade to GUI *64.exe. Fix start command title escaping: use
empty string instead of '""' to prevent libuv re-quoting.
Allow the existing "Open in" entries to launch a configured VS Code
launcher against an SSH-backed worktree via Remote-SSH:
code --remote ssh-remote+<authority> <remote-path>
- Split the blanket SSH/runtime block into a capability model: file
managers and non-VS Code launchers stay local-only (disabled with
"Local only" metadata); a recognized VS Code command is enabled and
forwarded with connectionId over a typed object IPC.
- Main process stays authoritative: rejects active/owned runtimes,
resolves the SshTarget from the persisted Store, derives the authority
(config alias, or username@host on port 22, or ssh-alias-required on a
non-default port), validates POSIX/Windows absolute remote paths without
local stat/normalize, and rejects non-VS Code and compound commands
before spawn.
- Authority and remote path are passed as separate argv; getSpawnArgsForWindows
remains the cmd/bat shim boundary and fails closed on metacharacters.
- Same capability rules across the worktree menu, Explorer overflow, and
the source-control entry context menu.
Refs STA-2386
Closes#9999
Reverts the hidden terminal pressure changes from #2661 to restore the prior terminal rendering path while the fullscreen TUI regression is handled separately.
* feat: add configurable Open In menu
Implements configurable Open In applications in worktree context menus with persisted settings, preload/API wiring, and renderer controls/tests.\n\nDesign doc: docs/configurable-open-in-menu.md
* fix: address review findings
* Add worktree open-in editor button
Implements the Open in menu flow from docs/open-in-worktree-button.md, including shell IPC validation and sidebar menu integration.
* Move worktree open action into menu
Updates the design to remove the card button and show VS Code under a single Open in context-menu item.
* Shorten worktree file manager labels
* Add support for custom desktop notification sounds
* perf(notifications): cache custom sound + restart-on-play
Avoids re-reading the configured audio file (up to 10MB) from disk and
re-transferring it over IPC on every notification. Adds a path-only
resolver so repeated dispatches with an unchanged sound skip the heavy
load entirely.
For burst handling, follows the VS Code AccessibilitySignalService /
GNOME canberra pattern: one shared HTMLAudioElement per sound, restarted
from t=0 on each play, with an in-flight guard that drops new plays
while the sound is still ringing. This self-dedupes by the sound's own
duration without any magic time constant — distinct sounds remain free
to overlap. The Test button passes force: true so an explicit user
action always plays through.
Co-authored-by: Orca <help@stably.ai>
---------
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
Co-authored-by: Orca <help@stably.ai>
* New workspace page with agent catalog, composer modal, and terminal integration
* fix lint
* better blank state
* fix: resolve typecheck errors in new-workspace flow
- widen activateAndRevealWorktree's issueCommand to accept direct
command shape used by NewWorkspacePage, not just the main-process
runner-script variant
- use a ref object in pty-connection tests to dodge TS narrowing the
captured callback to never across the mock closure boundary
* fix: bound worktree name auto-suffix loop to prevent OOM in tests
The auto-suffix loop in createLocalWorktree had no termination cap.
When tests (or a misconfigured env) mocked getBranchConflictKind /
getPRForBranch to always return a collision, the loop ran forever and
the vitest worker crashed with "Ineffective mark-compacts near heap
limit".
Cap the search at 100 suffixes, and if all fail, fall back to the
original specific error messages (branch already exists / PR already
owns the name) instead of a generic failure.
Update the two tests that asserted the old throw-on-first-conflict
behavior to verify the new auto-suffix path end-to-end.
- Add local image insertion support with file picker and toolbar button
- Harden image copy with COPYFILE_EXCL flag to prevent overwrites
- Add deconfliction loop limit (1000 iterations) to prevent hangs
- Force image re-render on filePath change for correct URL resolution
- Extract toolbar button into reusable RichMarkdownToolbarButton component
- Use setHeading (not toggleHeading) for idempotent slash commands
- Add path utilities (dirname, joinPath) with comprehensive tests
- Add image utility functions for safe copy destination handling
- Add terminal link detection that recognizes file paths with optional
line:column suffixes and opens them in the editor or externally
- Split shell IPC into separate openUrl, openFilePath, openFileUri, and
pathExists handlers with proper URL/path validation
- Register xterm link providers per pane with path existence caching
- Support OSC 8 hyperlinks for http(s) and file: protocols
- Add editor-reveal-location custom event for jumping to line/column
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>