mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-24 05:14:44 +00:00
test(cli): help-text snapshots for every CLI command (#28267)
This commit is contained in:
@@ -0,0 +1,623 @@
|
||||
// Bun Snapshot v1, https://bun.sh/docs/test/snapshots
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode acp --help 1`] = `
|
||||
"opencode acp
|
||||
|
||||
start ACP (Agent Client Protocol) server
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--port port to listen on [number] [default: 0]
|
||||
--hostname hostname to listen on [string] [default: "127.0.0.1"]
|
||||
--mdns enable mDNS service discovery (defaults hostname to 0.0.0.0)
|
||||
[boolean] [default: false]
|
||||
--mdns-domain custom domain name for mDNS service (default: opencode.local)
|
||||
[string] [default: "opencode.local"]
|
||||
--cors additional domains to allow for CORS [array] [default: []]
|
||||
--cwd working directory [string] [default: "<HOME>"]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode mcp --help 1`] = `
|
||||
"opencode mcp
|
||||
|
||||
manage MCP (Model Context Protocol) servers
|
||||
|
||||
Commands:
|
||||
opencode mcp add add an MCP server
|
||||
opencode mcp list list MCP servers and their status [aliases: ls]
|
||||
opencode mcp auth [name] authenticate with an OAuth-enabled MCP server
|
||||
opencode mcp logout [name] remove OAuth credentials for an MCP server
|
||||
opencode mcp debug <name> debug OAuth connection for an MCP server
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode attach --help 1`] = `
|
||||
"opencode attach <url>
|
||||
|
||||
attach to a running opencode server
|
||||
|
||||
Positionals:
|
||||
url http://localhost:4096 [string] [required]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--dir directory to run in [string]
|
||||
-c, --continue continue the last session [boolean]
|
||||
-s, --session session id to continue [string]
|
||||
--fork fork the session when continuing (use with --continue or --session) [boolean]
|
||||
-p, --password basic auth password (defaults to OPENCODE_SERVER_PASSWORD) [string]
|
||||
-u, --username basic auth username (defaults to OPENCODE_SERVER_USERNAME or 'opencode')[string]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode run --help 1`] = `
|
||||
"opencode run [message..]
|
||||
|
||||
run opencode with a message
|
||||
|
||||
Positionals:
|
||||
message message to send [array] [default: []]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--command the command to run, use message for args [string]
|
||||
-c, --continue continue the last session [boolean]
|
||||
-s, --session session id to continue [string]
|
||||
--fork fork the session before continuing (requires --continue or
|
||||
--session) [boolean]
|
||||
--share share the session [boolean]
|
||||
-m, --model model to use in the format of provider/model [string]
|
||||
--agent agent to use [string]
|
||||
--format format: default (formatted) or json (raw JSON events)
|
||||
[string] [choices: "default", "json"] [default: "default"]
|
||||
-f, --file file(s) to attach to message [array]
|
||||
--title title for the session (uses truncated prompt if no value
|
||||
provided) [string]
|
||||
--attach attach to a running opencode server (e.g.,
|
||||
http://localhost:4096) [string]
|
||||
-p, --password basic auth password (defaults to OPENCODE_SERVER_PASSWORD)
|
||||
[string]
|
||||
-u, --username basic auth username (defaults to OPENCODE_SERVER_USERNAME or
|
||||
'opencode') [string]
|
||||
--dir directory to run in, path on remote server if attaching
|
||||
[string]
|
||||
--port port for the local server (defaults to random port if no value
|
||||
provided) [number]
|
||||
--variant model variant (provider-specific reasoning effort, e.g., high,
|
||||
max, minimal) [string]
|
||||
--thinking show thinking blocks [boolean]
|
||||
--replay replay visible session history on interactive resume
|
||||
[boolean] [default: false]
|
||||
--replay-limit cap visible interactive replay to the newest N messages
|
||||
[number]
|
||||
-i, --interactive run in direct interactive split-footer mode
|
||||
[boolean] [default: false]
|
||||
--dangerously-skip-permissions auto-approve permissions that are not explicitly denied
|
||||
(dangerous!) [boolean] [default: false]
|
||||
--demo enable direct interactive demo slash commands; pass one as the
|
||||
message to run it immediately [boolean] [default: false]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode debug --help 1`] = `
|
||||
"opencode debug
|
||||
|
||||
debugging and troubleshooting tools
|
||||
|
||||
Commands:
|
||||
opencode debug config show resolved configuration
|
||||
opencode debug lsp LSP debugging utilities
|
||||
opencode debug rg ripgrep debugging utilities
|
||||
opencode debug file file system debugging utilities
|
||||
opencode debug scrap list all known projects
|
||||
opencode debug skill list all available skills
|
||||
opencode debug snapshot snapshot debugging utilities
|
||||
opencode debug startup print startup timing
|
||||
opencode debug agent <name> show agent configuration details
|
||||
opencode debug v2 debug v2 catalog and built-in plugins
|
||||
opencode debug info show debug information
|
||||
opencode debug paths show global paths (data, config, cache, state)
|
||||
opencode debug wait wait indefinitely (for debugging)
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode providers --help 1`] = `
|
||||
"opencode providers
|
||||
|
||||
manage AI providers and credentials
|
||||
|
||||
Commands:
|
||||
opencode providers list list providers and credentials [aliases: ls]
|
||||
opencode providers login [url] log in to a provider
|
||||
opencode providers logout log out from a configured provider
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode agent --help 1`] = `
|
||||
"opencode agent
|
||||
|
||||
manage agents
|
||||
|
||||
Commands:
|
||||
opencode agent create create a new agent
|
||||
opencode agent list list all available agents
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode upgrade --help 1`] = `
|
||||
"opencode upgrade [target]
|
||||
|
||||
upgrade opencode to the latest or a specific version
|
||||
|
||||
Positionals:
|
||||
target version to upgrade to, for ex '0.1.48' or 'v0.1.48' [string]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
-m, --method installation method to use
|
||||
[string] [choices: "curl", "npm", "pnpm", "bun", "brew", "choco", "scoop"]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode uninstall --help 1`] = `
|
||||
"opencode uninstall
|
||||
|
||||
uninstall opencode and remove all related files
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
-c, --keep-config keep configuration files [boolean] [default: false]
|
||||
-d, --keep-data keep session data and snapshots [boolean] [default: false]
|
||||
--dry-run show what would be removed without removing [boolean] [default: false]
|
||||
-f, --force skip confirmation prompts [boolean] [default: false]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode serve --help 1`] = `
|
||||
"opencode serve
|
||||
|
||||
starts a headless opencode server
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--port port to listen on [number] [default: 0]
|
||||
--hostname hostname to listen on [string] [default: "127.0.0.1"]
|
||||
--mdns enable mDNS service discovery (defaults hostname to 0.0.0.0)
|
||||
[boolean] [default: false]
|
||||
--mdns-domain custom domain name for mDNS service (default: opencode.local)
|
||||
[string] [default: "opencode.local"]
|
||||
--cors additional domains to allow for CORS [array] [default: []]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode web --help 1`] = `
|
||||
"opencode web
|
||||
|
||||
start opencode server and open web interface
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--port port to listen on [number] [default: 0]
|
||||
--hostname hostname to listen on [string] [default: "127.0.0.1"]
|
||||
--mdns enable mDNS service discovery (defaults hostname to 0.0.0.0)
|
||||
[boolean] [default: false]
|
||||
--mdns-domain custom domain name for mDNS service (default: opencode.local)
|
||||
[string] [default: "opencode.local"]
|
||||
--cors additional domains to allow for CORS [array] [default: []]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode models --help 1`] = `
|
||||
"opencode models [provider]
|
||||
|
||||
list all available models
|
||||
|
||||
Positionals:
|
||||
provider provider ID to filter models by [string]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--verbose use more verbose model output (includes metadata like costs) [boolean]
|
||||
--refresh refresh the models cache from models.dev [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode stats --help 1`] = `
|
||||
"opencode stats
|
||||
|
||||
show token usage and cost statistics
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--days show stats for the last N days (default: all time) [number]
|
||||
--tools number of tools to show (default: all) [number]
|
||||
--models show model statistics (default: hidden). Pass a number to show top N, otherwise
|
||||
shows all
|
||||
--project filter by project (default: all projects, empty string: current project)[string]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode export --help 1`] = `
|
||||
"opencode export [sessionID]
|
||||
|
||||
export session data as JSON
|
||||
|
||||
Positionals:
|
||||
sessionID session id to export [string]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--sanitize redact sensitive transcript and file data [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode import --help 1`] = `
|
||||
"opencode import <file>
|
||||
|
||||
import session data from JSON file or URL
|
||||
|
||||
Positionals:
|
||||
file path to JSON file or share URL [string] [required]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode github --help 1`] = `
|
||||
"opencode github
|
||||
|
||||
manage GitHub agent
|
||||
|
||||
Commands:
|
||||
opencode github install install the GitHub agent
|
||||
opencode github run run the GitHub agent
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode pr --help 1`] = `
|
||||
"opencode pr <number>
|
||||
|
||||
fetch and checkout a GitHub PR branch, then run opencode
|
||||
|
||||
Positionals:
|
||||
number PR number to checkout [number] [required]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode session --help 1`] = `
|
||||
"opencode session
|
||||
|
||||
manage sessions
|
||||
|
||||
Commands:
|
||||
opencode session list list sessions
|
||||
opencode session delete <sessionID> delete a session
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode plugin --help 1`] = `
|
||||
"opencode plugin <module>
|
||||
|
||||
install plugin and update config
|
||||
|
||||
Positionals:
|
||||
module npm module name [string] [required]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
-g, --global install in global config [boolean] [default: false]
|
||||
-f, --force replace existing plugin version [boolean] [default: false]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode db --help 1`] = `
|
||||
"opencode db
|
||||
|
||||
database tools
|
||||
|
||||
Commands:
|
||||
opencode db [query] open an interactive sqlite3 shell or run a query [default]
|
||||
opencode db path print the database path
|
||||
opencode db migrate migrate JSON data to SQLite (merges with existing data)
|
||||
|
||||
Positionals:
|
||||
query SQL query to execute [string]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--format Output format [string] [choices: "json", "tsv"] [default: "tsv"]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode mcp list --help 1`] = `
|
||||
"opencode mcp list
|
||||
|
||||
list MCP servers and their status
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode mcp add --help 1`] = `
|
||||
"opencode mcp add
|
||||
|
||||
add an MCP server
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode mcp auth --help 1`] = `
|
||||
"opencode mcp auth [name]
|
||||
|
||||
authenticate with an OAuth-enabled MCP server
|
||||
|
||||
Commands:
|
||||
opencode mcp auth list list OAuth-capable MCP servers and their auth status [aliases: ls]
|
||||
|
||||
Positionals:
|
||||
name name of the MCP server [string]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode mcp logout --help 1`] = `
|
||||
"opencode mcp logout [name]
|
||||
|
||||
remove OAuth credentials for an MCP server
|
||||
|
||||
Positionals:
|
||||
name name of the MCP server [string]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode providers list --help 1`] = `
|
||||
"opencode providers list
|
||||
|
||||
list providers and credentials
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode providers login --help 1`] = `
|
||||
"opencode providers login [url]
|
||||
|
||||
log in to a provider
|
||||
|
||||
Positionals:
|
||||
url opencode auth provider [string]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
-p, --provider provider id or name to log in to (skips provider selection) [string]
|
||||
-m, --method login method label (skips method selection) [string]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode providers logout --help 1`] = `
|
||||
"opencode providers logout
|
||||
|
||||
log out from a configured provider
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode agent create --help 1`] = `
|
||||
"opencode agent create
|
||||
|
||||
create a new agent
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--path directory path to generate the agent file [string]
|
||||
--description what the agent should do [string]
|
||||
--mode agent mode [string] [choices: "all", "primary", "subagent"]
|
||||
--permissions, --tools comma-separated list of permissions to allow (default: all).
|
||||
Available: "bash, read, edit, glob, grep, webfetch, task, todowrite,
|
||||
websearch, lsp, skill" [string]
|
||||
-m, --model model to use in the format of provider/model [string]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode agent list --help 1`] = `
|
||||
"opencode agent list
|
||||
|
||||
list all available agents
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode session list --help 1`] = `
|
||||
"opencode session list
|
||||
|
||||
list sessions
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
-n, --max-count limit to N most recent sessions [number]
|
||||
--format output format [string] [choices: "table", "json"] [default: "table"]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode session delete --help 1`] = `
|
||||
"opencode session delete <sessionID>
|
||||
|
||||
delete a session
|
||||
|
||||
Positionals:
|
||||
sessionID session ID to delete [string] [required]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode github install --help 1`] = `
|
||||
"opencode github install
|
||||
|
||||
install the GitHub agent
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode github run --help 1`] = `
|
||||
"opencode github run
|
||||
|
||||
run the GitHub agent
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--event GitHub mock event to run the agent for [string]
|
||||
--token GitHub personal access token (github_pat_********) [string]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode db path --help 1`] = `
|
||||
"opencode db path
|
||||
|
||||
print the database path
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]"
|
||||
`;
|
||||
139
packages/opencode/test/cli/help/help-snapshots.test.ts
Normal file
139
packages/opencode/test/cli/help/help-snapshots.test.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
// Help-text snapshots for every CLI command + key subcommand. Catches
|
||||
// accidental flag removals, renames, and reordering in a single sweep —
|
||||
// any change to the user-visible CLI surface shows up here as a diff.
|
||||
//
|
||||
// This is the broad coverage layer that makes the future Effect CLI
|
||||
// migration (yargs → effect-smol/cli) safe to attempt: if a refactor
|
||||
// preserves the surface, the snapshots stay green; if it doesn't, the
|
||||
// diff tells you exactly which command(s) changed.
|
||||
//
|
||||
// Snapshots are taken at COLUMNS=120 so wrapping is stable across
|
||||
// terminal sizes. The default opencode tui command is excluded —
|
||||
// `opencode --help` includes an ASCII banner that pulls in the install
|
||||
// version (changes per release), so we'd snapshot a moving target.
|
||||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import fs from "node:fs"
|
||||
import os from "node:os"
|
||||
import { cliIt } from "../../lib/cli-process"
|
||||
|
||||
// Strips dynamic content that varies per run so snapshots are stable.
|
||||
// Currently only the tmpdir prefix bleeds in (via `--cwd` defaults that
|
||||
// resolve to `process.cwd()`). Add new patterns here as they surface.
|
||||
//
|
||||
// On macOS `os.tmpdir()` returns `/var/folders/...` but `process.cwd()`
|
||||
// inside the child returns the realpath `/private/var/folders/...` — so
|
||||
// we strip both forms.
|
||||
const TMP = os.tmpdir()
|
||||
const REAL_TMP = fs.realpathSync(TMP)
|
||||
function normalize(text: string): string {
|
||||
return (
|
||||
text
|
||||
// Windows emits CRLF on stderr; collapse first so the rest of the
|
||||
// pipeline doesn't need separate Windows-vs-POSIX branches.
|
||||
.replaceAll("\r\n", "\n")
|
||||
.replaceAll(REAL_TMP, "<TMPDIR>")
|
||||
.replaceAll(TMP, "<TMPDIR>")
|
||||
// The harness writes the random home dir at `<TMPDIR>/oc-cli-XXX` on
|
||||
// POSIX, `<TMPDIR>\oc-cli-XXX` on Windows. Strip either form.
|
||||
.replace(/<TMPDIR>[/\\]oc-cli-[a-z0-9]+/g, "<HOME>")
|
||||
// yargs wraps the `[string] [default: "..."]` clause based on the
|
||||
// pre-normalized default's character length, so different random home
|
||||
// path widths produce different leading-whitespace counts (or even
|
||||
// line-wraps onto a fresh line on Windows). `\s+` matches both forms.
|
||||
.replace(/\s+\[string\] \[default: "<HOME>"\]/g, ' [string] [default: "<HOME>"]')
|
||||
)
|
||||
}
|
||||
|
||||
// Top-level commands. Order matches what `opencode --help` prints today;
|
||||
// keep it in that order so the snapshot file reads as a table of contents.
|
||||
// `completion` is intentionally excluded — it's a yargs built-in that emits
|
||||
// top-level help on `--help` and exits 1; not a real opencode command.
|
||||
const TOP_LEVEL = [
|
||||
"acp",
|
||||
"mcp",
|
||||
"attach",
|
||||
"run",
|
||||
"debug",
|
||||
"providers", // aliased to `auth`
|
||||
"agent",
|
||||
"upgrade",
|
||||
"uninstall",
|
||||
"serve",
|
||||
"web",
|
||||
"models",
|
||||
"stats",
|
||||
"export",
|
||||
"import",
|
||||
"github",
|
||||
"pr",
|
||||
"session",
|
||||
"plugin",
|
||||
"db",
|
||||
] as const
|
||||
|
||||
// Subcommands worth pinning. Not exhaustive — the goal is one snapshot per
|
||||
// distinct argv shape, not every leaf. Add new entries when a subcommand
|
||||
// gains user-visible flags that we want to lock in.
|
||||
const SUBCOMMANDS = [
|
||||
["mcp", "list"],
|
||||
["mcp", "add"],
|
||||
["mcp", "auth"],
|
||||
["mcp", "logout"],
|
||||
["providers", "list"],
|
||||
["providers", "login"],
|
||||
["providers", "logout"],
|
||||
["agent", "create"],
|
||||
["agent", "list"],
|
||||
["session", "list"],
|
||||
["session", "delete"],
|
||||
["github", "install"],
|
||||
["github", "run"],
|
||||
["db", "path"],
|
||||
] as const
|
||||
|
||||
// Fixed wrap width so a developer's terminal doesn't affect snapshots.
|
||||
// yargs honors COLUMNS; CI runners typically default to 80 which produces
|
||||
// different wraps from a 200-col local terminal.
|
||||
const SNAPSHOT_ENV = { COLUMNS: "120" }
|
||||
|
||||
describe("opencode CLI help-text snapshots", () => {
|
||||
// Single test, parallel spawns. Each command's help fires under
|
||||
// `concurrency: 8` — wall-clock stays under ~10s even for ~35 commands,
|
||||
// versus ~1 minute if we serialized.
|
||||
cliIt.live(
|
||||
"every documented command emits stable help text",
|
||||
({ opencode }) =>
|
||||
Effect.gen(function* () {
|
||||
const argvs: Array<readonly string[]> = [...TOP_LEVEL.map((c) => [c] as const), ...SUBCOMMANDS]
|
||||
|
||||
// Spawn in parallel, then assert in argv order so snapshot output is
|
||||
// deterministic and per-command failures don't abort the rest of
|
||||
// the sweep. `Effect.partition` is the canonical "run all, separate
|
||||
// failures from successes" primitive — no mutable accumulator needed.
|
||||
const [failures, results] = yield* Effect.partition(
|
||||
argvs,
|
||||
(argv) =>
|
||||
Effect.gen(function* () {
|
||||
const result = yield* opencode.spawn([...argv, "--help"], { env: SNAPSHOT_ENV })
|
||||
if (result.exitCode !== 0) {
|
||||
return yield* Effect.fail(`opencode ${argv.join(" ")}: exit ${result.exitCode}`)
|
||||
}
|
||||
return { argv, result }
|
||||
}),
|
||||
{ concurrency: 8 },
|
||||
)
|
||||
|
||||
for (const { argv, result } of results) {
|
||||
// yargs writes --help to stderr, not stdout. Snapshotting stderr
|
||||
// means our test catches the help body; stdout for these commands
|
||||
// is expected to be empty.
|
||||
expect(normalize(result.stderr)).toMatchSnapshot(`opencode ${argv.join(" ")} --help`)
|
||||
}
|
||||
if (failures.length > 0) {
|
||||
throw new Error(`Help text failed for:\n ${failures.join("\n ")}`)
|
||||
}
|
||||
}),
|
||||
180_000,
|
||||
)
|
||||
})
|
||||
@@ -33,6 +33,30 @@ const cliEntry = path.join(opencodeRoot, "src/index.ts")
|
||||
|
||||
export const testModelID = "test/test-model"
|
||||
|
||||
// Wrap a Bun subprocess pipe (or any ReadableStream<Uint8Array>) as a Stream.
|
||||
// Centralizes the `evaluate` + `onError` boilerplate and tags errors with the
|
||||
// stream name so a stderr/stdout failure is greppable in logs.
|
||||
function fromBunStream(name: string, get: () => ReadableStream<Uint8Array>) {
|
||||
return Stream.fromReadableStream({
|
||||
evaluate: get,
|
||||
onError: (cause) => new Error(`${name} stream error: ${String(cause)}`),
|
||||
})
|
||||
}
|
||||
|
||||
// Long-lived processes (serve, acp) all want the same stderr drain: read every
|
||||
// chunk, push to a tail buffer, swallow stream errors (the child closing the
|
||||
// pipe is normal). `log: true` surfaces a real protocol error to logs so a
|
||||
// regression doesn't silently disappear.
|
||||
function forkStderrDrain(stream: ReadableStream<Uint8Array>, into: string[]) {
|
||||
return Effect.forkScoped(
|
||||
fromBunStream("stderr", () => stream).pipe(
|
||||
Stream.decodeText(),
|
||||
Stream.runForEach((chunk) => Effect.sync(() => into.push(chunk))),
|
||||
Effect.ignore({ log: true }),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
function isolatedEnv(home: string, configJson: string): Record<string, string> {
|
||||
return {
|
||||
OPENCODE_TEST_HOME: home,
|
||||
@@ -225,20 +249,10 @@ export function withCliFixture<A, E>(
|
||||
}).pipe(Effect.ignore),
|
||||
)
|
||||
|
||||
// Drain stderr in a scope-bound fork. Without this the OS pipe buffer
|
||||
// eventually fills and the child blocks on its next log call. Kept as a
|
||||
// tail buffer so timeout failures can include context.
|
||||
// Tail buffer so timeout failures can include stderr context. The fork
|
||||
// also keeps the OS pipe buffer from filling and wedging the child.
|
||||
const stderrChunks: string[] = []
|
||||
yield* Effect.forkScoped(
|
||||
Stream.fromReadableStream({
|
||||
evaluate: () => proc.stderr,
|
||||
onError: () => new Error("stderr stream error"),
|
||||
}).pipe(
|
||||
Stream.decodeText(),
|
||||
Stream.runForEach((chunk) => Effect.sync(() => stderrChunks.push(chunk))),
|
||||
Effect.ignore,
|
||||
),
|
||||
)
|
||||
yield* forkStderrDrain(proc.stderr, stderrChunks)
|
||||
|
||||
// Watch stdout line-by-line for the listening sentinel. Format
|
||||
// (see src/cli/cmd/serve.ts):
|
||||
@@ -246,17 +260,14 @@ export function withCliFixture<A, E>(
|
||||
const readyRe = /listening on (http:\/\/([^\s:]+):(\d+))/
|
||||
const readyDeferred = yield* Deferred.make<{ url: string; hostname: string; port: number }>()
|
||||
yield* Effect.forkScoped(
|
||||
Stream.fromReadableStream({
|
||||
evaluate: () => proc.stdout,
|
||||
onError: () => new Error("stdout stream error"),
|
||||
}).pipe(
|
||||
fromBunStream("stdout", () => proc.stdout).pipe(
|
||||
Stream.decodeText(),
|
||||
Stream.splitLines,
|
||||
Stream.runForEach((line) => {
|
||||
const m = line.match(readyRe)
|
||||
return m ? Deferred.succeed(readyDeferred, { url: m[1], hostname: m[2], port: Number(m[3]) }) : Effect.void
|
||||
}),
|
||||
Effect.ignore,
|
||||
Effect.ignore({ log: true }),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -323,26 +334,14 @@ export function withCliFixture<A, E>(
|
||||
)
|
||||
|
||||
const stderrChunks: string[] = []
|
||||
yield* Effect.forkScoped(
|
||||
Stream.fromReadableStream({
|
||||
evaluate: () => proc.stderr,
|
||||
onError: () => new Error("stderr stream error"),
|
||||
}).pipe(
|
||||
Stream.decodeText(),
|
||||
Stream.runForEach((chunk) => Effect.sync(() => stderrChunks.push(chunk))),
|
||||
Effect.ignore,
|
||||
),
|
||||
)
|
||||
yield* forkStderrDrain(proc.stderr, stderrChunks)
|
||||
|
||||
// Each ndjson line becomes one queue entry. JSON.parse failures are
|
||||
// surfaced as the raw string so a malformed protocol message doesn't
|
||||
// silently wedge the test in `receive`.
|
||||
const responses = yield* Queue.unbounded<unknown>()
|
||||
yield* Effect.forkScoped(
|
||||
Stream.fromReadableStream({
|
||||
evaluate: () => proc.stdout,
|
||||
onError: () => new Error("stdout stream error"),
|
||||
}).pipe(
|
||||
fromBunStream("stdout", () => proc.stdout).pipe(
|
||||
Stream.decodeText(),
|
||||
Stream.splitLines,
|
||||
Stream.runForEach((line) => {
|
||||
@@ -355,23 +354,23 @@ export function withCliFixture<A, E>(
|
||||
}
|
||||
return Queue.offer(responses, parsed)
|
||||
}),
|
||||
Effect.ignore,
|
||||
Effect.ignore({ log: true }),
|
||||
),
|
||||
)
|
||||
|
||||
return {
|
||||
// `proc.stdin.write` returns `number | Promise<number>`. The promise
|
||||
// form is the backpressure signal — if we don't await it, rapid
|
||||
// successive sends can interleave under pipe-buffer-full conditions
|
||||
// and corrupt the ndjson framing.
|
||||
send: (msg: object) =>
|
||||
Effect.sync(() => {
|
||||
proc.stdin.write(JSON.stringify(msg) + "\n")
|
||||
Effect.promise(async () => {
|
||||
const ret = proc.stdin.write(JSON.stringify(msg) + "\n")
|
||||
if (typeof ret !== "number") await ret
|
||||
}),
|
||||
receive: Queue.take(responses),
|
||||
close: () => {
|
||||
try {
|
||||
proc.stdin.end()
|
||||
} catch {
|
||||
// already closed
|
||||
}
|
||||
},
|
||||
// proc.stdin.end() is idempotent in Bun; no try/catch needed.
|
||||
close: () => proc.stdin.end(),
|
||||
exited: proc.exited as Promise<number>,
|
||||
} satisfies AcpHandle
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user