docs: update README for figment mode

- Add figment mode to intro paragraph
- New Figment Mode section: enabling, assets, trigger protocol, deps
- Architecture table updated with engine/figment_render.py,
  figment_trigger.py, and effects_plugins/ directory breakdown
- Dev setup: separate uv sync --extras entries (mic vs figment)
- Testing section: mentions figment test coverage and Cairo skip
- Roadmap: adds figment follow-up items (CLI flag, intensity wiring,
  ntfy trigger)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-19 11:34:18 -07:00
parent 7a039cdfe0
commit ca1f2718f2

View File

@@ -2,7 +2,7 @@
> *Digital consciousness stream. Matrix aesthetic · THX-1138 hue.* > *Digital consciousness stream. Matrix aesthetic · THX-1138 hue.*
A full-screen terminal news ticker that renders live global headlines in large OTF-font block characters with selectable color gradients (Verdant Green, Molten Orange, or Violet Purple). Headlines auto-translate into the native script of their subject region. Ambient mic input warps the glitch rate in real time. A `--poetry` mode replaces the feed with public-domain literary passages. Live messages can be pushed to the display over [ntfy.sh](https://ntfy.sh). A full-screen terminal news ticker that renders live global headlines in large OTF-font block characters with selectable color gradients (Verdant Green, Molten Orange, or Violet Purple). Headlines auto-translate into the native script of their subject region. Ambient mic input warps the glitch rate in real time. A `--poetry` mode replaces the feed with public-domain literary passages. Live messages can be pushed to the display over [ntfy.sh](https://ntfy.sh). **Figment mode** overlays flickery, theme-colored SVG glyphs on the running stream at timed intervals — controllable from any input source via an extensible trigger protocol.
--- ---
@@ -95,6 +95,43 @@ curl -d "Body text" -H "Title: Alert title" https://ntfy.sh/your_topic
Update `NTFY_TOPIC` in `engine/config.py` to point at your own topic. Update `NTFY_TOPIC` in `engine/config.py` to point at your own topic.
### Figment Mode
Figment mode periodically overlays a full-screen SVG glyph on the running ticker — flickering through a reveal → hold (strobe) → dissolve cycle, colored with a randomly selected theme gradient.
**Enable it** by setting the plugin's config at runtime (no CLI flag yet):
```python
from engine.effects.registry import get_registry
plugin = get_registry().get("figment")
if plugin:
plugin.config.enabled = True
plugin.config.params["interval_secs"] = 60 # seconds between appearances
plugin.config.params["display_secs"] = 4.5 # duration of each appearance
```
**Figment assets** live in `figments/` — drop any `.svg` file there and it will be picked up automatically. The bundled set contains Mayan and Aztec glyphs. Figments are selected randomly, avoiding immediate repeats, and rasterized into half-block terminal art at display time.
**Triggering manually** — any object with a `poll() -> FigmentCommand | None` method satisfies the `FigmentTrigger` protocol and can be passed to the plugin:
```python
from engine.figment_trigger import FigmentAction, FigmentCommand
class MyTrigger:
def poll(self):
if some_condition:
return FigmentCommand(action=FigmentAction.TRIGGER)
return None
```
Built-in commands: `TRIGGER`, `SET_INTENSITY`, `SET_INTERVAL`, `SET_COLOR`, `STOP`.
**System dependency:** Figment mode requires the Cairo C library (`brew install cairo` on macOS) in addition to the `figment` extras group:
```bash
uv sync --extras figment # adds cairosvg
```
--- ---
## Internals ## Internals
@@ -109,6 +146,7 @@ Update `NTFY_TOPIC` in `engine/config.py` to point at your own topic.
- The mic stream runs in a background thread, feeding RMS dB into the glitch probability calculation each frame - The mic stream runs in a background thread, feeding RMS dB into the glitch probability calculation each frame
- The viewport scrolls through a virtual canvas of pre-rendered blocks; fade zones at top and bottom dissolve characters probabilistically - The viewport scrolls through a virtual canvas of pre-rendered blocks; fade zones at top and bottom dissolve characters probabilistically
- An ntfy.sh SSE stream runs in a background thread; incoming messages interrupt the scroll and render full-screen until dismissed or expired - An ntfy.sh SSE stream runs in a background thread; incoming messages interrupt the scroll and render full-screen until dismissed or expired
- Figment mode rasterizes SVGs via cairosvg → PIL → greyscale → half-block encode, then overlays them with ANSI cursor-positioning commands between the effect chain and the ntfy message layer
### Architecture ### Architecture
@@ -131,12 +169,25 @@ engine/
scroll.py stream() frame loop + message rendering scroll.py stream() frame loop + message rendering
viewport.py terminal dimension tracking (tw/th) viewport.py terminal dimension tracking (tw/th)
frame.py scroll step calculation, timing frame.py scroll step calculation, timing
layers.py ticker zone, firehose, message overlay rendering layers.py ticker zone, firehose, message + figment overlay rendering
figment_render.py SVG → cairosvg → PIL → half-block rasterizer with cache
figment_trigger.py FigmentTrigger protocol, FigmentAction enum, FigmentCommand
eventbus.py thread-safe event publishing for decoupled communication eventbus.py thread-safe event publishing for decoupled communication
events.py event types and definitions events.py event types and definitions
controller.py coordinates ntfy/mic monitoring and event publishing controller.py coordinates ntfy/mic monitoring and event publishing
emitters.py background emitters for ntfy and mic emitters.py background emitters for ntfy and mic
types.py type definitions and dataclasses types.py type definitions and dataclasses
themes.py THEME_REGISTRY — gradient color definitions
effects_plugins/
__init__.py plugin discovery (ABC issubclass scan)
noise.py NoiseEffect — random character noise
glitch.py GlitchEffect — horizontal glitch bars
fade.py FadeEffect — edge fade zones
firehose.py FirehoseEffect — dense bottom ticker strip
figment.py FigmentEffect — periodic SVG glyph overlay (state machine)
figments/ SVG assets for figment mode
``` ```
`ntfy.py` and `mic.py` have zero internal dependencies and can be imported by any other visualizer. `ntfy.py` and `mic.py` have zero internal dependencies and can be imported by any other visualizer.
@@ -204,11 +255,15 @@ See `Mainline Renderer + ntfy Message Queue for ESP32.md` for the full server +
Requires Python 3.10+ and [uv](https://docs.astral.sh/uv/). Requires Python 3.10+ and [uv](https://docs.astral.sh/uv/).
```bash ```bash
uv sync # minimal (no mic) uv sync # minimal (no mic, no figment)
uv sync --all-extras # with mic support (sounddevice + numpy) uv sync --extras mic # with mic support (sounddevice + numpy)
uv sync --extras figment # with figment mode (cairosvg + system Cairo)
uv sync --all-extras # all optional features
uv sync --all-extras --group dev # full dev environment uv sync --all-extras --group dev # full dev environment
``` ```
Figment mode also requires the Cairo C library: `brew install cairo` (macOS).
### Tasks ### Tasks
With [mise](https://mise.jdx.dev/): With [mise](https://mise.jdx.dev/):
@@ -226,7 +281,7 @@ mise run run-firehose # uv run mainline.py --firehose
### Testing ### Testing
Tests live in `tests/` and cover `config`, `filter`, `mic`, `ntfy`, `sources`, and `terminal`. Tests live in `tests/` and cover `config`, `filter`, `mic`, `ntfy`, `sources`, `terminal`, and the full figment pipeline (`figment_render`, `figment_trigger`, `figment`, `figment_overlay`). Figment tests are automatically skipped if Cairo is not installed.
```bash ```bash
uv run pytest uv run pytest
@@ -258,6 +313,9 @@ Pre-commit hooks run lint automatically via `hk`.
- **Parallax secondary column** — a second, dimmer, faster-scrolling stream of ambient text at reduced opacity on one side - **Parallax secondary column** — a second, dimmer, faster-scrolling stream of ambient text at reduced opacity on one side
### Cyberpunk Vibes ### Cyberpunk Vibes
- **Figment CLI flag** — expose `--figment` and `--figment-interval N` to enable figment mode from the command line without code changes
- **Figment intensity wiring** — `config.intensity` currently stored but not yet applied to reveal/dissolve speed or strobe frequency
- **ntfy figment trigger** — built-in `NtfyFigmentTrigger` that listens on a dedicated topic to fire figments on demand
- **Keyword watch list** — highlight or strobe any headline matching tracked terms (names, topics, tickers) - **Keyword watch list** — highlight or strobe any headline matching tracked terms (names, topics, tickers)
- **Breaking interrupt** — full-screen flash + synthesized blip when a high-priority keyword hits - **Breaking interrupt** — full-screen flash + synthesized blip when a high-priority keyword hits
- **Live data overlay** — secondary ticker strip at screen edge: BTC price, ISS position, geomagnetic index - **Live data overlay** — secondary ticker strip at screen edge: BTC price, ISS position, geomagnetic index