mirror of
https://github.com/stablyai/orca.git
synced 2026-09-25 16:02:38 +00:00
chore(search): drop bundled-ripgrep reference doc; assert full packaging layout parity
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
# Why only ripgrep: the bundled rg ships in every artifact and to SSH remotes, and a bump is a
|
||||
# one-line pin change (docs/reference/bundled-ripgrep.md). Other dependencies stay manual.
|
||||
# one-line pin change (the SSH cache keys on the binary's hash). Other dependencies stay manual.
|
||||
- package-ecosystem: npm
|
||||
directory: /
|
||||
schedule:
|
||||
|
||||
@@ -119,7 +119,6 @@ docs/**
|
||||
!docs/reference/agent-session-search-query-tuning.md
|
||||
!docs/reference/agent-session-search-contract.md
|
||||
!docs/reference/agent-status-store.md
|
||||
!docs/reference/bundled-ripgrep.md
|
||||
!docs/reference/antigravity-readiness-evidence.md
|
||||
!docs/reference/git-compatibility.md
|
||||
!docs/reference/headless-linux-server.md
|
||||
|
||||
@@ -75,7 +75,6 @@ Orca targets macOS, Linux, and Windows. Keep all platform-dependent behavior beh
|
||||
- **Windows terminal shells**: `--shell` picks the shell a terminal _is_; `--command` is typed into whatever shell the host spawned, so a shell choice routed through `command` silently becomes a child process. See [`docs/reference/windows-terminal-shell-selection.md`](./docs/reference/windows-terminal-shell-selection.md).
|
||||
- **Windows setup scripts**: the setup/issue-command runner is a `.cmd` batch file unless the script starts with a `#!` line — never derive that from the user's terminal-shell preference, and never launch a `.cmd` runner with a bare `cmd.exe /c` from a Git Bash pane (MSYS rewrites the `/c`). See [`docs/reference/windows-setup-shell.md`](./docs/reference/windows-setup-shell.md).
|
||||
- **Windows child processes**: start them through `runProcess`/`spawnProcess` in `src/shared/child-process/` — never `child_process` directly. It pins `windowsHide`, refuses `shell: true`, and encodes `.cmd`/`.bat` arguments so neither `CommandLineToArgvW` nor `cmd.exe` mangles them. A ratchet test fails on any new direct import. Recognised npm/pnpm `.cmd` shims are resolved to their real target so the spawn skips `cmd.exe` entirely; see [`docs/reference/windows-cmd-shim-resolution.md`](./docs/reference/windows-cmd-shim-resolution.md) before adding a shim shape or debugging one.
|
||||
- **Ripgrep**: Orca bundles `rg` for every platform, WSL, and SSH remotes. Spawn it through `bundledRipgrepCommand` (main) or the relay's resolver, never a bare `'rg'`, and don't add git/readdir fallbacks locally. See [`docs/reference/bundled-ripgrep.md`](./docs/reference/bundled-ripgrep.md).
|
||||
- **Windows process enumeration**: read the table through `src/main/windows/windows-process-table.ts`, never by forking `powershell.exe`. See [`docs/reference/windows-process-enumeration.md`](./docs/reference/windows-process-enumeration.md).
|
||||
- **Windows MSYS/Git Bash panes**: their children break away from the per-PTY job unless it is created without `JOB_OBJECT_LIMIT_BREAKAWAY_OK`, and a `conpty.node` built before that fix passes every existing gate. Before changing the per-PTY job or debugging `windows-msys-job.win32.test.ts`, read [`docs/reference/windows-msys-job-breakaway.md`](./docs/reference/windows-msys-job-breakaway.md).
|
||||
- **Windows daemon-host relocation**: the terminal daemon runs from a copy of the app runtime under `%LOCALAPPDATA%`, which is what survives an auto-update. Before touching that copy, its exe name, or the NSIS uninstall macro, read [`docs/reference/windows-daemon-host-relocation.md`](./docs/reference/windows-daemon-host-relocation.md).
|
||||
|
||||
@@ -12,6 +12,7 @@ const BUNDLED_RIPGREP_PLATFORMS = [
|
||||
'win32-arm64'
|
||||
]
|
||||
const RIPGREP_PACKAGE_BIN_DIR = 'node_modules/@vscode/ripgrep-universal/bin'
|
||||
const RIPGREP_RESOURCE_DIR = 'ripgrep'
|
||||
|
||||
function ripgrepBinaryName(platform) {
|
||||
return platform.startsWith('win32-') ? 'rg.exe' : 'rg'
|
||||
@@ -20,11 +21,11 @@ function ripgrepBinaryName(platform) {
|
||||
const bundledRipgrepExtraResources = [
|
||||
{
|
||||
from: RIPGREP_PACKAGE_BIN_DIR,
|
||||
to: 'ripgrep',
|
||||
to: RIPGREP_RESOURCE_DIR,
|
||||
filter: BUNDLED_RIPGREP_PLATFORMS.map((platform) => `${platform}/**`)
|
||||
},
|
||||
// Why: the binaries statically link PCRE2 (and musl on Linux), whose licenses require the notice.
|
||||
{ from: 'resources/licenses/ripgrep', to: 'ripgrep/licenses' }
|
||||
{ from: 'resources/licenses/ripgrep', to: `${RIPGREP_RESOURCE_DIR}/licenses` }
|
||||
]
|
||||
|
||||
// Why: codesign would try to sign the Linux/Windows builds; they are inert data on macOS.
|
||||
@@ -45,7 +46,12 @@ function assertBundledRipgrepInstalled(projectDir = join(__dirname, '..')) {
|
||||
|
||||
function finalizePackagedRipgrep(resourcesDir) {
|
||||
for (const platform of BUNDLED_RIPGREP_PLATFORMS) {
|
||||
const binaryPath = join(resourcesDir, 'ripgrep', platform, ripgrepBinaryName(platform))
|
||||
const binaryPath = join(
|
||||
resourcesDir,
|
||||
RIPGREP_RESOURCE_DIR,
|
||||
platform,
|
||||
ripgrepBinaryName(platform)
|
||||
)
|
||||
if (!existsSync(binaryPath)) {
|
||||
throw new Error(`Packaged app is missing bundled ripgrep: ${binaryPath}`)
|
||||
}
|
||||
@@ -57,6 +63,8 @@ function finalizePackagedRipgrep(resourcesDir) {
|
||||
module.exports = {
|
||||
BUNDLED_RIPGREP_PLATFORMS,
|
||||
RIPGREP_PACKAGE_BIN_DIR,
|
||||
RIPGREP_RESOURCE_DIR,
|
||||
ripgrepBinaryName,
|
||||
assertBundledRipgrepInstalled,
|
||||
bundledRipgrepExtraResources,
|
||||
bundledRipgrepMacSignIgnore,
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
# Bundled ripgrep
|
||||
|
||||
Orca ships its own `rg` and never depends on the user having installed one. Quick Open, the
|
||||
Explorer name filter, text search, and the paired-server `files.*` RPCs all spawn it.
|
||||
|
||||
## Where the binaries come from
|
||||
|
||||
- `@vscode/ripgrep-universal` (exact pin in `package.json`) carries prebuilt ripgrep for every
|
||||
platform inside its npm tarball: no install script, no download at install time, SHA-256 checked
|
||||
upstream at publish. Linux builds are static musl, so they pass the glibc floor
|
||||
(`linux-glibc-compatibility.md`) and run on any distro, including Alpine and WSL.
|
||||
- Every desktop artifact packages the six relay platforms (`linux|darwin|win32` × `x64|arm64`)
|
||||
under `Resources/ripgrep/<platform>/rg[.exe]` (`config/bundled-ripgrep-resources.cjs`).
|
||||
- The host's own copy serves local search.
|
||||
- Windows uses the Linux copy for WSL.
|
||||
- SSH deploys upload the remote host's copy.
|
||||
- `beforePack` fails when a binary is missing, and `afterPack` verifies all six and sets exec bits.
|
||||
- macOS `signIgnore` keeps codesign off the Linux/Windows copies, which are inert data there.
|
||||
- Windows SignPath signs every packaged `.exe`, including both `rg.exe` copies.
|
||||
- `Resources/ripgrep/licenses/` carries the ripgrep, PCRE2, and musl notices the static binaries
|
||||
require.
|
||||
- Plain-Node `orcad` copies its host binary to `<install root>/ripgrep/<platform>/`.
|
||||
|
||||
## Resolution
|
||||
|
||||
`src/main/ripgrep/bundled-ripgrep-path.ts` is the only resolver in the main process.
|
||||
- Packaged hosts look only in `Resources/ripgrep` or orcad's install root. A missing binary
|
||||
resolves to its expected absolute path, so it fails with ENOENT. A bare `rg` there would let
|
||||
Windows run an `rg.exe` from the repo, which is the spawn cwd.
|
||||
- Development and test hosts use `node_modules/@vscode/ripgrep-universal/bin`, then PATH `rg`.
|
||||
|
||||
Callers pass `{ wsl: true }` when the spawn is routed into a WSL distro, then spread
|
||||
`bundledRipgrepWslSpawnOptions(command)` into `wslAwareSpawn`. Inside the distro, a shell
|
||||
expression finds the Windows install through `wslpath -u`, which honors custom automount roots.
|
||||
- It picks the Linux build for the distro's own `uname -m`. Windows-on-ARM runs x64 Orca beside
|
||||
arm64 distros, so the Windows process's architecture is the wrong key.
|
||||
- It falls back to the distro's own `rg` when the install drive is not mounted.
|
||||
|
||||
There is no local fallback. When the bundled binary cannot start, local listing and search fail
|
||||
with a clear error instead of degrading to `git ls-files`/`git grep`. The usual causes are a
|
||||
damaged install or security software blocking it. This matches VS Code, which also ships rg with
|
||||
no fallback. A silent, slower, partial fallback hid exactly these failures before.
|
||||
|
||||
## SSH remotes
|
||||
|
||||
`src/main/ssh/ssh-relay-ripgrep-install.ts` installs the remote platform's binary at
|
||||
`~/.orca-remote/ripgrep/<content-hash>-<platform>/rg[.exe]`.
|
||||
- The path is keyed on a hash of the binary's bytes, so relay upgrades never re-upload it and any
|
||||
change to the shipped binary does.
|
||||
- It starts right after the relay launches, ahead of sweep/GC. It never delays connect and
|
||||
becomes available to the first Quick Open as soon as possible.
|
||||
- The upload lands in a private stage directory and is renamed into place after a size check.
|
||||
- A file at the final path counts as installed only when its size matches. A truncated leftover
|
||||
is replaced (on Windows only when not held open).
|
||||
- The relay is always launched with `--ripgrep-path`. It re-checks the file on each spawn, prefers
|
||||
it, and falls back to PATH `rg` and then its git/readdir chain. That covers a `noexec` home, a
|
||||
failed upload, or an older client that launched the relay without the flag.
|
||||
- A bundled binary that fails to launch is skipped for 60 s, then retried. Fd/process pressure
|
||||
never counts as failing. Windows antivirus commonly locks a new `rg.exe` briefly.
|
||||
|
||||
The relay fallbacks stay: mixed client/relay versions are normal
|
||||
(`remote-wire-compatibility.md`), and a remote can refuse to execute uploaded binaries.
|
||||
|
||||
## Updating ripgrep
|
||||
|
||||
Bump the exact `@vscode/ripgrep-universal` pin in `package.json`. Nothing else changes: the SSH
|
||||
cache key is the binary's content hash, so remotes fetch the new build on their next deploy.
|
||||
Dependabot proposes the bump (`.github/dependabot.yml`).
|
||||
@@ -1,6 +1,11 @@
|
||||
import { createRequire } from 'node:module'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { BUNDLED_RIPGREP_PACKAGE_BIN_DIR, BUNDLED_RIPGREP_PLATFORMS } from './bundled-ripgrep'
|
||||
import {
|
||||
BUNDLED_RIPGREP_PACKAGE_BIN_DIR,
|
||||
BUNDLED_RIPGREP_PLATFORMS,
|
||||
BUNDLED_RIPGREP_RESOURCE_DIR,
|
||||
bundledRipgrepBinaryName
|
||||
} from './bundled-ripgrep'
|
||||
|
||||
const requireFromRoot = createRequire(`${process.cwd()}/`)
|
||||
|
||||
@@ -9,9 +14,15 @@ describe('bundled ripgrep platforms', () => {
|
||||
const packaging: {
|
||||
BUNDLED_RIPGREP_PLATFORMS: string[]
|
||||
RIPGREP_PACKAGE_BIN_DIR: string
|
||||
RIPGREP_RESOURCE_DIR: string
|
||||
ripgrepBinaryName: (platform: string) => string
|
||||
} = requireFromRoot('./config/bundled-ripgrep-resources.cjs')
|
||||
|
||||
expect(packaging.BUNDLED_RIPGREP_PLATFORMS).toEqual([...BUNDLED_RIPGREP_PLATFORMS])
|
||||
expect(packaging.RIPGREP_PACKAGE_BIN_DIR).toBe(BUNDLED_RIPGREP_PACKAGE_BIN_DIR)
|
||||
expect(packaging.RIPGREP_RESOURCE_DIR).toBe(BUNDLED_RIPGREP_RESOURCE_DIR)
|
||||
for (const platform of BUNDLED_RIPGREP_PLATFORMS) {
|
||||
expect(packaging.ripgrepBinaryName(platform)).toBe(bundledRipgrepBinaryName(platform))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,7 +3,6 @@ import { RELAY_BUILD_PLATFORMS, type RelayBuildPlatform } from './relay-artifact
|
||||
/**
|
||||
* Orca ships its own ripgrep for every relay platform (from @vscode/ripgrep-universal), so local,
|
||||
* WSL, and SSH searches never depend on the user having installed `rg`.
|
||||
* See docs/reference/bundled-ripgrep.md.
|
||||
*/
|
||||
export const BUNDLED_RIPGREP_PLATFORMS: readonly RelayBuildPlatform[] = RELAY_BUILD_PLATFORMS
|
||||
export type BundledRipgrepPlatform = RelayBuildPlatform
|
||||
|
||||
Reference in New Issue
Block a user