chore: Project cleanup and Canvas UX improvements (Phase 7-9)
## Cleanup (v0.5.0) - Delete 102+ orphaned MCP session temp files - Remove build artifacts (htmlcov, dist, __pycache__) - Archive superseded plan docs (RALPH_LOOP V2/V3, CANVAS V3, etc.) - Move debug/analysis scripts from tests/ to tools/analysis/ - Archive redundant NX journals to archive/nx_journals/ - Archive monolithic PROTOCOL.md to docs/archive/ - Update .gitignore with missing patterns - Clean old study files (optimization_log_old.txt, run_optimization_old.py) ## Canvas UX (Phases 7-9) - Phase 7: Resizable panels with localStorage persistence - Left sidebar: 200-400px, Right panel: 280-600px - New useResizablePanel hook and ResizeHandle component - Phase 8: Enable all palette items - All 8 node types now draggable - Singleton logic for model/solver/algorithm/surrogate - Phase 9: Solver configuration - Add SolverEngine type (nxnastran, mscnastran, python, etc.) - Add NastranSolutionType (SOL101-SOL200) - Engine/solution dropdowns in config panel - Python script path support ## Documentation - Update CHANGELOG.md with recent versions - Update docs/00_INDEX.md - Create examples/README.md - Add docs/plans/CANVAS_UX_IMPROVEMENTS.md
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Atomizer Documentation Index
|
||||
|
||||
**Last Updated**: 2026-01-20
|
||||
**Project Version**: 1.0.0 (AtomizerSpec v2.0 - Full LLM Integration)
|
||||
**Last Updated**: 2026-01-24
|
||||
**Project Version**: 0.5.0 (AtomizerSpec v2.0 - Canvas Builder)
|
||||
|
||||
---
|
||||
|
||||
@@ -201,6 +201,8 @@ Historical documents are preserved in `archive/`:
|
||||
- `archive/historical/` - Legacy documents, old protocols
|
||||
- `archive/marketing/` - Briefings, presentations
|
||||
- `archive/session_summaries/` - Past development sessions
|
||||
- `archive/plans/` - Superseded plan documents (RALPH_LOOP V2/V3, CANVAS V3, etc.)
|
||||
- `archive/PROTOCOL_V1_MONOLITHIC.md` - Original monolithic protocol (Nov 2025)
|
||||
|
||||
---
|
||||
|
||||
@@ -216,5 +218,5 @@ For Claude/AI integration:
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-01-20
|
||||
**Last Updated**: 2026-01-24
|
||||
**Maintained By**: Antoine / Atomaste
|
||||
|
||||
1929
docs/archive/PROTOCOL_V1_MONOLITHIC.md
Normal file
1929
docs/archive/PROTOCOL_V1_MONOLITHIC.md
Normal file
File diff suppressed because it is too large
Load Diff
445
docs/plans/CANVAS_UX_IMPROVEMENTS.md
Normal file
445
docs/plans/CANVAS_UX_IMPROVEMENTS.md
Normal file
@@ -0,0 +1,445 @@
|
||||
# Canvas UX Improvements - Master Plan
|
||||
|
||||
**Created:** January 2026
|
||||
**Status:** Planning
|
||||
**Branch:** `feature/studio-enhancement`
|
||||
|
||||
## Overview
|
||||
|
||||
This plan addresses three major UX issues in the Canvas Builder:
|
||||
|
||||
1. **Resizable Panels** - Right pane (chat/config) is fixed at 384px, cannot be adjusted
|
||||
2. **Disabled Palette Items** - Model, Solver, Algorithm, Surrogate are grayed out and not draggable
|
||||
3. **Solver Type Selection** - Solver node should allow selection of solver type (NX Nastran, Python, etc.)
|
||||
|
||||
---
|
||||
|
||||
## Phase 7: Resizable Panels
|
||||
|
||||
### Current State
|
||||
- Left sidebar: Fixed 240px (expanded) or 56px (collapsed)
|
||||
- Right panel (Chat/Config): Fixed 384px
|
||||
- Canvas: Takes remaining space
|
||||
|
||||
### Requirements
|
||||
- Users should be able to drag panel edges to resize
|
||||
- Minimum/maximum constraints for usability
|
||||
- Persist panel sizes in localStorage
|
||||
- Smooth resize with proper cursor feedback
|
||||
|
||||
### Implementation
|
||||
|
||||
#### 7.1 Create Resizable Panel Hook
|
||||
```typescript
|
||||
// hooks/useResizablePanel.ts
|
||||
interface ResizablePanelState {
|
||||
width: number;
|
||||
isDragging: boolean;
|
||||
startDrag: (e: React.MouseEvent) => void;
|
||||
}
|
||||
|
||||
function useResizablePanel(
|
||||
key: string,
|
||||
defaultWidth: number,
|
||||
minWidth: number,
|
||||
maxWidth: number
|
||||
): ResizablePanelState
|
||||
```
|
||||
|
||||
#### 7.2 Update CanvasView Layout
|
||||
- Wrap left sidebar with resizer
|
||||
- Wrap right panel with resizer
|
||||
- Add visual drag handles (thin border that highlights on hover)
|
||||
- Add cursor: col-resize on hover
|
||||
|
||||
#### 7.3 Files to Modify
|
||||
| File | Changes |
|
||||
|------|---------|
|
||||
| `hooks/useResizablePanel.ts` | NEW - Resize hook with localStorage persistence |
|
||||
| `pages/CanvasView.tsx` | Add resizers to left/right panels |
|
||||
| `components/canvas/ResizeHandle.tsx` | NEW - Visual resize handle component |
|
||||
|
||||
#### 7.4 Constraints
|
||||
| Panel | Min | Default | Max |
|
||||
|-------|-----|---------|-----|
|
||||
| Left (Palette/Files) | 200px | 240px | 400px |
|
||||
| Right (Chat/Config) | 280px | 384px | 600px |
|
||||
|
||||
---
|
||||
|
||||
## Phase 8: Enable All Palette Items
|
||||
|
||||
### Current State
|
||||
- Model, Solver, Algorithm, Surrogate are marked `canAdd: false`
|
||||
- They appear grayed out with "Auto-created" text
|
||||
- Users cannot drag them to canvas
|
||||
|
||||
### Problem Analysis
|
||||
These nodes were marked as "synthetic" because they're derived from:
|
||||
- **Model**: From `spec.model.sim.path`
|
||||
- **Solver**: From model's solution type
|
||||
- **Algorithm**: From `spec.optimization.algorithm`
|
||||
- **Surrogate**: From `spec.optimization.surrogate`
|
||||
|
||||
However, users need to:
|
||||
1. Add a Model node when creating a new study from scratch
|
||||
2. Configure the Solver type
|
||||
3. Choose an Algorithm
|
||||
4. Enable/configure Surrogate
|
||||
|
||||
### Solution: Make All Items Draggable
|
||||
|
||||
#### 8.1 Update NodePalette
|
||||
```typescript
|
||||
// All items should be draggable
|
||||
export const PALETTE_ITEMS: PaletteItem[] = [
|
||||
{
|
||||
type: 'model',
|
||||
label: 'Model',
|
||||
canAdd: true, // Changed from false
|
||||
description: 'NX/FEM model file',
|
||||
},
|
||||
{
|
||||
type: 'solver',
|
||||
label: 'Solver',
|
||||
canAdd: true, // Changed from false
|
||||
description: 'Analysis solver',
|
||||
},
|
||||
// ... etc
|
||||
];
|
||||
```
|
||||
|
||||
#### 8.2 Handle "Singleton" Nodes
|
||||
Some nodes should only exist once on the canvas:
|
||||
- Model (only one model per study)
|
||||
- Solver (one solver)
|
||||
- Algorithm (one algorithm config)
|
||||
- Surrogate (optional, one)
|
||||
|
||||
When user drags a singleton that already exists:
|
||||
- Option A: Show warning toast "Model already exists"
|
||||
- Option B: Select the existing node instead of creating new
|
||||
- **Recommended**: Option B (select existing)
|
||||
|
||||
#### 8.3 Update SpecRenderer Drop Handler
|
||||
```typescript
|
||||
const onDrop = useCallback(async (event: DragEvent) => {
|
||||
const type = event.dataTransfer.getData('application/reactflow');
|
||||
|
||||
// Check if singleton already exists
|
||||
const SINGLETON_TYPES = ['model', 'solver', 'algorithm', 'surrogate'];
|
||||
if (SINGLETON_TYPES.includes(type)) {
|
||||
const existingNode = nodes.find(n => n.type === type);
|
||||
if (existingNode) {
|
||||
selectNode(existingNode.id);
|
||||
showNotification(`${type} already exists - selected it`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new node...
|
||||
}, [...]);
|
||||
```
|
||||
|
||||
#### 8.4 Default Data for New Node Types
|
||||
```typescript
|
||||
function getDefaultNodeData(type: NodeType, position) {
|
||||
switch (type) {
|
||||
case 'model':
|
||||
return {
|
||||
name: 'Model',
|
||||
sim: { path: '', solver: 'nastran' },
|
||||
canvas_position: position,
|
||||
};
|
||||
case 'solver':
|
||||
return {
|
||||
name: 'Solver',
|
||||
type: 'nxnastran', // Default solver
|
||||
solution_type: 'SOL101',
|
||||
canvas_position: position,
|
||||
};
|
||||
case 'algorithm':
|
||||
return {
|
||||
name: 'Algorithm',
|
||||
type: 'TPE',
|
||||
budget: { max_trials: 100 },
|
||||
canvas_position: position,
|
||||
};
|
||||
case 'surrogate':
|
||||
return {
|
||||
name: 'Surrogate',
|
||||
enabled: false,
|
||||
model_type: 'MLP',
|
||||
min_trials: 20,
|
||||
canvas_position: position,
|
||||
};
|
||||
// ... existing cases
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 8.5 Files to Modify
|
||||
| File | Changes |
|
||||
|------|---------|
|
||||
| `components/canvas/palette/NodePalette.tsx` | Set `canAdd: true` for all items |
|
||||
| `components/canvas/SpecRenderer.tsx` | Handle singleton logic in onDrop |
|
||||
| `lib/spec/converter.ts` | Ensure synthetic nodes have proper IDs |
|
||||
| `hooks/useSpecStore.ts` | Add model/solver/algorithm to addNode support |
|
||||
|
||||
---
|
||||
|
||||
## Phase 9: Solver Type Selection
|
||||
|
||||
### Current State
|
||||
- Solver node shows auto-detected solution type (SOL101, etc.)
|
||||
- No ability to change solver engine or configure it
|
||||
|
||||
### Requirements
|
||||
1. Allow selection of solver engine type
|
||||
2. Configure solution type
|
||||
3. Support future solver types
|
||||
|
||||
### Solver Types to Support
|
||||
|
||||
| Solver | Description | Status |
|
||||
|--------|-------------|--------|
|
||||
| `nxnastran` | NX Nastran (built-in) | Current |
|
||||
| `mscnastran` | MSC Nastran (external) | Future |
|
||||
| `python` | Python-based solver | Future |
|
||||
| `abaqus` | Abaqus (via Python API) | Future |
|
||||
| `ansys` | ANSYS (via Python API) | Future |
|
||||
|
||||
### Solution Types per Solver
|
||||
|
||||
**NX Nastran / MSC Nastran:**
|
||||
- SOL101 - Linear Static
|
||||
- SOL103 - Normal Modes
|
||||
- SOL105 - Buckling
|
||||
- SOL106 - Nonlinear Static
|
||||
- SOL111 - Frequency Response
|
||||
- SOL112 - Transient Response
|
||||
- SOL200 - Design Optimization
|
||||
|
||||
**Python Solver:**
|
||||
- Custom (user-defined)
|
||||
|
||||
### Schema Updates
|
||||
|
||||
#### 9.1 Update AtomizerSpec Types
|
||||
```typescript
|
||||
// types/atomizer-spec.ts
|
||||
|
||||
export type SolverEngine =
|
||||
| 'nxnastran'
|
||||
| 'mscnastran'
|
||||
| 'python'
|
||||
| 'abaqus'
|
||||
| 'ansys';
|
||||
|
||||
export type NastranSolutionType =
|
||||
| 'SOL101'
|
||||
| 'SOL103'
|
||||
| 'SOL105'
|
||||
| 'SOL106'
|
||||
| 'SOL111'
|
||||
| 'SOL112'
|
||||
| 'SOL200';
|
||||
|
||||
export interface SolverConfig {
|
||||
/** Solver engine type */
|
||||
engine: SolverEngine;
|
||||
|
||||
/** Solution type (for Nastran) */
|
||||
solution_type?: NastranSolutionType;
|
||||
|
||||
/** Custom solver script path (for Python solver) */
|
||||
script_path?: string;
|
||||
|
||||
/** Additional solver options */
|
||||
options?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface Model {
|
||||
sim?: {
|
||||
path: string;
|
||||
solver: SolverConfig; // Changed from just 'nastran' string
|
||||
};
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
#### 9.2 Update SolverNode Component
|
||||
```typescript
|
||||
// components/canvas/nodes/SolverNode.tsx
|
||||
|
||||
function SolverNodeComponent(props: NodeProps<SolverNodeData>) {
|
||||
const { data } = props;
|
||||
|
||||
return (
|
||||
<BaseNode {...props} icon={<Cpu size={16} />} iconColor="text-violet-400">
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="text-sm font-medium">{data.engine || 'nxnastran'}</span>
|
||||
<span className="text-xs text-dark-400">
|
||||
{data.solution_type || 'Auto-detect'}
|
||||
</span>
|
||||
</div>
|
||||
</BaseNode>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### 9.3 Solver Configuration Panel
|
||||
Add to `NodeConfigPanelV2.tsx`:
|
||||
|
||||
```typescript
|
||||
function SolverNodeConfig({ spec }: SpecConfigProps) {
|
||||
const { patchSpec } = useSpecStore();
|
||||
const solver = spec.model?.sim?.solver || { engine: 'nxnastran' };
|
||||
|
||||
const handleEngineChange = (engine: SolverEngine) => {
|
||||
patchSpec('model.sim.solver.engine', engine);
|
||||
};
|
||||
|
||||
const handleSolutionTypeChange = (type: NastranSolutionType) => {
|
||||
patchSpec('model.sim.solver.solution_type', type);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<label className={labelClass}>Solver Engine</label>
|
||||
<select
|
||||
value={solver.engine}
|
||||
onChange={(e) => handleEngineChange(e.target.value as SolverEngine)}
|
||||
className={selectClass}
|
||||
>
|
||||
<option value="nxnastran">NX Nastran</option>
|
||||
<option value="mscnastran">MSC Nastran</option>
|
||||
<option value="python">Python Script</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{(solver.engine === 'nxnastran' || solver.engine === 'mscnastran') && (
|
||||
<div>
|
||||
<label className={labelClass}>Solution Type</label>
|
||||
<select
|
||||
value={solver.solution_type || ''}
|
||||
onChange={(e) => handleSolutionTypeChange(e.target.value as NastranSolutionType)}
|
||||
className={selectClass}
|
||||
>
|
||||
<option value="">Auto-detect from model</option>
|
||||
<option value="SOL101">SOL101 - Linear Static</option>
|
||||
<option value="SOL103">SOL103 - Normal Modes</option>
|
||||
<option value="SOL105">SOL105 - Buckling</option>
|
||||
<option value="SOL106">SOL106 - Nonlinear Static</option>
|
||||
<option value="SOL111">SOL111 - Frequency Response</option>
|
||||
<option value="SOL112">SOL112 - Transient Response</option>
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{solver.engine === 'python' && (
|
||||
<div>
|
||||
<label className={labelClass}>Solver Script</label>
|
||||
<input
|
||||
type="text"
|
||||
value={solver.script_path || ''}
|
||||
onChange={(e) => patchSpec('model.sim.solver.script_path', e.target.value)}
|
||||
placeholder="/path/to/solver.py"
|
||||
className={inputClass}
|
||||
/>
|
||||
<p className="text-xs text-dark-500 mt-1">
|
||||
Python script that runs the analysis
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### 9.4 Files to Modify
|
||||
| File | Changes |
|
||||
|------|---------|
|
||||
| `types/atomizer-spec.ts` | Add SolverEngine, SolverConfig types |
|
||||
| `components/canvas/nodes/SolverNode.tsx` | Show engine and solution type |
|
||||
| `components/canvas/panels/NodeConfigPanelV2.tsx` | Add SolverNodeConfig |
|
||||
| `lib/canvas/schema.ts` | Update SolverNodeData |
|
||||
| Backend: `config/spec_models.py` | Add SolverConfig Pydantic model |
|
||||
|
||||
---
|
||||
|
||||
## Implementation Order
|
||||
|
||||
| Phase | Effort | Priority | Dependencies |
|
||||
|-------|--------|----------|--------------|
|
||||
| **7.1** Resizable Panel Hook | 2h | High | None |
|
||||
| **7.2** CanvasView Resizers | 2h | High | 7.1 |
|
||||
| **8.1** Enable Palette Items | 1h | High | None |
|
||||
| **8.2** Singleton Logic | 2h | High | 8.1 |
|
||||
| **8.3** Default Node Data | 1h | High | 8.2 |
|
||||
| **9.1** Schema Updates | 2h | Medium | None |
|
||||
| **9.2** SolverNode UI | 1h | Medium | 9.1 |
|
||||
| **9.3** Solver Config Panel | 2h | Medium | 9.1, 9.2 |
|
||||
|
||||
**Total Estimated Effort:** ~13 hours
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### Phase 7 (Resizable Panels)
|
||||
- [ ] Left panel can be resized between 200-400px
|
||||
- [ ] Right panel can be resized between 280-600px
|
||||
- [ ] Resize handles show cursor feedback
|
||||
- [ ] Panel sizes persist across page reload
|
||||
- [ ] Double-click on handle resets to default
|
||||
|
||||
### Phase 8 (Enable Palette Items)
|
||||
- [ ] All 8 node types are draggable from palette
|
||||
- [ ] Dragging singleton to canvas with existing node selects existing
|
||||
- [ ] Toast notification explains the behavior
|
||||
- [ ] New studies can start with empty canvas and add Model first
|
||||
|
||||
### Phase 9 (Solver Selection)
|
||||
- [ ] Solver node shows engine type (nxnastran, python, etc.)
|
||||
- [ ] Clicking solver node opens config panel
|
||||
- [ ] Can select solver engine from dropdown
|
||||
- [ ] Nastran solvers show solution type dropdown
|
||||
- [ ] Python solver shows script path input
|
||||
- [ ] Changes persist to atomizer_spec.json
|
||||
|
||||
---
|
||||
|
||||
## Future Considerations
|
||||
|
||||
### Additional Solver Support
|
||||
- ANSYS integration via pyANSYS
|
||||
- Abaqus integration via abaqus-python
|
||||
- OpenFOAM for CFD
|
||||
- Custom Python solvers with standardized interface
|
||||
|
||||
### Multi-Solver Workflows
|
||||
- Support for chained solvers (thermal → structural)
|
||||
- Co-simulation workflows
|
||||
- Parallel solver execution
|
||||
|
||||
### Algorithm Node Enhancement
|
||||
- Similar to Solver, allow algorithm selection
|
||||
- Show algorithm-specific parameters
|
||||
- Support custom algorithms
|
||||
|
||||
---
|
||||
|
||||
## Commit Strategy
|
||||
|
||||
```bash
|
||||
# Phase 7
|
||||
git commit -m "feat: Add resizable panels to canvas view"
|
||||
|
||||
# Phase 8
|
||||
git commit -m "feat: Enable all palette items with singleton handling"
|
||||
|
||||
# Phase 9
|
||||
git commit -m "feat: Add solver type selection and configuration"
|
||||
```
|
||||
Reference in New Issue
Block a user