plan
Implementation Plan: Markdown Documentation Editor (MDE)
Epic: TP-XXXX-MDE | Initiative: TP-2141-Work-Management Spec: spec.md | Design: design-spec.md Created: 2025-11-29 | Status: Draft
Summary
Expand the existing read-only documentation viewer into a full content management system. Users will be able to create, edit, update, and delete markdown documentation files (agents, commands, skills, MCP servers) directly through the web interface. The implementation builds on top of the existing DocumentationService and Vue components, adding CodeMirror 6 for editing and CRUD API endpoints.
Technical Context
| Aspect | Value |
|---|---|
| Backend | Laravel 12, PHP 8.4 |
| Frontend | Vue 3 (Composition API), Inertia.js v2, TypeScript |
| Styling | Tailwind CSS v3, Reka UI |
| Editor | CodeMirror 6 (new dependency) |
| Storage | Filesystem (.claude/ directory) |
| Testing | Pest (PHP), Vitest (JS) |
| Target Platform | Web (Desktop primary, mobile view-only) |
Existing Infrastructure (Reuse)
| Component | Location | Purpose |
|---|---|---|
DocumentationService | domain/Documentation/Services/ | Read operations for all doc types |
MarkdownParserService | domain/Documentation/Services/ | Parse markdown + frontmatter |
DocumentationShowLayout | resources/js/Components/Documentation/ | 3-column layout (nav, content, TOC) |
useTableOfContents | resources/js/composables/ | TOC navigation composable |
AgentData, SkillData, etc. | domain/Documentation/Data/ | DTOs for document types |
| Common components | resources/js/Components/Common/ | Badges, Cards, Icons, etc. |
New Dependencies
| Package | Version | Purpose |
|---|---|---|
codemirror | ^6.0 | Core editor |
@codemirror/lang-markdown | ^6.0 | Markdown syntax highlighting |
@codemirror/view | ^6.0 | Editor view layer |
vue-codemirror | ^6.0 | Vue 3 wrapper |
Constitution Check
Project constitution is a template placeholder. Applying standard Laravel/Vue best practices.
- Domain-Driven Design: Extend existing
domain/Documentation/structure - Inertia.js Patterns: Use Form component for submissions
- TypeScript: All new Vue components in TypeScript
- Pest Testing: Feature tests for all CRUD operations
- Tailwind/Reka UI: Use existing design system components
Project Structure
Documentation (this feature)
.claude/INITIATIVES/TP-2141-Work-Management/TP-XXXX-MDE-Markdown-Documentation-Editor/├── spec.md # Feature specification├── design-spec.md # UI/UX decisions├── plan.md # This file├── tasks.md # Generated by /speckit.tasks└── mockups/ # ASCII mockups (complete)Source Code Changes
domain/Documentation/├── Http/│ ├── Controllers/│ │ ├── DocumentationController.php # Extend with edit/create/delete│ │ └── DocumentationApiController.php # NEW: API endpoints│ └── Requests/│ ├── StoreDocumentRequest.php # NEW: Create validation│ └── UpdateDocumentRequest.php # NEW: Update validation├── Services/│ ├── DocumentationService.php # Extend with write methods│ └── DocumentationWriteService.php # NEW: Write operations└── Routes/ └── documentationRoutes.php # Extend with CRUD routes
resources/js/├── Components/│ └── Documentation/│ ├── Editor/│ │ ├── MarkdownEditor.vue # NEW: CodeMirror wrapper│ │ ├── MarkdownPreview.vue # NEW: Live preview│ │ ├── EditorHeader.vue # NEW: Title, save/cancel│ │ ├── EditorFooter.vue # NEW: Auto-save status│ │ └── MetadataPanel.vue # NEW: Frontmatter form│ ├── Modals/│ │ ├── CreateDocumentModal.vue # NEW: Create form│ │ └── DeleteConfirmModal.vue # NEW: Delete confirmation│ └── DocumentationShowLayout.vue # MODIFY: Add edit mode├── Pages/│ └── Documentation/│ ├── Agents/│ │ ├── Show.vue # MODIFY: Add edit toggle│ │ └── Edit.vue # NEW: Edit page (optional)│ └── [Skills|MCP|Commands]/ # Same pattern├── composables/│ ├── useAutoSave.ts # NEW: Auto-save logic│ └── useConcurrentEdit.ts # NEW: Lock indicator└── types/ └── documentation.d.ts # NEW: TypeScript interfaces
tests/├── Feature/│ └── Documentation/│ ├── AgentCrudTest.php # NEW│ ├── SkillCrudTest.php # NEW│ └── DocumentationEditorTest.php # NEW└── Unit/ └── Documentation/ └── DocumentationWriteServiceTest.php # NEWDesign Decisions
1. Data Model
No database changes required. Documents stored as markdown files with YAML frontmatter.
Document Structure:
---name: backend-developerdescription: Expert in Laravel/PHP backend developmentcolor: bluemodel: sonnettools: Read, Write, Edit, Bash, Grep, Glob---
# Backend Developer
Content here...Key Entities (existing DTOs):
AgentData: id, name, displayName, description, color, model, tools, content, filePathSkillData: id, name, displayName, description, content, filePath, categoryToolData(MCP): id, name, displayName, description, content, filePath, iconCommandData: id, name, displayName, description, content, filePath
2. API Contracts
| Method | Endpoint | Purpose | Request Body |
|---|---|---|---|
GET | /documentation/agents/{id}/edit | Load edit page | - |
PUT | /api/documentation/agents/{id} | Update agent | {content, metadata} |
POST | /api/documentation/agents | Create agent | {name, description, content, ...} |
DELETE | /api/documentation/agents/{id} | Delete agent | - |
GET | /api/documentation/agents/{id}/lock | Check edit lock | - |
POST | /api/documentation/agents/{id}/lock | Acquire lock | - |
DELETE | /api/documentation/agents/{id}/lock | Release lock | - |
Same pattern for /skills, /mcp, /commands.
Response Format:
{ "success": true, "data": { "id": "...", "name": "...", ... }, "message": "Document saved successfully"}Error Response:
{ "success": false, "error": "File was deleted externally", "code": "FILE_NOT_FOUND"}3. UI Components
| Component | Purpose | Props |
|---|---|---|
MarkdownEditor | CodeMirror 6 wrapper | modelValue, readonly, onSave |
MarkdownPreview | Render markdown to HTML | content, debounceMs |
EditorHeader | Title, cancel/save buttons | title, isDirty, isSaving |
EditorFooter | Auto-save status, metadata toggle | lastSaved, status |
MetadataPanel | Frontmatter form fields | metadata, documentType, onChange |
CreateDocumentModal | New document form | documentType, onSubmit |
DeleteConfirmModal | Confirmation dialog | document, onConfirm |
4. State Management
| State | Storage | Scope |
|---|---|---|
| Document content | Inertia props (initial) | Page |
| Draft content | localStorage | Device-specific |
| Auto-save status | Component ref | Editor session |
| Concurrent edit lock | Backend (cache/file) | Global |
localStorage Key Format:
mde:draft:{documentType}:{documentId}:{userId}Implementation Phases
Phase 1: Foundation (Editor Infrastructure)
Goal: Basic editor component working in isolation
- Install CodeMirror 6 dependencies
- Create
MarkdownEditor.vuecomponent - Create
MarkdownPreview.vuecomponent - Create
useAutoSave.tscomposable - Unit tests for composables
Exit Criteria: Editor renders, accepts input, shows preview
Phase 2: CRUD Backend
Goal: API endpoints for document operations
- Create
DocumentationWriteService.php - Create
StoreDocumentRequest/UpdateDocumentRequest - Create
DocumentationApiController.php - Add routes to
documentationRoutes.php - Feature tests for all CRUD operations
Exit Criteria: API endpoints work via Postman/curl
Phase 3: Edit Flow (P1 - Core Feature)
Goal: Users can edit existing documents
- Add “Edit” button to Show pages
- Create
EditorHeader.vue,EditorFooter.vue - Modify
DocumentationShowLayout.vuefor edit mode - Integrate editor components into Show pages
- Wire up save/cancel actions
- Add validation error handling
Exit Criteria: Can edit agent, save, see changes persist
Phase 4: Create Flow (P2)
Goal: Users can create new documents
- Create
CreateDocumentModal.vue - Create
MetadataPanel.vue - Add “Create New” button to Index pages
- Implement filename generation (slugify)
- Handle duplicate filename detection
Exit Criteria: Can create new agent from UI
Phase 5: Delete Flow (P3)
Goal: Users can delete documents
- Create
DeleteConfirmModal.vue - Add delete button to Show pages
- Implement nested content warnings
- Add audit logging for deletions
Exit Criteria: Can delete document with confirmation
Phase 6: Concurrent Edit & Polish
Goal: Handle edge cases and concurrent editing
- Create
useConcurrentEdit.tscomposable - Implement soft lock indicator
- Add “Edit anyway” override flow
- Handle session expiry during edit
- Large document performance optimization
- Keyboard shortcuts (Cmd+S)
Exit Criteria: Two users see lock indicator, edge cases handled
Risk Assessment
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| CodeMirror 6 Vue integration issues | Low | Medium | Use well-maintained vue-codemirror wrapper |
| File permission errors on save | Low | High | Proper error handling, user-friendly messages |
| Concurrent edit data loss | Medium | High | Soft lock + last-write-wins with logging |
| Large document performance | Low | Medium | Debounced preview (500ms for >100KB) |
| localStorage quota exceeded | Low | Low | Warn user, fallback to manual save |
Dependencies
Blocking Dependencies
- None (builds on existing infrastructure)
Non-Blocking Dependencies
- Design system components (already exist)
- Authentication middleware (already exist)
Success Metrics
From spec.md:
- SC-001: Edit and save within 30 seconds of clicking Edit
- SC-002: Create new document within 2 minutes
- SC-003: 95% of edit operations complete without data loss
- SC-004: Search returns results within 1 second
- SC-005: Clear error messages for 100% of validation failures
- SC-006: Handle documents up to 500KB without degradation
- SC-007: Auto-save every 30 seconds
- SC-008: 90% of users create first document without assistance
Next Steps
- Run
/speckit.tasks- Generate detailed implementation tasks - Run
/trilogy.jira-sync- Create Jira tickets from tasks - Run
/speckit.implement- Begin Phase 1 implementation
Appendix
Mockup Reference
See mockups/summary.md for:
- Editor layout (50/50 split)
- Create form design
- Delete confirmation modal
- Auto-save indicator states
- Concurrent edit indicator
Related Documentation
- Design Spec - UI/UX decisions
- Storybook - Component library
- Existing implementation:
domain/Documentation/