shapa 0.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. shapa-0.9.0/AGENTS.md +62 -0
  2. shapa-0.9.0/CHANGELOG.md +81 -0
  3. shapa-0.9.0/LICENSE +21 -0
  4. shapa-0.9.0/MANIFEST.in +18 -0
  5. shapa-0.9.0/PKG-INFO +221 -0
  6. shapa-0.9.0/README.md +189 -0
  7. shapa-0.9.0/pyproject.toml +68 -0
  8. shapa-0.9.0/setup.cfg +4 -0
  9. shapa-0.9.0/shapa/__init__.py +32 -0
  10. shapa-0.9.0/shapa/__main__.py +5 -0
  11. shapa-0.9.0/shapa/assets/AGENTS.md +124 -0
  12. shapa-0.9.0/shapa/assets/arch/index.md +27 -0
  13. shapa-0.9.0/shapa/assets/placement.md +55 -0
  14. shapa-0.9.0/shapa/assets/prompts/reconfigure.md +54 -0
  15. shapa-0.9.0/shapa/assets/skills/shapa-upgrade/SKILL.md +110 -0
  16. shapa-0.9.0/shapa/bm25.py +69 -0
  17. shapa-0.9.0/shapa/bootstrap.py +421 -0
  18. shapa-0.9.0/shapa/capture.py +870 -0
  19. shapa-0.9.0/shapa/cli.py +419 -0
  20. shapa-0.9.0/shapa/commit.py +276 -0
  21. shapa-0.9.0/shapa/config.py +285 -0
  22. shapa-0.9.0/shapa/db.py +855 -0
  23. shapa-0.9.0/shapa/embed.py +173 -0
  24. shapa-0.9.0/shapa/fetch.py +1136 -0
  25. shapa-0.9.0/shapa/frontmatter.py +161 -0
  26. shapa-0.9.0/shapa/get.py +64 -0
  27. shapa-0.9.0/shapa/githooks.py +222 -0
  28. shapa-0.9.0/shapa/heartbeat.py +221 -0
  29. shapa-0.9.0/shapa/ledger.py +864 -0
  30. shapa-0.9.0/shapa/maintain.py +619 -0
  31. shapa-0.9.0/shapa/mcp.py +512 -0
  32. shapa-0.9.0/shapa/memlog.py +1299 -0
  33. shapa-0.9.0/shapa/memri_import.py +212 -0
  34. shapa-0.9.0/shapa/migrate4.py +197 -0
  35. shapa-0.9.0/shapa/nodes.py +160 -0
  36. shapa-0.9.0/shapa/rank.py +153 -0
  37. shapa-0.9.0/shapa/reconfigure.py +184 -0
  38. shapa-0.9.0/shapa/redact.py +117 -0
  39. shapa-0.9.0/shapa/registry.py +231 -0
  40. shapa-0.9.0/shapa/save.py +296 -0
  41. shapa-0.9.0/shapa/score.py +288 -0
  42. shapa-0.9.0/shapa/serve.py +337 -0
  43. shapa-0.9.0/shapa/status.py +387 -0
  44. shapa-0.9.0/shapa/store.py +452 -0
  45. shapa-0.9.0/shapa/upgrade.py +747 -0
  46. shapa-0.9.0/shapa/validate.py +581 -0
  47. shapa-0.9.0/shapa.egg-info/PKG-INFO +221 -0
  48. shapa-0.9.0/shapa.egg-info/SOURCES.txt +50 -0
  49. shapa-0.9.0/shapa.egg-info/dependency_links.txt +1 -0
  50. shapa-0.9.0/shapa.egg-info/entry_points.txt +2 -0
  51. shapa-0.9.0/shapa.egg-info/requires.txt +9 -0
  52. shapa-0.9.0/shapa.egg-info/top_level.txt +1 -0
shapa-0.9.0/AGENTS.md ADDED
@@ -0,0 +1,62 @@
1
+ # shapa-llm
2
+
3
+ Source of the `shapa` tool: an operational-memory engine for LLM agents (one SQLite database per wiki holding the work ledger and memory/rule/issue rows, ranked recall, self-healing maintenance). This file is for agents working on the tool itself. The note schema a wiki follows is `shapa/assets/AGENTS.md`, which `shapa init` installs into every wiki; this repo's own wiki is `.shapa/`.
4
+
5
+ ## Navigation
6
+
7
+ - `shapa/` is the engine package; `cli.py` is the `shapa` command (`python3 -m shapa` from a clone).
8
+ - Wiki resolution and discovery: `config.py`, `registry.py` (`~/.shapa/wikis.json`).
9
+ - Read path: `bootstrap.py` (SessionStart), `fetch.py`, `rank.py`, `bm25.py`, `embed.py`, `get.py`.
10
+ - Database (format 4): `db.py` (schema, work ledger, rows, sweep, worktree resolution), `ledger.py` (`shapa ledger`/`row`/`correction` and the git and harness triggers), `migrate4.py` (format 3 to 4), `commit.py` (`shapa commit`: the wiki commits itself on the default branch, as a SessionEnd/SessionStart hook).
11
+ - Write path: `capture.py` (Stop hook), `redact.py`, `memlog.py` (format-3 log, and the derived index that also mirrors database rows), `save.py`.
12
+ - Index and daemon: `store.py`, `serve.py`. MCP server: `mcp.py`.
13
+ - Maintenance: `maintain.py`, `heartbeat.py`, `score.py`. Format: `frontmatter.py`, `nodes.py`, `validate.py`, `upgrade.py`, `status.py`, `reconfigure.py` (the session-start restructure directive; its prompt is `assets/prompts/reconfigure.md`). Opt-in importer: `memri_import.py`.
14
+ - `shapa/assets/` ships into user wikis: `AGENTS.md` (schema and wiki marker), `placement.md`, the `arch/index.md` template, and `skills/shapa-upgrade` (installed into harnesses, never into a wiki).
15
+ - `tests/` is the pytest suite, with fixtures under `tests/fixtures/`.
16
+ - `install.sh` wires hooks, MCP and the skill from a clone. `bootstrap.sh` is the `curl | sh` installer.
17
+ - `.shapa/` is this repo's wiki: `shapa.db` holds its work ledger and rows (`shapa ledger`, `shapa row list`), `arch/` the design docs.
18
+ - `.github/workflows/test.yml` is CI.
19
+
20
+ ## Owner
21
+
22
+ Roukh (github.com/Roukh/shapa-llm), sole maintainer, MIT license. Commits use the Roukh noreply identity, and pushes need the `Roukh` gh account active (`gh auth status`). Work is tracked in this repo's ledger (`shapa ledger`).
23
+
24
+ ## Commands
25
+
26
+ - Tests: `.venv/bin/python -m pytest -q`. In a network-sandboxed shell, `tests/test_serve.py` (Unix sockets) and `tests/test_installer_upgrade.py` fail; run those outside the sandbox before calling the suite green.
27
+ - CI runs `python -m pytest -q` on Python 3.11, 3.12 and 3.13, once on the bare core install and once with `[semantic,mcp]`.
28
+ - Install the live CLI from this checkout: `uv tool install --force '.[semantic,mcp]'` from the repo root, then `shapa upgrade --all --check`.
29
+ - Health: `shapa doctor` (exits 1 when the install needs a hand - a wiki behind format, this repo's git hooks not wired, no agent harness connected), `shapa status` (same report, never exits 1), `shapa validate`.
30
+ - Before checking a wheel's contents, delete `build/`; a stale one re-ships files removed from `shapa/assets/`.
31
+
32
+ ## Boundaries
33
+
34
+ - The repo is public. Everything tracked, `.shapa/` included, is published on push. Keep secrets, client names, other projects' details and private wiki content out of code, tests, fixtures, notes and commit messages.
35
+ - The core engine stays pure standard library (`dependencies = []` in `pyproject.toml`). A new dependency goes behind an optional extra, and the core path must still work without it.
36
+ - The engine has no hosted-database or hosted-service coupling; its one database is the local `shapa.db` file. Integrations with other systems live outside this repo.
37
+ - Never run `shapa maintain --prune` or a non-dry-run heartbeat against a live wiki from an agent session; use `--dry-run`. Prune is operator-run only.
38
+ - Destructive paths never trust frontmatter an agent wrote: `arch/` is protected by path, and superseded note files move to `archive/`. Database rows are different by design: the after-feature sweep deletes closed, expired, duplicate, superseded and stale rows, and the database file's git history is the record.
39
+ - A wiki database is committed only on the default branch - `shapa commit` does this itself at session end (SessionEnd hook, with SessionStart as a catch-up for a crashed session), scrubbing any configured terms first; `shapa ledger pre-commit` still refuses a manual commit of it elsewhere. Worktrees write and commit through the primary checkout's file.
40
+ - Only `shapa init --global` may write the global wiki pointer (`~/.shapa/config.json`).
41
+ - `capture` and `maintain` run as hooks: they never block a session (always exit 0) and never write inside this repo or the installed package.
42
+ - Tests run against temporary wikis. `tests/conftest.py` points `$SHAPA_REGISTRY` at a throwaway file; never aim the suite at a real wiki.
43
+ - A headless `claude -p` call from the engine passes empty hooks (`--settings '{"hooks":{}}'`) and closed stdin.
44
+
45
+ ## Dependencies
46
+
47
+ - Runtime: Python 3.11 or newer, standard library only.
48
+ - Optional extras: `[semantic]` adds `model2vec>=0.3.0` (the potion-base-8M model, loaded from the local cache with no hub round-trip) for fused vector plus BM25 recall; `[mcp]` adds `mcp>=1.0.0`, and `shapa mcp` falls back to a stdlib JSON-RPC shim without it. `[embeddings]` is a deprecated alias of `[semantic]`.
49
+ - Dev: `pytest`, in the repo's `.venv`.
50
+ - Touched by the installers: Claude Code `settings.json`, `~/.codex/config.toml`, `opencode.json` (merged with `jq`), and Obsidian when present. `maintain --resolve` shells out to the `claude` CLI.
51
+ - State outside the repo: `~/.shapa/config.json` (global pointer), `~/.shapa/wikis.json` (registry), `$SHAPA_MEMORY` (override).
52
+
53
+ ## Contracts
54
+
55
+ Current:
56
+ - A wiki is a `.shapa/` or `shapa/` directory holding `AGENTS.md`, found by walking up from the cwd (`.shapa/` first). `config.memory_dir()` resolves `$SHAPA_MEMORY`, then the discovered wiki, then the pointer, then `~/.shapa/memory`.
57
+ - A bare `shapa init` resolves the git top level (the PRIMARY checkout's, from a linked worktree) and creates `.shapa/` there - or respects a legacy `shapa/` already there - then links this repo's git hooks (`shapa/githooks.py`: never into a shared or hook-manager-owned dir it doesn't own). Only `--global` records the global pointer; `--obsidian` opts into the Obsidian vault.
58
+ - Reads fan out over the global and repo wikis in scope; writes are scope-gated (`save --scope global|repo|external`).
59
+ - Wiki format 4: `shapa.db` (tracked, committed whole) is the source of truth for the work ledger (features, jobs, tasks) and memory/rule/issue rows. `.shapa-index.db` (FTS5, vectors, use counters) is derived and gitignored and mirrors the rows for recall. `arch/` and `research/` stay files; `temp/<feature>/` is gitignored scrap. `.shapa-format` marks a wiki's format, and `shapa upgrade` migrates older wikis.
60
+ - Recall mode is `fused` with `[semantic]` and `bm25` without it, and every surface reports which.
61
+
62
+ Historical (do not resurrect): the format-3 `memory/*.jsonl` log, `checklist.md`, `agenda.md` and `ideas.md` as wiki files (replaced by the database in format 4), memory kept only outside the repo (v0.6), the `uses` frontmatter counter, `sentence-transformers` embeddings, the single repo-root wiki with no global/repo split (2026-07-10), one md note per captured session (before 0.8.0), and a `shapa search` command (0.8.0 has `fetch`). Superseded specs live in git history.
@@ -0,0 +1,81 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+ This project follows [Semantic Versioning](https://semver.org/).
7
+
8
+ ## [0.9.0] - 2026-10-08
9
+
10
+ ### Added
11
+
12
+ - `shapa init`, run inside a git repo, creates `.shapa/` at the git top
13
+ level from any subdirectory. A linked worktree initializes the primary
14
+ checkout. Outside git, `init` stops with a message; `--no-git` creates
15
+ `./.shapa` instead. Obsidian scaffolding is opt-in behind `--obsidian`.
16
+ `init` installs the repo's git pre-commit and post-commit hooks and
17
+ prints what happens next, without touching any file outside `.shapa/`.
18
+ It never writes into a shared or global `core.hooksPath`, or into hooks
19
+ owned by husky, lefthook or the pre-commit framework; it prints the
20
+ lines to add instead.
21
+ - `shapa doctor` checks the global wiki, the repo wiki, git hooks, and
22
+ every connected harness: Claude Code hooks and MCP, Codex MCP, OpenCode
23
+ MCP. It also confirms the `shapa` command resolves, and exits 1 listing
24
+ each problem with its fix command. `shapa status` shows the same
25
+ report.
26
+ - `shapa commit [--hook] [--dry-run] [--json] [--scrub TERM]` commits
27
+ `.shapa/` on the default branch only. It never pushes, touches only
28
+ wiki paths, and leaves other staged work alone. `install.sh` wires it
29
+ to the Claude Code `SessionEnd` hook, plus a `SessionStart` catch-up
30
+ for anything left uncommitted from a prior session. `install.sh
31
+ --no-auto-commit` opts out. An optional `scrub_terms` list in
32
+ `~/.shapa/config.json` redacts matching terms before a commit.
33
+ - Trusted publishing to PyPI: tagging a release (`vX.Y.Z`) and publishing
34
+ it on GitHub builds the sdist and wheel and uploads them with no
35
+ stored token.
36
+ - A real README: install paths, a 60-second quickstart, how shapa works,
37
+ a harness support matrix, and a comparison against other agent memory
38
+ tools.
39
+ - `CONTRIBUTING.md`, `SECURITY.md`, issue templates and a pull request
40
+ template.
41
+
42
+ ### Changed
43
+
44
+ - `pyproject.toml` metadata (description, keywords, classifiers, project
45
+ URLs) now describes what shapa does today, not the pre-format-4 tool.
46
+ - A bare `shapa init` no longer creates a visible `shapa/` in the current
47
+ directory; an existing `shapa/` wiki at the top level is still used.
48
+
49
+ ### Fixed
50
+
51
+ - `shapa ledger git-hooks` wrote its hooks into whatever `core.hooksPath`
52
+ pointed at, including a machine-wide hooks directory shared by every
53
+ repo. It now writes only inside the repo's own git directory.
54
+ - `shapa doctor` reported "problems: none" with no global wiki and no
55
+ harness connected.
56
+ - The default branch is detected from branches that exist in the repo, so
57
+ a machine-wide `init.defaultBranch` naming another branch no longer
58
+ blocks the database on the real default branch.
59
+
60
+ ## [0.8.0] - 2026-10-06
61
+
62
+ ### Added
63
+
64
+ - Wiki format 4: one SQLite database per wiki (`shapa.db`), replacing the
65
+ format-3 Markdown log. It holds the work ledger (features, jobs,
66
+ tasks) and memory, rule and issue rows; a derived, gitignored
67
+ `.shapa-index.db` carries the search index and vectors.
68
+ - The work ledger: `F` features (a branch and a PR), `J` jobs (one
69
+ commit whose subject starts `J<n>:`), and `T` tasks. `shapa ledger`
70
+ adds, claims, closes and shows a tree of ledger items.
71
+ - Git hooks for the ledger: a `pre-commit` hook refuses to commit
72
+ `shapa.db` outside the default branch, and a `post-commit` hook closes
73
+ the job a commit's subject names.
74
+ - A sweep after every merged feature deletes closed, expired, duplicate,
75
+ superseded and stale rows; the database's git history keeps the record.
76
+ - Correction capture now stores only the operator's own words as issue
77
+ rows, never a harness's restatement of them.
78
+ - A resumable `shapa upgrade` path from format 3 to format 4.
79
+
80
+ Related research and design notes live under `.shapa/arch/` and
81
+ `.shapa/research/` in this repository's own wiki.
shapa-0.9.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Roukh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to
7
+ deal in the Software without restriction, including without limitation the
8
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9
+ sell copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,18 @@
1
+ # What ships in the sdist, on top of the `shapa` package itself (see
2
+ # [tool.setuptools.package-data] in pyproject.toml for what ships inside
3
+ # the package). Without this file, setuptools' default sdist file list
4
+ # picks up stray top-level `test*.py` files by name pattern - this repo's
5
+ # `tests/` directory needs its `conftest.py` and `fixtures/` to run at all,
6
+ # so a partial copy is worse than none; `prune` drops the whole directory.
7
+ include LICENSE
8
+ include README.md
9
+ include CHANGELOG.md
10
+ include AGENTS.md
11
+
12
+ prune tests
13
+ prune .shapa
14
+ prune .worktrees
15
+ prune .github
16
+
17
+ global-exclude __pycache__
18
+ global-exclude *.py[cod]
shapa-0.9.0/PKG-INFO ADDED
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.4
2
+ Name: shapa
3
+ Version: 0.9.0
4
+ Summary: Memory and a work ledger for coding agents, in one SQLite file per wiki, with harness hooks for Claude Code, Codex and OpenCode.
5
+ Author: Roukh
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Roukh/shapa-llm
8
+ Project-URL: Repository, https://github.com/Roukh/shapa-llm
9
+ Project-URL: Issues, https://github.com/Roukh/shapa-llm/issues
10
+ Project-URL: Changelog, https://github.com/Roukh/shapa-llm/blob/main/CHANGELOG.md
11
+ Keywords: llm,agent,memory,coding-agent,work-ledger,sqlite,claude-code,codex,mcp
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: License :: OSI Approved :: MIT License
20
+ Classifier: Operating System :: OS Independent
21
+ Classifier: Topic :: Software Development
22
+ Requires-Python: >=3.11
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Provides-Extra: semantic
26
+ Requires-Dist: model2vec>=0.3.0; extra == "semantic"
27
+ Provides-Extra: embeddings
28
+ Requires-Dist: model2vec>=0.3.0; extra == "embeddings"
29
+ Provides-Extra: mcp
30
+ Requires-Dist: mcp>=1.0.0; extra == "mcp"
31
+ Dynamic: license-file
32
+
33
+ # shapa
34
+
35
+ [![tests](https://github.com/Roukh/shapa-llm/actions/workflows/test.yml/badge.svg)](https://github.com/Roukh/shapa-llm/actions/workflows/test.yml)
36
+ [![PyPI](https://img.shields.io/pypi/v/shapa.svg)](https://pypi.org/project/shapa/)
37
+ [![Python versions](https://img.shields.io/pypi/pyversions/shapa.svg)](https://pypi.org/project/shapa/)
38
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
39
+
40
+ shapa gives a coding agent memory and a work ledger that live in one SQLite
41
+ file per project, checked into git, with hooks for Claude Code, Codex and
42
+ OpenCode.
43
+
44
+ ## Install
45
+
46
+ Once shapa is on PyPI:
47
+
48
+ ```bash
49
+ uv tool install 'shapa[semantic,mcp]'
50
+ # or
51
+ pipx install shapa
52
+ ```
53
+
54
+ Until then, install straight from GitHub:
55
+
56
+ ```bash
57
+ curl -fsSL https://raw.githubusercontent.com/Roukh/shapa-llm/main/bootstrap.sh | sh
58
+ ```
59
+
60
+ `bootstrap.sh` installs the `shapa` command (pipx, then uv, then `pip
61
+ --user`) and wires Claude Code's hooks. Pass `--with-semantic`, `--with-mcp`
62
+ or `--full` to add the optional extras up front; see the comments at the top
63
+ of the script for every flag and environment variable.
64
+
65
+ ## 60-second quickstart
66
+
67
+ ```bash
68
+ # 1. Install shapa (see above).
69
+
70
+ # 2. In a git repo, create its wiki:
71
+ cd your-project
72
+ shapa init
73
+
74
+ # 3. Check that everything is wired correctly:
75
+ shapa doctor
76
+
77
+ # 4. Start your agent as usual. In Claude Code, shapa's hooks load memory
78
+ # at session start and on every prompt; Codex and OpenCode reach the
79
+ # same memory through shapa's MCP tools.
80
+ ```
81
+
82
+ `shapa init` finds the git top level, creates `.shapa/` there and nothing
83
+ else, and installs two git hooks: `pre-commit` keeps the database off
84
+ feature branches, and `post-commit` closes the job a `J<n>:` commit names.
85
+ It never writes into a machine-wide `core.hooksPath` or into hooks owned by
86
+ husky, lefthook or the pre-commit framework; it prints the lines to add
87
+ there instead.
88
+
89
+ ## What it does
90
+
91
+ - Surfaces relevant memory at session start and injects more on every
92
+ prompt, ranked by relevance.
93
+ - Turns an operator's correction ("no", "wrong", "not like this") into an
94
+ attributed issue row, not a buried chat line.
95
+ - Tracks work as a three-level ledger: a feature (`F`, a new capability
96
+ with its own branch and PR) holds jobs (`J`, one commit each), and a job
97
+ holds tasks (`T`). Fixes, docs and release work are standalone jobs that
98
+ share one batch branch and PR per session. A commit whose subject starts
99
+ `J<n>:` closes that job automatically.
100
+ - Sweeps the database after every merged feature: closed, expired,
101
+ duplicate, superseded and stale rows are deleted, and the database's git
102
+ history keeps the record.
103
+ - Commits `.shapa/` on the default branch at the end of each Claude Code
104
+ session (`shapa commit`), so a clone of the repo carries its memory. It
105
+ commits only wiki paths and never pushes.
106
+
107
+ ## How it works
108
+
109
+ ```mermaid
110
+ flowchart LR
111
+ subgraph Harness
112
+ H["Claude Code / Codex / OpenCode\n(hooks or MCP)"]
113
+ end
114
+ H --> CLI["shapa CLI"]
115
+ CLI --> DB[("shapa.db\ntracked in git")]
116
+ CLI --> IDX[(".shapa-index.db\ngitignored, derived")]
117
+ DB -.rebuilds.-> IDX
118
+ CLI --> GW["global wiki\n~/.shapa/memory"]
119
+ CLI --> RW["repo wiki\n.shapa/"]
120
+ ```
121
+
122
+ A repo's wiki is `.shapa/` at its git top level; the global wiki defaults to
123
+ `~/.shapa/memory`. Each holds `shapa.db`: the work ledger plus memory, rule
124
+ and issue rows. A second file, `.shapa-index.db`, holds the search index and
125
+ vectors; it is derived from `shapa.db`, gitignored, and rebuilt on demand. A
126
+ session reads from the global wiki and the current repo's wiki together, and
127
+ writes are scoped to one or the other.
128
+
129
+ ## Harness support
130
+
131
+ | Harness | Hooks | MCP |
132
+ |---|---|---|
133
+ | Claude Code | yes | yes |
134
+ | Codex | no | yes |
135
+ | OpenCode | no | yes |
136
+ | anything else that speaks MCP | no | by hand (see `shapa mcp`) |
137
+
138
+ Hooked harnesses get memory pushed to them automatically; any MCP client can
139
+ pull the same `search`, `get` and `save` tools by registering `shapa mcp` as
140
+ a stdio server itself.
141
+
142
+ ## How it compares
143
+
144
+ Figures below are each project's own numbers, checked in October 2026; they
145
+ move fast and several benchmark claims in this space are disputed.
146
+
147
+ | Tool | Storage | Git-tracked | Work ledger | License |
148
+ |---|---|---|---|---|
149
+ | **shapa** | one SQLite file per wiki | yes, on the default branch | yes (F/J/T) | MIT |
150
+ | claude-mem | SQLite plus Chroma | no | no | Apache-2.0 |
151
+ | mem0 + OpenMemory MCP | vector DB plus graph | no | no | Apache-2.0 |
152
+ | basic-memory | Markdown plus wikilinks, Obsidian sync | if you commit the files | no | AGPL-3.0 |
153
+ | beads | Dolt, JSONL export | yes | yes (dependency graph, not memory) | MIT |
154
+ | native harness memory (Claude Code, Codex, Cursor, ...) | machine-local files | no | no | - |
155
+
156
+ None of the native, per-harness memory features are git-tracked, shared
157
+ across harnesses, split into a global and a repo tier, or tied to a work
158
+ ledger. The trade-off: a SQLite file does not diff or merge like Markdown,
159
+ which is why shapa commits it only on the default branch.
160
+
161
+ ## Commands
162
+
163
+ | Command | Does |
164
+ |---|---|
165
+ | `shapa init [DIR] [--no-git] [--obsidian] [--global]` | create and register a wiki, with git hooks in a repo |
166
+ | `shapa doctor` | check the whole install; exits 1 with a fix command per problem |
167
+ | `shapa status` | the same report as `doctor`, without the exit code |
168
+ | `shapa commit [--hook] [--dry-run] [--json] [--scrub TERM]` | commit `.shapa/` on the default branch |
169
+ | `shapa bootstrap` | session-start overview of every wiki in scope |
170
+ | `shapa fetch` | rank and surface memory relevant to a prompt |
171
+ | `shapa get ID` | print a row's or a note's full text |
172
+ | `shapa save` | write one note or row (`--scope global\|repo\|external`) |
173
+ | `shapa row add\|edit\|rm\|link\|tag\|list` | manage memory, rule and issue rows |
174
+ | `shapa ledger add\|claim\|close\|tree\|issues` | manage the work ledger |
175
+ | `shapa correction` | record an operator correction as an issue row |
176
+ | `shapa maintain [--prune] [--dry-run]` | self-heal: merge duplicates, prune stale and orphaned rows |
177
+ | `shapa validate` | check note and wiki frontmatter |
178
+ | `shapa upgrade [--all] [--check]` | bring a wiki to the current format |
179
+ | `shapa mcp` | run the MCP stdio server (`search`, `get`, `save`, `placement`) |
180
+ | `shapa serve` | run the optional warm per-wiki daemon |
181
+
182
+ Run `shapa` with no arguments for the full, versioned usage text.
183
+
184
+ ## Files and privacy
185
+
186
+ Everything shapa reads or writes stays on disk, in files you own:
187
+
188
+ - `~/.shapa/config.json` and `~/.shapa/wikis.json`: the global wiki pointer
189
+ and the registry of known wikis.
190
+ - `~/.shapa/memory/`: the global wiki, unless `shapa init --global DIR`
191
+ put it elsewhere.
192
+ - `<repo>/.shapa/shapa.db`: that repo's wiki, tracked in git.
193
+ - `<repo>/.shapa/.shapa-index.db`: the derived search index, gitignored.
194
+
195
+ There is no hosted service and no account, and shapa makes no network calls
196
+ of its own. Two exceptions you opt into: the `[semantic]` extra downloads
197
+ its embedding model once, and session distillation
198
+ (`SHAPA_CAPTURE_DISTILL=1`) and `shapa maintain --resolve` run the `claude`
199
+ CLI you already use. The core engine has no dependencies beyond the Python
200
+ standard library.
201
+
202
+ ## Configuration
203
+
204
+ - `$SHAPA_MEMORY` overrides the resolved wiki directory for one process.
205
+ - `[semantic]` extra (`model2vec`) turns on local embeddings for fetch and
206
+ maintain; without it, shapa uses BM25 and token overlap.
207
+ - `[mcp]` extra (`mcp`) upgrades `shapa mcp` to the reference MCP SDK; it
208
+ works without the extra too, through a standard-library JSON-RPC shim.
209
+ - `scrub_terms` in `~/.shapa/config.json`: an optional list of terms
210
+ `shapa commit` redacts before committing `.shapa/`.
211
+ - `install.sh --no-auto-commit` skips wiring `shapa commit` into Claude
212
+ Code's session hooks; run `shapa commit` yourself instead.
213
+
214
+ ## Development
215
+
216
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the dev setup, the test matrix
217
+ and the house rules this project runs on.
218
+
219
+ ## License
220
+
221
+ MIT, see [LICENSE](LICENSE).
shapa-0.9.0/README.md ADDED
@@ -0,0 +1,189 @@
1
+ # shapa
2
+
3
+ [![tests](https://github.com/Roukh/shapa-llm/actions/workflows/test.yml/badge.svg)](https://github.com/Roukh/shapa-llm/actions/workflows/test.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/shapa.svg)](https://pypi.org/project/shapa/)
5
+ [![Python versions](https://img.shields.io/pypi/pyversions/shapa.svg)](https://pypi.org/project/shapa/)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
+
8
+ shapa gives a coding agent memory and a work ledger that live in one SQLite
9
+ file per project, checked into git, with hooks for Claude Code, Codex and
10
+ OpenCode.
11
+
12
+ ## Install
13
+
14
+ Once shapa is on PyPI:
15
+
16
+ ```bash
17
+ uv tool install 'shapa[semantic,mcp]'
18
+ # or
19
+ pipx install shapa
20
+ ```
21
+
22
+ Until then, install straight from GitHub:
23
+
24
+ ```bash
25
+ curl -fsSL https://raw.githubusercontent.com/Roukh/shapa-llm/main/bootstrap.sh | sh
26
+ ```
27
+
28
+ `bootstrap.sh` installs the `shapa` command (pipx, then uv, then `pip
29
+ --user`) and wires Claude Code's hooks. Pass `--with-semantic`, `--with-mcp`
30
+ or `--full` to add the optional extras up front; see the comments at the top
31
+ of the script for every flag and environment variable.
32
+
33
+ ## 60-second quickstart
34
+
35
+ ```bash
36
+ # 1. Install shapa (see above).
37
+
38
+ # 2. In a git repo, create its wiki:
39
+ cd your-project
40
+ shapa init
41
+
42
+ # 3. Check that everything is wired correctly:
43
+ shapa doctor
44
+
45
+ # 4. Start your agent as usual. In Claude Code, shapa's hooks load memory
46
+ # at session start and on every prompt; Codex and OpenCode reach the
47
+ # same memory through shapa's MCP tools.
48
+ ```
49
+
50
+ `shapa init` finds the git top level, creates `.shapa/` there and nothing
51
+ else, and installs two git hooks: `pre-commit` keeps the database off
52
+ feature branches, and `post-commit` closes the job a `J<n>:` commit names.
53
+ It never writes into a machine-wide `core.hooksPath` or into hooks owned by
54
+ husky, lefthook or the pre-commit framework; it prints the lines to add
55
+ there instead.
56
+
57
+ ## What it does
58
+
59
+ - Surfaces relevant memory at session start and injects more on every
60
+ prompt, ranked by relevance.
61
+ - Turns an operator's correction ("no", "wrong", "not like this") into an
62
+ attributed issue row, not a buried chat line.
63
+ - Tracks work as a three-level ledger: a feature (`F`, a new capability
64
+ with its own branch and PR) holds jobs (`J`, one commit each), and a job
65
+ holds tasks (`T`). Fixes, docs and release work are standalone jobs that
66
+ share one batch branch and PR per session. A commit whose subject starts
67
+ `J<n>:` closes that job automatically.
68
+ - Sweeps the database after every merged feature: closed, expired,
69
+ duplicate, superseded and stale rows are deleted, and the database's git
70
+ history keeps the record.
71
+ - Commits `.shapa/` on the default branch at the end of each Claude Code
72
+ session (`shapa commit`), so a clone of the repo carries its memory. It
73
+ commits only wiki paths and never pushes.
74
+
75
+ ## How it works
76
+
77
+ ```mermaid
78
+ flowchart LR
79
+ subgraph Harness
80
+ H["Claude Code / Codex / OpenCode\n(hooks or MCP)"]
81
+ end
82
+ H --> CLI["shapa CLI"]
83
+ CLI --> DB[("shapa.db\ntracked in git")]
84
+ CLI --> IDX[(".shapa-index.db\ngitignored, derived")]
85
+ DB -.rebuilds.-> IDX
86
+ CLI --> GW["global wiki\n~/.shapa/memory"]
87
+ CLI --> RW["repo wiki\n.shapa/"]
88
+ ```
89
+
90
+ A repo's wiki is `.shapa/` at its git top level; the global wiki defaults to
91
+ `~/.shapa/memory`. Each holds `shapa.db`: the work ledger plus memory, rule
92
+ and issue rows. A second file, `.shapa-index.db`, holds the search index and
93
+ vectors; it is derived from `shapa.db`, gitignored, and rebuilt on demand. A
94
+ session reads from the global wiki and the current repo's wiki together, and
95
+ writes are scoped to one or the other.
96
+
97
+ ## Harness support
98
+
99
+ | Harness | Hooks | MCP |
100
+ |---|---|---|
101
+ | Claude Code | yes | yes |
102
+ | Codex | no | yes |
103
+ | OpenCode | no | yes |
104
+ | anything else that speaks MCP | no | by hand (see `shapa mcp`) |
105
+
106
+ Hooked harnesses get memory pushed to them automatically; any MCP client can
107
+ pull the same `search`, `get` and `save` tools by registering `shapa mcp` as
108
+ a stdio server itself.
109
+
110
+ ## How it compares
111
+
112
+ Figures below are each project's own numbers, checked in October 2026; they
113
+ move fast and several benchmark claims in this space are disputed.
114
+
115
+ | Tool | Storage | Git-tracked | Work ledger | License |
116
+ |---|---|---|---|---|
117
+ | **shapa** | one SQLite file per wiki | yes, on the default branch | yes (F/J/T) | MIT |
118
+ | claude-mem | SQLite plus Chroma | no | no | Apache-2.0 |
119
+ | mem0 + OpenMemory MCP | vector DB plus graph | no | no | Apache-2.0 |
120
+ | basic-memory | Markdown plus wikilinks, Obsidian sync | if you commit the files | no | AGPL-3.0 |
121
+ | beads | Dolt, JSONL export | yes | yes (dependency graph, not memory) | MIT |
122
+ | native harness memory (Claude Code, Codex, Cursor, ...) | machine-local files | no | no | - |
123
+
124
+ None of the native, per-harness memory features are git-tracked, shared
125
+ across harnesses, split into a global and a repo tier, or tied to a work
126
+ ledger. The trade-off: a SQLite file does not diff or merge like Markdown,
127
+ which is why shapa commits it only on the default branch.
128
+
129
+ ## Commands
130
+
131
+ | Command | Does |
132
+ |---|---|
133
+ | `shapa init [DIR] [--no-git] [--obsidian] [--global]` | create and register a wiki, with git hooks in a repo |
134
+ | `shapa doctor` | check the whole install; exits 1 with a fix command per problem |
135
+ | `shapa status` | the same report as `doctor`, without the exit code |
136
+ | `shapa commit [--hook] [--dry-run] [--json] [--scrub TERM]` | commit `.shapa/` on the default branch |
137
+ | `shapa bootstrap` | session-start overview of every wiki in scope |
138
+ | `shapa fetch` | rank and surface memory relevant to a prompt |
139
+ | `shapa get ID` | print a row's or a note's full text |
140
+ | `shapa save` | write one note or row (`--scope global\|repo\|external`) |
141
+ | `shapa row add\|edit\|rm\|link\|tag\|list` | manage memory, rule and issue rows |
142
+ | `shapa ledger add\|claim\|close\|tree\|issues` | manage the work ledger |
143
+ | `shapa correction` | record an operator correction as an issue row |
144
+ | `shapa maintain [--prune] [--dry-run]` | self-heal: merge duplicates, prune stale and orphaned rows |
145
+ | `shapa validate` | check note and wiki frontmatter |
146
+ | `shapa upgrade [--all] [--check]` | bring a wiki to the current format |
147
+ | `shapa mcp` | run the MCP stdio server (`search`, `get`, `save`, `placement`) |
148
+ | `shapa serve` | run the optional warm per-wiki daemon |
149
+
150
+ Run `shapa` with no arguments for the full, versioned usage text.
151
+
152
+ ## Files and privacy
153
+
154
+ Everything shapa reads or writes stays on disk, in files you own:
155
+
156
+ - `~/.shapa/config.json` and `~/.shapa/wikis.json`: the global wiki pointer
157
+ and the registry of known wikis.
158
+ - `~/.shapa/memory/`: the global wiki, unless `shapa init --global DIR`
159
+ put it elsewhere.
160
+ - `<repo>/.shapa/shapa.db`: that repo's wiki, tracked in git.
161
+ - `<repo>/.shapa/.shapa-index.db`: the derived search index, gitignored.
162
+
163
+ There is no hosted service and no account, and shapa makes no network calls
164
+ of its own. Two exceptions you opt into: the `[semantic]` extra downloads
165
+ its embedding model once, and session distillation
166
+ (`SHAPA_CAPTURE_DISTILL=1`) and `shapa maintain --resolve` run the `claude`
167
+ CLI you already use. The core engine has no dependencies beyond the Python
168
+ standard library.
169
+
170
+ ## Configuration
171
+
172
+ - `$SHAPA_MEMORY` overrides the resolved wiki directory for one process.
173
+ - `[semantic]` extra (`model2vec`) turns on local embeddings for fetch and
174
+ maintain; without it, shapa uses BM25 and token overlap.
175
+ - `[mcp]` extra (`mcp`) upgrades `shapa mcp` to the reference MCP SDK; it
176
+ works without the extra too, through a standard-library JSON-RPC shim.
177
+ - `scrub_terms` in `~/.shapa/config.json`: an optional list of terms
178
+ `shapa commit` redacts before committing `.shapa/`.
179
+ - `install.sh --no-auto-commit` skips wiring `shapa commit` into Claude
180
+ Code's session hooks; run `shapa commit` yourself instead.
181
+
182
+ ## Development
183
+
184
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the dev setup, the test matrix
185
+ and the house rules this project runs on.
186
+
187
+ ## License
188
+
189
+ MIT, see [LICENSE](LICENSE).
@@ -0,0 +1,68 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "shapa"
7
+ version = "0.9.0"
8
+ description = "Memory and a work ledger for coding agents, in one SQLite file per wiki, with harness hooks for Claude Code, Codex and OpenCode."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Roukh" }]
13
+ keywords = [
14
+ "llm",
15
+ "agent",
16
+ "memory",
17
+ "coding-agent",
18
+ "work-ledger",
19
+ "sqlite",
20
+ "claude-code",
21
+ "codex",
22
+ "mcp",
23
+ ]
24
+ classifiers = [
25
+ "Development Status :: 4 - Beta",
26
+ "Environment :: Console",
27
+ "Intended Audience :: Developers",
28
+ "Programming Language :: Python :: 3",
29
+ "Programming Language :: Python :: 3.11",
30
+ "Programming Language :: Python :: 3.12",
31
+ "Programming Language :: Python :: 3.13",
32
+ "License :: OSI Approved :: MIT License",
33
+ "Operating System :: OS Independent",
34
+ "Topic :: Software Development",
35
+ ]
36
+ dependencies = [] # core engine is pure standard library
37
+
38
+ [project.optional-dependencies]
39
+ # Activates local semantic embeddings for fetch + maintain (else BM25/Jaccard).
40
+ # `semantic` is the current name (shapa-backend-spec.md §3); `embeddings` is
41
+ # kept as a deprecated alias with identical deps for one release. model2vec
42
+ # (potion-base-8M) replaces sentence-transformers as of Slice 6: numpy-only,
43
+ # no torch, ~94.7% of MiniLM's MTEB at a fraction of the install/latency cost.
44
+ semantic = ["model2vec>=0.3.0"]
45
+ embeddings = ["model2vec>=0.3.0"]
46
+ # The MCP stdio server (shapa/mcp.py, shapa-backend-spec.md §7.1, Slice 6).
47
+ # The official SDK is optional even with this extra installed: shapa/mcp.py
48
+ # falls back to a stdlib-only JSON-RPC shim (the same wire protocol a real
49
+ # MCP client speaks over stdio) whenever it is absent, so `shapa mcp` always
50
+ # works, extra or not - this just upgrades it to the reference SDK surface.
51
+ mcp = ["mcp>=1.0.0"]
52
+
53
+ [project.scripts]
54
+ shapa = "shapa.cli:main"
55
+
56
+ [project.urls]
57
+ Homepage = "https://github.com/Roukh/shapa-llm"
58
+ Repository = "https://github.com/Roukh/shapa-llm"
59
+ Issues = "https://github.com/Roukh/shapa-llm/issues"
60
+ Changelog = "https://github.com/Roukh/shapa-llm/blob/main/CHANGELOG.md"
61
+
62
+ [tool.setuptools]
63
+ packages = ["shapa"]
64
+
65
+ [tool.setuptools.package-data]
66
+ # Design docs (arch/ + AGENTS.md) shipped with the tool and installed into a
67
+ # wiki by `shapa init`.
68
+ shapa = ["assets/*.md", "assets/arch/*.md", "assets/skills/*/SKILL.md", "assets/prompts/*.md"]
shapa-0.9.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+