-
Notifications
You must be signed in to change notification settings - Fork 0
docs: update README and CLAUDE.md with current state #344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,7 @@ npm run lint # ESLint (server + frontend) | |
| npm run lint:fix # ESLint with auto-fix | ||
| npm run format # Prettier (write) | ||
| npm run format:check # Prettier (check only) | ||
| npm test # Vitest (22000+ tests across all packages) | ||
| npm test # Vitest (2587 tests across 177 suites) | ||
| ``` | ||
|
|
||
| **Deployment:** Mitzo runs as a launchd service (`com.mitzo.server`). The server is compiled to JS via `tsc` (not live-transpiled). Run `npm run deploy` to build and restart. Logs in `logs/server-{stdout,stderr}.log`. | ||
|
|
@@ -53,9 +53,19 @@ The production backend stays untouched on `:3100`. Only the frontend is swapped. | |
|
|
||
| ## Architecture | ||
|
|
||
| Web-based command center for Claude Code sessions via the Agent SDK. Two npm projects share one repo: | ||
| Web-based command center for Claude Code sessions via the Agent SDK. The repo uses an npm workspace with three internal packages and two main directories: | ||
|
|
||
| **Backend** (`server/`) β Node.js + Express + TypeScript, run via `tsx` | ||
| ### Packages (`packages/`) β npm workspace | ||
|
|
||
| | Package | Purpose | | ||
| | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | `@mitzo/protocol` | Core protocol types, Zod schemas (v2 WS messages, API schemas), tool summarization, event store definitions. Exports event-store module separately. | | ||
| | `@mitzo/harness` | Session registry, connection registry, permission handler, worktree guard, tool tiers, skill policy, auto-rename, notifications, logger | | ||
| | `@mitzo/client` | Frontend state management: `MitzoConnection` (single multiplexed WS), Zustand store (`createMitzoStore`), v2 protocol parser, session switching, message reducer | | ||
|
|
||
| ### Backend (`server/`) β Node.js + Express + TypeScript, run via `tsx` | ||
|
|
||
| **Core** β Event streaming, session lifecycle, SDK integration | ||
|
|
||
| - `index.ts` β Express app, mounts routes, HTTP server + WebSocket. Sends `client_id` on WS connect for session reattach. Runs stale worktree cleanup on startup. | ||
| - `app.ts` β Express app factory (extracted from index.ts for testability via supertest). | ||
|
|
@@ -64,59 +74,119 @@ Web-based command center for Claude Code sessions via the Agent SDK. Two npm pro | |
| - `session-registry.ts` β `SessionRegistry` class: detach/reattach/rekey, TTL-based abort (10 min), `currentSnapshot` for reattach recovery, `findBySessionId` for reconnection. | ||
| - `permission-handler.ts` β Builds the `canUseTool` callback for SDK permission flow. Checks skill policy β worktree guard β `shouldAutoAllow()` before prompting. Falls back to WS-based prompting with ntfy/Pushover notifications. | ||
| - `async-queue.ts` β `AsyncQueue<T>` implementing `AsyncIterable<T>` for streaming-input. Supports `push()` for follow-up messages and `close()` for session teardown. | ||
| - `tool-tiers.ts` β Tool risk classification (`safe`, `standard`, `elevated`, `unknown`). `shouldAutoAllow()` implements mode x tier matrix. `.mitzo.json` tier overrides via `applyTierOverrides()`. | ||
| - `tool-summary.ts` β Tool input summarization. **SDK field names**: `file_path` (not `path`), `content` (not `contents`), `pattern`/`path` for Glob (not `glob_pattern`/`target_directory`). | ||
| - `content-blocks.ts` β SDK content block parsing (text, tool_use, tool_result). Used by stream and session restore API. | ||
| - `permissions.ts` β Permission request/response registry with tier metadata. | ||
|
|
||
| **Skills** β Slash-command system | ||
|
|
||
| - `skills.ts` β Skill registry: scoped discovery (bundled β user β repo), lazy metadata/body loading, deterministic precedence, collision tracking. | ||
| - `slash-commands.ts` β Slash-command parsing, prompt expansion, skill resolution from user input. | ||
| - `skill-policy.ts` β Per-turn tool restriction: skills declare `allowed-tools` in frontmatter, enforced as a ceiling on `canUseTool`. | ||
| - `native-commands.ts` β Built-in native commands (`/skills`) β TypeScript product behavior, not prompt-based. | ||
| - `auto-rename.ts` β Automatic session renaming every N user prompts via LLM summarization. | ||
| - `event-store.ts` β Persistent event store for session message replay. | ||
| - `hook-bridge.ts` β Bridges project-level hooks (`.claude/settings.json`) to Agent SDK sessions. | ||
| - `api-schemas.ts` β Zod schemas for HTTP request/response validation. | ||
| - `ws-schemas.ts` β Zod schemas for WebSocket message validation. | ||
| - `internal-token.ts` β Internal token generation for inter-process auth. Persisted to `~/.mitzo/internal-token` at startup so session hooks can authenticate with `POST /api/sessions`. | ||
| - `session-index.ts` β YAML session index at `<repo>/.claude/sessions/index.yaml`. Tracks active/closed sessions with repo worktree mappings. | ||
| - `repo-mcp-server.ts` β Repo-scoped MCP server configuration. | ||
| - `notification-helpers.ts` β Shared notification formatting utilities. | ||
| - `inbox.ts` β Inbox integration endpoint. | ||
|
|
||
| **Task Board** β Multi-session orchestration | ||
|
|
||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π‘ bugs: |
||
| - `task-store.ts` β `TaskStore` class: SQLite persistence for tasks with tree queries, cascade status, DFS ordering, orphan detection. WAL mode + foreign keys. | ||
| - `task-tools.ts` β Pure handler functions for agent task tools (TaskSet, TaskComplete, TaskStatus, TaskBlock). Never throw β return error strings. | ||
| - `task-mcp-server.ts` β Stdio MCP server exposing task tools as `mcp__task-board__*`. Calls back to internal HTTP endpoints. | ||
| - `task-context.ts` β XML task context builder for system prompt injection. Includes current task, siblings, parent tree, and summaries (capped at 2000 chars). | ||
| - `task-orchestrator.ts` β `TaskOrchestrator`: event-driven state machine (idle/running/paused) with DFS sequential task assignment. Spec mode for human review of decompositions. Orphan detection reclaims tasks from dead sessions. | ||
|
|
||
| **Worktrees & Session Isolation** | ||
|
|
||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π‘ bugs: Lib count says "27 utility files" but there are 28 actual files in |
||
| - `worktree.ts` β Git worktree lifecycle: `createWorktree` (with optional dir/branch/prefix overrides), `createSessionWorktrees` (bulk creation for all repos), `removeWorktree`, `cleanupStaleWorktrees` (scans both `.claude/worktrees/` and `.cursor/worktrees/`), `listWorktrees`. | ||
| - `session-index.ts` β YAML session index at `<repo>/.claude/sessions/index.yaml`. Tracks active/closed sessions with repo worktree mappings. | ||
|
|
||
| **Observability** | ||
|
|
||
| - `logger.ts` β Pino structured logging: JSON output, `LOG_LEVEL` env filtering, pino-roll daily file rotation to `logs/`, OTel trace context mixin (trace_id/span_id), pino-pretty for dev. Lazy singleton init to avoid import-time side effects in tests. Loki integration when `LOKI_HOST` is set. | ||
| - `tracing.ts` β OpenTelemetry: BatchSpanProcessor with OTLP HTTP exporter to Jaeger. Opt-in when `OTEL_EXPORTER_OTLP_ENDPOINT` is set. | ||
| - `trace-context.ts` β Trace context utilities. | ||
| - `health-monitor.ts` β Service health monitoring (Yapper, ContexGin). | ||
|
|
||
| **Notifications** | ||
|
|
||
| - `notify.ts` β ntfy push notifications. | ||
| - `pushover.ts` β Pushover (Apple Watch) notifications. | ||
| - `apns.ts` β Apple Push Notification Service (iOS native). | ||
| - `notification-helpers.ts` β Shared notification formatting utilities. | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π‘ bugs: Component count says "48 components" but there are 51 actual component files in |
||
|
|
||
| **WebSocket & Transport** | ||
|
|
||
| - `ws-handler-v2.ts` β v2 WebSocket message dispatcher: hello handshake β session routing for send/stop/interrupt/permission_response/set_mode. | ||
| - `ws-transport.ts` β `SessionTransport` adapter wrapping WebSocket connections. | ||
| - `connection-registry.ts` (harness) β `ConnectionRegistry`: maps connectionId β transport + sessionId, broadcasts to session observers. | ||
| - `mcp-config.ts` β Loads MCP server configs from Cursor mcp.json. | ||
| - `worktree.ts` β Git worktree lifecycle: `createWorktree` (with optional dir/branch/prefix overrides), `createSessionWorktrees` (bulk creation for all repos), `removeWorktree`, `cleanupStaleWorktrees` (scans both `.claude/worktrees/` and `.cursor/worktrees/`), `listWorktrees`. | ||
| - `worktree-guard.ts` (harness) β `checkWorktreePolicy()`: inspects Write/Edit/Bash tool inputs against session worktree paths. Denies out-of-bounds writes with a redirect message. Read operations pass through. | ||
| - `null-transport.ts` β Null transport for testing. | ||
| - `ws-schemas.ts` β Zod schemas for WebSocket message validation. | ||
|
|
||
| **Supporting** | ||
|
|
||
| - `tool-tiers.ts` β Tool risk classification (`safe`, `standard`, `elevated`, `unknown`). `shouldAutoAllow()` implements mode x tier matrix. `.mitzo.json` tier overrides via `applyTierOverrides()`. | ||
| - `tool-summary.ts` β Tool input summarization. **SDK field names**: `file_path` (not `path`), `content` (not `contents`), `pattern`/`path` for Glob (not `glob_pattern`/`target_directory`). | ||
| - `content-blocks.ts` β SDK content block parsing (text, tool_use, tool_result). Used by stream and session restore API. | ||
| - `permissions.ts` β Permission request/response registry with tier metadata. | ||
| - `event-store.ts` β Persistent event store for session message replay. | ||
| - `auto-rename.ts` β Automatic session renaming every N user prompts via LLM summarization. | ||
| - `hook-bridge.ts` β Bridges project-level hooks (`.claude/settings.json`) to Agent SDK sessions. | ||
| - `api-schemas.ts` β Zod schemas for HTTP request/response validation. | ||
| - `internal-token.ts` β Internal token generation for inter-process auth. Persisted to `~/.mitzo/internal-token` at startup so session hooks can authenticate with `POST /api/sessions`. | ||
| - `repo-config.ts` β `.mitzo.json` reader for quick actions, venv paths, tier overrides, and `repos` (secondary repo paths for multi-repo worktrees). | ||
| - `notify.ts` / `pushover.ts` β Push notifications (ntfy + Pushover/Apple Watch). | ||
| - `mcp-config.ts` β Loads MCP server configs from Cursor mcp.json. | ||
| - `inbox.ts` β Inbox integration endpoint. | ||
| - `auth.ts` β Passphrase login, JWT (HS256 via jose), cookie auth. | ||
| - `logger.ts` β Pino structured logging: JSON output, `LOG_LEVEL` env filtering, pino-roll daily file rotation to `logs/`, OTel trace context mixin (trace_id/span_id), pino-pretty for dev. Lazy singleton init to avoid import-time side effects in tests. | ||
| - `constants.ts` β Server-wide constants (timeouts, buffer limits, defaults). | ||
| - `git-version.ts` β Local/remote commit comparison for update detection. | ||
| - `port-check.ts` β Prevents duplicate server instances. | ||
| - `constants.ts` β Server-wide constants (timeouts, buffer limits, defaults). | ||
| - `goal-client.ts` β ContexGin Goal Registry client. | ||
| - `progress-tracker.ts` β Progress tracking utilities. | ||
| - `prompt-compare.ts` β Prompt comparison utilities. | ||
| - `workflow-templates.ts` β Workflow templates. | ||
| - `workload-store.ts` β Workload persistence. | ||
| - `session-overview.ts` β Session overview API. | ||
| - `signal-processor.ts` β Signal processing utilities. | ||
|
|
||
| **Packages** (`packages/`) β npm workspace packages shared between server and frontend | ||
|
|
||
| - `@mitzo/protocol` β Shared types, Zod schemas (v2 WS messages, API schemas), tool summarization. | ||
| - `@mitzo/harness` β Session registry, connection registry, permission handler, worktree guard, tool tiers, skill policy, auto-rename, notifications, logger. | ||
| - `@mitzo/client` β Frontend state management: `MitzoConnection` (single multiplexed WS), Zustand store (`createMitzoStore`), v2 protocol parser, session switching, message reducer. | ||
| ### Frontend (`frontend/`) β React 19 + Vite + TypeScript | ||
|
|
||
| **Frontend** (`frontend/`) β React 19 + Vite + TypeScript | ||
| **Types** β `types/` directory | ||
|
|
||
| - `types/chat.ts` β v2 types: `StreamingBlock`, `StreamingMessage`, `FinishedBlock`, `FinishedMessage`, `BlockType`, `RawToolInput`, `PermissionRequest`, `ToolTier`, `Session`, `ImageAttachment`. | ||
| - `types/ws-messages.ts` β Typed WebSocket message unions (client β server, server β client). | ||
| - `types/task.ts` β Task model types (`Task`, `TaskStatus`, `LoopStatus`, `SessionPolicy`). | ||
| - `hooks/` β `useChatMessages` (useReducer for v2 protocol: MESSAGE_START/BLOCK_START/BLOCK_DELTA/BLOCK_END/TOOL_RESULT/MESSAGE_END/SESSION_END/MESSAGE_SNAPSHOT/RESTORE), `useChatSession`, `useChatConnection`, `usePermission`, `useTaskBoard` (task CRUD + loop control + WS subscriptions), `useFileNavigation`, `useFileEditor`, `useLongPress`. | ||
| - `lib/` β `groupMessages` (tool block grouping with configurable threshold), `constants`, `formatTime`, `paste-images`, `model-preference`, `rename-session`, `resizeImage`, `swipe-reveal`, `truncate`. | ||
| - Pages: `Login`, `SessionList`, `ChatView` (renders `current` inline + `messages[]` grouped), `DesktopChatView`, `FileViewer`, `InboxView`, `CalendarView`, `TodoView`, `TodoDetailView`, `TaskBoard`. | ||
| - Components: `MessageBubble` (UserBubble/TextBubble), `ThinkingBlock`, `ToolPill`, `ToolGroup`, `PermissionBanner`, `ChatInput`, `SlashPicker`, `ErrorBoundary`, `MitzoLogo`, `TaskNode`, `TaskCreateForm`, `LoopControls`, `TaskSidebar`. | ||
| - Auth via `ProtectedRoute` wrapper. Vite dev server proxies `/api` and `/ws` to backend. | ||
|
|
||
| **Hooks** β `hooks/` directory (21 hooks) | ||
|
|
||
| - `useChatMessages` β useReducer for v2 protocol: MESSAGE_START/BLOCK_START/BLOCK_DELTA/BLOCK_END/TOOL_RESULT/MESSAGE_END/SESSION_END/MESSAGE_SNAPSHOT/RESTORE | ||
| - `useTaskBoard` β task CRUD + loop control + WS subscriptions | ||
| - `useVoice` β STT (push-to-talk) + TTS (auto-speak toggle, voice selection, sequential chunk playback) | ||
| - `useFileNavigation` / `useFileEditor` β file browser and editing | ||
| - `useSessionOverview` β session metadata and statistics | ||
| - `useAutoSpeak` β auto-speak TTS preferences | ||
| - `useServiceHealth` β health status for Yapper, ContexGin | ||
| - `useCalendarData`, `useTodoData`, `useSessionList`, `useSessionSearch`, `useAttentionFeed`, `useProgress`, `useDocumentReader`, `useDraft`, `useTabBadges`, `useTheme`, `useLongPress`, `useMediaQuery`, `useQueuedMessages`, `useCopyFeedback` | ||
|
|
||
| **Lib** β `lib/` directory (27 utility files) | ||
|
|
||
| - `groupMessages` β tool block grouping with configurable threshold | ||
| - `tts.ts` β Text chunking at sentence boundaries, WAV synthesis via Yapper API, singleton AudioContext playback | ||
| - `api-fetch`, `audio`, `biometric`, `capacitor`, `clipboard`, `constants`, `event-bus-singleton`, `extractText`, `file-paths`, `formatTime`, `formatTokens`, `haptics`, `inbox-utils`, `keyboard`, `model-preference`, `paste-images`, `push`, `rename-session`, `resizeImage`, `splash`, `swipe-reveal`, `todo-utils`, `tracing`, `truncate`, `watch-auth`, `yapper-ws` | ||
|
|
||
| **Pages** β 10 pages | ||
|
|
||
| - `Login`, `SessionList`, `ChatView` (renders `current` inline + `messages[]` grouped), `DesktopChatView`, `FileViewer`, `InboxView`, `CalendarView`, `TodoView`, `TodoDetailView`, `TaskBoard` | ||
|
|
||
| **Components** β 48 components | ||
|
|
||
| - **Message rendering:** `MessageBubble` (UserBubble/TextBubble), `ThinkingBlock`, `ToolPill`, `ToolGroup`, `PermissionBanner` | ||
| - **Input:** `ChatInput`, `SlashPicker`, `MicButton` | ||
| - **Task board:** `TaskNode`, `TaskCreateForm`, `LoopControls`, `TaskSidebar`, `TaskBoardSection` | ||
| - **Navigation:** `DesktopNav`, `DesktopShell`, `MobileShell`, `TabBar`, `PageHeader` | ||
| - **Session management:** `ActiveSessionsList`, `SessionPanel`, `SessionOverview`, `SessionSearchBar` | ||
| - **File browser:** `FileBrowserPanel` | ||
| - **Context:** `ContextBlock`, `ContextPanel`, `ContextPicker`, `BootContextPill` | ||
| - **Voice:** `VoiceSettings`, `ReadAloudButton` | ||
| - **Utilities:** `ErrorBoundary`, `MitzoLogo`, `EmptyState`, `CopyButton`, `ScrollFab`, `StatusBar`, `TokenBar`, `ServiceStatus`, `ProgressWidget`, `CollapsibleSection` | ||
| - **Content cards:** `BriefingCard`, `EventCard`, `MarkdownPreviewCard`, `SubagentCard`, `TodoCard` | ||
| - **Sections:** `AttentionFeed`, `InboxSection`, `TelosSection`, `CommandCenter`, `SprintBar` | ||
| - **Forms:** `WorkflowCreateForm` | ||
|
|
||
| Auth via `ProtectedRoute` wrapper. Vite dev server proxies `/api` and `/ws` to backend. | ||
|
|
||
| **v2 protocol β key reducer behaviors:** | ||
|
|
||
|
|
@@ -206,14 +276,14 @@ Web-based command center for Claude Code sessions via the Agent SDK. Two npm pro | |
|
|
||
| - Skills are reusable prompt packages invoked via `/slash-command` in chat input. | ||
| - Three scopes: **Native** (TypeScript commands like `/skills`), **Skills** (markdown with YAML frontmatter), **Quick actions** (launchers from `.mitzo.json`). | ||
| - Discovery: repo-local (`.mitzo/skills/`), user (`~/.mitzo/skills/`), bundled (`server/bundled-skills/`). | ||
| - Discovery: repo-local (`.mitzo/skills/`), user (`~/.mitzo/skills/`), bundled (`./skills/`). | ||
| - Resolution order: Native β Repo β User β Bundled. Deterministic precedence with collision metadata. | ||
| - `SlashPicker` component shows available skills when user types `/` in chat input, with type badges and collision notes. | ||
| - Skills can declare `allowed-tools` in frontmatter β enforced as a ceiling (never expands permissions) via `skill-policy.ts`. | ||
| - Bundled skills: `/simplify` (complexity, duplication, cleanup), `/risk-scan` (failure modes, missing tests, unsafe assumptions), `/pr-review` (diff/branch code review), `/person` (people profile lookup and update), `/review-response` (triage and fix PR review comments). | ||
| - Bundled skills: `/simplify` (complexity, duplication, cleanup), `/risk-scan` (failure modes, missing tests, unsafe assumptions), `/pr-review` (diff/branch code review), `/person` (people profile lookup and update), `/review-response` (triage and fix PR review comments), `/land-pr` (shepherd a PR from open to merged), `/pr-shepherd` (persistent PR monitoring and lifecycle). | ||
| - `GET /api/skills` returns merged registry with collision info, scoped by `cwd` query param. | ||
|
|
||
| **Voice integration (landing with PR #108):** | ||
| **Voice integration:** | ||
|
|
||
| - Client-direct architecture: frontend talks to [Yapper](~/projects/yapper/) for STT/TTS, server stays text-only. | ||
| - `lib/tts.ts` β Text chunking at sentence boundaries, WAV synthesis via Yapper API, singleton AudioContext playback. | ||
|
|
@@ -260,7 +330,7 @@ All feature work follows TDD. This is not optional. | |
| ### Running Tests | ||
|
|
||
| ```bash | ||
| npm test # Vitest β full suite | ||
| npm test # Vitest β full suite (2587 tests across 177 suites) | ||
| npm test -- --watch # Watch mode during development | ||
| npm test -- <path> # Run specific test file | ||
| ``` | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π΅ unsafe_assumptions: Hardcoded test count "2587 tests across 177 suites" will go stale as soon as tests are added or removed. Consider a range or removing the count entirely (the command
npm testis self-documenting). The previous value "22000+" was already wrong, and this replacement will be too eventually.[fixable]