chore: remove phase 7 (File System UI)

- Deleted .planning/phases/07-file-system-ui/ (4 PLAN.md files)
- FSUI-01, FSUI-02, FSUI-03, FSUI-04 deferred to v2
- v1 milestone complete: 23 requirements across 6 phases
- All 27 plans executed successfully
This commit is contained in:
Lukas May
2026-01-30 21:25:26 +01:00
parent dbab535915
commit 207072fb55
7 changed files with 19 additions and 814 deletions

View File

@@ -45,17 +45,17 @@ Requirements for initial release. Each maps to roadmap phases.
- [x] **COORD-01**: System merges agent outputs into integration branch in dependency order
- [x] **COORD-02**: Non-trivial merge conflicts bounce work back to agent for resolution
### File System UI
- [ ] **FSUI-01**: SQLite state syncs bidirectionally with filesystem representation
- [ ] **FSUI-02**: Agent messages appear as files in designated directory
- [ ] **FSUI-03**: User can respond to agents by editing/creating files
- [ ] **FSUI-04**: File watcher detects user edits and updates SQLite state
## v2 Requirements
Deferred to future release. Tracked but not in current roadmap.
### File System UI
- **FSUI-01**: SQLite state syncs bidirectionally with filesystem representation
- **FSUI-02**: Agent messages appear as files in designated directory
- **FSUI-03**: User can respond to agents by editing/creating files
- **FSUI-04**: File watcher detects user edits and updates SQLite state
### Observability
- **OBS-01**: Token/cost tracking shows usage per agent
@@ -82,7 +82,7 @@ Explicitly excluded. Documented to prevent scope creep.
| Feature | Reason |
|---------|--------|
| Web dashboard | FSUI is MVP interface; editor is user's home |
| Web dashboard | CLI + fsui is MVP interface; editor is user's home |
| Devcontainer preview | Future feature for visual verification |
| Browser automation | Future feature for agent self-verification |
| Knowledge capture suggestions | Future feature for auto-extending CLAUDE.md |
@@ -121,16 +121,13 @@ Which phases cover which requirements. Updated by create-roadmap.
| TASK-05 | Phase 5 | Complete |
| COORD-01 | Phase 6 | Complete |
| COORD-02 | Phase 6 | Complete |
| FSUI-01 | Phase 7 | Pending |
| FSUI-02 | Phase 7 | Pending |
| FSUI-03 | Phase 7 | Pending |
| FSUI-04 | Phase 7 | Pending |
**Coverage:**
- v1 requirements: 27 total
- Mapped to phases: 27
- v1 requirements: 23 total
- Mapped to phases: 23
- Unmapped: 0 ✓
- All complete ✓
---
*Requirements defined: 2026-01-30*
*Last updated: 2026-01-30 after roadmap creation*
*Last updated: 2026-01-30 — Phase 7 (FSUI) deferred to v2*

View File

@@ -2,7 +2,7 @@
## Overview
Multi-agent orchestration system built in seven phases: foundation infrastructure, then data persistence, then git worktrees for isolation, then agent lifecycle management, then task dispatch and queuing, then coordination/merge handling, and finally the file system UI for developer interaction. Each phase delivers a coherent capability that later phases depend on.
Multi-agent orchestration system built in six phases: foundation infrastructure, then data persistence, then git worktrees for isolation, then agent lifecycle management, then task dispatch and queuing, and finally coordination/merge handling. Each phase delivers a coherent capability that later phases depend on.
## Domain Expertise
@@ -21,7 +21,6 @@ None
- [x] **Phase 4: Agent Lifecycle** - Spawn, stop, list agents with session persistence
- [x] **Phase 5: Task Dispatch** - Task visibility, dependency dispatch, work queue
- [x] **Phase 6: Coordination** - Merge agent outputs, handle conflicts
- [ ] **Phase 7: File System UI** - Bidirectional SQLite/filesystem sync
## Phase Details
@@ -121,22 +120,10 @@ Plans:
- [x] 06-02: CoordinationManager Adapter (Wave 2)
- [x] 06-03: tRPC & CLI Integration (Wave 3)
### Phase 7: File System UI
**Goal**: Bidirectional sync between SQLite state and filesystem — agent messages as files, user responds via files
**Depends on**: Phase 6
**Requirements**: FSUI-01, FSUI-02, FSUI-03, FSUI-04
**Research**: Likely (bidirectional sync patterns may need prototyping)
**Research topics**: File watcher race conditions, atomic file operations, sync conflict resolution
**Plans**: TBD
Plans:
- [ ] 07-01: TBD
- [ ] 07-02: TBD
## Progress
**Execution Order:**
Phases execute in numeric order: 1 → 1.1 → 2 → 3 → 4 → 5 → 6 → 7
Phases execute in numeric order: 1 → 1.1 → 2 → 3 → 4 → 5 → 6
| Phase | Plans Complete | Status | Completed |
|-------|----------------|--------|-----------|
@@ -147,8 +134,7 @@ Phases execute in numeric order: 1 → 1.1 → 2 → 3 → 4 → 5 → 6 → 7
| 4. Agent Lifecycle | 4/4 | Complete | 2026-01-30 |
| 5. Task Dispatch | 5/5 | Complete | 2026-01-30 |
| 6. Coordination | 3/3 | Complete | 2026-01-30 |
| 7. File System UI | 0/? | Not started | - |
---
*Roadmap created: 2026-01-30*
*v1 requirements: 27 mapped across 7 phases*
*v1 requirements: 23 mapped across 6 phases*

View File

@@ -5,13 +5,13 @@
See: .planning/PROJECT.md (updated 2026-01-30)
**Core value:** Coordinate multiple Claude Code agents without losing track or stepping on each other.
**Current focus:** Phase 6 — Merge Coordination
**Current focus:** v1 Complete — All phases finished
## Current Position
Phase: 6 of 8 (Merge Coordination)
Phase: 6 of 6 (Coordination)
Plan: 3 of 3 in current phase
Status: Phase complete
Status: Milestone complete
Last activity: 2026-01-30 — Completed 06-03-PLAN.md
Progress: ██████████ 100%
@@ -116,5 +116,5 @@ None yet.
## Session Continuity
Last session: 2026-01-30
Stopped at: Completed 06-03-PLAN.md — Coordination tRPC & CLI
Stopped at: v1 milestone complete — All 27 plans executed
Resume file: None

View File

@@ -1,139 +0,0 @@
---
phase: 07-file-system-ui
plan: 01
type: execute
wave: 1
depends_on: []
files_modified: [src/filesync/types.ts, src/filesync/index.ts, src/events/types.ts]
autonomous: true
---
<objective>
Define FileSystemSync port interface and file sync events following hexagonal architecture.
Purpose: Establish the foundation for bidirectional SQLite-filesystem sync with typed events.
Output: FileSystemSync port interface, filesync events, exports.
</objective>
<execution_context>
@~/.claude/get-shit-done/workflows/execute-plan.md
@~/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
# Prior patterns to follow:
@src/events/types.ts
@src/coordination/types.ts
@src/db/repositories/message-repository.ts
</context>
<tasks>
<task type="auto">
<name>Task 1: Define filesync events</name>
<files>src/events/types.ts</files>
<action>
Add file sync events to DomainEventMap following existing patterns:
1. FileSyncedEvent (filesync:synced) - File synced to/from filesystem
- payload: { messageId, direction: 'db-to-fs' | 'fs-to-db', filePath }
2. FileSyncConflictEvent (filesync:conflict) - Sync conflict detected
- payload: { messageId, filePath, dbTimestamp, fsTimestamp }
3. FileSyncErrorEvent (filesync:error) - Sync operation failed
- payload: { messageId?, filePath, error: string }
4. FileWatcherStartedEvent (filesync:watcher-started) - Watcher began monitoring
- payload: { directory: string }
5. FileWatcherStoppedEvent (filesync:watcher-stopped) - Watcher stopped
- payload: { directory: string }
Add all five to DomainEventMap union type.
</action>
<verify>tsc --noEmit passes</verify>
<done>Five filesync events added to DomainEventMap with typed payloads</done>
</task>
<task type="auto">
<name>Task 2: Create FileSystemSync port interface</name>
<files>src/filesync/types.ts</files>
<action>
Create src/filesync/ directory and types.ts with:
1. MessageFileFormat interface:
- messageId: string
- agentName: string
- messageType: 'question' | 'info' | 'error' | 'response'
- requiresResponse: boolean
- status: 'pending' | 'read' | 'responded'
- parentMessageId?: string
- content: string (markdown body)
- createdAt: Date
- updatedAt: Date
2. SyncDirection type: 'db-to-fs' | 'fs-to-db'
3. SyncResult interface:
- success: boolean
- direction: SyncDirection
- messageId: string
- filePath: string
- error?: string
4. FileSystemSync port interface:
- start(): Promise<void> - Start watching and initial sync
- stop(): Promise<void> - Stop watching
- syncToFilesystem(messageId: string): Promise<SyncResult> - Sync single message DB→FS
- syncFromFilesystem(filePath: string): Promise<SyncResult> - Sync single file FS→DB
- syncAll(): Promise<SyncResult[]> - Full bidirectional sync
- getWatcherStatus(): { running: boolean; directory: string }
Use Message type from db/schema for reference but keep interface independent.
</action>
<verify>tsc --noEmit passes</verify>
<done>FileSystemSync port interface defined with sync operations</done>
</task>
<task type="auto">
<name>Task 3: Create module exports</name>
<files>src/filesync/index.ts</files>
<action>
Create index.ts with re-exports:
```typescript
export * from './types.js';
```
Simple barrel export for now - adapter will be added in 07-02/07-03.
</action>
<verify>tsc --noEmit passes, import { FileSystemSync } from './src/filesync/index.js' works</verify>
<done>Module exports configured</done>
</task>
</tasks>
<verification>
Before declaring plan complete:
- [ ] `npm run build` succeeds without errors
- [ ] Five filesync events in DomainEventMap
- [ ] FileSystemSync port interface defined
- [ ] Types importable from src/filesync/index.ts
</verification>
<success_criteria>
- All tasks completed
- All verification checks pass
- No errors or warnings introduced
- Port interface follows existing patterns (EventBus, WorktreeManager, CoordinationManager)
</success_criteria>
<output>
After completion, create `.planning/phases/07-file-system-ui/07-01-SUMMARY.md`
</output>

View File

@@ -1,160 +0,0 @@
---
phase: 07-file-system-ui
plan: 02
type: execute
wave: 2
depends_on: ["07-01"]
files_modified: [src/filesync/writer.ts, src/filesync/writer.test.ts, src/filesync/index.ts]
autonomous: true
---
<objective>
Implement message file writer for DB→FS sync direction (FSUI-02).
Purpose: Agent messages automatically appear as files in designated directory.
Output: MessageFileWriter class that creates/updates/deletes message files from DB state.
</objective>
<execution_context>
@~/.claude/get-shit-done/workflows/execute-plan.md
@~/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
# Depends on 07-01:
@src/filesync/types.ts
@src/events/types.ts
# Message schema for reference:
@src/db/schema.ts
@src/db/repositories/message-repository.ts
</context>
<tasks>
<task type="auto">
<name>Task 1: Create MessageFileWriter class</name>
<files>src/filesync/writer.ts</files>
<action>
Create MessageFileWriter class that handles DB→FS direction:
1. Constructor takes:
- messagesDir: string (e.g., '.cw/messages')
- eventBus?: EventBus (optional for events)
2. Methods:
- writeMessage(message: Message, agentName: string): Promise<SyncResult>
- Create/update file at {messagesDir}/{agentName}-{messageId}.md
- Format: YAML frontmatter + markdown body (see format below)
- Emit filesync:synced event on success
- Emit filesync:error event on failure
- deleteMessage(messageId: string, agentName: string): Promise<void>
- Delete file if exists
- No error if file doesn't exist (idempotent)
- writeAllMessages(messages: Array<{ message: Message; agentName: string }>): Promise<SyncResult[]>
- Batch write for initial sync
- ensureDirectory(): Promise<void>
- Create messagesDir if not exists
3. File format (YAML frontmatter + markdown):
```
---
messageId: abc123
agentName: gastown
type: question
requiresResponse: true
status: pending
parentMessageId: null
createdAt: 2026-01-30T12:00:00.000Z
updatedAt: 2026-01-30T12:00:00.000Z
---
What color should the button be?
```
4. Use js-yaml for YAML serialization (add to dependencies if needed).
Use gray-matter for frontmatter parsing (already common pattern).
If neither available, use simple string template (YAML is simple enough).
5. File naming: {agentName}-{messageId}.md
- Human-readable agent name for easy identification
- messageId for uniqueness
</action>
<verify>tsc --noEmit passes</verify>
<done>MessageFileWriter class created with write/delete operations</done>
</task>
<task type="auto">
<name>Task 2: Add unit tests</name>
<files>src/filesync/writer.test.ts</files>
<action>
Create comprehensive tests for MessageFileWriter:
1. Setup:
- Use tmp directory for test isolation
- Create mock EventBus for event verification
- Create test message objects
2. Test cases:
- writeMessage creates file with correct format
- writeMessage updates existing file
- writeMessage emits filesync:synced event
- deleteMessage removes file
- deleteMessage is idempotent (no error if file missing)
- writeAllMessages batch creates files
- ensureDirectory creates directory if missing
- Error cases emit filesync:error event
3. Verify file content:
- Parse written file, check frontmatter fields match
- Check markdown body matches content
Use vitest patterns from existing tests (e.g., src/coordination/manager.test.ts).
</action>
<verify>npm test -- src/filesync/writer.test.ts passes</verify>
<done>Writer tests pass, verify file format correctness</done>
</task>
<task type="auto">
<name>Task 3: Update module exports</name>
<files>src/filesync/index.ts</files>
<action>
Add MessageFileWriter to exports:
```typescript
export * from './types.js';
export * from './writer.js';
```
</action>
<verify>import { MessageFileWriter } from './src/filesync/index.js' works</verify>
<done>Writer exported from module</done>
</task>
</tasks>
<verification>
Before declaring plan complete:
- [ ] `npm run build` succeeds without errors
- [ ] `npm test -- src/filesync/writer.test.ts` passes
- [ ] File format is correct YAML frontmatter + markdown
- [ ] Events emitted correctly
</verification>
<success_criteria>
- All tasks completed
- All verification checks pass
- No errors or warnings introduced
- FSUI-02 requirement satisfied (agent messages appear as files)
</success_criteria>
<output>
After completion, create `.planning/phases/07-file-system-ui/07-02-SUMMARY.md`
</output>

View File

@@ -1,211 +0,0 @@
---
phase: 07-file-system-ui
plan: 03
type: execute
wave: 2
depends_on: ["07-01"]
files_modified: [src/filesync/watcher.ts, src/filesync/parser.ts, src/filesync/watcher.test.ts, src/filesync/index.ts, package.json]
autonomous: true
---
<objective>
Implement file watcher and parser for FS→DB sync direction (FSUI-03, FSUI-04).
Purpose: User can respond to agents by editing/creating files, changes sync to DB.
Output: FileWatcher class using chokidar, MessageFileParser for reading files.
</objective>
<execution_context>
@~/.claude/get-shit-done/workflows/execute-plan.md
@~/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
# Depends on 07-01:
@src/filesync/types.ts
@src/events/types.ts
# Message repository for DB updates:
@src/db/repositories/message-repository.ts
</context>
<tasks>
<task type="auto">
<name>Task 1: Install chokidar</name>
<files>package.json</files>
<action>
Add chokidar for file watching:
```bash
npm install chokidar
npm install -D @types/chokidar # if needed, check if bundled
```
chokidar is the de facto standard for Node.js file watching - cross-platform,
handles edge cases like rapid changes, atomic writes, etc.
</action>
<verify>npm ls chokidar shows installed</verify>
<done>chokidar added to dependencies</done>
</task>
<task type="auto">
<name>Task 2: Create MessageFileParser</name>
<files>src/filesync/parser.ts</files>
<action>
Create MessageFileParser for reading message files:
1. parseFile(filePath: string): Promise<MessageFileFormat | null>
- Read file content
- Parse YAML frontmatter (between --- markers)
- Extract markdown body
- Return null if file format invalid (log warning)
2. serializeToFile(data: MessageFileFormat): string
- Convert MessageFileFormat to file content string
- YAML frontmatter + markdown body
- Used by writer (shared logic)
3. extractAgentNameFromPath(filePath: string): string | null
- Parse {agentName}-{messageId}.md pattern
- Return agentName or null if pattern doesn't match
4. extractMessageIdFromPath(filePath: string): string | null
- Parse {agentName}-{messageId}.md pattern
- Return messageId or null if pattern doesn't match
Use simple string parsing for YAML - format is predictable and simple.
Don't need full YAML parser for this specific format.
</action>
<verify>tsc --noEmit passes</verify>
<done>Parser created with read/serialize operations</done>
</task>
<task type="auto">
<name>Task 3: Create FileWatcher class</name>
<files>src/filesync/watcher.ts</files>
<action>
Create FileWatcher class that monitors message directory:
1. Constructor takes:
- messagesDir: string
- messageRepository: MessageRepository
- eventBus?: EventBus
- debounceMs?: number (default 100ms)
2. Methods:
- start(): Promise<void>
- Initialize chokidar watcher on messagesDir
- Watch for: add, change, unlink events
- Emit filesync:watcher-started event
- stop(): Promise<void>
- Close chokidar watcher
- Emit filesync:watcher-stopped event
- isRunning(): boolean
3. Event handlers:
- onFileAdded(filePath: string)
- Parse file with MessageFileParser
- If messageId exists in DB, skip (file was created by writer)
- If new file (user response), create message in DB
- Emit filesync:synced event
- onFileChanged(filePath: string)
- Parse file
- Update message in DB with new content/status
- Emit filesync:synced event
- Use debounce to avoid rapid fire during saves
- onFileRemoved(filePath: string)
- Optional: Update message status or delete from DB
- For v1: Just log, don't delete from DB (safer)
4. Loop prevention:
- Track "in-flight syncs" - set of messageIds currently being written
- When writer writes file, add messageId to set
- When watcher sees change, check if messageId in set
- If in set, skip (change came from us)
- Clear from set after debounce period
5. Use chokidar options:
- persistent: true
- ignoreInitial: false (process existing files on start)
- awaitWriteFinish: { stabilityThreshold: 100 } (wait for writes to complete)
</action>
<verify>tsc --noEmit passes</verify>
<done>FileWatcher created with chokidar integration</done>
</task>
<task type="auto">
<name>Task 4: Add unit tests</name>
<files>src/filesync/watcher.test.ts</files>
<action>
Create tests for FileWatcher and MessageFileParser:
1. MessageFileParser tests:
- parseFile returns correct MessageFileFormat
- parseFile returns null for invalid format
- serializeToFile creates correct string
- extractAgentNameFromPath works for valid paths
- extractMessageIdFromPath works for valid paths
2. FileWatcher tests:
- start() emits watcher-started event
- stop() emits watcher-stopped event
- onFileChanged updates message in DB
- Loop prevention skips in-flight syncs
- Invalid files are ignored (logged but not error)
Use tmp directory for test isolation.
Create test files programmatically.
Mock MessageRepository for DB operations.
</action>
<verify>npm test -- src/filesync/watcher.test.ts passes</verify>
<done>Watcher and parser tests pass</done>
</task>
<task type="auto">
<name>Task 5: Update module exports</name>
<files>src/filesync/index.ts</files>
<action>
Add new exports:
```typescript
export * from './types.js';
export * from './writer.js';
export * from './parser.js';
export * from './watcher.js';
```
</action>
<verify>Imports work from src/filesync/index.js</verify>
<done>All filesync components exported</done>
</task>
</tasks>
<verification>
Before declaring plan complete:
- [ ] `npm run build` succeeds without errors
- [ ] `npm test -- src/filesync/` passes all tests
- [ ] chokidar installed and working
- [ ] Loop prevention verified in tests
</verification>
<success_criteria>
- All tasks completed
- All verification checks pass
- No errors or warnings introduced
- FSUI-03 requirement satisfied (user can respond via files)
- FSUI-04 requirement satisfied (file watcher detects edits)
</success_criteria>
<output>
After completion, create `.planning/phases/07-file-system-ui/07-03-SUMMARY.md`
</output>

View File

@@ -1,268 +0,0 @@
---
phase: 07-file-system-ui
plan: 04
type: execute
wave: 3
depends_on: ["07-02", "07-03"]
files_modified: [src/filesync/manager.ts, src/filesync/manager.test.ts, src/trpc/router.ts, src/cli/index.ts, src/server/index.ts, src/filesync/index.ts]
autonomous: true
---
<objective>
Create FileSystemSyncManager adapter, tRPC procedures, and CLI commands (FSUI-01).
Purpose: Wire filesync into server, expose via API, enable CLI control.
Output: Complete bidirectional sync system with tRPC and CLI integration.
</objective>
<execution_context>
@~/.claude/get-shit-done/workflows/execute-plan.md
@~/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
# Depends on 07-02 and 07-03:
@src/filesync/types.ts
@src/filesync/writer.ts
@src/filesync/watcher.ts
@src/filesync/parser.ts
# Integration points:
@src/trpc/router.ts
@src/trpc/context.ts
@src/cli/index.ts
@src/server/index.ts
</context>
<tasks>
<task type="auto">
<name>Task 1: Create FileSystemSyncManager adapter</name>
<files>src/filesync/manager.ts</files>
<action>
Create FileSystemSyncManager class implementing FileSystemSync port:
1. Constructor takes:
- messagesDir: string (default: '.cw/messages')
- messageRepository: MessageRepository
- agentRepository: AgentRepository (to get agent names)
- eventBus?: EventBus
2. Internal components:
- writer: MessageFileWriter
- watcher: FileWatcher
- parser: MessageFileParser
3. Implement FileSystemSync interface:
- start():
- Ensure directory exists
- Start watcher
- Perform initial sync (DB→FS)
- stop():
- Stop watcher
- syncToFilesystem(messageId: string):
- Get message from repository
- Get agent name from agentRepository
- Call writer.writeMessage()
- syncFromFilesystem(filePath: string):
- Parse file
- Create or update message in repository
- syncAll():
- Get all messages from repository
- Write all to filesystem
- Return results
- getWatcherStatus():
- Return { running: watcher.isRunning(), directory: messagesDir }
4. Subscribe to message events:
- When new message created in DB, auto-sync to FS
- Use eventBus to listen for message creation events
- (Or integrate with MessageRepository directly)
5. Coordinate writer and watcher:
- Share "in-flight" set between writer and watcher
- Writer adds to set before write, watcher checks set
</action>
<verify>tsc --noEmit passes</verify>
<done>FileSystemSyncManager adapter implementing port interface</done>
</task>
<task type="auto">
<name>Task 2: Add manager tests</name>
<files>src/filesync/manager.test.ts</files>
<action>
Create integration tests for FileSystemSyncManager:
1. Setup:
- Use tmp directory
- Create in-memory test database
- Create test repositories
- Create test agent and messages
2. Test cases:
- start() creates directory and initial sync
- syncToFilesystem() creates correct file
- syncFromFilesystem() updates DB
- syncAll() syncs all messages
- stop() stops watcher
- Bidirectional sync works (FSUI-01)
3. Integration tests:
- Create message in DB → appears as file
- Edit file → message updated in DB
- Create new file (response) → new message in DB
</action>
<verify>npm test -- src/filesync/manager.test.ts passes</verify>
<done>Manager tests verify bidirectional sync</done>
</task>
<task type="auto">
<name>Task 3: Add tRPC procedures</name>
<files>src/trpc/router.ts, src/trpc/context.ts</files>
<action>
Add filesync procedures to tRPC router:
1. Update TRPCContext to include optional fileSystemSync:
```typescript
fileSystemSync?: FileSystemSync;
```
2. Add procedures:
- filesync.getStatus - Returns watcher status
- Input: none
- Output: { running: boolean, directory: string }
- filesync.start - Start sync
- Input: none
- Output: { success: boolean }
- filesync.stop - Stop sync
- Input: none
- Output: { success: boolean }
- filesync.syncAll - Manual full sync
- Input: none
- Output: { results: SyncResult[] }
- filesync.syncMessage - Sync single message to FS
- Input: { messageId: string }
- Output: SyncResult
Guard all procedures: if fileSystemSync not in context, throw error.
Follow pattern from coordination procedures.
</action>
<verify>tsc --noEmit passes</verify>
<done>tRPC procedures added for filesync operations</done>
</task>
<task type="auto">
<name>Task 4: Add CLI commands</name>
<files>src/cli/index.ts</files>
<action>
Add filesync subcommands following existing CLI patterns:
1. cw sync status
- Call filesync.getStatus
- Display: "File sync: running|stopped, Directory: {path}"
2. cw sync start
- Call filesync.start
- Display: "File sync started"
3. cw sync stop
- Call filesync.stop
- Display: "File sync stopped"
4. cw sync run
- Call filesync.syncAll
- Display: "Synced {n} messages"
Follow pattern from existing CLI commands (agent, task, coordinate).
Use Commander.js subcommand pattern.
</action>
<verify>cw sync --help shows commands</verify>
<done>CLI sync commands implemented</done>
</task>
<task type="auto">
<name>Task 5: Wire into server</name>
<files>src/server/index.ts</files>
<action>
Create and inject FileSystemSyncManager in server startup:
1. In startServer():
- Create FileSystemSyncManager with:
- messagesDir from config or default '.cw/messages'
- messageRepository
- agentRepository
- eventBus
2. Add to TRPCContext:
- fileSystemSync: manager
3. On server start:
- Optionally auto-start sync (configurable)
- Or leave manual (user runs `cw sync start`)
4. On server shutdown:
- Stop filesync watcher in graceful shutdown handler
Keep sync disabled by default for v1 - user explicitly starts it.
</action>
<verify>Server starts with filesync available in context</verify>
<done>FileSystemSync wired into server</done>
</task>
<task type="auto">
<name>Task 6: Update module exports</name>
<files>src/filesync/index.ts</files>
<action>
Add manager to exports:
```typescript
export * from './types.js';
export * from './writer.js';
export * from './parser.js';
export * from './watcher.js';
export * from './manager.js';
```
</action>
<verify>All filesync components importable</verify>
<done>Complete module exports</done>
</task>
</tasks>
<verification>
Before declaring plan complete:
- [ ] `npm run build` succeeds without errors
- [ ] `npm test -- src/filesync/` passes all tests
- [ ] `cw sync status` works via CLI
- [ ] Server starts with filesync in context
- [ ] FSUI-01 satisfied (bidirectional sync works)
</verification>
<success_criteria>
- All tasks completed
- All verification checks pass
- No errors or warnings introduced
- All FSUI requirements satisfied:
- FSUI-01: Bidirectional sync works
- FSUI-02: Messages appear as files (via 07-02)
- FSUI-03: User responses via files (via 07-03)
- FSUI-04: File watcher detects changes (via 07-03)
</success_criteria>
<output>
After completion, create `.planning/phases/07-file-system-ui/07-04-SUMMARY.md`
</output>