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]"
|
||||||
|
`;
|
||||||
@@ -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"
|
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> {
|
function isolatedEnv(home: string, configJson: string): Record<string, string> {
|
||||||
return {
|
return {
|
||||||
OPENCODE_TEST_HOME: home,
|
OPENCODE_TEST_HOME: home,
|
||||||
@@ -225,20 +249,10 @@ export function withCliFixture<A, E>(
|
|||||||
}).pipe(Effect.ignore),
|
}).pipe(Effect.ignore),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Drain stderr in a scope-bound fork. Without this the OS pipe buffer
|
// Tail buffer so timeout failures can include stderr context. The fork
|
||||||
// eventually fills and the child blocks on its next log call. Kept as a
|
// also keeps the OS pipe buffer from filling and wedging the child.
|
||||||
// tail buffer so timeout failures can include context.
|
|
||||||
const stderrChunks: string[] = []
|
const stderrChunks: string[] = []
|
||||||
yield* Effect.forkScoped(
|
yield* forkStderrDrain(proc.stderr, stderrChunks)
|
||||||
Stream.fromReadableStream({
|
|
||||||
evaluate: () => proc.stderr,
|
|
||||||
onError: () => new Error("stderr stream error"),
|
|
||||||
}).pipe(
|
|
||||||
Stream.decodeText(),
|
|
||||||
Stream.runForEach((chunk) => Effect.sync(() => stderrChunks.push(chunk))),
|
|
||||||
Effect.ignore,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
// Watch stdout line-by-line for the listening sentinel. Format
|
// Watch stdout line-by-line for the listening sentinel. Format
|
||||||
// (see src/cli/cmd/serve.ts):
|
// (see src/cli/cmd/serve.ts):
|
||||||
@@ -246,17 +260,14 @@ export function withCliFixture<A, E>(
|
|||||||
const readyRe = /listening on (http:\/\/([^\s:]+):(\d+))/
|
const readyRe = /listening on (http:\/\/([^\s:]+):(\d+))/
|
||||||
const readyDeferred = yield* Deferred.make<{ url: string; hostname: string; port: number }>()
|
const readyDeferred = yield* Deferred.make<{ url: string; hostname: string; port: number }>()
|
||||||
yield* Effect.forkScoped(
|
yield* Effect.forkScoped(
|
||||||
Stream.fromReadableStream({
|
fromBunStream("stdout", () => proc.stdout).pipe(
|
||||||
evaluate: () => proc.stdout,
|
|
||||||
onError: () => new Error("stdout stream error"),
|
|
||||||
}).pipe(
|
|
||||||
Stream.decodeText(),
|
Stream.decodeText(),
|
||||||
Stream.splitLines,
|
Stream.splitLines,
|
||||||
Stream.runForEach((line) => {
|
Stream.runForEach((line) => {
|
||||||
const m = line.match(readyRe)
|
const m = line.match(readyRe)
|
||||||
return m ? Deferred.succeed(readyDeferred, { url: m[1], hostname: m[2], port: Number(m[3]) }) : Effect.void
|
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[] = []
|
const stderrChunks: string[] = []
|
||||||
yield* Effect.forkScoped(
|
yield* forkStderrDrain(proc.stderr, stderrChunks)
|
||||||
Stream.fromReadableStream({
|
|
||||||
evaluate: () => proc.stderr,
|
|
||||||
onError: () => new Error("stderr stream error"),
|
|
||||||
}).pipe(
|
|
||||||
Stream.decodeText(),
|
|
||||||
Stream.runForEach((chunk) => Effect.sync(() => stderrChunks.push(chunk))),
|
|
||||||
Effect.ignore,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
// Each ndjson line becomes one queue entry. JSON.parse failures are
|
// Each ndjson line becomes one queue entry. JSON.parse failures are
|
||||||
// surfaced as the raw string so a malformed protocol message doesn't
|
// surfaced as the raw string so a malformed protocol message doesn't
|
||||||
// silently wedge the test in `receive`.
|
// silently wedge the test in `receive`.
|
||||||
const responses = yield* Queue.unbounded<unknown>()
|
const responses = yield* Queue.unbounded<unknown>()
|
||||||
yield* Effect.forkScoped(
|
yield* Effect.forkScoped(
|
||||||
Stream.fromReadableStream({
|
fromBunStream("stdout", () => proc.stdout).pipe(
|
||||||
evaluate: () => proc.stdout,
|
|
||||||
onError: () => new Error("stdout stream error"),
|
|
||||||
}).pipe(
|
|
||||||
Stream.decodeText(),
|
Stream.decodeText(),
|
||||||
Stream.splitLines,
|
Stream.splitLines,
|
||||||
Stream.runForEach((line) => {
|
Stream.runForEach((line) => {
|
||||||
@@ -355,23 +354,23 @@ export function withCliFixture<A, E>(
|
|||||||
}
|
}
|
||||||
return Queue.offer(responses, parsed)
|
return Queue.offer(responses, parsed)
|
||||||
}),
|
}),
|
||||||
Effect.ignore,
|
Effect.ignore({ log: true }),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
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) =>
|
send: (msg: object) =>
|
||||||
Effect.sync(() => {
|
Effect.promise(async () => {
|
||||||
proc.stdin.write(JSON.stringify(msg) + "\n")
|
const ret = proc.stdin.write(JSON.stringify(msg) + "\n")
|
||||||
|
if (typeof ret !== "number") await ret
|
||||||
}),
|
}),
|
||||||
receive: Queue.take(responses),
|
receive: Queue.take(responses),
|
||||||
close: () => {
|
// proc.stdin.end() is idempotent in Bun; no try/catch needed.
|
||||||
try {
|
close: () => proc.stdin.end(),
|
||||||
proc.stdin.end()
|
|
||||||
} catch {
|
|
||||||
// already closed
|
|
||||||
}
|
|
||||||
},
|
|
||||||
exited: proc.exited as Promise<number>,
|
exited: proc.exited as Promise<number>,
|
||||||
} satisfies AcpHandle
|
} satisfies AcpHandle
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user