Skip to content

Fix Ctrl+Backspace not deleting word in terminal - #2

Merged
nwparker merged 1 commit into
mainfrom
fix/ctrl-backspace-delete-word
Mar 20, 2026
Merged

nwparker merged 1 commit into
mainfrom
fix/ctrl-backspace-delete-word

Conversation

@mathnogueira

Copy link
Copy Markdown
Contributor

Summary

  • Intercept Ctrl+Backspace in the terminal pane keydown handler and send \x17 (backward-kill-word) to the PTY via sendKeyInput
  • Restty/xterm.js doesn't map this shortcut by default, so the key was being ignored or producing an invalid character

Test plan

  • Open a terminal pane and type a multi-word command
  • Press Ctrl+Backspace and verify the previous word is deleted
  • Verify regular Backspace still works as expected
  • Verify Ctrl+W still closes split panes (not affected)

🤖 Generated with Claude Code

Restty does not map Ctrl+Backspace to backward-kill-word by default.
Intercept the key combination at the capture phase and send \x17 via
sendKeyInput so it reaches the PTY process directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@nwparker
nwparker merged commit f4840ab into main Mar 20, 2026
brennanb2025 added a commit that referenced this pull request May 11, 2026
…ent status) (#1678)

* feat(agent-hooks): introduce relay wire envelope + connectionId stamping

Adds the shared `agent-hook-relay.ts` module with the `agent.hook` JSON-RPC
notification envelope, the `agent_hook.requestReplay` /
`agent_hook.installPlugins` method names, and the
`ORCA_FEATURE_REMOTE_AGENT_HOOKS` flag helper. Promotes `AgentHookSource` to
`shared/` so the relay can import it without dragging Electron in.

Threads a `connectionId: string | null` field through `AgentHookEventPayload`,
the `agentStatus:set` IPC contract, and the renderer-bound preload listener.
Local hook posts stamp `null`; the relay-forwarded path will stamp from `mux`
identity in a later commit. Renderer uses the stamp for stale-event filtering
when an SSH connection tears down with notifications still in flight.

See docs/design/agent-status-over-ssh.md §1, §5, §8 (commit #1).

Co-authored-by: Orca <help@stably.ai>

* refactor(agent-hooks): extract shared listener; add relay-side adapter

Extracts the listener internals (request parsing, payload normalization,
endpoint-file writing, per-CLI extractors, warn-once Sets, slowloris timer
helper, request size cap, paneKey caches) from `src/main/agent-hooks/server.ts`
into a new transport-agnostic `src/shared/agent-hook-listener.ts`. The shared
module uses only Node builtins (no Electron) so it is safe to import from
`src/relay/`.

Adds `src/relay/agent-hook-server.ts` — a thin HTTP-loopback adapter that
wires the shared listener to a `forward(envelope)` callback so `relay.ts` can
re-emit each parsed payload as an `agent.hook` JSON-RPC notification on the
existing SshChannelMultiplexer. The adapter owns:

- 127.0.0.1:0 socket + bearer-token auth, identical shape to the local server
- per-paneKey last-payload cache + replayCachedPayloadsForPanes() for the
  request-driven replay path used after `--connect` reattach (see §5 Path 3)
- clearPaneState(paneKey) for PTY-exit eviction (symmetric with local server)
- buildPtyEnv() / endpoint-file writing for relay-spawned PTYs

Orca's `AgentHookServer` is now a ~200-LoC adapter over the shared listener
that owns the IPC fanout, listener replay, and `ingestRemote(envelope, connId)`
entry point that bypasses the HTTP path for relay-forwarded events.

See docs/design/agent-status-over-ssh.md §3, §8 (commit #2).

Co-authored-by: Orca <help@stably.ai>

* fix(preload): expose connectionId on agentStatus.onSet type

src/preload/index.ts already passes through `connectionId?: string | null`
from main, but the PreloadApi declaration in api-types.ts was missing the
field. Align the type with the runtime contract so renderer call sites
can read connectionId without an `as` cast.

Co-authored-by: Orca <help@stably.ai>

* fix(agent-hooks): harden ingestRemote + relay replay; review-driven cleanup

- ingestRemote: re-run normalizeAgentStatusPayload at trust boundary;
  trim+validate connectionId/paneKey/tabId/worktreeId
- relay: preserve source/env/version through replay via sidecar map;
  drop sourceFromAgentType fallback that mis-tagged unknown agents
- shared listener: exhaustive switch+never on AgentHookSource dispatch
  chains; extractPromptText returns trimmed values; export MAX_PANE_KEY_LEN
- preload: tighten connectionId from optional to required (always sent)
- main IPC: reorder spread so explicit envelope fields win on collision

Co-authored-by: Orca <help@stably.ai>

* chore(docs): drop agent-status-over-ssh design doc from PR

The design RFC was useful for authoring this PR series but doesn't belong
in-tree — keeping it here would freeze line-number references and design
prose against future churn. Folding it into the PR description instead.

Co-authored-by: Orca <help@stably.ai>

* chore(agent-hooks): widen ingestRemote type for env/version (PR2 prep)

Declares `env?: string` and `version?: string` on the `ingestRemote` envelope
parameter so PR2 only needs to add the `warnOnHookEnvOrVersionMismatch`
callsite, not also widen the type. The fields are forwarded verbatim from
the agent CLI POST body on the remote and let Orca's warn-once cross-build
/ dev-vs-prod diagnostics fire identically on remote-sourced events.

Type-only addition; no runtime consumer in this PR.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
LesleyMurfin referenced this pull request in LesleyMurfin/orca Jun 8, 2026
importFromSshConfig only inserted unknown hosts and never updated an
existing target, so a rotated port (or any changed config field) was
silently ignored on re-import. Make it an upsert: config-sourced targets
are refreshed in place, genuinely new hosts are inserted, and the SSH
Manage pane auto-syncs when it opens so changes appear without a manual
Import click.

A new optional SshTarget.source ('ssh-config' | 'manual') protects
user-created and user-edited targets from being overwritten by sync —
editing a target in the UI detaches it from config-sync. Unchanged
targets are skipped so a repeat sync performs no disk write. Editing a
target now also carries cleared optional fields (identity file, proxy
command, jump host) so removing a config-derived value actually deletes
it instead of silently keeping the stale value through the partial merge.

Resolves item #1 of stablyai#4684 (item #2 was fixed in stablyai#4860).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Jinwoo-H added a commit that referenced this pull request Jun 8, 2026
* fix(ssh): sync ~/.ssh/config on import and Manage open

importFromSshConfig only inserted unknown hosts and never updated an
existing target, so a rotated port (or any changed config field) was
silently ignored on re-import. Make it an upsert: config-sourced targets
are refreshed in place, genuinely new hosts are inserted, and the SSH
Manage pane auto-syncs when it opens so changes appear without a manual
Import click.

A new optional SshTarget.source ('ssh-config' | 'manual') protects
user-created and user-edited targets from being overwritten by sync —
editing a target in the UI detaches it from config-sync. Unchanged
targets are skipped so a repeat sync performs no disk write. Editing a
target now also carries cleared optional fields (identity file, proxy
command, jump host) so removing a config-derived value actually deletes
it instead of silently keeping the stale value through the partial merge.

Resolves item #1 of #4684 (item #2 was fixed in #4860).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(ssh): preserve legacy manual targets during config sync

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
thomaszdxsn pushed a commit to thomaszdxsn/orca that referenced this pull request Jun 15, 2026
LesleyMurfin referenced this pull request in LesleyMurfin/orca Jun 20, 2026
…2e; doc wire-format

Adds unit guards that the floating sentinel resolves consistently on activate/close (no selector_not_found) and a Playwright e2e driving the sentinel through the real resolver. Augments the resolveWorktreeSelector comment to document that the client always sends the id: form via toRuntimeWorktreeSelector (no logic change). Per peer-review items #1 (doc) and #2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
LesleyMurfin referenced this pull request in LesleyMurfin/orca Jun 20, 2026
…w (4 fixes)

NotebookLM peer review verdict: CHANGES-NEEDED. Applied the genuine
findings (assessed against actual Electron/Node behavior; teardown was
the only hypothesis NLM rated already-Established):

- fix #7: also override XDG_RUNTIME_DIR (scratch, mode 0700) -- Chromium/
  Electron IPC sockets live there (/run/user/UID, shared w/ prod) and are
  NOT covered by app.getPath('userData').
- fix #8: PRE-7b df -h /tmp gate -- --appimage-extract-and-run unpacks the
  full ~400-600MB squashfs into shared /tmp; a full /tmp could hang prod.
- fix #9: correct Step 4 + acceptance #2 -- under the HOME override,
  homedir() resolves to the scratch home, so expect that cwd (avoids a
  false-negative wrong-cwd failure).
- fix #10: documented prod-recovery pointer for Lesley (systemctl restart
  / orca-serve-version restore); STOP-first posture retained per the
  never-hotfix / deviation=STOP governance.

Execution remains GATED on Lesley's approval. Notebook:
cf8d676b-fb68-4f01-9388-922b83568759

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dvic added a commit to dvic/orca that referenced this pull request Jun 22, 2026
Remote-runtime and SSH worktrees are fetched/created/reparented through the
owning host, which reports them from its own perspective (hostId defaults to
"local"). After the per-worktree hostId override in stablyai#2, that bogus "local"
overrode the repo's runtime owner, so terminals/sessions for a remote worktree
resolved to the local machine instead of the remote (clicking an omarchy-office
worktree opened a shell on the local omarchy-thinkpad).

Re-stamp every runtime worktree payload with the repo's execution host via a
shared withRepoHostId helper, applied at all worktreesByRepo ingress points:
toVisibleWorktrees (fetch), createWorktree, and applyWorktreeLineageUpdate.
Local-owned repos are left untouched, so an explicit local worktree still
overrides a runtime repo owner. Mirrors how repos already get repoWithFetchedOwner.
dvic added a commit to dvic/orca that referenced this pull request Jun 22, 2026
PR stablyai#2 gated the global session-tab sync to web clients only, removing the
desktop path that eagerly populated remote projects. With no on-connect repo
fetch left, remote projects only appeared after the user opened the
Add-Project dropdown (which calls fetchRuntimeEnvironmentRepos directly).

Seed an initial repo/worktree/lineage refresh for every runtime environment
that is already connected when useIpcEvents mounts, and for each one that
becomes connected afterward. Reuses the debounced/throttled refresh scheduler,
and works regardless of whether the remote server emits client events.
Jinwoo-H added a commit that referenced this pull request Jun 22, 2026
* Fix idle remote runtime session work

* fix: stamp remote/SSH worktrees with their repo execution host

Remote-runtime and SSH worktrees are fetched/created/reparented through the
owning host, which reports them from its own perspective (hostId defaults to
"local"). After the per-worktree hostId override in #2, that bogus "local"
overrode the repo's runtime owner, so terminals/sessions for a remote worktree
resolved to the local machine instead of the remote (clicking an omarchy-office
worktree opened a shell on the local omarchy-thinkpad).

Re-stamp every runtime worktree payload with the repo's execution host via a
shared withRepoHostId helper, applied at all worktreesByRepo ingress points:
toVisibleWorktrees (fetch), createWorktree, and applyWorktreeLineageUpdate.
Local-owned repos are left untouched, so an explicit local worktree still
overrides a runtime repo owner. Mirrors how repos already get repoWithFetchedOwner.

* fix: auto-discover remote runtime projects on connect

PR #2 gated the global session-tab sync to web clients only, removing the
desktop path that eagerly populated remote projects. With no on-connect repo
fetch left, remote projects only appeared after the user opened the
Add-Project dropdown (which calls fetchRuntimeEnvironmentRepos directly).

Seed an initial repo/worktree/lineage refresh for every runtime environment
that is already connected when useIpcEvents mounts, and for each one that
becomes connected afterward. Reuses the debounced/throttled refresh scheduler,
and works regardless of whether the remote server emits client events.

* fix: tighten idle runtime refresh behavior

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com>
Co-authored-by: Orca <help@stably.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants