ZSeven-W/zode(opens in a new tab)
Language: Rust
AI-native coding CLI for your terminal. Microkernel + plugin architecture, multi-provider, full-screen TUI.
- stars
- 24
- watchers
- 0
- forks
- 6
- open issues
- 0
- Last updated
- 09/26/2026
Language: Rust
AI-native coding CLI for your terminal. Microkernel + plugin architecture, multi-provider, full-screen TUI.
Open-source, AI-native coding assistant for your terminal.
Reads your code. Runs commands. Searches files. Manages git. All from a fast Rust TUI.
English | 简体中文 | 繁體中文 | 日本語 | 한국어 | Español | Français | Deutsch | Português | Русский | हिन्दी | Bahasa Indonesia | ไทย | Türkçe | Tiếng Việt
contextWindow / maxOutputTokens are configurable)MultiEdit), code & content search, foreground and background shells, git, web fetch (plus optional WebSearch with a Tavily key), notebooks, TODO trackingbrowser_* tools can drive a managed Chromium instance or your real Chrome profile through the zode Chrome bridge extension: navigate, click/type, inspect DOM, capture screenshots, read console/network logs, and group zode-opened tabs. Pairing is one-time — the extension reconnects automatically across zode restartsread-only or workspace-write mode, with outbound network denied by default. Toggle live with /sandbox; the model can request an escape for a single command (dangerouslyDisableSandbox) which you authorize at the prompt/language)<id>.jsonl transcript contract while adding journals, checkpoints, rewind, fork, and isolated Git worktrees as sidecar data; context compaction never loses the visible conversation — resumed sessions replay the full pre-compaction history while the model context stays compactCtrl+T), each an isolated agent; resume past sessions with full history replay/agents, /team, and /workflowsSKILL.md instruction packs on demand and connect MCP servers (mcp__<server>__<tool>); created agents, skills, and MCP tools surface as slash commands~/.zode/) → project root → cwd (AGENTS.md / CLAUDE.md)macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/ZSeven-W/zode/main/scripts/install.sh | shWindows (PowerShell):
irm https://raw.githubusercontent.com/ZSeven-W/zode/main/scripts/install.ps1 | iex
The installer auto-detects your OS + CPU, downloads the matching binary from
the latest release, and puts zode
on your PATH. Pin a version or change the location:
# macOS / Linux curl -fsSL https://raw.githubusercontent.com/ZSeven-W/zode/main/scripts/install.sh | sh -s -- --version v0.1.0-beta.1 ZODE_BIN_DIR="$HOME/.local/bin" curl -fsSL .../install.sh | sh
# Windows $env:ZODE_VERSION = 'v0.1.0-beta.1'; irm https://raw.githubusercontent.com/ZSeven-W/zode/main/scripts/install.ps1 | iex
Grab the archive for your platform from the releases page:
| OS | Arch | Asset |
|---|---|---|
| macOS | Apple Silicon | zode-<version>-arm64-mac.tar.gz |
| macOS | Intel | zode-<version>-x64-mac.tar.gz |
| Linux | x86_64 | zode-<version>-x64-linux.tar.gz |
| Linux | ARM64 | zode-<version>-arm64-linux.tar.gz |
| Windows | x64 | zode-<version>-x64-windows.zip |
| Windows | ARM64 | zode-<version>-arm64-windows.zip |
Then unpack and move zode onto your PATH (sudo mv zode /usr/local/bin/).
Linux builds are glibc; macOS binaries are unsigned (xattr -dr com.apple.quarantine ./zode if Gatekeeper complains).
Requires Rust 1.88 or newer:
git clone --recurse-submodules https://github.com/ZSeven-W/zode.git cd zode cargo build --release -p zode # binary at target/release/zode
The agent runtime lives in the
vendor/agentgit submodule — always clone with--recurse-submodules(or rungit submodule update --init).
The easiest way is to launch zode and run /connect — an interactive,
models.dev-backed picker that writes the config for you.
To write ~/.zode/config.json by hand: providers is the source of truth
— one entry per provider (shared credentials) holding one or more models —
and the top-level provider records the active model:
{
"providers": {
"anthropic": {
"type": "anthropic", // wire protocol: "anthropic" | "openai" | "ollama"
"apiKey": "sk-...",
"models": { "claude-sonnet-4-6": {} }
}
},
"provider": { "model": "claude-sonnet-4-6" } // the active model
}OpenAI-compatible providers (DeepSeek, Moonshot, OpenRouter, …) add a baseUrl
dialect, and per-model settings live in each model's entry:{
"providers": {
"deepseek": {
"type": "openai",
"apiKey": "sk-...",
"baseUrl": "https://api.deepseek.com/v1",
"dialect": "deepseek", // "standard" | "deepseek" | "moonshot" | "openrouter"
"models": {
"deepseek-v4-pro": { "contextWindow": 1000000, "maxOutputTokens": 16384 },
"deepseek-chat": {}
}
}
},
"provider": { "model": "deepseek-v4-pro" }
}One provider entry can hold several models — switch between them live with /model.
Then run:
zode # full-screen TUI zode -p "explain main.rs" # headless: one prompt, stream to stdout, exit zode --no-tui # plain readline REPL zode -c # continue the most recent session zode -r <id> # resume a session by id prefix zode --yolo # bypass approval prompts (deny rules still apply) zode --no-sandbox # disable the OS sandbox (it is ON by default) zode --sandbox-read-only # sandbox in read-only mode (deny all writes) zode --sandbox-allow-network # allow outbound network inside the sandbox zode --browser # force-enable built-in browser tools for this run zode --no-browser # disable built-in browser tools for this run zode --model <id> # override the model zode --provider <name> # pick a named provider from config.providers zode server # JSON-RPC app-server mode over stdio zode acp # Agent Client Protocol agent over stdio zode dashboard # local sessions/checkpoints/worktrees overview
You can also point at any provider without editing the config by exporting the
matching key (ANTHROPIC_API_KEY, OPENAI_API_KEY, …); for Ollama the
baseUrl is taken from the environment when unset.
Task execution mode is orthogonal to agent_type: any built-in or custom agent
type can use the registered child modes plan and read-only. Omitting mode
uses inherit; default is an alias for the same behavior.
{
"agent_type": "my-custom-agent",
"description": "Design the migration",
"prompt": "Inspect the current schema and return an implementation plan.",
"mode": "plan"
}inherit preserves the caller's capability ceiling. read-only narrows that
ceiling to read-only tools while completing the task normally; plan applies
the same read-only boundary and asks the child to return an implementation
plan. Neither can gain permissions, write access, or network access the caller
does not have, and neither changes the caller's mode. Capability-increasing
states such as bypass/yolo or sandbox-off are not child modes. External CLI Task
workers currently support only inherit (including omitted mode or
default); non-inherit modes are rejected.
Internal Task children also inherit every enabled Skill and every MCP tool in
the caller's final registered tool set. Their prompt contains the same Skill
index, and their rebuilt ToolSearch can discover the inherited Skill and
mcp__<server>__<tool> entries. Parent plugin/tool filters remain authoritative;
plan and read-only keep Skills but exclude MCP tools whose side effects are
unknown. External CLI workers do not inherit Zode's in-process tools.
Zode can use an installed third-party agent CLI as a one-shot Task worker or
as a persistent or stateless teammate. Registration is deliberately manual:
installing a CLI or putting it on PATH does not expose it to the model.
Add a profile under externalAgents.agents, then start Zode in the project.
Or run /external-agents to inspect supported CLIs currently on PATH, then
/external-agents discover to explicitly add every detected preset to the
global config. This command is user-triggered; startup never scans or registers
external CLIs automatically.
| Agent profile | Executable | Task worker | Team mode | External CLI sandbox |
|---|---|---|---|---|
claude-code |
claude |
yes | persistent | unrestricted (--dangerously-skip-permissions) |
codex |
codex |
yes | persistent | workspace-write |
opencode |
opencode |
yes | stateless | unknown |
cline |
cline |
yes | stateless | unrestricted |
antigravity |
agy |
yes | stateless | unknown |
cursor |
cursor-agent |
yes | persistent | unrestricted |
kiro |
kiro-cli |
yes | stateless | unrestricted |
pi |
pi |
yes | persistent | unrestricted |
grok (Grok Build) |
grok |
yes | persistent | unrestricted |
Every registered profile can join a team. Resumable profiles preserve the CLI's session ID and conversation across assignments; other CLIs are stateless teammates that start a fresh process for each assignment. The presets use the documented headless interfaces of Cline, Antigravity, Cursor, Kiro, Pi, and xAI's Grok Build. Other tools, including alternative Grok CLIs, can use a custom profile.
Put externalAgents in ~/.zode/config.json for all projects, or in
<project>/.zode/config.json for one project. An empty object explicitly
enables a known preset and resolves its executable on the sanitized PATH:
{
"externalAgents": {
"enabled": true,
"timeoutSecs": 1800,
"maxConcurrent": 2,
"agents": {
"claude-code": {},
"codex": {
"command": "codex",
"extraArgs": ["--model", "your-model-id"],
"envAllow": ["OPENAI_API_KEY"],
"trusted": false
},
"opencode": {},
"cline": {},
"antigravity": {},
"cursor": {},
"kiro": {},
"pi": {},
"grok": {}
}
}
}Add only the profiles you intend to expose. A bare command such as cline
is resolved on PATH; paths such as ./tools/my-agent or
/opt/agents/my-agent are also accepted. Known presets honor enabled,
command, extraArgs, envAllow, and trusted; extraArgs is appended to
Zode's preset invocation.
CLI processes start with a cleared environment containing only PATH, HOME,
and TERM (plus required Windows variables), so explicitly add API keys or
other required variables to envAllow. Existing login state under HOME
continues to work. A project entry with the same profile name replaces the
whole global entry, so repeat every override that the project still needs.
A custom profile declares the complete invocation and protocol:
{
"externalAgents": {
"agents": {
"my-agent": {
"command": "my-agent",
"args": ["run", "--json", "{prompt}"],
"promptTransport": "argv",
"output": "jsonl",
"textSource": "/event/delta",
"sessionIdSource": "/session/id",
"resumeArgs": ["--session", "{session_id}"],
"effectiveSandbox": "workspaceWrite",
"authEnv": ["MY_AGENT_API_KEY"],
"trusted": false
}
}
}
}promptTransport is stdin, argv, or file; argv requires a standalone
{prompt} argument and file requires {prompt_file}. output is text,
generic jsonl, jsonl-claude, or jsonl-codex. Generic JSONL profiles use
RFC 6901 textSource and sessionIdSource pointers to extract streamed text
and a resumable session ID from any event. resumeArgs must contain a
standalone {session_id} token and is appended on later turns; resumeFlag
is retained as the shorthand <flag> <session-id> form.
If a CLI accepts a caller-selected session ID, newSessionArgs can contain a
standalone {session_id} token. Zode generates a UUID, appends the expanded
arguments on the first run, and uses resumeArgs on later assignments. This
also makes a plain-text CLI resumable without parsing an ID from its output.
This lets any headless CLI become a Task worker or stateless teammate. To
preserve conversation context between team assignments, it must additionally
expose a session ID, or accept one through newSessionArgs, plus a
non-interactive resume invocation.
effectiveSandbox accepts none, readOnly, workspaceWrite,
unrestricted, or unknown and is displayed in the trust prompt.
Ask the leader in normal language; TeamHire and TeamSend are model-facing
tools, not slash commands:
Hire the `codex` external agent as a teammate named `implementer`.
Its role is to implement the authentication refactor and run the focused tests.
Send `implementer` the task now and claim `src/auth/` for it before editing.
Ask `implementer` to address the review findings while preserving its session context.
Naming rules. Teammate names (the name you give a hire) must be
lowercase ASCII: a-z, 0-9, and -, at most 32 characters — they appear in
@ask name: relay lines and session filenames, so non-ASCII (including
Chinese) names are rejected. External profile names (the keys under
externalAgents.agents, and what agent refers to in a hire) should also be
ASCII: /external-agents discover registers the fixed English preset names,
and non-ASCII custom profile keys are untested and unsupported.
The first hire shows the resolved executable and arguments, working directory,
and the CLI's effective sandbox. Approving it delegates work to that process in
the current project: Zode gates the process launch, but does not gate each
file edit or shell command performed by the external CLI. Trust grants last
for the current Zode session; the persistent roster is recovered from
<cwd>/.zode/team/, but an external teammate must be trusted again after a
restart or executable change.
In non-interactive/bypass runs (including --yolo), Zode cannot show the trust
prompt and fails closed. Set externalAgents.agents.<profile>.trusted to
true only when you deliberately want that profile to run without the prompt.
Use /team to inspect the roster and board after hiring:
/team # roster + board panel
/team status # text roster
/team board # shared goal, notes, assignments, and claims
/team dismiss implementer # remove the teammate
-p, --prompt-file, and --prompt-json all use the same headless engine.
json emits one final result object; stream-json emits one
zode.run-event.v1 JSON object per line. Structured modes reserve stdout for
machine-readable output and use stable exit codes: 0 success, 10 provider
error, 11 permission denied, 12 turn/limit reached, 13 interrupted
(Ctrl-C), 14 partial result, 15 session targeting error.
zode -p "fix the failing tests" --output-format json --max-turns 12 zode -p "review this repo" --output-format stream-json \ --tools 'File*,ContentSearch,Git' --disallowed-tools FileWrite zode --prompt-file prompt.txt --permission-mode accept-edits zode --prompt-json '{"prompt":"summarize the workspace"}' # Exact IDs do not prefix-match. A fork never mutates its source session. zode -p "continue the work" --session-id my-session zode -p "try another approach" --fork-session my-session --fork-worktree
Tool deny patterns win over allow patterns and are inherited by Task
sub-agents. --permission-mode accepts default, dont-ask, accept-edits,
and bypass; --yolo remains a shortcut for bypass, while hard deny rules
still apply.
The transcript remains the original V1 file at
~/.zode/sessions/<id>.jsonl. It is the only transcript copy, so older Zode
clients can keep reading and writing it. New metadata is additive and lives in
~/.zode/sessions/<id>/ (meta.json, journal, checkpoints, and snapshots).
No new session format or transcript migration is required.
zode session list zode session list --json zode session show <id> # metadata + checkpoint IDs zode session fork <id> --target-id experiment zode session fork <id> --checkpoint <cp> --worktree zode session rewind <id> <cp> # conflict-aware preview zode session rewind <id> <cp> --apply zode session apply-back <id> --target /path/to/checkout zode session delete <id> --remove-worktree
A checkpoint is captured before a mutating turn. Rewind restores tracked file content and the transcript prefix, reports conflicts instead of overwriting newer changes, and records a new logical journal branch rather than deleting history. Worktree forks can be applied back explicitly when the experiment is ready.
Compaction never loses the visible conversation. When context compaction
replaces old messages with a summary, the originals are preserved in an
additive sidecar (~/.zode/sessions/<id>/compacted.jsonl). Resuming a
session, pressing Ctrl+L, /export, and the Chrome side panel all display
the full pre-compaction history, while the model keeps receiving only the
compacted context. Forks carry the archive (filtered to their own transcript),
/clear removes it, and deleting a session removes the whole sidecar.
Rules can live under permissions.rules in config.json, or in a standalone
JSON file passed with --rules. A field matcher uses an RFC 6901 JSON pointer;
deny takes precedence over ask, which takes precedence over allow.
The standalone file must be either a rule array or { "rules": [...] }; it is
not wrapped in a top-level permissions object.
{
"permissions": {
"deny": ["Remove"],
"rules": [
{
"behavior": "allow",
"tool": "Bash",
"matcher": {
"kind": "field",
"pointer": "/command",
"pattern": { "kind": "glob", "value": "git status*" }
}
},
{
"behavior": "deny",
"tool": "Bash",
"matcher": {
"kind": "field",
"pointer": "/command",
"pattern": { "kind": "glob", "value": "*--force*" }
}
}
]
},
"sandbox": {
"profiles": {
"ci": {
"enabled": true,
"mode": "workspace-write",
"network": false,
"writableRoots": ["/tmp/build-cache"]
}
}
}
}zode -p "inspect only" --sandbox-profile read-only zode -p "run checks" --sandbox-profile workspace zode -p "download dependencies" --sandbox-profile workspace-network zode -p "run CI" --sandbox-profile ci --rules ./permissions.json
Built-in profiles are read-only, workspace, workspace-network, and
unconfined. Config-defined profiles use the same sandbox fields shown above.
A managed plugin can contribute skills, commands, agents, hooks, MCP servers,
LSP servers, and sandboxed JavaScript UI renderers. Zode accepts plugin.json, .zode-plugin/plugin.json,
.codex-plugin/plugin.json, .grok-plugin/plugin.json, and
.claude-plugin/plugin.json. Codex and Claude Code component path arrays are
supported, and Claude Code's defaultEnabled is honored on first install.
Host-only components such as Codex apps/connectors and Claude Code themes,
monitors, or output styles are ignored; an app-only plugin is rejected because
it has no Zode-compatible component. Installs are immutable snapshots with
provenance and a SHA-256 tree hash. Executable plugin content is never activated
without the explicit --trust flag.
The smallest UI plugin contains a manifest and one JavaScript file:
my-plugin/
├── plugin.json
└── scripts/
└── ui.js
plugin.json:
{
"name": "my-plugin",
"version": "0.1.0",
"ui": {
"sidebar": "./scripts/ui.js",
"statusLine": "./scripts/ui.js"
},
"permissions": {
"network": ["quota.example.com"],
"env": ["CODING_PLAN_TOKEN"],
"context": ["tabs", "workspace", "tools", "tasks", "services"]
}
}Install a local directory or a GitHub repository/subdirectory, then restart a running Zode process so it loads the new snapshot:
zode plugin validate ./my-plugin zode plugin install ./my-plugin --trust zode plugin install owner/repo@main#plugins/my-plugin --trust zode plugin list
Use zode plugin update my-plugin after changing the source. --trust is
required because JavaScript, hooks, MCP servers, and declared network access are
executable capabilities. Install and update print the plugin's declared
permission grant (network hosts, env vars, context scopes). An update whose
manifest requests broader permissions than the installed snapshot is refused
unless you rerun it with --trust — a moving Git source cannot silently widen
its own grant.
UI plugins can contribute declarative rows immediately above the sidebar version — at most six rows in total, shared across all plugins in load order. Declare a JavaScript entrypoint in the manifest:
{
"name": "my-sidebar",
"ui": {
"sidebar": "./ui/sidebar.js",
"statusLine": "./ui/status-line.js"
}
}Register a synchronous renderer with zode.ui.sidebar. The context is a
read-only JSON snapshot containing terminal, session, model, status, token, and
context-window fields. The result is rendered by Zode; scripts receive no
filesystem, network, terminal, or Ratatui bridge.
zode.ui.sidebar((ctx) => ({ lines: [ { spans: [ { text: ctx.model.id, tone: "accent", bold: true }, { text: ` ctx ${ctx.context.usedPercent ?? "?"}%`, tone: "muted" } ] } ] }));
Supported tones are default, muted, accent, success, warning, and
danger; spans also accept bold and italic. A renderer must be synchronous.
Each script is limited to 256 KiB, 8 MiB of JS memory, and 25 ms per evaluation,
and renderers are re-evaluated at most every 250 ms (cached output is reused
between evaluations). Sidebar output is limited to 6 lines per renderer (6 in
total across plugins), each line to 16 spans and 2,048 bytes of text. Control
characters are sanitized by the host.
The status bar is also extensible. It remains one row when no plugin returns
content and grows to two rows dynamically when a synchronous
zode.ui.statusLine renderer returns spans. Zode keeps its core status and
safety indicators on the first row; plugin output is composed on the second.
zode.ui.statusLine((ctx) => ({ spans: [ { text: ctx.session.title, tone: "accent", bold: true }, { text: ` ↑${ctx.tokens.input} ↓${ctx.tokens.output}`, tone: "muted" } ] }));
Every renderer receives the following base fields without requesting additional context permission:
| Field | Shape and meaning |
|---|---|
ctx.apiVersion |
Context API version; currently 1. |
ctx.app |
{ version, effort }. |
ctx.terminal |
{ width, height } in terminal cells. |
ctx.session |
{ id, title, cwd, busy } for the active task. |
ctx.model |
{ id, provider }. |
ctx.status |
{ mode, planMode, selectionMode, yolo, sandbox }; sandbox contains { enabled, readOnly, network }. |
ctx.tokens |
{ input, output } token counters. |
ctx.context |
{ used, window, usedPercent }; the percentage can be null. |
ctx.data |
Results belonging only to data sources registered by this plugin. |
Richer sections are omitted unless the plugin requests the matching scope in
permissions.context:
| Scope | Exposed field | Shape and limits |
|---|---|---|
tabs |
ctx.tabs |
{ active, count }; active is one-based. |
workspace |
ctx.workspace.modifiedFiles |
Up to 50 { path, added, removed } Git entries. |
tools |
ctx.tools.available |
Sorted names of tools enabled for the active task. |
tools |
ctx.tools.active |
Names of tools currently executing. |
tools |
ctx.tools.recent |
Up to 20 { name, status, durationMs } records. |
tasks |
ctx.tasks.todoStatuses |
Todo status strings only, without todo text. |
tasks |
ctx.tasks.subagents |
{ type, status } records, without prompts or transcripts. |
tasks |
ctx.tasks.goal |
{ active, turn }, without goal text. |
services |
ctx.services.mcp |
{ name, connected } records. |
services |
ctx.services.lsp |
{ language, running } records. |
For example:
{
"permissions": {
"context": ["tabs", "workspace", "tools", "tasks", "services"]
}
}ctx.tools is an observation API: it tells a renderer which tools exist and
which tools are or were running. UI plugins cannot invoke a tool. Tool inputs,
tool outputs, prompts, transcript content, todo/goal text, environment values,
and credentials are not included, and the API cannot bypass Zode's approval
system.
UI plugins can also register background HTTP data sources. Network and secret access must be declared in the manifest:
{
"permissions": {
"network": ["quota.example.com"],
"env": ["CODING_PLAN_TOKEN"]
}
}The request is declarative and runs outside the render path. Secret environment variables are assembled into headers by Zode and are never exposed to JavaScript:
zode.data.define("codingPlan", { refreshIntervalMs: 60000, request: { url: "https://quota.example.com/v1/usage", method: "GET", timeoutMs: 3000, headers: { Authorization: { env: "CODING_PLAN_TOKEN", prefix: "Bearer " } } } }); zode.ui.statusLine((ctx) => ({ spans: [ { text: `remaining ${ctx.data.codingPlan?.data?.remaining ?? "…"}`, tone: "accent" } ] }));
zode.data.define(key, config) accepts a 1–64 character alphanumeric,
underscore, or hyphen key. request supports url, method, headers,
optional JSON body, and timeoutMs. Defaults are GET, 3-second timeout,
and a 60-second refresh. Only HTTPS GET and POST are accepted. Literal
headers are strings; a secret header uses
{ "env": "NAME", "prefix": "Bearer " }. The environment variable must also
appear in permissions.env, is read only by Rust when building the request,
and is never returned to JavaScript.
request.headers can also be a function for dynamic authentication
(e.g. HMAC-SHA256 signing). Zode calls it before each request with a context
object (method, url, body, timestamp, secrets) and uses the returned
header key-value pairs. The zode.crypto global (sha256hex,
hmacSha256Hex, hmacSha256HexKey) provides crypto primitives so any signing
algorithm can be implemented in pure JS — including Volcano Engine HMAC-SHA256
and AWS SigV4 derived-key chains.
Zode disables redirects and proxies, validates and pins public DNS addresses,
rejects localhost/private networks, caps responses at 256 KiB, clamps request
timeouts to 500 ms–10 seconds, and clamps refresh intervals to
10 seconds–1 hour. A wildcard such as *.example.com matches subdomains but
not the bare example.com host.
Each plugin sees only its own data. ctx.data.<key> contains
{ ok, status, data, updatedAt } or
{ ok: false, error, updatedAt }. JSON responses become objects/arrays;
non-JSON responses become strings. An HTTP error status still includes
status and data, with ok: false.
Start Zode with the required secret in its environment when using a private quota or coding-plan API:
CODING_PLAN_TOKEN=... zode
The complete runnable example displays
model/context/tool activity in the sidebar and status line and uses
zode.data.define for a public GitHub API quota.
zode plugin list --json zode plugin details my-plugin zode plugin disable my-plugin zode plugin enable my-plugin zode plugin update my-plugin zode plugin uninstall my-plugin # A marketplace is a local/Git static index, not a Zode-hosted service. zode plugin marketplace add owner/plugin-index --trust zode plugin marketplace list --json zode plugin install my-plugin@MARKETPLACE_NAME --trust # disambiguate if needed zode plugin marketplace update
zode acp implements ACP initialize/new/load/fork/prompt/cancel over stdio,
streams message/thought/tool updates, requests permissions through the client,
and accepts client-supplied stdio, HTTP, and SSE MCP servers. Session data uses
the same V1-compatible store as the TUI and headless CLI.
zode acp zode dashboard zode dashboard --json
OTLP export is off by default and requires an explicit opt-in. It exports only content-free lifecycle/tool-name/status/usage attributes: prompts, generated text, tool inputs/outputs, file paths, and error messages are never sent.
ZODE_OTEL=1 \
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318 \
zode -p "run the test suite" --output-format jsonFor real-terminal TUI regression scenarios, the workspace includes a PTY + VT100 harness that records raw diagnostics and virtual-screen snapshots:
cargo test -p zode-pty-harness
cargo run -p zode-pty-harness --bin zode-pty-scenario -- scenario.jsonscenario.json drives the real terminal with ordered waits, key input,
resizes, and snapshots (key notation supports <Enter>, <Esc>, <Tab
| | |
| | |
| | |
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
| |
| |
| |
|
| ||||