pixelweaver 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. package/.env.development +1 -0
  2. package/.github/workflows/ci.yml +22 -0
  3. package/.github/workflows/publish.yml +18 -0
  4. package/.prettierignore +5 -0
  5. package/.prettierrc +16 -0
  6. package/.python-version +1 -0
  7. package/.rlsbl/bases/.github/workflows/ci.yml +21 -0
  8. package/.rlsbl/bases/.github/workflows/publish.yml +18 -0
  9. package/.rlsbl/bases/.rlsbl/changes/unreleased.jsonl +0 -0
  10. package/.rlsbl/bases/.rlsbl/hooks/post-release.sh +8 -0
  11. package/.rlsbl/bases/.rlsbl/hooks/pre-checks.sh +5 -0
  12. package/.rlsbl/bases/.rlsbl/hooks/pre-release.sh +8 -0
  13. package/.rlsbl/bases/.rlsbl/lint/go.toml +17 -0
  14. package/.rlsbl/bases/.rlsbl/lint/npm.toml +19 -0
  15. package/.rlsbl/bases/.rlsbl/lint/python.toml +25 -0
  16. package/.rlsbl/bases/CHANGELOG.md +5 -0
  17. package/.rlsbl/bases/LICENSE +21 -0
  18. package/.rlsbl/changes/.validated +1 -0
  19. package/.rlsbl/changes/0.1.0.jsonl +85 -0
  20. package/.rlsbl/changes/0.1.0.md +13 -0
  21. package/.rlsbl/changes/unreleased.jsonl +0 -0
  22. package/.rlsbl/config.json +6 -0
  23. package/.rlsbl/hashes.json +14 -0
  24. package/.rlsbl/hooks/post-release.sh +8 -0
  25. package/.rlsbl/hooks/pre-checks.sh +5 -0
  26. package/.rlsbl/hooks/pre-release.sh +8 -0
  27. package/.rlsbl/lint/go.toml +17 -0
  28. package/.rlsbl/lint/npm.toml +19 -0
  29. package/.rlsbl/lint/python.toml +25 -0
  30. package/.rlsbl/releases/unreleased.toml +0 -0
  31. package/.rlsbl/releases/v0.1.0.toml +3 -0
  32. package/.rlsbl/version +1 -0
  33. package/.selfdoc/hashes/hashes.json +146 -0
  34. package/.strictcli/schema.json +227 -0
  35. package/CHANGELOG.md +17 -0
  36. package/CLAUDE.md +100 -0
  37. package/LICENSE +21 -0
  38. package/README.md +116 -0
  39. package/assets/icon.png +0 -0
  40. package/docs/_README.md +117 -0
  41. package/docs/cli-config.md +35 -0
  42. package/docs/cli-dev.md +21 -0
  43. package/docs/cli-diagnose.md +12 -0
  44. package/docs/cli-index.md +30 -0
  45. package/docs/cli-list.md +18 -0
  46. package/docs/cli-mcp.md +18 -0
  47. package/docs/cli-new.md +26 -0
  48. package/docs/cli-open.md +21 -0
  49. package/docs/cli-serve.md +21 -0
  50. package/docs/cli-stop.md +12 -0
  51. package/docs/gen-index.md +36 -0
  52. package/docs/index.md +13 -0
  53. package/docs/server-src-pixelweaver-__main__.md +12 -0
  54. package/docs/server-src-pixelweaver-autosave.md +12 -0
  55. package/docs/server-src-pixelweaver-bridge.md +12 -0
  56. package/docs/server-src-pixelweaver-cli.md +12 -0
  57. package/docs/server-src-pixelweaver-config.md +12 -0
  58. package/docs/server-src-pixelweaver-connections.md +12 -0
  59. package/docs/server-src-pixelweaver-main.md +12 -0
  60. package/docs/server-src-pixelweaver-mcp_bridge.md +12 -0
  61. package/docs/server-src-pixelweaver-mcp_drawing_tools.md +12 -0
  62. package/docs/server-src-pixelweaver-mcp_export_tools.md +12 -0
  63. package/docs/server-src-pixelweaver-mcp_frame_tools.md +12 -0
  64. package/docs/server-src-pixelweaver-mcp_history_tools.md +12 -0
  65. package/docs/server-src-pixelweaver-mcp_layer_tools.md +12 -0
  66. package/docs/server-src-pixelweaver-mcp_lock.md +12 -0
  67. package/docs/server-src-pixelweaver-mcp_project_tools.md +12 -0
  68. package/docs/server-src-pixelweaver-mcp_read_tools.md +12 -0
  69. package/docs/server-src-pixelweaver-mcp_registry.md +12 -0
  70. package/docs/server-src-pixelweaver-mcp_resources.md +12 -0
  71. package/docs/server-src-pixelweaver-mcp_server.md +12 -0
  72. package/docs/server-src-pixelweaver-protocol.md +12 -0
  73. package/docs/server-src-pixelweaver-state.md +12 -0
  74. package/docs/server-src-pixelweaver-storage.md +12 -0
  75. package/docs/server-src-pixelweaver-websocket.md +12 -0
  76. package/docs/server-src-pixelweaver.md +12 -0
  77. package/e2e/app-launch.test.ts +35 -0
  78. package/e2e/menus.test.ts +26 -0
  79. package/e2e/tools.test.ts +27 -0
  80. package/e2e/undo-redo.test.ts +11 -0
  81. package/eslint.config.js +62 -0
  82. package/index.html +13 -0
  83. package/package.json +48 -0
  84. package/playwright.config.ts +19 -0
  85. package/plugins/builtin/.gitkeep +0 -0
  86. package/plugins/builtin/advanced-fill-tool.ts +146 -0
  87. package/plugins/builtin/circle-tool.ts +186 -0
  88. package/plugins/builtin/diamond-tool.ts +182 -0
  89. package/plugins/builtin/dither-tool.ts +186 -0
  90. package/plugins/builtin/drawing-primitives-plugin.ts +362 -0
  91. package/plugins/builtin/drawing-utils.test.ts +495 -0
  92. package/plugins/builtin/drawing-utils.ts +431 -0
  93. package/plugins/builtin/effects/blur.ts +97 -0
  94. package/plugins/builtin/effects/color-effects.ts +278 -0
  95. package/plugins/builtin/effects/flip.ts +83 -0
  96. package/plugins/builtin/effects/glow.ts +118 -0
  97. package/plugins/builtin/effects/outline.ts +110 -0
  98. package/plugins/builtin/effects/rotate.ts +357 -0
  99. package/plugins/builtin/effects/scale.ts +258 -0
  100. package/plugins/builtin/effects/shadow.ts +111 -0
  101. package/plugins/builtin/effects/sharpen.ts +102 -0
  102. package/plugins/builtin/effects.test.ts +715 -0
  103. package/plugins/builtin/eraser-tool.ts +23 -0
  104. package/plugins/builtin/eyedropper-tool.ts +83 -0
  105. package/plugins/builtin/fill-tool.ts +93 -0
  106. package/plugins/builtin/gradient-tool.ts +204 -0
  107. package/plugins/builtin/gradient.test.ts +142 -0
  108. package/plugins/builtin/importers/aseprite-importer-plugin.ts +174 -0
  109. package/plugins/builtin/importers/aseprite-parser.ts +497 -0
  110. package/plugins/builtin/importers/piskel-importer-plugin.ts +222 -0
  111. package/plugins/builtin/importers/sky-spec-plugin.ts +409 -0
  112. package/plugins/builtin/line-tool.ts +267 -0
  113. package/plugins/builtin/make-stroke-tool.ts +271 -0
  114. package/plugins/builtin/noise-dither.test.ts +151 -0
  115. package/plugins/builtin/noise-tool.ts +131 -0
  116. package/plugins/builtin/pattern-stamp-tool.ts +162 -0
  117. package/plugins/builtin/pencil-tool.ts +25 -0
  118. package/plugins/builtin/rect-tool.ts +179 -0
  119. package/plugins/builtin/selection-tool.ts +388 -0
  120. package/plugins/builtin/selection.test.ts +195 -0
  121. package/plugins/builtin/tool-plugins.test.ts +529 -0
  122. package/public/favicon.svg +7 -0
  123. package/public/sw.js +91 -0
  124. package/pyproject.toml +49 -0
  125. package/scripts/eslint-wave-a-list.sh +24 -0
  126. package/scripts/eslint-wave-a-status.sh +25 -0
  127. package/scripts/fix-index-signature-access.py +127 -0
  128. package/scripts/fix-unchecked-index.py +128 -0
  129. package/scripts/fix-unchecked-vars.py +127 -0
  130. package/scripts/fix-wave-a-bangs.py +36 -0
  131. package/scripts/fix-wave-a-templates.py +108 -0
  132. package/scripts/fix-wave-b-void-expr.py +167 -0
  133. package/scripts/generate-command-params.py +540 -0
  134. package/scripts/migrate-single-frame-to-multi.py +171 -0
  135. package/scripts/smoke-test.sh +77 -0
  136. package/selfdoc.json +10 -0
  137. package/server/README.md +0 -0
  138. package/server/src/pixelweaver/__init__.py +1 -0
  139. package/server/src/pixelweaver/__main__.py +4 -0
  140. package/server/src/pixelweaver/autosave.py +114 -0
  141. package/server/src/pixelweaver/bridge.py +127 -0
  142. package/server/src/pixelweaver/cli.py +199 -0
  143. package/server/src/pixelweaver/config.py +24 -0
  144. package/server/src/pixelweaver/connections.py +54 -0
  145. package/server/src/pixelweaver/main.py +271 -0
  146. package/server/src/pixelweaver/mcp_bridge.py +189 -0
  147. package/server/src/pixelweaver/mcp_drawing_tools.py +178 -0
  148. package/server/src/pixelweaver/mcp_export_tools.py +291 -0
  149. package/server/src/pixelweaver/mcp_frame_tools.py +423 -0
  150. package/server/src/pixelweaver/mcp_history_tools.py +106 -0
  151. package/server/src/pixelweaver/mcp_layer_tools.py +64 -0
  152. package/server/src/pixelweaver/mcp_lock.py +37 -0
  153. package/server/src/pixelweaver/mcp_project_tools.py +302 -0
  154. package/server/src/pixelweaver/mcp_read_tools.py +163 -0
  155. package/server/src/pixelweaver/mcp_registry.py +247 -0
  156. package/server/src/pixelweaver/mcp_resources.py +312 -0
  157. package/server/src/pixelweaver/mcp_server.py +234 -0
  158. package/server/src/pixelweaver/protocol.py +219 -0
  159. package/server/src/pixelweaver/state.py +267 -0
  160. package/server/src/pixelweaver/storage.py +293 -0
  161. package/server/src/pixelweaver/websocket.py +282 -0
  162. package/server/tests/__init__.py +0 -0
  163. package/server/tests/conftest.py +17 -0
  164. package/server/tests/test_api.py +96 -0
  165. package/server/tests/test_bridge.py +161 -0
  166. package/server/tests/test_health.py +9 -0
  167. package/server/tests/test_integration.py +86 -0
  168. package/server/tests/test_mcp_bridge.py +293 -0
  169. package/server/tests/test_mcp_lock.py +34 -0
  170. package/server/tests/test_mcp_registry.py +679 -0
  171. package/server/tests/test_mcp_resources.py +648 -0
  172. package/server/tests/test_protocol.py +125 -0
  173. package/server/tests/test_state.py +87 -0
  174. package/server/tests/test_storage.py +306 -0
  175. package/server/tests/test_websocket.py +275 -0
  176. package/src/App.svelte +107 -0
  177. package/src/app.css +215 -0
  178. package/src/lib/animation/AnimationPreviewPanel.svelte +667 -0
  179. package/src/lib/animation/animation-commands.test.ts +228 -0
  180. package/src/lib/animation/animation-commands.ts +540 -0
  181. package/src/lib/animation/animation-preview-panel-plugin.ts +25 -0
  182. package/src/lib/animation/animation-preview.svelte.ts +151 -0
  183. package/src/lib/animation/clipboard.ts +134 -0
  184. package/src/lib/animation/frame-model.svelte.ts +437 -0
  185. package/src/lib/animation/frame-model.test.ts +314 -0
  186. package/src/lib/animation/frame-selection.svelte.ts +77 -0
  187. package/src/lib/animation/frame-tags.svelte.ts +238 -0
  188. package/src/lib/animation/frame-tags.test.ts +136 -0
  189. package/src/lib/animation/import.test.ts +141 -0
  190. package/src/lib/animation/import.ts +112 -0
  191. package/src/lib/animation/spritesheet-export.test.ts +239 -0
  192. package/src/lib/animation/spritesheet-export.ts +314 -0
  193. package/src/lib/canvas/CanvasViewport.svelte +216 -0
  194. package/src/lib/canvas/canvas-init-plugin.ts +178 -0
  195. package/src/lib/canvas/canvas-renderer.ts +408 -0
  196. package/src/lib/canvas/canvas-state.svelte.ts +232 -0
  197. package/src/lib/canvas/canvas-state.test.ts +139 -0
  198. package/src/lib/canvas/input-handler.ts +221 -0
  199. package/src/lib/canvas/input-plugin.ts +150 -0
  200. package/src/lib/canvas/onion-skin.ts +94 -0
  201. package/src/lib/canvas/pixel-buffer.test.ts +249 -0
  202. package/src/lib/canvas/pixel-buffer.ts +151 -0
  203. package/src/lib/canvas/render-state.svelte.ts +18 -0
  204. package/src/lib/canvas/shape-preview-state.svelte.ts +36 -0
  205. package/src/lib/canvas/tile-mode.test.ts +53 -0
  206. package/src/lib/canvas/tile-mode.ts +92 -0
  207. package/src/lib/canvas/viewport-utils.ts +24 -0
  208. package/src/lib/canvas/zoom-utils.ts +31 -0
  209. package/src/lib/color/.gitkeep +0 -0
  210. package/src/lib/color/color-commands.ts +87 -0
  211. package/src/lib/color/color-state.svelte.ts +98 -0
  212. package/src/lib/color/color-state.test.ts +91 -0
  213. package/src/lib/color/color-utils.test.ts +220 -0
  214. package/src/lib/color/color-utils.ts +243 -0
  215. package/src/lib/color/palette-state.svelte.ts +127 -0
  216. package/src/lib/color/palette-state.test.ts +154 -0
  217. package/src/lib/color/palette.ts +79 -0
  218. package/src/lib/core/bootstrap.ts +66 -0
  219. package/src/lib/core/command-params.generated.ts +1549 -0
  220. package/src/lib/core/command-params.ts +20 -0
  221. package/src/lib/core/command-runner.ts +79 -0
  222. package/src/lib/core/commands.ts +134 -0
  223. package/src/lib/core/dispatcher.test.ts +548 -0
  224. package/src/lib/core/dispatcher.ts +361 -0
  225. package/src/lib/core/index.test.ts +7 -0
  226. package/src/lib/core/notification-state.svelte.ts +119 -0
  227. package/src/lib/core/plugin-api.ts +210 -0
  228. package/src/lib/core/plugin-discovery.test.ts +53 -0
  229. package/src/lib/core/plugin-discovery.ts +65 -0
  230. package/src/lib/core/plugin-loader.test.ts +159 -0
  231. package/src/lib/core/plugin-loader.ts +240 -0
  232. package/src/lib/core/plugin-types.ts +286 -0
  233. package/src/lib/core/registries.svelte.ts +74 -0
  234. package/src/lib/core/tool-options-state.svelte.ts +61 -0
  235. package/src/lib/dock/DockLayout.svelte +375 -0
  236. package/src/lib/dock/TabAddMenu.svelte +90 -0
  237. package/src/lib/dock/dock-persistence.ts +46 -0
  238. package/src/lib/dock/dock-plugin.ts +49 -0
  239. package/src/lib/dock/dock-presets.ts +156 -0
  240. package/src/lib/dock/dock-state.svelte.ts +77 -0
  241. package/src/lib/dock/dock-types.ts +2 -0
  242. package/src/lib/dock/dockview-theme.css +226 -0
  243. package/src/lib/dock/dockview-theme.ts +17 -0
  244. package/src/lib/dock/header-action-renderer.ts +77 -0
  245. package/src/lib/edit/clipboard-state.ts +34 -0
  246. package/src/lib/export/download.ts +201 -0
  247. package/src/lib/export/png-metadata.ts +181 -0
  248. package/src/lib/history/ActionLogPanel.svelte +418 -0
  249. package/src/lib/history/action-log-panel-plugin.ts +24 -0
  250. package/src/lib/history/action-log.svelte.ts +172 -0
  251. package/src/lib/history/action-log.test.ts +168 -0
  252. package/src/lib/history/history-commands.ts +403 -0
  253. package/src/lib/history/macros.svelte.ts +320 -0
  254. package/src/lib/history/macros.test.ts +224 -0
  255. package/src/lib/history/replay-engine.test.ts +241 -0
  256. package/src/lib/history/replay-engine.ts +149 -0
  257. package/src/lib/history/spec-format.test.ts +250 -0
  258. package/src/lib/history/spec-format.ts +210 -0
  259. package/src/lib/iso/SeamCheckerPanel.svelte +251 -0
  260. package/src/lib/iso/iso-math.test.ts +77 -0
  261. package/src/lib/iso/iso-math.ts +77 -0
  262. package/src/lib/iso/seam-checker-panel-plugin.ts +25 -0
  263. package/src/lib/iso/seam-checker.test.ts +126 -0
  264. package/src/lib/iso/seam-checker.ts +93 -0
  265. package/src/lib/iso/tessellation.ts +67 -0
  266. package/src/lib/layers/compositor.test.ts +193 -0
  267. package/src/lib/layers/compositor.ts +175 -0
  268. package/src/lib/layers/layer-commands.test.ts +263 -0
  269. package/src/lib/layers/layer-commands.ts +429 -0
  270. package/src/lib/layers/layer-tree.svelte.ts +516 -0
  271. package/src/lib/layers/layer-tree.test.ts +383 -0
  272. package/src/lib/layers/layer-types.ts +56 -0
  273. package/src/lib/leveleditor/LevelEditorViewport.svelte +1808 -0
  274. package/src/lib/leveleditor/MapPropertiesPanel.svelte +266 -0
  275. package/src/lib/leveleditor/TilePickerPanel.svelte +324 -0
  276. package/src/lib/leveleditor/depth-sort.test.ts +70 -0
  277. package/src/lib/leveleditor/depth-sort.ts +39 -0
  278. package/src/lib/leveleditor/level-editor-commands.ts +353 -0
  279. package/src/lib/leveleditor/level-editor-viewport-plugin.ts +25 -0
  280. package/src/lib/leveleditor/map-properties-panel-plugin.ts +25 -0
  281. package/src/lib/leveleditor/map-state.svelte.ts +372 -0
  282. package/src/lib/leveleditor/map-state.test.ts +243 -0
  283. package/src/lib/leveleditor/tile-picker-panel-plugin.ts +25 -0
  284. package/src/lib/leveleditor/tile-source-registry.svelte.ts +91 -0
  285. package/src/lib/leveleditor/tiled-export.test.ts +144 -0
  286. package/src/lib/leveleditor/tiled-export.ts +374 -0
  287. package/src/lib/pywebview.d.ts +15 -0
  288. package/src/lib/recovery/.gitkeep +0 -0
  289. package/src/lib/recovery/idb-store.ts +118 -0
  290. package/src/lib/recovery/recovery-manager.test.ts +321 -0
  291. package/src/lib/recovery/recovery-manager.ts +115 -0
  292. package/src/lib/recovery/recovery-plugin.ts +55 -0
  293. package/src/lib/recovery/recovery-state.svelte.ts +21 -0
  294. package/src/lib/recovery/sw-plugin.ts +18 -0
  295. package/src/lib/recovery/sw-register.ts +17 -0
  296. package/src/lib/save/directory-format.ts +42 -0
  297. package/src/lib/save/project-snapshot.ts +139 -0
  298. package/src/lib/save/recent-projects.ts +56 -0
  299. package/src/lib/save/save-state.svelte.ts +35 -0
  300. package/src/lib/save/storage.ts +167 -0
  301. package/src/lib/save/zip-format.ts +45 -0
  302. package/src/lib/shortcuts/.gitkeep +0 -0
  303. package/src/lib/shortcuts/ShortcutEditorPanel.svelte +690 -0
  304. package/src/lib/shortcuts/default-bindings.ts +61 -0
  305. package/src/lib/shortcuts/shortcut-editor-panel-plugin.ts +25 -0
  306. package/src/lib/shortcuts/shortcut-init.ts +380 -0
  307. package/src/lib/shortcuts/shortcut-manager.test.ts +466 -0
  308. package/src/lib/shortcuts/shortcut-manager.ts +281 -0
  309. package/src/lib/shortcuts/shortcut-state.svelte.ts +78 -0
  310. package/src/lib/shortcuts/shortcuts-plugin.ts +17 -0
  311. package/src/lib/sync/patch-applicator.ts +300 -0
  312. package/src/lib/sync/patch-types.ts +65 -0
  313. package/src/lib/sync/project-manager.ts +108 -0
  314. package/src/lib/sync/sync-init.ts +152 -0
  315. package/src/lib/sync/sync-plugin.ts +19 -0
  316. package/src/lib/sync/sync-state.svelte.ts +56 -0
  317. package/src/lib/sync/ws-client.test.ts +604 -0
  318. package/src/lib/sync/ws-client.ts +574 -0
  319. package/src/lib/tools/.gitkeep +0 -0
  320. package/src/lib/ui/.gitkeep +0 -0
  321. package/src/lib/ui/AboutDialog.svelte +113 -0
  322. package/src/lib/ui/ColorPicker.svelte +761 -0
  323. package/src/lib/ui/ContextMenu.svelte +216 -0
  324. package/src/lib/ui/ExportDialog.svelte +747 -0
  325. package/src/lib/ui/FrameStrip.svelte +854 -0
  326. package/src/lib/ui/LayerPanel.svelte +810 -0
  327. package/src/lib/ui/MenuBar.svelte +590 -0
  328. package/src/lib/ui/NewProjectDialog.svelte +803 -0
  329. package/src/lib/ui/PluginManagerPanel.svelte +475 -0
  330. package/src/lib/ui/PromptDialog.svelte +252 -0
  331. package/src/lib/ui/RecoveryDialog.svelte +295 -0
  332. package/src/lib/ui/ResizeDialog.svelte +416 -0
  333. package/src/lib/ui/StatusBar.svelte +145 -0
  334. package/src/lib/ui/ToolbarPanel.svelte +488 -0
  335. package/src/lib/ui/animation-menu-commands.ts +194 -0
  336. package/src/lib/ui/command-palette/CommandPalette.svelte +232 -0
  337. package/src/lib/ui/command-palette/command-palette-plugin.ts +30 -0
  338. package/src/lib/ui/command-palette/command-palette-state.svelte.ts +190 -0
  339. package/src/lib/ui/command-palette/command-palette.test.ts +129 -0
  340. package/src/lib/ui/dialog-state.svelte.ts +70 -0
  341. package/src/lib/ui/edit-commands.ts +271 -0
  342. package/src/lib/ui/file-commands.ts +275 -0
  343. package/src/lib/ui/file-open.ts +99 -0
  344. package/src/lib/ui/help-commands.ts +93 -0
  345. package/src/lib/ui/image-commands.ts +181 -0
  346. package/src/lib/ui/layer-menu-commands.ts +420 -0
  347. package/src/lib/ui/menu-builder.ts +224 -0
  348. package/src/lib/ui/notifications/NotificationBanner.svelte +137 -0
  349. package/src/lib/ui/notifications/notification-plugin.ts +29 -0
  350. package/src/lib/ui/notifications/notification-state.svelte.ts +9 -0
  351. package/src/lib/ui/plugin-manager-panel-plugin.ts +26 -0
  352. package/src/lib/ui/plugin-state.svelte.ts +62 -0
  353. package/src/lib/ui/select-commands.ts +75 -0
  354. package/src/lib/ui/theme-plugin.ts +18 -0
  355. package/src/lib/ui/theme.svelte.ts +45 -0
  356. package/src/lib/ui/theme.test.ts +51 -0
  357. package/src/lib/ui/toolbar-config.ts +90 -0
  358. package/src/lib/ui/toolbar-plugin.ts +39 -0
  359. package/src/lib/ui/view-commands.ts +629 -0
  360. package/src/lib/variants/BisectionExportDialog.svelte +500 -0
  361. package/src/lib/variants/VariantPanel.svelte +822 -0
  362. package/src/lib/variants/bisection-export.test.ts +113 -0
  363. package/src/lib/variants/bisection-export.ts +148 -0
  364. package/src/lib/variants/palette-extraction.test.ts +111 -0
  365. package/src/lib/variants/palette-extraction.ts +84 -0
  366. package/src/lib/variants/palette-interpolation.test.ts +113 -0
  367. package/src/lib/variants/palette-interpolation.ts +87 -0
  368. package/src/lib/variants/palette-swap.test.ts +101 -0
  369. package/src/lib/variants/palette-swap.ts +114 -0
  370. package/src/lib/variants/variant-commands.ts +594 -0
  371. package/src/lib/variants/variant-panel-plugin.ts +27 -0
  372. package/src/lib/variants/variant-randomizer.ts +101 -0
  373. package/src/lib/variants/variant-state.svelte.ts +166 -0
  374. package/src/lib/variants/variant-state.test.ts +138 -0
  375. package/src/main.ts +14 -0
  376. package/src/vite-env.d.ts +3 -0
  377. package/svelte.config.js +2 -0
  378. package/todo/.done/audit-design-decisions.md +812 -0
  379. package/todo/.done/audit-implementation-plan.md +1235 -0
  380. package/todo/.done/happy-path-polish.md +177 -0
  381. package/todo/.done/pixelweaver-full-build.md +937 -0
  382. package/todo/.done/server-multi-frame-design.md +405 -0
  383. package/todo/.done/typed-dispatcher-design.md +435 -0
  384. package/todo/.done/unified-toolbar-and-action-system.md +323 -0
  385. package/todo/.obsolete/comprehensive-audit-obsolete-items.md +33 -0
  386. package/todo/.obsolete/tauri-desktop-bundle.md +424 -0
  387. package/todo/comprehensive-audit.md +1085 -0
  388. package/tsconfig.app.json +26 -0
  389. package/tsconfig.json +7 -0
  390. package/tsconfig.node.json +20 -0
  391. package/uv.lock +1167 -0
  392. package/vite.config.ts +32 -0
@@ -0,0 +1,323 @@
1
+ # Unified Toolbar & Action System
2
+
3
+ ## Context
4
+
5
+ PixelWeaver's current toolbar is a hardcoded 44px vertical strip (`src/lib/ui/ToolBar.svelte`) that sits outside the dockview system. It renders every registered tool from `toolRegistry` in insertion order with no ability to reorder, group, hide, or customize items. It only understands `ToolDefinition` entries -- there is no concept of non-tool toolbar items (zoom, undo/redo, separators).
6
+
7
+ Additionally, there are two overlapping panel registration systems (`PanelDefinition` in `plugin-types.ts` and `DockPanelConfig` in `dock-types.ts`) that serve similar purposes but aren't connected.
8
+
9
+ This plan unifies these systems into a fully data-driven, config-driven UI where:
10
+ - Commands are self-describing (with icons)
11
+ - Toolbars are dockable panels with configurable contents, orientation, thickness, and icon size
12
+ - Multiple toolbars are supported from day one
13
+ - Plugin defaults can be overridden by user config
14
+ - The two panel systems are merged into one
15
+
16
+ ## Design Decisions (locked in)
17
+
18
+ | Decision | Choice |
19
+ |----------|--------|
20
+ | Icon location | On `CommandDefinition` -- single source of truth |
21
+ | Toolbar count | Multi-toolbar from day one |
22
+ | Orientation | Both horizontal and vertical, auto-detected from dock position |
23
+ | Thickness | Configurable items-per-row (1, 2, 3, ...) |
24
+ | Icon size | Configurable per toolbar |
25
+ | Customization model | Plugin-driven defaults + user overrides via config file |
26
+ | Panel systems | Merge `PanelDefinition` and `DockPanelConfig` into a single unified registry |
27
+
28
+ ## Problem
29
+
30
+ 1. **No action abstraction**: Tools, commands, and shortcuts are separate concepts with no shared "action" identity. A pencil tool and an undo command cannot both be toolbar items.
31
+ 2. **Toolbar is not dockable**: Hardcoded in `App.svelte` as a sibling of the dock area. Cannot be moved, resized, or hidden by the user.
32
+ 3. **No toolbar configuration**: No way to specify which items appear, in what order, with what grouping. Every tool is always shown.
33
+ 4. **No structural metadata on tools**: `ToolDefinition` lacks `order`, `group`, `category` fields.
34
+ 5. **Commands lack icons**: `CommandDefinition` has `label` and `category` but no `icon` field, so commands can't self-render in toolbars.
35
+ 6. **Two panel systems**: `PanelDefinition` (plugin-facing, `component: unknown`) and `DockPanelConfig` (dock-internal, `component: Component`) coexist without a bridge.
36
+ 7. **Dockview theme bug**: `themePixelWeaver` is exported but never passed to the `DockviewComponent` constructor, causing dockview's blue-tinted default theme to leak through.
37
+
38
+ ## Solution
39
+
40
+ ### Architecture Overview
41
+
42
+ ```
43
+ ToolbarContribution (plugin-declared)
44
+ |
45
+ v
46
+ toolbarRegistry (reactive SvelteMap)
47
+ |
48
+ v
49
+ ToolbarConfig (merged: plugin defaults + user overrides)
50
+ |
51
+ v
52
+ ToolbarPanel.svelte (generic dockable component)
53
+ |
54
+ reads from:
55
+ - commandRegistry (for command actions + icons)
56
+ - toolRegistry (for tool activators)
57
+ - shortcutRegistry (for keybinding display)
58
+ ```
59
+
60
+ ### New/Modified Types
61
+
62
+ **`CommandDefinition`** -- add `icon` field:
63
+ - `icon?: string | import('svelte').Component` -- optional icon for menus, toolbars, palette
64
+
65
+ **`ToolbarItemKind`** -- union discriminator:
66
+ - `'tool'` -- activates a tool from `toolRegistry`
67
+ - `'command'` -- executes a command from `commandRegistry`
68
+ - `'separator'` -- visual divider
69
+ - `'widget'` -- custom Svelte component (e.g. zoom slider)
70
+
71
+ **`ToolbarContribution`** -- what plugins register:
72
+ - `toolbarId: string` -- which toolbar this item belongs to
73
+ - `kind: ToolbarItemKind`
74
+ - `targetId?: string` -- tool name or command name (not needed for separator/widget)
75
+ - `group: string` -- grouping bucket (items in same group are together, separators between groups)
76
+ - `order: number` -- sort position within group
77
+ - `label?: string` -- override label
78
+ - `icon?: string | Component` -- override icon (falls back to command/tool icon)
79
+ - `widget?: Component` -- Svelte component for `kind: 'widget'`
80
+
81
+ **`ToolbarConfig`** -- per-toolbar configuration:
82
+ - `id: string` -- unique toolbar ID
83
+ - `title: string` -- display title for the dock tab
84
+ - `orientation: 'auto' | 'horizontal' | 'vertical'` -- `auto` detects from dock position
85
+ - `iconSize: number` -- icon dimensions in px (default 20)
86
+ - `thickness: number` -- items per row/column (default 1)
87
+ - `items?: ToolbarContribution[]` -- user overrides (replaces plugin defaults for this toolbar)
88
+ - `closeable?: boolean` -- whether user can close this toolbar (default true)
89
+
90
+ **`PanelConfig`** -- unified panel type (replaces both `PanelDefinition` and `DockPanelConfig`):
91
+ - `id: string`
92
+ - `title: string`
93
+ - `component: Component`
94
+ - `props?: Record<string, unknown>`
95
+ - `position?: 'left' | 'right' | 'bottom' | 'center'`
96
+ - `minWidth?: number`
97
+ - `minHeight?: number`
98
+ - `closeable?: boolean` -- default true
99
+
100
+ ## Phases
101
+
102
+ ### Phase 0: Dockview Theme Fix
103
+
104
+ **Effort**: Trivial (one-liner)
105
+
106
+ **Files changed**:
107
+ - `src/lib/dock/DockLayout.svelte` -- import `themePixelWeaver`, pass to constructor
108
+
109
+ This is a standalone bug fix that should be done first regardless of the rest of the plan.
110
+
111
+ ---
112
+
113
+ ### Phase 1: Merge Panel Systems
114
+
115
+ **Effort**: Small
116
+
117
+ Unify `PanelDefinition` (plugin-types.ts) and `DockPanelConfig` (dock-types.ts) into a single `PanelConfig` type and a single registration path.
118
+
119
+ **Files changed**:
120
+ - `src/lib/core/plugin-types.ts` -- replace `PanelDefinition` with `PanelConfig` (add `closeable`, `props`, `center` position, type `component` as `Component`)
121
+ - `src/lib/dock/dock-types.ts` -- delete `DockPanelConfig`, re-export `PanelConfig` from plugin-types for backward compat or just delete
122
+ - `src/lib/core/registries.svelte.ts` -- `panelRegistry` now stores `PanelConfig`
123
+ - `src/lib/core/plugin-api.ts` -- `addPanel()` now registers into the unified registry used by the dock system
124
+ - `src/lib/dock/dock-state.svelte.ts` -- remove its own `SvelteMap<string, DockPanelConfig>`; read from `panelRegistry` instead. `registerPanel()` becomes a thin wrapper or is removed in favor of `api.addPanel()`
125
+ - `src/lib/dock/dock-plugin.ts` -- switch from `dockState.registerPanel()` to `api.addPanel()`
126
+ - `src/lib/dock/DockLayout.svelte` -- read from `panelRegistry` instead of `dockState.panels`
127
+ - `src/lib/dock/dock-presets.ts` -- update references if needed
128
+ - `src/lib/ui/menu-commands-plugin.ts` -- update `isPanelVisible`/`addPanel`/`removePanel` calls if API changes
129
+
130
+ ---
131
+
132
+ ### Phase 2: Add Icon to CommandDefinition
133
+
134
+ **Effort**: Small-medium
135
+
136
+ Add the `icon` field to `CommandDefinition` and update all existing command registrations to include icons where appropriate.
137
+
138
+ **Files changed**:
139
+ - `src/lib/core/commands.ts` -- add `icon?: string | import('svelte').Component` to `CommandDefinition`
140
+ - `plugins/builtin/effects/blur.ts` -- add icon
141
+ - `plugins/builtin/effects/sharpen.ts` -- add icon
142
+ - `plugins/builtin/effects/glow.ts` -- add icon
143
+ - `plugins/builtin/effects/shadow.ts` -- add icon
144
+ - `plugins/builtin/effects/outline.ts` -- add icon
145
+ - `plugins/builtin/effects/color-effects.ts` -- add icons (invert, grayscale, colorize, brightness_contrast, hue_shift)
146
+ - `plugins/builtin/effects/flip.ts` -- add icon
147
+ - `plugins/builtin/effects/rotate.ts` -- add icon
148
+ - `plugins/builtin/effects/scale.ts` -- add icon
149
+ - `src/lib/ui/menu-commands-plugin.ts` -- add icons to system commands (new_project, open, save, export, undo, redo, zoom_in, zoom_out, zoom_reset, toggle_theme, panel toggles, layout presets, etc.)
150
+ - `plugins/builtin/drawing-primitives-plugin.ts` -- add icons if it registers commands
151
+ - `plugins/builtin/importers/*.ts` -- add icons to importer commands
152
+ - `src/lib/ui/command-palette/command-palette-state.svelte.ts` -- render command icons in palette items
153
+ - `src/lib/ui/menu-builder.ts` -- optionally include icon in menu tree for rendering
154
+ - `src/lib/ui/MenuBar.svelte` -- optionally render command icon next to menu item label
155
+
156
+ ---
157
+
158
+ ### Phase 3: Toolbar Contribution Registry
159
+
160
+ **Effort**: Medium
161
+
162
+ Create the `ToolbarContribution` type, `toolbarRegistry`, and `api.addToolbarItem()` method. Update plugins to declare toolbar contributions.
163
+
164
+ **Files changed**:
165
+ - `src/lib/core/plugin-types.ts` -- add `ToolbarItemKind`, `ToolbarContribution`, `ToolbarConfig` types. Add `addToolbarItem(name: string, contribution: ToolbarContribution): void` to `PluginAPI`
166
+ - `src/lib/core/registries.svelte.ts` -- add `toolbarRegistry = createRegistry<ToolbarContribution>()`
167
+ - `src/lib/core/plugin-api.ts` -- implement `addToolbarItem()` delegating to `toolbarRegistry.set()`
168
+ - All 15 tool plugins (`plugins/builtin/*-tool.ts`) -- each registers a `ToolbarContribution` with `kind: 'tool'`, targeting the default `'drawing-tools'` toolbar
169
+ - `src/lib/ui/menu-commands-plugin.ts` -- register toolbar contributions for undo, redo, zoom_in, zoom_out, zoom_reset in a `'view-controls'` toolbar
170
+
171
+ ---
172
+
173
+ ### Phase 4: ToolbarPanel Component
174
+
175
+ **Effort**: Medium-large
176
+
177
+ Build the generic `ToolbarPanel.svelte` that replaces `ToolBar.svelte`. This is a dockable panel that reads its config and renders items with support for both orientations, configurable thickness, and icon sizes.
178
+
179
+ **Files changed**:
180
+ - `src/lib/ui/ToolbarPanel.svelte` -- new file, the core component:
181
+ - Accepts a `toolbarId` prop
182
+ - Reads contributions from `toolbarRegistry` filtered by `toolbarId`
183
+ - Groups items by `group`, sorts by `order`, inserts separators between groups
184
+ - Renders tool activators, command buttons, separators, and widgets
185
+ - Detects orientation from container aspect ratio (or explicit config)
186
+ - Supports configurable `iconSize` and `thickness` (items per row)
187
+ - Tool activators: highlight active tool, call onDeactivate/setActiveTool/onActivate
188
+ - Command buttons: execute command on click, show tooltip with shortcut
189
+ - Icons resolved from: contribution icon override -> command/tool icon -> fallback
190
+ - `src/lib/ui/ToolBar.svelte` -- delete (replaced by ToolbarPanel)
191
+ - `src/App.svelte` -- remove hardcoded `<ToolBar />` from the layout
192
+
193
+ ---
194
+
195
+ ### Phase 5: Register Toolbars as Dockable Panels
196
+
197
+ **Effort**: Small-medium
198
+
199
+ Create a toolbar dock plugin that registers toolbar panels into the unified panel system, and define default toolbar configurations.
200
+
201
+ **Files changed**:
202
+ - `src/lib/ui/toolbar-plugin.ts` -- new file. Registers:
203
+ - `'drawing-tools'` toolbar panel (position: left, not closeable, thickness: 1, iconSize: 20)
204
+ - `'view-controls'` toolbar panel (position: top or bottom, closeable, thickness: 1, iconSize: 18)
205
+ - Uses `api.addPanel()` to register each as a dockable `PanelConfig` with `component: ToolbarPanel` and `props: { toolbarId: '...' }`
206
+ - `src/lib/dock/dock-presets.ts` -- update presets to include toolbar panels in their layouts
207
+ - `src/lib/ui/menu-commands-plugin.ts` -- add View > Toolbars submenu with toggle commands for each toolbar
208
+
209
+ **Default toolbar contents**:
210
+
211
+ `drawing-tools` (the main tool palette):
212
+
213
+ | Group | Items |
214
+ |-------|-------|
215
+ | draw | pencil, eraser, fill, line |
216
+ | shapes | rect, circle, diamond |
217
+ | select | rect-select, lasso-select |
218
+ | color | eyedropper, gradient, noise, dither |
219
+ | advanced | advanced-fill, pattern-stamp, symmetry |
220
+
221
+ `view-controls` (view/edit actions):
222
+
223
+ | Group | Items |
224
+ |-------|-------|
225
+ | history | undo, redo |
226
+ | zoom | zoom_in, zoom_out, zoom_reset |
227
+
228
+ ---
229
+
230
+ ### Phase 6: Toolbar Configuration Persistence
231
+
232
+ **Effort**: Small-medium
233
+
234
+ Allow user overrides of toolbar configs via a JSON configuration file, persisted alongside the dock layout.
235
+
236
+ **Files changed**:
237
+ - `src/lib/ui/toolbar-config.ts` -- new file:
238
+ - `ToolbarUserConfig` type: `{ toolbars: Record<string, Partial<ToolbarConfig>> }`
239
+ - `loadToolbarConfig()` -- reads from localStorage key `pixelweaver:toolbar-config`
240
+ - `saveToolbarConfig()` -- writes to localStorage
241
+ - `getEffectiveConfig(toolbarId)` -- merges plugin defaults with user overrides
242
+ - `resetToolbarConfig(toolbarId)` -- removes user overrides for a toolbar
243
+ - `src/lib/ui/ToolbarPanel.svelte` -- read effective config instead of raw contributions
244
+ - `src/lib/ui/toolbar-plugin.ts` -- register a "Reset Toolbar" command per toolbar
245
+ - `src/lib/ui/menu-commands-plugin.ts` -- add "Reset Toolbars" menu item under View
246
+
247
+ **Config format** (stored in localStorage, editable via dev tools or future settings UI):
248
+ ```json
249
+ {
250
+ "toolbars": {
251
+ "drawing-tools": {
252
+ "thickness": 2,
253
+ "iconSize": 24,
254
+ "items": [
255
+ { "kind": "tool", "targetId": "pencil", "group": "draw", "order": 10 },
256
+ { "kind": "tool", "targetId": "eraser", "group": "draw", "order": 20 },
257
+ { "kind": "separator", "group": "divider-1", "order": 30 },
258
+ { "kind": "command", "targetId": "undo", "group": "history", "order": 40 }
259
+ ]
260
+ }
261
+ }
262
+ }
263
+ ```
264
+
265
+ ---
266
+
267
+ ### Phase 7: Add Missing Action Icons & Toolbar-Eligible Commands
268
+
269
+ **Effort**: Small
270
+
271
+ Register additional commands that are useful as toolbar items but don't exist yet (fit-to-view, zoom-to-selection, etc.) and ensure all commands that should be toolbar-eligible have icons.
272
+
273
+ **Files changed**:
274
+ - `src/lib/ui/menu-commands-plugin.ts` -- add new commands:
275
+ - `fit_to_view` (icon: lucide/maximize, category: View)
276
+ - `zoom_to_selection` (icon: lucide/scan, category: View)
277
+ - `center_canvas` (icon: lucide/crosshair, category: View)
278
+ - `toggle_grid` (icon: pixelarticons/grid, category: View)
279
+ - `toggle_pixel_grid` (icon: lucide/grid-3x3, category: View)
280
+ - Register toolbar contributions for these in the `view-controls` toolbar
281
+ - Audit all existing commands for missing icons and add them
282
+
283
+ ---
284
+
285
+ ## File Change Summary
286
+
287
+ | File | Phase | Action |
288
+ |------|-------|--------|
289
+ | `src/lib/dock/DockLayout.svelte` | 0 | Fix: pass theme to constructor |
290
+ | `src/lib/core/plugin-types.ts` | 1, 3 | Modify: merge PanelConfig, add toolbar types |
291
+ | `src/lib/dock/dock-types.ts` | 1 | Delete or gut |
292
+ | `src/lib/core/registries.svelte.ts` | 1, 3 | Modify: update panelRegistry type, add toolbarRegistry |
293
+ | `src/lib/core/plugin-api.ts` | 1, 3 | Modify: update addPanel, add addToolbarItem |
294
+ | `src/lib/dock/dock-state.svelte.ts` | 1 | Modify: read from panelRegistry |
295
+ | `src/lib/dock/dock-plugin.ts` | 1 | Modify: use api.addPanel instead of dockState.registerPanel |
296
+ | `src/lib/dock/dock-presets.ts` | 1, 5 | Modify: update references, add toolbar panels |
297
+ | `src/lib/core/commands.ts` | 2 | Modify: add icon field |
298
+ | 9 effect plugin files | 2 | Modify: add icons to commands |
299
+ | 3 importer plugin files | 2 | Modify: add icons to commands |
300
+ | `src/lib/ui/menu-commands-plugin.ts` | 2, 5, 6, 7 | Modify: add icons, toolbar contributions, new commands |
301
+ | `src/lib/ui/command-palette/command-palette-state.svelte.ts` | 2 | Modify: render icons |
302
+ | `src/lib/ui/menu-builder.ts` | 2 | Modify: include icon in tree |
303
+ | `src/lib/ui/MenuBar.svelte` | 2 | Modify: render icons |
304
+ | 15 tool plugin files | 3 | Modify: register toolbar contributions |
305
+ | `src/lib/ui/ToolbarPanel.svelte` | 4 | New file |
306
+ | `src/lib/ui/ToolBar.svelte` | 4 | Delete |
307
+ | `src/App.svelte` | 4 | Modify: remove hardcoded toolbar |
308
+ | `src/lib/ui/toolbar-plugin.ts` | 5 | New file |
309
+ | `src/lib/ui/toolbar-config.ts` | 6 | New file |
310
+ | `plugins/builtin/drawing-primitives-plugin.ts` | 2 | Modify: add icons if applicable |
311
+
312
+ ## Relative Effort
313
+
314
+ | Phase | Effort | Dependencies |
315
+ |-------|--------|-------------|
316
+ | Phase 0: Dockview theme fix | Trivial | None |
317
+ | Phase 1: Merge panel systems | Small | None |
318
+ | Phase 2: Add icon to CommandDefinition | Small-medium | None |
319
+ | Phase 3: Toolbar contribution registry | Medium | Phase 2 (icons exist) |
320
+ | Phase 4: ToolbarPanel component | Medium-large | Phase 3 (registry exists) |
321
+ | Phase 5: Register toolbars as dock panels | Small-medium | Phase 1 (unified panels), Phase 4 (component exists) |
322
+ | Phase 6: Config persistence | Small-medium | Phase 4 (component reads config) |
323
+ | Phase 7: Additional actions & icons | Small | Phase 2, Phase 3 |
@@ -0,0 +1,33 @@
1
+ # Comprehensive Audit -- Obsolete Items
2
+
3
+ **Reason:** These items were specific to the Tauri 2 / FastAPI / uvicorn stack, which has been replaced by wesktop (granian ASGI server + pywebview). They no longer apply to the current architecture.
4
+
5
+ **Source:** Extracted from `todo/comprehensive-audit.md` (audit dated 2026-04-10).
6
+
7
+ ---
8
+
9
+ ## C4. Server: No CORS middleware
10
+
11
+ **Severity:** Critical
12
+ **Impact:** The frontend in Tauri dev mode (`localhost:1420`) cannot reach the server (`localhost:7779`). Showstopper for the intended local-server use case.
13
+
14
+ `server/src/pixelweaver/main.py` has no `CORSMiddleware` configured.
15
+
16
+ **Files to change:** `server/src/pixelweaver/main.py`
17
+ **Effort:** Small -- add `CORSMiddleware` from `starlette.middleware.cors` with appropriate origins.
18
+
19
+ **Why obsolete:** Tauri dev mode is gone. The wesktop architecture serves the frontend through the same granian server, eliminating cross-origin requests entirely. No CORS middleware is needed.
20
+
21
+ ---
22
+
23
+ ## H12. reload=True always on in uvicorn
24
+
25
+ **Severity:** High
26
+ **Impact:** Every Python file save drops all WebSocket connections and wipes in-memory state. No flag to disable.
27
+
28
+ `cli.py:99` hardcodes `reload=True` in the uvicorn configuration.
29
+
30
+ **Files to change:** `server/src/pixelweaver/cli.py`
31
+ **Effort:** Small -- make reload a CLI flag, default to `False` (or `True` only when `--dev` is passed).
32
+
33
+ **Why obsolete:** uvicorn has been replaced by granian via wesktop. The `serve` command now passes `reload` as an explicit CLI flag (`--reload`), and the new `dev` command handles development mode separately. The original hardcoded-reload problem no longer exists.