Persona-driven fiction review simulator CLI
Project description
Ghost Reader CLI
Local-first persona-driven fiction review simulator for structured beta-reader-style feedback.
Repository: https://github.com/clchinkc/ghost-reader
For AI agents
Agents with web fetch and shell access should start here:
- Fetch agent-setup.md (short bootstrap; do not scrape HTML report templates).
- Install uv or pipx, then install from PyPI:
uv tool install ghost-reader
# or: pipx install ghost-reader
ghost-reader help
ghost-reader update check
- Install the skill: copy
skills/ghost-reader/into your harness skill directory, or invokeSkill(ghost-reader)when available. - Read the operational contract: skills/ghost-reader/SKILL.md (workflow) and skills/ghost-reader/reference.md (data model, Phase 3 roadmap).
Documentation map
| Document | Audience | Role |
|---|---|---|
| agent-setup.md | Agents | Bootstrap, install, 11-step workflow |
| skills/ghost-reader/SKILL.md | Agents | Operational contract |
| skills/ghost-reader/reference.md | Agents | Schemas, paths, HTTP API |
| llms.txt | Agents | Command index |
| examples/README.md | Everyone | Canonical sample trace (committed) |
| AGENTS.md / CLAUDE.md | Harness | Pointers to the above |
The CLI remains local-first and binds serve to 127.0.0.1 by default. An optional,
account-free Vercel deployment can serve Supabase-backed sessions by share URL.
Current status (Phase 2.5)
- Local CLI with iterative refinement rounds (
round init,refine snapshot). - Structured YAML for personas, reviews, feedback, and revision prompts.
- Local HTML reports from
report/payload.jsonand swappable templates. - Bidirectional feedback via
ghost-reader serve(POST /api/feedback,/api/dialogue). - Persona dialogue (
dialogue append,dialogue context). - Content-safe local telemetry and local sync bundles.
- Optional Supabase session storage selected with
GHOST_READER_STORAGE=supabase. - Public, telemetry-disabled Vercel report serving with
?session=<id>routing. - Verification statuses (per session):
review_ready_feedback_pending→refinement_complete→phase1_complete(these are verify outputs, not separate product phases).
Artifact contracts: review and feedback schema v2 only; sessions use round-* directories (no flat legacy layout).
There are no hosted user accounts or authentication. Phase 3 persona recommendation is planned (not in the CLI yet); see roadmap below.
Share a report through Vercel
The authoring CLI writes directly to Ghost Reader's dedicated Supabase project; the deployed server is a read/write presentation layer over the same session. Keep the service-role key on trusted authoring machines and in Vercel environment variables only.
cd /path/to/your-story-project
export GHOST_READER_STORAGE=supabase
export GHOST_READER_PROJECT_ID=your-project-id
export SUPABASE_URL=https://your-project.supabase.co
export SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
ghost-reader init
session_id="<unguessable-session-id>"
ghost-reader session create --id "$session_id" --story-unit "chapter 3" --personas mara,dex,pip
ghost-reader artifact write --session "$session_id" --type source-text --from chapter-3.md
# Write the persona review artifacts, then render:
ghost-reader render --session "$session_id"
Share https://ghost-reader-six.vercel.app/?session=<session-id>. The deployed server has
no login: anyone who receives a session URL can access that report. Use non-guessable
session IDs for material that is not intended for broad discovery.
Deployment uses an isolated ghost_reader Supabase schema in the dedicated Ghost Reader
project. Telemetry is disabled in the container, and personas and templates are packaged
in the image.
The Vercel project requires SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY,
GHOST_READER_PROJECT_ID, and a default SESSION_ID. Vercel injects PORT. Container
startup fails immediately if SESSION_ID or PORT is missing.
For Writers (human users)
Ghost Reader is designed for writers who want structured, persona-driven feedback on their drafts. You don't need to be an AI expert — the CLI handles everything.
Typical workflow (10 minutes):
# 1. Install once
uv tool install ghost-reader
# 2. Go to your story project
cd ~/writing/my-novel
# 3. Initialize Ghost Reader
ghost-reader init
# 4. Create a review session for a chapter
ghost-reader session create --id chapter-3 --personas mara,dex,pip
# 5. Have your AI assistant (Claude, ChatGPT, etc.) write review YAMLs
# Give it this prompt: "Read the attached chapter and write a Ghost Reader
# review as the Mara persona. Use schema v2. Save as mara.review.yaml."
# (Repeat for Dex and Pip.)
# 6. Load the reviews into Ghost Reader
ghost-reader artifact write --session chapter-3 --type review --persona mara --from mara.review.yaml
ghost-reader artifact write --session chapter-3 --type review --persona dex --from dex.review.yaml
ghost-reader artifact write --session chapter-3 --type review --persona pip --from pip.review.yaml
# 7. Render the interactive report
ghost-reader render --session chapter-3
# 8. Open it in your browser
ghost-reader serve --session chapter-3
The report shows each persona's findings side-by-side with cited passages, severity ratings, and specific revision suggestions. You can select which items to address and export a revision prompt to guide your next rewrite.
No AI assistant? You can also write review YAMLs manually — see the schema reference in skills/ghost-reader/reference.md. But Ghost Reader works best paired with an LLM that generates the structured reviews.
Key concept: Ghost Reader is the review management system. The AI generates the reviews. Ghost Reader renders, verifies, and tracks them — giving you a structured feedback loop instead of scattered chat responses.
Install (users)
Requires Python 3.11+. Install uv or pipx first.
| Method | Command |
|---|---|
| uv tool (recommended) | uv tool install ghost-reader |
| pipx | pipx install ghost-reader |
| uvx (no global install) | uvx ghost-reader help |
| Dev (clone) | git clone git@github.com:clchinkc/ghost-reader.git && cd ghost-reader && uv sync --extra dev then uv run ghost-reader help |
uv tool install places ghost-reader on your PATH (typically ~/.local/bin).
ghost-reader init # run from your story project directory
ghost-reader help
Build wheel locally
uv build
uv tool install dist/*.whl
Version management
Published to PyPI via OIDC trusted publishing. Version is set in pyproject.toml and released with a v* git tag. Run ghost-reader update check to compare the installed version against PyPI.
Sample trace
The repo includes a full review_ready_feedback_pending example at examples/sample-trace/. See examples/README.md.
cd examples/sample-trace
export GHOST_READER_HOME="$PWD/.ghostreader-home"
ghost-reader init
ghost-reader verify --session chapter-1
ghost-reader serve --session chapter-1
Regenerate after contract changes: uv run python scripts/refresh_sample_trace.py
Quick workflow
Run all commands from the story project directory (where .ghostreader/ lives), not from a clone of this repo unless you are developing Ghost Reader itself.
cd /path/to/your-story-project
ghost-reader init
ghost-reader session create --id chapter-3 --story-unit "chapter 3" --personas mara,dex,pip
# LLM writes review YAML per persona, then:
ghost-reader artifact write --session chapter-3 --type review --persona mara --from mara.review.yaml
ghost-reader render --session chapter-3
ghost-reader verify --session chapter-3
ghost-reader serve --session chapter-3 --timeout 600
After reviews render, serve is the primary user path: the user selects items in the browser and clicks Submit Feedback, which writes feedback/feedback.yaml. The agent then polls ghost-reader feedback summary --session chapter-3, runs ghost-reader prompt revision, rerenders, and verifies phase1_complete.
If serve is unavailable, open file:// on .ghostreader/sessions/<id>/round-<n>/report/index.html and use the copy-paste Ghost Reader Prompt fallback.
Pasted text (no story repo yet)
mkdir -p ~/ghost-reader-projects/my-chapter
cd ~/ghost-reader-projects/my-chapter
export GHOST_READER_HOME="$PWD/.ghostreader-home"
ghost-reader init
ghost-reader session create --id ch1 --story-unit "chapter 1"
Use /tmp/ghost-reader-* only for disposable tests.
Developer setup (this repo)
git clone git@github.com:clchinkc/ghost-reader.git
cd ghost-reader
uv sync --extra dev
uv run ghost-reader update check
cd /path/to/story-project
uv run --project /path/to/ghost-reader --no-editable ghost-reader init
Report design contract
- Source text stays readable; annotations tie to cited passages.
- Full reader reasons live in persona sections, not only tooltips.
- Quiet, dense layout; no marketing-style chrome.
Test
uv lock --check
uv run --with ruff ruff check .
uv run --with pytest pytest
Code structure
| Module | Role |
|---|---|
cli.py |
Command surface |
server.py |
Local bidirectional HTTP (serve) |
feedback_store.py |
Shared feedback persist + telemetry |
validators.py |
Artifact contracts |
report.py |
HTML from payload.json |
verify.py |
Session gates |
telemetry.py / sync.py |
Local events and export bundles |
storage/ |
Local and Supabase session persistence |
Roadmap: Phase 3 (planned)
Persona recommendation as a spatial HTML comparison artifact (recommendation.html) and ghost-reader recommend are not implemented yet. Until then, users choose personas manually (mara, dex, pip, or optional elena, rook). Custom personas are created by LLMs through the Ghost Reader skill — no CLI import command. Design notes: skills/ghost-reader/reference.md.
Project details
Release history Release notifications | RSS feed
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 ghost_reader-0.2.0.tar.gz.
File metadata
- Download URL: ghost_reader-0.2.0.tar.gz
- Upload date:
- Size: 103.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8aab3787e0ea61f3e33f38f63c48655934073fce352a882d93c0d926235b6fcd
|
|
| MD5 |
ce428d9724348c1da1032d98a3e72cda
|
|
| BLAKE2b-256 |
decdf3f69206b409b64005274335ae396a5ad727dbd491617184914d9127ea40
|
Provenance
The following attestation bundles were made for ghost_reader-0.2.0.tar.gz:
Publisher:
publish.yml on clchinkc/ghost-reader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ghost_reader-0.2.0.tar.gz -
Subject digest:
8aab3787e0ea61f3e33f38f63c48655934073fce352a882d93c0d926235b6fcd - Sigstore transparency entry: 2062548533
- Sigstore integration time:
-
Permalink:
clchinkc/ghost-reader@10aee05371acb681b1ab87b90794a9d266916acb -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/clchinkc
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@10aee05371acb681b1ab87b90794a9d266916acb -
Trigger Event:
push
-
Statement type:
File details
Details for the file ghost_reader-0.2.0-py3-none-any.whl.
File metadata
- Download URL: ghost_reader-0.2.0-py3-none-any.whl
- Upload date:
- Size: 87.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b4e97e5d384265fe7c6c647201307349b9882b649428dbbbb8de1496d362230
|
|
| MD5 |
f116a2438e6aa4a7ba931ff7d686459f
|
|
| BLAKE2b-256 |
6b268a4d4b7145007af2119ff4fc0e536e14742a068d51d8bed0aae5f3c0ef6c
|
Provenance
The following attestation bundles were made for ghost_reader-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on clchinkc/ghost-reader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ghost_reader-0.2.0-py3-none-any.whl -
Subject digest:
5b4e97e5d384265fe7c6c647201307349b9882b649428dbbbb8de1496d362230 - Sigstore transparency entry: 2062548706
- Sigstore integration time:
-
Permalink:
clchinkc/ghost-reader@10aee05371acb681b1ab87b90794a9d266916acb -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/clchinkc
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@10aee05371acb681b1ab87b90794a9d266916acb -
Trigger Event:
push
-
Statement type: