Skip to main content

A minimal placeholder package for the future Ritebook project.

Project description

ritebook

Ritebook is a Python CLI for validating, publishing, registering, browsing, and installing Agent Skill indexes. It supports publisher workflows that generate reviewable ritebook-index.json files and consumer workflows that install skills from registered Git-backed indexes.

Requirements

  • Python 3.13 or newer
  • uv for dependency management and command execution

Development setup

Install development dependencies:

uv sync --group dev

Install the Git pre-commit hook:

uv run pre-commit install

Run the pre-commit hooks across the full repository when changing the hook configuration or before opening a PR:

uv run pre-commit run --all-files

Pre-commit provides fast local feedback for file hygiene, Ruff formatting and linting, and ty type checking. It complements, but does not replace, the full local quality gate.

Run local quality checks:

uv run ruff format .
uv run ruff check .
uv run ty check src/ritebook
uv run pytest -m "not e2e"

Run E2E tests directly when iterating on the black-box CLI workflow:

uv run pytest tests/e2e -q

Run the mandatory clean-room Docker E2E gate before handoff:

docker build -f Dockerfile.e2e -t ritebook-e2e .
docker run --rm ritebook-e2e

Dockerfile.e2e is a clean-room end-to-end test boundary, not production packaging. The Docker runner verifies the publisher-to-consumer CLI workflow using local Git repositories, explicit registry files, and explicit cache directories without relying on developer-local Ritebook state. CI/CD runs Docker E2E as a mandatory quality gate in parallel with the non-E2E quality checks.

Build the package distributions:

uv build

Publisher skill index generation

Maintainers can validate skill headers and generate a reviewable skill catalog index from an explicit skills root:

uv run ritebook lint-skills --skills-root <path>

The lint-skills command recursively discovers SKILL.md files under the skills root and validates their required Agent Skill headers without writing an index file.

uv run ritebook publish-index --skills-root <path> --index-name <name>

The --skills-root option is required so the command only scans the intended skills directory. The --index-name option is required and must be a stable index name, either a kebab-case identifier such as company-skills or an owner/repository-style name such as ondrej-winter/ritebook-shelf; it is written to the generated index metadata as the default consumer registry name. The publish-index command reuses the same validation flow as lint-skills and refuses to write or overwrite ritebook-index.json when any discovered skill is invalid. When validation succeeds, Ritebook writes the canonical index file ritebook-index.json in the current working directory.

Review the generated ritebook-index.json before committing it with the related skill changes.

Consumer index registry

Users can register, refresh, browse, and install skills from Git-backed Ritebook skill indexes.

Register a Git URL source:

uv run ritebook add-index --source git@github.com:company/internal-skills.git

Register an already-cloned local Git repository without Ritebook mutating it:

uv run ritebook add-index --source ./internal-skills

Override the local effective index name or replace an existing registration:

uv run ritebook add-index \
  --source git@github.com:company/internal-skills.git \
  --name platform-skills \
  --force

Refresh a registered index from its remembered Git source:

uv run ritebook update-index --name platform-skills

List skills from all locally cached registered indexes:

uv run ritebook list-skills

List skills from one effective index name:

uv run ritebook list-skills --index-name platform-skills

Show cached skill descriptions when available:

uv run ritebook list-skills --show-description

The list-skills command is offline-first: it reads the local registry and each selected registry entry's cached ritebook-index.json file only. It does not clone, fetch, pull, scan publisher skill directories, or read raw SKILL.md files.

Non-empty output is grouped by effective index name in a deterministic tree:

Indexes
├── platform-skills
│   ├── skill-a
│   └── skill-b
└── data-skills
    └── query-helper

By default, the tree shows skill names only. With --show-description, Ritebook appends descriptions cached from publisher indexes when that metadata is present:

Indexes
└── platform-skills
    └── skill-a — Helps with platform workflows.

When no registered cached skills are available, Ritebook prints:

No skills found

Consumer skill installation

Ritebook installs skills from already registered and cached indexes. Installation commands are offline-first: they read the local registry and cached ritebook-index.json files, then copy skill directories from the remembered source repository path or managed local clone. They do not clone, fetch, pull, or mutate source repositories. Run update-index first when you want to refresh the cached index and managed Git clone before installing.

Install one fully qualified skill into an explicit target path:

uv run ritebook install-skill platform-skills/code-review \
  --target .claude/skills/code-review

Ritebook copies the whole skill directory, creates missing target parent directories, and refuses to overwrite an existing target unless --force is provided:

uv run ritebook install-skill platform-skills/code-review \
  --target .claude/skills/code-review \
  --force

Direct install-skill runs write generated user-level installation state to:

~/.config/ritebook/installations.json

Tests and automation can override both the index registry and direct-install state paths:

uv run ritebook install-skill platform-skills/code-review \
  --target .claude/skills/code-review \
  --registry-path <path-to-indexes.json> \
  --installation-registry-path <path-to-installations.json>

Repositories can declare repeatable skill installations in ritebook.toml:

[targets]
claude = ".claude/skills"
agents = ".agents/skills"

[[skills]]
name = "platform-skills/code-review"
target = "claude"

[[skills]]
name = "platform-skills/test-driven-development"
target = "agents"

[[skills]]
name = "company-agents/security-review"
target_path = "../shared-agent-skills/security-review"

Install all declared skills from the default ritebook.toml in the current working directory:

uv run ritebook install

Use --file to read a different requirements file, --force to replace existing target directories, and --lockfile to choose where generated lock state is written:

uv run ritebook install \
  --file path/to/ritebook.toml \
  --force \
  --registry-path <path-to-indexes.json> \
  --lockfile <path-to-ritebook.lock>

target = "nickname" resolves to <targets.nickname>/<skill-name>. target_path is used exactly as the target path for that skill entry. Each skill entry must use exactly one of target or target_path.

After a successful requirements install, Ritebook writes deterministic generated state to ritebook.lock by default. Commit ritebook.lock when a repository uses ritebook.toml so repo-local skill installation state is reviewable and repeatable.

By default, Ritebook stores registry metadata and cached index contents under:

~/.config/ritebook/indexes.json
~/.cache/ritebook/indexes/<effective-index-name>/ritebook-index.json
~/.cache/ritebook/git/<source-cache-id>/

When an effective index name includes an owner separator, Ritebook keeps the registry name unchanged but flattens the cache directory by replacing / with _; for example, ondrej-winter/ritebook-shelf is cached under ~/.cache/ritebook/indexes/ondrej-winter_ritebook-shelf/ritebook-index.json.

Tests and automation can override these locations:

uv run ritebook add-index \
  --source <git-url-or-local-git-repo> \
  --registry-path <path-to-indexes.json> \
  --cache-root <cache-directory>

uv run ritebook update-index \
  --name <effective-index-name> \
  --registry-path <path-to-indexes.json> \
  --cache-root <cache-directory>

uv run ritebook list-skills \
  --registry-path <path-to-indexes.json>

uv run ritebook list-skills \
  --index-name <effective-index-name> \
  --registry-path <path-to-indexes.json>

Consumer registration requires published schema version 1 indexes to include index.name metadata. Legacy ritebook-index.json files without that metadata are rejected instead of guessing a name.

Publishing

The GitHub Actions workflow in .github/workflows/ci-cd.yaml runs formatting, linting, type checking, non-E2E tests, package builds, Docker E2E, patch releases, and PyPI publishing. Docker E2E runs as a separate mandatory job in parallel with the main quality-check job, and releases require both jobs to pass.

During the early project lifecycle, releases stay on the 0.1.x line and every non-bot push to master increments the patch version. The CI/CD workflow uses Python Semantic Release to:

  1. run the quality gate,
  2. bump pyproject.toml from 0.1.x to the next patch version,
  3. commit the version bump,
  4. create the matching v0.1.x tag, and
  5. publish a GitHub release without maintaining a changelog, and
  6. publish the built distributions to PyPI in the same workflow run.

The release job skips commits authored by github-actions[bot] so the automated version-bump commit does not trigger another release. When the project is ready to move beyond patch-only 0.1.x releases, the same Semantic Release tooling can be used for normal commit-derived SemVer releases.

For the current solo-maintainer workflow, master can allow direct pushes and CI/CD verifies changes after each push. Repository rules should allow GitHub Actions to write release bump commits and tags.

Publishing uses PyPI Trusted Publishing through GitHub Actions OIDC. Before the first release, configure a trusted publisher for this repository in the PyPI project settings:

  • Repository owner: ondrej-winter
  • Repository name: ritebook
  • Workflow filename: ci-cd.yaml
  • Environment name: pypi

Architecture direction

Future business capabilities should be implemented as vertical feature slices under src/ritebook/features/, keeping domain, application ports/use cases, and adapters separated according to hexagonal architecture principles.

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

ritebook-0.1.21.tar.gz (275.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ritebook-0.1.21-py3-none-any.whl (89.9 kB view details)

Uploaded Python 3

File details

Details for the file ritebook-0.1.21.tar.gz.

File metadata

  • Download URL: ritebook-0.1.21.tar.gz
  • Upload date:
  • Size: 275.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ritebook-0.1.21.tar.gz
Algorithm Hash digest
SHA256 bc6592bd1bf0941f79d309bc31fa6d8f11db75f395f93bdd72fe4ab116df63ea
MD5 559b4244122247503c7432e96151ecfc
BLAKE2b-256 70cc426ca153ce075bfe9d5a331b75c7efe2a1058e3e536a2a2f27e5597332cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for ritebook-0.1.21.tar.gz:

Publisher: ci-cd.yaml on ondrej-winter/ritebook

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ritebook-0.1.21-py3-none-any.whl.

File metadata

  • Download URL: ritebook-0.1.21-py3-none-any.whl
  • Upload date:
  • Size: 89.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ritebook-0.1.21-py3-none-any.whl
Algorithm Hash digest
SHA256 6e00f86a30fb66bdc6d0a888d7484607d158df87a770ea7e826ac2a8c64ad86a
MD5 7914e64ce51a0e45720863ece17da4be
BLAKE2b-256 9822ee0dfa2a6dd30e8cd2894e61b6bc92f00070a9fc8df2d19dbbb4d454dfb4

See more details on using hashes here.

Provenance

The following attestation bundles were made for ritebook-0.1.21-py3-none-any.whl:

Publisher: ci-cd.yaml on ondrej-winter/ritebook

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page