Bring Your Own Compute — run AI-dispatched commands on your own machine, safely and transparently.
v5.0 BYOC Release · Last updated: April 2026
SynquoRum Agent CLI is a small, zero-dependency program you install on your own computer. It listens for commands from SynquoRum and executes them locally. The AI you are chatting with on synquorum.com can use it to read your project files, run your build, execute scripts, search for code, and more — all without ever uploading your source to our servers.
We call this model BYOC (Bring Your Own Compute). It is the counterpart to SynquoRum's BYOK (Bring Your Own Keys): you bring the compute, you bring the keys, SynquoRum orchestrates. No file is persisted on our servers, no command is executed in our cloud, and no output is retained beyond your chat session.
The CLI is a long-running daemon that polls synquorum.com for pending commands over HTTPS (long polling via Supabase Realtime, with short-polling fallback). When a command arrives, the CLI verifies it against local policy, executes it, and posts the result back. The chat UI renders the stdout/stderr inline, exactly as if you had run it yourself.
Requires Node.js 18 or newer. On Windows, install Node.js from nodejs.org or via winget:
winget install OpenJS.NodeJS.LTSThen install the CLI globally:
npm install -g @synquorum/cli
synquorum --versionPrefer not to install globally? Clone the repo and run it directly:
git clone https://github.com/coretin7/synquorum.git
cd synquorum/packages/cli-node
node bin/synquorum.js --versionRequires Python 3.9 or newer. Zero runtime dependencies — just standard library:
pip install synquorum-cli
synquorum --versionThe Python CLI is feature-identical to the Node CLI and shares the same ~/.synquorum/config.json. You can install both without conflict; the synquorum shim on PATH will point to whichever you installed last.
The IDE actions (Phase 2i) shell out to existing tools when available. Install what matches your workflow:
ripgrep — fast code search (find_in_files). winget install BurntSushi.ripgrep.MSVCprettier, black, rustfmt, gofmt, JuliaFormatter — formatters (format_file)eslint, ruff, clippy, golangci-lint — linters (lint_file)Missing tools are reported with actionable errors — the CLI will never silently fall back to an incorrect result.
This walkthrough assumes you installed the Node CLI globally. The Python CLI uses the same commands.
In your browser, open /settings → Agent CLI tab → click Generate new token → select Other agent → give it a label like my-laptop → copy the 64-character hex token.
synquorum login
# Paste the token when promptedThe CLI refuses to read or write files outside the allowed_directories list, unless you are in YOLO mode. Add the directory you want to give the AI access to:
synquorum allow ~/code/my-project
# or on Windows:
synquorum allow "C:\Users\me\code\my-project"synquorum startYou should see:
synquorum-cli v0.4.0 starting
server: https://synquorum.com
machine: my-laptop
permission mode: safe
allowed directories: 1
transport: long polling (Realtime)
waiting for commands... (Ctrl+C to stop)Leave this terminal open. Ctrl+C will stop the daemon.
Open /chat. You should see 🟢 my-laptop ▼ in the top-right header — that's the active session indicator. Ask the AI something like:
python で "hello from my-laptop" と表示するだけの 1 行のコードを書いてWhen the AI replies with a code block, a ▶ Run Python button appears next to Copy. Click it. In Safe Mode an approval dialog pops up — click Approve and run. A second later, hello from my-laptop appears inline in the chat.
That's it. You are running AI-dispatched code on your own machine through SynquoRum.
Every Agent CLI session runs in one of three permission modes. You set the mode with synquorum config set permission_mode …. The mode affects how destructive actions are handled.
| Mode | Read-only actions | Destructive actions | Dangerous patterns |
|---|---|---|---|
| safe (default) | Executes immediately | Parks in pending_approval; you see an approve / deny dialog in chat | Blocked, no override |
| developer | Executes immediately | Executes immediately, logs a warning chunk | Blocked unless force_unsafe: true is set |
| yolo | Executes immediately | Executes immediately | Executes (!) — use with care |
Regardless of mode, the following patterns are always blocked in Safe mode and require force_unsafe: true in Developer mode:
rm -rf / or rm -rf $HOME — never overridable:() { :|:& };: — never overridabledd of=/dev/sdX writing to raw block devicesmkfs.* /dev/sdX formatting block devicessudo … privilege escalationcurl … | sh piping network downloads into shellsActions that take a file path or working directory cwd are checked against allowed_directories. Paths outside the whitelist are rejected in Safe and Developer modes. YOLO mode skips this check.
synquorum allow /home/me/projects/one
synquorum allow /home/me/projects/two
synquorum disallow /home/me/projects/one # removesynquorum config set permission_mode developer
synquorum config set permission_mode safe # go back
synquorum config set permission_mode yolo # everything, use with care⚠ YOLO mode bypasses every safeguard including path whitelisting and dangerous-pattern detection. Use only in disposable environments (ephemeral VMs, throwaway containers, etc.).
18 primitives total: 14 core actions (Phase 2a–2c) plus 4 optional IDE actions (Phase 2i). All actions are accepted by POST /api/agent/execute with a Bearer token, or by POST /api/agent/cli/run-from-chat with cookie auth from the chat UI.
Execute a shell command via the platform's default shell (cmd.exe on Windows, /bin/sh elsewhere). Buffered stdout/stderr. Callable from the chat UI: the ▶ Run button on bash / sh / zsh / fish / powershell / cmd code blocks dispatches to this action.
{
"action": "run_command",
"params": {
"command": "npm test",
"cwd": "/home/me/my-project",
"timeout_seconds": 300
}
}Same as run_command but streams stdout/stderr in 32 KB / 300 ms chunks while the command runs. The chat UI displays output as it arrives. Dispatched from the chat UI when the shell code block is long-running.
{
"action": "run_command_streaming",
"params": {
"command": "cargo build --release",
"cwd": "/home/me/rust-project",
"timeout_seconds": 1800
}
}Write a multi-line script to a temp file and invoke the specified interpreter. Temp file is deleted after execution (even on error). Dispatched from the chat UI for python / py / node / js / ruby / perl / php / lua / julia / R / pwsh / powershell code blocks.
{
"action": "run_script",
"params": {
"interpreter": "python3",
"script": "import sys\nprint(sys.version)"
}
}Terminate a previously-started long-running process. Phase 2e Part 2 feature — currently returns an informational error asking you to Ctrl+C the daemon.
{ "action": "kill_process", "params": {} }Read the contents of a text file. Supports optional byte range and base64 encoding for binary files.
{
"action": "read_file",
"params": { "path": "/home/me/project/src/main.rs" }
}Write content to a file. Atomic: writes to a temp file and renames over the target. Creates parent directories if needed.
{
"action": "write_file",
"params": {
"path": "/home/me/project/notes.md",
"content": "# Notes\n\nFirst line."
}
}Apply a str_replace-style edit to an existing file. Searches for old_str (which must match exactly and appear exactly once) and replaces it with new_str.
{
"action": "apply_diff",
"params": {
"path": "/home/me/project/src/config.ts",
"old_str": "timeout: 30",
"new_str": "timeout: 60"
}
}List files in a directory. Supports recursive walking, glob filtering, and respects .gitignore when present.
{
"action": "list_directory",
"params": {
"path": "/home/me/project/src",
"recursive": true,
"glob": "*.rs"
}
}Return stat metadata for a file (size, mtime, mode). Optionally computes SHA-256.
{
"action": "file_info",
"params": {
"path": "/home/me/project/Cargo.lock",
"include_hash": true
}
}Probe for 21+ languages (Python, Node, Rust, Go, Julia, Ruby, Elixir, …), 18+ package managers (npm, pnpm, yarn, cargo, poetry, uv, …), and 10+ build tools. Returns versions and paths.
{ "action": "detect_environment", "params": {} }Read an environment variable from the daemon's process environment. Values containing common secret patterns (TOKEN, KEY, PASSWORD) are redacted unless reveal_secrets: true.
{ "action": "get_env_var", "params": { "name": "PATH" } }Set an environment variable for the current daemon session only. Does NOT persist to disk — next command in the same session sees it, but a daemon restart clears it.
{
"action": "set_env_var",
"params": { "name": "RUST_LOG", "value": "debug" }
}Build the project at cwd. Auto-detects the build system from lock files and config: Cargo, npm/pnpm/yarn/bun, Go, Julia (Pkg), Maven, Gradle, .NET, Swift, Xcode, Python (poetry/hatch/pdm/uv/setup.py), Bundler, Mix, Stack, Cabal, Dune, Composer, CMake, Meson, Make, Just, Taskfile.
{
"action": "build_project",
"params": { "cwd": "/home/me/my-rust-project" }
}Run the project's test suite. Same auto-detection as build_project, using the test target (cargo test, npm test, go test ./..., pytest, julia Pkg.test, …).
{
"action": "test_project",
"params": { "cwd": "/home/me/my-rust-project" }
}Run any git subcommand. Read-only subcommands (status, diff, log, show, branch --list) are classified at runtime and bypass the approval prompt. Write operations (add, commit, push, merge, rebase, tag) follow the Safe-mode approval flow.
{
"action": "git",
"params": { "subcommand": "status", "cwd": "/home/me/my-project" }
}Search files under a directory for a text or regex pattern. Prefers ripgrep for speed and .gitignore awareness; falls back to grep -rnE. Returns structured matches with file / line / text.
{
"action": "find_in_files",
"params": {
"path": "/home/me/project/src",
"pattern": "TODO",
"max_results": 100
}
}Find and replace a pattern across files. Pure-JS/Python walker — no sed dependency — so behavior is identical on GNU, BSD, and Windows. Skips .git, node_modules, target, dist, build, .venv, __pycache__. Supports dry_run to preview without writing.
{
"action": "replace_in_files",
"params": {
"path": "/home/me/project",
"pattern": "oldAPI\\.",
"replacement": "newAPI.",
"include_glob": "*.ts",
"dry_run": true
}
}Format a source file in place. Auto-detects formatter from extension: prettier (js/ts/css/json/md/yaml), black (py), rustfmt (rs), gofmt (go), JuliaFormatter (jl), mix format (ex). Supports --check mode to report without writing.
{
"action": "format_file",
"params": {
"path": "/home/me/project/src/main.py",
"check": false
}
}Lint a source file. Auto-detects linter: eslint (js/ts), ruff (py), clippy (rs, via cargo), golangci-lint (go). Returns structured JSON diagnostics when the linter supports it. fix: true enables auto-fixing where available.
{
"action": "lint_file",
"params": {
"path": "/home/me/project/src/main.py",
"linter": "ruff"
}
}No agent CLI, the daemon is not connected.waiting for commands...).build_project instead.Tokens expire after 30 days of inactivity. Generate a new one:
# In browser: /settings → Agent CLI → Generate new token
synquorum login # paste new tokenThe AI asked to read or write a file outside your whitelist. Add it if you intended to:
synquorum allow /path/to/directoryYou clicked Deny on an approval dialog. If that was accidental, just ask the AI to retry the command.
Agent CLI sessions expire after 24 hours of no activity. Restart the daemon and it will refresh the session automatically.
If you have more than one daemon running (laptop + desktop, for example), the header indicator becomes a dropdown. Click it and select the machine you want commands to go to. You can also revoke old tokens at /settings → Agent CLI.
On Windows, the executable is usually python, not python3. When the AI uses run_script with interpreter: python3, either install Python with the py launcher option (the installer adds both names) or create a manual alias:
# PowerShell profile — adds python3 alias
New-Item -Type SymbolicLink -Path "$env:LOCALAPPDATA\Microsoft\WindowsApps\python3.exe" Agent CLI is language-agnostic. Below are minimal end-to-end recipes for four popular runtimes. Each follows the same pattern: install the interpreter or toolchain, whitelist a project directory, then let the chat UI dispatch run_script or run_command to your daemon via the ▶ Run button.
If your language is not in the list, the general rule is: any interpreter that's on your PATH and is known to languageToPrimitive (python, node, ruby, perl, php, lua, julia, R) works with the ▶ Run button out of the box. Compiled languages (Rust, Go, Java, …) don't have a ▶ Run button on code blocks yet — you invoke them through build_project / test_project or the AI calling run_command with a shell command block.
Python is the most common interpreter you'll want for quick data experiments. Install it with winget / brew / apt, then let the AI reach it through run_script.
# Windows
winget install Python.Python.3.12
python --version
# macOS
brew install python@3.12
# Ubuntu
sudo apt install python3 python3-venvIn the chat, ask for a data-analysis snippet:
python で [1, 4, 9, 16, 25] の平均と標準偏差を計算する 1 行のコードを書いてThe AI replies with a ```python block. Click ▶ Run Python, approve, and you'll see the result in a few hundred milliseconds. Common next moves: install numpy / pandas / matplotlib (pip install …) and use the same flow for real datasets that never leave your laptop.
Julia shines at numerical work and the first run of a new Julia process is slow (JIT compilation). Expect 10–30 seconds on the first command, < 1 second after that.
winget install Julialang.Julia
julia --versionTry a compact numerical prompt:
julia で 1 から 10 までの整数の二乗和を 1 行で出力してExpected output: 385. If you plan to use packages (Plots, DataFrames, Flux), you can install them with a preceding code block that the AI generates:
using Pkg
Pkg.add(["Plots", "DataFrames"])That block becomes a separate ▶ Run Julia click. The packages land in your own Julia depot under ~/.julia — no dependency ever reaches SynquoRum's servers.
You already have Node installed if you installed the Agent CLI via npm. The ▶ Run button on a ```js or ```node block invokes run_script with interpreter: node.
node で 現在の unix timestamp をミリ秒で出力する 1 行のコードを書いてNode is also the right choice when you want to hit a local development server from the AI: the AI can write fetch("http://localhost:3000/api/health") and run it, giving you a live smoke test without leaving the chat.
Compiled languages don't get a ▶ Run button on code blocks because there's no one-shot "run this snippet" story — you need a project, a build step, and an entry point. Agent CLI covers them through the build_project / test_project actions, which auto-detect Cargo, Go modules, Maven, Gradle, and more. In v5.0 these are API-only; once you wire them into your workflow, typical patterns look like:
# Rust (via run_command ▶ Run Shell on a bash block)
cd ~/code/my-rust-project
cargo build --release
# Go
cd ~/code/my-go-service
go test ./...
# Java (Maven)
cd ~/code/my-java-app
mvn verifyWhen you want the AI to build and iterate autonomously over a Rust or Go project, a common recipe is: AI asks the daemon to call build_project (returns exit code + stderr), AI inspects stderr, AI calls apply_diff to fix a line, AI calls build_project again. This agentic loop works today via direct API calls; a first-class chat UI for it is on the roadmap after v5.0.
Need help? Check GitHub issues or reach out via the settings page.
© 2026 SynquoRum · BYOC Release