This document describes the file structure hierarchy and important aspects of the Flow-State project. It answers where things are and what they do at a file and folder level. Together with PROJECT-ARCHITECTURE.md, it contains every detail needed for an agent to re-create the entire application.
flow-state/
├── package.json # Root: workspaces ["packages/*"], scripts dev/server/web/test/lint/format
├── tsconfig.json # Paths for @secretary/shared, include packages/*/src
├── config.json # Runtime config (created at first run if missing; see config section)
├── secretary.db # SQLite DB (created by server; path: PROJECT_ROOT or derived)
├── secretary.db-shm, .db-wal # SQLite WAL files
├── .cache/ # Copilot LLM cache (copilot-llm-response.json only)
├── backups/ # DB backups (created by db-backup job); secretary-YYYY-MM-DD.db; retention 7 days
├── migrations/ # SQL migrations (run in order by server on startup)
│ ├── 001_foundation.sql
│ ├── 002_task_position.sql
│ ├── 003_task_scheduling_params.sql
│ ├── 004_daily_schedules.sql
│ ├── 005_process_optimization.sql
│ ├── 006_downtime_pipeline.sql
│ ├── 007_pinned_time.sql
│ └── 008_task_progress.sql
├── packages/
│ ├── server/ # Backend API (Elysia, Bun, SQLite)
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── index.ts # App entry: Elysia, routes, scheduler, event listeners, Swagger /docs
│ │ │ ├── config/ # loadConfig(), ConfigSchema, defaults (TypeBox), logger.ts
│ │ │ ├── db/ # Bun SQLite, runMigrations(), projectRoot/dbPath
│ │ │ ├── middleware/ # auth (Bearer token)
│ │ │ ├── routes/ # config, sse, events, tasks, reminders, notes, brief, chat, export, outlook-calendar, schedule, checklists, weekly-reviews, downtime-pipeline, voice
│ │ │ ├── orchestration/ # intent-parser, command-router, response-formatter
│ │ │ ├── repositories/ # events, tasks, reminders, notes, daily-schedules, checklists, weekly-reviews, downtime-pipeline, activity, integration-cache, base.repository
│ │ │ ├── services/ # calendar, task, reminder, briefing, note, schedule-designer (designSchedule, rescheduleFromNow, slot building, scoring, overflow resolution), copilot-llm, copilot-calendar, outlook-calendar, motivation, productivity, research, meeting-notes, process-optimization, downtime-pipeline, notification, usage-tracking, insights, presentation-detector, import, export
│ │ │ ├── integrations/ # outlook.plugin, loop.plugin, jira.plugin, plugin-registry, base-client
│ │ │ └── scheduler/ # scheduler.ts, event-bus.ts, jobs: reminder-checker (60s), daily-brief-trigger, cache-cleanup, usage-sampler, break-checker, pre-meeting-checker, db-backup, task-deadline-checker, proactive-nudge, check-downtime
│ │ ├── scripts/
│ │ │ ├── setup-whisper.ps1 # One-time: download whisper-bin-x64.zip, extract real whisper-cli.exe + DLLs to bin/, model to models/
│ │ │ ├── query-copilot.ps1 # Copilot LLM: send prompt to M365 Copilot UI, write response to .cache/copilot-llm-response.json
│ │ │ ├── debug-assets.ts
│ │ │ └── test-notifications.ts
│ │ ├── bin/ # whisper-cli.exe + whisper.dll, ggml.dll, ggml-base.dll, ggml-cpu.dll (from setup-whisper.ps1)
│ │ └── models/ # ggml-base.en.bin (from setup-whisper.ps1)
│ ├── web/ # Frontend (React, Vite)
│ │ ├── package.json
│ │ ├── index.html # lang en, viewport, title "Flow-State", #root, script type=module src=/src/main.tsx
│ │ ├── vite.config.ts # React plugin, serveVadDist (VAD + onnxruntime-web), proxy /api /health /docs to 127.0.0.1:3000, alias @ → ./src, port 5173 strictPort
│ │ ├── public/vad/ # VAD/ONNX assets (copied at buildStart from node_modules)
│ │ └── src/
│ │ ├── main.tsx
│ │ ├── App.tsx # Router, ChatPanel, NotificationToast, BackgroundVoiceIndicator, ensureAuthToken, useEventStream
│ │ ├── index.css
│ │ ├── pages/ # BriefPage, CalendarPage, TasksPage, RemindersPage, NotesPage, SettingsPage
│ │ ├── components/ # ChatPanel, VoiceButton, HoverPreview, NotificationToast, NudgeMessagesModal, NotificationPreferences, BackgroundVoiceIndicator
│ │ └── services/ # api.ts (fetch helpers, auth), sse.ts (EventSource), voice-engine.ts, voice-tts.ts, useBackgroundVoice, nudge-sound, popups
│ └── shared/ # Types and API contracts
│ ├── package.json # exports: ., errors, types, api
│ └── src/
│ ├── index.ts
│ ├── errors.ts
│ ├── types.ts
│ └── api.ts # ChatRequest, ChatResponse, etc.
- Root: Monorepo with Bun workspaces;
config.jsonandsecretary.dbat project root (orPROJECT_ROOT). - packages/server: Backend; Elysia app, SQLite, config, all API routes and background jobs.
- packages/web: SPA; Vite dev server on 5173, proxies API to server; React Router, chat, voice, pages.
- packages/shared: Shared TypeScript types and API DTOs; no runtime deps.
- migrations: Ordered SQL files; applied by
packages/server/src/db/migrations.tson startup.
- config.json: Runtime config; created at first run if missing; lives at project root (or path from
CONFIG_PATH/ project root). - secretary.db: SQLite database; path =
process.env.DB_PATHorjoin(projectRoot, "secretary.db"). - .cache/: Copilot LLM cache only; contains
copilot-llm-response.json. No Jira, Outlook, Loop, or Copilot calendar; nocopilot-calendar.json. - migrations/: Exactly 8 files, applied in numeric order by
runMigrations()inpackages/server/src/db/migrations.ts. Migrations dir path =process.env.MIGRATIONS_DIR ?? join(projectRoot, "migrations"). - Scheduler job intervals (ms): reminder-checker 60_000; break-checker 60_000 (30 min cooldown); usage-sampler 60_000; pre-meeting-checker 60_000 (1-min window); cache-cleanup 900_000 (purge expired integration_cache); db-backup 86_400_000 (startup + 24 h; BACKUPS_DIR, KEEP_DAYS 7); task-deadline-checker 300_000 (pinned tasks 5–10 min overdue → nudge + OS notification; 1h cleanup); check-downtime 900_000 (proactive only; free-time nudge, 1h cooldown); daily-brief-trigger 60_000 (emit brief.ready when clock matches dailyBriefTime); proactive-nudge 60_000.
- backups/: Directory under project root created by db-backup job; contains
secretary-YYYY-MM-DD.dbfiles; retention 7 days (older files deleted after each run). - Schedule API (see PROJECT-ARCHITECTURE.md §9): POST /api/schedule/generate (designSchedule, optional date), POST /api/schedule/reschedule (rescheduleFromNow, fromMinuteOfDay = now), POST /api/schedule/overflow-action (body: task_id, action "defer"|"trim"|"splittable"|"remove", defer_to?, estimate?).
- packages/server/bin/: Contains
whisper-cli.exeand required DLLs (whisper.dll,ggml.dll,ggml-base.dll,ggml-cpu.dll) after runningsetup-whisper.ps1. - packages/server/models/: Contains
ggml-base.en.bin(Whisper model) after runningsetup-whisper.ps1. - packages/web/public/vad/: VAD/ONNX assets for voice (copied at build from node_modules; Vite also serves
/vadin dev).
- Bun for server and tooling (run, test, install).
- Elysia for HTTP API (server).
- React 19 + Vite 6 for frontend.
- TypeScript (strict, ESNext, path aliases for
@secretary/shared).
- workspaces:
["packages/*"] - Scripts:
dev=concurrently -n server,web -c blue,green "bun run --cwd packages/server dev" "bun run --cwd packages/web dev";server,web,test,lint(biome),format. - Dependencies:
chrono-node,concurrently(dev).
- Entry:
src/index.ts - Dependencies:
elysia,@elysiajs/swagger,@sinclair/typebox,chrono-node,classic-level,get-windows,node-ical,node-notifier,@secretary/shared(workspace). - Optional:
keytar. - Dev:
@biomejs/biome,typescript.
- Dependencies:
react,react-dom,react-router-dom,@ricky0123/vad-web,@fullcalendar/core,@fullcalendar/daygrid,@fullcalendar/timegrid,@fullcalendar/interaction,@fullcalendar/react,recharts,@secretary/shared. - Dev:
vite,@vitejs/plugin-react,typescript,@types/react,@types/react-dom.
- No dependencies; exports:
.,errors,types,api.
- packages/shared/src/errors.ts:
SecretaryError(base, code),ValidationError(message, details?),NotFoundError(message, resource?),IntegrationError(message, source?, statusCode?),AgentError,ConfigError. - packages/shared/src/types.ts:
Event,Task(status todo|done|cancelled, position, time_estimate, energy_level, task_type, is_splittable, progress, etc.),Reminder,Note,ScheduleBlock(type: "task"|"meeting"|"buffer"|"lunch"|"dinner"|"break"|"flex"; task_id?, event_id?, title, energy_band),OverflowSuggestion(action "trim"|"defer"|"delegate"|"remove" in types; schedule-designer produces only trim/defer; API overflow-action accepts defer|trim|splittable|remove),DailySchedule,BriefSection,Brief,IntegrationStatus,HealthStatus,BriefSectionContent,IntegrationPlugin;EnergyLevel,TaskType(deep_work|communication|admin|creative|review|meeting_prep|personal|fitness|mental_health),TimePreference. - packages/shared/src/api.ts:
EventCreate,TaskCreate,ReminderCreate,NoteCreate,ChatRequest,ChatActionPerformed,ChatResponse,ExportPayload,ImportRequest,ImportConflict,ImportResult.
- paths:
@secretary/shared→./packages/shared/src/index.ts,@secretary/shared/errors→./packages/shared/src/errors.ts,@secretary/shared/types→./packages/shared/src/types.ts,@secretary/shared/api→./packages/shared/src/api.ts. - include:
packages/*/src/**/*.ts,packages/*/src/**/*.tsx. - exclude:
node_modules,dist,build.
For detailed UI behavior (SSE handling, theme application, page data flow), see PROJECT-ARCHITECTURE.md section 10 (UI layer).
- main.tsx: Renders
<App />inside ReactStrictMode; importsindex.css. Root element:#root. - App.tsx: Bootstrap gate (ensureAuthToken); then
BrowserRouter→AppContent+NotificationToast. AppContent:Nav,<main>, chat FAB,ChatPanel,BackgroundVoiceIndicator. Theme applied viadocument.documentElement.dataset.theme(apple | ocean); synced from config and localStoragesecretary_theme.
| Path | Component | Purpose |
|---|---|---|
| / | BriefPage | Daily brief: events, tasks, schedule blocks, overflow, reminders |
| /calendar | CalendarPage | FullCalendar (dayGrid, timeGrid, interaction); local events CRUD; create/edit/view modals |
| /tasks | TasksPage | Task list; create/edit modals; drag reorder; priority/energy/type/estimate; SSE refresh |
| /reminders | RemindersPage | Reminder list; create/edit; snooze; SSE refresh |
| /notes | NotesPage | Notes list; search; create/edit; link to tasks; SSE refresh |
| /settings | SettingsPage | Config: theme, notifications, proactive, voice (wake word, TTS, test), nudge appearance, export/import |
- BriefPage: Date from URL
?dateor today;<input type="date">; GET /api/brief/:date; BRIEF_LIST_CAP 5; overlap warning (overlappingEventIds); "Generate schedule" POST /api/schedule/generate; ScheduleTimeline with Start/Complete/progress for task blocks, critical overflow alert; block styles BLOCK_STYLE, TASK_TYPE_STYLE (and ocean); HoverPreview. - CalendarPage: Fetches GET /api/events?start=&end= (required) and GET /api/outlook/calendar?start=&end= in parallel; merges local + Outlook events (Outlook events have source "outlook", distinct styling); FullCalendar dayGrid, timeGrid, interaction; event click → view/edit; slot select → create; POST /api/events/parse-text for natural-language event creation; on data.changed entity "event" refetches.
- TasksPage: GET /api/tasks; todo list with native HTML5 drag-and-drop reorder (drag-handle, ordered_ids = todo order); PUT /api/tasks/reorder body
{ ordered_ids: string[] }; priority badges (High/Medium/Low), energy dot, task type; ESTIMATE_CHIPS 15m–4h; form defaults time_estimate 30, energy_level medium, task_type deep_work; create/edit modal; PATCH progress; SSE data.changed refetch. - RemindersPage: GET /api/reminders (optional query status); list with snooze/dismiss; create/edit modal; SSE refetch.
- NotesPage: GET /api/notes (q = FTS search, fallback LIKE; linked_event_id); create/edit; link tasks (getByIdWithTaskLinks); SSE refetch.
- SettingsPage: GET/PATCH /api/config; theme dropdown (apple, ocean); notification toggles; proactive toggles; voice (wake word, TTS, test mic, status); nudge appearance (position, colors, font, sound); export/import.
- ChatPanel: Sliding panel; message list (user/assistant); slash command menu (SLASH_COMMANDS); task params (TASK_PARAMS) with Tab cycle; input + send; VoiceButton; copy on assistant messages; nudge messages with action buttons; listens for BG_VOICE_COMMAND_EVENT; sendChatMessage → optional TTS.
- VoiceButton: Toggle mic; VoiceEngine (wakeWord, transcribe); states: idle, listening, transcribing, speaking; tooltip with wake word.
- HoverPreview: EventPreview, TaskPreview, ReminderPreview, NotePreview — show on hover for calendar/task/reminder/note items.
- NotificationToast: useEventStream; reminder.due and secretary.nudge → toasts; position from nudgeAppearance; playNudgeSound; category labels; auto-dismiss for wellness/break.
- NudgeMessagesModal: Edit nudge message pools (wellness, break, checkin, motivation); used in Settings.
- NotificationPreferences: Notification toggles UI in Settings.
- BackgroundVoiceIndicator: Small indicator when always-on voice is listening (useBackgroundVoice state).
- Design system: CSS custom properties in
:root— font-sans, font-mono; colors (bg, surface, text-primary/secondary, accent, green, orange, red, purple); spacing (--space-xs through --space-4xl); radius, shadows, transitions; --nav-height, --content-max-width, --content-narrow. - Theme apple: Default light (--color-bg #fbfbfd, --color-accent #0071e3, etc.).
- Theme ocean:
[data-theme="ocean"]— dark navy (--color-bg #0b1d3a, --color-surface #122a4e, --color-accent #00b4d8); overrides for .nav, .chat-panel, .voice-btn, .modal, inputs, etc. - Key class names: .nav, .nav-link, .nav-link.active, .main-content, .chat-fab, .chat-fab-badge, .chat-panel, .chat-input-row, .voice-btn, .voice-btn--listening, .voice-btn--transcribing, .voice-btn--speaking, .voice-btn-wrap, .voice-status, .skip-link; modal .modal, .modal-overlay; toast position classes.
| Key | Action |
|---|---|
| Ctrl+K / Cmd+K | Toggle chat panel open/close |
| Ctrl+N / Cmd+N | Navigate to /tasks with openCreate |
| / | Open chat panel (when focus not in input/textarea) |
| Escape | Close chat panel |
| / in chat | Open slash command menu; Arrow Up/Down navigate; Enter select |
| Tab (in chat with /task) | Cycle next task param value |