README.md
1 # Features Directory 2 3 Self-contained feature slices following **Vertical Slice Architecture**. Each feature owns its domain logic, state, services, and components. 4 5 ## Feature Slice Architecture 6 7 ### Directory Structure Pattern 8 9 Features organize code by **category subdirectories** when complexity warrants it: 10 11 ``` 12 features/ 13 ├── dreamnode/ # Complex feature - full structure 14 │ ├── store/ 15 │ │ └── slice.ts # Zustand slice for feature state 16 │ ├── services/ # Orchestrators with state/side-effects 17 │ │ ├── git-dreamnode-service.ts 18 │ │ ├── udd-service.ts 19 │ │ └── media-loading-service.ts 20 │ ├── utils/ # Stateless pure functions 21 │ │ ├── git-utils.ts 22 │ │ ├── vault-scanner.ts 23 │ │ └── repo-initializer.ts 24 │ ├── components/ # React/R3F components 25 │ │ ├── DreamNode3D.tsx 26 │ │ └── ... 27 │ ├── types/ # TypeScript interfaces 28 │ │ └── dreamnode.ts 29 │ ├── styles/ # CSS and style constants 30 │ ├── commands.ts # Obsidian command registrations 31 │ ├── test-utils.ts # Mock factories for testing 32 │ ├── README.md # Feature documentation 33 │ └── index.ts # Barrel export 34 │ 35 ├── settings/ # Simple feature - flat structure 36 │ ├── settings-tab.ts # Single service file (no services/ needed) 37 │ ├── settings-status-service.ts 38 │ ├── README.md 39 │ └── index.ts 40 ``` 41 42 ### When to Use Subdirectories 43 44 | Category | Create subdirectory when... | 45 |----------|---------------------------| 46 | `store/` | Feature has Zustand state (always use for slices) | 47 | `services/` | 2+ service files, or 1 complex service | 48 | `utils/` | 2+ utility files | 49 | `components/` | 2+ React components | 50 | `types/` | 2+ type definition files | 51 | `styles/` | 2+ style files | 52 53 **Guidance**: Use subdirectories for **semantic clarity**, not just file count. A single `store/slice.ts` is clearer than `feature-slice.ts` at the root. 54 55 ### File Naming Conventions 56 57 | File Type | Naming Pattern | Example | 58 |-----------|---------------|---------| 59 | Store slice | `store/slice.ts` | `dreamnode/store/slice.ts` | 60 | Service | `*-service.ts` | `git-dreamnode-service.ts` | 61 | Utility | `*-utils.ts` or descriptive | `git-utils.ts`, `vault-scanner.ts` | 62 | Component | `PascalCase.tsx` | `DreamNode3D.tsx` | 63 | Types | `*.ts` (descriptive) | `dreamnode.ts` | 64 | Commands | `commands.ts` | `commands.ts` | 65 | Barrel | `index.ts` | `index.ts` | 66 67 ### Service vs Utility Distinction 68 69 **Services** (in `services/`): 70 - Have state or manage side effects 71 - Orchestrate multiple operations 72 - May hold references (singletons, caches) 73 - Example: `GitDreamNodeService` - manages node CRUD with store updates 74 75 **Utilities** (in `utils/`): 76 - Pure functions, stateless 77 - Single-purpose operations 78 - Easily testable in isolation 79 - Example: `gitUtils.getGitStatus(repoPath)` - runs git command, returns result 80 81 ### Feature-Owned Settings Pattern 82 83 Features own their settings panel sections through `settings-section.ts`: 84 85 ```typescript 86 // features/my-feature/settings-section.ts 87 88 // Status check - called by settings aggregator 89 export async function checkMyFeatureStatus(): Promise<FeatureStatus> { 90 // Feature-specific status logic 91 } 92 93 // Settings UI - rendered in settings panel 94 export function createMyFeatureSettingsSection( 95 containerEl: HTMLElement, 96 plugin: InterBrainPlugin, 97 status: FeatureStatus | undefined, 98 refreshDisplay: () => Promise<void> 99 ): void { 100 // Feature-specific settings UI 101 } 102 ``` 103 104 The `settings` feature is a **thin orchestrator** that: 105 - Owns global settings (AI Integration, Keyboard Shortcuts, Advanced) 106 - Delegates feature sections to `create*SettingsSection()` functions 107 - Aggregates status via `check*Status()` functions 108 109 This pattern ensures features own their configuration UI and status checking logic. 110 111 ### Barrel Export Pattern 112 113 Every feature has an `index.ts` that exports its public API: 114 115 ```typescript 116 // features/dreamnode/index.ts 117 118 // Store (state management) 119 export * from './store/slice'; 120 121 // Types 122 export * from './types/dreamnode'; 123 124 // Services (orchestrators) 125 export { GitDreamNodeService } from './services/git-dreamnode-service'; 126 127 // Utilities (namespaced to avoid collisions) 128 export * as gitUtils from './utils/git-utils'; 129 export * as vaultScanner from './utils/vault-scanner'; 130 131 // Components 132 export { default as DreamNode3D } from './components/DreamNode3D'; 133 134 // Commands 135 export { registerDreamNodeCommands } from './commands'; 136 ``` 137 138 **Namespace exports** (`export * as gitUtils`) prevent naming collisions between features. 139 140 ## Feature Catalog 141 142 | Feature | Purpose | Complexity | 143 |---------|---------|------------| 144 | **DreamNode Family** | | | 145 | [dreamnode](./dreamnode/README.md) | Core: types, services, git operations, 3D visualization | High | 146 | [dreamnode-creator](./dreamnode-creator/README.md) | Creation workflow UI (builds on dreamnode) | Medium | 147 | [dreamnode-editor](./dreamnode-editor/README.md) | Editing workflow UI (builds on dreamnode) | Medium | 148 | **Layout & Navigation** | | | 149 | [constellation-layout](./constellation-layout/README.md) | Fibonacci sphere layout + node filtering for scalability (ephemeral loading) | High | 150 | [liminal-web-layout](./liminal-web-layout/README.md) | Focused node with related nodes in rings | Medium | 151 | [songline](./songline/README.md) | Songline navigation feature | Low | 152 | **Content & Canvas** | | | 153 | [dreamweaving](./dreamweaving/README.md) | Canvas parsing, submodules, DreamSong playback | High | 154 | [drag-and-drop](./drag-and-drop/README.md) | File and URL drop handling | Medium | 155 | [web-link-analyzer](./web-link-analyzer/README.md) | AI-powered URL content analysis | Low | 156 | **Search & AI** | | | 157 | [search](./search/README.md) | Search overlay and result display | Low | 158 | [semantic-search](./semantic-search/README.md) | Vector embeddings and similarity search | High | 159 | [conversational-copilot](./conversational-copilot/README.md) | AI conversation mode with node invocation | Medium | 160 | **Collaboration** | | | 161 | [social-resonance-filter](./social-resonance-filter/README.md) | Radicle P2P integration & commit propagation | Medium | 162 | [coherence-beacon](./coherence-beacon/README.md) | Node synchronization beacons | Medium | 163 | [github-publishing](./github-publishing/README.md) | GitHub sharing + Pages broadcast | Medium | 164 | [video-calling](./video-calling/README.md) | Video call initiation (FaceTime, future: more) | Low | 165 | **UI & System** | | | 166 | [action-buttons](./action-buttons/README.md) | Action menu around nodes | Low | 167 | [realtime-transcription](./realtime-transcription/README.md) | Voice transcription via Python backend | Medium | 168 | [settings](./settings/README.md) | Plugin settings tab (thin orchestrator) | Low | 169 | [dreamnode-updater](./dreamnode-updater/README.md) | DreamNode update workflow (preview, apply) | Low | 170 | [uri-handler](./uri-handler/README.md) | interbrain:// protocol handling | Low | 171 | [feedback](./feedback/README.md) | Bug reporting and feedback system | Low | 172 | [tutorial](./tutorial/README.md) | Onboarding with Manim-style text animations | Low | 173 174 ## Creating a New Feature 175 176 1. **Create the directory**: `src/features/my-feature/` 177 178 2. **Add README.md** with: 179 - Purpose (1-2 sentences) 180 - Key files description 181 - Main exports 182 - Architecture notes (if complex) 183 184 3. **Add index.ts** barrel export 185 186 4. **Choose structure based on complexity**: 187 - Simple (1-3 files): Flat structure 188 - Medium (4-8 files): Add subdirectories as needed 189 - Complex (9+ files): Full subdirectory structure 190 191 5. **Register with core** (if needed): 192 - Add slice to `core/store/interbrain-store.ts` 193 - Add to core README feature table 194 - Add to this README feature catalog 195 196 ## For AI Agents 197 198 When working in features: 199 200 1. **Read the feature README first** - understand the domain before making changes 201 2. **Follow existing patterns** - if the feature uses `services/`, add services there 202 3. **Use barrel exports** - import from `features/X` not `features/X/services/thing` 203 4. **Keep features isolated** - features should not import from each other (use core as intermediary) 204 5. **Services orchestrate, utils compute** - put stateful logic in services, pure functions in utils