A DuckDB-backed knowledge layer over your local work that helps LLMs navigate everything
Project description
quack
A DuckDB-backed knowledge layer over your local work — any files: notes, docs,
code, configs, assets — that helps LLMs navigate everything. It generates a
cheap, precise meta layer from your files; you author metadata in one editable
place (.index.yaml), and everything else is derived. Plays well with Obsidian
but does not require it.
PyPI package: quackspace · command: quack
Install
curl -fsSL https://raw.githubusercontent.com/Ocramaru/quackspace/main/install.sh | bash
This installs uv (if needed) and the quack CLI globally. Then create a space
anywhere:
quack init my-workspace # make & scaffold the folder (or `quack init` to use the current one)
cd my-workspace
quack mcp install # connect an LLM (Claude Code, Kiro, …) over MCP
Prefer Python packaging? uv tool install quackspace (or pipx install quackspace) does the same as the one-liner's second step.
Releasing
Releases publish to PyPI via GitHub Actions + Trusted Publishing (no stored
token). One-time: add a PyPI pending publisher (project quackspace, owner
Ocramaru, repo quackspace, workflow publish.yml, environment pypi) and a
GitHub environment named pypi. Then bump version in pyproject.toml, tag,
and publish a GitHub Release — the workflow builds and uploads. Manual fallback:
uv build && uv publish --token <pypi-token>.
Architecture
<your-root>/ ← any directory; quack finds it by the .quack/ marker
├── .quack/ ← the toolkit (and the root marker)
│ ├── GUIDE.md hand-written: how an AI should search the tree
│ ├── map.yaml GENERATED: folder tree + folder descriptions
│ ├── quack.duckdb GENERATED: catalog (files, tags, links, FTS) — the queryable store
│ ├── diagram.md GENERATED: whole-graph Mermaid link diagram
│ ├── config.yaml your AI assistant choice
│ └── src/quack/ the CLI + library
├── .quackignore optional: extra ignore patterns
├── QUACK.md visible navigation anchor for LLMs
├── src/ docs/ notes/ … ANY files: code, configs, markdown, assets
│ ├── .index.yaml EDITABLE: per-file description + tags (links derived)
│ └── _diagrams.md GENERATED: this folder's Mermaid link graph
└── …
One rule: the only thing you edit is each folder's .index.yaml
(description + tags per file; Markdown may also use frontmatter). quack reindex
MERGES it — preserving your text — and regenerates every map, catalog, and
diagram from the files + [[wikilinks]], so the navigation layer can never
drift. The root can be named anything; quack locates it by walking up for
.quack/ (like git finds .git).
The catalog (DuckDB)
quack reindex builds .quack/quack.duckdb, a single embedded catalog of all
metadata: files (name, rel, folder, ext, description, tags_csv, n_links,
n_inbound, is_orphan, is_binary, file_modified, described_at, stale, body),
tags(name, tag), and links(src, dst, dst_exists), plus a BM25 full-text
index over name/description/body. (stale is true when a file changed after its
description was written — see quack generate --stale.)
It is the queryable store and the graph lives here too: the links table
is the edge list, and multi-hop traversal is a recursive CTE behind
quack search and quack graph. There is no separate graph.json: a query
pulls only the relevant slice into context instead of loading the whole graph,
which matters as the tree grows. The catalog is derived, never authoritative;
delete it and quack reindex rebuilds it from the files.
quack sql "SELECT folder, count(*) FROM files GROUP BY folder"
quack sql "SELECT rel FROM files WHERE stale" # descriptions to refresh
quack sql "SELECT src, dst FROM links WHERE NOT dst_exists" # broken links
quack search "regex" --fts # BM25 ranking
quack graph path file-a file-b # shortest link path
The quack command
Once installed (see Install), quack is on your PATH and finds the
root from any directory inside it by walking up for .quack/ — so commands work
no matter where you invoke them. (Developing on a checkout instead? uv run quack inside .quack/ is the equivalent.)
quack init [dir] # create & scaffold a new space (dir, or the current folder)
quack reindex # regenerate everything (indexes, map, catalog, diagrams)
quack reindex --no-diagrams
quack diagram # diagrams only
quack doctor # check files + MCP registration
quack doctor --files # only files; --mcp only MCP; --strict to fail on issues
quack new "Title" -f projects -d "one-line description" -t tag,tag # new markdown note
quack describe PATH -d "…" -t tag,tag # record a description + tags for any file
quack setup # choose the AI assistant (arrow-key menu)
quack generate # AI: write description + tags for files missing one
quack generate --stale # also refresh descriptions whose file changed since
quack search "terms" # auto-hybrid: structural + FTS + semantic + graph
quack search "terms" --fts # force DuckDB BM25 full-text ranking
quack search "terms" --semantic # force vss semantic ranking
quack embed # build semantic embeddings (DuckDB vss)
quack graph path|central|clusters # graph queries
quack sql "SELECT ..." # query the catalog directly
quack mcp install # register the MCP server with clients
quack where # show root / toolkit / command paths
Root resolution: --root > walk up for .quack/ > $QUACK_ROOT >
$OBSIDIAN_VAULT > the package location.
LLM access (MCP)
quack mcp install writes a project-root .mcp.json (the auto-discover
convention Claude Code and others pick up) and offers to register with installed
client CLIs (kiro-cli, claude). The server exposes typed tools, map, search,
get_file, sql, graph_path, central, clusters (read), plus describe
and reindex (write), each returning root so the LLM can join root +
relative path. QUACK.md at the root is a visible anchor telling any LLM how to
navigate even without MCP.
Seeding quack on a repo an agent already knows. Point the MCP server at a
codebase and ask the assistant to annotate it: for each relevant file it calls
describe(path, description, tags) (writing into .index.yaml — the file
itself is untouched), then reindex() once. No per-file model shell-out; the
agent records what it already understands, and the catalog becomes searchable.
AI is optional
The assistant is used for one thing: writing short descriptions + tags for your
files (quack generate) so the search index is rich. quack works fully without
it — you just author descriptions yourself by editing each folder's
.index.yaml.
quack setupshows an arrow-key menu of assistants (kiro-cli, claude, a custom command, or "use without AI"), probes which are installed, and writes the choice to.quack/config.yaml.quack initis an alias that runs it.quack generatefills in missing descriptions using that command. If none is set up, it explains what the AI is for and offers to run setup.- Set
ai.skip: trueinconfig.yamlto use quack without AI permanently;generatethen stops offering to set one up. - Swap assistants anytime by editing
ai.command(use{prompt}for the prompt, or omit it to pipe on stdin) or re-runningquack setup.
Keeping it in sync
Run quack reindex after structural changes. To automate, wire it to one of:
- Obsidian Shell Commands plugin (run on save),
- a git pre-commit hook (
quack doctor --strict --files && quack reindex), - a file-watcher,
quack kiro install(writes a Kiro reindex-on-save hook).
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quackspace-0.1.1.tar.gz.
File metadata
- Download URL: quackspace-0.1.1.tar.gz
- Upload date:
- Size: 37.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a107e93d9986330e4e2c947a152ae99fdaf9e4f9c0e23f31168b0216dbe5d30
|
|
| MD5 |
e954ea814be3e2202af7ca6e0cbb8c2a
|
|
| BLAKE2b-256 |
a294ba008915c5ab640d0e1441bdfa8f81b6bf1778a3fadbf0dae897ac10dd8d
|
File details
Details for the file quackspace-0.1.1-py3-none-any.whl.
File metadata
- Download URL: quackspace-0.1.1-py3-none-any.whl
- Upload date:
- Size: 47.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f010b1a6037ab1323ad1be98ccb0f23b536c838c8ad2eb96c218b915db1920a
|
|
| MD5 |
f5c76ed6bdecdc58beb8b536fdb99bf9
|
|
| BLAKE2b-256 |
15d754b61ba6ed27ffc83d75a92e1d65fae2357f42fb7a59175b7ee660a5b295
|