Refactored dev-docs folder after multiple additions to organise correctly

This commit is contained in:
Richard Osborne
2026-01-07 20:28:40 +01:00
parent beff9f0886
commit 4a1080d547
125 changed files with 18456 additions and 957 deletions

View File

@@ -0,0 +1,282 @@
# TASK-REORG: Documentation Structure Cleanup
**Task ID:** TASK-REORG
**Created:** 2026-01-07
**Status:** 🟡 In Progress
**Priority:** HIGH
**Effort:** 2-4 hours
---
## Problem Statement
The task documentation has become disorganized over time with:
1. **Misplaced Content** - Phase 3 TASK-008 "granular-deployment" contains UBA (Universal Backend Adapter) content, not project file structure
2. **Wrong Numbering** - UBA files named "PHASE-6A-6F" but located in Phase 3, while actual Phase 6 is Code Export
3. **Duplicate Topics** - Styles work in both Phase 3 TASK-000 AND Phase 8
4. **Broken References** - Phase 9 references "Phase 6 UBA" which doesn't exist as a separate phase
5. **Typo in Folder Name** - "stabalisation" instead of "stabilisation"
6. **Missing Progress Tracking** - No easy way to see completion status of each phase
7. **Incorrect README** - Phase 8 README contains WIZARD-001 content, not phase overview
---
## Current vs Target Structure
### Phase Mapping
| New # | Current Location | New Location | Change Type |
| ------- | --------------------------------------------- | ---------------------------------- | ------------------------ |
| **0** | phase-0-foundation-stabalisation | phase-0-foundation-stabilisation | RENAME (fix typo) |
| **1** | phase-1-dependency-updates | phase-1-dependency-updates | KEEP |
| **2** | phase-2-react-migration | phase-2-react-migration | KEEP |
| **3** | phase-3-editor-ux-overhaul | phase-3-editor-ux-overhaul | MODIFY (remove TASK-008) |
| **3.5** | phase-3.5-realtime-agentic-ui | phase-3.5-realtime-agentic-ui | KEEP |
| **4** | phase-4-canvas-visualisation-views | phase-4-canvas-visualisation-views | KEEP |
| **5** | phase-5-multi-target-deployment | phase-5-multi-target-deployment | KEEP |
| **6** | phase-3.../TASK-008-granular-deployment | phase-6-uba-system | NEW (move UBA here) |
| **7** | phase-6-code-export | phase-7-code-export | RENUMBER |
| **8** | phase-7-auto-update-and-distribution | phase-8-distribution | RENUMBER |
| **9** | phase-3.../TASK-000 + phase-8-styles-overhaul | phase-9-styles-overhaul | MERGE |
| **10** | phase-9-ai-powered-development | phase-10-ai-powered-development | RENUMBER |
---
## Execution Checklist
### Phase 1: Create New Phase 6 (UBA System)
- [ ] Create folder `dev-docs/tasks/phase-6-uba-system/`
- [ ] Create `phase-6-uba-system/README.md` (UBA overview)
- [ ] Move `phase-3.../TASK-008-granular-deployment/PHASE-6A-FOUNDATION.md``phase-6-uba-system/UBA-001-FOUNDATION.md`
- [ ] Move `phase-3.../TASK-008-granular-deployment/PHASE-6B-FIELD-TYPES.md``phase-6-uba-system/UBA-002-FIELD-TYPES.md`
- [ ] Move `phase-3.../TASK-008-granular-deployment/PHASE-6C-DEBUG-SYSTEM.md``phase-6-uba-system/UBA-003-DEBUG-SYSTEM.md`
- [ ] Move `phase-3.../TASK-008-granular-deployment/PHASE-6D-POLISH.md``phase-6-uba-system/UBA-004-POLISH.md`
- [ ] Move `phase-3.../TASK-008-granular-deployment/PHASE-6E-REFERENCE-BACKEND.md``phase-6-uba-system/UBA-005-REFERENCE-BACKEND.md`
- [ ] Move `phase-3.../TASK-008-granular-deployment/PHASE-6F-COMMUNITY.md``phase-6-uba-system/UBA-006-COMMUNITY.md`
- [ ] Delete empty `phase-3-editor-ux-overhaul/TASK-008-granular-deployment/` folder
- [ ] Create `phase-6-uba-system/PROGRESS.md`
### Phase 2: Renumber Existing Phases
- [ ] Rename `phase-6-code-export/``phase-7-code-export/`
- [ ] Update any internal references in Phase 7 files
- [ ] Rename `phase-7-auto-update-and-distribution/``phase-8-distribution/`
- [ ] Update any internal references in Phase 8 files
### Phase 3: Merge Styles Content
- [ ] Create `phase-9-styles-overhaul/` (new merged folder)
- [ ] Move `phase-8-styles-overhaul/PHASE-8-OVERVIEW.md``phase-9-styles-overhaul/README.md`
- [ ] Move `phase-8-styles-overhaul/QUICK-REFERENCE.md``phase-9-styles-overhaul/QUICK-REFERENCE.md`
- [ ] Move `phase-8-styles-overhaul/STYLE-001-*` through `STYLE-005-*` folders → `phase-9-styles-overhaul/`
- [ ] Move `phase-8-styles-overhaul/WIZARD-001-*``phase-9-styles-overhaul/` (keep together with styles)
- [ ] Move `phase-3-editor-ux-overhaul/TASK-000-styles-overhaul/``phase-9-styles-overhaul/CLEANUP-SUBTASKS/` (legacy cleanup tasks)
- [ ] Delete old `phase-8-styles-overhaul/` folder
- [ ] Create `phase-9-styles-overhaul/PROGRESS.md`
### Phase 4: Renumber AI Phase
- [ ] Rename `phase-9-ai-powered-development/``phase-10-ai-powered-development/`
- [ ] Update references to "Phase 9" → "Phase 10" within files
- [ ] Update Phase 6 UBA references (now correct!)
- [ ] Create `phase-10-ai-powered-development/PROGRESS.md`
### Phase 5: Fix Phase 0 Typo
- [ ] Rename `phase-0-foundation-stabalisation/``phase-0-foundation-stabilisation/`
- [ ] Update any references to the old folder name
### Phase 6: Create PROGRESS.md Files
Create `PROGRESS.md` in each phase root:
- [ ] `phase-0-foundation-stabilisation/PROGRESS.md`
- [ ] `phase-1-dependency-updates/PROGRESS.md`
- [ ] `phase-2-react-migration/PROGRESS.md`
- [ ] `phase-3-editor-ux-overhaul/PROGRESS.md`
- [ ] `phase-3.5-realtime-agentic-ui/PROGRESS.md`
- [ ] `phase-4-canvas-visualisation-views/PROGRESS.md`
- [ ] `phase-5-multi-target-deployment/PROGRESS.md`
- [ ] `phase-6-uba-system/PROGRESS.md` (created in Phase 1)
- [ ] `phase-7-code-export/PROGRESS.md`
- [ ] `phase-8-distribution/PROGRESS.md`
- [ ] `phase-9-styles-overhaul/PROGRESS.md` (created in Phase 3)
- [ ] `phase-10-ai-powered-development/PROGRESS.md` (created in Phase 4)
### Phase 7: Update Cross-References
- [ ] Search all `.md` files for "phase-6" and update to "phase-7" (code export)
- [ ] Search all `.md` files for "phase-7" and update to "phase-8" (distribution)
- [ ] Search all `.md` files for "phase-8" and update to "phase-9" (styles)
- [ ] Search all `.md` files for "phase-9" and update to "phase-10" (AI)
- [ ] Search for "Phase 6 UBA" or "Phase 6 (UBA)" and verify points to new phase-6
- [ ] Search for "stabalisation" and fix typo
- [ ] Update `.clinerules` if it references specific phase numbers
### Phase 8: Verification
- [ ] All folders exist with correct names
- [ ] All PROGRESS.md files created
- [ ] No orphaned files or broken links
- [ ] README in each phase root is correct content
- [ ] Git commit with descriptive message
---
## PROGRESS.md Template
Use this template for all `PROGRESS.md` files:
```markdown
# Phase X: [Phase Name] - Progress Tracker
**Last Updated:** YYYY-MM-DD
**Overall Status:** 🔴 Not Started | 🟡 In Progress | 🟢 Complete
---
## Quick Summary
| Metric | Value |
| ------------ | ------ |
| Total Tasks | X |
| Completed | X |
| In Progress | X |
| Not Started | X |
| **Progress** | **X%** |
---
## Task Status
| Task | Name | Status | Notes |
| -------- | ------ | -------------- | --------------- |
| TASK-001 | [Name] | 🔴 Not Started | |
| TASK-002 | [Name] | 🟡 In Progress | 50% complete |
| TASK-003 | [Name] | 🟢 Complete | Done 2026-01-05 |
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
- ⏸️ **Blocked** - Waiting on dependency
- 🔵 **Planned** - Scheduled but not started
---
## Recent Updates
| Date | Update |
| ---------- | ----------------------- |
| YYYY-MM-DD | [Description of change] |
---
## Dependencies
List any external dependencies or blocking items here.
---
## Notes
Additional context or important information about this phase.
```
---
## Final Phase Structure
After reorganization:
```
dev-docs/tasks/
├── TASK-REORG-documentation-cleanup/ # This task (can be archived after)
├── phase-0-foundation-stabilisation/ # Fixed typo
│ └── PROGRESS.md
├── phase-1-dependency-updates/
│ └── PROGRESS.md
├── phase-2-react-migration/
│ └── PROGRESS.md
├── phase-3-editor-ux-overhaul/ # TASK-008 removed (moved to Phase 6)
│ └── PROGRESS.md
├── phase-3.5-realtime-agentic-ui/
│ └── PROGRESS.md
├── phase-4-canvas-visualisation-views/
│ └── PROGRESS.md
├── phase-5-multi-target-deployment/
│ └── PROGRESS.md
├── phase-6-uba-system/ # NEW - UBA content from old TASK-008
│ ├── README.md
│ ├── PROGRESS.md
│ ├── UBA-001-FOUNDATION.md
│ ├── UBA-002-FIELD-TYPES.md
│ ├── UBA-003-DEBUG-SYSTEM.md
│ ├── UBA-004-POLISH.md
│ ├── UBA-005-REFERENCE-BACKEND.md
│ └── UBA-006-COMMUNITY.md
├── phase-7-code-export/ # Renumbered from old Phase 6
│ └── PROGRESS.md
├── phase-8-distribution/ # Renumbered from old Phase 7
│ └── PROGRESS.md
├── phase-9-styles-overhaul/ # Merged Phase 3 TASK-000 + old Phase 8
│ ├── README.md
│ ├── PROGRESS.md
│ ├── QUICK-REFERENCE.md
│ ├── STYLE-001-*/
│ ├── STYLE-002-*/
│ ├── STYLE-003-*/
│ ├── STYLE-004-*/
│ ├── STYLE-005-*/
│ ├── WIZARD-001-*/
│ └── CLEANUP-SUBTASKS/ # From old Phase 3 TASK-000
└── phase-10-ai-powered-development/ # Renumbered from old Phase 9
├── README.md
├── PROGRESS.md
├── DRAFT-CONCEPT.md
└── TASK-9A-DRAFT.md # Will need internal renumber to TASK-10A
```
---
## Success Criteria
- [ ] All 12 phase folders have correct names
- [ ] All 12 phase folders have PROGRESS.md
- [ ] No orphaned content (nothing lost in moves)
- [ ] All cross-references updated
- [ ] No typos in folder names
- [ ] UBA content cleanly separated into Phase 6
- [ ] Styles content merged into Phase 9
- [ ] Phase 10 (AI) references correct Phase 6 (UBA) for dependencies
---
## Notes
- This reorganization is a **documentation-only** change - no code is modified
- Git history will show moves as delete+create, which is fine
- Consider a single commit with clear message: "docs: reorganize phase structure"
- After completion, update `.clinerules` if needed
- Archive this TASK-REORG folder or move to `completed/` subfolder
---
## Estimated Time
| Section | Estimate |
| ------------------------ | ------------ |
| Create Phase 6 (UBA) | 30 min |
| Renumber Phases 7-8 | 15 min |
| Merge Styles | 30 min |
| Renumber AI Phase | 15 min |
| Fix Phase 0 typo | 5 min |
| Create PROGRESS.md files | 45 min |
| Update cross-references | 30 min |
| Verification | 15 min |
| **Total** | **~3 hours** |

View File

@@ -0,0 +1,59 @@
# Phase 0: Foundation Stabilisation - Progress Tracker
**Last Updated:** 2026-01-07
**Overall Status:** 🟡 In Progress
---
## Quick Summary
| Metric | Value |
| ------------ | ------- |
| Total Tasks | 5 |
| Completed | 2 |
| In Progress | 2 |
| Not Started | 1 |
| **Progress** | **40%** |
---
## Task Status
| Task | Name | Status | Notes |
| -------- | ----------------------------------- | -------------- | ------------------------------------------ |
| TASK-008 | EventDispatcher React Investigation | 🔴 Not Started | Investigation needed but never started |
| TASK-009 | Webpack Cache Elimination | 🟡 In Progress | Awaiting user verification (3x test) |
| TASK-010 | EventListener Verification | 🟡 In Progress | Ready for user testing (6/9 items pending) |
| TASK-011 | React Event Pattern Guide | 🟢 Complete | Guide written |
| TASK-012 | Foundation Health Check | 🟢 Complete | Health check script created |
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
- ⏸️ **Blocked** - Waiting on dependency
- 🔵 **Planned** - Scheduled but not started
---
## Recent Updates
| Date | Update |
| ---------- | ---------------------------------------------------- |
| 2026-01-07 | Audit corrected task statuses (was incorrectly 100%) |
| 2026-01-07 | Phase marked complete, docs reorganized (incorrect) |
---
## Dependencies
None - this is the foundation phase.
---
## Notes
This phase established critical patterns for React/EventDispatcher integration that all subsequent phases must follow.

View File

@@ -0,0 +1,106 @@
# Phase 1: Dependency Updates - Progress Tracker
**Last Updated:** 2026-01-07
**Overall Status:** 🟡 Mostly Complete (Core work done, one task planned only)
---
## Quick Summary
| Metric | Value |
| ------------ | ------- |
| Total Tasks | 7 |
| Completed | 5 |
| In Progress | 0 |
| Not Started | 2 |
| **Progress** | **71%** |
---
## Task Status
| Task | Name | Status | Notes |
| --------- | ------------------------- | -------------- | --------------------------------------------- |
| TASK-000 | Dependency Analysis | 🟢 Complete | Analysis done |
| TASK-001 | Dependency Updates | 🟢 Complete | Core deps updated |
| TASK-001B | React 19 Migration | 🟢 Complete | Migrated to React 19 (48 createRoot usages) |
| TASK-002 | Legacy Project Migration | 🔴 Not Started | **Planning only** - noodl-cli not implemented |
| TASK-003 | TypeScript Config Cleanup | 🟢 Complete | Option B implemented (global path aliases) |
| TASK-004 | Storybook 8 Migration | 🟢 Complete | 92 stories migrated to CSF3 |
| TASK-006 | TypeScript 5 Upgrade | 🔴 Not Started | Required for Zod v4 compatibility |
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
- ⏸️ **Blocked** - Waiting on dependency
- 🔵 **Planned** - Scheduled but not started
---
## Code Verification Notes
### Verified 2026-01-07
**TASK-001B (React 19 Migration)**:
- ✅ 48 files using `createRoot` from react-dom/client
- ✅ No legacy `ReactDOM.render` calls in production code (only in migration tool for detection)
**TASK-003 (TypeScript Config Cleanup)**:
- ✅ Root tsconfig.json has global path aliases (Option B implemented)
- ✅ Includes: @noodl-core-ui/_, @noodl-hooks/_, @noodl-utils/_, @noodl-models/_, etc.
**TASK-004 (Storybook 8 Migration)**:
- ✅ 92 story files using CSF3 format (Meta, StoryObj)
- ✅ 0 files using old CSF2 format (ComponentStory, ComponentMeta)
**TASK-002 (Legacy Project Migration)**:
-`packages/noodl-cli/` does not exist
- ❌ No MigrationDialog component created
- ⚠️ Previous status was incorrect - this task has comprehensive planning docs but no implementation
**TASK-006 (TypeScript 5 Upgrade)**:
- ❌ Not previously tracked in PROGRESS.md
- Required for Zod v4 and modern @ai-sdk/\* packages
---
## Recent Updates
| Date | Update |
| ---------- | ----------------------------------------------------------------- |
| 2026-01-07 | Corrected TASK-002 status (was incorrectly marked complete) |
| 2026-01-07 | Added TASK-006 (TypeScript 5 Upgrade) - was missing from tracking |
| 2026-01-07 | Verified actual code state for TASK-001B, TASK-003, TASK-004 |
---
## Dependencies
Depends on: Phase 0 (Foundation)
---
## Notes
### Completed Work
React 19 migration, Storybook 8 CSF3 migration, and TypeScript config cleanup are all verified complete in the codebase.
### Outstanding Items
1. **TASK-002 (Legacy Project Migration)**: Has detailed planning documentation but no implementation. The `noodl-cli` package and migration tooling were never created.
2. **TASK-006 (TypeScript 5 Upgrade)**: New task required for Zod v4 compatibility. Currently using TypeScript 4.9.5 with `transpileOnly: true` workaround in webpack.
### Documentation vs Reality
Task README files have unchecked checkboxes even though work was completed - the checkboxes track planned files rather than actual completion. Code verification is the source of truth.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,202 @@
# Phase 10: AI-Powered Development - Progress Tracker
**Last Updated:** 2026-01-07
**Overall Status:** 🔴 Not Started
---
## Quick Summary
| Metric | Value |
| ------------ | ------ |
| Total Tasks | 42 |
| Completed | 0 |
| In Progress | 0 |
| Not Started | 42 |
| **Progress** | **0%** |
---
## Sub-Phase Overview
| Sub-Phase | Name | Tasks | Effort | Status |
| --------- | ------------------------------- | ----- | ------------- | -------------- |
| **10A** | Project Structure Modernization | 9 | 80-110 hours | 🔴 Not Started |
| **10B** | Frontend AI Assistant | 8 | 100-130 hours | 🔴 Not Started |
| **10C** | Backend Creation AI | 10 | 140-180 hours | 🔴 Not Started |
| **10D** | Unified AI Experience | 6 | 60-80 hours | 🔴 Not Started |
| **10E** | DEPLOY System Updates | 4 | 20-30 hours | 🔴 Not Started |
| **10F** | Legacy Migration System | 5 | 40-50 hours | 🔴 Not Started |
**Total Effort Estimate:** 400-550 hours (24-32 weeks)
---
## Phase 10A: Project Structure Modernization
**Status:** 🔴 Not Started
**Priority:** CRITICAL - Blocks all AI features
Transform the monolithic `project.json` into a component-per-file structure that AI can understand and edit.
| Task | Name | Effort | Status |
| ---------- | ----------------------- | ------ | -------------- |
| STRUCT-001 | JSON Schema Definition | 12-16h | 🔴 Not Started |
| STRUCT-002 | Export Engine Core | 16-20h | 🔴 Not Started |
| STRUCT-003 | Import Engine Core | 16-20h | 🔴 Not Started |
| STRUCT-004 | Editor Format Detection | 6-8h | 🔴 Not Started |
| STRUCT-005 | Lazy Component Loading | 12-16h | 🔴 Not Started |
| STRUCT-006 | Component-Level Save | 12-16h | 🔴 Not Started |
| STRUCT-007 | Migration Wizard UI | 10-14h | 🔴 Not Started |
| STRUCT-008 | Testing & Validation | 16-20h | 🔴 Not Started |
| STRUCT-009 | Documentation | 6-8h | 🔴 Not Started |
---
## Phase 10B: Frontend AI Assistant
**Status:** 🔴 Not Started
**Depends on:** Phase 10A complete
Build an AI assistant that can understand, navigate, and modify frontend components using natural language.
| Task | Name | Effort | Status |
| ------ | ----------------------------- | ------ | -------------- |
| AI-001 | Component Reading Tools | 12-16h | 🔴 Not Started |
| AI-002 | Component Modification Tools | 16-20h | 🔴 Not Started |
| AI-003 | LangGraph Agent Setup | 16-20h | 🔴 Not Started |
| AI-004 | Conversation Memory & Caching | 12-16h | 🔴 Not Started |
| AI-005 | AI Panel UI | 16-20h | 🔴 Not Started |
| AI-006 | Context Menu Integration | 8-10h | 🔴 Not Started |
| AI-007 | Streaming Responses | 8-10h | 🔴 Not Started |
| AI-008 | Error Handling & Recovery | 8-10h | 🔴 Not Started |
---
## Phase 10C: Backend Creation AI
**Status:** 🔴 Not Started
**Depends on:** Phase 10B started
AI-powered backend code generation with Docker integration.
| Task | Name | Effort | Status |
| -------- | ------------------------- | ------ | -------------- |
| BACK-001 | Requirements Analyzer | 16-20h | 🔴 Not Started |
| BACK-002 | Architecture Planner | 12-16h | 🔴 Not Started |
| BACK-003 | Code Generation Engine | 24-30h | 🔴 Not Started |
| BACK-004 | UBA Schema Generator | 12-16h | 🔴 Not Started |
| BACK-005 | Docker Integration | 16-20h | 🔴 Not Started |
| BACK-006 | Container Management | 12-16h | 🔴 Not Started |
| BACK-007 | Backend Agent (LangGraph) | 16-20h | 🔴 Not Started |
| BACK-008 | Iterative Refinement | 12-16h | 🔴 Not Started |
| BACK-009 | Backend Templates | 12-16h | 🔴 Not Started |
| BACK-010 | Testing & Validation | 16-20h | 🔴 Not Started |
---
## Phase 10D: Unified AI Experience
**Status:** 🔴 Not Started
**Depends on:** Phase 10B and 10C substantially complete
Unified chat experience across frontend and backend AI.
| Task | Name | Effort | Status |
| --------- | ------------------------- | ------ | -------------- |
| UNIFY-001 | AI Orchestrator | 16-20h | 🔴 Not Started |
| UNIFY-002 | Intent Classification | 8-12h | 🔴 Not Started |
| UNIFY-003 | Cross-Agent Context | 12-16h | 🔴 Not Started |
| UNIFY-004 | Unified Chat UI | 10-14h | 🔴 Not Started |
| UNIFY-005 | AI Settings & Preferences | 6-8h | 🔴 Not Started |
| UNIFY-006 | Usage Analytics | 8-10h | 🔴 Not Started |
---
## Phase 10E: DEPLOY System Updates
**Status:** 🔴 Not Started
**Can proceed after:** Phase 10A STRUCT-004
Update deployment system to work with new project structure and AI features.
| Task | Name | Effort | Status |
| ----------------- | ------------------------------- | ------ | -------------- |
| DEPLOY-UPDATE-001 | V2 Project Format Support | 8-10h | 🔴 Not Started |
| DEPLOY-UPDATE-002 | AI-Generated Backend Deploy | 6-8h | 🔴 Not Started |
| DEPLOY-UPDATE-003 | Preview Deploys with AI Changes | 4-6h | 🔴 Not Started |
| DEPLOY-UPDATE-004 | Environment Variables for AI | 4-6h | 🔴 Not Started |
---
## Phase 10F: Legacy Migration System
**Status:** 🔴 Not Started
**Can proceed in parallel with:** Phase 10A after STRUCT-003
Automatic migration from legacy project.json to new V2 format.
| Task | Name | Effort | Status |
| ----------- | ------------------------------ | ------ | -------------- |
| MIGRATE-001 | Project Analysis Engine | 10-12h | 🔴 Not Started |
| MIGRATE-002 | Pre-Migration Warning UI | 8-10h | 🔴 Not Started |
| MIGRATE-003 | Integration with Import Flow | 10-12h | 🔴 Not Started |
| MIGRATE-004 | Incremental Migration | 8-10h | 🔴 Not Started |
| MIGRATE-005 | Migration Testing & Validation | 10-12h | 🔴 Not Started |
---
## Critical Path
```
STRUCT-001 → STRUCT-002 → STRUCT-003 → STRUCT-004 → STRUCT-005 → STRUCT-006
MIGRATE-001 → MIGRATE-002 → MIGRATE-003
AI-001 → AI-002 → AI-003 → AI-004 → AI-005
BACK-001 → BACK-002 → ... → BACK-010
UNIFY-001 → UNIFY-002 → ... → UNIFY-006
```
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
---
## Recent Updates
| Date | Update |
| ---------- | ---------------------------------------------------------------- |
| 2026-01-07 | Updated PROGRESS.md to reflect full 42-task scope from README.md |
| 2026-01-07 | Renumbered from Phase 9 to Phase 10 |
---
## Dependencies
- **Phase 6 (UBA)**: Recommended but not blocking for 10A
- **Phase 3 (Editor UX)**: Some UI patterns may be reused
---
## Notes
This phase is the FOUNDATIONAL phase for AI vibe coding!
**Phase 10A (Project Structure)** is critical - transforms the monolithic 50,000+ line project.json into a component-per-file structure that AI can understand and edit.
Key features:
- Components stored as individual JSON files (~3000 tokens each)
- AI can edit single components without loading entire project
- Enables AI-driven development workflows
- Foundation for future AI assistant features
See README.md for full task specifications and implementation details.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,60 @@
# Phase 2: React Migration - Progress Tracker
**Last Updated:** 2026-01-07
**Overall Status:** 🟢 Complete
---
## Quick Summary
| Metric | Value |
| ------------ | -------- |
| Total Tasks | 9 |
| Completed | 9 |
| In Progress | 0 |
| Not Started | 0 |
| **Progress** | **100%** |
---
## Task Status
| Task | Name | Status | Notes |
| --------- | ------------------------- | ----------- | ------------------------- |
| TASK-000 | Legacy CSS Migration | 🟢 Complete | CSS modules adopted |
| TASK-001 | New Node Test | 🟢 Complete | Node creation patterns |
| TASK-002 | React 19 UI Fixes | 🟢 Complete | UI compatibility fixed |
| TASK-003 | React 19 Runtime | 🟢 Complete | Runtime updated |
| TASK-004 | Runtime Migration System | 🟢 Complete | Migration system in place |
| TASK-004B | ComponentsPanel Migration | 🟢 Complete | Panel fully React |
| TASK-005 | New Nodes | 🟢 Complete | New node types added |
| TASK-006 | Preview Font Loading | 🟢 Complete | Fonts load correctly |
| TASK-007 | Wire AI Migration | 🟢 Complete | AI wiring complete |
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
---
## Recent Updates
| Date | Update |
| ---------- | --------------------- |
| 2026-01-07 | Phase marked complete |
---
## Dependencies
Depends on: Phase 1 (Dependency Updates)
---
## Notes
Major React 19 migration completed. Editor now fully React-based.

View File

@@ -0,0 +1,66 @@
# Phase 3: Editor UX Overhaul - Progress Tracker
**Last Updated:** 2026-01-07
**Overall Status:** 🟡 In Progress
---
## Quick Summary
| Metric | Value |
| ------------ | ------- |
| Total Tasks | 9 |
| Completed | 3 |
| In Progress | 0 |
| Not Started | 6 |
| **Progress** | **33%** |
---
## Task Status
| Task | Name | Status | Notes |
| --------- | ----------------------- | -------------- | ------------------------------------- |
| TASK-001 | Dashboard UX Foundation | 🟢 Complete | Tabbed navigation done |
| TASK-001B | Launcher Fixes | 🟢 Complete | All 4 subtasks implemented |
| TASK-002 | GitHub Integration | 🟢 Complete | OAuth + basic features done |
| TASK-002B | GitHub Advanced | 🔴 Not Started | Issues/PR panels planned |
| TASK-003 | Shared Component System | 🔴 Not Started | Prefab system refactor |
| TASK-004 | AI Project Creation | 🔴 Not Started | AI scaffolding feature |
| TASK-005 | Deployment Automation | 🔴 Not Started | Planning docs only, no implementation |
| TASK-006 | Expressions Overhaul | 🔴 Not Started | Enhanced expression nodes |
| TASK-007 | App Config | 🔴 Not Started | App configuration system |
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
---
## Recent Updates
| Date | Update |
| ---------- | ----------------------------------------------------- |
| 2026-01-07 | Audit completed: corrected TASK-001B, TASK-005 status |
| 2026-01-07 | Added TASK-006 and TASK-007 to tracking |
| 2026-01-07 | TASK-008 moved to Phase 6 (UBA) |
| 2026-01-07 | TASK-000 moved to Phase 9 (Styles) |
---
## Dependencies
Depends on: Phase 2 (React Migration)
---
## Notes
- TASK-008 (granular deployment / UBA) moved to Phase 6.
- TASK-000 (styles overhaul) moved to Phase 9.
- TASK-001B marked complete on 2026-01-07 after verification that all success criteria were met.
- TASK-005 corrected from "In Progress" to "Not Started" - only planning docs exist.

View File

@@ -0,0 +1,415 @@
# DASH-001B-4: Create Project Modal
## Overview
Replace the basic browser `prompt()` dialog with a proper React modal for creating new projects. Provides name input and folder picker in a clean UI.
## Problem
Current implementation uses a browser prompt:
```typescript
const name = prompt('Project name:'); // ❌ Bad UX
if (!name) return;
```
**Issues:**
- Poor UX (browser native prompt looks outdated)
- No validation feedback
- No folder selection context
- Doesn't match app design
- Not accessible
## Solution
Create a React modal component with:
- Project name input field
- Folder picker button
- Validation (name required, path valid)
- Cancel/Create buttons
- Proper styling matching launcher theme
## Component Design
### Modal Structure
```
┌─────────────────────────────────────────────┐
│ Create New Project ✕ │
├─────────────────────────────────────────────┤
│ │
│ Project Name │
│ ┌─────────────────────────────────────┐ │
│ │ My New Project │ │
│ └─────────────────────────────────────┘ │
│ │
│ Location │
│ ┌──────────────────────────────┐ [Choose] │
│ │ ~/Documents/Noodl Projects/ │ │
│ └──────────────────────────────┘ │
│ │
│ Full path: ~/Documents/Noodl Projects/ │
│ My New Project/ │
│ │
│ [Cancel] [Create] │
└─────────────────────────────────────────────┘
```
### Props Interface
```typescript
export interface CreateProjectModalProps {
isVisible: boolean;
onClose: () => void;
onConfirm: (name: string, location: string) => void;
}
```
## Implementation Steps
### 1. Create CreateProjectModal component
**File:** `packages/noodl-core-ui/src/preview/launcher/Launcher/components/CreateProjectModal/CreateProjectModal.tsx`
```typescript
import React, { useState, useEffect } from 'react';
import { PrimaryButton, PrimaryButtonVariant, PrimaryButtonSize } from '@noodl-core-ui/components/inputs/PrimaryButton';
import { TextInput } from '@noodl-core-ui/components/inputs/TextInput';
import { BaseDialog } from '@noodl-core-ui/components/layout/BaseDialog';
import { Label } from '@noodl-core-ui/components/typography/Label';
import { Text } from '@noodl-core-ui/components/typography/Text';
import css from './CreateProjectModal.module.scss';
export interface CreateProjectModalProps {
isVisible: boolean;
onClose: () => void;
onConfirm: (name: string, location: string) => void;
onChooseLocation?: () => Promise<string | null>; // For folder picker
}
export function CreateProjectModal({ isVisible, onClose, onConfirm, onChooseLocation }: CreateProjectModalProps) {
const [projectName, setProjectName] = useState('');
const [location, setLocation] = useState('');
const [isChoosingLocation, setIsChoosingLocation] = useState(false);
// Reset state when modal opens
useEffect(() => {
if (isVisible) {
setProjectName('');
setLocation('');
}
}, [isVisible]);
const handleChooseLocation = async () => {
if (!onChooseLocation) return;
setIsChoosingLocation(true);
try {
const chosen = await onChooseLocation();
if (chosen) {
setLocation(chosen);
}
} finally {
setIsChoosingLocation(false);
}
};
const handleCreate = () => {
if (!projectName.trim() || !location) return;
onConfirm(projectName.trim(), location);
};
const isValid = projectName.trim().length > 0 && location.length > 0;
if (!isVisible) return null;
return (
<BaseDialog
isVisible={isVisible}
title="Create New Project"
onClose={onClose}
onPrimaryAction={handleCreate}
primaryActionLabel="Create"
primaryActionDisabled={!isValid}
onSecondaryAction={onClose}
secondaryActionLabel="Cancel"
>
<div className={css['Content']}>
{/* Project Name */}
<div className={css['Field']}>
<Label>Project Name</Label>
<TextInput
value={projectName}
onChange={(e) => setProjectName(e.target.value)}
placeholder="My New Project"
autoFocus
UNSAFE_style={{ marginTop: 'var(--spacing-2)' }}
/>
</div>
{/* Location */}
<div className={css['Field']}>
<Label>Location</Label>
<div className={css['LocationRow']}>
<TextInput
value={location}
onChange={(e) => setLocation(e.target.value)}
placeholder="Choose folder..."
readOnly
UNSAFE_style={{ flex: 1 }}
/>
<PrimaryButton
label="Choose..."
size={PrimaryButtonSize.Small}
variant={PrimaryButtonVariant.Muted}
onClick={handleChooseLocation}
isDisabled={isChoosingLocation}
UNSAFE_style={{ marginLeft: 'var(--spacing-2)' }}
/>
</div>
</div>
{/* Preview full path */}
{projectName && location && (
<div className={css['PathPreview']}>
<Text variant="shy">
Full path: {location}/{projectName}/
</Text>
</div>
)}
</div>
</BaseDialog>
);
}
```
### 2. Create styles
**File:** `packages/noodl-core-ui/src/preview/launcher/Launcher/components/CreateProjectModal/CreateProjectModal.module.scss`
```scss
.Content {
min-width: 400px;
padding: var(--spacing-4) 0;
}
.Field {
margin-bottom: var(--spacing-4);
&:last-child {
margin-bottom: 0;
}
}
.LocationRow {
display: flex;
align-items: center;
margin-top: var(--spacing-2);
}
.PathPreview {
margin-top: var(--spacing-3);
padding: var(--spacing-3);
background-color: var(--theme-color-bg-3);
border-radius: var(--radius-default);
border: 1px solid var(--theme-color-border-default);
}
```
### 3. Create index export
**File:** `packages/noodl-core-ui/src/preview/launcher/Launcher/components/CreateProjectModal/index.ts`
```typescript
export { CreateProjectModal } from './CreateProjectModal';
export type { CreateProjectModalProps } from './CreateProjectModal';
```
### 4. Update ProjectsPage to use modal
**File:** `packages/noodl-editor/src/editor/src/pages/ProjectsPage/ProjectsPage.tsx`
Replace prompt-based flow with modal:
```typescript
import { CreateProjectModal } from '@noodl-core-ui/preview/launcher/Launcher/components/CreateProjectModal';
export function ProjectsPage(props: ProjectsPageProps) {
// ... existing code
// Add state for modal
const [isCreateModalVisible, setIsCreateModalVisible] = useState(false);
const handleCreateProject = useCallback(() => {
// Open modal instead of prompt
setIsCreateModalVisible(true);
}, []);
const handleChooseLocation = useCallback(async (): Promise<string | null> => {
try {
const direntry = await filesystem.openDialog({
allowCreateDirectory: true
});
return direntry || null;
} catch (error) {
console.error('Failed to choose location:', error);
return null;
}
}, []);
const handleCreateProjectConfirm = useCallback(
async (name: string, location: string) => {
setIsCreateModalVisible(false);
try {
const path = filesystem.makeUniquePath(filesystem.join(location, name));
const activityId = 'creating-project';
ToastLayer.showActivity('Creating new project', activityId);
LocalProjectsModel.instance.newProject(
(project) => {
ToastLayer.hideActivity(activityId);
if (!project) {
ToastLayer.showError('Could not create project');
return;
}
// Navigate to editor with the newly created project
props.route.router.route({ to: 'editor', project });
},
{ name, path, projectTemplate: '' }
);
} catch (error) {
console.error('Failed to create project:', error);
ToastLayer.showError('Failed to create project');
}
},
[props.route]
);
const handleCreateModalClose = useCallback(() => {
setIsCreateModalVisible(false);
}, []);
// ... existing code
return (
<>
<Launcher
projects={realProjects}
onCreateProject={handleCreateProject}
onOpenProject={handleOpenProject}
onLaunchProject={handleLaunchProject}
onOpenProjectFolder={handleOpenProjectFolder}
onDeleteProject={handleDeleteProject}
projectOrganizationService={ProjectOrganizationService.instance}
githubUser={githubUser}
githubIsAuthenticated={githubIsAuthenticated}
githubIsConnecting={githubIsConnecting}
onGitHubConnect={handleGitHubConnect}
onGitHubDisconnect={handleGitHubDisconnect}
/>
{/* Add modal */}
<CreateProjectModal
isVisible={isCreateModalVisible}
onClose={handleCreateModalClose}
onConfirm={handleCreateProjectConfirm}
onChooseLocation={handleChooseLocation}
/>
</>
);
}
```
## Files to Create
1. `packages/noodl-core-ui/src/preview/launcher/Launcher/components/CreateProjectModal/CreateProjectModal.tsx`
2. `packages/noodl-core-ui/src/preview/launcher/Launcher/components/CreateProjectModal/CreateProjectModal.module.scss`
3. `packages/noodl-core-ui/src/preview/launcher/Launcher/components/CreateProjectModal/index.ts`
## Files to Modify
1. `packages/noodl-editor/src/editor/src/pages/ProjectsPage/ProjectsPage.tsx`
## Testing Checklist
- [ ] Click "Create new project" button
- [ ] Modal appears with focus on name input
- [ ] Can type project name
- [ ] Create button disabled until name and location provided
- [ ] Click "Choose..." button
- [ ] Folder picker dialog appears
- [ ] Selected folder displays in location field
- [ ] Full path preview shows correctly
- [ ] Click Cancel closes modal without action
- [ ] Click Create with valid inputs creates project
- [ ] Navigate to editor after successful creation
- [ ] Invalid input shows appropriate feedback
## Validation Rules
1. **Project name:**
- Must not be empty
- Trim whitespace
- Allow any characters (filesystem will sanitize if needed)
2. **Location:**
- Must not be empty
- Must be a valid directory path
- User must select via picker (not manual entry)
3. **Full path:**
- Combination of location + name
- Must be unique (handled by `filesystem.makeUniquePath`)
## Benefits
1. **Better UX** - Modern modal matches app design
2. **Visual feedback** - See full path before creating
3. **Validation** - Clear indication of required fields
4. **Accessibility** - Proper keyboard navigation
5. **Consistent** - Uses existing UI components
## Future Enhancements (Phase 8)
This modal is intentionally minimal. Phase 8 WIZARD-001 will add:
- Template selection
- Git initialization option
- AI-assisted project setup
- Multi-step wizard flow
## Edge Cases
### Location picker cancelled
If user cancels the folder picker, the location field remains unchanged (keeps previous value or stays empty).
### Invalid name characters
The filesystem will handle sanitization if the name contains invalid characters for the OS.
### Path already exists
`filesystem.makeUniquePath()` automatically appends a number if the path exists (e.g., "My Project (2)").
## Follow-up
This completes the TASK-001B fixes. After all subtasks are implemented, verify:
- Folders persist after restart
- Folders appear in modal
- Only grid view visible
- Project creation uses modal
---
**Estimated Time:** 2-3 hours
**Status:** Not Started

View File

@@ -0,0 +1,198 @@
# DASH-001B-1: Electron-Store Migration
## Overview
Migrate `ProjectOrganizationService` from localStorage to electron-store for persistent, disk-based storage that survives editor restarts, reinstalls, and `npm run dev:clean`.
## Problem
Current implementation uses localStorage:
```typescript
private loadData(): ProjectOrganizationData {
const stored = localStorage.getItem(this.storageKey);
// ...
}
private saveData(): void {
localStorage.setItem(this.storageKey, JSON.stringify(this.data));
}
```
**Issues:**
- Data cleared during `npm run dev:clean`
- Lost on editor reinstall/update
- Stored in Electron session cache (temporary)
## Solution
Use `electron-store` like `GitStore` does:
```typescript
import Store from 'electron-store';
const store = new Store<ProjectOrganizationData>({
name: 'project_organization',
encryptionKey: 'unique-key-here' // Optional
});
```
## Implementation Steps
### 1. Update ProjectOrganizationService.ts
**File:** `packages/noodl-editor/src/editor/src/services/ProjectOrganizationService.ts`
Replace localStorage with electron-store:
```typescript
import Store from 'electron-store';
import { EventDispatcher } from '../../../shared/utils/EventDispatcher';
// ... (keep existing interfaces)
export class ProjectOrganizationService extends EventDispatcher {
private static _instance: ProjectOrganizationService;
private store: Store<ProjectOrganizationData>;
private data: ProjectOrganizationData;
private constructor() {
super();
// Initialize electron-store
this.store = new Store<ProjectOrganizationData>({
name: 'project_organization',
defaults: {
version: 1,
folders: [],
tags: [],
projectMeta: {}
}
});
this.data = this.loadData();
}
private loadData(): ProjectOrganizationData {
try {
return this.store.store; // Get all data from store
} catch (error) {
console.error('[ProjectOrganizationService] Failed to load data:', error);
return {
version: 1,
folders: [],
tags: [],
projectMeta: {}
};
}
}
private saveData(): void {
try {
this.store.store = this.data; // Save all data to store
this.notifyListeners('dataChanged', this.data);
} catch (error) {
console.error('[ProjectOrganizationService] Failed to save data:', error);
}
}
// ... (rest of the methods remain the same)
}
```
### 2. Remove localStorage references
Remove the `storageKey` property as it's no longer needed:
```typescript
// DELETE THIS:
private storageKey = 'projectOrganization';
```
### 3. Test persistence
After implementation:
1. Create a folder in the launcher
2. Run `npm run dev:clean`
3. Restart the editor
4. Verify the folder still exists
## Files to Modify
1. `packages/noodl-editor/src/editor/src/services/ProjectOrganizationService.ts`
## Changes Summary
**Before:**
- Used `localStorage.getItem()` and `localStorage.setItem()`
- Data stored in Electron session
- Cleared on dev mode restart
**After:**
- Uses `electron-store` with disk persistence
- Data stored in OS-appropriate app data folder:
- macOS: `~/Library/Application Support/Noodl/project_organization.json`
- Windows: `%APPDATA%\Noodl\project_organization.json`
- Linux: `~/.config/Noodl/project_organization.json`
- Survives all restarts and reinstalls
## Testing Checklist
- [ ] Import `electron-store` successfully
- [ ] Service initializes without errors
- [ ] Can create folders
- [ ] Can rename folders
- [ ] Can delete folders
- [ ] Can move projects to folders
- [ ] Data persists after `npm run dev:clean`
- [ ] Data persists after editor restart
- [ ] No console errors
## Edge Cases
### If electron-store fails to initialize
The service should gracefully fall back:
```typescript
private loadData(): ProjectOrganizationData {
try {
return this.store.store;
} catch (error) {
console.error('[ProjectOrganizationService] Failed to load data:', error);
// Return empty structure - don't crash the app
return {
version: 1,
folders: [],
tags: [],
projectMeta: {}
};
}
}
```
### Data corruption
If the stored JSON is corrupted, electron-store will throw an error. The loadData method catches this and returns empty defaults.
## Benefits
1. **Persistent storage** - Data survives restarts
2. **Proper location** - Stored in OS app data folder
3. **Consistent pattern** - Matches GitStore implementation
4. **Type safety** - Generic `Store<ProjectOrganizationData>` provides type checking
5. **Atomic writes** - electron-store handles file write safety
## Follow-up
After this subtask, proceed to **DASH-001B-2** (Service Integration) to connect the service to the UI.
---
**Estimated Time:** 1-2 hours
**Status:** Not Started

View File

@@ -0,0 +1,298 @@
# DASH-001B-3: Remove List View
## Overview
Remove all list view code and make grid view the standard. Simplify the UI by eliminating the view mode toggle and related complexity.
## Problem
Both list and grid views were implemented per DASH-002 spec, but grid view is the only one needed. List view adds:
- Unnecessary code to maintain
- UI complexity (toggle button)
- Performance overhead (two rendering modes)
- Testing surface area
## Solution
Delete list view completely and make grid the only rendering mode.
## Implementation Steps
### 1. Delete ViewModeToggle component
**Directory to delete:** `packages/noodl-core-ui/src/preview/launcher/Launcher/components/ViewModeToggle/`
This directory contains:
- `ViewModeToggle.tsx`
- `ViewModeToggle.module.scss`
- `ViewModeToggle.stories.tsx` (if exists)
- `index.ts`
### 2. Delete ProjectList component
**Directory to delete:** `packages/noodl-core-ui/src/preview/launcher/Launcher/components/ProjectList/`
This directory contains:
- `ProjectList.tsx`
- `ProjectListRow.tsx`
- `ProjectListHeader.tsx`
- `ProjectList.module.scss`
- `ProjectList.stories.tsx` (if exists)
- `index.ts`
### 3. Delete useProjectList hook
**File to delete:** `packages/noodl-core-ui/src/preview/launcher/Launcher/hooks/useProjectList.ts`
This hook provides sorting logic specifically for list view.
### 4. Remove from LauncherContext
**File:** `packages/noodl-core-ui/src/preview/launcher/Launcher/LauncherContext.tsx`
Remove `ViewMode` and related properties:
```typescript
// DELETE THIS EXPORT:
export { ViewMode };
export interface LauncherContextValue {
activePageId: LauncherPageId;
setActivePageId: (pageId: LauncherPageId) => void;
// DELETE THESE TWO LINES:
// viewMode: ViewMode;
// setViewMode: (mode: ViewMode) => void;
useMockData: boolean;
setUseMockData: (value: boolean) => void;
// ... rest
}
```
### 5. Update Launcher component
**File:** `packages/noodl-core-ui/src/preview/launcher/Launcher/Launcher.tsx`
Remove viewMode state and prop:
```typescript
export interface LauncherProps {
projects?: LauncherProjectData[];
initialPage?: LauncherPageId;
useMockData?: boolean;
// DELETE THIS:
// initialViewMode?: ViewMode;
onCreateProject?: () => void;
// ... rest
}
export function Launcher({
projects = [],
initialPage = 'projects',
useMockData: useMockDataProp = false,
// DELETE THIS:
// initialViewMode = ViewMode.Grid,
onCreateProject
}: // ... rest
LauncherProps) {
const [activePageId, setActivePageId] = useState<LauncherPageId>(initialPage);
// DELETE THESE LINES:
// const [viewMode, setViewMode] = useState<ViewMode>(initialViewMode);
const [useMockData, setUseMockData] = useState(useMockDataProp);
const [selectedFolderId, setSelectedFolderId] = useState<string | null>(null);
const contextValue: LauncherContextValue = {
activePageId,
setActivePageId,
// DELETE THESE LINES:
// viewMode,
// setViewMode,
useMockData,
setUseMockData
// ... rest
};
// ... rest of component
}
```
### 6. Update Projects view
**File:** `packages/noodl-core-ui/src/preview/launcher/Launcher/views/Projects.tsx`
Remove all list view logic:
```typescript
// DELETE THESE IMPORTS:
// import { ProjectList } from '@noodl-core-ui/preview/launcher/Launcher/components/ProjectList';
// import { ViewModeToggle } from '@noodl-core-ui/preview/launcher/Launcher/components/ViewModeToggle';
// import { useProjectList } from '@noodl-core-ui/preview/launcher/Launcher/hooks/useProjectList';
// import { ViewMode } from '@noodl-core-ui/preview/launcher/Launcher/LauncherContext';
export function Projects({}: ProjectsViewProps) {
const {
// DELETE THIS:
// viewMode,
// setViewMode,
projects: allProjects
// ... rest
} = useLauncherContext();
// ... (keep existing filtering and search logic)
// DELETE THIS ENTIRE BLOCK:
// const { sortedProjects, sortField, sortDirection, setSorting } = useProjectList({
// projects,
// initialSortField: 'lastModified',
// initialSortDirection: 'desc'
// });
// In the JSX, DELETE the ViewModeToggle:
<HStack hasSpacing={4} UNSAFE_style={{ justifyContent: 'space-between', alignItems: 'center' }}>
<LauncherSearchBar
searchTerm={searchTerm}
setSearchTerm={setSearchTerm}
filterValue={filterValue}
setFilterValue={setFilterValue}
filterDropdownItems={visibleTypesDropdownItems}
/>
{/* DELETE THIS: */}
{/* <ViewModeToggle mode={viewMode} onChange={setViewMode} /> */}
</HStack>;
{
/* DELETE THE ENTIRE CONDITIONAL RENDERING: */
}
{
/* Replace this: */
}
{
/* {viewMode === ViewMode.List ? (
<ProjectList ... />
) : (
<grid view>
)} */
}
{
/* With just the grid view: */
}
<Box hasTopSpacing={4}>
{/* Project list legend */}
<Box hasBottomSpacing={4}>
<HStack hasSpacing>
<div style={{ width: 100 }} />
<div style={{ width: '100%' }}>
<Columns layoutString={'1 1 1'}>
<Label variant={TextType.Shy} size={LabelSize.Small}>
Name
</Label>
<Label variant={TextType.Shy} size={LabelSize.Small}>
Version control
</Label>
<Label variant={TextType.Shy} size={LabelSize.Small}>
Contributors
</Label>
</Columns>
</div>
</HStack>
</Box>
{/* Grid of project cards */}
<Columns layoutString="1" hasXGap hasYGap>
{projects.map((project) => (
<LauncherProjectCard
key={project.id}
{...project}
onClick={() => onLaunchProject?.(project.id)}
contextMenuItems={
[
// ... existing menu items
]
}
/>
))}
</Columns>
</Box>;
}
```
### 7. Update Storybook stories
**Files to check:**
- `packages/noodl-core-ui/src/preview/launcher/Launcher/Launcher.stories.tsx`
Remove any `initialViewMode` or `ViewMode` usage:
```typescript
// DELETE imports of ViewMode, ViewModeToggle
export const Default: Story = {
args: {
projects: MOCK_PROJECTS
// DELETE THIS:
// initialViewMode: ViewMode.Grid,
}
};
```
## Files to Delete
1. `packages/noodl-core-ui/src/preview/launcher/Launcher/components/ViewModeToggle/` (entire directory)
2. `packages/noodl-core-ui/src/preview/launcher/Launcher/components/ProjectList/` (entire directory)
3. `packages/noodl-core-ui/src/preview/launcher/Launcher/hooks/useProjectList.ts`
## Files to Modify
1. `packages/noodl-core-ui/src/preview/launcher/Launcher/LauncherContext.tsx`
2. `packages/noodl-core-ui/src/preview/launcher/Launcher/Launcher.tsx`
3. `packages/noodl-core-ui/src/preview/launcher/Launcher/views/Projects.tsx`
4. `packages/noodl-core-ui/src/preview/launcher/Launcher/Launcher.stories.tsx` (if exists)
## Testing Checklist
- [ ] ViewModeToggle button is gone
- [ ] Only grid view renders
- [ ] Search still works
- [ ] Filter dropdown still works
- [ ] Project cards render correctly
- [ ] Context menu on cards works
- [ ] No TypeScript errors
- [ ] No console errors
- [ ] Storybook builds successfully
## Benefits
1. **Simpler codebase** - ~500+ lines of code removed
2. **Easier maintenance** - Only one rendering mode to maintain
3. **Better performance** - No conditional rendering overhead
4. **Cleaner UI** - No toggle button cluttering the toolbar
5. **Focused UX** - One consistent way to view projects
## Potential Issues
### If grid view has issues
If problems are discovered with grid view after list view removal, they can be fixed directly in the grid implementation without worrying about list view parity.
### If users request list view later
The code can be recovered from git history if truly needed, but grid view should be sufficient for most users.
## Follow-up
After this subtask, proceed to **DASH-001B-4** (Create Project Modal) to improve project creation UX.
---
**Estimated Time:** 1-2 hours
**Status:** Not Started

View File

@@ -0,0 +1,247 @@
# DASH-001B-2: Service Integration
## Overview
Connect the real `ProjectOrganizationService` from noodl-editor to the launcher UI so folders appear correctly in the "Move to Folder" modal.
## Problem
The `useProjectOrganization` hook creates its own isolated localStorage service:
```typescript
// In useProjectOrganization.ts
const service = useMemo(() => {
// TODO: In production, get this from window context or inject it
return createLocalStorageService(); // ❌ Creates separate storage
}, []);
```
This means:
- Folders created in the sidebar go to one storage
- "Move to Folder" modal reads from a different storage
- The two never sync
## Solution
Bridge the service through the launcher context, similar to how GitHub OAuth is handled.
## Implementation Steps
### 1. Expose service through launcher context
**File:** `packages/noodl-core-ui/src/preview/launcher/Launcher/LauncherContext.tsx`
Add organization service to context:
```typescript
import { ProjectOrganizationService } from '@noodl-editor';
// TODO: Add proper import path
export interface LauncherContextValue {
// ... existing properties
// Project organization service (optional for Storybook compatibility)
projectOrganizationService?: any; // Use 'any' to avoid circular deps
}
```
### 2. Pass service from ProjectsPage
**File:** `packages/noodl-editor/src/editor/src/pages/ProjectsPage/ProjectsPage.tsx`
Add to Launcher component:
```typescript
import { ProjectOrganizationService } from '../../services/ProjectOrganizationService';
export function ProjectsPage(props: ProjectsPageProps) {
// ... existing code
return (
<Launcher
projects={realProjects}
onCreateProject={handleCreateProject}
onOpenProject={handleOpenProject}
onLaunchProject={handleLaunchProject}
onOpenProjectFolder={handleOpenProjectFolder}
onDeleteProject={handleDeleteProject}
projectOrganizationService={ProjectOrganizationService.instance} // ✅ Add this
githubUser={githubUser}
githubIsAuthenticated={githubIsAuthenticated}
githubIsConnecting={githubIsConnecting}
onGitHubConnect={handleGitHubConnect}
onGitHubDisconnect={handleGitHubDisconnect}
/>
);
}
```
### 3. Update Launcher component
**File:** `packages/noodl-core-ui/src/preview/launcher/Launcher/Launcher.tsx`
Accept and pass service through context:
```typescript
export interface LauncherProps {
// ... existing props
projectOrganizationService?: any; // Optional for Storybook
}
export function Launcher({
projects = [],
initialPage = 'projects',
useMockData: useMockDataProp = false,
onCreateProject,
onOpenProject,
onLaunchProject,
onOpenProjectFolder,
onDeleteProject,
projectOrganizationService, // ✅ Add this
githubUser,
githubIsAuthenticated = false,
githubIsConnecting = false,
onGitHubConnect,
onGitHubDisconnect
}: LauncherProps) {
// ... existing state
const contextValue: LauncherContextValue = {
activePageId,
setActivePageId,
viewMode,
setViewMode,
useMockData,
setUseMockData,
projects: displayProjects,
hasRealProjects,
selectedFolderId,
setSelectedFolderId,
onCreateProject,
onOpenProject,
onLaunchProject,
onOpenProjectFolder,
onDeleteProject,
projectOrganizationService, // ✅ Add this
githubUser,
githubIsAuthenticated,
githubIsConnecting,
onGitHubConnect,
onGitHubDisconnect
};
// ... rest of component
}
```
### 4. Update useProjectOrganization hook
**File:** `packages/noodl-core-ui/src/preview/launcher/Launcher/hooks/useProjectOrganization.ts`
Use real service when available:
```typescript
import { useLauncherContext } from '../LauncherContext';
export function useProjectOrganization(): UseProjectOrganizationReturn {
const { projectOrganizationService } = useLauncherContext();
const [folders, setFolders] = useState<Folder[]>([]);
const [tags, setTags] = useState<Tag[]>([]);
const [, setUpdateTrigger] = useState(0);
// Use real service if available, otherwise fall back to localStorage
const service = useMemo(() => {
if (projectOrganizationService) {
console.log('✅ Using real ProjectOrganizationService');
return projectOrganizationService;
}
console.warn('⚠️ ProjectOrganizationService not available, using localStorage fallback');
return createLocalStorageService();
}, [projectOrganizationService]);
// ... rest of hook (unchanged)
}
```
### 5. Add export path for service
**File:** `packages/noodl-editor/src/editor/src/index.ts` (or appropriate export file)
Ensure `ProjectOrganizationService` is exported:
```typescript
export { ProjectOrganizationService } from './services/ProjectOrganizationService';
```
## Files to Modify
1. `packages/noodl-core-ui/src/preview/launcher/Launcher/LauncherContext.tsx`
2. `packages/noodl-editor/src/editor/src/pages/ProjectsPage/ProjectsPage.tsx`
3. `packages/noodl-core-ui/src/preview/launcher/Launcher/Launcher.tsx`
4. `packages/noodl-core-ui/src/preview/launcher/Launcher/hooks/useProjectOrganization.ts`
5. `packages/noodl-editor/src/editor/src/index.ts` (if not already exporting service)
## Testing Checklist
- [ ] Service is passed to Launcher component
- [ ] useProjectOrganization receives real service
- [ ] Console shows "Using real ProjectOrganizationService" message
- [ ] Can create folder in sidebar
- [ ] Folder appears immediately in sidebar
- [ ] Click "Move to Folder" on project card
- [ ] Modal shows all user-created folders
- [ ] Moving project to folder works correctly
- [ ] Folder counts update correctly
- [ ] Storybook still works (falls back to localStorage)
## Data Flow
```
ProjectsPage.tsx
└─> ProjectOrganizationService.instance
└─> Launcher.tsx (prop)
└─> LauncherContext (context value)
└─> useProjectOrganization (hook)
└─> FolderTree, Projects view, etc.
```
## Storybook Compatibility
The service is optional in the context, so Storybook stories will still work:
```typescript
// In Launcher.stories.tsx
<Launcher
projects={mockProjects}
// projectOrganizationService not provided - uses localStorage fallback
/>
```
## Benefits
1. **Single source of truth** - All components read from same service
2. **Real-time sync** - Changes immediately visible everywhere
3. **Persistent storage** - Combined with Subtask 1, data survives restarts
4. **Backward compatible** - Storybook continues to work
## Edge Cases
### Service not available
If `projectOrganizationService` is undefined (e.g., in Storybook), the hook falls back to localStorage service with a warning.
### Multiple service instances
The service uses a singleton pattern (`instance` getter), so all references point to the same instance.
## Follow-up
After this subtask, proceed to **DASH-001B-3** (Remove List View) to simplify the UI.
---
**Estimated Time:** 2-3 hours
**Status:** Not Started

View File

@@ -0,0 +1,169 @@
# TASK-001B: Launcher Fixes & Improvements
## Overview
This task addresses critical bugs and UX issues discovered after the initial launcher implementation (TASK-001). Four main issues are resolved: folder persistence, service integration, view mode simplification, and project creation UX.
## Problem Statement
After deploying the new launcher dashboard, several issues were identified:
1. **Folders don't appear in "Move to Folder" modal** - The UI and service are disconnected
2. **Can't create new project** - Using basic browser `prompt()` provides poor UX
3. **List view is unnecessary** - Grid view should be the only option
4. **Folders don't persist** - Data lost after `npm run dev:clean` or reinstall
## Root Causes
### Issue 1: Disconnected Service
The `useProjectOrganization` hook creates its own localStorage service instead of using the real `ProjectOrganizationService` from noodl-editor. This creates two separate data stores that don't communicate.
```typescript
// In useProjectOrganization.ts
// TODO: In production, get this from window context or inject it
return createLocalStorageService(); // ❌ Creates isolated storage
```
### Issue 2: Poor Project Creation UX
The current implementation uses browser `prompt()`:
```typescript
const name = prompt('Project name:'); // ❌ Bad UX
```
### Issue 3: Unnecessary Complexity
Both list and grid views were implemented per spec, but only grid view is needed, adding unnecessary code and maintenance burden.
### Issue 4: Non-Persistent Storage
`ProjectOrganizationService` uses localStorage which is cleared during dev mode restarts:
```typescript
private loadData(): ProjectOrganizationData {
const stored = localStorage.getItem(this.storageKey); // ❌ Session-only
}
```
## Solution Overview
### Subtask 1: Migrate to electron-store
Replace localStorage with electron-store for persistent, disk-based storage that survives reinstalls and updates.
**Files affected:**
- `packages/noodl-editor/src/editor/src/services/ProjectOrganizationService.ts`
**Details:** See `DASH-001B-electron-store-migration.md`
### Subtask 2: Connect Service to UI
Bridge the real `ProjectOrganizationService` to the launcher context so folders appear correctly in the modal.
**Files affected:**
- `packages/noodl-editor/src/editor/src/pages/ProjectsPage/ProjectsPage.tsx`
- `packages/noodl-core-ui/src/preview/launcher/Launcher/hooks/useProjectOrganization.ts`
- `packages/noodl-core-ui/src/preview/launcher/Launcher/Launcher.tsx`
- `packages/noodl-core-ui/src/preview/launcher/Launcher/LauncherContext.tsx`
**Details:** See `DASH-001B-service-integration.md`
### Subtask 3: Remove List View
Delete all list view code and make grid view the standard.
**Files affected:**
- `packages/noodl-core-ui/src/preview/launcher/Launcher/components/ViewModeToggle/` (delete)
- `packages/noodl-core-ui/src/preview/launcher/Launcher/components/ProjectList/` (delete)
- `packages/noodl-core-ui/src/preview/launcher/Launcher/views/Projects.tsx`
- `packages/noodl-core-ui/src/preview/launcher/Launcher/LauncherContext.tsx`
- `packages/noodl-core-ui/src/preview/launcher/Launcher/Launcher.tsx`
**Details:** See `DASH-001B-remove-list-view.md`
### Subtask 4: Add Project Creation Modal
Replace prompt() with a proper React modal for better UX.
**Files to create:**
- `packages/noodl-core-ui/src/preview/launcher/Launcher/components/CreateProjectModal/CreateProjectModal.tsx`
- `packages/noodl-core-ui/src/preview/launcher/Launcher/components/CreateProjectModal/CreateProjectModal.module.scss`
- `packages/noodl-core-ui/src/preview/launcher/Launcher/components/CreateProjectModal/index.ts`
**Files to modify:**
- `packages/noodl-editor/src/editor/src/pages/ProjectsPage/ProjectsPage.tsx`
**Details:** See `DASH-001B-create-project-modal.md`
## Implementation Order
The subtasks should be completed in sequence:
1. **Electron-store migration** - Foundation for persistence
2. **Service integration** - Fixes folder modal immediately
3. **Remove list view** - Simplifies codebase
4. **Create project modal** - Improves new project UX
Each subtask is independently testable and provides immediate value.
## Testing Strategy
After each subtask:
- **Subtask 1:** Verify data persists after `npm run dev:clean`
- **Subtask 2:** Verify folders appear in "Move to Folder" modal
- **Subtask 3:** Verify only grid view renders, no toggle button
- **Subtask 4:** Verify new project modal works correctly
## Success Criteria
- [x] Folders persist across editor restarts and `npm run dev:clean`
- [x] "Move to Folder" modal shows all user-created folders
- [x] Only grid view exists (no list view toggle)
- [x] Project creation uses modal with name + folder picker
- [x] All existing functionality continues to work
## Dependencies
- Phase 3 TASK-001 (Dashboard UX Foundation) - completed
- electron-store package (already installed)
## Blocked By
None
## Blocks
None (this is a bug fix task)
## Estimated Effort
- Subtask 1: 1-2 hours
- Subtask 2: 2-3 hours
- Subtask 3: 1-2 hours
- Subtask 4: 2-3 hours
- **Total: 6-10 hours**
## Notes
- **No backward compatibility needed** - Fresh start with electron-store is acceptable
- **Delete list view completely** - No need to keep for future revival
- **Minimal modal scope** - Name + folder picker only (Phase 8 wizard will enhance later)
- This task prepares the foundation for Phase 8 WIZARD-001 (full project creation wizard)
## Related Tasks
- **TASK-001** (Dashboard UX Foundation) - Original implementation
- **Phase 8 WIZARD-001** (Project Creation Wizard) - Future enhancement
---
_Created: January 2026_
_Status: ✅ Complete (verified 2026-01-07)_

View File

@@ -0,0 +1,58 @@
# Phase 3.5: Realtime Agentic UI - Progress Tracker
**Last Updated:** 2026-01-07
**Overall Status:** 🔴 Not Started
---
## Quick Summary
| Metric | Value |
| ------------ | ------ |
| Total Tasks | 7 |
| Completed | 0 |
| In Progress | 0 |
| Not Started | 7 |
| **Progress** | **0%** |
---
## Task Status
| Task | Name | Status | Notes |
| --------- | ----------------------- | -------------- | ------------------------- |
| AGENT-001 | SSE Node | 🔴 Not Started | Server-sent events node |
| AGENT-002 | WebSocket Node | 🔴 Not Started | Real-time WebSocket |
| AGENT-003 | Global State Store | 🔴 Not Started | Centralized state |
| AGENT-004 | Optimistic Updates | 🔴 Not Started | UI optimism patterns |
| AGENT-005 | Action Dispatcher | 🔴 Not Started | Event dispatch system |
| AGENT-006 | State History | 🔴 Not Started | Undo/redo for state |
| AGENT-007 | Stream Parser Utilities | 🔴 Not Started | Parse streaming responses |
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
---
## Recent Updates
| Date | Update |
| ---------- | -------------------- |
| 2026-01-07 | Phase docs organized |
---
## Dependencies
Depends on: Phase 3 (Editor UX), Phase 2 (Runtime nodes)
---
## Notes
This phase enables building AI agent interfaces with real-time streaming capabilities.

View File

@@ -0,0 +1,180 @@
# Phase 4: Canvas Visualisation Views - Progress Tracker
**Last Updated:** 2026-07-01
**Overall Status:** 🟡 In Progress
---
## Quick Summary
| Metric | Value |
| ------------ | -------- |
| Total Tasks | 12 |
| Completed | 6 |
| In Progress | 1 |
| Unstable | 2 |
| Not Started | 3 |
| **Progress** | **~60%** |
---
## Task Status
### Prerequisites
| Task | Name | Status | Notes |
| ---------- | ---------------------- | ----------- | ------------------------------------------ |
| PREREQ-001 | Webpack Caching Fix | 🟢 Complete | March 2026 - Fixed dev caching issues |
| PREREQ-002 | React 19 Debug Fixes | 🟢 Complete | March 2026 - Fixed createRoot memory leaks |
| PREREQ-003 | Canvas Overlay Pattern | 🟢 Complete | January 2026 - 5 reference docs created |
| PREREQ-004 | Highlighting API | 🟢 Complete | Phase 1-4 infrastructure done, bug fixed |
### Views
| Task | Name | Status | Notes |
| -------- | ---------------------- | ----------------- | ---------------------------------------------------- |
| VIEW-000 | Foundation & Utils | 🟢 Complete | 26 functions, ~1200 LOC, graph analysis utilities |
| VIEW-001 | Project Topology Map | 🟡 In Progress | Phase 1-2 done, bugs fixed, Phase 3-5 pending |
| VIEW-002 | Component X-Ray | 🟢 Complete | Full implementation, 1 minor known bug with AI nodes |
| VIEW-003 | Trigger Chain Debugger | ⚠️ Unstable | Phase 1-3 done, known issues with deduplication |
| VIEW-004 | Node Census | 🔴 Not Started | README spec only |
| VIEW-005 | Data Lineage View | ⚠️ Not Prod Ready | Code exists but disabled due to bugs |
| VIEW-006 | Impact Radar | 🔴 Not Started | README spec only |
| VIEW-007 | Semantic Layers | 🔴 Not Started | README spec only |
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
- ⚠️ **Unstable/Not Prod Ready** - Has known issues, needs fixes
---
## Recent Updates
| Date | Update |
| ---------- | ------------------------------------------------------------------------ |
| 2026-07-01 | Audit and correction of PROGRESS.md status |
| 2026-04-01 | VIEW-001 bug fixes complete (5 critical bugs) |
| 2026-03-01 | PREREQ-001, PREREQ-002 completed |
| 2026-01-04 | VIEW-003 known issues identified, VIEW-005 disabled |
| 2026-01-03 | VIEW-000, VIEW-002, VIEW-003 Phase 1-3, PREREQ-003, PREREQ-004 completed |
---
## Detailed Status
### PREREQ-001: Webpack Caching Fix ✅
- Fixed persistent webpack caching issues preventing code changes from loading
- Added `cache: false` to dev config, build timestamp canary
- Developers no longer need `npm run clean:all` after every change
### PREREQ-002: React 19 Debug Fixes ✅
- Fixed `createRoot` memory leaks in ConnectionPopup, HMR, and News Modal
- Established root reuse pattern for React 18/19
### PREREQ-003: Canvas Overlay Pattern ✅
- Created 5 reference docs in `dev-docs/reference/CANVAS-OVERLAY-*`
- Documents coordinate systems, event handling, React patterns
- Based on CommentLayer analysis
### PREREQ-004: Highlighting API ✅
- HighlightManager singleton with channel system
- React overlay components (HighlightOverlay, HighlightedNode, HighlightedConnection)
- Fixed MacBook trackpad pinch-zoom displacement bug
- Component boundary infrastructure (skeleton methods for future)
### VIEW-000: Foundation & Utils ✅
- `traversal.ts` - Connection chain tracing
- `crossComponent.ts` - Component boundary resolution
- `categorization.ts` - Semantic node grouping
- `duplicateDetection.ts` - Duplicate node detection
- 26 functions, ~1200 lines of code
### VIEW-001: Project Topology Map 🟡
**Completed:**
- Phase 1: Icons & styling (SVG icons, design tokens)
- Phase 2: Enhanced info (gradients, X-Ray stats, connection counts)
- Bug fixes: Card title wrapping, text contrast, mystery icon, padding, node list
**Pending:**
- Phase 3: Draggable cards (useDraggable hook ready)
- Phase 4: Sticky notes
- Phase 5: Drilldown navigation
### VIEW-002: Component X-Ray ✅
- Full sidebar panel implementation
- Shows usage, interface, structure, subcomponents, external deps, internal state
- Navigation to nodes and components
- Known issue: AI function nodes cause sidebar disappearing bug (workaround: close property editor)
### VIEW-003: Trigger Chain Debugger ⚠️
**Implemented:**
- Phase 1: TriggerChainRecorder infrastructure
- Phase 2: Chain builder utilities
- Phase 3: UI panel with timeline, stats
**Known Issues (see KNOWN-ISSUES.md):**
- Event deduplication still imperfect
- Filtering may show inaccurate data
- Feature marked experimental
### VIEW-005: Data Lineage View ⚠️
**Implemented but Disabled:**
- Core engine in `graphAnalysis/lineage.ts`
- UI components (DataLineagePanel, LineagePath, PathSummary)
**Why Disabled:**
- Event handling/timing issues (panel shows "No node selected")
- Excessive/irrelevant data in results (40+ steps for 3-node connection)
- Needs fundamental algorithm rethink
---
## Dependencies
- **Phase 2** (React Migration) - Required for React overlay patterns
- Canvas overlay pattern documentation (PREREQ-003)
- Graph analysis utilities (VIEW-000)
---
## Notes
### What's Working Well
- Foundation utilities are robust and well-documented
- Component X-Ray provides significant value
- Highlighting API infrastructure is solid
- Prerequisites unblocked all development work
### What Needs Attention
- VIEW-003 needs stability fixes before production use
- VIEW-005 needs algorithm redesign (not small fixes)
- VIEW-001 has remaining phases to implement
### Recommended Next Steps
1. Fix VIEW-003 known issues (improve deduplication)
2. Complete VIEW-001 Phase 3 (draggable cards)
3. Consider if VIEW-005 should be redesigned or removed
4. VIEW-004 (Node Census) would be straightforward to implement

View File

@@ -0,0 +1,111 @@
# Phase 5: Multi-Target Deployment - Progress Tracker
**Last Updated:** 2026-01-07
**Overall Status:** 🟡 In Progress
---
## Quick Summary
| Metric | Value |
| ------------ | ------- |
| Total Tasks | 11 |
| Completed | 2 |
| In Progress | 0 |
| Not Started | 9 |
| **Progress** | **18%** |
---
## Task Status
### Phase A: BYOB Backend System 🟡 In Progress
| Task | Name | Status | Notes |
| -------- | ---------------------- | -------------- | ---------------------------------------- |
| TASK-001 | Backend Services Panel | 🟢 Complete | Completed 2025-12-29 |
| TASK-002 | Data Nodes | 🟢 Complete | Completed Dec 2025 with bug fixes Dec 30 |
| TASK-003 | Schema Viewer | 🔴 Not Started | Browse backend schema in dedicated UI |
| TASK-004 | Edit Backend Dialog | 🔴 Not Started | Edit existing backend configurations |
| TASK-005 | Local Docker Wizard | 🔴 Not Started | Spin up backends locally |
| TASK-006 | Auth Nodes | 🔴 Not Started | Authentication node integration |
| TASK-007 | Integrated Backend | 🔴 Not Started | Zero-config local backend (docs only) |
### Other Deployment Targets 🔴 Not Started
| Phase | Name | Status | Notes |
| ------- | ----------------------- | -------------- | ------------------------- |
| Phase B | Capacitor Mobile Target | 🔴 Not Started | iOS/Android via Capacitor |
| Phase C | Electron Desktop Target | 🔴 Not Started | Desktop app deployment |
| Phase D | Chrome Extension Target | 🔴 Not Started | Browser extension support |
| Phase E | Target System Core | 🔴 Not Started | Node compatibility badges |
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
---
## Recent Updates
| Date | Update |
| ---------- | --------------------------------------------------------- |
| 2026-01-07 | Corrected PROGRESS.md to reflect actual completion status |
| 2025-12-30 | TASK-002 bug fixes and system table support |
| 2025-12-29 | TASK-001 Backend Services Panel completed |
| 2025-12-29 | TASK-002 Data Nodes completed |
---
## Completed Work Summary
### TASK-001: Backend Services Panel ✅
- New "Backend Services" sidebar panel
- Backend list with connection status
- Add Backend Dialog with presets (Directus, Supabase, Pocketbase)
- Schema introspection for connected backends
- Persistence to project metadata
### TASK-002: Data Nodes ✅
- Query Records node with visual filter builder
- Create Record node with schema-driven inputs
- Update Record node with schema-driven inputs
- Delete Record node
- System table support (directus\_\* collections)
- Type-aware inputs (numbers, booleans, dates, enums)
- Date normalization to ISO 8601
**Implementation Files:**
```
packages/noodl-runtime/src/nodes/std-library/data/
├── byob-utils.js
├── byob-query-data.js
├── byob-create-record.js
├── byob-update-record.js
└── byob-delete-record.js
packages/noodl-editor/src/editor/src/
├── models/BackendServices/
└── views/panels/BackendServicesPanel/
```
---
## Dependencies
Depends on: Phase 2 (Runtime), HTTP Node updates
---
## Notes
- Phase A (BYOB) has significant progress with 2/7 tasks complete
- Phase E (Target System Core) should start first as foundation for other deployment targets
- TASK-007 (Integrated Backend) has comprehensive documentation but no implementation yet

View File

@@ -0,0 +1,57 @@
# Phase 6: UBA System (Universal Backend Adapter) - Progress Tracker
**Last Updated:** 2026-01-07
**Overall Status:** 🔴 Not Started
---
## Quick Summary
| Metric | Value |
| ------------ | ------ |
| Total Tasks | 6 |
| Completed | 0 |
| In Progress | 0 |
| Not Started | 6 |
| **Progress** | **0%** |
---
## Task Status
| Task | Name | Status | Notes |
| ------- | ----------------- | -------------- | -------------------------- |
| UBA-001 | Foundation | 🔴 Not Started | Schema parser, basic UI |
| UBA-002 | Field Types | 🔴 Not Started | Complex field type support |
| UBA-003 | Debug System | 🔴 Not Started | Debug streaming for panels |
| UBA-004 | Polish | 🔴 Not Started | UX improvements |
| UBA-005 | Reference Backend | 🔴 Not Started | Reference implementation |
| UBA-006 | Community | 🔴 Not Started | Community adapter sharing |
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
---
## Recent Updates
| Date | Update |
| ---------- | ---------------------------------------- |
| 2026-01-07 | Moved from Phase 3 TASK-008 to own phase |
---
## Dependencies
Depends on: Phase 3 (Editor UX foundation)
---
## Notes
This phase was previously TASK-008 in Phase 3. Moved to its own phase for clarity. UBA enables configuring any backend (Directus, Supabase, etc.) through a unified adapter interface.

View File

@@ -0,0 +1,96 @@
# Phase 6: Universal Backend Adapter (UBA) System
**Phase:** 6
**Status:** 🔴 Not Started
**Effort:** 8-12 weeks
**Priority:** HIGH
---
## Overview
The Universal Backend Adapter (UBA) system enables Noodl to connect to any backend service (Directus, Supabase, Pocketbase, Firebase, custom APIs) through a unified configuration interface. Instead of hardcoding backend integrations, users configure adapters that translate between Noodl's data model and the target backend.
---
## Problem Statement
Currently, Noodl users who want to use external backends must:
1. Manually configure HTTP requests for each endpoint
2. Handle authentication, pagination, and error handling themselves
3. Build custom UI for CRUD operations
4. No schema introspection - everything is manual
---
## Solution: UBA System
```
┌─────────────────────────────────────────────────────────────────┐
│ NOODL DATA LAYER │
│ │
│ Query Node → UBA Adapter → Backend API → Response │
│ │
│ The adapter handles: │
│ • Authentication (Bearer, Basic, API Key) │
│ • Schema introspection │
│ • Query translation │
│ • Pagination │
│ • Error normalization │
└─────────────────────────────────────────────────────────────────┘
```
---
## Task Breakdown
| Task | Name | Description | Effort |
| ------- | ----------------- | --------------------------------- | --------- |
| UBA-001 | Foundation | Schema parser, basic field types | 2-3 weeks |
| UBA-002 | Field Types | Complex fields (relations, JSON) | 1-2 weeks |
| UBA-003 | Debug System | Live debugging panel | 1-2 weeks |
| UBA-004 | Polish | UX improvements, error handling | 1 week |
| UBA-005 | Reference Backend | Example implementation (Directus) | 1-2 weeks |
| UBA-006 | Community | Adapter sharing, marketplace | 2-3 weeks |
---
## Architecture
See individual task files for detailed architecture:
- [UBA-001-FOUNDATION.md](./UBA-001-FOUNDATION.md) - Core system architecture
- [UBA-002-FIELD-TYPES.md](./UBA-002-FIELD-TYPES.md) - Field type system
- [UBA-003-DEBUG-SYSTEM.md](./UBA-003-DEBUG-SYSTEM.md) - Debug infrastructure
- [UBA-004-POLISH.md](./UBA-004-POLISH.md) - UX polish tasks
- [UBA-005-REFERENCE-BACKEND.md](./UBA-005-REFERENCE-BACKEND.md) - Directus adapter
- [UBA-006-COMMUNITY.md](./UBA-006-COMMUNITY.md) - Community features
---
## Dependencies
- Phase 3 Editor UX (property panel infrastructure)
- HTTP Node improvements (Phase 2/3)
---
## Success Criteria
- [ ] Users can configure Directus/Supabase connection via UI
- [ ] Schema introspection populates dropdowns automatically
- [ ] CRUD operations work with configured adapters
- [ ] Debug panel shows live request/response data
- [ ] At least 3 backend adapters available
---
## History
- **2026-01-07**: Moved from Phase 3 TASK-008 to dedicated Phase 6
- Previously named "granular-deployment" which was misleading
---
_Last Updated: January 2026_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,871 @@
# Phase 6D: UBA Polish & Documentation
## Error Handling, Performance, and Developer Documentation
**Phase:** 6D of 6
**Duration:** 2 weeks (10 working days)
**Priority:** HIGH
**Status:** NOT STARTED
**Depends On:** Phase 6A, 6B, 6C complete
---
## Overview
Phase 6D focuses on production readiness: comprehensive error handling, performance optimization, accessibility compliance, and complete documentation for both users and backend developers.
This phase transforms the UBA system from "it works" to "it works reliably and is well-documented."
### Key Outcomes
1. **Robust Error Handling** - Graceful failures, helpful messages, recovery paths
2. **Performance** - Smooth UI even with complex schemas and many events
3. **Accessibility** - Full keyboard navigation, screen reader support
4. **Documentation** - Schema reference, backend guide, tutorials
---
## Goals
1. **Comprehensive error handling** - Every failure mode handled gracefully
2. **Performance optimization** - Lazy loading, virtualization, caching
3. **Backend Services integration** - UBA seamlessly integrated into existing panel
4. **Complete documentation** - Reference docs, tutorials, examples
5. **Example schemas** - Templates for common backend types
---
## Prerequisites
- Phase 6A complete ✅
- Phase 6B complete ✅
- Phase 6C complete ✅
---
## Task Breakdown
### UBA-018: Error Handling
**Effort:** 3 days
**Assignee:** TBD
**Branch:** `feature/uba-018-error-handling`
#### Description
Implement comprehensive error handling for all UBA operations with user-friendly messages, recovery suggestions, and graceful degradation.
#### Error Categories
| Category | Examples | User Impact |
|----------|----------|-------------|
| **Network** | Backend unreachable, timeout, DNS failure | Can't fetch schema or push config |
| **Schema** | Invalid YAML, unsupported version, missing fields | Can't render config panel |
| **Auth** | Token expired, invalid credentials, 403 | Can't communicate with backend |
| **Validation** | Required field missing, pattern mismatch | Can't save config |
| **Runtime** | Debug stream disconnected, event parse error | Degraded debugging |
#### Files to Create
```
packages/noodl-editor/src/editor/src/models/UBA/
├── errors/
│ ├── UBAError.ts
│ ├── NetworkError.ts
│ ├── SchemaError.ts
│ ├── AuthError.ts
│ ├── ValidationError.ts
│ └── index.ts
└── ErrorRecovery.ts
packages/noodl-editor/src/editor/src/views/UBA/
├── ErrorBoundary.tsx
├── ErrorDisplay.tsx
└── ErrorRecoveryActions.tsx
```
#### Implementation
```typescript
// UBAError.ts
export abstract class UBAError extends Error {
abstract readonly code: string;
abstract readonly category: 'network' | 'schema' | 'auth' | 'validation' | 'runtime';
abstract readonly recoverable: boolean;
abstract readonly userMessage: string;
abstract readonly recoveryActions: RecoveryAction[];
readonly timestamp: Date = new Date();
readonly context: Record<string, any> = {};
constructor(message: string, context?: Record<string, any>) {
super(message);
this.name = this.constructor.name;
if (context) {
this.context = context;
}
}
toJSON() {
return {
code: this.code,
category: this.category,
message: this.message,
userMessage: this.userMessage,
recoverable: this.recoverable,
context: this.context,
timestamp: this.timestamp.toISOString()
};
}
}
export interface RecoveryAction {
label: string;
action: () => void | Promise<void>;
primary?: boolean;
}
// NetworkError.ts
export class BackendUnreachableError extends UBAError {
readonly code = 'BACKEND_UNREACHABLE';
readonly category = 'network' as const;
readonly recoverable = true;
get userMessage(): string {
return `Cannot connect to backend at ${this.context.url}. Please check that the backend is running and accessible.`;
}
get recoveryActions(): RecoveryAction[] {
return [
{
label: 'Retry Connection',
action: this.context.retry,
primary: true
},
{
label: 'Check Backend Status',
action: () => window.open(this.context.healthUrl, '_blank')
},
{
label: 'Use Cached Schema',
action: this.context.useCached
}
];
}
}
export class RequestTimeoutError extends UBAError {
readonly code = 'REQUEST_TIMEOUT';
readonly category = 'network' as const;
readonly recoverable = true;
get userMessage(): string {
return `Request to backend timed out after ${this.context.timeout}ms. The backend may be overloaded.`;
}
get recoveryActions(): RecoveryAction[] {
return [
{ label: 'Retry', action: this.context.retry, primary: true },
{ label: 'Increase Timeout', action: this.context.increaseTimeout }
];
}
}
// SchemaError.ts
export class SchemaParseError extends UBAError {
readonly code = 'SCHEMA_PARSE_ERROR';
readonly category = 'schema' as const;
readonly recoverable = false;
get userMessage(): string {
const location = this.context.line ? ` at line ${this.context.line}` : '';
return `Failed to parse backend schema${location}: ${this.context.parseError}`;
}
get recoveryActions(): RecoveryAction[] {
return [
{ label: 'View Raw Schema', action: this.context.viewRaw },
{ label: 'Report Issue', action: () => this.context.reportIssue() }
];
}
}
export class UnsupportedSchemaVersionError extends UBAError {
readonly code = 'UNSUPPORTED_SCHEMA_VERSION';
readonly category = 'schema' as const;
readonly recoverable = false;
get userMessage(): string {
return `Schema version ${this.context.schemaVersion} is not supported. Nodegx supports up to version ${this.context.supportedVersion}.`;
}
get recoveryActions(): RecoveryAction[] {
return [
{ label: 'Check for Updates', action: this.context.checkUpdates, primary: true }
];
}
}
// AuthError.ts
export class AuthenticationError extends UBAError {
readonly code = 'AUTH_FAILED';
readonly category = 'auth' as const;
readonly recoverable = true;
get userMessage(): string {
if (this.context.status === 401) {
return 'Authentication failed. Your credentials may be invalid or expired.';
}
if (this.context.status === 403) {
return 'Access denied. You may not have permission to access this backend.';
}
return 'Authentication error occurred.';
}
get recoveryActions(): RecoveryAction[] {
return [
{ label: 'Update Credentials', action: this.context.openAuthDialog, primary: true },
{ label: 'Remove Backend', action: this.context.removeBackend }
];
}
}
// ErrorBoundary.tsx
export class UBAErrorBoundary extends React.Component<
{ children: React.ReactNode; fallback?: React.ReactNode },
{ error: Error | null; errorInfo: React.ErrorInfo | null }
> {
state = { error: null, errorInfo: null };
static getDerivedStateFromError(error: Error) {
return { error };
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
this.setState({ errorInfo });
console.error('UBA Error Boundary caught error:', error, errorInfo);
}
handleRetry = () => {
this.setState({ error: null, errorInfo: null });
};
render() {
if (this.state.error) {
return this.props.fallback || (
<ErrorDisplay
error={this.state.error}
errorInfo={this.state.errorInfo}
onRetry={this.handleRetry}
/>
);
}
return this.props.children;
}
}
// ErrorDisplay.tsx
export function ErrorDisplay({ error, errorInfo, onRetry, compact }: ErrorDisplayProps) {
const isUBAError = error instanceof UBAError;
if (compact) {
return (
<div className={css['error-compact']}>
<IconAlertCircle />
<span>{isUBAError ? error.userMessage : error.message}</span>
{onRetry && <button onClick={onRetry}>Retry</button>}
</div>
);
}
return (
<div className={css['error-display']}>
<div className={css['error-header']}>
<IconAlertCircle />
<h3>Something went wrong</h3>
</div>
<p className={css['error-message']}>
{isUBAError ? error.userMessage : error.message}
</p>
{isUBAError && error.recoveryActions.length > 0 && (
<div className={css['recovery-actions']}>
{error.recoveryActions.map((action, index) => (
<button
key={index}
onClick={() => action.action()}
className={cn(css['action-button'], action.primary && css['primary'])}
>
{action.label}
</button>
))}
</div>
)}
{process.env.NODE_ENV === 'development' && (
<details className={css['error-details']}>
<summary>Technical Details</summary>
<pre>{isUBAError ? JSON.stringify(error.toJSON(), null, 2) : error.stack}</pre>
</details>
)}
</div>
);
}
```
#### Error Scenarios
| Scenario | Error Class | Recovery |
|----------|-------------|----------|
| Backend URL returns 404 | `BackendUnreachableError` | Retry, check URL |
| Schema YAML syntax error | `SchemaParseError` | View raw, report |
| Schema version too new | `UnsupportedSchemaVersionError` | Update Nodegx |
| API key expired | `AuthenticationError` | Update credentials |
| Config push rejected | `ConfigRejectedError` | Show field errors |
| WebSocket disconnected | `DebugDisconnectedError` | Auto-reconnect |
#### Acceptance Criteria
- [ ] All error classes implemented
- [ ] User-friendly messages for all errors
- [ ] Recovery actions work correctly
- [ ] Error boundary catches React errors
- [ ] Development mode shows details
- [ ] Production mode hides internals
---
### UBA-019: Performance Optimization
**Effort:** 3 days
**Assignee:** TBD
**Branch:** `feature/uba-019-performance`
#### Description
Optimize UBA system performance through lazy loading, memoization, virtualization, and efficient caching.
#### Performance Goals
| Metric | Target | Method |
|--------|--------|--------|
| Schema parse time | < 50ms | Optimize parser |
| Config panel render | < 100ms | Lazy load fields |
| Field type switch | < 16ms | Memoization |
| Debug event render | < 5ms | Virtualization |
| Memory (1000 events) | < 50MB | Ring buffer |
#### Key Optimizations
##### 1. Lazy Loading Field Renderers
```typescript
// fields/index.ts
const fieldComponents: Record<string, React.LazyExoticComponent<any>> = {
string: React.lazy(() => import('./StringField')),
text: React.lazy(() => import('./TextField')),
number: React.lazy(() => import('./NumberField')),
// Complex types loaded only when needed
field_mapping: React.lazy(() => import('./FieldMappingField')),
prompt: React.lazy(() => import('./PromptField')),
code: React.lazy(() => import('./CodeField')),
};
export function FieldRenderer({ field, ...props }: FieldRendererProps) {
const Component = fieldComponents[field.type] || fieldComponents.string;
return (
<React.Suspense fallback={<FieldSkeleton />}>
<Component field={field} {...props} />
</React.Suspense>
);
}
```
##### 2. Memoized Components
```typescript
// ConfigSection.tsx
export const ConfigSection = React.memo(function ConfigSection({
section, values, errors, onChange, disabled
}: ConfigSectionProps) {
const visibility = useMemo(
() => calculateVisibility(section.fields, values),
[section.fields, values]
);
const handleFieldChange = useCallback(
(fieldId: string) => (value: any) => onChange(`${section.id}.${fieldId}`, value),
[section.id, onChange]
);
return (
<div className={css['section']}>
{section.fields.map(field => (
visibility.get(field.id)?.visible && (
<MemoizedFieldRenderer
key={field.id}
field={field}
value={getNestedValue(values, `${section.id}.${field.id}`)}
onChange={handleFieldChange(field.id)}
error={errors[`${section.id}.${field.id}`]}
disabled={disabled}
/>
)
))}
</div>
);
});
```
##### 3. Virtualized Debug Event List
```typescript
// DebugEventTree.tsx
import { VariableSizeList } from 'react-window';
import AutoSizer from 'react-virtualized-auto-sizer';
export function DebugEventTree({ events, eventSchema }: DebugEventTreeProps) {
const [expandedEvents, setExpandedEvents] = useState<Set<string>>(new Set());
const getItemSize = useCallback((index: number) => {
const event = events[index];
return expandedEvents.has(event.id) ? 200 : 48;
}, [events, expandedEvents]);
return (
<AutoSizer>
{({ height, width }) => (
<VariableSizeList
height={height}
width={width}
itemCount={events.length}
itemSize={getItemSize}
overscanCount={5}
>
{({ index, style }) => (
<div style={style}>
<DebugEventItem
event={events[index]}
expanded={expandedEvents.has(events[index].id)}
onToggle={() => toggleExpand(events[index].id)}
/>
</div>
)}
</VariableSizeList>
)}
</AutoSizer>
);
}
```
##### 4. Schema Caching with ETag
```typescript
// SchemaCache.ts
export class SchemaCache {
private cache: Map<string, CacheEntry> = new Map();
private ttl = 24 * 60 * 60 * 1000; // 24 hours
async fetchWithCache(url: string, auth?: AuthConfig): Promise<UBASchema> {
const cached = this.cache.get(url);
const headers: HeadersInit = { ...buildAuthHeaders(auth) };
if (cached?.etag) {
headers['If-None-Match'] = cached.etag;
}
const response = await fetch(url, { headers });
if (response.status === 304 && cached) {
return cached.schema; // Not modified
}
const rawYaml = await response.text();
const schema = parseSchema(rawYaml);
const etag = response.headers.get('ETag') || undefined;
this.cache.set(url, { schema, fetchedAt: Date.now(), etag });
return schema;
}
}
```
#### Performance Tests
```typescript
describe('UBA Performance', () => {
it('parses complex schema in < 50ms', async () => {
const start = performance.now();
await parseSchema(complexSchemaYaml);
expect(performance.now() - start).toBeLessThan(50);
});
it('renders config panel in < 100ms', async () => {
const start = performance.now();
render(<ConfigPanel schema={complexSchema} />);
await waitFor(() => screen.getByRole('tablist'));
expect(performance.now() - start).toBeLessThan(100);
});
it('handles 1000 debug events without memory leak', () => {
const store = new DebugStore({ maxEvents: 1000 });
for (let i = 0; i < 2000; i++) {
store.addEvent(generateMockEvent(i));
}
expect(store.getAllEvents().length).toBe(1000);
});
});
```
#### Acceptance Criteria
- [ ] Lazy loading implemented
- [ ] Component memoization applied
- [ ] Debug list virtualized
- [ ] Schema caching with ETag
- [ ] Performance benchmarks pass
---
### UBA-020: Backend Services Integration
**Effort:** 2 days
**Assignee:** TBD
**Branch:** `feature/uba-020-backend-integration`
#### Description
Integrate UBA backends into the existing Backend Services panel for a unified experience.
#### Integration Points
1. **Backend List** - UBA backends appear alongside Directus, Supabase
2. **Add Backend Dialog** - "Schema-Configured Backend" option
3. **Config Button** - Opens UBA Config Panel
4. **Debug Button** - Opens Debug Panel (if supported)
5. **Health Status** - Show connection status
#### Implementation
```typescript
// BackendPanel.tsx (updated)
export function BackendPanel() {
const { directusBackends, supabaseBackends } = useBYOBBackends();
const { ubaBackends } = useUBABackends();
return (
<div className={css['backend-panel']}>
<section className={css['section']}>
<h3>Data Backends</h3>
<BackendList backends={[...directusBackends, ...supabaseBackends]} />
</section>
<section className={css['section']}>
<h3>Schema-Configured Backends</h3>
{ubaBackends.length === 0 ? (
<EmptyState message="No schema-configured backends" />
) : (
ubaBackends.map(backend => (
<UBABackendItem
key={backend.id}
backend={backend}
onConfigure={() => openConfigPanel(backend)}
onDebug={() => openDebugPanel(backend)}
/>
))
)}
</section>
<Button onClick={openAddDialog}>
<IconPlus /> Add Backend
</Button>
</div>
);
}
// UBABackendItem.tsx
export function UBABackendItem({ backend, onConfigure, onDebug, onRemove }) {
const [healthStatus, setHealthStatus] = useState<'healthy' | 'unhealthy' | 'checking'>('checking');
useEffect(() => {
checkHealth(backend).then(setHealthStatus);
}, [backend]);
return (
<div className={css['backend-item']}>
<div className={css['backend-info']}>
<h4>{backend.schema.backend.name}</h4>
<p>{backend.url}</p>
<HealthBadge status={healthStatus} />
</div>
<div className={css['actions']}>
<Button onClick={onConfigure}><IconSettings /></Button>
{backend.schema.debug?.enabled && (
<Button onClick={onDebug}><IconBug /></Button>
)}
<Button onClick={onRemove}><IconTrash /></Button>
</div>
</div>
);
}
```
#### Acceptance Criteria
- [ ] UBA backends appear in panel
- [ ] Add dialog includes UBA option
- [ ] Configure opens Config Panel
- [ ] Debug opens Debug Panel
- [ ] Health status displayed
---
### UBA-021: Documentation
**Effort:** 4 days
**Assignee:** TBD
**Branch:** `feature/uba-021-documentation`
#### Description
Create comprehensive documentation for UBA.
#### Documentation Structure
```
docs/uba/
├── README.md # Overview and quick start
├── schema-specification.md # Complete schema reference
├── field-types.md # All field types with examples
├── backend-implementation.md # How to make backends UBA-compatible
├── tutorials/
│ ├── first-backend.md # Create your first UBA backend
│ ├── field-mapping.md # Using field mappings
│ ├── debug-integration.md # Adding debug support
│ └── advanced-validation.md # Custom validation
├── api-reference/
│ ├── endpoints.md # Required and optional endpoints
│ ├── events.md # Debug event format
│ └── responses.md # Response formats
└── troubleshooting.md # Common issues and solutions
```
#### Key Content
##### Quick Start (README.md)
```markdown
# Universal Backend Adapter (UBA)
Connect any backend to Nodegx with a simple YAML schema.
## Quick Start
### 1. Create Schema
```yaml
schema_version: "1.0"
backend:
id: "my-backend"
name: "My Backend"
version: "1.0.0"
endpoints:
config: "/nodegx/config"
sections:
- id: "settings"
fields:
- id: "api_key"
type: "secret"
name: "API Key"
required: true
```
### 2. Serve Schema
```python
@app.get("/.well-known/nodegx-schema.yaml")
async def get_schema():
return FileResponse("nodegx-schema.yaml")
```
### 3. Implement Config Endpoint
```python
@app.post("/nodegx/config")
async def apply_config(request: ConfigRequest):
# Apply configuration
return {"success": True, "applied_at": datetime.utcnow().isoformat()}
```
[Full Guide →](./backend-implementation.md)
```
##### Backend Implementation Guide
- Python/FastAPI example
- Node.js/Express example
- Go example
- Health endpoint
- Debug stream implementation
- Testing your integration
#### Acceptance Criteria
- [ ] README with quick start
- [ ] Schema specification complete
- [ ] All field types documented
- [ ] Backend guide with examples
- [ ] 4+ tutorials
- [ ] API reference
- [ ] Troubleshooting guide
---
### UBA-022: Example Schemas
**Effort:** 2 days
**Assignee:** TBD
**Branch:** `feature/uba-022-examples`
#### Description
Create example schemas for common backend types.
#### Examples
1. **Minimal** - Simplest possible schema
2. **AI Agent** - Full-featured with debug
3. **Analytics** - Event tracking backend
4. **Webhook Handler** - With code field
```yaml
# examples/minimal.yaml
schema_version: "1.0"
backend:
id: "minimal"
name: "Minimal Backend"
version: "1.0.0"
endpoints:
config: "/config"
sections:
- id: "settings"
name: "Settings"
fields:
- id: "enabled"
type: "boolean"
name: "Enabled"
default: true
```
```yaml
# examples/ai-agent.yaml
schema_version: "1.0"
backend:
id: "ai-agent"
name: "AI Agent"
version: "1.0.0"
endpoints:
config: "/nodegx/config"
health: "/health"
debug_stream: "/nodegx/debug"
capabilities:
hot_reload: true
debug: true
sections:
- id: "llm"
name: "Language Model"
fields:
- id: "provider"
type: "select"
options:
- value: "anthropic"
label: "Anthropic"
- value: "openai"
label: "OpenAI"
- id: "api_key"
type: "secret"
required: true
- id: "temperature"
type: "slider"
min: 0
max: 2
default: 0.7
- id: "tools"
name: "Tools"
fields:
- id: "web_search"
type: "tool_toggle"
name: "Web Search"
default: true
- id: "prompts"
name: "Prompts"
fields:
- id: "system"
type: "prompt"
variables:
- name: "agent_name"
source: "project.name"
debug:
enabled: true
event_schema:
- id: "agent_step"
fields:
- id: "step"
type: "string"
- id: "duration_ms"
type: "number"
format: "duration"
```
#### Acceptance Criteria
- [ ] Minimal example
- [ ] AI Agent example
- [ ] Analytics example
- [ ] Webhook example
- [ ] All validate correctly
---
## Phase 6D Checklist
### UBA-018: Error Handling
- [ ] Error class hierarchy
- [ ] All error types
- [ ] Error boundary
- [ ] Error display
- [ ] Recovery actions
### UBA-019: Performance
- [ ] Lazy loading
- [ ] Memoization
- [ ] Virtualization
- [ ] Caching
- [ ] Benchmarks pass
### UBA-020: Integration
- [ ] Backend panel updated
- [ ] UBA backend item
- [ ] Add dialog option
- [ ] Panel connections
### UBA-021: Documentation
- [ ] README
- [ ] Schema spec
- [ ] Field types
- [ ] Backend guide
- [ ] Tutorials
- [ ] API reference
### UBA-022: Examples
- [ ] Minimal
- [ ] AI Agent
- [ ] Analytics
- [ ] Webhook
---
## Success Criteria
- [ ] All errors handled gracefully
- [ ] Performance benchmarks pass
- [ ] Documentation complete
- [ ] Examples validated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,228 @@
# CODE-007: CLI & Editor Integration
## Overview
The CLI & Editor Integration task provides the command-line interface for exporting Noodl projects to React code, and integrates the export functionality into the editor UI.
**Estimated Effort:** 1-2 weeks
**Priority:** MEDIUM
**Dependencies:** CODE-001 through CODE-006
**Blocks:** None (final integration task)
---
## CLI Tool
### Package: @nodegx/cli
```bash
# Installation
npm install -g @nodegx/cli
# Usage
nodegx export ./my-project --output ./my-app
nodegx export ./my-project --output ./my-app --typescript
nodegx export ./my-project --output ./my-app --css-mode tailwind
```
### CLI Options
| Option | Description | Default |
| --------------- | --------------------------------------------- | ---------- |
| `--output, -o` | Output directory | `./export` |
| `--typescript` | Generate TypeScript | `true` |
| `--css-mode` | CSS approach: `modules`, `tailwind`, `inline` | `modules` |
| `--clean` | Clean output directory first | `false` |
| `--verbose, -v` | Verbose output | `false` |
| `--dry-run` | Preview without writing files | `false` |
### CLI Implementation
```typescript
// packages/nodegx-cli/src/index.ts
import { Command } from 'commander';
import { exportProject } from './export';
const program = new Command();
program.name('nodegx').description('Export Noodl projects to React applications').version('0.1.0');
program
.command('export <project-path>')
.description('Export a Noodl project to React code')
.option('-o, --output <dir>', 'Output directory', './export')
.option('--typescript', 'Generate TypeScript', true)
.option('--css-mode <mode>', 'CSS mode: modules, tailwind, inline', 'modules')
.option('--clean', 'Clean output directory first', false)
.option('-v, --verbose', 'Verbose output', false)
.option('--dry-run', 'Preview without writing files', false)
.action(async (projectPath, options) => {
await exportProject(projectPath, options);
});
program.parse();
```
---
## Editor Integration
### Export Menu Item
Add "Export to React" option in File menu:
```typescript
// In editor menu configuration
{
label: 'Export to React...',
click: () => {
showExportDialog();
}
}
```
### Export Dialog UI
```tsx
// components/ExportDialog.tsx
interface ExportDialogProps {
projectPath: string;
onExport: (options: ExportOptions) => void;
onCancel: () => void;
}
function ExportDialog({ projectPath, onExport, onCancel }: ExportDialogProps) {
const [outputDir, setOutputDir] = useState('./export');
const [cssMode, setCssMode] = useState<'modules' | 'tailwind' | 'inline'>('modules');
const [useTypeScript, setUseTypeScript] = useState(true);
return (
<Dialog title="Export to React">
<FormField label="Output Directory">
<DirectoryPicker value={outputDir} onChange={setOutputDir} />
</FormField>
<FormField label="CSS Mode">
<Select value={cssMode} onChange={setCssMode}>
<Option value="modules">CSS Modules</Option>
<Option value="tailwind">Tailwind CSS</Option>
<Option value="inline">Inline Styles</Option>
</Select>
</FormField>
<FormField label="TypeScript">
<Checkbox checked={useTypeScript} onChange={setUseTypeScript} />
</FormField>
<DialogFooter>
<Button onClick={onCancel}>Cancel</Button>
<Button primary onClick={() => onExport({ outputDir, cssMode, useTypeScript })}>
Export
</Button>
</DialogFooter>
</Dialog>
);
}
```
### Progress Indicator
Show export progress:
```tsx
function ExportProgress({ status, progress, currentFile }: ExportProgressProps) {
return (
<div className={styles.progress}>
<ProgressBar value={progress} max={100} />
<span className={styles.status}>{status}</span>
{currentFile && <span className={styles.currentFile}>Processing: {currentFile}</span>}
</div>
);
}
```
---
## Export Workflow
### 1. Project Analysis
```typescript
async function analyzeProject(projectPath: string): Promise<ProjectAnalysis> {
const project = await loadProject(projectPath);
return {
components: analyzeComponents(project),
stores: analyzeStores(project),
events: analyzeEvents(project),
routes: analyzeRoutes(project),
assets: analyzeAssets(project)
};
}
```
### 2. Code Generation
```typescript
async function generateCode(analysis: ProjectAnalysis, options: ExportOptions): Promise<GeneratedFiles> {
const files: GeneratedFiles = {};
// Generate stores
files['src/stores/variables.ts'] = generateVariables(analysis.stores);
files['src/stores/objects.ts'] = generateObjects(analysis.stores);
files['src/stores/arrays.ts'] = generateArrays(analysis.stores);
// Generate components
for (const component of analysis.components) {
const code = generateComponent(component, options);
files[`src/components/${component.name}.tsx`] = code;
}
// Generate events
files['src/events/channels.ts'] = generateEventChannels(analysis.events);
// Generate routing
files['src/App.tsx'] = generateApp(analysis.routes);
return files;
}
```
### 3. File Output
```typescript
async function writeFiles(files: GeneratedFiles, outputDir: string, options: ExportOptions): Promise<void> {
if (options.clean) {
await fs.rm(outputDir, { recursive: true, force: true });
}
await fs.mkdir(outputDir, { recursive: true });
for (const [path, content] of Object.entries(files)) {
const fullPath = join(outputDir, path);
await fs.mkdir(dirname(fullPath), { recursive: true });
await fs.writeFile(fullPath, content, 'utf-8');
}
}
```
---
## Testing Checklist
- [ ] CLI parses all options correctly
- [ ] Export creates valid project structure
- [ ] Editor dialog shows correct options
- [ ] Progress updates during export
- [ ] Error handling shows helpful messages
- [ ] Generated project builds without errors
---
## Success Criteria
1. **CLI works standalone** - Export works without editor
2. **Editor integration seamless** - One-click export from menu
3. **Clear feedback** - Progress and errors well-communicated
4. **Generated code runs** - `npm install && npm run dev` succeeds

View File

@@ -0,0 +1,70 @@
# Phase 7: Code Export - Progress Tracker
**Last Updated:** 2026-01-07
**Overall Status:** 🔴 Not Started
---
## Quick Summary
| Metric | Value |
| ------------ | ------ |
| Total Tasks | 8 |
| Completed | 0 |
| In Progress | 0 |
| Not Started | 8 |
| **Progress** | **0%** |
---
## Task Status
| Task | Name | Status | Effort | Notes |
| -------- | ---------------------- | -------------- | --------- | ----------------------------- |
| CODE-001 | @nodegx/core Library | 🔴 Not Started | 2-3 weeks | Companion runtime library |
| CODE-002 | Visual Node Generator | 🔴 Not Started | 1-2 weeks | UI components + styling |
| CODE-003 | State Store Generator | 🔴 Not Started | 1-2 weeks | Variables, Objects, Arrays |
| CODE-004 | Logic Node Generator | 🔴 Not Started | 2-3 weeks | Functions, Expressions, Logic |
| CODE-005 | Event System Generator | 🔴 Not Started | 1-2 weeks | Send/Receive Event, Scope |
| CODE-006 | Project Scaffolding | 🔴 Not Started | 1-2 weeks | Routing, entry point, build |
| CODE-007 | CLI & Integration | 🔴 Not Started | 1-2 weeks | Export command, editor UI |
| CODE-008 | Node Comments Export | 🔴 Not Started | 1 week | Export node comments to code |
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
---
## Recent Updates
| Date | Update |
| ---------- | ----------------------------------------------- |
| 2026-01-07 | Updated PROGRESS.md to list all 8 defined tasks |
| 2026-01-07 | Renumbered from Phase 6 to Phase 7 |
---
## Dependencies
Depends on: Phase 2 (React Migration), Phase 10 (Project Structure)
---
## Documentation
- [CODE-EXPORT-overview.md](./CODE-EXPORT-overview.md) - Full system overview
- [CODE-REFERENCE-noodl-nodes.md](./CODE-REFERENCE-noodl-nodes.md) - Node mapping reference
- Individual task specs: CODE-001 through CODE-008
---
## Notes
This phase enables exporting Noodl projects as standalone React 19 applications. Uses a companion library approach (@nodegx/core) to preserve Noodl's mental model while generating idiomatic React code.
**Estimated Total Effort:** 12-16 weeks

View File

@@ -0,0 +1,153 @@
# Phase 8: Auto-Update & Distribution - Progress Tracker
**Last Updated:** 2026-01-07
**Overall Status:** 🔴 Not Started
---
## Quick Summary
| Metric | Value |
| ------------ | ------ |
| Total Tasks | 5 |
| Completed | 0 |
| In Progress | 0 |
| Not Started | 5 |
| **Progress** | **0%** |
**Estimated Effort:** 38-56 hours (excluding optional Windows signing)
---
## Task Status
| Task | Name | Status | Effort | Doc |
| ---- | -------------------------------- | -------------- | ------ | -------------------------------------------- |
| 7.1 | Rebrand to Nodegex | 🔴 Not Started | 4-6h | [TASK-7.1](./TASK-7.1-rebrand-nodegex.md) |
| 7.2 | Fix macOS Code Signing | 🔴 Not Started | 8-12h | [TASK-7.2](./TASK-7.2-macos-signing.md) |
| 7.3 | Configure Auto-Update Publishing | 🔴 Not Started | 4-6h | [TASK-7.3](./TASK-7.3-auto-update-config.md) |
| 7.4 | Linux Universal Distribution | 🔴 Not Started | 6-8h | [TASK-7.4](./TASK-7.4-linux-distribution.md) |
| 7.5 | GitHub Actions CI/CD | 🔴 Not Started | 12-16h | [TASK-7.5](./TASK-7.5-github-actions.md) |
| 7.6 | Windows Code Signing | 🔴 Not Started | 4-8h | _(optional, no doc yet)_ |
---
## Task Details
### 7.1 Rebrand to Nodegex
**Status:** 🔴 Not Started
Rename application from OpenNoodl to Nodegex across all user-facing surfaces:
- Package.json productName, appId, protocols
- Window titles and UI strings
- Protocol handlers (`nodegex://`)
- userData paths with migration for existing users
### 7.2 Fix macOS Code Signing
**Status:** 🔴 Not Started
Configure electron-builder for automatic signing (eliminates 30+ manual file signatures):
- Certificate configuration via `CSC_NAME`
- Entitlements for hardened runtime
- Automatic notarization via afterSign hook
- Support for both Intel and Apple Silicon
### 7.3 Configure Auto-Update Publishing
**Status:** 🔴 Not Started
Connect existing electron-updater infrastructure to GitHub Releases:
- Add publish configuration to package.json
- Configure update server URL
- Generate `latest-*.yml` manifests
- Test update detection and installation
### 7.4 Linux Universal Distribution
**Status:** 🔴 Not Started
Add AppImage and .deb targets:
- AppImage for universal distribution (auto-update supported)
- .deb for Debian/Ubuntu native experience
- Handle native module compatibility (dugite, desktop-trampoline)
- Test on Ubuntu 22.04/24.04 LTS
### 7.5 GitHub Actions CI/CD
**Status:** 🔴 Not Started
Create automated build pipeline:
- Matrix build for macOS (x64, arm64), Windows (x64), Linux (x64)
- Secure certificate storage via GitHub Secrets
- Automatic GitHub Release creation on tag push
- Update manifest generation
### 7.6 Windows Code Signing (Optional)
**Status:** 🔴 Not Started
Add Windows code signing to eliminate SmartScreen warnings:
- Obtain code signing certificate (EV or standard)
- Configure in electron-builder
- Add to CI/CD pipeline
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
---
## Recent Updates
| Date | Update |
| ---------- | ------------------------------------------------- |
| 2026-01-07 | Updated PROGRESS.md to reflect actual task status |
| 2026-01-07 | Renumbered from Phase 7 to Phase 8 |
---
## Dependencies
**Depends on:** Phase 0-3 (stable editor)
**Task Dependencies:**
```
7.1 Rebrand ──┬──► 7.2 macOS Signing ──┐
├──► 7.3 Auto-Update ────┼──► 7.5 GitHub Actions CI/CD
└──► 7.4 Linux Distro ───┘
7.6 Windows Signing (optional)
```
---
## Success Criteria
1. ✅ User can receive update notification without losing projects
2. ✅ macOS build requires zero manual signing steps
3. ✅ Linux AppImage runs on Ubuntu 22.04+ without dependencies
4.`git tag v1.2.0 && git push --tags` triggers full release
5. ✅ All UI shows "Nodegex" branding
6. ✅ Existing OpenNoodl users' data migrates automatically
---
## Notes
Previously Phase 7 "auto-update-and-distribution". Covers macOS code signing, Windows signing, auto-update infrastructure, Linux distribution, and GitHub Actions CI/CD.
See [README.md](./README.md) for comprehensive technical analysis and architecture decisions.

View File

@@ -1,8 +1,8 @@
# Phase 7: Auto-Update & Cross-Platform Deployment Infrastructure
# Phase 8: Auto-Update & Cross-Platform Deployment Infrastructure
## Executive Summary
Phase 7 transforms Nodegex from a manually-distributed application requiring full reinstalls into a professionally deployed desktop application with seamless auto-updates across Windows, macOS (Intel & Apple Silicon), and Linux.
Phase 8 transforms Nodegex from a manually-distributed application requiring full reinstalls into a professionally deployed desktop application with seamless auto-updates across Windows, macOS (Intel & Apple Silicon), and Linux.
**Current Pain Points:**
- Manual code signing of 30+ files for each macOS build

View File

@@ -0,0 +1,116 @@
# Phase 9: Styles Overhaul - Progress Tracker
**Last Updated:** 2026-01-07
**Overall Status:** 🟡 In Progress
---
## Quick Summary
| Metric | Value |
| ----------------- | ----------- |
| Total Major Tasks | 7 |
| Completed | 0 |
| In Progress | 1 (CLEANUP) |
| Not Started | 6 |
| **Progress** | **~15%** |
> **Note:** Significant foundational work completed in CLEANUP-SUBTASKS (000A-000G).
> Major feature tasks (STYLE-001 to STYLE-005, WIZARD-001) remain not started.
---
## Task Status
### Major Feature Tasks
| Task | Name | Status | Notes |
| ---------- | ------------------------ | -------------- | ----------------------------- |
| STYLE-001 | Token System Enhancement | 🔴 Not Started | Design tokens system |
| STYLE-002 | Element Configs/Variants | 🔴 Not Started | Component styling system |
| STYLE-003 | Style Presets System | 🔴 Not Started | Pre-built style presets |
| STYLE-004 | Property Panel UX | 🔴 Not Started | Improved styling UX |
| STYLE-005 | Smart Style Suggestions | 🔴 Not Started | AI-assisted suggestions |
| WIZARD-001 | Project Creation Wizard | 🔴 Not Started | Guided project setup |
| CLEANUP-\* | Legacy Color Cleanup | 🟡 In Progress | 7/8 subtasks complete (87.5%) |
---
## CLEANUP-SUBTASKS Detail
Foundation work to remove hardcoded colors and establish token infrastructure.
| Subtask | Name | Status | Completed |
| --------- | ----------------------------- | -------------- | ---------- |
| TASK-000A | Token Consolidation | 🟢 Complete | 2025-12-30 |
| TASK-000B | Hardcoded Colors - Legacy | 🟢 Complete | 2025-12-30 |
| TASK-000C | Hardcoded Colors - Node Graph | 🟢 Complete | 2025-12-30 |
| TASK-000D | Hardcoded Colors - Core UI | 🟢 Complete | 2025-12-30 |
| TASK-000E | Typography & Spacing Tokens | 🟢 Complete | 2025-12-30 |
| TASK-000F | Component Updates - Buttons | 🟢 Complete | 2025-12-31 |
| TASK-000G | Component Updates - Dialogs | 🟢 Complete | 2025-12-31 |
| TASK-000H | Migration Wizard Polish | 🔴 Not Started | - |
**CLEANUP Progress:** 7/8 complete (87.5%)
### Completed Work Summary:
- **000A:** Synced RED-MINIMAL color palette across editor and core-ui packages
- **000B:** Replaced 398 hardcoded colors in 14 legacy style files
- **000C:** Replaced 28 hardcoded colors in node graph editor views
- **000D:** Replaced 9 hardcoded colors in core UI components
- **000E:** Added ~85 typography and spacing design tokens
- **000F:** Visual polish for PrimaryButton and TextInput components
- **000G:** Visual polish for BaseDialog, Modal, BasePanel, Section, Tooltip
---
## Status Legend
- 🔴 **Not Started** - Work has not begun
- 🟡 **In Progress** - Actively being worked on
- 🟢 **Complete** - Finished and verified
---
## Recent Updates
| Date | Update |
| ---------- | -------------------------------------------------------------- |
| 2026-01-07 | Audit: Updated PROGRESS.md to reflect actual completion status |
| 2025-12-31 | Completed TASK-000F (Buttons) and TASK-000G (Dialogs/Panels) |
| 2025-12-30 | Completed TASK-000A through TASK-000E (Token/Color foundation) |
| 2026-01-07 | Merged Phase 8 + Phase 3 TASK-000 into new Phase 9 |
---
## Dependencies
Depends on: Phase 3 (Editor UX)
---
## Notes
This phase merges:
- Old Phase 8 "styles-overhaul" (STYLE-001 to STYLE-005, WIZARD-001)
- Phase 3 TASK-000 cleanup subtasks (in CLEANUP-SUBTASKS/ folder)
### What's Done:
The foundational cleanup work (000A-000G) has established:
- Unified RED-MINIMAL color palette
- ~500+ hardcoded colors replaced with CSS variables
- Typography and spacing token system
- Modern visual polish on core UI components
### What's Remaining:
- **TASK-000H:** Final polish on Migration Wizard
- **STYLE-001 to STYLE-005:** Major feature work (enhanced token system, element configs, presets, property panel UX, AI suggestions)
- **WIZARD-001:** Project creation wizard
See CLEANUP-SUBTASKS/ folder for detailed changelogs of completed work.
See STYLE-\* folders for README specs of upcoming feature work.

View File

@@ -1,8 +1,8 @@
# Phase 8: Styles Overhaul
# Phase 9: Styles Overhaul
## Overview
Phase 8 transforms Noodl's styling experience from "start with nothing, figure it out yourself" to "sensible defaults that scale with your needs." This phase builds on Noodl's existing style tokens and variant systems, enhancing them into a cohesive design system that works for beginners and power users alike.
Phase 9 transforms Noodl's styling experience from "start with nothing, figure it out yourself" to "sensible defaults that scale with your needs." This phase builds on Noodl's existing style tokens and variant systems, enhancing them into a cohesive design system that works for beginners and power users alike.
**Philosophy**: Make the happy path so good that manual styling feels unnecessary, while preserving complete freedom for those who need it.
@@ -153,7 +153,7 @@ All three levels coexist. Nothing is blocked. The UX guides users toward systema
1. **Migration**: How do we handle existing projects? Opt-in to new system, or automatic detection/upgrade?
2. **Custom Presets**: Should users be able to save/share their own presets?
3. **Dark Mode**: Built into presets (each preset has light/dark), or separate toggle?
4. **Component Library**: Does Phase 8 create the foundation for a future Noodl prefab library?
4. **Component Library**: Does Phase 9 create the foundation for a future Noodl prefab library?
---

Some files were not shown because too many files have changed in this diff Show More