Croissant Le Doux 62d62ef4fd feat: Reginald is real — model router + agent loop + query_project (P4)
The fixture chat panel is now a working agent. Ask Reginald a question and it
consults the real project through a tool loop, then answers in grounded prose.
Read-only v0 — writes still go through the propose-approve controls.

core (@commitea/core/agent):
- chat-client: OpenAI-wire chat completions over an injected fetch (same seam as
  gitea). Points at any OpenAI-compatible endpoint (LM Studio/Ollama/OpenAI).
- model-router: small model for prose + the read tool; big model reserved for
  later decomposition (pickModel).
- agent-loop: runAgentTurn drives call→tool→result→call until prose (or a step
  budget), recording each tool step. Injected complete + execute → fully testable.
- query-project: the single read tool's engine — compact focus/board/calibration/
  issue/search views built from scheduler + lifecycle + calibration; unbuilt views
  return a notImplemented marker (never fabricated). The model reports, never computes.
- agent-tools: query_project declaration + Reginald's system prompt.

app:
- main model bridge (model:status, model:chat) runs the loop; query_project
  reconciles the repo and builds the view. Model traffic stays in main (token/CSP).
  gitea.ts refactored to share getGiteaClient + reconcileSnapshot.
- preload + global.d.ts expose the model bridge; useChat drives the panel — real
  agent turn when a model is configured, scripted fixture reply otherwise (so
  fixture e2e is unchanged). A subtle "consulted the project" activity line.

Model config (env, defaults to LM Studio on :1234): COMMITEA_MODEL_URL /
_SMALL (google/gemma-4-e4b) / _BIG (qwen/qwen3.6-35b-a3b). COMMITEA_E2E=1 keeps
it unconfigured so the panel stays scripted.

Verified: 88 core tests green (14 agent: client parse, loop tool/error/budget,
all views) + a gated live integration test. Desktop typecheck clean, 14 fixture
e2e green. Gated live e2e drives the real app against gitea + gemma-4-e4b: asked
"what now?", Reginald called query_project and answered "focus is on issue #2"
(the real scheduler pick).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 20:43:02 -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%