Skip to content

Releases: jrapakko/scree

Release list

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 18:53

Code vocabulary routing for auto

auto, the default search mode, now also runs hybrid (vector plus keyword search) when a query names something from the repo's code, even a name with no _ or digit, such as psycopg or PageFetcher. Before, auto caught only words with a _ or digit, such as SCREE_FIRST_SYNC_MB or R7-Q2.

Each sync builds a vocabulary of names from the repo:

  • Dependency names from requirements*.txt, pyproject.toml, package.json, go.mod and Cargo.toml.
  • Mixed-case names from imports and declarations in Python, JavaScript, TypeScript and Go, such as PageFetcher and useState.

Privacy

  • Code is read for names only, under the same .gitignore, .screeignore, size and symlink rules as markdown.
  • Only the lowercased names are stored, in the repo's local index. Code is never chunked, embedded, sent to the API or returned by read_doc.
  • Names come only from where code declares or imports them, never from values, strings, comments or docstrings.
  • Code under hidden folders such as .claude/ and .github/ adds no names, and vendored folders such as node_modules and vendor are skipped.
  • A symlink must point to a file of its own kind: a .md link to a source file is refused.

Routing quality

  • A stoplist of about 350 common words keeps plain questions on semantic. It covers question words, packages named after ordinary words (requests, markdown, sync) and mixed-case plain words (setUp, FileName).
  • On two repos with code and docs, most questions naming code switched to hybrid, and no plain question did.
  • A word the stoplist misses can still send a plain question to hybrid. -mode semantic is always available.

Limits

  • At most 20,000 source files are read per sync. Each file adds at most 2,000 names, and the vocabulary holds at most 100,000.
  • Unchanged files aren't parsed again. Names are rebuilt when the extractor changes.
  • The vocabulary refreshes on a full sync: at startup, on takeover, on reindex, or on a resync. The file watcher doesn't re-read code between syncs.

scree doctor

doctor reports the vocabulary size and how many names also appear in the notes. doctor -v prints a sample, showing only names that also appear in the notes.

Upgrading

  • The index schema moves to v4. It upgrades automatically when an index is opened, and the next sync fills in the vocabulary.
  • Restart Claude Code sessions, or reconnect scree with /mcp, so they run the new binary. An older binary can still open a v4 index, but it doesn't keep the vocabulary.

Other

  • A test that timed out on slow macOS runners now has a longer deadline.
  • The docs at https://scree.jrpko.dev are updated for this release.

Full changelog: v0.1.0...v0.2.0

Changelog

  • f00d335 Docs: v0.1.0 is cut; drop it from the registry to-do
  • 5dc9a9c Route auto to hybrid on names from the repo's code
  • cc10a9c Tests: give the stale-path writer test 15s
  • eda5346 Vocab: close the markdown-symlink leak and tighten the vocabulary
  • b38c04c Vocab: count a code name only when the notes mention it
  • 27903f2 Vocab: route on the vocabulary alone; gate only doctor's sample
  • 756baa9 Vocab: take names only from name positions

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 24 Oct 16:13

scree v0.1.0

First release. scree gives Claude Code search over a repo's markdown: by meaning, and by exact identifiers. It runs locally as an MCP server, and each repo opts in.

Highlights

  • Per-repo, opt-in. Register scree in a repo's committed .mcp.json with claude mcp add scree --scope project -- scree mcp. Each repo gets its own index, stored outside the repo.
  • Search that fits how docs are used.
    • auto (the default) uses semantic search for plain questions, and adds keyword search when a query contains an identifier like MAX_RETRIES or R7-Q2.
    • semantic, keyword and hybrid are available explicitly. keyword needs no API call.
  • Precise hits.
    • Each result gives its file, heading trail and line range (docs/api.md:486-492).
    • If the file changed since indexing, the range is relocated, or the hit is marked stale.
    • Duplicate copies fold into one hit, listed under also=.
  • Respects your repo.
    • Follows .gitignore with git's rules, including nested files, info/exclude and your global excludes.
    • Indexes markdown in .github/, .claude/, .cursor/ and similar folders at the repo root.
    • Supports .screeignore and scree: ignore front matter.
    • scree run doctor -v shows what's indexed and ignored, with a cost estimate.
  • Stays current. One session per repo indexes in the background and watches for changes; other sessions share the index.
  • Cheap and light. About $0.0025 per MB of markdown to index once, through OpenRouter with zero data retention requested. About 13–20 MB of memory per process. A single static binary.

Install

  • Download the archive for your platform below, or docker pull ghcr.io/jrapakko/scree:0.1.0.
  • Put scree on your PATH (for example ~/.local/bin).
  • Write ~/.config/scree/env (mode 600) containing OPENROUTER_API_KEY='…'.
  • In a repo: claude mcp add scree --scope project -- scree mcp, then commit .mcp.json.

Full guide: https://scree.jrpko.dev/getting-started.html

Security notes

  • The settings file is the only source of configuration. scree mcp re-runs scree with a clean environment.
  • scree takes the indexed folder from where Claude Code started it, refuses folders that haven't opted in, and never indexes your home directory.
  • Approving scree in a repo's .mcp.json means trusting that repo: Claude Code applies the repo's env, including PATH, which decides which program runs. Only approve it in repos you trust. Details: https://scree.jrpko.dev/security.html

Known limitations

  • On Windows, scree mcp and scree run aren't supported yet. Run scree serve directly.
  • On macOS, the binary links the system library dynamically, so DYLD_INSERT_LIBRARIES from a repo's .mcp.json can reach it. That falls within the repo-trust note above.
  • Docker on SELinux hosts needs SCREE_MOUNT_OPTS=ro,z, which relabels the mounted folder.

Checksums are in checksums.txt. Licenses for bundled dependencies are in each archive under THIRD_PARTY_LICENSES/.

Changelog

  • bdd52c9 Add MIT license, CI, and GoReleaser/GHCR release workflow
  • 8c339c0 Docs: match the code before v0.1.0
  • 0fd9bac Fix pass: ignore rules, red-team fixes, ZDR, Docker, key-safe wrappers
  • de7d0a4 Initial scree: semantic search over markdown notes via MCP
  • e76e251 Merge branch 'main' into per-repo
  • d1af508 Merge branch 'main' into per-repo
  • 5ff78d5 README: add Quick start; keep the API key out of shell profiles
  • 107e772 SPEC: record open items, including local and LAN embedding models
  • 1c7d72e Tests: don't expect one watcher event per file on macOS
  • aa579d4 Tests: pass when the temp dir is behind a symlink (macOS)
  • cb88f0a Use invented example identifiers in tests and docs
  • fa35156 Wrappers read the settings file as data; scrub the key before truncating
  • 7f14b84 Wrappers: re-exec once in an empty environment before running anything
  • 41fad78 Wrappers: the settings file is the only source of configuration
  • a337551 per-repo step 4: folder from -notes or CLAUDE_PROJECT_DIR, per-folder index
  • f298b98 per-repo step 4b: canonical on-disk names, NFC and case folding, read races
  • b97e7d1 per-repo step 4c: file rules beat folder negations, looser front matter, search re-checks
  • 66a5ecf per-repo step 5: writer lock per index, background sync in serve, watcher split
  • be4f2d1 per-repo step 5c-1: no symlinked git files, no echoed content, serve uses only the repo
  • a369232 per-repo step 5c-2: FIFO-safe reads, bounded shutdown, trust only your own .git, fast Canonical
  • e526434 per-repo step 6-1: search_docs/read_doc, line ranges, cost estimate, first-sync cap
  • 17bb689 per-repo step 6-2: current line ranges for changed files, duplicate collapse
  • 4def87d per-repo step 6b: hybrid search (FTS5 keyword index + vectors, RRF)
  • c2a2afe per-repo step 7: scree indexes [-prune]
  • 2967301 per-repo step 8: final README and SPEC; settings file always from passwd home
  • 5ba5bc3 per-repo steps 1-3: git-style ignores, hidden-folder allowlist, watcher pruning
  • ee50679 per-repo: final fix round (red-team round 4, final verifier)
  • d56292d policy: let TestUnsafeName run where the filesystem refuses a name
  • 6a575f9 policy: map paths that reach the notes folder through another symlink
  • 0425233 scree mcp / scree run: the launchers move into the static binary
  • fcd92a3 scree-mcp-docker: never pull the image
  • 7c56901 search: auto is the default mode