render-session 0.1.0

CLI for render-session: HTTP viewer with optional auto-watcher, MCP server alias, config-driven gen, session/recent capture.
# render-session

Single-binary tool (Rust + rmcp + axum) for viewing AI session output.
Provides an MCP server for write operations and an HTTP viewer for read-only browsing.

Release notes are tracked in [CHANGELOG.md](CHANGELOG.md).

## Phase status

| Phase | Status | Scope |
|---|---|---|
| 1 (scaffold) | done | Workspace layout, crate skeletons, binary entry points |
| 1 (HTTP serve) | done | `serve --port N --dir D`; axum router, rust-embed index.html, `/api/list` + `/api/md/{id}` |
| 1 (MCP tools) | done | viewer.lease / list / release / report.write / draft.write |
| 2 (config-gen) | done | 3-layer config merger (`extends:` chains, cycle detection), `gen --project D` emitting `list.json` + `render-lanes.md` |
| 3 (block IF) | done | `Item.block_type` announce + `X-Block-Type` HTTP header. Concrete plugins deferred to frontend. |
| 4 (a) source (session) | done | `sources/session` module + `capture` subcommand. Legacy `render-session.py` session / recent modes ported. |
| 4 (b) filter middleware | done | `filters` module with `Filter` trait + 4 built-in (`HasTable` / `HasMermaid` / `KeywordMatch` / `RegexMatch`) + `FilterRegistry` + `FilterChainConfig`. `capture_recent` supports config-driven filter chain via `categories.recent.filter` yaml field. Legacy `has_visual_artifact` default preserved when filter is None. |
| 4 (c) viewer watcher | done | `serve --watch-tick <secs>` and `viewer.lease(tick=<secs>)` enable a background `tokio::spawn` watcher loop that calls `auto_capture_once` every <tick> seconds. Idempotent emit (existing files skipped). Hook-based capture (`UserPromptSubmit`) DEPRECATED in favor of viewer-watcher. |
| 5+ | pending | rss / jira / github / linear / slack-export source plugins; `SourcePlugin` trait concrete impls. Frontend block plugins (markdown-it / mermaid.js), SPA viewer integration. |

## Build

```sh
cargo build
```

## Run

```sh
# Show available subcommands
cargo run -p render-session -- --help

# Start MCP server (stdio) — called by .mcp.json clients
# render-session-mcp reads stdin / writes stdout following MCP protocol
cargo run -p render-session-mcp
# or via the CLI alias (thin exec wrapper):
cargo run -p render-session -- mcp

# Start HTTP viewer
# Serves GET / (index.html), GET /api/list, GET /api/md/{id}
# Reads markdown from <dir>/render-site/{drafts,reports,session,recent}/
cargo run -p render-session -- serve --port 8000 --dir /path/to/project

# Write a report file (reads body from stdin)
echo "## Summary\n\nContent here." | cargo run -p render-session -- report --dir /path/to/project --title "My Report"

# Generate list.json + render-lanes.md from project config
# Emits: <D>/render-site/list.json and <D>/render-site/rules/render-lanes.md
cargo run -p render-session -- gen --project /path/to/project

# Capture Claude Code session output to render-site/
# Reads from ~/.claude/projects/<slug>/*.jsonl (slug derived from project path if omitted)
# session mode: emits <D>/render-site/session/latest.md
cargo run -p render-session -- capture --project /path/to/project --mode session
# recent mode: emits <D>/render-site/recent/<turn_id>-<ts>.md for last N visual-artifact turns
cargo run -p render-session -- capture --project /path/to/project --mode recent --n 5
# both (default): session + recent
cargo run -p render-session -- capture --project /path/to/project

# Phase 4 (c): start viewer with built-in watcher (auto-captures every 5 seconds)
render-session serve --port 8000 --dir /path/to/project --watch-tick 5
# or via MCP: { "tool": "viewer.lease", "args": { "dir": "/path/to/project", "tick": 5 } }
```

## License

Licensed under either of

- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)

at your option.