Commit Graph

35 Commits

Author SHA1 Message Date
teernisse
d2df4cee21 feat: add SyncStatus component with visual indicator
Displays sync state with:
- Green dot for synced (with relative time)
- Spinner for syncing
- Amber dot for stale (auto-detected after 15min)
- Red dot for error (with retry button)
- Gray dot for offline

Includes 23 tests covering all states, time formatting,
button visibility, and click handlers.

bd-2or

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 10:37:00 -05:00
teernisse
47c7b3e83c feat: integrate app initialization into Tauri setup
Startup sequence now:
1. Creates data directories (~/.local/share/mc/)
2. Cleans up orphaned tmp files from crashes
3. Verifies CLI dependencies (lore, br, bv) asynchronously
4. Emits startup-warnings event with missing CLI warnings
5. Emits cli-availability event with tool status
6. Emits startup-sync-ready when CLIs available

This enables the frontend to:
- Display warnings for missing tools
- Know which features are available
- Trigger reconciliation when ready

bd-3jh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 10:34:34 -05:00
teernisse
0ad1b30941 feat: add app initialization module with startup sequence
Implements core startup infrastructure:
- AppConfig for data directory paths
- ensure_data_dir() to create ~/.local/share/mc/
- verify_cli_dependencies() async CLI availability check
- load_with_migration() for state file loading with migration support
- init() main entry point coordinating lock acquisition and setup
- StartupWarning enum for non-fatal issues (missing CLIs, state reset)
- InitError enum with conversion to McError

Also exposes Bridge::with_data_dir() publicly (was test-only).

Includes 11 tests covering directory creation, lock acquisition,
lock contention, corrupt file handling, and config paths.

bd-3jh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 10:33:07 -05:00
teernisse
61a068ad99 feat: add schema migration utilities for versioned state files
Implements MigrationRegistry for managing versioned JSON file migrations:
- Version tracking for gitlab_bead_map.json, state.json, settings.json
- Sequential migration execution (v1→v2→v3)
- Error handling for future versions, missing versions, failed migrations
- Factory functions for each file type's registry

Includes 12 tests covering migration chains, error cases, and idempotency.

bd-1jf

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 10:29:19 -05:00
teernisse
c069e03714 feat: implement sync orchestrator for automated bridge sync
- Add SyncOrchestrator that coordinates file watcher events with bridge sync
- Debounce rapid file changes (500ms window)
- Auto-check if full reconciliation is due (every 6 hours)
- Emit status events (Started, Completed, Failed, ReconciliationStarted/Completed)
- Support both incremental sync and full reconciliation
- 5 tests covering sync, debounce, reconciliation scheduling, and status events

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 10:26:08 -05:00
teernisse
da13b99b75 fix: add missing specta annotations, scope tmp cleanup, and secure state file permissions 2026-02-26 10:24:28 -05:00
teernisse
807899bc49 feat: implement CommandPalette for quick filter and search
- Add text search across all focus items
- Support filter commands: type: and stale:
- Keyboard navigation with arrow keys + Enter
- Click to select items
- Escape or backdrop click to close
- 17 tests covering search, filters, keyboard nav, and empty state

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 10:16:14 -05:00
teernisse
23a4e6bf19 fix: improve error handling across Rust and TypeScript
- Log swallowed errors in file watcher and window operations (lib.rs, watcher.rs)
- Propagate recovery errors from bridge::recover_pending to SyncResult.errors
  so the frontend can display them instead of silently dropping failures
- Fix useTauriEvent/useTauriEvents race condition where cleanup fires before
  async listen() resolves, leaking the listener (cancelled flag pattern)
- Guard computeStaleness against invalid date strings (NaN -> 'normal'
  instead of incorrectly returning 'urgent')
- Strengthen isMcError type guard to check field types, not just presence
- Log warning when data directory resolution falls back to '.' (state.rs, bridge.rs)
- Add test for computeStaleness with invalid date inputs
2026-02-26 10:14:35 -05:00
teernisse
29b44f1b4c fix: patch memory leaks in event hooks and strengthen type guard
Fix three bugs found during code review:

1. useTauriEvent/useTauriEvents: If the component unmounts before the
   async listen() promise resolves, the unlisten function was lost,
   leaking the event subscription. Added a cancelled flag to call
   unlisten immediately when the promise resolves after cleanup.

2. useTauriEvents: The handlers object was used directly as a useEffect
   dependency, causing re-subscription on every render when callers
   pass an inline object literal. Replaced with a useRef for handler
   stability and a derived eventNames string as the dependency.

3. isMcError type guard: Only checked property existence via 'in'
   operator, not property types. An object with wrong-typed properties
   (e.g. code: 42) would pass the guard. Now validates that code and
   message are strings and recoverable is boolean.

4. AppShell global shortcut listener: Same race condition as (1), plus
   missing .catch() on the listen promise could produce unhandled
   rejections.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 10:13:17 -05:00
teernisse
378a173084 feat: implement ReasonPrompt component with quick tags
- Create ReasonPrompt dialog for capturing optional reasons
- Add quick tag buttons (Blocking, Urgent, Context switch, etc.)
- Support keyboard navigation (Escape to cancel)
- Handle text input with trimming and null for empty
- Different titles for different actions (set_focus, defer, skip)
- All 10 tests pass

Closes bd-2p0

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 10:10:02 -05:00
teernisse
175c1994fc feat: implement Inbox view with triage actions
- Add InboxItem types and TriageAction/DeferDuration types
- Create Inbox component with:
  - Accept/Defer/Archive actions for each item
  - Keyboard shortcuts (A/D/X) for fast triage
  - Defer duration picker popup
  - Inbox Zero celebration state
  - Type-specific badges with colors
- Add comprehensive tests for all functionality

Closes bd-qvc

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 10:08:54 -05:00
teernisse
087b588d71 feat: add Tauri state persistence and BvCli trait
- Add Tauri storage adapter for Zustand (tauri-storage.ts)
- Add read_state, write_state, clear_state Tauri commands
- Wire focus-store and nav-store to use Tauri persistence
- Add BvCli trait for bv CLI mocking with response types
- Add BvError and McError conversion for bv errors
- Add cleanup_tmp_files tests for bridge
- Fix linter-introduced tauri_specta::command issues

Closes bd-2x6, bd-gil, bd-3px

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 10:06:57 -05:00
teernisse
443db24fb3 chore: update beads task tracking
Updates .beads/issues.jsonl with task status changes from this
development session.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:56:45 -05:00
teernisse
f9f35c9476 chore: call tmp file cleanup on app startup
Integrates the bridge's cleanup_tmp_files() method into the Tauri
setup phase. This ensures any orphaned .json.tmp files from previous
crashes are cleaned up before the app starts operating.

The cleanup runs early in setup(), before tray and shortcuts, to
ensure a clean state for the bridge to operate in.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:56:36 -05:00
teernisse
5059eb008a feat: add nav store persistence and tmp file cleanup
Completes persistence story and crash recovery hardening.

Nav store persistence:
- Wraps nav store with zustand persist middleware
- Persists activeView to localStorage under "mc-nav-store"
- Remembers which view you were on across sessions

Bridge tmp file cleanup (src-tauri/src/data/bridge.rs):
- New cleanup_tmp_files() method removes orphaned .json.tmp files
- Called on startup to clean up from crashes during save_map()
- Logs cleaned files for debugging
- Returns count of files removed

The atomic write pattern (write to .tmp, then rename) can leave
orphan files if the app crashes between write and rename. This
cleanup ensures we don't accumulate stale tmp files over time.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:56:24 -05:00
teernisse
6c04c2efe7 feat: add localStorage persistence to focus store
Wraps the focus store with zustand/middleware persist to maintain
queue state across page refreshes and app restarts.

Persists:
- current: The currently focused item
- queue: Remaining items in the work queue

Not persisted (transient state):
- isLoading: Reset on mount
- error: Reset on mount

Storage key: "mc-focus-store"

This prevents losing your place in the queue when the app restarts
or the page refreshes during development.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:56:09 -05:00
teernisse
7120323295 chore: update app icons for Mission Control branding
Updates the Tauri app icons to use Mission Control's visual identity.
These icons appear in the dock, system tray, and window title bar.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:55:53 -05:00
teernisse
c32a71a0b0 test: add persistence test for nav store and update test setup
Adds test coverage for the navigation store's localStorage persistence
and ensures clean state between tests.

Changes:
- nav-store.test.ts: Add persistence test verifying activeView is saved
- Clear localStorage in beforeEach to prevent test pollution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:55:48 -05:00
teernisse
7404acdfb4 feat: add Tauri event hook and lore.db file watcher
Adds real-time updates when lore syncs new GitLab data by watching
the lore.db file for changes.

React hook (src/hooks/useTauriEvents.ts):
- useTauriEvent(): Subscribe to a single Tauri event with auto-cleanup
- useTauriEvents(): Subscribe to multiple events with a handler map
- Typed payloads for each event type:
  - global-shortcut-triggered: toggle-window | quick-capture
  - lore-data-changed: void (refresh trigger)
  - sync-status: started | completed | failed
  - error-notification: code + message

Rust watcher (src-tauri/src/watcher.rs):
- Watches lore's data directory for lore.db modifications
- Uses notify crate with 2-second poll interval
- Emits "lore-data-changed" event to frontend on file change
- Handles atomic writes by watching parent directory
- Gracefully handles missing lore.db (logs warning, skips watcher)

Test coverage:
- Hook subscription and cleanup behavior
- Focus store test fix: clear localStorage before each test

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:55:30 -05:00
teernisse
df26eab361 docs: add AGENTS.md and progress screenshots for agent swarm coordination
Adds documentation for agent coordination when working on Mission Control.
Screenshots capture the UI state at key development milestones.

AGENTS.md includes:
- Project overview and core principle (THE ONE THING)
- Architecture diagram showing IPC flow and CLI integration
- Key file reference table
- Agent coordination: team name, beads workflow, communication
- Current development status (Phase 0-1 complete, Phase 2 in progress)
- Development commands for running tests and dev servers
- Visual verification instructions using Playwright MCP
- Critical constraints: CLI over libraries, trait-based mocking, TDD, no any

Screenshots:
- mission-control-current.png: Current app state
- mission-control-focus-view.png: Focus view with THE ONE THING
- mission-control-phase1-complete.png: Phase 1 milestone capture

These files help multiple agents coordinate on the project and understand
the current implementation state.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:55:10 -05:00
teernisse
480d0817d9 test: add comprehensive frontend tests for components, stores, and utils
Full test coverage for the frontend implementation using Vitest and
Testing Library. Tests are organized by concern with shared fixtures.

Component tests:
- AppShell.test.tsx: Navigation tabs, view switching, batch mode overlay
- FocusCard.test.tsx: Rendering, action buttons, keyboard shortcuts, empty state
- QueueView.test.tsx: Item display, focus promotion, empty state
- QueueItem.test.tsx: Type badges, click handling
- QueueSummary.test.tsx: Count display by type
- QuickCapture.test.tsx: Modal behavior, form submission, error states
- BatchMode.test.tsx: Progress tracking, item advancement, completion
- App.test.tsx: Updated for AppShell integration

Store tests:
- focus-store.test.ts: Item management, act(), setFocus(), reorderQueue()
- nav-store.test.ts: View switching
- capture-store.test.ts: Open/close, submission states
- batch-store.test.ts: Batch lifecycle, status tracking, derived counts

Library tests:
- types.test.ts: Type guards, staleness computation
- transform.test.ts: Lore data transformation, priority ordering
- format.test.ts: IID formatting for MRs vs issues

E2E tests (app.spec.ts):
- Navigation flow
- Focus card interactions
- Queue management
- Quick capture flow

Test infrastructure:
- fixtures.ts: makeFocusItem() factory
- tauri-plugin-shell.ts: Mock for @tauri-apps/plugin-shell
- Updated tauri-api.ts mock with new commands
- vitest.config.ts: Path aliases, jsdom environment
- playwright.config.ts: Removed webServer (run separately)
- package.json: Added @tauri-apps/plugin-shell dependency

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:54:59 -05:00
teernisse
df53096aa8 feat: implement React UI components for focus and queue views
Complete frontend implementation for Mission Control's core workflow:
surface THE ONE THING and let the user act on it.

Layout (AppShell.tsx):
- Tab navigation: Focus | Queue | Inbox
- View switching with AnimatePresence transitions
- Global shortcut event listener for quick capture
- Batch mode overlay when active

Focus View (FocusView.tsx, FocusCard.tsx):
- Prominent display of THE ONE THING
- Type badge with staleness coloring (fresh/normal/amber/urgent)
- Context quote and requestedBy for reviews
- Action buttons: Start (Enter), 1h (Cmd+1), Tomorrow (Cmd+2), Skip (Cmd+S)
- Empty state: "All Clear" when queue is empty

Queue View (QueueView.tsx, QueueItem.tsx, QueueSummary.tsx):
- List view of all items with reordering capability
- Click to set as focus (promotes to THE ONE THING)
- Summary shows counts by type
- Links back to Focus view

Quick Capture (QuickCapture.tsx):
- Modal overlay triggered by Cmd+Shift+C
- Creates new bead via quick_capture command
- Shows success/error feedback

Batch Mode (BatchMode.tsx):
- Full-screen overlay for rapid item processing
- Progress indicator: 3/10 DONE
- Same action buttons as FocusCard
- Exit returns to regular Focus view

App entry updates:
- App.tsx now renders AppShell
- main.tsx unchanged (React 19 + StrictMode)
- Tailwind config adds MC-specific colors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:54:46 -05:00
teernisse
259f751f45 feat: add Zustand stores for focus, navigation, capture, and batch
Implements the frontend state management layer using Zustand. Each store
is single-purpose and testable in isolation.

Focus Store (focus-store.ts):
- Tracks current focused item (THE ONE THING)
- Manages the queue of remaining items
- Actions: setItems, act (start/defer/skip), setFocus, reorderQueue
- Advancing through items removes from queue, promotes next to current

Navigation Store (nav-store.ts):
- Simple view routing: focus | queue | inbox
- No URL-based routing needed for native app
- Default view is "focus"

Capture Store (capture-store.ts):
- Manages quick capture overlay state
- Tracks submission status and errors
- Opens via global shortcut event listener

Batch Store (batch-store.ts):
- Manages batch processing mode for rapid item completion
- Tracks items, their statuses (pending/done/skipped), and current index
- Derives counts: completedCount, skippedCount, isFinished
- Used for "knock out all code reviews" workflow

State design principles:
- No derived state stored; computed on access
- Actions are pure mutations with logging
- Loading/error states colocated with data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:54:34 -05:00
teernisse
e01e93f846 feat: add frontend TypeScript types and IPC layer
Establishes type-safe communication between React frontend and Rust backend.
Types mirror the Rust structs to ensure consistency across the Tauri boundary.

Type definitions (src/lib/types.ts):
- LoreStatus, LoreSummaryStatus: Lore CLI response shapes
- BridgeStatus, SyncResult: Bridge operation results
- McError, McErrorCode: Structured error handling with type guard
- FocusItem, FocusItemType: THE ONE THING work items
- FocusAction, DecisionEntry: User action tracking
- Staleness computation: fresh/normal/amber/urgent based on age

IPC wrapper (src/lib/tauri.ts):
- Typed invoke() calls for each Rust command
- getLoreStatus, getBridgeStatus, syncNow, reconcile, quickCapture

Data transformation (src/lib/transform.ts):
- transformLoreData: Converts lore response to FocusItem[]
- Priority ordering: reviews first (blocking others), issues, authored MRs
- Generates stable IDs matching bridge mapping keys

Formatting utilities (src/lib/format.ts):
- formatIid: Prefix with ! for MRs, # for issues

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:54:24 -05:00
teernisse
2e0ead8660 feat: wire up Tauri IPC commands with global shortcuts and tray
Completes the backend command layer, exposing bridge operations to the
frontend via Tauri IPC. Also adds system tray support and global hotkeys.

New commands:
- get_lore_status: Real CLI integration (was stub), returns issue/MR counts
- get_bridge_status: Mapping counts, pending items, sync timestamps
- sync_now: Trigger incremental sync (since_last_check events)
- reconcile: Full reconciliation pass (two-strike orphan detection)
- quick_capture: Create a new bead from freeform text

All commands use tokio::spawn_blocking for CLI I/O, preventing async
executor starvation. Commands accept trait objects for testability.

System integration:
- Global shortcut: Cmd+Shift+M toggles window visibility
- Global shortcut: Cmd+Shift+C opens quick capture overlay
- System tray: Left-click toggles window, right-click shows menu
- Tray menu: Show Mission Control, Quit

Tauri configuration:
- Added global-shortcut plugin with permissions
- Shell plugin scoped to lore, br, bv commands only
- Removed trayIcon config (using TrayIconBuilder instead)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:54:15 -05:00
teernisse
908dff4f07 feat: implement GitLab -> Beads bridge with crash-safe syncing
Adds the core sync engine that maps GitLab events (from lore CLI) to beads
tasks. This is the foundational data layer for Mission Control's unified
task view.

Bridge architecture:
- GitLabBeadMap: JSON file storing event -> bead_id mappings
- MappingKey: Type-safe keys for MR reviews, issues, and authored MRs
- Cursor: Tracks last sync and reconciliation timestamps

Crash-safety features:
- Write-ahead pattern: pending=true written before bead creation
- Atomic file writes via temp file + rename
- Recovery on startup: retries pending entries with bead_id=None
- flock(2) based single-instance locking (prevents concurrent MC)

Two-strike orphan detection:
- First miss sets suspect_orphan=true (items may temporarily vanish)
- Second miss closes the bead (confirmed deleted/merged)
- Reappearance clears the flag (healed)

Sync operations:
- incremental_sync(): Process since_last_check events
- full_reconciliation(): Cross-check all open items
- recover_pending(): Handle interrupted syncs

Dependencies added:
- libc: For flock(2) system call
- thiserror: For ergonomic error types

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:54:05 -05:00
teernisse
6eebe082c8 feat: add structured error types for Tauri IPC commands
Introduces McError and McErrorCode to replace string-based errors in
Tauri commands. This enables the frontend to handle errors programmatically
rather than parsing error messages.

Key design decisions:
- Error codes use SCREAMING_SNAKE_CASE for frontend pattern matching
- Each error indicates whether it's recoverable (user can retry)
- Automatic conversion from LoreError, BeadsError, and BridgeError
- Errors serialize to JSON for consistent IPC transport

Error categories:
- Lore: LORE_UNAVAILABLE, LORE_UNHEALTHY, LORE_FETCH_FAILED
- Bridge: BRIDGE_LOCKED, BRIDGE_MAP_CORRUPTED, BRIDGE_SYNC_FAILED
- Beads: BEADS_UNAVAILABLE, BEADS_CREATE_FAILED, BEADS_CLOSE_FAILED
- General: IO_ERROR, INTERNAL_ERROR

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 09:53:53 -05:00
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