Local CLI runtime for agents and operators, powered by V.
vshx turns local CLI tools into structured execution capabilities for humans and agents.
The current product direction is:
- run local CLI commands through a controlled runtime
- capture execution as typed events
- render output as
markdownorndjson - support optional streaming output for both formats
- expose the same capabilities through CLI, task runtime, and stdio MCP
In the broader stack:
vphpis the PHP/V bridge runtimevhttpdis the online transport/runtimevshxis the local CLI/tool runtime
cd vshx
v run ./cmd/vshx --helpBuild a local binary:
cd vshx
v run build.v
./bin/vshx --helpOr with make:
cd vshx
make build
make run
make mcp-inspect
make smokeRender a one-shot command as Markdown:
v run ./cmd/vshx run --format markdown -- echo helloUse the markdown-first Git entrypoint:
v run ./cmd/vshx git status --cwd ..
v run ./cmd/vshx git diff --cwd ..
v run ./cmd/vshx git log --cwd .. --limit 5
v run ./cmd/vshx git show --cwd .. --revision HEADInclude raw Git output when you want the structured summary and the original transcript together:
v run ./cmd/vshx git status --cwd .. --transcriptHuman + agent examples for git.readonly:
# human: compact working tree summary
v run ./cmd/vshx git status --cwd ..
# agent: stable per-file status entries
v run ./cmd/vshx git status --cwd .. --format json
# read structured_output.status_entries_json
# human: compact file-level diff summary
v run ./cmd/vshx git diff --cwd ..
# agent: stable diff entries without patch bodies
v run ./cmd/vshx git diff --cwd .. --format json
# read structured_output.diff_entries_jsonUse the markdown-first ripgrep entrypoint:
v run ./cmd/vshx rg shell.exec --cwd vshx/core/runtime
v run ./cmd/vshx rg policy --cwd . --path vshx/core --limit 20Human + agent examples for rg.search:
# human: grouped markdown search view
v run ./cmd/vshx rg shell.exec --cwd vshx/core/runtime
# agent: flattened search summary + match events
v run ./cmd/vshx rg shell.exec --cwd vshx/core/runtime --format json
# read structured_output.match_count, matched_files, matchesStream typed execution events as NDJSON:
v run ./cmd/vshx run --format ndjson --stream -- git status --shortStream a command as Markdown in a terminal-style view:
v run ./cmd/vshx run --format markdown --stream -- tail -f app.logOverride the default risk policy for an intentional high-risk command shape:
v run ./cmd/vshx run --format markdown --allow-risky -- sh -lc 'echo hello'Inspect the tool registry:
v run ./cmd/vshx tool list
v run ./cmd/vshx tool describe git.readonly
v run ./cmd/vshx tool describe rg.search
v run ./cmd/vshx tool describe shell.exec
v run ./cmd/vshx tool call rg.search --query shell.exec --cwd vshx/core/runtime
v run ./cmd/vshx tool call git.readonly --op status --cwd ..
v run ./cmd/vshx tool call shell.exec -- echo helloAgent-native examples for tool call:
# call a tool directly and get the full TaskResult JSON
v run ./cmd/vshx tool call git.readonly --op diff --cwd ..
# call search directly and consume structured_output / events
v run ./cmd/vshx tool call rg.search --query shell.exec --cwd vshx/core/runtime
# call shell.exec directly when you want generic local execution
v run ./cmd/vshx tool call shell.exec -- echo helloPersist a command execution as a task record:
v run ./cmd/vshx task run shell.exec -- echo helloOperator examples for task run:
# persist a generic command execution
v run ./cmd/vshx task run shell.exec -- echo hello
# persist a structured git inspection
v run ./cmd/vshx task run git.readonly --op status --cwd ..
# inspect the saved record later
v run ./cmd/vshx task show <task_id>
v run ./cmd/vshx task logs <task_id>Inspect MCP bridge shape:
v run ./cmd/vshx mcp inspect
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","clientInfo":{"name":"demo","version":"0.1.0"},"capabilities":{}}}' | v run ./cmd/vshx mcp serveUse mcp when you want a stdio host for MCP clients, not when you just want to call tools locally.
cmd/vshx/CLI entrypointscore/runtime/tool registry, shell execution, renderers, task storecore/mcp/stdio MCP servercore/config/shared argument helpersmodules/legacy skeleton modules kept for nowdocs/product direction and runtime notes.vshx/local task artifacts (gitignored)
Key design doc:
docs/AI_NATIVE_PLAN.mddocs/RUNTIME_CONTRACT.mddocs/TOOL_CATALOG.md
Current MVP is focused on the local CLI runtime path:
run --format markdown|ndjsonrun --stream- default risk policy with
--allow-riskyoverride tool list|describe|calltask run|show|logs- file-backed task records under
.vshx/tasks/ mcp inspect|serve
Current built-in tools:
rg.searchfor ripgrep-backed code and text searchgit.readonlyfor constrained read-only Git operationsshell.execfor local command executiondata.aggas a simple built-in example tool
Current git.readonly behavior:
- supports
status,diff,log, andshow - keeps Git access on explicit read-only subcommands
- enriches output with Git-specific fields such as branch state, change counts, commit ids, and entry counts
- renders a markdown-first summary view for the human
vshx git ...entrypoint - keeps raw Git transcript optional in the human CLI through
--transcript - exposes grouped status paths such as
staged_paths,unstaged_paths,untracked_paths, anddeleted_paths - exposes compact status summaries for agents through
status_entriesandstatus_entries_json - exposes diff summaries without patch bodies, including
file_count,insertions,deletions,changed_paths,created_paths,deleted_paths,renamed_paths,diff_entries, anddiff_entries_json - exposes show metadata such as
author,date,subject, and stat-derivedchanged_paths - exposes compact log entry summaries through
entries,entry_commits, andentry_subjects - works through CLI, task runtime, and MCP with the same schema
Preferred git.readonly machine fields:
status_entries_jsonforgit statusdiff_entries_jsonforgit diffentriesforgit logchanged_pathsplus commit metadata forgit show
Current rg.search behavior:
- provides a ripgrep-backed search tool with a narrower contract than raw shell usage
- supports
query,cwd,path,glob,case,limit, andword - renders a markdown-first grouped match view for the human
vshx rg ...entrypoint - emits
matchevents in NDJSON and exposes a flattenedresultevent beforefinal - normalizes ripgrep no-match exits into a successful zero-match tool result
- exposes summary fields such as
match_count,displayed_match_count,file_count,matched_files,matches, andtruncated
Preferred rg.search machine fields:
match_countfile_countmatched_filesmatchestruncated
Current output rendering behavior:
- Markdown favors a human-readable summary first, then grouped sections or terminal-style output
vshx git ...hides raw Git transcript by default and exposes it with--transcript- NDJSON emits typed events and includes a flattened
resultevent before the terminalfinalsummary
Current contract docs:
docs/AI_NATIVE_PLAN.mdexplains the product directiondocs/RUNTIME_CONTRACT.mddefines the current MVP event, result, and tool field contractdocs/TOOL_CATALOG.mddescribes the current built-in tool surface and intended usage
Current shell policy behavior:
- allows read-oriented commands such as
git status - blocks obviously risky command shapes such as
sh -lc ...by default - records policy decision and effective risk level in task output
- lets operators override with
--allow-risky
Current mcp serve behavior:
- reuses the same runtime contract as CLI and task execution
- tracks
initializeandnotifications/initialized - rejects tool methods until the session is ready
- exposes the registry through
tools/list - runs registry-backed tools through
tools/call - exposes placeholder
resources/listandprompts/listsurfaces
Build helper:
build.vcompiles./cmd/vshxtobin/vshxv run build.v releasebuilds with-prodv run build.v cleanremoves the built binarymake build|debug|release|run|cleanwraps the same workflowmake mcp-inspect|tool-list|tool-describe|task-demo|smokegives quick dev/demo entrypoints