The foundation for a shareable team build. Replaces the .env.local-only dev config
with a real, per-teammate connection flow.
main:
- config-store.ts: token encrypted at rest via Electron safeStorage (OS keychain),
config JSON in userData. Token lives only in main; renderer gets everything but.
- resolveConfig: saved config > .env.local (dev) > null; ignored under COMMITEA_E2E.
pm-state repo defaults to `${repo}-pm-state`. resetClients() re-reads on change so
saving config takes effect without a restart. gitea:status gains `demo` (e2e).
- IPC: config:get (no token), config:test (authed read validates token+repo),
config:set (encrypt+save+reset), config:clear. Model bridge reads config.modelUrl
and probes reachability — chat is "configured" only if a model actually answers;
localhost default is dev-only (app.isPackaged gate).
renderer:
- ConnectScreen: real onboarding form (URL/owner/repo/PAT/optional model) → test →
save. AppShell gates on it: demo → shell (fixtures/e2e); configured → shell (real);
else → connect. Settings Connection card is real (repo/url/model/sidecar) with
Reconfigure + Disconnect. Chat cleanly disables with a "no model" state instead of
the scripted canned reply.
Verified: main + desktop typecheck clean, 14 fixture e2e green (demo mode unchanged),
live onboarding e2e: fresh app → connect form → validated PAT → real board (24 done /
10 open). COMMITEA_NO_ENV_LOCAL + COMMITEA_USERDATA are test hooks for the onboarding path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The last three P3 screens, retiring every placeholder:
- DirectivesScreen — jade consequence diff (propose-approve: Make it so
/ Amend / Withdraw, resolving moves it into the ledger) + append-only
ledger (seq, who/when/why, verbatim quote, status badge).
- SettingsScreen — gitea connection + managed repos, sync switches,
model router, read-only label schema, rituals, appearance radios
(wired to the shared theme), single danger action.
- OnboardingScreen — full-window first run: welcome → connect (test
gate) → repo pick → propose-approve bootstrap; onDone routes into the
app. Shell early-returns it (no rail/chat), matching the design.
Shell routes directives/settings and the firstrun full-window flow.
DIRECTIVES fixture added. typecheck + 14 e2e green (incl. directive
resolve, appearance↔theme sync, onboarding test gate); all three
screenshot-verified.
Closes P3-8. P3 (UI views) complete — all 14 screens live on fixtures.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First real P3 screens, replacing the placeholders:
- FocusScreen — Now/Next/Later cards (Now = jade + Start/Defer footer),
each with #id, label tags, steeping badge, agent-font rationale, and
a title link that drives the shell issue drill-in. Milestone card
wraps the burn-up cone.
- StandupScreen — typeset letter: overnight drift (dot + delta), per-
person plan (initials avatars), warn-tint stale-blocker nag; sections
settle in on a 90ms stagger, reduced-motion-safe.
- charts/chart.tsx — BurnUpCone (actual polyline, forecast cone with
dashed 80% bounds, jade today rule) + RunwayBar (for P3-5). Fixed
sample geometry until P2 feeds it.
Fixtures (today/focus/standup) mirrored from data.js. Shell routes
focus/standup to the real screens; the drill-in now starts from a Focus
card. Screenshot helper freezes animations so fade-in screens capture
settled. typecheck + 9 e2e green; light/standup/states verified.
Closes P3-3.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reimplements the handoff Shell in React/TS: 208px left rail (nav +
connection dot + Evening service theme switch), max-1120 main column,
330px Reginald chat panel. Routing across top-level views with an
issue drill-in + back-stack of one; data-theme owned by the shell.
- ChatPanel: fixture write-path — echoes a canned reply so layout +
interactions are real; model router wiring lands in P4.
- states.tsx: EmptyState / OfflineBanner / ModelAwayState + the States
specimen gallery, ported from the handoff.
- PlaceholderScreen stands in for not-yet-built views (P3-3+), keeping
navigation live; it also exposes the issue drill-in for now.
- Gallery loses its own theme toggle (shell owns data-theme); reachable
via a Primitives rail entry as a living reference.
Fixtures mirrored from the handoff's data.js. typecheck + 7 e2e green
(nav, theme, offline banner + disabled composer, chat echo, drill-in
back-stack); light/dark/states screenshots verified.
Closes P3-2.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Verbatim port of the handoff primitives into components/ui/ — Icon,
Button, IconButton, Badge, Tag, Card, Tabs (core); Input, Select,
Checkbox, Radio, Switch (forms); Dialog, Toast, Tooltip (feedback).
Each keeps its injected token-referencing CSS byte-for-byte; the
handoff .d.ts contracts become the exported prop interfaces. Barrel at
components/ui/index.ts.
Adds a PrimitivesGallery (app root for now; real shell is P3-2) that
exercises every primitive with a light/dark toggle. Smoke suite asserts
the gallery, section coverage, theme flip, and dialog open/Escape;
screenshots captured for both themes. typecheck + 5 e2e green.
Closes P3-1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Launches the built app (out/main/index.js) via Playwright's _electron
API — no browser project, no chromium download. Adds a launch fixture
(electronApp/window/app), an AppPage page object with a screenshot
helper for autonomous visual review, and a boot smoke suite (shell
renders, @commitea/core label-parse runs in the renderer, preload API
exposed). Scripts: e2e (build+run), e2e:only, e2e:report. Artifacts
gitignored.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>