mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-01-11 14:52:55 +01:00
1557 lines
39 KiB
Plaintext
1557 lines
39 KiB
Plaintext
# Cline Development Guidelines for OpenNoodl
|
|
|
|
## Overview
|
|
|
|
This document provides guidelines for AI-assisted development on the OpenNoodl codebase using Cline in VSCode. Follow these guidelines to ensure consistent, well-documented, and testable contributions.
|
|
|
|
**🚨 CRITICAL: OpenNoodl Editor is an Electron Desktop Application**
|
|
|
|
- The editor is NOT a web app - never try to open it in a browser
|
|
- Running `npm run dev` launches the Electron app automatically
|
|
- Use Electron DevTools (View → Toggle Developer Tools) for debugging
|
|
- The viewer/runtime creates web apps, but the editor itself is always Electron
|
|
- Never use `browser_action` tool to test the editor - it only works for Storybook or deployed viewers
|
|
|
|
---
|
|
|
|
## 1. Before Starting Any Task
|
|
|
|
### 1.1 Understand the Context
|
|
|
|
```bash
|
|
# Always check which branch you're on
|
|
git branch
|
|
|
|
# Check for uncommitted changes
|
|
git status
|
|
|
|
# Review recent commits
|
|
git log --oneline -10
|
|
```
|
|
|
|
### 1.2 Read Relevant Documentation
|
|
|
|
Before modifying any file, understand its purpose:
|
|
|
|
1. Check for README files in the package
|
|
2. Read JSDoc comments on functions
|
|
3. Look for related test files
|
|
4. Search for usage patterns: `grep -r "functionName" packages/`
|
|
|
|
### 1.3 Identify Dependencies
|
|
|
|
```bash
|
|
# Check what imports a file
|
|
grep -r "from.*filename" packages/
|
|
|
|
# Check what the file imports
|
|
head -50 path/to/file.ts | grep "import"
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Code Style Requirements
|
|
|
|
### 2.1 TypeScript Standards
|
|
|
|
```typescript
|
|
// ✅ GOOD: Explicit types
|
|
interface NodeProps {
|
|
id: string;
|
|
type: NodeType;
|
|
connections: Connection[];
|
|
}
|
|
|
|
function processNode(node: NodeProps): ProcessedNode {
|
|
// ...
|
|
}
|
|
|
|
// ❌ BAD: Implicit any
|
|
function processNode(node) {
|
|
// ...
|
|
}
|
|
|
|
// ❌ BAD: Using TSFixme
|
|
function processNode(node: TSFixme): TSFixme {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
### 2.2 React Component Standards
|
|
|
|
```tsx
|
|
// ✅ GOOD: Functional component with types
|
|
interface ButtonProps {
|
|
label: string;
|
|
onClick: () => void;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
export function Button({ label, onClick, disabled = false }: ButtonProps) {
|
|
return (
|
|
<button onClick={onClick} disabled={disabled}>
|
|
{label}
|
|
</button>
|
|
);
|
|
}
|
|
|
|
// ❌ BAD: Class component (unless necessary for lifecycle)
|
|
class Button extends React.Component {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
### 2.3 Import Organization
|
|
|
|
```typescript
|
|
// 1. External packages (alphabetical)
|
|
import classNames from 'classnames';
|
|
import React, { useCallback, useState } from 'react';
|
|
|
|
import { NodeGraphModel } from '@noodl-models/nodegraphmodel';
|
|
import { KeyCode } from '@noodl-utils/keyboard/KeyCode';
|
|
|
|
// 2. Internal packages (alphabetical by alias)
|
|
import { IconName } from '@noodl-core-ui/components/common/Icon';
|
|
|
|
import css from './Component.module.scss';
|
|
// 3. Relative imports (by depth, then alphabetical)
|
|
import { localHelper } from './helpers';
|
|
```
|
|
|
|
### 2.4 Naming Conventions
|
|
|
|
| Type | Convention | Example |
|
|
| ----------- | --------------------- | ------------------------- |
|
|
| Components | PascalCase | `NodeEditor.tsx` |
|
|
| Hooks | camelCase, use prefix | `useNodeSelection.ts` |
|
|
| Utils | camelCase | `formatNodeName.ts` |
|
|
| Constants | UPPER_SNAKE | `MAX_CONNECTIONS` |
|
|
| CSS Modules | kebab-case | `node-editor.module.scss` |
|
|
| Test files | Same + .test | `NodeEditor.test.tsx` |
|
|
|
|
---
|
|
|
|
## 3. Documentation Requirements
|
|
|
|
### 3.1 File Headers
|
|
|
|
Every new file should have a header comment:
|
|
|
|
```typescript
|
|
/**
|
|
* NodeProcessor
|
|
*
|
|
* Handles the processing of node graph updates and manages
|
|
* the execution order of connected nodes.
|
|
*
|
|
* @module noodl-runtime
|
|
* @since 1.2.0
|
|
*/
|
|
```
|
|
|
|
### 3.2 Function Documentation
|
|
|
|
````typescript
|
|
/**
|
|
* Processes a node and propagates changes to connected nodes.
|
|
*
|
|
* @param node - The node to process
|
|
* @param context - The execution context
|
|
* @param options - Processing options
|
|
* @param options.force - Force re-evaluation even if inputs unchanged
|
|
* @returns The processed output values
|
|
* @throws {NodeProcessingError} If the node definition is invalid
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* const output = processNode(myNode, context, { force: true });
|
|
* console.log(output.value);
|
|
* ```
|
|
*/
|
|
function processNode(node: NodeInstance, context: ExecutionContext, options: ProcessOptions = {}): NodeOutput {
|
|
// ...
|
|
}
|
|
````
|
|
|
|
### 3.3 Complex Logic Comments
|
|
|
|
```typescript
|
|
// Calculate the topological sort order for node evaluation.
|
|
// This ensures nodes are processed after their dependencies.
|
|
// Uses Kahn's algorithm for O(V+E) complexity.
|
|
const sortedNodes = topologicalSort(nodes, connections);
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Testing Requirements
|
|
|
|
### 4.1 Test File Location
|
|
|
|
Tests should be co-located or in a parallel `tests/` directory:
|
|
|
|
```
|
|
// Option A: Co-located
|
|
components/
|
|
├── Button/
|
|
│ ├── Button.tsx
|
|
│ ├── Button.test.tsx
|
|
│ └── Button.module.scss
|
|
|
|
// Option B: Parallel (current pattern in noodl-editor)
|
|
packages/noodl-editor/
|
|
├── src/
|
|
│ └── components/Button.tsx
|
|
└── tests/
|
|
└── components/Button.test.ts
|
|
```
|
|
|
|
### 4.2 Test Structure
|
|
|
|
```typescript
|
|
import { describe, it, expect, beforeEach, jest } from '@jest/globals';
|
|
import { renderHook, act } from '@testing-library/react-hooks';
|
|
|
|
describe('useNodeSelection', () => {
|
|
// Setup
|
|
let mockContext: NodeGraphContext;
|
|
|
|
beforeEach(() => {
|
|
mockContext = createMockContext();
|
|
});
|
|
|
|
// Group related tests
|
|
describe('when selecting a single node', () => {
|
|
it('should update selection state', () => {
|
|
const { result } = renderHook(() => useNodeSelection(mockContext));
|
|
|
|
act(() => {
|
|
result.current.selectNode('node-1');
|
|
});
|
|
|
|
expect(result.current.selectedNodes).toContain('node-1');
|
|
});
|
|
|
|
it('should clear previous selection by default', () => {
|
|
// ...
|
|
});
|
|
});
|
|
|
|
describe('when multi-selecting nodes', () => {
|
|
// ...
|
|
});
|
|
});
|
|
```
|
|
|
|
### 4.3 What to Test
|
|
|
|
| Priority | What to Test |
|
|
| -------- | ---------------------- |
|
|
| High | Utility functions |
|
|
| High | Data transformations |
|
|
| High | State management logic |
|
|
| Medium | React hooks |
|
|
| Medium | Component behavior |
|
|
| Low | Pure UI rendering |
|
|
|
|
---
|
|
|
|
## 5. Git Workflow
|
|
|
|
### 5.1 Branch Naming
|
|
|
|
```bash
|
|
# Features
|
|
git checkout -b feature/add-vercel-deployment
|
|
|
|
# Bug fixes
|
|
git checkout -b fix/page-router-scroll
|
|
|
|
# Refactoring
|
|
git checkout -b refactor/remove-tsfixme-panels
|
|
|
|
# Documentation
|
|
git checkout -b docs/update-node-api
|
|
```
|
|
|
|
### 5.2 Commit Messages
|
|
|
|
Follow conventional commits:
|
|
|
|
```bash
|
|
# Format: type(scope): description
|
|
|
|
# Features
|
|
git commit -m "feat(editor): add breakpoint support for node connections"
|
|
|
|
# Bug fixes
|
|
git commit -m "fix(viewer): resolve scroll position reset in nested Page Router"
|
|
|
|
# Refactoring
|
|
git commit -m "refactor(runtime): replace TSFixme with proper types in node processor"
|
|
|
|
# Documentation
|
|
git commit -m "docs(api): add JSDoc to all public node methods"
|
|
|
|
# Tests
|
|
git commit -m "test(editor): add unit tests for node selection hook"
|
|
|
|
# Chores
|
|
git commit -m "chore(deps): update react to 19.0.0"
|
|
```
|
|
|
|
### 5.3 Commit Frequency
|
|
|
|
- Commit after each logical change
|
|
- Don't combine unrelated changes
|
|
- Commit working states (tests should pass)
|
|
|
|
---
|
|
|
|
## 6. Codebase Navigation
|
|
|
|
### 6.1 Key Directories
|
|
|
|
```
|
|
packages/
|
|
├── noodl-editor/
|
|
│ ├── src/
|
|
│ │ ├── editor/src/
|
|
│ │ │ ├── models/ # Data models (ProjectModel, NodeGraph, etc.)
|
|
│ │ │ ├── views/ # UI components and views
|
|
│ │ │ ├── utils/ # Helper utilities
|
|
│ │ │ ├── store/ # State stores (AI Assistant, etc.)
|
|
│ │ │ └── pages/ # Page-level components
|
|
│ │ ├── main/ # Electron main process
|
|
│ │ └── shared/ # Shared utilities
|
|
│ └── tests/ # Test files
|
|
│
|
|
├── noodl-runtime/
|
|
│ └── src/
|
|
│ ├── nodes/ # Runtime node definitions
|
|
│ └── nodecontext.js # Execution context
|
|
│
|
|
├── noodl-viewer-react/
|
|
│ └── src/
|
|
│ └── nodes/ # React-based visual nodes
|
|
│
|
|
└── noodl-core-ui/
|
|
└── src/
|
|
└── components/ # Shared UI components
|
|
```
|
|
|
|
### 6.2 Finding Things
|
|
|
|
```bash
|
|
# Find a component
|
|
find packages/ -name "*NodeEditor*" -type f
|
|
|
|
# Find where something is imported
|
|
grep -r "import.*from.*NodeEditor" packages/
|
|
|
|
# Find where a function is called
|
|
grep -r "processNode(" packages/ --include="*.ts" --include="*.tsx"
|
|
|
|
# Find all TODO comments
|
|
grep -rn "TODO\|FIXME" packages/noodl-editor/src
|
|
|
|
# Find test files
|
|
find packages/ -name "*.test.ts" -o -name "*.spec.ts"
|
|
```
|
|
|
|
### 6.3 Understanding Data Flow
|
|
|
|
1. **User Action** → `views/` components capture events
|
|
2. **State Update** → `models/` handle business logic
|
|
3. **Runtime Sync** → `ViewerConnection` sends to preview
|
|
4. **Persistence** → `ProjectModel` saves to disk
|
|
|
|
---
|
|
|
|
## 7. Common Patterns
|
|
|
|
### 7.1 Event Handling Pattern
|
|
|
|
```typescript
|
|
// Models use EventDispatcher for pub/sub
|
|
import { EventDispatcher } from '../../../shared/utils/EventDispatcher';
|
|
|
|
class MyModel extends EventDispatcher {
|
|
doSomething() {
|
|
// ... logic
|
|
this.notifyListeners('updated', { data: result });
|
|
}
|
|
}
|
|
|
|
// Usage
|
|
const model = new MyModel();
|
|
model.on('updated', (data) => {
|
|
console.log('Model updated:', data);
|
|
});
|
|
```
|
|
|
|
### 7.2 React Hook Pattern
|
|
|
|
```typescript
|
|
// Custom hook for model subscription
|
|
function useModel<T>(model: EventDispatcher, event: string): T {
|
|
const [state, setState] = useState<T>(model.getState());
|
|
|
|
useEffect(() => {
|
|
const handler = (newState: T) => setState(newState);
|
|
model.on(event, handler);
|
|
return () => model.off(event, handler);
|
|
}, [model, event]);
|
|
|
|
return state;
|
|
}
|
|
```
|
|
|
|
### 7.3 Node Definition Pattern
|
|
|
|
```javascript
|
|
// In noodl-runtime/src/nodes/
|
|
const MyNode = {
|
|
name: 'My.Custom.Node',
|
|
displayName: 'My Custom Node',
|
|
category: 'Custom',
|
|
|
|
inputs: {
|
|
inputValue: {
|
|
type: 'string',
|
|
displayName: 'Input Value',
|
|
default: ''
|
|
}
|
|
},
|
|
|
|
outputs: {
|
|
outputValue: {
|
|
type: 'string',
|
|
displayName: 'Output Value'
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
setInputValue(value) {
|
|
this._internal.inputValue = value;
|
|
this.flagOutputDirty('outputValue');
|
|
}
|
|
},
|
|
|
|
getOutputValue(name) {
|
|
if (name === 'outputValue') {
|
|
return this._internal.inputValue.toUpperCase();
|
|
}
|
|
}
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Error Handling
|
|
|
|
### 8.1 User-Facing Errors
|
|
|
|
```typescript
|
|
import { ToastLayer } from '../views/ToastLayer/ToastLayer';
|
|
|
|
try {
|
|
await riskyOperation();
|
|
} catch (error) {
|
|
// Log for debugging
|
|
console.error('Operation failed:', error);
|
|
|
|
// Show user-friendly message
|
|
ToastLayer.showError('Unable to complete operation. Please try again.');
|
|
}
|
|
```
|
|
|
|
### 8.2 Developer Errors
|
|
|
|
```typescript
|
|
// Use assertions for developer errors
|
|
function processNode(node: NodeInstance) {
|
|
if (!node.id) {
|
|
throw new Error(`processNode: node.id is required`);
|
|
}
|
|
|
|
if (!node.definition) {
|
|
throw new Error(`processNode: node "${node.id}" has no definition`);
|
|
}
|
|
}
|
|
```
|
|
|
|
### 8.3 Graceful Degradation
|
|
|
|
```typescript
|
|
function getNodeIcon(node: NodeInstance): string {
|
|
try {
|
|
return node.definition.icon || 'default-icon';
|
|
} catch {
|
|
console.warn(`Could not get icon for node ${node.id}`);
|
|
return 'default-icon';
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Performance Considerations
|
|
|
|
### 9.1 Avoid Unnecessary Re-renders
|
|
|
|
```tsx
|
|
// ✅ GOOD: Memoized callback
|
|
const handleClick = useCallback(() => {
|
|
onNodeSelect(node.id);
|
|
}, [node.id, onNodeSelect]);
|
|
|
|
// ✅ GOOD: Memoized expensive computation
|
|
const sortedNodes = useMemo(() => {
|
|
return topologicalSort(nodes);
|
|
}, [nodes]);
|
|
|
|
// ❌ BAD: New function on every render
|
|
<Button onClick={() => onNodeSelect(node.id)} />;
|
|
```
|
|
|
|
### 9.2 Lazy Loading
|
|
|
|
```tsx
|
|
// Lazy load heavy components
|
|
const CodeEditor = React.lazy(() => import('./CodeEditor'));
|
|
|
|
function EditorPanel() {
|
|
return (
|
|
<Suspense fallback={<LoadingSpinner />}>
|
|
<CodeEditor />
|
|
</Suspense>
|
|
);
|
|
}
|
|
```
|
|
|
|
### 9.3 Batch Updates
|
|
|
|
```typescript
|
|
// Batch multiple state updates
|
|
import { unstable_batchedUpdates } from 'react-dom';
|
|
|
|
unstable_batchedUpdates(() => {
|
|
setSelection(newSelection);
|
|
setHighlight(newHighlight);
|
|
setZoom(newZoom);
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Checklist Before Submitting
|
|
|
|
### Code Quality
|
|
|
|
- [ ] No `TSFixme` types added
|
|
- [ ] All new functions have JSDoc comments
|
|
- [ ] Complex logic has inline comments
|
|
- [ ] No console.log statements (except errors/warnings)
|
|
- [ ] No unused imports or variables
|
|
|
|
### Testing
|
|
|
|
- [ ] Unit tests for new utility functions
|
|
- [ ] Integration tests for new features
|
|
- [ ] Existing tests still pass
|
|
- [ ] Manual testing completed
|
|
|
|
### Documentation
|
|
|
|
- [ ] README updated if needed
|
|
- [ ] JSDoc added to public APIs
|
|
- [ ] Comments explain "why", not "what"
|
|
|
|
### Git
|
|
|
|
- [ ] Meaningful commit messages
|
|
- [ ] No unrelated changes in commits
|
|
- [ ] Branch named correctly
|
|
- [ ] Based on latest main branch
|
|
|
|
### Performance
|
|
|
|
- [ ] No obvious performance regressions
|
|
- [ ] Large lists use virtualization
|
|
- [ ] Expensive computations are memoized
|
|
|
|
### React + EventDispatcher (Phase 0 Critical Bugs)
|
|
|
|
- [ ] Using `useEventListener` hook for ALL EventDispatcher subscriptions (NOT direct `.on()`)
|
|
- [ ] Singleton instances included in useEffect dependencies (e.g., `[ProjectModel.instance]`)
|
|
- [ ] Using `UndoQueue.instance.pushAndDo()` pattern (NOT `undoGroup.push()` + `undoGroup.do()`)
|
|
- [ ] No direct EventDispatcher `.on()` calls in React components
|
|
- [ ] Event subscriptions verified with debug logging
|
|
|
|
---
|
|
|
|
## Quick Reference Commands
|
|
|
|
```bash
|
|
# Development
|
|
npm run dev # Start editor with hot reload
|
|
npm run test:editor # Run tests
|
|
npm run build:editor # Production build
|
|
|
|
# Code Quality
|
|
npx eslint packages/noodl-editor/src --fix
|
|
npx prettier --write "packages/**/*.{ts,tsx}"
|
|
npx tsc --noEmit # Type check
|
|
|
|
# Debugging
|
|
DEBUG=* npm run dev # Verbose logging
|
|
npm run test:editor -- --verbose
|
|
|
|
# Finding Issues
|
|
grep -r "TSFixme" packages/ # Find type escapes
|
|
grep -r "any" packages/ --include="*.ts" | head -20
|
|
```
|
|
|
|
## 11. Additional system instructions and critical development files
|
|
|
|
dev-docs/
|
|
├── reference/
|
|
│ ├── CODEBASE-MAP.md # OpenNoodl Codebase Quick Navigation
|
|
│ ├── COMMON-ISSUES.md # Solutions to frequently encountered problems when developing OpenNoodl.
|
|
│ ├── NODE-PATTERNS.md # How to create and modify nodes in OpenNoodl.
|
|
├── guidelines/
|
|
│ ├── CODING-STANDARDS.md # This document defines the coding style and patterns for OpenNoodl development.
|
|
│ ├── GIT-WORKFLOW.md # How to manage branches, commits, and pull requests for OpenNoodl development.
|
|
├── TASK-TEMPLATE.md # Use this template to create new task documentation. Copy the entire `TASK-XXX-template/` folder and rename it.
|
|
|
|
## 12. Institutional Learning
|
|
|
|
### Discovering & Recording Knowledge
|
|
|
|
As you work through tasks in this large codebase, you WILL discover things that aren't documented:
|
|
|
|
- Why something was built a certain way
|
|
- Hidden gotchas or edge cases
|
|
- Patterns that aren't obvious
|
|
- Fixes for confusing errors
|
|
- Relationships between distant parts of the code
|
|
|
|
**When you learn something useful, write it down immediately.**
|
|
|
|
Add discoveries to: `dev-docs/reference/LEARNINGS.md`
|
|
|
|
Format each entry:
|
|
|
|
```
|
|
### [Date] - [Brief Title]
|
|
|
|
**Context**: What were you trying to do?
|
|
**Discovery**: What did you learn?
|
|
**Location**: What files/areas does this apply to?
|
|
**Keywords**: [searchable terms]
|
|
```
|
|
|
|
Examples of things worth recording:
|
|
|
|
- "The `scheduleAfterInputsHaveUpdated` pattern is required when multiple inputs might change in the same frame"
|
|
- "RouterAdapter.ts secretly depends on component naming conventions - pages must be in folders"
|
|
- "React 19 automatic batching breaks the old `forceUpdate` pattern in nodegrapheditor"
|
|
- "Collection change events don't fire if you mutate items directly - must use `.set()`"
|
|
|
|
### Using Accumulated Knowledge
|
|
|
|
**Before struggling with something complex, check the learnings:**
|
|
|
|
1. Read `dev-docs/reference/LEARNINGS.md`
|
|
2. Search for relevant keywords
|
|
3. Check if someone already solved this problem
|
|
|
|
**When hitting a confusing error:**
|
|
|
|
1. Search LEARNINGS.md for the error message or related terms
|
|
2. Check `dev-docs/reference/COMMON-ISSUES.md`
|
|
3. If you solve it and it's not documented, ADD IT
|
|
|
|
### What Makes Good Learnings
|
|
|
|
✅ **Worth recording:**
|
|
|
|
- Non-obvious behavior ("X only works if Y is true")
|
|
- Error solutions that took time to figure out
|
|
- Undocumented dependencies between systems
|
|
- Performance gotchas
|
|
- Patterns you had to reverse-engineer
|
|
|
|
❌ **Not worth recording:**
|
|
|
|
- Basic TypeScript/React knowledge
|
|
- Things already in official docs
|
|
- One-off typos or simple mistakes
|
|
- Task-specific details (those go in task CHANGELOG)
|
|
|
|
### Building the Knowledge Base
|
|
|
|
Over time, LEARNINGS.md may grow large. When it does:
|
|
|
|
- Group related entries under headings
|
|
- Move mature topics to dedicated docs (e.g., `LEARNINGS.md` entry about data nodes → `DATA-SYSTEM-DEEP-DIVE.md`)
|
|
- Cross-reference from COMMON-ISSUES.md
|
|
|
|
The goal: **No one should have to solve the same puzzle twice.**
|
|
|
|
---
|
|
|
|
---
|
|
|
|
## 13. UI Styling Rules
|
|
|
|
> **CRITICAL:** Before any UI/CSS work, read `dev-docs/reference/UI-STYLING-GUIDE.md`
|
|
|
|
### 13.1 Never Use Hardcoded Colors
|
|
|
|
```scss
|
|
// ❌ BAD - copying legacy patterns
|
|
.Card {
|
|
background-color: #27272a;
|
|
color: #b8b8b8;
|
|
}
|
|
|
|
// ✅ GOOD - using design tokens
|
|
.Card {
|
|
background-color: var(--theme-color-bg-3);
|
|
color: var(--theme-color-fg-default);
|
|
}
|
|
```
|
|
|
|
### 13.2 Quick Token Reference
|
|
|
|
| Purpose | Token |
|
|
| ----------------- | ------------------------------ |
|
|
| Panel backgrounds | `--theme-color-bg-2` |
|
|
| Card backgrounds | `--theme-color-bg-3` |
|
|
| Normal text | `--theme-color-fg-default` |
|
|
| Secondary text | `--theme-color-fg-default-shy` |
|
|
| Emphasized text | `--theme-color-fg-highlight` |
|
|
| Primary buttons | `--theme-color-primary` |
|
|
| Borders | `--theme-color-border-default` |
|
|
|
|
### 13.3 Legacy Files Warning
|
|
|
|
DO NOT copy patterns from these files (they have hardcoded colors):
|
|
|
|
- `packages/noodl-editor/src/editor/src/styles/popuplayer.css`
|
|
- `packages/noodl-editor/src/editor/src/styles/propertyeditor.css`
|
|
|
|
DO reference these files (they use proper patterns):
|
|
|
|
- `packages/noodl-core-ui/src/components/layout/BaseDialog/`
|
|
- `packages/noodl-core-ui/src/components/inputs/PrimaryButton/`
|
|
|
|
### 13.4 Before Completing UI Tasks
|
|
|
|
Verify:
|
|
|
|
- [ ] No hardcoded hex colors (`grep -E '#[0-9a-fA-F]{3,6}' your-file.scss`)
|
|
- [ ] All colors use `var(--theme-color-*)` tokens
|
|
- [ ] Hover/focus/disabled states defined
|
|
|
|
---
|
|
|
|
## Section: React + EventDispatcher Integration
|
|
|
|
````markdown
|
|
## React + EventDispatcher Integration
|
|
|
|
### CRITICAL: Always use useEventListener hook
|
|
|
|
When subscribing to EventDispatcher events from React components, ALWAYS use the `useEventListener` hook. Direct subscriptions silently fail.
|
|
|
|
**Hook location:** `@noodl-hooks/useEventListener`
|
|
|
|
**✅ CORRECT - Always do this:**
|
|
|
|
```typescript
|
|
import { useEventListener } from '@noodl-hooks/useEventListener';
|
|
|
|
import { ProjectModel } from '@noodl-models/projectmodel';
|
|
|
|
function MyComponent() {
|
|
useEventListener(ProjectModel.instance, 'componentRenamed', (data) => {
|
|
// This works!
|
|
});
|
|
}
|
|
```
|
|
````
|
|
|
|
**❌ BROKEN - Never do this:**
|
|
|
|
```typescript
|
|
// This compiles and runs without errors, but events are NEVER received
|
|
useEffect(() => {
|
|
const context = {};
|
|
ProjectModel.instance.on('event', handler, context);
|
|
return () => ProjectModel.instance.off(context);
|
|
}, []);
|
|
```
|
|
|
|
### Why this matters
|
|
|
|
EventDispatcher uses a context-object cleanup pattern incompatible with React closures. Direct subscriptions fail silently - no errors, no events, just confusion.
|
|
|
|
This pattern was established in Phase 0 after discovering the issue in TASK-004B.
|
|
|
|
### Available dispatchers
|
|
|
|
- `ProjectModel.instance` - component changes, settings
|
|
- `NodeLibrary.instance` - library/module changes
|
|
- `WarningsModel.instance` - validation warnings
|
|
- `EventDispatcher.instance` - global events
|
|
- `UndoQueue.instance` - undo/redo state
|
|
|
|
### Full documentation
|
|
|
|
See: `dev-docs/patterns/REACT-EVENTDISPATCHER.md`
|
|
|
|
````
|
|
|
|
---
|
|
|
|
## Section: Webpack Cache Issues
|
|
|
|
```markdown
|
|
## Webpack Cache Issues
|
|
|
|
### If code changes don't appear
|
|
|
|
When editing code and changes don't load in the running app:
|
|
|
|
1. **First, run `npm run clean:all`** - This nukes all caches
|
|
2. **Restart the dev server** - Don't just refresh
|
|
3. **Check for the build canary** - Console should show `🔥 BUILD TIMESTAMP: [recent time]`
|
|
|
|
If the canary shows an old timestamp, caching is still an issue. Check:
|
|
- Electron app cache (platform-specific location)
|
|
- Any lingering node/Electron processes (`pkill -f node; pkill -f Electron`)
|
|
- Browser cache (hard refresh with Cmd+Shift+R)
|
|
|
|
### Never debug without verifying fresh code
|
|
|
|
Before spending time debugging, ALWAYS verify your code changes are actually running:
|
|
|
|
1. Add a distinctive console.log: `console.log('🔥 MY CHANGE LOADED:', Date.now())`
|
|
2. Save the file
|
|
3. Check if the log appears
|
|
4. If not, clear caches and restart
|
|
|
|
This avoids wasting hours debugging stale code.
|
|
|
|
### Webpack config notes
|
|
|
|
- Dev mode should NOT use `cache: { type: 'filesystem' }`
|
|
- Memory cache or no cache is preferred for development
|
|
- Production can use filesystem cache for CI speed
|
|
````
|
|
|
|
---
|
|
|
|
## Section: Foundation Health
|
|
|
|
```markdown
|
|
## Foundation Health Check
|
|
|
|
### When to run
|
|
|
|
Run `npm run health:check` when:
|
|
|
|
- Starting work after a break
|
|
- After updating dependencies
|
|
- When things "feel broken"
|
|
- Before investigating mysterious bugs
|
|
|
|
### What it checks
|
|
|
|
1. Cache state (not stale/oversized)
|
|
2. Webpack config (correct cache settings)
|
|
3. useEventListener hook (present and exported)
|
|
4. Direct EventDispatcher subscriptions (anti-pattern detection)
|
|
5. Build canary (present in entry)
|
|
6. Package versions (no known problematic versions)
|
|
|
|
### Interpreting results
|
|
|
|
- ✅ Pass: All good
|
|
- ⚠️ Warning: Works but could be improved
|
|
- ❌ Fail: Must fix before proceeding
|
|
```
|
|
|
|
---
|
|
|
|
## Section: Debugging React Migrations
|
|
|
|
````markdown
|
|
## Debugging Legacy → React Migrations
|
|
|
|
### Common issue: UI doesn't update after action
|
|
|
|
If you perform an action (rename, add, delete) and the UI doesn't update:
|
|
|
|
1. **Check if the action succeeded** - Look in console for success logs
|
|
2. **Check if event was emitted** - Add logging to the model method
|
|
3. **Check if event was received** - Add logging in useEventListener callback
|
|
4. **Check if component re-rendered** - Add console.log in component body
|
|
|
|
Usually the problem is:
|
|
|
|
- ❌ Using direct `.on()` instead of `useEventListener`
|
|
- ❌ Cached old code running (run `npm run clean:all`)
|
|
- ❌ Event name mismatch (check exact spelling)
|
|
|
|
### Pattern for debugging event subscriptions
|
|
|
|
```typescript
|
|
useEventListener(ProjectModel.instance, 'componentRenamed', (data) => {
|
|
console.log('🔔 Event received:', data); // Add this temporarily
|
|
// Your actual handler
|
|
});
|
|
```
|
|
````
|
|
|
|
If you don't see the log, the subscription isn't working.
|
|
|
|
```
|
|
|
|
---
|
|
|
|
|
|
_Last Updated: December 2025_
|
|
```
|
|
|
|
---
|
|
|
|
## 14. Node Creation Checklist
|
|
|
|
> **🚨 CRITICAL:** Before creating or modifying runtime nodes, read `dev-docs/reference/LEARNINGS-NODE-CREATION.md`
|
|
|
|
Creating nodes in OpenNoodl is deceptively tricky. This checklist prevents the most common (and hardest to debug) issues.
|
|
|
|
### 14.1 Pre-Flight Checklist
|
|
|
|
Before writing any node code:
|
|
|
|
- [ ] Read `dev-docs/reference/LEARNINGS-NODE-CREATION.md` (especially the CRITICAL GOTCHAS section)
|
|
- [ ] Check `dev-docs/reference/LEARNINGS.md` for recent node-related discoveries (search for "node", "runtime", "coreNodes")
|
|
- [ ] Study an existing working node of similar complexity (e.g., `restnode.js` for data nodes)
|
|
- [ ] Understand the difference between `inputs` (static) vs `prototypeExtensions` (instance methods)
|
|
- [ ] Know where your node should be registered (noodl-runtime vs noodl-viewer-react)
|
|
|
|
### 14.2 Input Handler Rules
|
|
|
|
```javascript
|
|
// ✅ CORRECT: Signal inputs use valueChangedToTrue
|
|
inputs: {
|
|
fetch: {
|
|
type: 'signal',
|
|
valueChangedToTrue: function() {
|
|
this.scheduleFetch();
|
|
}
|
|
}
|
|
}
|
|
|
|
// ❌ WRONG: Signal inputs with set() - NEVER TRIGGERS
|
|
inputs: {
|
|
fetch: {
|
|
type: 'signal',
|
|
set: function(value) { // ☠️ Never called for signals
|
|
this.scheduleFetch();
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 14.3 Never Override setInputValue
|
|
|
|
```javascript
|
|
// ❌ BREAKS EVERYTHING - Never define setInputValue in prototypeExtensions
|
|
prototypeExtensions: {
|
|
setInputValue: function(name, value) { // ☠️ Overrides base - signals stop working
|
|
// ...
|
|
}
|
|
}
|
|
|
|
// ✅ Use a different name for custom storage
|
|
prototypeExtensions: {
|
|
_storeInputValue: function(name, value) { // ✅ Doesn't override anything
|
|
this._internal.inputValues[name] = value;
|
|
}
|
|
}
|
|
```
|
|
|
|
### 14.4 Dynamic Ports Must Include Static Ports
|
|
|
|
```javascript
|
|
// ❌ WRONG - Static ports disappear
|
|
function updatePorts(nodeId, parameters, editorConnection) {
|
|
const ports = [];
|
|
// Only adds dynamic ports...
|
|
editorConnection.sendDynamicPorts(nodeId, ports); // Static inputs gone!
|
|
}
|
|
|
|
// ✅ CORRECT - Include all ports
|
|
function updatePorts(nodeId, parameters, editorConnection) {
|
|
const ports = [
|
|
// Re-add static inputs
|
|
{ name: 'url', displayName: 'URL', type: 'string', plug: 'input', group: 'Request' },
|
|
{ name: 'fetch', displayName: 'Fetch', type: 'signal', plug: 'input', group: 'Actions' },
|
|
// Then add dynamic ports...
|
|
];
|
|
editorConnection.sendDynamicPorts(nodeId, ports);
|
|
}
|
|
```
|
|
|
|
### 14.5 Register Config Inputs Explicitly
|
|
|
|
```javascript
|
|
// Config inputs (from stringlist editors) need explicit registration
|
|
registerInputIfNeeded: function(name) {
|
|
if (this.hasInput(name)) return;
|
|
|
|
// Map config names to their setters
|
|
const configSetters = {
|
|
'method': this.setMethod.bind(this),
|
|
'headers': this.setHeaders.bind(this),
|
|
'queryParams': this.setQueryParams.bind(this)
|
|
};
|
|
|
|
if (configSetters[name]) {
|
|
return this.registerInput(name, { set: configSetters[name] });
|
|
}
|
|
|
|
// Handle prefixed dynamic inputs
|
|
if (name.startsWith('header-')) {
|
|
return this.registerInput(name, {
|
|
set: this._storeInputValue.bind(this, name)
|
|
});
|
|
}
|
|
}
|
|
```
|
|
|
|
### 14.6 Export Format Matters
|
|
|
|
```javascript
|
|
// ✅ CORRECT: Export with setup function
|
|
module.exports = {
|
|
node: MyNode,
|
|
setup: function (context, graphModel) {
|
|
// Port management goes here
|
|
}
|
|
};
|
|
|
|
// ❌ WRONG: Direct export (setup never runs)
|
|
module.exports = MyNode;
|
|
```
|
|
|
|
### 14.7 Post-Creation Verification
|
|
|
|
After creating a node:
|
|
|
|
1. **Check ports appear**: All static AND dynamic inputs/outputs visible in editor?
|
|
2. **Check signals work**: Add console.log in `valueChangedToTrue` - does it print?
|
|
3. **Check config inputs work**: Change dropdown/stringlist values - does setter get called?
|
|
4. **Clear caches if needed**: `npm run clean:all` and restart
|
|
|
|
### 14.8 Quick Reference
|
|
|
|
| Input Type | Handler | Callback Format |
|
|
| ---------------------------- | --------------------------- | --------------------------- |
|
|
| Signal | `valueChangedToTrue` | `function() { ... }` |
|
|
| Value (string, number, etc.) | `set` | `function(value) { ... }` |
|
|
| Enum (dropdown) | `set` | `function(value) { ... }` |
|
|
| StringList (config) | Needs explicit registration | Via `registerInputIfNeeded` |
|
|
|
|
### 14.9 Where to Find Examples
|
|
|
|
| Pattern | Example File |
|
|
| ------------------------------------ | ---------------------------------------------------------------- |
|
|
| Complex data node with dynamic ports | `noodl-runtime/src/nodes/std-library/data/restnode.js` |
|
|
| HTTP node (fixed, working) | `noodl-runtime/src/nodes/std-library/data/httpnode.js` |
|
|
| Simple value node | `noodl-runtime/src/nodes/std-library/variables/numbernode.js` |
|
|
| Signal-based node | `noodl-runtime/src/nodes/std-library/timer.js` (in viewer-react) |
|
|
|
|
---
|
|
|
|
---
|
|
|
|
## 15. Task Sizing & Context Management
|
|
|
|
### 15.1 Understanding Your Limits
|
|
|
|
You (Cline) are running on Claude API with hard limits:
|
|
|
|
- **Context window**: ~200K tokens (~150K words)
|
|
- **Output limit**: ~8K tokens per response
|
|
- **When you exceed these**: You get an API error and must retry
|
|
|
|
**CRITICAL**: If you hit an API error about context length or output limit, DO NOT retry the same approach. You must split the task.
|
|
|
|
### 15.2 Recognizing Tasks That Are Too Large
|
|
|
|
Before starting implementation, estimate task size:
|
|
|
|
#### Signs a task will exceed limits:
|
|
|
|
```
|
|
❌ TOO LARGE - Will hit API limits:
|
|
- Modifying 10+ files in one go
|
|
- Reading entire large files multiple times
|
|
- Converting 50+ Storybook stories
|
|
- Refactoring a whole subsystem at once
|
|
- Adding features across runtime + editor + viewer
|
|
|
|
✅ MANAGEABLE - Can complete in context:
|
|
- Modifying 1-3 related files
|
|
- Adding a single feature to one package
|
|
- Converting 5-10 Storybook stories
|
|
- Fixing a specific bug in one area
|
|
- Writing focused tests for one module
|
|
```
|
|
|
|
#### Quick size estimation:
|
|
|
|
| Task Scope | Estimated Files | Context Safety | Action |
|
|
| -------------- | --------------- | -------------- | ------------------------- |
|
|
| Bug fix | 1-3 files | ✅ Safe | Proceed |
|
|
| Small feature | 3-5 files | ✅ Safe | Proceed |
|
|
| Medium feature | 5-10 files | ⚠️ Monitor | Watch context carefully |
|
|
| Large feature | 10-20 files | ❌ Risky | Split into subtasks first |
|
|
| Refactoring | 20+ files | ❌ Too large | Must split |
|
|
|
|
### 15.3 When You Get an API Error
|
|
|
|
If you receive an error like:
|
|
|
|
- "Request too large"
|
|
- "Context length exceeded"
|
|
- "Maximum token limit exceeded"
|
|
- Any message about being over limits
|
|
|
|
**DO NOT** retry the same task at the same scope.
|
|
|
|
**IMMEDIATELY** follow this protocol:
|
|
|
|
```markdown
|
|
## Error Recovery Protocol
|
|
|
|
1. **Acknowledge the error**
|
|
"I've hit an API context limit. This task is too large to complete in one pass."
|
|
|
|
2. **Analyze what you were trying to do**
|
|
"I was attempting to [describe full scope]"
|
|
|
|
3. **Propose a split**
|
|
"I'll break this into smaller subtasks:
|
|
|
|
**Subtask 1**: [Specific scope - 2-4 files max]
|
|
|
|
- File A: [specific changes]
|
|
- File B: [specific changes]
|
|
|
|
**Subtask 2**: [Next logical chunk]
|
|
|
|
- File C: [specific changes]
|
|
- File D: [specific changes]
|
|
|
|
**Subtask 3**: [Remaining work]
|
|
|
|
- File E: [specific changes]
|
|
|
|
Each subtask is independently testable and won't exceed limits."
|
|
|
|
4. **Start with Subtask 1**
|
|
"Starting with Subtask 1 now..."
|
|
```
|
|
|
|
### 15.4 How to Split Tasks Intelligently
|
|
|
|
#### Strategy 1: By Package/Module
|
|
|
|
```markdown
|
|
# Original (too large):
|
|
|
|
"Implement responsive breakpoints across the platform"
|
|
|
|
# Split:
|
|
|
|
**Subtask 1**: Runtime changes (noodl-runtime)
|
|
|
|
- Add breakpoint evaluation to node context
|
|
- Update reactive system for breakpoint changes
|
|
|
|
**Subtask 2**: Editor changes (noodl-editor)
|
|
|
|
- Add breakpoint UI to property panel
|
|
- Implement breakpoint selector component
|
|
|
|
**Subtask 3**: Integration
|
|
|
|
- Connect editor to runtime
|
|
- Add tests for full flow
|
|
```
|
|
|
|
#### Strategy 2: By Feature Slice
|
|
|
|
```markdown
|
|
# Original (too large):
|
|
|
|
"Add cURL import with parsing, UI, validation, and error handling"
|
|
|
|
# Split:
|
|
|
|
**Subtask 1**: Core parsing logic
|
|
|
|
- Implement cURL parser utility
|
|
- Add unit tests for parser
|
|
- Handle basic HTTP methods
|
|
|
|
**Subtask 2**: UI integration
|
|
|
|
- Add import button to HTTP node config
|
|
- Create import modal/dialog
|
|
- Wire up parser to UI
|
|
|
|
**Subtask 3**: Advanced features
|
|
|
|
- Add validation and error states
|
|
- Handle complex cURL flags
|
|
- Add user feedback/toasts
|
|
```
|
|
|
|
#### Strategy 3: By File Groups
|
|
|
|
```markdown
|
|
# Original (too large):
|
|
|
|
"Migrate 50 Storybook stories to CSF3"
|
|
|
|
# Split:
|
|
|
|
**Subtask 1**: Button components (5 stories)
|
|
|
|
- PrimaryButton, SecondaryButton, IconButton, etc.
|
|
|
|
**Subtask 2**: Input components (6 stories)
|
|
|
|
- TextInput, NumberInput, Select, etc.
|
|
|
|
**Subtask 3**: Layout components (7 stories)
|
|
|
|
- Panel, Dialog, Popover, etc.
|
|
|
|
# Continue until complete
|
|
```
|
|
|
|
#### Strategy 4: By Logical Phases
|
|
|
|
```markdown
|
|
# Original (too large):
|
|
|
|
"Refactor EventDispatcher usage in panels"
|
|
|
|
# Split:
|
|
|
|
**Subtask 1**: Audit and preparation
|
|
|
|
- Find all direct .on() usage
|
|
- Document required changes
|
|
- Create shared hook if needed
|
|
|
|
**Subtask 2**: Core panels (3-4 files)
|
|
|
|
- NodeGraphEditor
|
|
- PropertyEditor
|
|
- ComponentPanel
|
|
|
|
**Subtask 3**: Secondary panels (3-4 files)
|
|
|
|
- LibraryPanel
|
|
- WarningsPanel
|
|
- NavigatorPanel
|
|
|
|
**Subtask 4**: Utility panels (remaining)
|
|
|
|
- All other panels
|
|
- Verification and testing
|
|
```
|
|
|
|
### 15.5 Maintaining Quality While Splitting
|
|
|
|
**DO NOT cut corners to fit in context:**
|
|
|
|
❌ **WRONG approaches**:
|
|
|
|
- Removing documentation to save tokens
|
|
- Skipping test files
|
|
- Using placeholders instead of real implementation
|
|
- Commenting out code with "// TODO: Implement later"
|
|
- Removing type safety to save space
|
|
|
|
✅ **CORRECT approaches**:
|
|
|
|
- Split into complete, working subtasks
|
|
- Each subtask is fully implemented and tested
|
|
- Each subtask can be verified independently
|
|
- Each subtask advances the overall goal
|
|
- Quality standards maintained for every subtask
|
|
|
|
### 15.6 Progress Tracking for Multi-Subtask Work
|
|
|
|
When you've split a task, track progress:
|
|
|
|
```markdown
|
|
## Task Progress: [Feature Name]
|
|
|
|
**Overall Goal**: [Brief description]
|
|
|
|
**Subtasks**:
|
|
|
|
- [x] Subtask 1: [Name] - ✅ Complete
|
|
- [ ] Subtask 2: [Name] - 🔄 In Progress
|
|
- [ ] Subtask 3: [Name] - ⏳ Pending
|
|
- [ ] Subtask 4: [Name] - ⏳ Pending
|
|
|
|
**Current Status**: Working on Subtask 2
|
|
**Files Modified So Far**: [List]
|
|
**Tests Added**: [Count]
|
|
```
|
|
|
|
Update this at the start of each subtask session.
|
|
|
|
### 15.7 When to Ask for Help
|
|
|
|
You should ask Richard for guidance when:
|
|
|
|
1. **Task scope is genuinely unclear**
|
|
- "This could be split 3 different ways - which do you prefer?"
|
|
2. **Dependencies block all split approaches**
|
|
- "Files A, B, C must change together atomically - can't split safely"
|
|
3. **You've split but still hitting limits on a subtask**
|
|
|
|
- "Subtask 1 is still too large. Should I split further or simplify scope?"
|
|
|
|
4. **Integration approach is ambiguous**
|
|
- "I can split by feature or by layer - which matches your mental model better?"
|
|
|
|
### 15.8 Context-Saving Techniques
|
|
|
|
When context is tight but task is manageable, use these techniques:
|
|
|
|
#### Read files strategically:
|
|
|
|
```bash
|
|
# ❌ BAD - Reads entire 2000-line file
|
|
view path/to/huge-component.tsx
|
|
|
|
# ✅ GOOD - Reads just what you need
|
|
view path/to/huge-component.tsx [50, 100] # Lines 50-100
|
|
```
|
|
|
|
#### Use targeted searches:
|
|
|
|
```bash
|
|
# ❌ BAD - Reads all search results
|
|
grep -r "EventDispatcher" packages/
|
|
|
|
# ✅ GOOD - Limit scope first
|
|
grep -r "EventDispatcher" packages/noodl-editor/src/views/panels/ --include="*.tsx"
|
|
```
|
|
|
|
#### Build incrementally:
|
|
|
|
```typescript
|
|
// ❌ BAD - Write entire 500-line component at once
|
|
create_file(path, [massive-file-content])
|
|
|
|
// ✅ GOOD - Build in stages
|
|
create_file(path, [minimal-working-version])
|
|
# Test it works
|
|
str_replace(path, old, new) # Add feature 1
|
|
# Test it works
|
|
str_replace(path, old, new) # Add feature 2
|
|
# Continue...
|
|
```
|
|
|
|
### 15.9 Emergency Context Recovery
|
|
|
|
If you're deep in a task and suddenly hit limits:
|
|
|
|
1. **Save your current work immediately**
|
|
|
|
```bash
|
|
git add .
|
|
git commit -m "WIP: [what you completed]"
|
|
```
|
|
|
|
2. **Document exactly where you are**
|
|
|
|
```markdown
|
|
## Current State
|
|
|
|
- Completed: [specific changes]
|
|
- Files modified: [list]
|
|
- Next step: [exactly what remains]
|
|
- Blocked by: [if applicable]
|
|
```
|
|
|
|
3. **Propose next steps**
|
|
"I've completed X and Y. To finish, I need to do Z.
|
|
Should I continue with Z in the next session?"
|
|
|
|
### 15.10 Self-Check Before Starting Large Tasks
|
|
|
|
Before beginning any task that modifies 5+ files:
|
|
|
|
```markdown
|
|
## Pre-Flight Context Check
|
|
|
|
**Task**: [Name]
|
|
**Estimated files to modify**: [Count]
|
|
**Estimated LOC to read**: [Rough guess]
|
|
|
|
**Risk assessment**:
|
|
|
|
- [ ] Will I need to read multiple large files (>500 lines)?
|
|
- [ ] Does this touch 3+ packages?
|
|
- [ ] Will I need to trace complex dependencies?
|
|
- [ ] Is this a refactor touching 10+ files?
|
|
|
|
**If 2+ boxes checked**: Propose split BEFORE starting implementation
|
|
|
|
**My split plan**:
|
|
|
|
1. [Subtask with 2-4 files]
|
|
2. [Subtask with 2-4 files]
|
|
3. [Remaining work]
|
|
```
|
|
|
|
---
|
|
|
|
## Usage Examples
|
|
|
|
### Example 1: Proactive Split
|
|
|
|
```markdown
|
|
Richard: "Implement the full HTTP node with cURL import, auth presets, and JSONPath mapping"
|
|
|
|
Cline: "This task is quite large and would likely exceed API limits if done in one pass. Let me break it down:
|
|
|
|
**Subtask 1 - Core HTTP Node** (Est: 3 files, 2h)
|
|
|
|
- Implement basic HTTP node structure
|
|
- Add method/URL/body inputs
|
|
- Handle simple requests/responses
|
|
|
|
**Subtask 2 - cURL Import** (Est: 2 files, 1.5h)
|
|
|
|
- Add cURL parser utility
|
|
- Integrate import UI
|
|
- Handle common cURL flags
|
|
|
|
**Subtask 3 - Auth Presets** (Est: 2 files, 1h)
|
|
|
|
- Create auth preset system
|
|
- Add Bearer/Basic/Custom options
|
|
- Persist presets in project
|
|
|
|
**Subtask 4 - JSONPath Mapping** (Est: 2 files, 1.5h)
|
|
|
|
- Implement JSONPath evaluation
|
|
- Add output port creation
|
|
- Handle mapping UI
|
|
|
|
Should I start with Subtask 1?"
|
|
```
|
|
|
|
### Example 2: Error Recovery
|
|
|
|
```markdown
|
|
[API error occurs]
|
|
|
|
Cline: "I've hit an API context limit while trying to update all 15 panel components at once.
|
|
|
|
I was attempting to migrate EventDispatcher usage across:
|
|
|
|
- NodeGraphEditor, PropertyEditor, ComponentPanel, LibraryPanel... [full list]
|
|
|
|
This is too large. Let me split it:
|
|
|
|
**Subtask 1 - Core Panels** (3 files)
|
|
|
|
- NodeGraphEditor.tsx
|
|
- PropertyEditor.tsx
|
|
- ComponentPanel.tsx
|
|
|
|
**Subtask 2 - Secondary Panels** (4 files)
|
|
|
|
- LibraryPanel.tsx
|
|
- WarningsPanel.tsx
|
|
- NavigatorPanel.tsx
|
|
- InspectorPanel.tsx
|
|
|
|
**Subtask 3 - Remaining Panels** (8 files)
|
|
|
|
- All other panels
|
|
- Final verification
|
|
|
|
Starting with Subtask 1 now..."
|
|
|
|
[Proceeds with focused work]
|
|
```
|
|
|
|
---
|
|
|
|
## Key Principles
|
|
|
|
1. **Recognize limits early** - Better to split proactively than hit errors
|
|
2. **Split logically** - Each subtask should be coherent and testable
|
|
3. **Maintain quality** - Never sacrifice standards to fit in context
|
|
4. **Track progress** - Show what's done and what remains
|
|
5. **Ask when stuck** - Richard can guide unclear splits
|
|
6. **Learn from errors** - If you hit limits, that task was too large
|
|
|
|
**Remember**: It's better to complete 3 small subtasks successfully than fail on 1 large task repeatedly.
|
|
|
|
---
|
|
|
|
## 16. Code Comments Language
|
|
|
|
**All code comments must be in English**, regardless of the user's language. This ensures:
|
|
|
|
- Consistent codebase for international collaboration
|
|
- Better compatibility with AI tools
|
|
- Easier code review and maintenance
|
|
|
|
```typescript
|
|
// ✅ GOOD: English comments
|
|
function calculateTotal(items: Item[]): number {
|
|
// Sum up all item prices
|
|
return items.reduce((sum, item) => sum + item.price, 0);
|
|
}
|
|
|
|
// ❌ BAD: Non-English comments
|
|
function calculateTotal(items: Item[]): number {
|
|
// Additionner tous les prix des articles
|
|
return items.reduce((sum, item) => sum + item.price, 0);
|
|
}
|
|
```
|
|
|
|
This rule applies to:
|
|
|
|
- Inline comments
|
|
- Function/class documentation (JSDoc)
|
|
- Block comments explaining logic
|
|
- TODO/FIXME notes
|
|
- Commit messages (covered in Git Workflow section)
|
|
|
|
**Exception**: User-facing strings in UI components may be in any language (they will be localized later).
|