# Use the CLI without a host

> Pull and commit by hand, how a notebook path resolves, how to read the success and error reports, and how to drive both from scripts.

Canonical URL: https://www.slivingdoc.dev/docs/guides/cli/ · Version: 0.1 · Updated: 2026-09-21

Full site index: https://www.slivingdoc.dev/llms.txt

`pull` and `commit` are the human mirror of the two MCP tools. They take
the same flags as `serve`, run the same startup sequence — the pinned
engine check and the S3 compatibility probe — perform one operation,
print the result, and exit. No MCP host is involved, and no daemon is
left behind.

```text
export SLIVINGDOC_BUCKET=my-notes
slivingdoc pull notes
# edit UTF-8 text files under notes/
slivingdoc commit notes -m "meeting summary"
```

That is the whole loop. `pull` writes the current notebook into the
directory. `commit` publishes what you changed there and merges in any
concurrent, non-conflicting changes other writers published meanwhile.

## The notebook path

Each subcommand takes at most one notebook path. It may come before or
after the flags.

- Omitting it uses the workspace root, which is the working directory
  unless `--workspace-root` says otherwise.
- A path that begins with `~/` resolves against the current user's home
  directory.
- Any other relative path resolves against the working directory.
- The resolved path must stay at or below the workspace root.

`commit` also requires a message, `-m` or `--message`. A missing message,
or more than one path, exits nonzero before any native or network
dependency is touched — so a typo in a script fails fast and costs
nothing.

## The success report

A subcommand that succeeds writes its report to standard output and exits
zero:

```text
OK  generation 18
  archive/old.md  -3
  notes/a.md  +1 -1
  notes/c.md  +2
3 files changed, 3 insertions(+), 4 deletions(-)
```

Line by line:

- `OK` is the status token, and `generation 18` is the accepted remote
  generation the operation ended on. The status line also names the
  notebook directory the operation worked in; every result does.
- One line per changed file, with its insertion and deletion counts. A
  zero count is left out, so `-3` means deletions only.
- The totals trailer closes the report.

The per-file counts answer "what is new to check out". For `pull` they
are the delta between the directory as it was and the materialized
result. For `commit` they are the increment your publication added over
the remote state it observed. A synchronization that changed nothing
reports an empty stat.

## The error report

A domain error prints the same skeleton to standard output and exits
nonzero:

```text
CONTENT_CONFLICT · MERGE_CONFLICT
Resolve the conflict blocks before notes_commit.
  notes/today.md  conflict  lines 12-18, 40-42
next: edit the files, then commit
retryable: false
```

- The status line is the error code, a middle dot, and the reason token.
- Then the message.
- Then one line per affected file: its reason in lower-case words, and
  its one-based inclusive line ranges when the reason has them.
- `next:` names your next step, and `retryable:` says whether trying
  again unchanged can help.
- A recovery report follows when the operation performed one.

Both reports end with the same path-policy trailers when the process is
configured with them: a `writable:` trailer naming the configured
writable set, then a `read-only:` trailer naming the configured read-only
set, and — when both are set — a `path-rule: longest match decides`
trailer, because the two sets can name the same region at different
depths. See
[Restrict agents with path policies](/docs/guides/path-policies/).

[Errors](/docs/reference/errors/) lists every code, reason, and action.
`CONTENT_CONFLICT` has its own guide:
[Resolve conflicts](/docs/guides/conflicts/).

## Colour

Colour is presentation only. The status tokens, the generation summary,
the per-file counts, and the conflict paths are coloured only when
standard output is a real terminal; piped or redirected output is plain
text. Any non-empty `NO_COLOR` disables the colour even on a terminal.

## From scripts and cron

Nothing about the two commands is interactive, so a script can drive
them directly:

- Read the exit status. Zero is success; nonzero is a domain error whose
  report is on standard output.
- Redirected output is already plain text. Set `NO_COLOR` as well if the
  job may run attached to a terminal.
- Standard output carries only the report. Logs go to standard error,
  where `LOG_LEVEL` controls them. See
  [Logging and profiling](/docs/reference/logging/).
- Configure the job through the environment (`SLIVINGDOC_BUCKET`,
  `AWS_REGION`, and the rest) instead of a long flag list. Flags override
  environment variables, and the environment overrides the defaults.

> **Warning:** `serve` resolves the AWS credential chain once and holds
> the session, but every `pull` or `commit` invocation resolves it fresh.
> With short-lived STS or SSO credentials, each scheduled run needs a
> currently valid session. An expired login surfaces as a redacted
> startup refusal from the compatibility probe, not as a mid-operation
> error.

## Next

- [Share a directory with humans](/docs/guides/shared-directory/) — when
  an agent and a person work in the same directory.
- [Configuration](/docs/reference/configuration/) — every flag and
  environment variable.
- [CLI](/docs/reference/cli/) — the command reference.
