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:
@@ -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*
|
||||
|
||||
@@ -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*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user