Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 65 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# `dbxcli`: Dropbox from the command line

[![CI](https://github.com/dropbox/dbxcli/actions/workflows/ci.yml/badge.svg)](https://github.com/dropbox/dbxcli/actions/workflows/ci.yml)
[![Scorecard](https://github.com/dropbox/dbxcli/actions/workflows/scorecard.yml/badge.svg)](https://github.com/dropbox/dbxcli/actions/workflows/scorecard.yml)
[![CodeQL](https://github.com/dropbox/dbxcli/actions/workflows/codeql.yml/badge.svg)](https://github.com/dropbox/dbxcli/actions/workflows/codeql.yml)

`dbxcli` is a scriptable Dropbox CLI for files, shared links, teams, and
automation workflows. It is built for humans in the terminal, scripts, CI jobs,
Expand Down Expand Up @@ -36,13 +38,18 @@ dbxcli --help --output=json
dbxcli put --help --output=json
```

Stable JSON error codes and process exit codes are documented in
Stable JSON envelopes, error codes, and process exit codes are documented in
[Automation and JSON output](https://github.com/dropbox/dbxcli/blob/master/docs/automation.md).

## JSON output

`--output=json` emits stable schema v1 success and error envelopes for
automation. Use JSON help for machine-readable command manifests:
For commands that support structured execution output, `--output=json` runs the
command and emits stable schema v1 success and error envelopes for automation.

JSON help is the machine-readable command-discovery surface. Use it to discover
command paths, arguments, flags, aliases, input schemas, auth behavior,
stdin/stdout behavior, schema references, and whether structured command
execution output is supported:

```sh
dbxcli --help --output=json
Expand Down Expand Up @@ -99,6 +106,59 @@ Some team accounts may not have a writable Dropbox root namespace. Run
`dbxcli ls /` first, then upload under a writable folder, such as your personal
folder or a team folder.

### Proxy configuration

`dbxcli` uses Go's standard HTTP proxy behavior, so `HTTPS_PROXY`,
`HTTP_PROXY`, and `NO_PROXY` apply to Dropbox API requests and OAuth token
exchange/refresh requests made by the CLI.

For Dropbox API and OAuth requests, set `HTTPS_PROXY`:

```sh
HTTPS_PROXY=http://127.0.0.1:8080 dbxcli ls /
```

For a shell session:

```sh
export HTTPS_PROXY=http://proxy.company.example:8080
export NO_PROXY=localhost,127.0.0.1,.company.example
dbxcli login
```

On Windows PowerShell:

```powershell
$env:HTTPS_PROXY = "http://127.0.0.1:8080"
dbxcli login
```

On Windows cmd:

```bat
set HTTPS_PROXY=http://127.0.0.1:8080
dbxcli login
```

`HTTP_PROXY` is also honored for plain HTTP requests. Use `NO_PROXY` to bypass
the proxy for local or internal hosts. Lowercase forms such as `https_proxy`
and `no_proxy` are also supported by Go's HTTP stack.

If your proxy requires basic authentication, include credentials in the proxy
URL:

```sh
HTTPS_PROXY=http://user:password@proxy.company.example:8080 dbxcli ls /
```

URL-encode special characters in proxy usernames or passwords. Be careful with
proxy credentials in environment variables, shell history, CI logs, and process
listings.

The browser authorization step in `dbxcli login` is outside `dbxcli`; configure
your browser or operating-system proxy separately if that page also needs a
proxy.

## Features

* File operations: `ls`, `cp`, `mkdir`, `mv`, `rm`, `put`, and `get`
Expand All @@ -111,7 +171,7 @@ folder or a team folder.
* OAuth login with refreshable saved credentials
* Direct token automation with `DBXCLI_ACCESS_TOKEN`
* Alternate saved-credential files with `DBXCLI_AUTH_FILE`
* Structured JSON success and error envelopes for migrated commands
* Structured JSON success and error envelopes for supported commands
* JSON help manifests for machine-readable command discovery
* Team administration commands and member-scoped access with `--as-member`

Expand Down Expand Up @@ -141,23 +201,6 @@ tar -xzf dbxcli_X.Y.Z_linux_amd64.tar.gz
sudo mv dbxcli_X.Y.Z_linux_amd64/dbxcli /usr/local/bin/
```

For security-sensitive direct downloads, verify the signed checksum file and
provenance before installing:

```sh
curl -LO https://github.com/dropbox/dbxcli/releases/download/vX.Y.Z/SHA256SUMS.sigstore.json
cosign verify-blob SHA256SUMS \
--bundle SHA256SUMS.sigstore.json \
--certificate-identity "https://github.com/dropbox/dbxcli/.github/workflows/release.yml@refs/tags/vX.Y.Z" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"

curl -LO https://github.com/dropbox/dbxcli/releases/download/vX.Y.Z/dbxcli_X.Y.Z_slsa.intoto.jsonl
slsa-verifier verify-artifact dbxcli_X.Y.Z_linux_amd64.tar.gz \
--provenance-path dbxcli_X.Y.Z_slsa.intoto.jsonl \
--source-uri github.com/dropbox/dbxcli \
--source-tag vX.Y.Z
```

Release assets include:

* `dbxcli_X.Y.Z_darwin_amd64.tar.gz`
Expand All @@ -168,9 +211,6 @@ Release assets include:
* `dbxcli_X.Y.Z_openbsd_amd64.tar.gz`
* `dbxcli_X.Y.Z_windows_amd64.zip`
* `SHA256SUMS`
* `SHA256SUMS.sigstore.json`
* `dbxcli_X.Y.Z_sbom.spdx.json`
* `dbxcli_X.Y.Z_slsa.intoto.jsonl`

### Build from source

Expand Down Expand Up @@ -231,7 +271,7 @@ stay in sync with the CLI.
* If you are submitting a non-trivial change, please fill out the
[Dropbox Contributor License Agreement](https://opensource.dropbox.com/cla/)
first.
* Open a [pull request](https://help.github.com/articles/using-pull-requests/)
* Open a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request)
with a clear description of the change.
* Include tests or manual validation details when relevant.

Expand Down
82 changes: 57 additions & 25 deletions docs/automation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,20 @@
`dbxcli` supports text output for humans, structured JSON command output for
scripts, and JSON help for machine-readable command discovery.

Command results and JSON errors are written to stdout. Status, progress,
human-facing warnings, diagnostics, and verbose logs are written to stderr.
In JSON mode, command result and error envelopes are written to stdout. The
`warnings` field contains machine-actionable warning objects. Human-facing
warnings, progress, diagnostics, and verbose logs are written to stderr.

## Which interface should I use?

For ordinary shell scripts and CI jobs running supported commands, use
`--output=json`, check the process exit code, and inspect `ok`, `error.code`,
`results[].status`, and `results[].kind`. You do not need to validate schemas
before invoking basic commands.

For wrappers, agents, and other tools that need to discover commands or
validate inputs before invoking the CLI, use JSON help manifests and
`input_schema`.

## JSON command output

Expand All @@ -17,18 +29,13 @@ dbxcli account --output=json
dbxcli logout --output=json
```

Use JSON help to discover whether a command supports structured command output:
To check programmatically whether a command supports structured command output,
use JSON help:

```sh
dbxcli put --help --output=json
```

JSON help is also the Command Manifest v1 surface for tools and agents. Command
manifests expose machine-readable metadata such as structured positional
arguments, flag enum values and conflicts, prompt/sensitive-input metadata,
examples, auth modes, best-effort Dropbox scopes, stdin/stdout behavior, schema
refs, result statuses/kinds, and known warning codes when available.

Successful JSON responses use a stable envelope:

```json
Expand Down Expand Up @@ -71,15 +78,11 @@ a non-zero status:
}
```

The full JSON command catalog, stable error codes, and schemas live in
[json-schema/v1](json-schema/v1/README.md).
Use `commands.schema.json` from that directory when a caller needs
command-specific success validation for `input`, `results`, primitive field
types, statuses, kinds, and warning codes.

## Schema-first automation
## Schema-first tool integration

Automation should treat the CLI and schemas as the stable interface:
Wrappers, agents, and other tools can treat the CLI and schemas as the stable
interface when they need command discovery or input validation before invoking
`dbxcli`:

* Use `dbxcli --help --output=json` for command discovery.
* Use each manifest's `input_schema` to validate arguments and flags before
Expand All @@ -88,9 +91,14 @@ Automation should treat the CLI and schemas as the stable interface:
* Use `error.schema.json` to validate JSON error responses.
* Prefer schema URLs from a pinned release tag when reproducibility matters.

The full JSON command catalog, stable error codes, and schemas live in
[json-schema/v1](json-schema/v1/README.md). Use `commands.schema.json` when a
caller needs command-specific success validation for `input`, `results`,
primitive field types, statuses, kinds, and warning codes.

dbxcli currently does not expose a separate machine protocol. Tools should
invoke the CLI, read stdout as JSON in `--output=json` mode, and treat stderr as
status, progress, warnings, diagnostics, and verbose logs.
status, progress, human-facing warnings, diagnostics, and verbose logs.

## JSON help manifest

Expand All @@ -110,6 +118,10 @@ input schemas, aliases, known auth modes, known destructive levels,
stdin/stdout behavior, schema refs, and whether normal structured command
output is supported.

In each JSON help result, check `results[].result.supports_structured_output`.
If it is false, JSON help is still available, but normal command execution with
`--output=json` may return `structured_output_unsupported`.

Each manifest result includes `input_schema`, a JSON Schema object for the
command's CLI inputs. It uses JSON-friendly names such as `if_exists`, includes
enum values for bounded arguments and flags, and preserves original CLI names in
Expand Down Expand Up @@ -140,6 +152,25 @@ dbxcli --timeout 2m ls --output=json /
`--timeout` uses Go duration units such as `30s`, `2m`, or `1h`. The default
`0` disables the command deadline.

If a runner must reach Dropbox through a corporate or local proxy, set the
standard proxy environment variables before invoking `dbxcli`:

```sh
export HTTPS_PROXY=http://proxy.company.example:8080
export NO_PROXY=localhost,127.0.0.1,.company.example
dbxcli ls --output=json /
```

`dbxcli` uses Go's standard HTTP proxy behavior, so `HTTPS_PROXY`,
`HTTP_PROXY`, and `NO_PROXY` apply to Dropbox API requests and OAuth token
exchange/refresh requests made by the CLI.
Lowercase forms such as `https_proxy` and `no_proxy` are also supported by Go's
HTTP stack.

The browser authorization step in `dbxcli login` is outside `dbxcli`; configure
the browser or operating-system proxy separately if that page also needs a
proxy.

Check auth and identity before running a job:

```sh
Expand Down Expand Up @@ -185,7 +216,7 @@ jobs:
publish-report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- name: Upload report to Dropbox
env:
DBXCLI_ACCESS_TOKEN: ${{ secrets.DROPBOX_ACCESS_TOKEN }}
Expand All @@ -208,10 +239,11 @@ Use `dbxcli login` to save refreshable credentials:
dbxcli login
```

Use `dbxcli account --output=json` as an auth and identity check. The account
result includes `result.auth`:
Use `dbxcli account --output=json` as an auth and identity check. In the JSON
envelope, auth metadata appears at `results[0].result.auth`. The examples below
show only the relevant `result` fragment.

`result.auth` example:
`result` fragment example:

```json
{
Expand All @@ -223,7 +255,7 @@ result includes `result.auth`:
}
```

Stable auth fields:
Stable fields inside `results[0].result.auth`:

* `result.auth.source`: `saved` or `env`
* `result.auth.refreshable`: boolean
Expand All @@ -238,7 +270,7 @@ DBXCLI_ACCESS_TOKEN=sl.xxxxxx dbxcli ls --output=json /
This token is used directly and is not saved or refreshed. If it expires, the
command fails and you must provide a fresh token.

`result.auth` example:
`result` fragment example:

```json
{
Expand All @@ -257,7 +289,7 @@ DBXCLI_AUTH_FILE=/path/to/auth.json dbxcli login
DBXCLI_AUTH_FILE=/path/to/auth.json dbxcli ls /
```

`result.auth` example:
`result` fragment example:

```json
{
Expand Down
8 changes: 4 additions & 4 deletions docs/json-schema/v1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ directly relevant path and `from_path`/`to_path` for relocation-style source
and destination context. Add a new key such as `target` or `local_path` only
when the existing keys would be ambiguous.

Command results and JSON errors are written to stdout. Status, progress,
human-facing warnings, diagnostics, and verbose logs are written to stderr.
In JSON mode, error responses are written to stdout and the process exits with
a non-zero status.
In JSON mode, command result and error envelopes are written to stdout. The
`warnings` field contains machine-actionable warning objects. Human-facing
warnings, progress, diagnostics, and verbose logs are written to stderr. Error
responses exit with a non-zero status.

Commands that intentionally do not support structured command-result JSON yet
include `login` and `completion`. Their help output is still
Expand Down
2 changes: 1 addition & 1 deletion docs/sharing.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ standard JSON envelope with `ok`, `schema_version`, `command`, `input`,
link or target type, such as `file`, `folder`, or `shared_link`.

In text mode, `share-link create` prints only the shared-link URL to stdout.
Status, warnings, diagnostics, and verbose logs go to stderr.
Status, human-facing warnings, diagnostics, and verbose logs go to stderr.

```sh
url="$(dbxcli share-link create /file.txt)"
Expand Down
Loading