← SynquoRum

Agent CLI

Bring Your Own Compute — run AI-dispatched commands on your own machine, safely and transparently.

v5.0 BYOC Release · Last updated: April 2026

1. Overview

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.

Why BYOC?

  • Privacy — Your source code, environment variables, and build artifacts never leave your machine.
  • Speed — Builds and tests run at local disk speed, not over a sandbox network.
  • Cost — You pay for the compute you are already paying for (your laptop, your workstation). SynquoRum does not run a VPS fleet to forward your bills to.
  • Trust — Every destructive action can be gated by an approval prompt in the chat UI. You see the exact command, you click Approve, it runs. No hidden actions.

Architecture

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.

2. Installation

Option A: Node.js (recommended)

Requires Node.js 18 or newer. On Windows, install Node.js from nodejs.org or via winget:

powershell
winget install OpenJS.NodeJS.LTS

Then install the CLI globally:

bash
npm install -g @synquorum/cli
synquorum --version

Prefer not to install globally? Clone the repo and run it directly:

bash
git clone https://github.com/coretin7/synquorum.git
cd synquorum/packages/cli-node
node bin/synquorum.js --version

Option B: Python (for Python / Julia / R researchers)

Requires Python 3.9 or newer. Zero runtime dependencies — just standard library:

bash
pip install synquorum-cli
synquorum --version

The 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.

Optional dependencies

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.MSVC
  • prettier, 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.

3. Quickstart (5 minutes)

This walkthrough assumes you installed the Node CLI globally. The Python CLI uses the same commands.

Step 1 — Generate a token

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.

Step 2 — Log in

bash
synquorum login
# Paste the token when prompted

Step 3 — Whitelist a working directory

The 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:

bash
synquorum allow ~/code/my-project
# or on Windows:
synquorum allow "C:\Users\me\code\my-project"

Step 4 — Start the daemon

bash
synquorum start

You 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.

Step 5 — Run something from chat

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.

4. Permission Model

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.

ModeRead-only actionsDestructive actionsDangerous patterns
safe (default)Executes immediatelyParks in pending_approval; you see an approve / deny dialog in chatBlocked, no override
developerExecutes immediatelyExecutes immediately, logs a warning chunkBlocked unless force_unsafe: true is set
yoloExecutes immediatelyExecutes immediatelyExecutes (!) — use with care

Dangerous patterns

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
  • Classic fork bomb :() { :|:& };: never overridable
  • dd of=/dev/sdX writing to raw block devices
  • mkfs.* /dev/sdX formatting block devices
  • sudo … privilege escalation
  • curl … | sh piping network downloads into shells

Allowed directories

Actions 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.

bash
synquorum allow /home/me/projects/one
synquorum allow /home/me/projects/two
synquorum disallow /home/me/projects/one  # remove

Switching modes

bash
synquorum 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.).

5. Actions Reference

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.

Category: shell

run_commandshelldestructivechat ui ✓default timeout: 120s

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.

Required params
command
Optional params
cwd, env, stdin, timeout_seconds, shell
json
{
  "action": "run_command",
  "params": {
    "command": "npm test",
    "cwd": "/home/me/my-project",
    "timeout_seconds": 300
  }
}
run_command_streamingshelldestructivechat ui ✓default timeout: 600s

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.

Required params
command
Optional params
cwd, env, timeout_seconds, shell
json
{
  "action": "run_command_streaming",
  "params": {
    "command": "cargo build --release",
    "cwd": "/home/me/rust-project",
    "timeout_seconds": 1800
  }
}
run_scriptshelldestructivechat ui ✓default timeout: 300s

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.

Required params
interpreter, script
Optional params
cwd, env, args, timeout_seconds
json
{
  "action": "run_script",
  "params": {
    "interpreter": "python3",
    "script": "import sys\nprint(sys.version)"
  }
}
kill_processshelldestructiveapi onlydefault timeout: 30s

Terminate a previously-started long-running process. Phase 2e Part 2 feature — currently returns an informational error asking you to Ctrl+C the daemon.

Required params
(none)
json
{ "action": "kill_process", "params": {} }

Category: filesystem

read_filefilesystemread-onlyapi onlydefault timeout: 30s

Read the contents of a text file. Supports optional byte range and base64 encoding for binary files.

Required params
path
Optional params
encoding, max_bytes, start_line, end_line
json
{
  "action": "read_file",
  "params": { "path": "/home/me/project/src/main.rs" }
}
write_filefilesystemdestructiveapi onlydefault timeout: 30s

Write content to a file. Atomic: writes to a temp file and renames over the target. Creates parent directories if needed.

Required params
path, content
Optional params
encoding, create_dirs, overwrite
json
{
  "action": "write_file",
  "params": {
    "path": "/home/me/project/notes.md",
    "content": "# Notes\n\nFirst line."
  }
}
apply_difffilesystemdestructiveapi onlydefault timeout: 30s

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.

Required params
path, old_str, new_str
json
{
  "action": "apply_diff",
  "params": {
    "path": "/home/me/project/src/config.ts",
    "old_str": "timeout: 30",
    "new_str": "timeout: 60"
  }
}
list_directoryfilesystemread-onlyapi onlydefault timeout: 30s

List files in a directory. Supports recursive walking, glob filtering, and respects .gitignore when present.

Required params
path
Optional params
recursive, glob, respect_gitignore, max_depth
json
{
  "action": "list_directory",
  "params": {
    "path": "/home/me/project/src",
    "recursive": true,
    "glob": "*.rs"
  }
}
file_infofilesystemread-onlyapi onlydefault timeout: 10s

Return stat metadata for a file (size, mtime, mode). Optionally computes SHA-256.

Required params
path
Optional params
include_hash
json
{
  "action": "file_info",
  "params": {
    "path": "/home/me/project/Cargo.lock",
    "include_hash": true
  }
}

Category: environment

detect_environmentenvironmentread-onlyapi onlydefault timeout: 60s

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.

Required params
(none)
Optional params
probe_timeout_seconds
json
{ "action": "detect_environment", "params": {} }
get_env_varenvironmentread-onlyapi onlydefault timeout: 10s

Read an environment variable from the daemon's process environment. Values containing common secret patterns (TOKEN, KEY, PASSWORD) are redacted unless reveal_secrets: true.

Required params
name
Optional params
reveal_secrets
json
{ "action": "get_env_var", "params": { "name": "PATH" } }
set_env_varenvironmentdestructiveapi onlydefault timeout: 10s

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.

Required params
name, value
json
{
  "action": "set_env_var",
  "params": { "name": "RUST_LOG", "value": "debug" }
}

Category: build

build_projectbuilddestructiveapi onlydefault timeout: 600s

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.

Required params
(none)
Optional params
cwd, build_system, args, timeout_seconds
json
{
  "action": "build_project",
  "params": { "cwd": "/home/me/my-rust-project" }
}
test_projectbuilddestructiveapi onlydefault timeout: 600s

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, …).

Required params
(none)
Optional params
cwd, build_system, args, timeout_seconds
json
{
  "action": "test_project",
  "params": { "cwd": "/home/me/my-rust-project" }
}

Category: vcs

gitvcsdestructiveapi onlydefault timeout: 300s

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.

Required params
subcommand
Optional params
args, cwd, timeout_seconds
json
{
  "action": "git",
  "params": { "subcommand": "status", "cwd": "/home/me/my-project" }
}

Category: optional (Phase 2i IDE actions)

find_in_filesoptionalread-onlyapi onlydefault timeout: 60s

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.

Required params
path, pattern
Optional params
regex, case_sensitive, max_results, include_glob, exclude_glob, follow_symlinks
json
{
  "action": "find_in_files",
  "params": {
    "path": "/home/me/project/src",
    "pattern": "TODO",
    "max_results": 100
  }
}
replace_in_filesoptionaldestructiveapi onlydefault timeout: 120s

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.

Required params
path, pattern, replacement
Optional params
regex, case_sensitive, include_glob, exclude_glob, dry_run, max_files
json
{
  "action": "replace_in_files",
  "params": {
    "path": "/home/me/project",
    "pattern": "oldAPI\\.",
    "replacement": "newAPI.",
    "include_glob": "*.ts",
    "dry_run": true
  }
}
format_fileoptionaldestructiveapi onlydefault timeout: 60s

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.

Required params
path
Optional params
formatter, check
json
{
  "action": "format_file",
  "params": {
    "path": "/home/me/project/src/main.py",
    "check": false
  }
}
lint_fileoptionalread-onlyapi onlydefault timeout: 120s

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.

Required params
path
Optional params
linter, fix, config_path
json
{
  "action": "lint_file",
  "params": {
    "path": "/home/me/project/src/main.py",
    "linter": "ruff"
  }
}

6. Troubleshooting

The ▶ Run button does not appear on code blocks

  • Check that the header shows 🟢 your-label in the top-right of the chat page. If it shows No agent CLI, the daemon is not connected.
  • Verify the daemon is still running in its terminal (look for waiting for commands...).
  • The Run button only appears for runnable languages: bash, sh, powershell, python, node/js, ruby, perl, php, lua, julia, R. Languages like TypeScript, Java, Go, Rust, C/C++ need to be compiled first — use build_project instead.

"Token is invalid or expired"

Tokens expire after 30 days of inactivity. Generate a new one:

bash
# In browser: /settings → Agent CLI → Generate new token
synquorum login    # paste new token

"path is not in allowed_directories"

The AI asked to read or write a file outside your whitelist. Add it if you intended to:

bash
synquorum allow /path/to/directory

"Command was denied by the user"

You clicked Deny on an approval dialog. If that was accidental, just ask the AI to retry the command.

The daemon stops after a while

Agent CLI sessions expire after 24 hours of no activity. Restart the daemon and it will refresh the session automatically.

Multiple machines connected, wrong one executing

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.

Python CLI on Windows: "python3" not found

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
# PowerShell profile — adds python3 alias
New-Item -Type SymbolicLink -Path "$env:LOCALAPPDATA\Microsoft\WindowsApps\python3.exe" 

7. Per-language Quickstart

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.

7a. Python — data analysis

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.

powershell
# Windows
winget install Python.Python.3.12
python --version
# macOS
brew install python@3.12
# Ubuntu
sudo apt install python3 python3-venv

In 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.

7b. Julia — scientific computing

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.

powershell
winget install Julialang.Julia
julia --version

Try 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:

julia
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.

7c. Node.js — quick script experiments

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.

7d. Rust / Go / Java — compiled languages

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:

bash
# 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 verify

When 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.

Why BYOC matters

  • Privacy. Your datasets, API keys, and proprietary source code never leave the machine they already live on.
  • Speed. Local disk, local CPU, local RAM. No sandbox container cold starts, no cross-region network hops.
  • Cost. You pay once for the hardware you own, not per second for cloud compute that already exists on your desk.
  • Reproducibility. The exact toolchain versions, the exact data, the exact environment — identical between "I ran it in chat" and "I ran it in my terminal manually."

Need help? Check GitHub issues or reach out via the settings page.

© 2026 SynquoRum · BYOC Release

Agent CLI Documentation | SynquoRum | SynquoRum