This branch contains the CLI for Ferret v2. For the stable v1 CLI, see the
v1branch.
Ferret CLI is the command-line interface for Ferret, a declarative query language and runtime for structured data extraction, browser automation, and data workflows.
Use it to run FQL scripts, format and check source files, inspect compiled bytecode, manage browser sessions, and debug local scripts.
Full documentation lives at ferretlang.org.
Download a release from the releases page, or install from source:
go install github.com/MontFerret/cli/v2/ferret@latestShell installer:
curl https://raw.githubusercontent.com/MontFerret/cli/master/install.sh | shRun the REPL:
ferret replRun an inline expression:
ferret run --eval 'RETURN "Hello, Ferret!"'Run a script:
ferret run example.fqlPass parameters:
ferret run example.fql --param url=https://example.com --param limit=10Parameter values are parsed as JSON when possible. Values that are not valid JSON are passed as strings.
ferret run example.fql --param active=true
ferret run example.fql --param tags='["news","tech"]'
ferret run example.fql --param code='"123"'Use parameters in FQL with @name:
LET page = DOCUMENT(@url)
RETURN ELEMENT(page, "title").innerText
ferret run script.fql # Run a script
ferret exec script.fql # Alias for run
ferret repl # Start the interactive shell
ferret check script.fql # Check syntax and semantics
ferret fmt script.fql # Format source
ferret build script.fql # Compile to a bytecode artifact
ferret inspect script.fql # Print compiled program details
ferret debug script.fql # Start the interactive debugger
ferret browser open # Start a managed browser
ferret config list # Show configuration
ferret mod search sqlite # Search the Ferret module registry
ferret mod install montferret/archive # Install a module into a Go application
ferret version # Show version informationRun ferret [command] --help for command-specific options.
Ferret CLI handles module discovery, installation into Go applications, project scaffolding, and preparation of registry publication records. Installation uses the Go module toolchain and the package path published by the Ferret registry.
Search the public registry by canonical module ID or description, or inspect one registered module:
ferret mod search sqlite
ferret mod info montferret/sqliteInstall a compatible registered release into an existing Go application:
ferret mod install montferret/archive
ferret mod install montferret/archive@1.0.0-rc.3
ferret mod install --yes montferret/archive # Approve safe missing prerequisites automaticallyIf the application is missing github.com/MontFerret/ferret/v2 or an active
ferret.New(...) composition, an interactive install shows the complete setup
before changing the project. It can add the exact Ferret version embedded in the
CLI and create an exported NewFerret(options ...ferret.Option) helper in
ferret.go when the destination package is unambiguous. Empty modules derive the
package name from the module path; projects with one package use that package.
Projects with multiple packages must add a composition manually.
Use -y or --yes to approve safe missing prerequisites in automation.
Non-interactive installs without that flag fail with equivalent manual steps
instead of reading stdin. The application must already have a go.mod.
The installer updates go.mod, go.sum, and the composition, then builds only
its owning package before committing all changes. It does not modify the Ferret
CLI runtime or create Ferret-specific project state. Installed modules are Go
code compiled into the application and execute with the application's process
permissions.
Initialize a new module project with the guided flow. It explains each value, offers editable defaults, and shows the resolved configuration before creating files:
ferret mod initYou can also provide any known values up front; the wizard asks only for what is missing. For non-interactive use, provide the module name and Go import path. The directory and namespace retain their module-name defaults:
ferret mod init acme/sqlite \
--go-module github.com/acme/ferret-sqlite \
--dir sqlite \
--namespace DB::SQLITEThe scaffold contains schema-valid TODO metadata. Replace it before preparing a release, commit the module files, and push the release tag. The manifest must identify a public repository that supports anonymous HTTPS Git access. From the module root, print the validated Barn registration records and pull-request guidance:
ferret mod publishBy default, the tag is v<version> for a standalone module or
<repository.directory>/v<version> for a monorepo module. For non-standard
release tags, pass --tag. Publication preparation consults the public
registry, inspects the pushed tag through anonymous HTTPS Git, and returns only
the records needed for a new module or version. It does not write records,
upload packages, authenticate with a provider, or open a pull request.
Ferret can use Chrome or Chromium through the Chrome DevTools Protocol.
Open a managed browser:
ferret browser openRun a script with a visible browser:
ferret run --browser-open script.fqlRun with a headless browser:
ferret run --browser-headless script.fqlUse an existing browser endpoint:
ferret run --browser-address http://127.0.0.1:9222 script.fqlStart the debugger for a local source file:
ferret debug script.fqlUseful debugger commands:
break 12 Set a breakpoint
breakpoints List breakpoints
continue Resume execution
step Step into
next Step over
out Step out
where Show stack trace
locals Show local variables
print <expr> Evaluate a safe debug expression
quit Exit
The debugger currently supports local source scripts with the builtin runtime. Compiled artifacts, remote debugging, DAP, conditional breakpoints, hit-count breakpoints, and logpoints are not supported yet.
Ferret's builtin runtime exposes filesystem functions through a writable sandbox rooted at the CLI's current working directory. Select a narrower relative or absolute root, and optionally make it read-only:
ferret run \
--policy-fs-root=./fixtures \
--policy-fs-read-only \
script.fqlFilesystem policy options are available on run, repl, and debug and apply only to the builtin runtime. Supplying one with a remote runtime is a configuration error.
| Flag and config key | Environment variable | Default | Behavior |
|---|---|---|---|
policy-fs-root |
FERRET_POLICY_FS_ROOT |
Current working directory | Filesystem sandbox root |
policy-fs-read-only |
FERRET_POLICY_FS_READ_ONLY |
false |
Reject writes, directory changes, and removals |
Ferret's builtin runtime blocks localhost, loopback, private-network, and link-local HTTP access by default. Grant only the access a script needs; for example, a script that intentionally calls a local development service requires an explicit opt-in:
ferret run \
--policy-http-allow-localhost \
--policy-http-default-headers='{"X-Trace":"local"}' \
script.fqlHTTP policy options are available on run, repl, and debug and apply only to the builtin runtime. Supplying one with a remote runtime is a configuration error. They configure Ferret HTTP integrations such as IO::NET::HTTP and NET::REST; the existing --proxy and --user-agent options continue to configure HTML/browser drivers.
List values accept repeated flags or comma-separated values. Default headers use a JSON object with string values. Only values explicitly supplied through a flag, environment variable, or config file override Ferret's secure defaults. Numeric zero retains the Ferret default; use the dedicated no-timeout or unlimited-* option to disable a limit.
| Flag and config key | Environment variable | Default | Behavior |
|---|---|---|---|
policy-http-allowed-schemes |
FERRET_POLICY_HTTP_ALLOWED_SCHEMES |
http,https |
Allowed URL schemes |
policy-http-allowed-methods |
FERRET_POLICY_HTTP_ALLOWED_METHODS |
GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS |
Allowed HTTP methods |
policy-http-allowed-hosts |
FERRET_POLICY_HTTP_ALLOWED_HOSTS |
unrestricted | Exact allowed hosts or host:port values |
policy-http-blocked-hosts |
FERRET_POLICY_HTTP_BLOCKED_HOSTS |
none | Exact blocked hosts or host:port values |
policy-http-allow-localhost |
FERRET_POLICY_HTTP_ALLOW_LOCALHOST |
false |
Allow localhost and loopback addresses |
policy-http-allow-private-networks |
FERRET_POLICY_HTTP_ALLOW_PRIVATE_NETWORKS |
false |
Allow private-network addresses |
policy-http-allow-link-local |
FERRET_POLICY_HTTP_ALLOW_LINK_LOCAL |
false |
Allow link-local addresses |
policy-http-default-headers |
FERRET_POLICY_HTTP_DEFAULT_HEADERS |
none | Default request headers as a JSON string map |
policy-http-blocked-request-headers |
FERRET_POLICY_HTTP_BLOCKED_REQUEST_HEADERS |
none | Block requests containing these header names |
policy-http-timeout |
FERRET_POLICY_HTTP_TIMEOUT |
30s |
Overall HTTP timeout |
policy-http-no-timeout |
FERRET_POLICY_HTTP_NO_TIMEOUT |
false |
Explicitly disable the overall timeout |
policy-http-max-request-size |
FERRET_POLICY_HTTP_MAX_REQUEST_SIZE |
16777216 |
Maximum request-body size in bytes |
policy-http-unlimited-request-size |
FERRET_POLICY_HTTP_UNLIMITED_REQUEST_SIZE |
false |
Explicitly disable the request-body limit |
policy-http-max-response-size |
FERRET_POLICY_HTTP_MAX_RESPONSE_SIZE |
16777216 |
Maximum response-body size in bytes |
policy-http-unlimited-response-size |
FERRET_POLICY_HTTP_UNLIMITED_RESPONSE_SIZE |
false |
Explicitly disable the response-body limit |
policy-http-max-response-header-size |
FERRET_POLICY_HTTP_MAX_RESPONSE_HEADER_SIZE |
1048576 |
Maximum response-header size in bytes |
policy-http-follow-redirects |
FERRET_POLICY_HTTP_FOLLOW_REDIRECTS |
true |
Follow HTTP redirects |
policy-http-max-redirects |
FERRET_POLICY_HTTP_MAX_REDIRECTS |
10 |
Maximum redirects to follow |
Configuration values can come from command-line flags, environment variables, or the config file.
Priority order:
- Command-line flags
- Environment variables, for example
FERRET_RUNTIME - Config file
- Defaults
Config file locations:
- Linux/macOS:
~/.config/ferret/config.yaml - Windows:
%APPDATA%\ferret\config.yaml
Examples:
ferret config set runtime builtin
ferret config set browser-address http://127.0.0.1:9222
ferret config set policy-fs-root ./fixtures
ferret config set policy-fs-read-only true
ferret config set policy-http-allow-localhost true
ferret config set policy-http-allowed-hosts api.example.com,cdn.example.com
ferret config set policy-http-default-headers '{"X-Trace":"local"}'
ferret config get browser-address
ferret config list
ferret config unset policy-http-allowed-hostsconfig set validates the complete persisted filesystem and HTTP policy before writing it. Invalid policy values and conflicting controls, such as setting both policy-http-timeout and policy-http-no-timeout=true, leave the existing config unchanged. List values use comma-separated strings, and default headers use a JSON object with string values.
config unset removes only the value stored in the config file and restores the implicit default for that key. Command-line flags and environment variables remain unaffected.
Build and test locally:
git clone https://github.com/MontFerret/cli.git
cd cli
make compile
make testCommon development commands:
make fmt
make lint
make buildIssues and pull requests are welcome. Before opening a pull request, run the formatter, linter, and test suite.
Apache-2.0