mirror of
https://github.com/stablyai/orca.git
synced 2026-10-02 16:02:15 +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
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
# Why only ripgrep: the bundled rg ships in every artifact and to SSH remotes, and a bump is a
|
# 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
|
- package-ecosystem: npm
|
||||||
directory: /
|
directory: /
|
||||||
schedule:
|
schedule:
|
||||||
|
|||||||
@@ -119,7 +119,6 @@ docs/**
|
|||||||
!docs/reference/agent-session-search-query-tuning.md
|
!docs/reference/agent-session-search-query-tuning.md
|
||||||
!docs/reference/agent-session-search-contract.md
|
!docs/reference/agent-session-search-contract.md
|
||||||
!docs/reference/agent-status-store.md
|
!docs/reference/agent-status-store.md
|
||||||
!docs/reference/bundled-ripgrep.md
|
|
||||||
!docs/reference/antigravity-readiness-evidence.md
|
!docs/reference/antigravity-readiness-evidence.md
|
||||||
!docs/reference/git-compatibility.md
|
!docs/reference/git-compatibility.md
|
||||||
!docs/reference/headless-linux-server.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 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 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.
|
- **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 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 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).
|
- **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'
|
'win32-arm64'
|
||||||
]
|
]
|
||||||
const RIPGREP_PACKAGE_BIN_DIR = 'node_modules/@vscode/ripgrep-universal/bin'
|
const RIPGREP_PACKAGE_BIN_DIR = 'node_modules/@vscode/ripgrep-universal/bin'
|
||||||
|
const RIPGREP_RESOURCE_DIR = 'ripgrep'
|
||||||
|
|
||||||
function ripgrepBinaryName(platform) {
|
function ripgrepBinaryName(platform) {
|
||||||
return platform.startsWith('win32-') ? 'rg.exe' : 'rg'
|
return platform.startsWith('win32-') ? 'rg.exe' : 'rg'
|
||||||
@@ -20,11 +21,11 @@ function ripgrepBinaryName(platform) {
|
|||||||
const bundledRipgrepExtraResources = [
|
const bundledRipgrepExtraResources = [
|
||||||
{
|
{
|
||||||
from: RIPGREP_PACKAGE_BIN_DIR,
|
from: RIPGREP_PACKAGE_BIN_DIR,
|
||||||
to: 'ripgrep',
|
to: RIPGREP_RESOURCE_DIR,
|
||||||
filter: BUNDLED_RIPGREP_PLATFORMS.map((platform) => `${platform}/**`)
|
filter: BUNDLED_RIPGREP_PLATFORMS.map((platform) => `${platform}/**`)
|
||||||
},
|
},
|
||||||
// Why: the binaries statically link PCRE2 (and musl on Linux), whose licenses require the notice.
|
// 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.
|
// 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) {
|
function finalizePackagedRipgrep(resourcesDir) {
|
||||||
for (const platform of BUNDLED_RIPGREP_PLATFORMS) {
|
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)) {
|
if (!existsSync(binaryPath)) {
|
||||||
throw new Error(`Packaged app is missing bundled ripgrep: ${binaryPath}`)
|
throw new Error(`Packaged app is missing bundled ripgrep: ${binaryPath}`)
|
||||||
}
|
}
|
||||||
@@ -57,6 +63,8 @@ function finalizePackagedRipgrep(resourcesDir) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
BUNDLED_RIPGREP_PLATFORMS,
|
BUNDLED_RIPGREP_PLATFORMS,
|
||||||
RIPGREP_PACKAGE_BIN_DIR,
|
RIPGREP_PACKAGE_BIN_DIR,
|
||||||
|
RIPGREP_RESOURCE_DIR,
|
||||||
|
ripgrepBinaryName,
|
||||||
assertBundledRipgrepInstalled,
|
assertBundledRipgrepInstalled,
|
||||||
bundledRipgrepExtraResources,
|
bundledRipgrepExtraResources,
|
||||||
bundledRipgrepMacSignIgnore,
|
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 { createRequire } from 'node:module'
|
||||||
import { describe, expect, it } from 'vitest'
|
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()}/`)
|
const requireFromRoot = createRequire(`${process.cwd()}/`)
|
||||||
|
|
||||||
@@ -9,9 +14,15 @@ describe('bundled ripgrep platforms', () => {
|
|||||||
const packaging: {
|
const packaging: {
|
||||||
BUNDLED_RIPGREP_PLATFORMS: string[]
|
BUNDLED_RIPGREP_PLATFORMS: string[]
|
||||||
RIPGREP_PACKAGE_BIN_DIR: string
|
RIPGREP_PACKAGE_BIN_DIR: string
|
||||||
|
RIPGREP_RESOURCE_DIR: string
|
||||||
|
ripgrepBinaryName: (platform: string) => string
|
||||||
} = requireFromRoot('./config/bundled-ripgrep-resources.cjs')
|
} = requireFromRoot('./config/bundled-ripgrep-resources.cjs')
|
||||||
|
|
||||||
expect(packaging.BUNDLED_RIPGREP_PLATFORMS).toEqual([...BUNDLED_RIPGREP_PLATFORMS])
|
expect(packaging.BUNDLED_RIPGREP_PLATFORMS).toEqual([...BUNDLED_RIPGREP_PLATFORMS])
|
||||||
expect(packaging.RIPGREP_PACKAGE_BIN_DIR).toBe(BUNDLED_RIPGREP_PACKAGE_BIN_DIR)
|
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,
|
* 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`.
|
* 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 const BUNDLED_RIPGREP_PLATFORMS: readonly RelayBuildPlatform[] = RELAY_BUILD_PLATFORMS
|
||||||
export type BundledRipgrepPlatform = RelayBuildPlatform
|
export type BundledRipgrepPlatform = RelayBuildPlatform
|
||||||
|
|||||||
Reference in New Issue
Block a user