Commit Graph

30 Commits

Author SHA1 Message Date
Jinwoo Hong 06780260c0
test(remote-runtime): run an old client and an old server against current code (#12682)
Mixed versions are the normal state of the remote-server feature: users update clients and servers independently. Until now nothing tested that. Every cross-version claim was made by code reading plus unit tests with hand-written old/new shapes — enough to catch design problems, not enough to catch a real skew regression.

This runs the REAL protocol implementations from two builds against each other in one process: the actual host methods and RPC dispatcher on one side, the actual renderer multiplexer on the other, with a transport that reproduces the production asymmetry — each side decodes with its OWN codec and drops frames whose opcode it does not know. A frame survives only if the RECEIVING build understands it, which is what makes this level sufficient without launching two apps. The old side is a genuine checkout extracted from the release tag; the extracted client was confirmed to lack a symbol that exists only on main.

Journey: subscribe, first snapshot, input reaching the process, live output, hide/reveal snapshot, transport drop, resubscribe, input landing again — across old->new, new->old, and a current/current control. Every step ends on an observed-state barrier; no sleeps. The oracle asserts the recorded step list, the exact 16-frame named sequence, negotiated capabilities, the exact input the host wrote to the PTY, rendered content, and zero decoder-rejected frames. A host method the stub lacks is recorded by name and asserted empty, so a harness gap cannot masquerade as a wire break.

Detection is proven per violation shape, and it attributes each to the correct side: an unnegotiated opcode goes red only where a decoder would reject it, a removed published field goes red only where an old client consumes it, and a legal additive field stays green in all three pairings so the harness will not cry wolf on safe changes.

It also documents the three compatibility rules in docs/reference/remote-wire-compatibility.md, linked from AGENTS.md, since they previously existed only as folklore — notably that "decoders reject unknown opcodes" is true for the desktop decoder but NOT for mobile, which silently drops them.

Deliberately scoped: terminal stream only. The session-tab sync channel is not covered, nor agent-session publications, file/Git RPCs, mobile E2EE framing, or the relay transport. Two version points, so a regression introduced and reverted between them is invisible.

CI selection was verified rather than assumed — `vitest list` confirms 0 matches under the shard's exclude and 4 under the dedicated job — because a lane silently running zero tests is precisely how a host-side defect escaped CI earlier in this series. Closes STA-3469.
2026-08-05 01:31:29 -07:00
OrcaWin ed7849eb7b
fix(worktrees): stop silently switching existing Windows setup scripts to Git Bash (#12406)
* fix(worktrees): stop silently switching existing Windows setup scripts to Git Bash

#6967 derived the Windows setup-runner shell from `terminalWindowsShell`. On
upgrade, any Windows user whose terminal preference resolved to Git Bash had
their existing `orca.yaml` setup script (and issue command) handed to bash
instead of cmd.exe. Scripts authored against the cmd runner — `copy`, `xcopy`,
`set VAR=value`, `if errorlevel 1`, `%VAR%`, backslash paths — broke with no
migration and no warning, and the failure looked like Orca broke the project.

The conflation is also wrong in the steady state: a terminal preference is
per-user, so two people on the same repo got different interpreters for the
same orca.yaml and no project could write a setup script that worked for all
of its Windows contributors.

The interpreter is now a property of the script, declared the standard way:
a leading `#!` line. Native Windows keeps the historical `.cmd` runner unless
the script declares a POSIX shell, so no existing script changes behavior.
`resolveSetupRunnerShell` keeps its role as the feasibility gate — a bash
runner still requires the terminal to resolve to Git Bash, since the launch
command is typed into that shell and uses MSYS `/c/...` paths.

`buildWindowsRunnerScript` now drops a leading `#!` line rather than `call`ing
it, so a declared-bash script that falls back to cmd (Git Bash missing) fails
on a real setup line instead of aborting on errorlevel at line one.

WSL worktrees, POSIX platforms, and SSH hosts are untouched.

* fix(worktrees): keep the cmd setup runner launchable from a Git Bash pane

Adversarial review of this PR found that pinning the runner format per script
reopened issue #6896 one layer down.

- `WorktreeSetupLaunch.shell` had been redefined to mean "the format the runner
  file was written in". `resolveSetupRunnerCommand` consumes it as "the shell
  that types the launch command", so a Git Bash terminal with a batch setup
  script produced `cmd.exe /c "C:\...\setup-runner.cmd"` typed into a bash pane,
  where MSYS rewrites the `/c` switch into a drive path: cmd opens interactively
  and setup never runs. `shell` is the terminal's family again; the runner file's
  .cmd/.sh extension carries the format, and a batch runner launched from a POSIX
  pane reuses the existing PowerShell ProcessStartInfo launcher.
- The cmd runner dropped a leading `#!` line and ran the rest as batch, so a bash
  script reaching cmd (PowerShell/cmd terminal, or any SSH-to-Windows host) got
  its interpreter-agnostic prefix executed before failing mid-way. It now prints
  why and exits 1 without running anything.
- A `#!` line's option flags were discarded: `#!/usr/bin/env -S bash -euo
  pipefail` lost pipefail because the runner is launched as `bash <path>`. The
  generated posix runner now replays declared flags via `set` and drops the
  duplicate interpreter line.
- Docs cover the per-user setup command in repository hook settings, which goes
  through the same `#!` rule, and describe what the `#!` line does and does not
  select.

Tests: composed launch command for a POSIX pane + cmd runner (hooks, shared
runner command, setup sequencing gate, observed-setup signal), the cmd runner's
shebang refusal, and shebang flag replay. Each fails with the source reverted.

* fix(worktrees): replay only real `set` flags and keep the gate in the pane's shell

Two round-2 review findings:

- `#!/bin/bash -l` replayed `set -l`, which exits 2 and aborted the runner under
  its own `set -e` before a single setup line ran (all platforms). Only the flags
  `set` documents are replayed now; a bare `-o` with no option name is dropped
  instead of dumping the shell-option table.
- The wait-for-setup gate picked its language from the runner file, so a batch
  runner launched from a Git Bash pane got the PowerShell gate while the agent
  startup command was already POSIX-quoted — `Invoke-Expression` cannot parse
  `'\''`. The gate now follows the pane; the runner still launches through the
  ProcessStartInfo launcher, never through bash.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-08-03 23:25:50 -07:00
Neil f820f40502
Update AGENTS.md 2026-08-01 22:48:43 -07:00
Jinjing b36ae94e8d docs: add folder workspace use case guidance to AGENTS.md
Folder workspaces are a first-class workspace type that all changes must consider
alongside git worktrees. Document this requirement for developers.
2026-07-23 22:20:43 -07:00
Neil efaaf51136
Update AGENTS.md 2026-07-23 19:24:28 -07:00
Neil a0944cc129
fix(linux): restore Ubuntu 20.04 launch — pin node-pty glibc symbols + add glibc/libstdc++ packaging gate (#9902) (#10019)
* fix(linux): restore Ubuntu 20.04 launch by pinning node-pty glibc symbols (#9902)

The bundled node-pty pty.node is compiled from source in release CI on
ubuntu-latest (glibc 2.39). glibc's 2.32-2.34 libpthread/libutil merge
relocated openpty/forkpty (GLIBC_2.34) and pthread_sigmask (GLIBC_2.32)
into libc under new symbol versions, so the from-source build bound to
versions absent on Ubuntu 20.04 (glibc 2.31). The main process imports
node-pty at startup, so the app crashed on launch. pty.node is the sole
blocker (Electron needs GLIBC_2.25; other native modules <= 2.17).

- Patch node-pty: a .symver shim pins the 3 symbols to their pre-merge
  version (GLIBC_2.2.5 x64 / GLIBC_2.17 arm64), and Linux-only ldflags
  force libutil.so.1/libpthread.so.0 back into DT_NEEDED. Guarded to
  Linux; macOS/Windows untouched.
- Add a packaging gate (verify-linux-glibc-floor.cjs, afterPack): reads
  each bundled native binary's objdump -p version needs and fails the
  Linux build if any strong GLIBC_/GLIBCXX_/CXXABI_ node exceeds stock
  Ubuntu 20.04 (glibc 2.31 / GLIBCXX_3.4.28 / CXXABI_1.3.12). Catches
  GLIBC_ABI_DT_RELR, rejects GLIBC_PRIVATE, skips weak needs, fail-closed.
- Docs + tests; the lazy sherpa-onnx speech prebuilt (GLIBCXX_3.4.29,
  never loaded at launch) is a documented libstdc++-floor exemption.

* fix(linux): assert DT_NEEDED provider deps in the glibc-floor gate

Harden the packaging gate (flagged in adversarial re-eval): the version-floor
check alone can false-pass if the patch's forced `-l:libutil.so.1` ever silently
drops — the pinned openpty@GLIBC_2.2.5 still resolves from libc's compat alias at
build time, but fails to load on Ubuntu 20.04 where openpty/forkpty live only in
libutil. The gate now also asserts that any binary importing openpty/forkpty
keeps libutil.so.1 in DT_NEEDED. Validated on a real symver-pinned .so with
libutil dropped (now fails) vs. present (passes). Documents the recommended
real-host smoke-test follow-up.
2026-07-22 19:11:44 -07:00
Neil 1bb50a5fe1
Update AGENTS.md 2026-07-21 20:51:55 -07:00
Neil a02389cea8
Update code comments section in AGENTS.md
Clarified guidelines for code comments, emphasizing the importance of explaining the 'why' behind non-obvious code.
2026-07-19 21:40:49 -07:00
Neil 057a81493a
fix(sidebar): guard every worktree sort against undefined displayName (crash 99657ab1) (#9315)
* fix(sidebar): guard every worktree sort against undefined displayName (crash 99657ab1)

Worktree.displayName is typed non-optional but arrives undefined at runtime for
persisted/discovered worktrees (crash 99657ab1). PR #8683 fixed the kanban board;
this extends the same guard to the five other sort sites that share those worktree
objects — including the Cmd+J switcher (order-empty-query-worktrees) — via one
shared compareWorktreeDisplayName helper in lib/. Behavior-neutral when names are
present; a missing name now sorts as '' instead of throwing.

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

* docs(agents): add over-commenting anti-pattern example to the comment rule

Anchors the existing 'document the why, briefly' rule with a concrete
before/after (the worktree-displayName guard) so agents stop dumping the
crash id, mechanism, file location, and every call site into a comment.

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

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-18 01:55:00 -07:00
Neil 8b94875cf1
Remove redundant line on PR evidence images
Removed redundant line about committing PR evidence images.
2026-07-12 01:38:02 -07:00
Neil 533992bdda
fix(git): cache unsupported capabilities per host (#8109)
* fix(git): cache unsupported capabilities per host

Old Git worktree, ref-search, and merge-tree fallbacks retried unsupported flags on recurring operations, flooding subprocess traces. Centralize capability probing per native, WSL, and SSH execution host, coalesce concurrent probes, and retry periodically for in-place Git upgrades.

* fix(git): recognize real old-Git merge-tree rejection

* test(git): enforce real binary compatibility matrix

* fix(ci): preserve Git compatibility test ownership

* fix(git): retain supported capability state
2026-07-10 18:19:36 -07:00
Neil f311307560
Add max-lines ratchet CI gate to block new line-limit bypasses (#7608)
oxlint already fails any file over max-lines that is not suppressed, so the
only way to grow past the budget is to add an eslint/oxlint-disable max-lines
comment or a per-file max-lines bump in mobile/.oxlintrc.json. This adds a CI
gate that freezes the current set of suppressions (config/max-lines-baseline.txt,
355 grandfathered entries) and fails the build when a NEW one appears — with a
loud, actionable message pointing at 'split the file'. Existing oversized files
are untouched; the baseline may only shrink (pnpm check:max-lines-ratchet --prune).

Wired into the root lint script and as a dedicated pr.yml step. Unit-tested
(15 cases) and verified against all three failure paths + clean-tree pass.

Co-authored-by: Orca <help@stably.ai>
2026-07-06 17:12:27 -07:00
Neil b9e153570b
Update AGENTS.md 2026-06-08 22:32:42 -07:00
Neil 77d4f8347d
Adjust max-lines lint budgets (#4515) 2026-06-02 15:22:17 -07:00
Neil ddbb6a1e7d
Update oxlint and oxfmt 2026-05-30 13:09:17 -07:00
Jinjing 3884f6d267
docs: revert AGENTS styleguide edit (#3470) 2026-05-29 22:57:47 -07:00
Jinjing a66dc12cb9
fix: address review findings (#3461) 2026-05-29 22:02:44 -07:00
Jinjing fca5f498db
Keep PR refreshes anchored to cached review numbers (#2541)
- Use fallback PR numbers after branch lookup misses, including detached HEAD
- Preserve review cards for forked or deleted-head PRs across manual refreshes
- Clear stale GitHub PR cache entries when unlinking worktree review metadata
2026-05-21 12:12:10 -07:00
Neil 35b77651bf
Strip Grok user_query wrapper from status prompts (#2164)
* Strip Grok user query wrapper from status prompts

* Document PR evidence image handling

* Surface Grok final responses in agent status

* Harden Grok status result extraction
2026-05-17 15:39:14 -07:00
Neil 5eb5043344
Move STYLEGUIDE.md into docs/ (#1625)
Co-authored-by: Orca <help@stably.ai>
2026-05-09 01:08:35 -07:00
Brennan Benson 325ee96ec4
docs(styleguide): UI style guide + AGENTS pointer + selection token cleanup (#1601)
Co-authored-by: Orca <help@stably.ai>
2026-05-08 15:38:09 -07:00
Jinjing 7fbea584ca
docs(agents): note SSH use case in AGENTS.md (#1299)
Co-authored-by: Orca <help@stably.ai>
2026-04-30 23:01:06 -07:00
Brennan Benson 812ca5488b
fix(preload): collapse index.d.ts into type-checked api-types.ts (#1197)
Co-authored-by: Orca <help@stably.ai>
2026-04-27 21:46:17 -07:00
Jinjing 8ea1f2ee33
docs(agents): tighten code-comment rule to short, why-only (#883) 2026-04-20 19:39:25 -07:00
Neil 8dbfec4e20
feat: when closing a tab, go to previous tab (MRU) not nearest neighbor (#784) 2026-04-17 19:43:22 -07:00
Neil fead39f00d
Refactor code comments section in AGENTS.md
Removed bullet points from the code comments section and streamlined the text.
2026-04-12 23:23:08 -07:00
Jinjing 333023fb67
feat: show merge conflicts in source control sidebar (#204)
* Squashed commits

- refactor

- commit design doc

* docs: add why-comments to conflict resolution code and track conflicts on open

- Add explanatory comments throughout conflict resolution code covering
  safety constraints, architectural boundaries, and compatibility choices
- Track unresolved conflicts in openConflictFile so Resolved locally
  state works for conflict-safe entry point
- Add CLAUDE.md/AGENTS.md guideline for documenting the "why"
- Add test for conflict tracking through openConflictFile
2026-03-29 15:40:23 -07:00
Jinjing 9d85347772
docs: add GitHub CLI usage guidelines to AGENTS.md (#179)
* docs: add GitHub CLI usage guidelines to AGENTS.md

* docs: broaden cross-platform compatibility to all code and scripts
2026-03-28 15:56:25 -07:00
Neil 0b9624ec70
feat: linux-friendly keyboard shortcuts (#93)
* feat: make keyboard shortcuts work with Ctrl on Linux/Windows

All Cmd+X shortcuts now also respond to Ctrl+X on non-Mac platforms.
Tooltip hints show platform-appropriate modifier symbols.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add cross-platform guidelines to AGENTS.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 22:21:14 -07:00
Jinjing 5c461c8021
Add AGENTS.md and CLAUDE.md configuration files (#70)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:49:12 -07:00