Commit Graph

8 Commits

Author SHA1 Message Date
teernisse
8c9f66cdee chore: add Tauri app icons and generated schemas
Include necessary assets for Tauri app packaging and development:

App Icons (src-tauri/icons/):
- 32x32.png: Small icon for window title bar
- 128x128.png: Standard app icon
- 128x128@2x.png: Retina display icon
- icon.png: Source icon for tray

These are placeholder icons (simple geometric shapes) to be replaced
with proper branding before release.

Generated Schemas (src-tauri/gen/schemas/):
- acl-manifests.json: Access control list manifests
- capabilities.json: Tauri capability definitions
- desktop-schema.json: Desktop platform configuration schema
- macOS-schema.json: macOS-specific configuration schema

These schemas are auto-generated by 'cargo tauri dev' and should be
committed to enable IDE autocompletion and CI schema validation.
They regenerate automatically when tauri.conf.json changes.
2026-02-25 17:02:10 -05:00
teernisse
d9f9c6aae7 test: add contract tests for CLI output parsing
Implement contract testing to catch CLI schema drift early:

Contract Test Suite (fixture_contract_tests.rs):
- parse_lore_me_empty_fixture: Validates LoreMeResponse on empty data
- parse_lore_me_with_activity_fixture: Real lore output with activity
- parse_br_list_empty_fixture: Empty beads list
- parse_br_list_with_beads_fixture: Real br output with beads

Fixtures (captured from real CLI output):
- fixtures/lore/me_empty.json: Synthetic empty response
- fixtures/lore/me_with_activity.json: Real 'lore --robot me' output
- fixtures/br/list_empty.json: Empty array []
- fixtures/br/list_with_beads.json: Real 'br list --json' output
- fixtures/br/bv_triage.json: Real 'bv --robot-triage' output

Fixture Regeneration:
- scripts/regenerate-fixtures.sh: Captures fresh CLI output
  - Run periodically to update fixtures
  - CI can diff against committed fixtures to detect drift

Why Contract Tests Matter:
MC depends on external CLIs (lore, br, bv) whose output format may
change. Contract tests fail fast when our Rust types diverge from
actual CLI output, preventing runtime deserialization errors.

The tests use include_str!() for compile-time fixture embedding,
ensuring tests fail to compile if fixtures are missing.
2026-02-25 17:02:02 -05:00
teernisse
c8854e59e9 test: add test infrastructure with Vitest and Playwright
Set up comprehensive testing infrastructure for both unit and E2E tests:

Unit Testing (Vitest):
- vitest.config.ts: jsdom environment, globals enabled
  - Path alias @tauri-apps/api -> tests/mocks/tauri-api.ts
  - Excludes tests/e2e/** to prevent Playwright collision
  - V8 coverage configured for src/**/*.{ts,tsx}
- tests/setup.ts: @testing-library/jest-dom matchers

Tauri API Mocking:
- tests/mocks/tauri-api.ts: Mock implementation of @tauri-apps/api
  - invoke(): Returns configurable mock responses
  - listen()/emit(): Event system stubs
  - setMockResponse()/resetMocks(): Test helpers
  - Enables testing React components without Tauri runtime

Component Tests:
- tests/components/App.test.tsx: Verifies App shell renders
  - "Mission Control" heading
  - "What should you be doing right now?" tagline
  - "THE ONE THING will appear here" placeholder

E2E Testing (Playwright):
- playwright.config.ts: Chromium + WebKit (Tauri uses WebKit on macOS)
  - Runs Vite dev server before tests
  - HTML reporter, trace on retry
- tests/e2e/app.spec.ts: Smoke tests for deployed app
  - Heading visible, tagline visible, dark mode applied

This dual-layer testing strategy (Vitest for speed, Playwright for
integration) follows the testing trophy: many unit, fewer E2E.
2026-02-25 17:01:51 -05:00
teernisse
bb1b608fbb feat: add trait-based CLI integration for lore and beads
Implement the data layer with mockable CLI wrappers for testability:

CLI Traits (data/*.rs):
- LoreCli: Trait for lore --robot commands (get_me, health_check)
- BeadsCli: Trait for br commands (create, close, list)
- Both use #[automock] for unit testing without real CLI

Real Implementations:
- RealLoreCli: Shells to 'lore --robot me', parses JSON response
- RealBeadsCli: Shells to 'br create/close/list --json'

Type Definitions:
- LoreMeResponse: Full response from 'lore --robot me'
  - open_issues, open_mrs_authored, reviewing_mrs, activity
  - since_last_check with EventGroup for inbox functionality
  - All fields use #[serde(default)] for forward compatibility
- Bead: Task from br list (id, title, status, priority, issue_type)

Local State Management (data/state.rs):
- GitLabBeadMap: Deduplication mapping (GitLab event -> bead ID)
- MappedBead: Tracks miss_count for two-strike orphan detection
- DecisionLog: Append-only JSONL for learning from user choices
- Atomic writes via .tmp files + rename pattern

Tauri Commands (commands/mod.rs):
- greet: Placeholder for IPC testing
- get_lore_status: Exposes lore health to frontend

This establishes the CLI-over-library pattern from PLAN.md:
clean boundaries, no schema coupling, full testability via mocks.
2026-02-25 17:01:39 -05:00
teernisse
62ee08de29 feat: scaffold Tauri 2.0 backend foundation
Set up the Rust backend for Mission Control using Tauri 2.0:

Cargo Configuration:
- Cargo.toml: Tauri 2.0, serde, thiserror, tracing, mockall
  - Library crate (mission_control_lib) for testability
  - Binary crate for Tauri entry point
- Cargo.lock: Pinned dependencies for reproducible builds

Tauri Configuration (tauri.conf.json):
- App identifier: com.mission-control.app
- Window: 800x600, centered, hiddenTitle for clean macOS look
- Shell plugin scoped to lore, br, bv commands only
- Tray icon configured for background operation

Application Bootstrap:
- src/main.rs: Minimal entry point, delegates to lib
- src/lib.rs: Tracing setup, plugin registration, command handlers
  - Debug mode: auto-opens devtools
  - Safe window lookup (no unwrap panic)
- build.rs: Tauri build script for codegen

Architecture: The lib/bin split enables unit testing the Tauri
command handlers without launching the full app.
2026-02-25 17:01:25 -05:00
teernisse
7877ff9218 feat: add React application shell with dark mode UI
Create the minimal React application structure for Mission Control:

Entry Points:
- index.html: Dark mode root (class="dark", bg-surface body)
- src/main.tsx: React 19 createRoot with StrictMode

Application Shell:
- src/App.tsx: Initial landing with "THE ONE THING" placeholder
  - Uses Framer Motion for subtle fade-in animation
  - Centered layout with Mission Control branding
  - Surfaces the core UX principle: "What should you be doing right now?"

Styling:
- src/styles.css: Tailwind directives + custom scrollbar styling
  - Dark scrollbars (zinc-700 thumb, transparent track)
  - .no-select utility for draggable elements

The shell is deliberately minimal - it will evolve as beads integration
(bd-28q) and dashboard components (bd-30f) are implemented.
2026-02-25 17:01:14 -05:00
teernisse
9cfd471d24 chore: configure build tooling and dependencies
Set up the foundational build configuration for Mission Control:

Frontend Build (Vite + TypeScript):
- package.json: React 19, TanStack Query, Zustand, Framer Motion
- tsconfig.json: Strict TypeScript with path aliases (@/)
- vite.config.ts: Tailored for Tauri (port 1420, ignores src-tauri)

Styling (Tailwind CSS):
- tailwind.config.ts: Custom surface color palette (zinc-900/800/700)
- postcss.config.js: Tailwind + autoprefixer pipeline
- tailwind.config.js: Generated config (superseded by .ts)

Code Quality:
- eslint.config.js: ESLint 9 flat config with TypeScript + React hooks
- .gitignore: Exclude node_modules, dist, coverage, test artifacts

This establishes the monorepo structure where:
- Frontend lives in src/ and builds to dist/
- Tauri backend lives in src-tauri/ with its own Cargo workspace
2026-02-25 17:01:05 -05:00
teernisse
954067a38b docs: initial Mission Control planning documents
- PLAN.md: Complete implementation plan with architecture, ACs, phases
- CLAUDE.md: Project context for AI agents

Architecture: Tauri + React, beads as universal work graph,
manual-first priority with rich decision logging.
2026-02-25 16:23:07 -05:00