Scaffold CommiTea: yarn workspaces, Electron shell, core label schema, design system

- apps/desktop: electron-vite + React + Tailwind mapped onto design tokens
  (preflight off; tokens/base.css owns the reset); boots to a Reginald
  placeholder proving fonts/tokens/core wiring
- packages/core: pure TS; gitea label schema (est/*, p/*, deadline/hard)
  with pessimistic conflict resolution + 15 unit tests
- docs/design: full design handoff (tokens, 16 component contracts,
  interactive 14-screen prototype, Reginald voice rules)
- docs/PLAN.md: product plan (purity rule, pm-state repo, deterministic
  scheduler + Monte Carlo, directive log)
- Deliberate deviation from novelpad stack: no ElectricSQL/PGlite — local
  store is a rebuildable cache over gitea REST/webhooks (better-sqlite3
  in main process, arriving in P1)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Christian LeDoux
2026-07-07 20:42:46 -04:00
commit 7a5cacc54c
268 changed files with 15766 additions and 0 deletions

74
docs/design/README.md Normal file
View File

@@ -0,0 +1,74 @@
# Handoff: CommiTea App
## Overview
CommiTea is an AI-project-manager built on Gitea: an Electron desktop app (one window) where an LLM agent persona ("Reginald") captures work via interview, forecasts milestones as Monte Carlo ranges, and manages issues through labels only. This package contains the complete design system plus a fully interactive HTML prototype of the app with 11 screens.
## About the Design Files
**The files in this bundle are design references created in HTML** — prototypes showing intended look and behavior, not production code to copy directly. Your task is to **recreate these designs in the target codebase's environment**. The product plan specifies **Electron + React + Tailwind**; if that scaffold doesn't exist yet, that is the intended stack. Map the CSS custom properties in `tokens/` to Tailwind theme config; reimplement the `components/` primitives as your base component library.
`ui_kits/app/index.html` opens directly in a browser (via a local static server) — use it as the living spec. Everything is real: navigation, drill-ins, theme toggle, offline simulation.
## Fidelity
**High-fidelity.** Colors, typography, spacing, radii, shadows, copy, and interactions are final. Recreate pixel-perfectly using the token values (all defined in `tokens/*.css`). The fixture data in `ui_kits/app/data.js` is demo content — replace with real Gitea/scheduler data.
## Design System (source of truth)
- `design_system_readme.md` — brand context, CONTENT FUNDAMENTALS (Reginald's voice rules: dry wit, no emoji, sentence case, forecasts always ranges), VISUAL FOUNDATIONS, ICONOGRAPHY.
- `styles.css` → imports `tokens/fonts.css` (self-hosted woff2 in `assets/fonts/`), `tokens/colors.css` (light `:root` + dark `[data-theme="dark"]`), `tokens/typography.css`, `tokens/spacing.css`, `tokens/base.css`.
- `components/{core,forms,feedback}/` — 16 React primitives (Button, IconButton, Badge, Tag, Card, Tabs, Icon, Input, Select, Checkbox, Radio, Switch, Dialog, Toast, Tooltip). Each has `<Name>.jsx` (reference implementation), `<Name>.d.ts` (props contract), `<Name>.prompt.md` (usage + rules). Reuse these contracts verbatim.
- `_ds_bundle.js` — compiled bundle the prototype loads; not for production.
### Type voices (strictly cast — never mix)
- `--text-display/title/hero`: Libre Caslon Display — headlines, hero numerals
- `--text-agent(-lg)`: Libre Caslon Text, **upright** — ONLY for Reginald's speech
- `--text-body/small/caption`: Instrument Sans — all UI
- `--text-data/label`: IBM Plex Mono — machine data verbatim: `est/3d`, `p/1`, `#87`, dates, deltas
### Key color tokens (light / dark)
- Surfaces: `--paper-0` #F0F4F0/#121C18 (app), `--paper-1` #FAFCF9/#182420 (card), `--paper-2` inset, `--paper-3` pressed
- Ink: `--ink-1` #1D2522/#E4EEE7, `--ink-2`, `--ink-3`; hairlines `--line-1/2`
- Brand: `--accent` (spruce #275546/#3A7260), hover/pressed darker steps; `--jade` #46996F/#6FC694 (small accents + key-card top rule `--shadow-jade-line` only — never large fills)
- Status: `--ok --warn --danger --info` + `*-tint` pairs; label chips `--label-p1..p4`, `--label-est-*`, `--label-hard`
- Forecast: `--cone-fill`, `--cone-line`, `--cone-actual`
- Radii 4/6/10px; spacing 4px scale (`--space-1..10`); motion 120320ms `--ease-out`, no bounces; focus = 2px `--focus-ring` outline offset 2.
## Screens (all in `ui_kits/app/`, routed by `Shell.jsx`)
Layout shell: 208px left rail (nav + connection status + theme switch) · main column (max 1120px, 24/28px padding) · 330px right chat panel. Page headers: Caslon display title over a `3px double` rule, mono subtitle. One `jade` (top-ruled) card per view maximum.
1. **Shell** (`Shell.jsx`) — nav, routing, dark mode (`data-theme` on `<html>`), offline simulation (click connection dot), issue navigation with back-stack of one.
2. **Standup** (`StandupScreen.jsx`) — morning ritual as a typeset letter: drift report (dot + text + mono delta), per-person plan, stale-blocker nag (warn tint, clickable). Sections fade in once, 90ms stagger, reduced-motion-safe.
3. **Morning service / Focus** (`FocusScreen.jsx`) — Now/Next/Later cards (Now = jade + footer actions), burn-up cone card (`Chart.jsx` BurnUpCone SVG).
4. **Inbox** (`InboxScreen.jsx`) — day-grouped notifications, filter Tabs, unread dots, live rail badge; rows navigate to issue/directives; "Mark all read".
5. **Capture** (`CaptureScreen.jsx`) — braindump → chip-answered interview (running mm:ss clock, amber past 2:00) → editable tray review with consequence line → filed. State machine: dump | interview | review | filed.
6. **The pot / Board** (`BoardScreen.jsx`) — 5-column lifecycle kanban (Diagnosis/Triage/Steeping/In review/Done), live search with empty state, Tabs to drill-ins.
7. **Gantt** (`GanttView.jsx`) — scheduler bars by state, critical rows inset-ruled, dotted 80% tails, today rule (jade), milestone band + due diamond.
8. **Dependencies** (`DepsGraph.jsx`) — layered DAG, SVG bezier edges w/ arrowheads, critical path in accent, milestone capsule terminal.
9. **Runway** (`RunwayScreen.jsx`) — milestone range bars (due marker vs 80% band), capacity list, calibration teaser → **Calibration** (`CalibrationScreen.jsx`): scatter + honest diagonal + ×1.18 fit, bias-by-label bars, per-person bias, forecast effect. Milestone rows → **Milestone detail** (`MilestoneScreen.jsx`): stats strip, cone, grouped issue list.
10. **Issue detail** (`IssueScreen.jsx`) — human intent left (description, comments, composer "writes to gitea, as you"), machine-derived right (inferred lifecycle timeline, per-issue forecast, dependency chips, provenance note).
11. **Directives** (`DirectivesScreen.jsx`) — pending consequence diff (before → after mono rows; Make it so / Amend / Withdraw) + append-only ledger (seq, who/when/why, verbatim quote, status badge).
12. **Settings** (`SettingsScreen.jsx`) — connection, sync switches, model router, read-only label schema, rituals, appearance radios, single danger action.
13. **Onboarding** (`OnboardingScreen.jsx`, "First run") — full-window: welcome → connect (test gate) → repo pick → propose-approve bootstrap.
14. **States** (`StatesGallery.jsx`) — EmptyState/OfflineBanner/ModelAwayState components + gallery of all empty & trouble states.
## Interactions & Behavior
- Hovers: surfaces step one paper darker; buttons darken (`--accent-hover`); never opacity on text. Press: one step darker again, no shrink.
- All fake async (connection test ~1.1s, chat reply ~0.9s, bootstrap ticks 700ms) represent real network calls.
- Offline mode: amber banner (copy in `StatesGallery.jsx`), chat composer disabled + queue note, red rail dot. Reads work from cache; writes queue.
- Issue click anywhere → issue page; Back returns to origin view.
- Chat = the only write path for mutations; destructive ops always propose-approve (Dialog or consequence diff).
## State Management (suggested)
- `view` routing + `prevView` (back), `dark`, `offline`, `issue` selection, inbox `readIds`, capture state machine, directives pending/ledger. In production: Gitea REST + webhooks fill a local cache (SQLite per plan); scheduler output feeds focus/gantt/runway; all copy rules live in the design-system readme.
## Assets
- `assets/fonts/` — Libre Caslon Display/Text, Instrument Sans, IBM Plex Mono (woff2, latin, self-hosted; Google Fonts sources)
- `assets/icons/` — 69 Lucide SVGs (lucide-static v0.462.0, ISC). In production use the `lucide-react` package at strokeWidth 1.5.
- `assets/logo.jpeg` (original), `assets/logo-icon.png` (cropped, rounded) — provided brand mark; never redraw.
## Files
- `ui_kits/app/index.html` — entry; open with a static server from this folder's root
- `ui_kits/app/*.jsx` — one file per screen (see Screens above); `data.js` — all fixture data
- `styles.css`, `tokens/`, `components/`, `assets/` — the design system
- `SKILL.md` — agent-facing skill entry (works with Claude Code as an Agent Skill)
## Note on file suffixes
Reference source files in this bundle carry a `.txt` suffix (`*.js.txt`, `*.d-ts.txt`) so the design tool's compiler ignores these copies — the originals live in the design project. They are ordinary JSX/TypeScript inside; strip the suffix after copying into your repo. `ui_kits/app/index.html` still runs as-is (Babel loads the .txt files by src).