Metadata-Version: 2.4
Name: hakodesh
Version: 0.2.8
Summary: Host-agnostic empty book: mint spells, enchantments, wards, and combos as you need them.
Author: Shelleyguitar
License-Expression: LicenseRef-Proprietary
Project-URL: Homepage, https://pypi.org/project/hakodesh/
Keywords: cli,sdk,spells,agents,receipts,akashic,grimoire
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: platformdirs<5,>=4.2
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file

# hakodesh

Host-agnostic Python CLI and SDK. After `pip install hakodesh` the user book is empty. Your LLM or agents **mint** spells, enchantments, wards, and combos as they need them.

PyPI name, import, and command: **hakodesh**. Not snax. Not snx.

## Install

```bash
pip install hakodesh
```

Data home: `HAKODESH_HOME` or the platform user-data directory for `hakodesh`. Never `~/spells`.

## Kernel commands

These are the runtime, not starter spells:

| Command | What it does |
|---|---|
| `hakodesh catalog` | User artifacts in the book (empty at install) |
| `hakodesh route "<intent>"` | Rank minted names plus kernel commands |
| `hakodesh invoke <name> [args...]` | Cast a minted spell by name |
| `hakodesh mint <name> --kind spell\|enchantment\|ward\|combo` | Scaffold into the book (preview; `--confirm` writes) |
| `hakodesh akashic` | Verify HMAC chain; `--tail N` |
| `hakodesh grimoire` | Cast ledger stats |
| `hakodesh grimoire-seal` | RFC 6962 Merkle seal (preview; `--confirm` writes; `--verify`) |
| `hakodesh enchant bind\|lift <name> --settings <path>` | Bind or lift a minted enchantment |
| `hakodesh ward status\|lock\|unlock\|check <name>` | Fail-closed ward kernel |
| `hakodesh combo seal\|cast\|list [name]` | Sealed pipelines of minted spells |
| `hakodesh <minted-name> [args...]` | Cast after mint |

`--like` on an empty book uses the **kind template** in the wheel. After one spell exists, `--like <that>` copies its shape.

Every mint and cast emits `hakodesh.event/v1`. Akashic is SHA-256 linked and HMAC-SHA256 signed. Grimoire is Merkle-sealed with the same chain key. The keystore is `$HAKODESH_HOME/keys` (0700/0600), minted on first seal, never in the wheel.

Notifications default to `none`. The package does not write LaunchAgents or editor hooks until you mint and bind an enchantment.

## Hebrew-native names

Artifact names may be lowercase Latin or Hebrew (U+0590–U+05FF), digits and dashes. Every
lookup normalizes to NFC, so a presentation-form or decomposed spelling typed at the shell
matches the stored name. Kernel verbs have Hebrew equivalents via `hakodesh.lexicon`
(`devra קטלגתי` == `devra catalog`; `טבעתי` is a third entry point for `mint`).

```bash
טבעתי mint בדקתי-קנוני --confirm      # mint a Hebrew-named spell -> book/spells/בדקתי_קנוני.py
devra בדקתי-קנוני                      # cast it; receipts land in receipts/בדקתי-קנוני/
```

Wards are fail-closed: `ward check` on an unknown or unreadable ward **denies**. Ward lookup
reads `book/wards/*.json` directly and never executes spell modules, so a broken spell cannot
disable a ward. A spell that fails to import is reported under `catalog()["broken"]` instead
of taking the book down.

## Canonical repo on Google Drive

The source of truth is a bare repo in the Drive folder `GitMirrors/hakodesh.git`
(id `1scHceC8Q43y1wDFyoWenQNjb3RAWbGVi`), moved with rclone — never through the Drive
FileProvider mount, which hangs on file reads. Local checkouts are transient.

```bash
scripts/drive-sync.sh down ~/hakodesh-work   # rclone bare repo -> ~/.cache/hakodesh-sync/canon.git, clone it
# work, commit on main
scripts/drive-sync.sh up   ~/hakodesh-work   # push -> local bare, gc, upload objects first, packed-refs last, verify
rm -rf ~/hakodesh-work                        # nothing canonical lives on the workstation
```

The Drive layout is `packed-refs` plus a loose `refs/heads/main` with the same sha (git needs `refs/` to exist and rclone never creates empty directories); the script writes both from one sha and uploads the loose ref last. Release order: push to Drive, then
`python -m build && twine upload`, so `devra בדקתי-קנוני --accept` can record the head the
published wheel came from.

## SDK

```python
from hakodesh.catalog import catalog
from hakodesh.mint import mint
from hakodesh import events, akashic, grimoire
from hakodesh.enchant import bind, lift
from hakodesh.ward import unlock
from hakodesh.combo import seal, cast
```

## Empty book law

A fresh install has zero user spells, enchantments, wards, or combos. Discovery picks up a file the moment it lands under `HAKODESH_HOME/book/`.
