# bellpull > Runs a subprocess, resolves the executable it names, and returns one structured result every caller can read: a line for a person, a --json envelope or an agent event. Zero dependencies. Drop-in paths for cross-spawn and which. ## Documentation - [bellpull/cross-spawn](https://bellpull.interlace.tools/docs/api/cross-spawn): Every export of bellpull/cross-spawn, with its signature and doc comment: _enoent, crossSpawn, parse, spawn, sync, ChildProcess and 1 more, plus 3 types. - [bellpull](https://bellpull.interlace.tools/docs/api): Every export of bellpull, with its signature and doc comment: ambientRuntime, DEFAULT_GRACE, DEFAULT_TIMEOUT, escapeArgument, escapeCommand, extensionCandidates and 20 more, plus 9 types. - [bellpull/node-which](https://bellpull.interlace.tools/docs/api/node-which): Every export of bellpull/node-which, with its signature and doc comment: which, plus 1 type. - [bellpull/plugin](https://bellpull.interlace.tools/docs/api/plugin): Every export of bellpull/plugin, with its signature and doc comment: validate, register, reset, registered, contributions, substitute and 3 more, plus 6 types. - [bellpull/which](https://bellpull.interlace.tools/docs/api/which): Every export of bellpull/which, with its signature and doc comment: pathExtensions, extensionCandidates, searchPath, whichAllSync, whichSync, resolveExecutable and 5 more, plus 3 types. - [Changelog](https://bellpull.interlace.tools/docs/changelog): Every release of bellpull, newest first, from its CHANGELOG.md — what changed and the pull request it came from. - [Coming from cross-spawn](https://bellpull.interlace.tools/docs/coming-from/cross-spawn): A cross-spawn alternative with a drop-in path: import spawn from bellpull/cross-spawn, graded 68 / 68 by cross-spawn's own test suite — then zero dependencies, and a run() whose result says which binary ran and treats a non-zero exit as a value. - [Coming from execa](https://bellpull.interlace.tools/docs/coming-from/execa): An execa alternative with zero dependencies: bellpull's run() treats a non-zero exit as a value, not an exception, says which binary ran, and renders one result as text, --json or an agent event. Not an execa drop-in: execa's own suite grades it 0 / 1179, and that zero is the design. - [Coming from which](https://bellpull.interlace.tools/docs/coming-from/which): A which alternative with a drop-in path: import which from bellpull/node-which, graded 5 / 5 by node-which's own test suite — then zero dependencies, and a resolver that returns the PATH entry the binary came from. - [Compatibility](https://bellpull.interlace.tools/docs/drop-ins): How bellpull's drop-ins are graded — cross-spawn 68 / 68 and node-which 5 / 5 by their own suites — and why execa's suite grades bellpull 0 / 1360 and is declared a ceiling, not a drop-in. - [FAQ](https://bellpull.interlace.tools/docs/faq): Short answers about bellpull — execa, non-zero exits, the default timeout, shells, Windows, which binary ran, plugins, CommonJS and what is not built — each with where to read more. - [Getting started](https://bellpull.interlace.tools/docs/getting-started): Install bellpull, run a program, and read one result back: whether it succeeded, its output, and which binary on PATH actually ran — no try/catch. - [Deadlines and the kill ladder](https://bellpull.interlace.tools/docs/guides/deadlines): Every run is bounded: 30 s by default, SIGTERM then SIGKILL after a grace window, and the output written before the kill is kept — plus killing the child when the parent shuts down. - [Resolver plugins](https://bellpull.interlace.tools/docs/guides/plugins): bellpull/plugin: a plugin contributes a search order — asdf or nvm shims, a devcontainer's tools — as plain data with no function, validated at register() and checked by npx bellpull check. - [One result for people and agents](https://bellpull.interlace.tools/docs/guides/reports): format, toJson and toEvent: three renderings of one bellpull Result, over one verdict — ok, failed, timedOut or signalled — so a --json flag cannot say something the human output did not. - [Finding the executable](https://bellpull.interlace.tools/docs/guides/resolution): bellpull/which: whichSync returns the path and the PATH entry that found it, skips empty and relative PATH entries, honours and reports PATHEXT, and runPath puts node_modules/.bin in front. - [Running a program](https://bellpull.interlace.tools/docs/guides/running): run(command, args, { runtime }): an argv array, no shell, output collected, and a result that resolves on a non-zero exit — rejecting only when no process ran. - [Windows without a shell](https://bellpull.interlace.tools/docs/guides/windows): How bellpull runs npm.cmd and other batch files on Windows without shell: true: resolve with PATHEXT, invoke cmd.exe itself, and escape every argument for both parsers so caller data cannot become a command. - [bellpull](https://bellpull.interlace.tools/docs): Runs a subprocess, resolves the executable it names, and returns one structured result every caller can read: a line for a person, a --json envelope or an agent event. Zero dependencies. Drop-in paths for cross-spawn and which. - [Subprocess results for --json and agents](https://bellpull.interlace.tools/docs/recipes/agent-output): Give a CLI's --json mode and an agent's event stream the same facts about a subprocess the terminal shows, from one bellpull Result. - [Incremental migration from cross-spawn](https://bellpull.interlace.tools/docs/recipes/incremental-migration): Swap cross-spawn for bellpull/cross-spawn in one import, then move call sites to run() one at a time, and know what changes at each step. - [Run a project's local tools](https://bellpull.interlace.tools/docs/recipes/local-tools): Run the tools a project installed in node_modules/.bin by name, from any directory inside it, with runPath — npm-run-path's contract, without the dependency. - [Testing resolution without process.env](https://bellpull.interlace.tools/docs/recipes/testing-without-process): Test what your program would run — on Linux, on Windows, with a hostile PATH — by passing a literal runtime instead of mutating process.env. - [Which binary ran?](https://bellpull.interlace.tools/docs/recipes/which-binary-ran): Diagnose a build that differs between machines: list every install of a tool on PATH, best first, and report which one a run actually used. - [Why bellpull](https://bellpull.interlace.tools/docs/why-bellpull): bellpull against execa, cross-spawn and which, one capability per row — including the rows where execa is ahead — every cell linked to the test, grade or source that proves it. ## Family - [burgee](https://burgee.interlace.tools): the family front door - [Compatibility](https://burgee.interlace.tools/docs/compatibility): Every drop-in path in the family, graded by the incumbent’s own test suite. - [Gallery](https://burgee.interlace.tools/docs/gallery): Every glyph, spinner and border the family has registered, rendered. - [Comparison](https://burgee.interlace.tools/docs/comparison): The family against its incumbents: weight, speed and surface.