Croissant Le Doux 0dd26b8b05 feat: config & onboarding — each teammate connects their own Gitea (Phase A)
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>
2026-07-09 02:09:53 -04:00

CommiTea

AI project manager built on Gitea. A deterministic scheduler does the math (Monte Carlo forecasts over your own estimate-vs-actual history); the agent — Reginald — captures work via interview, negotiates priorities, and explains the consequences. Gitea holds human-authored intent; a pm-state repo holds machine-derived state. The LLM never does math.

Structure

  • apps/desktop — Electron app (electron-vite, React, Tailwind)
  • packages/core — pure TypeScript: label schema, scheduler, gitea client (no Electron imports)
  • docs/PLAN.md — product plan (goals, phases, not-doing list)
  • docs/design/ — design handoff: tokens, component contracts, interactive prototype (docs/design/ui_kits/app/index.html via a static server), brand voice rules in design_system_readme.md

Development

yarn            # install
yarn dev        # electron app, logs tee to apps/desktop/desktop.log
yarn test       # unit tests (vitest)
yarn typecheck

End-to-end (Electron + Playwright)

yarn workspace @commitea/desktop e2e        # build, then drive the built app
yarn workspace @commitea/desktop e2e:only   # reuse existing out/ build (tight loop)
yarn workspace @commitea/desktop e2e:report # open the last HTML report

Tests launch the built app (out/main/index.js) through Playwright's _electron API — no browser project, no chromium download. Fixtures and page objects live in apps/desktop/e2e/; screenshots land in e2e/.artifacts/screens/ for visual review. Page objects use user-facing locators (getByRole/getByText), never CSS/DOM structure.

Conventions

  • Yarn 4 workspaces; ESM everywhere; .js extensions on relative imports
  • @commitea/core stays pure — unit-testable without Electron or network
  • Design tokens are the source of truth (apps/desktop/src/renderer/src/design/, mirrored from docs/design/); Tailwind maps onto the CSS custom properties, never redefines them
  • Reginald's voice rules live in docs/design/design_system_readme.md — no emoji, no point-date forecasts, wit in sentences never in buttons
Description
No description provided
Readme 2.6 MiB
Languages
TypeScript 97.8%
CSS 1.7%
JavaScript 0.4%