Skip to main content

ScopeDocs CLI — explain services, map impact, ask questions across your engineering knowledge graph.

Project description

ScopeDocs CLI

Stateless HTTP client for the ScopeDocs knowledge graph. Three core verbs — ask, impact, why — plus auth and feedback. Designed for humans (TUI) and agents (--json) with the same code path.

$ scopedocs why payment-service

  ᴡʜʏ — payment-service
  ════════════════════════════════════════════════════
  Stripe was chosen over Adyen in 2024-Q3 to keep the
  refund SLA under 5 minutes [1]. Idempotency keys are
  enforced at the edge by checkout-web [2].

  ɢ ᴏ ᴠ ᴇ ʀ ɴ ɪ ɴ ɢ   ᴅ ᴇ ᴄ ɪ ꜱ ɪ ᴏ ɴ ꜱ
    ADR-042  Refund SLA + provider choice    long@
    ADR-051  Idempotency at edge             radha@

  [1] notion://adr-042
  [2] github://checkout-web/pull/1834

Install

Requires Python 3.11+.

macOS / Linux / WSL2:

curl -fsSL https://api.scopedocs.ai/install.sh | sh

Windows (PowerShell):

irm https://api.scopedocs.ai/install.ps1 | iex

Manual (any platform):

pipx install scopedocs-cli                       # recommended
python3 -m pip install --user scopedocs-cli      # plain pip

Local dev install:

cd cli
python3 -m venv .venv
.venv/bin/pip install -e .

Authenticate

Get an API key from the ScopeDocs web UI (Settings → API keys), then:

scopedocs auth login                  # prompts for the key
scopedocs auth status                 # who am I — key, org, scopes, rate-limit
scopedocs auth status --json          # same, machine-readable
scopedocs auth logout                 # clears saved credentials

auth status hits /api/v1/me and shows your CLI version, key name, org, scopes, rate-limit budget, and last-used timestamp. Use it as a "whoami" probe in CI to verify a key is still valid.

Credentials are saved to ~/.config/scopedocs/config.toml with 0600 perms. You can also bypass the file with the SCOPEDOCS_API_KEY env var or --api-key flag.

Core commands

scopedocs ask "<question>"

Free-form Q&A across all sources (GitHub, Linear, Slack, Notion, code). Streams tokens by default.

scopedocs ask "why is the refund flow flaky right now?"
scopedocs ask "who owns auth-service on-call?" --json

Backend: POST /api/v1/chat.

scopedocs impact <target>

Blast-radius map for a service, file, or symbol — direct consumers, pipelines, dashboards, recent incidents (≤90 days), live workarounds.

scopedocs impact payment-service
scopedocs impact backend/payment/stripe.py
scopedocs impact RefundProcessor.refund

Backend: GET /api/v1/impact/{target}.

Status: the backend endpoint is not deployed yet. The CLI calls it and exits cleanly with code 4 (not-found) until backend ships it. No canned data fallback.

scopedocs why <target>

Why is this designed this way? Returns governing ADRs, chosen path, rejected alternatives, owners — decisions only, not "what does this code do" (that's your coding agent's job).

scopedocs why payment-service
scopedocs why backend/auth/jwt_auth.py

Backend: GET /api/v1/docs/search?query=...&category=adr + GET /api/v1/graph/node/{id}.

scopedocs update

Check PyPI for a newer release. Detects how the CLI was installed (pipx / pip --user / venv) and prints the matching upgrade command. Pass --apply to run it automatically (only safe for pipx — other install methods print the command for you to run manually).

scopedocs update                      # check + print upgrade command
scopedocs update --apply              # auto-upgrade (pipx only)
scopedocs update --json               # machine-readable
scopedocs update --channel pre        # opt into pre-releases

The default --channel auto mirrors the channel of the installed version: stable on 0.x.y, pre-release on 0.x.ybN / 0.x.yaN. Pass --channel pre to track betas, --channel stable to ignore them.

scopedocs feedback --good | --bad "<note>"

Rate the most recent answer. Reads the latest entry from the local trace log, posts it to /api/v1/feedback with the original client_trace_id so the backend can join it back to the original query for DSPy training.

scopedocs feedback --good "matched the right ADR"
scopedocs feedback --bad  "missed the live workaround for INC-204"

Interactive TUI

Run with no arguments to open a chat-style Textual app:

scopedocs

Slash commands: /ask, /impact, /why, /copy (Ctrl+Y), /clear (Ctrl+L), /help, /exit. Bare input (no leading slash) is treated as /ask. / walks prompt history.

Copy uses OSC 52 — works over SSH and tmux on iTerm2, Kitty, Alacritty, WezTerm, Ghostty, Windows Terminal. Silently no-ops on macOS Terminal.app and GNOME Terminal.

Global flags

Apply to every command:

Flag Default Purpose
--format text|json|markdown text Output format. Markdown deferred.
--json off Shortcut for --format json
--budget <n> 3000 Token budget hint sent to backend
--workspace <id> from config Override workspace
--api-key <key> from env / config Override auth
--backend <url> from config Override backend URL
--no-color auto Disable ANSI (auto-detected on non-tty)
--quiet / -q off Suppress logs
--verbose / -v off Print HTTP request/response trace to stderr
--no-context off Skip the local query-enrichment layer (privacy)
--no-trace off Don't append to the local trace log
--session off Attach the last few Q/A turns from the same cwd as conversation history
--no-stream off Force single-shot response (disable SSE streaming)
--version, --help Standard

Config

Precedence (high → low): CLI flag > env var > user config > repo config > built-in default.

User config (path varies by platform):

  • POSIX: $XDG_CONFIG_HOME/scopedocs/config.toml, default ~/.config/scopedocs/config.toml
  • Windows: %APPDATA%/scopedocs/config.toml
[default]
workspace = "ws_xxx"
api_key = "sk-sd_xxx"
budget = 3000

[backend]
url = "https://api.scopedocs.ai"  # default — override only for self-hosted / staging

Repo override: .scopedocs/config.toml at the repo root (commit this for team-wide defaults). Currently honors workspace, repo_alias, and privacy.deny.

Environment variables: SCOPEDOCS_API_KEY, SCOPEDOCS_WORKSPACE, SCOPEDOCS_BACKEND_URL, SCOPEDOCS_BUDGET, SCOPEDOCS_NO_TRACE.

Exit codes

Code Meaning
0 Success
1 Auth required / invalid key, or generic backend error
2 Usage error (handled by Typer)
3 Backend unreachable (network / timeout)
4 Not found (404 — endpoint or target missing)

All error paths print a clean one-line message; no Python tracebacks reach the user.

Query enrichment layer

Before every /api/v1/chat call, the CLI attaches a small query_context payload that the backend cannot otherwise see. This is query refinement only — it is not the DSPy context distillation, which lives in the backend.

Provider Collects
env cwd, CLI version, terminal, IDE hint
git branch, head sha (12 chars), uncommitted dirty files (cap 20)
ide_selection file, line range, highlighted text (cap 1200 chars)
workspace_config .scopedocs/config.toml workspace, repo alias, privacy denylist

Total payload is capped at ~2000 chars (≈500 tokens). Eviction order when over: workspace_configide_selection.textgit.dirty_files[5:] → drop entire provider. env always survives.

Deliberately not collected: recent commits, PR descriptions, file content beyond uncommitted changes — those already exist in Layer 2 via the GitHub integration.

Disable with --no-context (one-shot) or remove the relevant provider via .scopedocs/config.toml.

Trace log

Every invocation appends one JSONL line to a per-user state file:

  • POSIX: $XDG_STATE_HOME/scopedocs/traces.jsonl, default ~/.local/state/scopedocs/traces.jsonl
  • Windows: %LOCALAPPDATA%/scopedocs/traces.jsonl
{"trace_id": "...", "ts": "...", "command": "ask", "question": "...", "query_context": {...}, "answer_summary": "...", "source_refs": [...], "tokens_used": 0, "backend_request_id": "..."}

Perms 0600. Auto-rotates at 5000 lines. The feedback command reads the most recent entry to wire the rating back to the original query.

Disable with --no-trace or SCOPEDOCS_NO_TRACE=1.

JSON output

Every command supports --json for agent consumption. Stable schemas — see scopedocs_cli/renderers/json.py. Example:

scopedocs ask "who owns billing?" --json | jq '.sources[].url'

ask shape:

{
  "command": "ask",
  "question": "string",
  "summary": "string with [1] [2] citations",
  "evidence": [{"source": "...", "system": "github|slack|linear|notion|...", "signal": "...", "ref": "1"}],
  "recommendation": "string",
  "sources": [{"ref": "1", "url": "...", "type": "pr|slack_thread|notion_page|adr|incident", "title": "..."}],
  "tokens_used": 0,
  "tokens_budget": 3000
}

Schemas for impact and why are documented inline in scopedocs_cli/renderers/json.py.

Verbose mode

--verbose enables Warp-style per-request tracing on stderr:

→ POST https://api.scopedocs.ai/api/v1/chat
← 200 https://api.scopedocs.ai/api/v1/chat in 412ms

Useful when debugging auth/backend issues without enabling Python logging.

Structure

cli/
├── pyproject.toml
├── README.md
└── scopedocs_cli/
    ├── main.py                 # Typer entry, global flags, lazy-imported subcommands
    ├── client.py               # httpx wrapper (4 exception types, streaming SSE)
    ├── config.py               # XDG config loader, save/clear creds
    ├── theme.py                # Terminal Cartography palette
    ├── tui.py                  # Textual chat TUI
    ├── ui.py                   # Rich helpers (shared TUI + one-shot)
    ├── commands/               # ask · impact · why · feedback · auth
    ├── orchestrator/           # query enrichment layer + budget + trace
    │   ├── budget.py
    │   ├── trace.py
    │   └── providers/          # env · git · ide_selection · workspace_config
    └── renderers/              # tui.py + json.py

Tests

cd cli && python -m pytest tests/ -v

73 tests covering providers, budget, trace, client, config, ask command, auth status / me plumbing, and update (version compare, channel filtering, install-method detection). Mocked with httpx.MockTransport; no live network. CI runs the matrix on Python 3.11/3.12/3.13 across Ubuntu, macOS, and Windows — see .github/workflows/cli-tests.yml.

Releasing

Releases are automatic. Merge a PR that bumps the version in cli/pyproject.toml (and the matching cli/scopedocs_cli/__init__.py) to main, and .github/workflows/cli-release.yml will:

  1. Read the version from cli/pyproject.toml.
  2. Verify __init__.py matches (catch desync mistakes).
  3. Skip cleanly if that version already exists on PyPI (idempotent).
  4. Run the test suite, build sdist + wheel, validate with twine check --strict.
  5. Publish to PyPI via Trusted Publishing (OIDC — no API token in secrets).
  6. Tag the commit cli-v<version> and create a GitHub Release with the artifacts attached.

To force a re-publish (rare — only if you yanked and want to re-upload), use the workflow's workflow_dispatch trigger with force=true.

One-time setup (already done if you can see releases): on PyPI go to project → Settings → Publishing → "Add a new pending publisher" with owner=scopedocs, repo=scopedocs-ai, workflow=cli-release.yml, environment=pypi-cli-release-d9421f10. Then create the pypi-cli-release-d9421f10 environment in GitHub repo settings (no secrets needed; restrict deployment branches to main).

See CHANGELOG.md for release history.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scopedocs_cli-0.1.3.tar.gz (46.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scopedocs_cli-0.1.3-py3-none-any.whl (58.6 kB view details)

Uploaded Python 3

File details

Details for the file scopedocs_cli-0.1.3.tar.gz.

File metadata

  • Download URL: scopedocs_cli-0.1.3.tar.gz
  • Upload date:
  • Size: 46.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scopedocs_cli-0.1.3.tar.gz
Algorithm Hash digest
SHA256 9b4d8f23b8562e9ee2b2239116eacab5ea68e155e5ec656064c9e15b8fc4ede4
MD5 ae405418a632a984fa8fa0ee98512c68
BLAKE2b-256 2dd2dd4e2df76de83a70ad256bd9034942148243e0b2194a583f02c9db7eecbb

See more details on using hashes here.

Provenance

The following attestation bundles were made for scopedocs_cli-0.1.3.tar.gz:

Publisher: cli-release.yml on scopedocs/scopedocs-ai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scopedocs_cli-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: scopedocs_cli-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 58.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scopedocs_cli-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 df40d1bab5bacd968d6377fdecc64b7a02aa9f5be110c0fa50e2ec11a96eb61e
MD5 e8e426ac397b7ddbf17dcc1317810af7
BLAKE2b-256 02cd929be97d98de2a5709a026f6f7eeccd011cb9ead17481cf350dc49db3a67

See more details on using hashes here.

Provenance

The following attestation bundles were made for scopedocs_cli-0.1.3-py3-none-any.whl:

Publisher: cli-release.yml on scopedocs/scopedocs-ai

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page