Files
ratatoskr/pyproject.toml
vh 922ef34b48 feat(web): frontend redesign — aurora telemetry instrument + live Markdown (v0.17.0)
A design pass through /frontend-design on the web companion to retain
all debugging richness while raising usability and polish. Single-file
vanilla HTML/CSS/JS; no build, no CDN, no node_modules. HTTP surface,
endpoints, presentation contract, and INV-001..009 all unchanged.

Aesthetic direction: "Aurora telemetry instrument."
- Runic glyph + wordmark, live connection dot (idle = aurora-green,
  streaming = pulsing cyan, error = dawn-red), session identity right-
  aligned. Persona summary lives inline in the top bar with labeled
  P/A/D micro-bars (centered baseline, [-1,1] mapped).
- Aurora signature band — thin cyan→blue→green shimmer animation
  at the top edge, echoed on the setup card.
- Conversation column with turn-divider rules, cyan ❯ prompt echoes,
  assistant text with a live cyan left-rule. Terminal events become
  status chips (done = aurora-green, error = dawn-red, cancelled =
  dawn-yellow) with metadata. Animated "awaiting first token · Ns"
  indicator with elapsed counter.
- Telemetry column: tabs with live count badges that flash on new
  events, sticky pane header carries the active pane name + copy
  button, new-line flash highlight on each pane append, structured
  empty states, persona pane structured render.
- Composer: real input, send/cancel buttons, streaming-lock state.
- Status line: keyboard legend + version footer.
- Centered setup card overlay with styled agent select on first open.
- All-monospace by intent (no-CDN constraint + right for a wire-
  monitor tool); system mono stack. CSS-only motion (pulse, shimmer,
  staggered rise, flash, awaiting dots).

Live Markdown — transcript response + thinking panes:
- Hand-rolled markdownSafe() renderer: escape-FIRST (INV-004
  preserved), then a whitelist subset (headings, bold, italic, inline
  code, fenced code blocks, ordered/unordered lists, blockquotes,
  links). No raw HTML passthrough. Link href restricted to http(s):// +
  conservative charset (rejects javascript:, attribute-breakout URLs).
- Per-turn live buffer; each text/thinking delta re-renders the
  accumulated buffer in place (same pattern as the TUI's v0.9.0 live
  MD rendering).
- Verified under node: rendering (bold/italic/code/lists/headings/
  fences/safe links) + XSS neutralization (script tags, javascript:
  schemes, attribute-breakout URLs, img onerror) all behave correctly.
- Tools/Debug/Persona panes stay literal monospace by deliberate
  choice: they carry our structured audit lines + JSON, where MD would
  corrupt readability (underscores in tool names, JSON braces, etc.).

Thinking pane per-turn breaks:
- Each turn lays down a labeled `── turn N ──` divider in the
  thinking pane. The prior turn's live block is closed and a fresh
  MD-rendered block opens below the divider, so each turn's chain-
  of-thought is its own break-separated section.

Tests: 378 passing (no test change — server-side surface unchanged).
Markdown safety verified via standalone node harness exercising
rendering + 4 XSS vectors.

Minor per SemVer discipline: substantial new browser-side behavior
(live Markdown rendering, redesigned presentation) that consumers
would opt into via the next launch. No HTTP-caller adapts.
2026-05-29 21:42:36 -07:00

77 lines
2.2 KiB
TOML

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "ratatoskr"
version = "0.17.0"
description = "Worldtree Conversation API debug TUI — multi-pane observability dashboard"
readme = "README.md"
requires-python = ">=3.12"
license = { file = "LICENSE" }
authors = [{ name = "Vuong Hoang" }]
keywords = ["worldtree", "tui", "debug", "sse", "textual"]
# Network + SSE consumer + TUI framework.
# See docs/design-brief.md §1 (Textual), §3 (httpx-sse).
dependencies = [
"httpx>=0.27",
"httpx-sse>=0.4",
"textual>=0.85",
]
[project.optional-dependencies]
web = [
"starlette>=0.40",
"uvicorn[standard]>=0.30",
]
dev = [
"pytest>=8",
"pytest-asyncio>=0.24",
"respx>=0.21", # httpx mocking for SSE-recorded snapshot tests
"ruff>=0.6",
"mypy>=1.11",
"textual-dev>=1.5", # textual console + live reload during dev
"pyyaml>=6", # used by docs/contracts/contract_parser.py and scripts/contract_drift_check.py
"ratatoskr[web]", # web extras included in dev so test_web_* can import starlette
]
[project.scripts]
ratatoskr = "ratatoskr.cli:main"
ratatoskr-web = "ratatoskr.web.entrypoint:main"
[project.urls]
Repository = "https://gitea.phasefinal.com/vh/ratatoskr"
"Design Brief" = "https://gitea.phasefinal.com/vh/brokkr-smithy/src/branch/main/docs/ratatoskr-design-brief.md"
# Worldtree spec pin — see docs/SPEC-PIN.md for the full bump procedure.
# Ratatoskr is built against Worldtree at this commit; the vendored
# spec snapshot in docs/ reflects that SHA.
[tool.ratatoskr.spec-pin]
worldtree-spec-rev = "562001af28d752c3a60d449c7ddd09f44fa9dc9a"
worldtree-version = "v0.29.0"
pinned-on = "2026-05-26"
[tool.hatch.build.targets.wheel]
packages = ["src/ratatoskr"]
# Issue #16: ship the web companion's static HTML in the wheel so
# importlib.resources can locate it post-install.
[tool.hatch.build.targets.wheel.force-include]
"src/ratatoskr/web/static" = "ratatoskr/web/static"
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
[tool.ruff]
line-length = 100
target-version = "py312"
[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP", "RUF"]
[tool.mypy]
python_version = "3.12"
strict = true