/ src / features / dreamnode / README.md
README.md
  1  # DreamNode Feature
  2  
  3  **Purpose**: Core DreamNode management - the fundamental unit of InterBrain's spatial knowledge representation.
  4  
  5  ## Overview
  6  
  7  DreamNodes are git-backed repositories representing either ideas (Dreams) or people (Dreamers). This feature owns their complete lifecycle: types, state, persistence, git operations, and 3D visualization.
  8  
  9  **Derivative features** build on this foundation:
 10  - `dreamnode-creator/` - Creation workflow UI
 11  - `dreamnode-editor/` - Editing workflow UI
 12  
 13  ## Directory Structure
 14  
 15  ```
 16  dreamnode/
 17  ├── store/
 18  │   └── slice.ts              # Zustand state (dreamNodes Map, flip state)
 19  ├── types/
 20  │   └── dreamnode.ts          # Core interfaces (DreamNode, UDDFile, GitStatus, etc.)
 21  ├── services/
 22  │   ├── git-dreamnode-service.ts   # CRUD orchestrator with git + store sync
 23  │   ├── udd-service.ts             # .udd file read/write
 24  │   └── dreamnode-conversion-service.ts # Convert existing folders to DreamNodes
 25  ├── utils/
 26  │   ├── git-utils.ts          # Stateless git commands (status, stash, commit)
 27  │   ├── vault-scanner.ts      # Filesystem discovery (scan, validate, read)
 28  │   ├── repo-initializer.ts   # Repository creation (init, template, commit)
 29  │   ├── title-sanitization.ts # Title → PascalCase folder name
 30  │   └── git-operations.ts     # Legacy class (deprecated)
 31  ├── components/
 32  │   ├── DreamNode3D.tsx       # Main 3D component with flip animations
 33  │   ├── DreamTalkSide.tsx     # Front face HTML (selected node, buttons)
 34  │   ├── DreamTalkSprite.tsx   # Front face WebGL (non-selected nodes)
 35  │   ├── DreamTalkMesh.tsx     # Legacy mesh-based WebGL approach
 36  │   ├── DreamSongSide.tsx     # Back face (canvas content)
 37  │   └── PDFPreview.tsx        # PDF rendering
 38  ├── hooks/
 39  │   ├── useContentTexture.ts  # Load media into THREE.Texture via getResourcePath
 40  │   └── useMediaTexture.ts    # Legacy base64-based texture loading
 41  ├── shaders/
 42  │   ├── circularClipShader.ts # Circular clip with border and vignette
 43  │   └── radialGradient.ts     # Radial fade-to-black shader
 44  ├── styles/
 45  │   ├── dreamNodeStyles.ts    # Colors, dimensions, glows
 46  │   └── dreamNodeAnimations.css
 47  ├── DreamNode-template/       # Git template for new DreamNode repos
 48  │   ├── hooks/                # Git hooks (pre-commit, post-commit)
 49  │   ├── udd                   # Template .udd file
 50  │   ├── LICENSE               # AGPL license
 51  │   └── README.md             # Template README
 52  ├── commands.ts               # Obsidian command palette (flip, fullscreen)
 53  ├── test-utils.ts             # Mock factories for testing
 54  ├── index.ts                  # Barrel export
 55  └── README.md
 56  ```
 57  
 58  ## Main Exports
 59  
 60  ```typescript
 61  // Store (state management)
 62  export * from './store/slice';
 63  // → DreamNodeSlice, DreamNodeData, createDreamNodeSlice
 64  
 65  // Types
 66  export * from './types/dreamnode';
 67  // → DreamNode, UDDFile, MediaFile, CanvasFile, GitStatus
 68  
 69  // Services
 70  export { GitDreamNodeService } from './services/git-dreamnode-service';
 71  export { UDDService } from './services/udd-service';
 72  
 73  // Utilities (namespaced)
 74  export * as gitUtils from './utils/git-utils';
 75  export * as vaultScanner from './utils/vault-scanner';
 76  export * as repoInitializer from './utils/repo-initializer';
 77  export { sanitizeTitleToPascalCase } from './utils/title-sanitization';
 78  
 79  // Components
 80  export { default as DreamNode3D } from './components/DreamNode3D';
 81  export type { DreamNode3DRef } from './components/DreamNode3D';
 82  export { DreamTalkSide } from './components/DreamTalkSide';
 83  export { DreamTalkSprite } from './components/DreamTalkSprite';
 84  export { DreamSongSide } from './components/DreamSongSide';
 85  
 86  // Hooks
 87  export { useContentTexture } from './hooks/useContentTexture';
 88  
 89  // Shaders
 90  export * from './shaders/circularClipShader';
 91  
 92  // Commands
 93  export { registerDreamNodeCommands } from './commands';
 94  ```
 95  
 96  ## Commands
 97  
 98  | Command | Hotkey | Description |
 99  |---------|--------|-------------|
100  | Flip Selected DreamNode | `Ctrl+J` | Toggle between DreamTalk and DreamSong |
101  | Flip DreamNode to Front | - | Show DreamTalk side |
102  | Flip DreamNode to Back | - | Show DreamSong side |
103  | Open DreamTalk Full-Screen | - | Full-screen DreamTalk media |
104  | Open DreamSong Full-Screen | - | Open DreamSong in Obsidian tab |
105  | Reveal Containing DreamNode | - | Focus DreamNode containing current file |
106  | Convert Folder to DreamNode | - | Initialize folder as DreamNode repository |
107  
108  ## Architecture
109  
110  ### Two-Tier Type System
111  
112  | Layer | Type | Purpose |
113  |-------|------|---------|
114  | Disk | `UDDFile` | JSON persisted in `.udd` file |
115  | Runtime | `DreamNode` | Includes resolved media, position, connections |
116  
117  ### Service vs Utility Pattern
118  
119  **Services** (stateful orchestrators):
120  - `GitDreamNodeService` - Coordinates git operations + store updates
121  
122  **Utilities** (stateless functions):
123  - `gitUtils.*` - Pure git command wrappers
124  - `vaultScanner.*` - Pure filesystem discovery
125  - `repoInitializer.*` - Pure repo creation steps
126  
127  ### Git-Native Storage
128  
129  - Each DreamNode = git repository in vault root
130  - `.udd` file = single JSON with all metadata (UUID, title, type, relationships)
131  - `DreamNode-template/` provides hooks for bidirectional relationship tracking
132  - Git hooks maintain `submodules` ↔ `supermodules` consistency
133  
134  ### Relationship Storage
135  
136  | Node Type | Storage | Reason |
137  |-----------|---------|--------|
138  | Dreamer | `liminal-web.json` (gitignored) | Private social connections |
139  | Dream | Discovered via git submodules | Bidirectional during vault scan |
140  
141  ### Visual Git State
142  
143  | Glow | Meaning |
144  |------|---------|
145  | Red | Uncommitted or stashed (work-in-progress) |
146  | Blue | Committed but unpushed (ready to share) |
147  | None | Clean and synchronized |
148  
149  ## Notes
150  
151  - **Media loading**: Handled directly by `useContentTexture` hook (simplified in v0.14.0)
152  - **Radicle failures**: Don't block node creation (graceful degradation)
153  - **Legacy `git-operations.ts`**: Deprecated, use `gitUtils` namespace
154  - **⚠️ Creator Mode**: DEPRECATED - The `creatorMode` state in the store slice is leftover from an early UX experiment and will be removed in a future update. Do not build new features on this pattern.
155  
156  ## WebGL Rendering Architecture
157  
158  The DreamTalk visualization uses a dual-mode rendering strategy:
159  
160  ### Rendering Modes
161  
162  | Mode | Component | When Used |
163  |------|-----------|-----------|
164  | WebGL Sprite | `DreamTalkSprite` | Non-selected nodes (performance) |
165  | HTML Overlay | `DreamTalkSide` | Selected node (buttons, interactions) |
166  
167  ### Texture Pipeline
168  
169  ```
170  Media File → getResourcePath() → THREE.Texture → Circular Clip Shader → Screen
171  ```
172  
173  1. **`useContentTexture`**: Loads media via Obsidian's `getResourcePath()` API
174     - Bypasses Electron `file://` restrictions
175     - No base64 encoding (better performance, no storage quota issues)
176     - Supports images, videos, PDFs
177  
178  2. **`circularClipShader`**: WebGL shader for DreamTalk appearance
179     - Circular clipping with soft edges
180     - Type-colored border ring (blue=Dream, red=Dreamer)
181     - Radial vignette fade-to-black
182     - Aspect ratio correction (cover fit)
183  
184  ### Why Dual Rendering?
185  
186  - **WebGL sprites** are GPU-native and scale to hundreds of nodes
187  - **HTML overlays** provide DOM interactivity (flip button, fullscreen)
188  - Selected node transitions from sprite to HTML when animation completes
189  - Prevents visual artifacts on high-DPI displays from sprite/HTML mismatch