Port sketch editor to feat/ts-backend-migration branch#2140
Draft
Port sketch editor to feat/ts-backend-migration branch#2140
Conversation
Dashboard tests had intermittent timing failures when running in parallel due to race conditions with the Getting Started panel. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Universal JavaScript code node that runs user code in a sandboxed V8 isolate (isolated-vm) with 128MB memory limit and hard CPU timeout. Dynamic inputs become global variables; return value defines outputs. Supports streaming via genProcess() with yield_() pattern. 130 tests covering dynamic inputs, return values, implicit return, streaming, type coverage, edge cases, and sandbox isolation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Start PythonBridge on server startup to spawn nodetool_worker process - Route Python node types (HF, MLX) through PythonNodeExecutor - Fall back to TS registry for native TS nodes - Add gzip compression for large API responses (e.g. /api/nodes/metadata) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ages Cover previously untested areas: - workflow-crud-real: create, list, get, update, delete workflows via API + UI editor integration - settings-api-real: settings/secrets endpoints, providers, nodes metadata validation - standalone-pages: /apps, /miniapp, /standalone-chat, /assets, /collections, route redirects Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Server now waits for PythonBridge to connect before listening - Improved resolveExecutor: check TS registry first, then Python bridge - Better error message when Python worker is not connected - Add gzip compression for large API responses Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- run-workflow.mjs auto-starts PythonBridge when graph has non-TS nodes - Fix property passing: check both node.properties and node.data - Properly clean up Python bridge on exit Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename vector.chroma.* nodes to vector.* namespace since they already use sqlite-vec under the hood. Rename Chroma* agent tools to Vec*, update UI labels, settings, CLI env vars, and deploy interfaces. Remove unused chromadb dependency from base-nodes and websocket packages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…le path Change worker module invocation from nodetool_worker to nodetool.worker to match the merge of the worker into nodetool-core. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PythonProvider: BaseProvider that proxies to Python via PythonBridge - PythonBridge: new methods for provider calls (models, generate, stream, text-to-image, TTS, ASR, embeddings) with streaming support - models-api: registerPythonProviders() auto-registers Python providers after bridge connects; getAllModels() queries all available providers - server: fire-and-forget provider registration, better error messages - electron: pass NODETOOL_PYTHON and getProcessEnv() to TS backend so PythonBridge spawns the correct conda Python Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…odal, property widget, and node integration Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com>
…tore Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add modular sketch editor for nodetool
feat: Modular sketch editor with property widget, custom node, and layer-based document model
Mar 15, 2026
- Updated the release workflow to create a Windows unpacked archive during the build process. - Modified the condition for resolving Windows artifacts to always run on 'windows-latest'. - Removed the inclusion of win-unpacked executables from the artifacts list, as they are now archived separately. This change improves the organization of Windows build artifacts and ensures that unpacked versions are readily available.
Port 80 requires root — gracefully skip the redirect instead of crashing. Adds REDIRECT_PORT env var for custom redirect port. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Updated `getCondaEnvPath` to prefer activated conda environments when in explicit development mode. - Removed caching of conda environment paths to streamline the environment detection process. - Added tests to verify behavior for using activated conda environments in and out of development mode. - Implemented functionality to clear inherited conda and virtualenv markers from the process environment. This change improves the flexibility of conda environment management during local development.
…detool into feat/ts-backend-migration
- Updated multiple components to use hexToRgba instead of alpha for background colors and shadows, enhancing color consistency across the application. - Affected files include ThreadMessageList.tsx, DataframeProperty.tsx, ImageListProperty.tsx, TextListProperty.tsx, and WorkflowCard.tsx.
Adds scripts/start-production.sh for running the API server in production with auto-restart, memory limits, and exponential backoff. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace forward slashes in VERSION_NO_V so branch names like feat/ts-backend-migration don't cause PowerShell Compress-Archive to treat the path as a non-existent subdirectory. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Source secrets (S3, Supabase, API keys) from sibling nodetool-core/.env before starting pm2, so the server has access to all production config. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move secrets and TLS certs into the nodetool repo (both gitignored). Remove sibling directory lookups from server.ts and start script. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three fixes to ensure externalized native packages (sharp, better-sqlite3, etc.) are available at runtime in the packaged Electron app: 1. electron-builder.json: Add explicit filter ["**/*"] to the backend-bundle extraResources entry to ensure node_modules/ is copied to the final package (electron-builder may exclude node_modules by default). 2. server.ts: Set NODE_PATH environment variable pointing to the backend's node_modules directory so Node.js can resolve packages from there. 3. watchdog.ts: Add cwd option and set the backend process working directory to the backend bundle directory, ensuring Node.js ESM module resolution starts from the correct location. https://claude.ai/code/session_011W9HjJqjoAdNzBxDpF7VD1 Co-authored-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Forward the authenticated userId set by Fastify's req.userId decorator into the Web API Request as x-user-id header, so route handlers that call getUserId(request, "x-user-id") pick it up automatically once the auth hook (Task 2) is in place. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…patibility electron-builder excludes node_modules directories from extraResources by default (respects .gitignore patterns). Renaming to _modules ensures native packages like sharp and better-sqlite3 are included in the app bundle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The _modules directory contains 18k+ files; the previous limit of 4096 caused EMFILE errors during electron-builder packaging. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Modified the URL loading in both the Electron main process and the React app to append /index.html, ensuring correct routing for the web application. - Enhanced the websocket server to serve static files and handle 404 responses by returning index.html for unmatched routes, improving user experience for static content access.
…tion' of github.com:nodetool-ai/nodetool into feat/ts-backend-migration
…stent background color handling - Introduced a new rerouteBackground function to determine background colors based on theme mode. - Updated styles in RerouteNode component to use rerouteBackground for both node background and title background.
…2234) * Initial plan * feat(sketch): add pressure sensitivity and brush roundness/angle - Add pressureSensitivity, pressureAffects, roundness, and angle to BrushSettings - Update DEFAULT_BRUSH_SETTINGS with new defaults - Modify drawBrushStroke/drawEraserStroke/drawPencilStroke to accept optional pressure param - Apply pressure-based size/opacity modulation (min 20% at zero pressure) - Apply canvas scale+rotate transform for elliptical brush footprints - Pass e.pressure from pointer events to drawing functions via currentPressureRef - Add pressure toggle, pressure affects selector, roundness and angle sliders to toolbar - normalizeSketchDocument handles backward compatibility via spread defaults Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * style: use multi-line curly braces for needsTransform guards Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Implement rectangle selection tool in sketch editor - Add select tool handling in SketchCanvas (pointerDown/Move/Up) - Add drawOverlaySelection with marching ants (white+black dashed border) - Add drawSelectionOverlay for persistent selection display - Add selection/onSelectionChange props to SketchCanvasProps - Add clearLayerRect method to SketchCanvasRef for partial clearing - Wire selection state from store into SketchEditor - Delete/Backspace clears only selection area when selection exists - Escape key deselects current selection - Select tool uses crosshair cursor Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add pressure sensitivity, brush roundness/angle, and rectangle selection tool Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/41aa8d60-8ca3-4f15-8a80-0c0e57be8434 * Fix input image not showing up as layer - use latest document ref when opening editor Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/41aa8d60-8ca3-4f15-8a80-0c0e57be8434 * Update SKETCH_FEATURES.md and add tests for new features Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/41aa8d60-8ca3-4f15-8a80-0c0e57be8434 * Changes before error encountered Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/41aa8d60-8ca3-4f15-8a80-0c0e57be8434 * Fix lint warnings: remove unused import, move constants to module level, add missing useCallback deps Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/a9ef6463-2d76-4078-9893-186736642fa4 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Co-authored-by: heavy-d <david@reaktant.com>
…chNode UI (#2250) * Initial plan * Add layer color presets, fix mask icon, fix shift+click straight lines - Add transparent/black/white/gray color preset buttons to layer panel - Replace MasksIcon with GradientIcon for mask button - Fix shift+click straight lines by using capture-phase key listeners (the SketchEditor's capture-phase stopPropagation was blocking the SketchCanvas's bubble-phase key listeners for Shift/Space/S tracking) - Update handleAddLayer to accept optional fillColor parameter Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/d09949d7-112e-4c5f-9b88-c102e8ba623d * Add rAF-batched redraw for drawing performance + update SKETCH_FEATURES.md - Coalesce layer compositing during active drawing using requestAnimationFrame - Only one redraw per animation frame instead of per pointer move event - Reduces jank on large canvases (2K-4K) - Update SKETCH_FEATURES.md: mark straight lines, eraser, layer presets, mask icon, and performance batching as completed Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/d09949d7-112e-4c5f-9b88-c102e8ba623d * Add tests for layer presets + update SKETCH_FEATURES.md shipped appendix - Add 14 new tests covering transparent layer creation, default document structure, eraser settings, and layer data updates - Update Shipped Phase 2 appendix with new features - Update test count in architecture section (13 suites, 267+ tests) Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/d09949d7-112e-4c5f-9b88-c102e8ba623d * Address code review feedback: add comments and fix test assertions - Add explanatory comment for capture-phase key listeners in SketchCanvas - Add clarifying comment for fillColor null check in SketchEditor - Fix non-null assertion in tests (initialize with empty string) Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/d09949d7-112e-4c5f-9b88-c102e8ba623d * Performance: cache blur canvases + checkerboard pattern; add isolate/solo layer Performance: - Cache blur tool temporary canvases as refs (avoids 3 canvas allocations per pointer move during blur strokes) - Cache checkerboard as a CanvasPattern (avoids per-pixel fillRect loops on every redraw — critical for 4K canvases with 262K fillRect calls per frame) Isolate/solo layer: - Wire existing store toggleIsolateLayer to SketchLayersPanel UI - Add solo button per layer (FilterNone icon) with visual feedback - Pass isolatedLayerId to SketchCanvas; redraw skips non-isolated layers - Layer row gets .isolated CSS class with warning outline - Toggling again shows all layers Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/3fff605e-8268-47a5-9896-378fb47081af * Color swatches: hold-to-drag color selection for faster picking Add mousedown+mouseenter handlers to color swatches and user presets: - Press on a swatch to select color immediately - Hold mouse and drag over other swatches to preview colors in real-time - Release anywhere to confirm - Uses global mouseup listener for cleanup - Keeps existing click behavior as fallback Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/3fff605e-8268-47a5-9896-378fb47081af * Add tests for isolate/solo layer + update SKETCH_FEATURES.md - 11 new tests covering layer isolation, blur settings, color updates - Update SKETCH_FEATURES.md: mark isolate/solo layer, performance improvements, color swatch drag as completed - Update shipped appendix with new features - Test count: 14 suites, 278+ tests Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/3fff605e-8268-47a5-9896-378fb47081af * Address code review: fix checkerboard pattern caching, add icons to layer buttons - Fix checkerboard: cache tile canvas only (not context-specific CanvasPattern) - Add AddIcon children to Black/White/Gray layer preset buttons for usability - Improve capture-phase key listener comment with feature traceability Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/3fff605e-8268-47a5-9896-378fb47081af * feat(sketch): expose layer input/output — dynamic handles on SketchNode Add "Expose Input" and "Expose Output" toggle buttons to each layer row in the layers panel. When toggled, these create corresponding dynamic input/output handles on the SketchNode in the workflow editor. Changes: - Layer type: add optional exposedAsInput/exposedAsOutput fields - Store: add toggleLayerExposedInput/toggleLayerExposedOutput actions - SketchLayersPanel: add Input/Output icon buttons per layer row - SketchEditor: wire expose handlers through to panel - SketchNode: compute exposed layers, render dynamic Handle components - SketchNode: export exposed output layer data as node properties - 13 new tests covering type, store, toggling, and serialization Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/1a5d5dce-5787-4df5-84ba-321e77c86c61 * feat(sketch): cleaner SketchNode UI + update SKETCH_FEATURES.md SketchNode styling improvements: - Hover state: border highlight on hover - Edit overlay: flex column layout with "Edit Sketch" label - Dynamic handle labels: layer name shown next to exposed handles - Content area: rounded bottom corners matching node shape SKETCH_FEATURES.md: - Mark "Expose input/output" and "Cleaner node UI" as completed - Add both to shipped appendix - Update test count to 15 suites, 291+ tests Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/1a5d5dce-5787-4df5-84ba-321e77c86c61 * Address code review: batch updateNodeProperties, extract handle constants - Batch all output properties (image, mask, exposed layers) into a single updateNodeProperties call instead of calling it per-layer in a loop - Extract magic numbers for dynamic handle positioning into named constants: DYNAMIC_HANDLE_START_TOP, DYNAMIC_HANDLE_SPACING, DYNAMIC_OUTPUT_START_TOP Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com> Agent-Logs-Url: https://github.com/nodetool-ai/nodetool/sessions/1a5d5dce-5787-4df5-84ba-321e77c86c61 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: heavy-d <3121000+heavy-d@users.noreply.github.com>
- Introduced lastSmoothedPointRef for improved stroke smoothing. - Added strokeDirtyRectRef to track dirty areas for optimized redraws. - Implemented dynamic cursor canvas resizing with ResizeObserver for better user experience. - Enhanced brush stamp creation with caching for performance improvements. - Updated pressure sensitivity handling to include new brush settings. These changes aim to improve the overall drawing experience and performance in the SketchCanvas component.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fresh branch from
feat/ts-backend-migrationwith only sketch editor feature code cherry-picked. No code frommain— adapted all integration points to the ts-backend-migration code structure.Changes (20 files, 4960 insertions)
Sketch module (
web/src/components/sketch/):SketchEditor.tsx/SketchModal.tsx/SketchCanvas.tsx/SketchToolbar.tsx/SketchLayersPanel.tsx— fullscreen modal editor with brush, pencil, eraser, eyedropper, shape tools, flood fill, 28-color palettestate/useSketchStore.ts— Zustand store for document state, tool settings, undo/redo (30-entry cap)types/index.ts— document format, layer model with 12 blend modes, mask designationserialization/index.ts— flatten layers, export mask,loadImageWithDimensions()__tests__/— 79 unit tests covering types, store, serialization, data flowNode integration:
SketchNode/SketchNode.tsx— custom ReactFlow node withinput_imagetarget +image/masksource handlesSketchProperty.tsx— property widget with thumbnail previewIntegration points (2 modified files):
PropertyInput.tsx— addedcase "sketch"→SketchPropertyReactFlowWrapper.tsx— addedSketchNodetonodeTypes📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.