From 4d6070a6733ed92779edc1c44333dfa1da83172b Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sun, 22 Feb 2026 17:51:53 -0600 Subject: [PATCH 1/4] chore(orchestrator): bootstrap phase-1 tasks and planning - Created Gitea issue #457 for Dashboard Polish + Theming - Created milestone Go-Live-MVP-Phase1 (0.0.16) - Populated TASKS.md with 4 tasks (MS-P1-001 through MS-P1-004) - Updated mission manifest to Execution phase - Recorded planning decisions in scratchpad Co-Authored-By: Claude Opus 4.6 --- docs/MISSION-MANIFEST.md | 23 ++++++++-------- docs/TASKS.md | 8 ++++-- .../mosaic-stack-go-live-mvp-20260222.md | 27 ++++++++++++++++--- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/docs/MISSION-MANIFEST.md b/docs/MISSION-MANIFEST.md index a93be87..724c6b1 100644 --- a/docs/MISSION-MANIFEST.md +++ b/docs/MISSION-MANIFEST.md @@ -7,11 +7,11 @@ **ID:** mosaic-stack-go-live-mvp-20260222 **Statement:** Ship Mosaic Stack MVP: operational dashboard with theming, task ingestion, one visible agent cycle, deployed and smoke-tested. Unblocks SagePHR, DYOR, Calibr, and downstream projects. -**Phase:** Intake -**Current Milestone:** — +**Phase:** Execution +**Current Milestone:** phase-1 (Dashboard Polish + Theming) **Progress:** 0 / 4 milestones **Status:** active -**Last Updated:** 2026-02-22 23:35 UTC +**Last Updated:** 2026-02-22 23:51 UTC ## Success Criteria @@ -34,12 +34,12 @@ This mission continues from that foundation. ## Milestones -| # | ID | Name | Status | Branch | Issue | Started | Completed | -| --- | ------- | -------------------------- | ------- | ------ | ----- | ------- | --------- | -| 1 | phase-1 | Dashboard Polish + Theming | pending | — | — | — | — | -| 2 | phase-2 | Task Ingestion Pipeline | pending | — | — | — | — | -| 3 | phase-3 | Agent Cycle Visibility | pending | — | — | — | — | -| 4 | phase-4 | Deploy + Smoke Test | pending | — | — | — | — | +| # | ID | Name | Status | Branch | Issue | Started | Completed | +| --- | ------- | -------------------------- | ----------- | ------------------- | ----- | ---------- | --------- | +| 1 | phase-1 | Dashboard Polish + Theming | in-progress | feat/phase-1-polish | #457 | 2026-02-22 | — | +| 2 | phase-2 | Task Ingestion Pipeline | pending | — | — | — | — | +| 3 | phase-3 | Agent Cycle Visibility | pending | — | — | — | — | +| 4 | phase-4 | Deploy + Smoke Test | pending | — | — | — | — | ## Deployment @@ -59,8 +59,9 @@ This mission continues from that foundation. ## Session History -| Session | Runtime | Started | Duration | Ended Reason | Last Task | -| ------- | ------- | ------- | -------- | ------------ | --------- | +| Session | Runtime | Started | Duration | Ended Reason | Last Task | +| ------- | ------- | ---------------- | -------- | ------------ | --------- | +| S1 | Claude | 2026-02-22 17:50 | — | — | — | ## Scratchpad diff --git a/docs/TASKS.md b/docs/TASKS.md index 6748d81..ffa7e6d 100644 --- a/docs/TASKS.md +++ b/docs/TASKS.md @@ -2,5 +2,9 @@ > Single-writer: orchestrator only. Workers read but never modify. -| id | status | milestone | description | pr | notes | -| --- | ------ | --------- | ----------- | --- | ----- | +| id | status | milestone | description | pr | notes | +| --------- | ----------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------ | --- | ------------------------------------------------ | +| MS-P1-001 | not-started | phase-1 | Fix broken test suites: Button.test.tsx (4 fails, old Tailwind classes) + page.test.tsx (5 fails, old widget refs) | — | issue #457, est 15K | +| MS-P1-002 | not-started | phase-1 | Remove legacy unused dashboard widgets: DomainOverviewWidget, RecentTasksWidget, UpcomingEventsWidget, QuickCaptureWidget | — | issue #457, est 5K | +| MS-P1-003 | not-started | phase-1 | Visual + theme polish: audit current vs design reference, fix gaps, verify dark/light across all components, responsive verification | — | issue #457, est 25K, depends MS-P1-001 MS-P1-002 | +| MS-P1-004 | not-started | phase-1 | Phase verification: all quality gates pass, visual verification dark+light, responsive all breakpoints | — | issue #457, est 5K, depends MS-P1-003 | diff --git a/docs/scratchpads/mosaic-stack-go-live-mvp-20260222.md b/docs/scratchpads/mosaic-stack-go-live-mvp-20260222.md index f05e925..7ce802c 100644 --- a/docs/scratchpads/mosaic-stack-go-live-mvp-20260222.md +++ b/docs/scratchpads/mosaic-stack-go-live-mvp-20260222.md @@ -6,15 +6,36 @@ ## Original Mission Prompt ``` -(Paste the mission prompt here on first session) +Continue Mosaic Stack Go-Live MVP from existing state. +- Mission: Ship Mosaic Stack MVP: operational dashboard with theming, task ingestion, + one visible agent cycle, deployed and smoke-tested. +- 4 milestones: Dashboard Polish+Theming, Task Ingestion Pipeline, + Agent Cycle Visibility, Deploy+Smoke Test +- Prior work: MS15-DashboardShell complete (PRs #451-454) +- Design ref: mosaic-stack-website/docs/designs/round-5/claude/01/dashboard.html ``` ## Planning Decisions +### 2026-02-22: Phase-1 Task Breakdown + +Baseline assessment: + +- Lint: PASS, Typecheck: PASS, Tests: FAIL (9 failures) +- UI Button.test.tsx: 4 fails (old Tailwind class assertions vs new CSS token Button) +- Web page.test.tsx: 5 fails (old widget layout vs Phase 3 rebuild) +- Design system + theming already substantially complete from MS15 +- 5 live widgets all use mock data (real data integration is phase-2) +- 4 legacy widgets unused (hardcoded light theme, pre-Phase 3) + +Tasks created: MS-P1-001 through MS-P1-004, issue #457, milestone Go-Live-MVP-Phase1 (0.0.16) +Estimated total: ~50K tokens + ## Session Log -| Session | Date | Milestone | Tasks Done | Outcome | -| ------- | ---- | --------- | ---------- | ------- | +| Session | Date | Milestone | Tasks Done | Outcome | +| ------- | ---------- | --------- | ---------- | ------------------------------------------- | +| S1 | 2026-02-22 | phase-1 | 0/4 | In progress — bootstrap complete, executing | ## Open Questions -- 2.49.1 From 8fa0b3059c5ae34688b254d708429d293c57740c Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sun, 22 Feb 2026 17:58:29 -0600 Subject: [PATCH 2/4] fix(web,ui): fix broken tests and remove legacy dashboard widgets (#457) - Update Button.test.tsx assertions for CSS token-based Button component - Rewrite page.test.tsx to test Phase 3 dashboard widgets - Remove 4 unused legacy widgets: DomainOverview, RecentTasks, UpcomingEvents, QuickCapture (hardcoded light theme, pre-Phase 3) - Remove orphaned QuickCaptureWidget test file Tasks: MS-P1-001, MS-P1-002 Co-Authored-By: Claude Opus 4.6 --- .../web/src/app/(authenticated)/page.test.tsx | 84 ++++++----------- .../dashboard/DomainOverviewWidget.tsx | 65 ------------- .../dashboard/QuickCaptureWidget.tsx | 85 ----------------- .../dashboard/RecentTasksWidget.tsx | 79 ---------------- .../dashboard/UpcomingEventsWidget.tsx | 64 ------------- .../__tests__/QuickCaptureWidget.test.tsx | 93 ------------------- docs/TASKS.md | 4 +- packages/ui/src/components/Button.test.tsx | 10 +- 8 files changed, 35 insertions(+), 449 deletions(-) delete mode 100644 apps/web/src/components/dashboard/DomainOverviewWidget.tsx delete mode 100644 apps/web/src/components/dashboard/QuickCaptureWidget.tsx delete mode 100644 apps/web/src/components/dashboard/RecentTasksWidget.tsx delete mode 100644 apps/web/src/components/dashboard/UpcomingEventsWidget.tsx delete mode 100644 apps/web/src/components/dashboard/__tests__/QuickCaptureWidget.test.tsx diff --git a/apps/web/src/app/(authenticated)/page.test.tsx b/apps/web/src/app/(authenticated)/page.test.tsx index 4702f0d..98da381 100644 --- a/apps/web/src/app/(authenticated)/page.test.tsx +++ b/apps/web/src/app/(authenticated)/page.test.tsx @@ -1,85 +1,55 @@ import { describe, it, expect, vi } from "vitest"; -import { render, screen, waitFor } from "@testing-library/react"; +import { render, screen } from "@testing-library/react"; import DashboardPage from "./page"; -// Mock dashboard widgets -vi.mock("@/components/dashboard/RecentTasksWidget", () => ({ - RecentTasksWidget: ({ - tasks, - isLoading, - }: { - tasks: unknown[]; - isLoading: boolean; - }): React.JSX.Element => ( -
- {isLoading ? "Loading tasks" : `${String(tasks.length)} tasks`} -
+// Mock Phase 3 dashboard widgets +vi.mock("@/components/dashboard/DashboardMetrics", () => ({ + DashboardMetrics: (): React.JSX.Element => ( +
Dashboard Metrics
), })); -vi.mock("@/components/dashboard/UpcomingEventsWidget", () => ({ - UpcomingEventsWidget: ({ - events, - isLoading, - }: { - events: unknown[]; - isLoading: boolean; - }): React.JSX.Element => ( -
- {isLoading ? "Loading events" : `${String(events.length)} events`} -
+vi.mock("@/components/dashboard/OrchestratorSessions", () => ({ + OrchestratorSessions: (): React.JSX.Element => ( +
Orchestrator Sessions
), })); -vi.mock("@/components/dashboard/QuickCaptureWidget", () => ({ - QuickCaptureWidget: (): React.JSX.Element =>
Quick Capture
, +vi.mock("@/components/dashboard/QuickActions", () => ({ + QuickActions: (): React.JSX.Element =>
Quick Actions
, })); -vi.mock("@/components/dashboard/DomainOverviewWidget", () => ({ - DomainOverviewWidget: ({ - tasks, - isLoading, - }: { - tasks: unknown[]; - isLoading: boolean; - }): React.JSX.Element => ( -
- {isLoading ? "Loading overview" : `${String(tasks.length)} tasks overview`} -
- ), +vi.mock("@/components/dashboard/ActivityFeed", () => ({ + ActivityFeed: (): React.JSX.Element =>
Activity Feed
, +})); + +vi.mock("@/components/dashboard/TokenBudget", () => ({ + TokenBudget: (): React.JSX.Element =>
Token Budget
, })); describe("DashboardPage", (): void => { - it("should render the page title", (): void => { + it("should render the DashboardMetrics widget", (): void => { render(); - expect(screen.getByRole("heading", { level: 1 })).toHaveTextContent("Dashboard"); + expect(screen.getByTestId("dashboard-metrics")).toBeInTheDocument(); }); - it("should show loading state initially", (): void => { + it("should render the OrchestratorSessions widget", (): void => { render(); - expect(screen.getByTestId("recent-tasks")).toHaveTextContent("Loading tasks"); - expect(screen.getByTestId("upcoming-events")).toHaveTextContent("Loading events"); - expect(screen.getByTestId("domain-overview")).toHaveTextContent("Loading overview"); + expect(screen.getByTestId("orchestrator-sessions")).toBeInTheDocument(); }); - it("should render all widgets with data after loading", async (): Promise => { + it("should render the QuickActions widget", (): void => { render(); - await waitFor((): void => { - expect(screen.getByTestId("recent-tasks")).toHaveTextContent("4 tasks"); - expect(screen.getByTestId("upcoming-events")).toHaveTextContent("3 events"); - expect(screen.getByTestId("domain-overview")).toHaveTextContent("4 tasks overview"); - expect(screen.getByTestId("quick-capture")).toBeInTheDocument(); - }); + expect(screen.getByTestId("quick-actions")).toBeInTheDocument(); }); - it("should have proper layout structure", (): void => { - const { container } = render(); - const main = container.querySelector("main"); - expect(main).toBeInTheDocument(); + it("should render the ActivityFeed widget", (): void => { + render(); + expect(screen.getByTestId("activity-feed")).toBeInTheDocument(); }); - it("should render the welcome subtitle", (): void => { + it("should render the TokenBudget widget", (): void => { render(); - expect(screen.getByText(/Welcome back/)).toBeInTheDocument(); + expect(screen.getByTestId("token-budget")).toBeInTheDocument(); }); }); diff --git a/apps/web/src/components/dashboard/DomainOverviewWidget.tsx b/apps/web/src/components/dashboard/DomainOverviewWidget.tsx deleted file mode 100644 index 577bf3c..0000000 --- a/apps/web/src/components/dashboard/DomainOverviewWidget.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import type { Task } from "@mosaic/shared"; -import { TaskStatus, TaskPriority } from "@mosaic/shared"; - -interface DomainOverviewWidgetProps { - tasks: Task[]; - isLoading: boolean; -} - -export function DomainOverviewWidget({ - tasks, - isLoading, -}: DomainOverviewWidgetProps): React.JSX.Element { - if (isLoading) { - return ( -
-
-
- Loading overview... -
-
- ); - } - - const stats = { - total: tasks.length, - inProgress: tasks.filter((t) => t.status === TaskStatus.IN_PROGRESS).length, - completed: tasks.filter((t) => t.status === TaskStatus.COMPLETED).length, - highPriority: tasks.filter((t) => t.priority === TaskPriority.HIGH).length, - }; - - const StatCard = ({ - label, - value, - color, - }: { - label: string; - value: number; - color: string; - }): React.JSX.Element => ( -
-
{value}
-
{label}
-
- ); - - return ( -
-

Domain Overview

-
- - - - -
-
- ); -} diff --git a/apps/web/src/components/dashboard/QuickCaptureWidget.tsx b/apps/web/src/components/dashboard/QuickCaptureWidget.tsx deleted file mode 100644 index 96cac82..0000000 --- a/apps/web/src/components/dashboard/QuickCaptureWidget.tsx +++ /dev/null @@ -1,85 +0,0 @@ -"use client"; - -import { useState } from "react"; -import { Button } from "@mosaic/ui"; -import { useRouter } from "next/navigation"; -import { ComingSoon } from "@/components/ui/ComingSoon"; - -/** - * Check if we're in development mode (runtime check for testability) - */ -function isDevelopment(): boolean { - return process.env.NODE_ENV === "development"; -} - -/** - * Internal Quick Capture Widget implementation - */ -function QuickCaptureWidgetInternal(): React.JSX.Element { - const [idea, setIdea] = useState(""); - const router = useRouter(); - - const handleSubmit = (e: React.SyntheticEvent): void => { - e.preventDefault(); - if (!idea.trim()) return; - - // TODO: Implement quick capture API call - // For now, just show a success indicator - console.log("Quick capture:", idea); - setIdea(""); - }; - - const goToTasks = (): void => { - router.push("/tasks"); - }; - - return ( -
-

Quick Capture

-

Quickly jot down ideas or brain dumps

-
-