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 and beta builds
Quack uses uv-native packaging. CI runs uv sync --locked --dev and
uv run pytest tests. Release and beta workflows use uv build, uv version,
and uv publish, following Astral uv’s documented GitHub Actions flow.
For a local beta wheel:
uv version --bump patch --bump dev=$(date -u +%Y%m%d%H%M) --no-sync
uv build --wheel
uv tool install --force dist/quackspace-*.whl
If the beta version should not stay in the checkout, restore or bump the version
before merging. For mainline releases, set a stable version, tag it as vX.Y.Z,
and push the tag. The Publish release to PyPI workflow builds, smoke-tests the
wheel and sdist, then publishes with PyPI Trusted Publishing.
One-time PyPI setup: add a trusted publisher for project quackspace, owner
Ocramaru, repo quackspace, workflow publish.yml, environment pypi, and
create the matching GitHub environment.
For beta artifacts in GitHub, run the Build beta wheel workflow manually. It
uses uv version --bump patch --bump dev=${{ github.run_number }}, builds a dev
wheel, smoke-tests it, and uploads the wheel as an artifact. To push that dev
build to TestPyPI, enable the workflow input and configure a matching TestPyPI
trusted publisher/environment named testpypi.
Architecture
A Quack Space is the workspace root: the directory of files you want agents
to navigate. The installed package provides the quack and quack-mcp
commands; workspace-local state lives under .quack/.
<your-root>/ ← the Quack Space; quack finds it by the .quack/ marker
├── .quack/ ← workspace-local state/config/index data
│ ├── config.yaml your AI assistant and embedding command choices
│ ├── map.yaml GENERATED: full nested folder tree + descriptions/rollups
│ └── quack.duckdb GENERATED: catalog (files, folders, tags, links, FTS) — the queryable store
├── .quackignore optional: extra ignore patterns
├── QUACK.md visible navigation anchor for LLMs
├── src/ docs/ notes/ … ANY files: code, configs, markdown, assets
│ ├── .index.yaml EDITABLE: this folder's direct files: + directories:
│ └── _diagrams.md GENERATED: this folder's Mermaid link graph
└── …
One rule: the only thing you edit is each folder's .index.yaml. It
describes the folder's direct children: a files: section (description +
tags per file; Markdown may also use frontmatter) and a directories: section
for its subfolders — so a folder is described by its parent, just like a file.
Well-known files/folders get a recognition default (authored → frontmatter →
recognition → blank). There is one .index.yaml per folder, including
subdir-only folders and the root. 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). Source code for the tool stays in the
installed package or development checkout, not inside .quack/.
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),
folders(folder, parent, description, n_files, diagram, described_at) — the
direct subfolders of X are WHERE parent = 'X' (root is ''), mirroring the
directories: sections 1:1 — tags(name, tag), and
links(src, dst, dst_exists), plus a BM25 full-text index over
name/description/body. Set index.store_body: false in .quack/config.yaml
and run quack reindex to leave files.body empty and limit catalog full-text
search to names/descriptions. (stale is true when a file changed after its
description was written — see quack generate --stale.) With quack embed,
files and folders get separate vector tables (embeddings and
folder_embeddings); quack search routes where/which-folder questions to the
folder space and keeps file vs folder hits distinct.
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 agent kiro install # install Kiro agent hooks
quack where # show workspace / state / package / command paths
Root resolution: --root > walk up for .quack/ > $QUACK_ROOT >
$OBSIDIAN_VAULT. If none points to a directory containing .quack/, commands
that need a Quack Space fail clearly and tell you to run quack init or pass
--root.
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 agent 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.2.tar.gz.
File metadata
- Download URL: quackspace-0.1.2.tar.gz
- Upload date:
- Size: 148.2 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 |
e60add6d414a5cc2dd0b61a7096482953e09f535ead86250c3c05d744f75f097
|
|
| MD5 |
763408c5de2dc3f7cf2c51b739e90b7f
|
|
| BLAKE2b-256 |
6d642686227634427cfae0d0c8968f3c605833b5ee1b92bb532c4afbc298a94d
|
File details
Details for the file quackspace-0.1.2-py3-none-any.whl.
File metadata
- Download URL: quackspace-0.1.2-py3-none-any.whl
- Upload date:
- Size: 87.1 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 |
fe5b546c1aa525e0e71ad8258cebd249f9d015b911c83b0c9519a9879d5aa606
|
|
| MD5 |
4698899e7b80e38e57c0a4bb61582917
|
|
| BLAKE2b-256 |
70d02d0f7d6f93a134020bdc8d5c0d6ea6f45859bf708f70b7befb81e2a2c2d9
|