auvrynt 1.0.2 → 1.0.5
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.
- package/LICENSE +21 -21
- package/README.md +366 -233
- package/addons/auvrynt_bridge/auvrynt_bridge.gd +500 -0
- package/addons/auvrynt_bridge/plugin.cfg +7 -0
- package/bin/auvrynt-launcher.cjs +77 -0
- package/dist/artifact-registry.js +1 -0
- package/dist/aseprite-tools.js +1 -0
- package/dist/auth/connection-registry.js +145 -0
- package/dist/auth/connection-status.js +176 -0
- package/dist/auth/oauth-provider.js +617 -0
- package/dist/auth/room-registry.js +131 -0
- package/dist/auth/session-registry.js +531 -0
- package/dist/background-lifecycle.js +1 -0
- package/dist/blender-client.js +1 -109
- package/dist/blender-tools.js +1 -930
- package/dist/browser-stability.js +1 -0
- package/dist/cli/commands/help-command.js +10 -0
- package/dist/cli/commands/init-command.js +190 -0
- package/dist/cli/commands/integration-commands.js +88 -0
- package/dist/cli/commands/serve-command.js +83 -0
- package/dist/cli/commands/setup-command.js +81 -0
- package/dist/cli/commands/status-commands.js +166 -0
- package/dist/cli/commands/tunnel-command.js +127 -0
- package/dist/cli/commands/user-config-commands.js +105 -0
- package/dist/cli/dashboard-actions.js +516 -0
- package/dist/cli/dashboard-native-actions.js +282 -0
- package/dist/cli/foreground-server.js +270 -0
- package/dist/cli/instance-control.js +21 -0
- package/dist/cli/instance-lock.js +123 -0
- package/dist/cli/integration-bootstrap.js +206 -0
- package/dist/cli/lifecycle-manager.js +493 -0
- package/dist/cli/runtime-support.js +74 -0
- package/dist/cli/serena-detected-default.js +27 -0
- package/dist/cli/tunnel-health-monitor.js +182 -0
- package/dist/cli.js +82 -739
- package/dist/config.js +1 -243
- package/dist/connection-registry.js +1 -73
- package/dist/connection-status.js +1 -139
- package/dist/control-retry.js +1 -0
- package/dist/crash-recovery.js +1 -0
- package/dist/db/client.js +16 -3
- package/dist/db/schema.js +30 -0
- package/dist/dotnet-tools.js +1 -223
- package/dist/git-worktrees.js +1 -134
- package/dist/git.js +1 -41
- package/dist/godot-animation-tilemap.js +1 -82
- package/dist/godot-csharp-build.js +1 -93
- package/dist/godot-csharp-project.js +1 -157
- package/dist/godot-csharp-runner.js +1 -146
- package/dist/godot-csharp-semantic.js +1 -161
- package/dist/godot-csharp-validate.js +1 -71
- package/dist/godot-dotnet-env.js +1 -169
- package/dist/godot-editor-bridge.js +1 -140
- package/dist/godot-gdscript.js +1 -824
- package/dist/godot-project-settings.js +1 -223
- package/dist/godot-runtime-testing.js +1 -249
- package/dist/godot-tools.js +1 -183
- package/dist/http-rate-limit.js +1 -0
- package/dist/http-server-hardening.js +1 -0
- package/dist/image-tools.js +1 -157
- package/dist/infrastructure/command-reference.js +32 -0
- package/dist/infrastructure/config.js +424 -0
- package/dist/infrastructure/context7-auth.js +55 -0
- package/dist/infrastructure/http-rate-limit.js +42 -0
- package/dist/infrastructure/http-server-hardening.js +23 -0
- package/dist/infrastructure/integration-queue.js +46 -0
- package/dist/infrastructure/logger.js +129 -0
- package/dist/infrastructure/mcp-event-store.js +103 -0
- package/dist/infrastructure/ngrok-auth-pool.js +208 -0
- package/dist/infrastructure/request-context.js +14 -0
- package/dist/infrastructure/shutdown.js +37 -0
- package/dist/infrastructure/sse-heartbeat.js +47 -0
- package/dist/infrastructure/tool-capabilities.js +67 -0
- package/dist/infrastructure/tool-result-budget.js +175 -0
- package/dist/infrastructure/user-config.js +167 -0
- package/dist/integration-discovery.js +1 -98
- package/dist/integration-queue.js +1 -0
- package/dist/integrations/agent-reach/agent-reach-tools.js +196 -0
- package/dist/integrations/agent-reach/native-channels.js +468 -0
- package/dist/integrations/aseprite/aseprite-analysis-tools.js +368 -0
- package/dist/integrations/aseprite/aseprite-editing-tools.js +647 -0
- package/dist/integrations/aseprite/aseprite-live-tools.js +297 -0
- package/dist/integrations/aseprite/aseprite-safety-tools.js +594 -0
- package/dist/integrations/aseprite/aseprite-specialized-tools.js +289 -0
- package/dist/integrations/aseprite/aseprite-tools.js +837 -0
- package/dist/integrations/blender/blender-catalog-mesh.js +593 -0
- package/dist/integrations/blender/blender-catalog-object.js +906 -0
- package/dist/integrations/blender/blender-catalog-scene.js +266 -0
- package/dist/integrations/blender/blender-catalog-select.js +581 -0
- package/dist/integrations/blender/blender-catalog-stubs.js +7512 -0
- package/dist/integrations/blender/blender-catalog.js +165 -0
- package/dist/integrations/blender/blender-client.js +105 -0
- package/dist/integrations/blender/blender-tools.js +2243 -0
- package/dist/integrations/context7/context7-tools.js +106 -0
- package/dist/integrations/dotnet/dotnet-tools.js +195 -0
- package/dist/integrations/godot/godot-animation-tilemap.js +74 -0
- package/dist/integrations/godot/godot-csharp-build.js +91 -0
- package/dist/integrations/godot/godot-csharp-project.js +155 -0
- package/dist/integrations/godot/godot-csharp-runner.js +118 -0
- package/dist/integrations/godot/godot-csharp-semantic.js +146 -0
- package/dist/integrations/godot/godot-csharp-validate.js +71 -0
- package/dist/integrations/godot/godot-dotnet-env.js +134 -0
- package/dist/integrations/godot/godot-editor-bridge.js +328 -0
- package/dist/integrations/godot/godot-gdscript.js +536 -0
- package/dist/integrations/godot/godot-project-settings.js +178 -0
- package/dist/integrations/godot/godot-runtime-testing.js +263 -0
- package/dist/integrations/godot/godot-tools.js +193 -0
- package/dist/integrations/images/image-tools.js +414 -0
- package/dist/integrations/images/png-codec.js +251 -0
- package/dist/integrations/images/view-image.js +99 -0
- package/dist/integrations/images/window-capture.js +148 -0
- package/dist/integrations/integration-discovery.js +185 -0
- package/dist/integrations/obsidian/obsidian-tools.js +205 -0
- package/dist/integrations/playwright/browser-session.js +516 -0
- package/dist/integrations/playwright/browser-stability.js +36 -0
- package/dist/integrations/playwright/playwright-runtime.js +105 -0
- package/dist/integrations/playwright/web-tools.js +504 -0
- package/dist/integrations/roblox/roblox-helpers.js +381 -0
- package/dist/integrations/roblox/roblox-studio-client.js +112 -0
- package/dist/integrations/roblox/roblox-tools.js +106 -0
- package/dist/integrations/serena/serena-manager.js +464 -0
- package/dist/integrations/serena/serena-tools.js +411 -0
- package/dist/logger.js +1 -76
- package/dist/mcp-event-store.js +1 -0
- package/dist/oauth-provider.js +1 -377
- package/dist/pi-tools.js +1 -81
- package/dist/playwright-runtime.js +1 -0
- package/dist/process/background-lifecycle.js +189 -0
- package/dist/process/control-retry.js +42 -0
- package/dist/process/crash-recovery.js +23 -0
- package/dist/process/processes.js +456 -0
- package/dist/processes.js +1 -218
- package/dist/request-context.js +1 -0
- package/dist/review-checkpoints.js +1 -142
- package/dist/room-registry.js +1 -0
- package/dist/roots.js +1 -53
- package/dist/search-discovery.js +1 -271
- package/dist/serena-manager.js +1 -443
- package/dist/serena-tools.js +1 -411
- package/dist/server/dashboard-page-styles.js +331 -0
- package/dist/server/dashboard-page.js +1509 -0
- package/dist/server/dashboard-routes.js +46 -0
- package/dist/server/dashboard.js +240 -0
- package/dist/server/http-helpers.js +30 -0
- package/dist/server/integration-profile-update.js +37 -0
- package/dist/server/mcp-policy.js +169 -0
- package/dist/server/mcp-server-factory.js +127 -0
- package/dist/server/mcp-tool-registrar.js +182 -0
- package/dist/server/openai-session-hint.js +14 -0
- package/dist/server/tool-groups.js +29 -0
- package/dist/server/tool-logging.js +33 -0
- package/dist/server/tool-registration-shared.js +59 -0
- package/dist/server/tools/aseprite-advanced-tools-registration.js +547 -0
- package/dist/server/tools/aseprite-tools-registration.js +213 -0
- package/dist/server/tools/blender-tools-registration.js +690 -0
- package/dist/server/tools/core-file-tools-registration.js +459 -0
- package/dist/server/tools/dotnet-godot-window-tools-registration.js +120 -0
- package/dist/server/tools/godot-csharp-tools-registration.js +252 -0
- package/dist/server/tools/godot-gdscript-tools-registration.js +189 -0
- package/dist/server/tools/process-project-tools-registration.js +155 -0
- package/dist/server/tools/roblox-tools-registration.js +514 -0
- package/dist/server/tools/web-image-tools-registration.js +326 -0
- package/dist/server/tools/workspace-lifecycle-tools-registration.js +130 -0
- package/dist/server/ui-assets.js +97 -0
- package/dist/server/workspace-analytics.js +92 -0
- package/dist/server.js +453 -2713
- package/dist/session-registry.js +1 -0
- package/dist/shutdown.js +1 -0
- package/dist/skills.js +1 -45
- package/dist/sse-heartbeat.js +1 -0
- package/dist/tool-capabilities.js +1 -0
- package/dist/tool-result-budget.js +1 -0
- package/dist/tools/pi-tools.js +81 -0
- package/dist/tunnels/cloudflare-tunnel.js +217 -0
- package/dist/tunnels/cloudflared-service.js +174 -0
- package/dist/tunnels/ngrok-tunnel.js +220 -0
- package/dist/tunnels/tunnel-manager.js +186 -0
- package/dist/tunnels/tunnel-types.js +1 -0
- package/dist/tunnels/tunnel-utils.js +62 -0
- package/dist/ui/.vite/manifest.json +9 -2487
- package/dist/ui/assets/heavy-payload-D42A9ceL.js +1 -0
- package/dist/ui/assets/lightweight-diff-Cv4g9Hdr.js +13 -0
- package/dist/ui/assets/review-payload-DKIg1cKF.js +1 -0
- package/dist/ui/assets/workspace-app-CeK3NhmB.css +1 -0
- package/dist/ui/assets/{workspace-app-C5QsE314.js → workspace-app-CkUXnpl4.js} +6 -6
- package/dist/ui/brand-theme.js +23 -0
- package/dist/ui/workspace-app.html +15 -15
- package/dist/user-config.js +1 -57
- package/dist/view-image.js +1 -104
- package/dist/web-tools.js +1 -200
- package/dist/window-capture.js +1 -74
- package/dist/workspace/artifact-registry.js +69 -0
- package/dist/workspace/git-worktrees.js +141 -0
- package/dist/workspace/git.js +42 -0
- package/dist/workspace/review-checkpoints.js +142 -0
- package/dist/workspace/roots.js +56 -0
- package/dist/workspace/search-discovery.js +264 -0
- package/dist/workspace/skills.js +45 -0
- package/dist/workspace/workspace-store.js +219 -0
- package/dist/workspace/workspaces.js +314 -0
- package/dist/workspace-store.js +1 -125
- package/dist/workspaces.js +1 -226
- package/docs/CREATOR_STORE_FREE_ASSETS.md +162 -0
- package/docs/DEVELOPMENT_TOOLS.md +136 -93
- package/docs/assets/auvrynt-icon.png +0 -0
- package/docs/assets/auvrynt-icon.svg +20 -0
- package/docs/chatgpt-coding-workflow.md +143 -143
- package/docs/configuration.md +156 -124
- package/docs/diagnostics.md +79 -0
- package/docs/gotchas.md +244 -202
- package/docs/multi-agent-and-long-projects.md +91 -0
- package/docs/security.md +138 -100
- package/docs/setup.md +171 -131
- package/docs/source-layout.md +60 -0
- package/extensions/auvrynt_bridge/auvrynt_bridge.lua +594 -0
- package/extensions/auvrynt_bridge/live_analysis.lua +181 -0
- package/extensions/auvrynt_bridge/live_animation.lua +134 -0
- package/extensions/auvrynt_bridge/live_commands.lua +24 -0
- package/extensions/auvrynt_bridge/live_common.lua +130 -0
- package/extensions/auvrynt_bridge/live_document.lua +78 -0
- package/extensions/auvrynt_bridge/live_drawing.lua +125 -0
- package/extensions/auvrynt_bridge/live_effects.lua +91 -0
- package/extensions/auvrynt_bridge/live_palette_template.lua +167 -0
- package/extensions/auvrynt_bridge/live_selection.lua +110 -0
- package/extensions/auvrynt_bridge/live_structure.lua +129 -0
- package/extensions/auvrynt_bridge/package.json +17 -0
- package/guides/ASEPRITE_AGENT_GUIDE.md +133 -0
- package/guides/BLENDER_AGENT_GUIDE.md +472 -0
- package/guides/GODOT_AGENT_GUIDE.md +298 -0
- package/guides/PROJECT_ROUTER.md +165 -0
- package/guides/ROBLOX_AGENT_GUIDE.md +75 -0
- package/guides/SOFTWARE_AGENT_GUIDE.md +104 -0
- package/guides/WEB_AGENT_GUIDE.md +287 -0
- package/package.json +78 -70
- package/scripts/dev-server.mjs +121 -120
- package/scripts/live-tunnel-smoke.mjs +538 -0
- package/scripts/repo-hygiene.mjs +74 -0
- package/scripts/restart-after-crash.mjs +49 -0
- package/scripts/run-tests.mjs +166 -0
- package/dist/ui/assets/abap-CLvhMVsD.js +0 -1
- package/dist/ui/assets/actionscript-3--17pq3dv.js +0 -1
- package/dist/ui/assets/ada-C5qYipkI.js +0 -1
- package/dist/ui/assets/andromeeda-vGVdxbeo.js +0 -1
- package/dist/ui/assets/angular-html-BJqQFYI6.js +0 -1
- package/dist/ui/assets/angular-ts-CMJECO0Y.js +0 -1
- package/dist/ui/assets/apache-U0d_L8uA.js +0 -1
- package/dist/ui/assets/apex-CGTLDQj6.js +0 -1
- package/dist/ui/assets/apl-DWeXpBBr.js +0 -1
- package/dist/ui/assets/applescript-CCn79oCD.js +0 -1
- package/dist/ui/assets/ara-4CJ0cIlV.js +0 -1
- package/dist/ui/assets/asciidoc-DE70LPWp.js +0 -1
- package/dist/ui/assets/asm-Cmm7eHzH.js +0 -1
- package/dist/ui/assets/astro-CLbttLOq.js +0 -1
- package/dist/ui/assets/aurora-x-CDeNXAV0.js +0 -1
- package/dist/ui/assets/awk-BWXHIvNe.js +0 -1
- package/dist/ui/assets/ayu-dark-DluEY0Gj.js +0 -1
- package/dist/ui/assets/ayu-light-C3h-C4tm.js +0 -1
- package/dist/ui/assets/ayu-mirage-Bqwy1Gya.js +0 -1
- package/dist/ui/assets/ballerina-B7ZEbQpA.js +0 -1
- package/dist/ui/assets/bat-Bo4NYOV-.js +0 -1
- package/dist/ui/assets/beancount-D-usSTwE.js +0 -1
- package/dist/ui/assets/berry-DKpUyyne.js +0 -1
- package/dist/ui/assets/bibtex-Ci_nEsc7.js +0 -1
- package/dist/ui/assets/bicep-CUHmPFLl.js +0 -1
- package/dist/ui/assets/bird2-C2hNVINV.js +0 -1
- package/dist/ui/assets/blade-BOzY0P2V.js +0 -1
- package/dist/ui/assets/bsl-BkkzgIyY.js +0 -1
- package/dist/ui/assets/c-BG-8uJvh.js +0 -1
- package/dist/ui/assets/c3-CnJL0r0V.js +0 -1
- package/dist/ui/assets/cadence-CQ2zXKGN.js +0 -1
- package/dist/ui/assets/cairo-DLTphjLi.js +0 -1
- package/dist/ui/assets/catppuccin-frappe-3VR1Za6u.js +0 -1
- package/dist/ui/assets/catppuccin-latte-DwIHMF0Q.js +0 -1
- package/dist/ui/assets/catppuccin-macchiato-DYnBP6_5.js +0 -1
- package/dist/ui/assets/catppuccin-mocha-DYhrFGRu.js +0 -1
- package/dist/ui/assets/clarity-SemFz856.js +0 -1
- package/dist/ui/assets/clojure-DqKBuwfJ.js +0 -1
- package/dist/ui/assets/cmake-Bj61d0ZC.js +0 -1
- package/dist/ui/assets/cobol-I_17IuGe.js +0 -1
- package/dist/ui/assets/codeowners-C8r90Shi.js +0 -1
- package/dist/ui/assets/codeql-oeQT6MSM.js +0 -1
- package/dist/ui/assets/coffee-C0B8hmok.js +0 -1
- package/dist/ui/assets/common-lisp-Cv5bFMCO.js +0 -1
- package/dist/ui/assets/coq-BrsZFFmf.js +0 -1
- package/dist/ui/assets/cpp-DDJXt6Vs.js +0 -1
- package/dist/ui/assets/crystal-Bexqace6.js +0 -1
- package/dist/ui/assets/csharp-Ct8U2NOr.js +0 -1
- package/dist/ui/assets/css-DSQhw_9R.js +0 -1
- package/dist/ui/assets/csv-Dx-8-gkx.js +0 -1
- package/dist/ui/assets/cue-CE9AQfxI.js +0 -1
- package/dist/ui/assets/cypher-ClKdZ_lG.js +0 -1
- package/dist/ui/assets/d-qD-0Kul2.js +0 -1
- package/dist/ui/assets/dark-plus-Cs2F2srj.js +0 -1
- package/dist/ui/assets/dart-DkHntEIa.js +0 -1
- package/dist/ui/assets/dax-BkyTk9wS.js +0 -1
- package/dist/ui/assets/desktop-Dlh5hvp9.js +0 -1
- package/dist/ui/assets/diff-woXpYk--.js +0 -1
- package/dist/ui/assets/docker-IyjqRm3v.js +0 -1
- package/dist/ui/assets/dotenv-_5a1GRtc.js +0 -1
- package/dist/ui/assets/dracula-BHWKrbxM.js +0 -1
- package/dist/ui/assets/dracula-soft-5eyTD99u.js +0 -1
- package/dist/ui/assets/dream-maker-DW3nJb8Q.js +0 -1
- package/dist/ui/assets/edge-Z8YYkHOr.js +0 -1
- package/dist/ui/assets/elixir-CG9uKtAF.js +0 -1
- package/dist/ui/assets/elm-GfWG2IfT.js +0 -1
- package/dist/ui/assets/emacs-lisp-C9PiwqqW.js +0 -1
- package/dist/ui/assets/erb-xe89e73J.js +0 -1
- package/dist/ui/assets/erlang-Cphh6RMH.js +0 -1
- package/dist/ui/assets/everforest-dark-sB-x3p7T.js +0 -1
- package/dist/ui/assets/everforest-light-Df2xbC6M.js +0 -1
- package/dist/ui/assets/fennel-DQxkIbk2.js +0 -1
- package/dist/ui/assets/fish-BJitypiv.js +0 -1
- package/dist/ui/assets/fluent-C03EYrpw.js +0 -1
- package/dist/ui/assets/fortran-fixed-form-DEKoE2YW.js +0 -1
- package/dist/ui/assets/fortran-free-form-CYNrtFtB.js +0 -1
- package/dist/ui/assets/fsharp-D13ZGOAj.js +0 -1
- package/dist/ui/assets/gdresource-C0sCabJj.js +0 -1
- package/dist/ui/assets/gdscript-Cp2uCuqX.js +0 -1
- package/dist/ui/assets/gdshader-CBce3t8t.js +0 -1
- package/dist/ui/assets/genie-CV2tkWYe.js +0 -1
- package/dist/ui/assets/gherkin-DExj1W_8.js +0 -1
- package/dist/ui/assets/git-commit-BSykSTBG.js +0 -1
- package/dist/ui/assets/git-rebase-CoTL_uSE.js +0 -1
- package/dist/ui/assets/github-dark-C-LZuMrd.js +0 -1
- package/dist/ui/assets/github-dark-default-DXG-b-1a.js +0 -1
- package/dist/ui/assets/github-dark-dimmed-Bx1FflLF.js +0 -1
- package/dist/ui/assets/github-dark-high-contrast-B_tTalzw.js +0 -1
- package/dist/ui/assets/github-light-EUqPIrTm.js +0 -1
- package/dist/ui/assets/github-light-default-BXViO-2h.js +0 -1
- package/dist/ui/assets/github-light-high-contrast-B68TUdTA.js +0 -1
- package/dist/ui/assets/gleam-CSRkHgEL.js +0 -1
- package/dist/ui/assets/glimmer-js-DAn4UCSu.js +0 -1
- package/dist/ui/assets/glimmer-ts-Tjyi6Gh5.js +0 -1
- package/dist/ui/assets/glsl-CtTDZoqR.js +0 -1
- package/dist/ui/assets/gn-ilITqXS6.js +0 -1
- package/dist/ui/assets/gnuplot-7GGW24-e.js +0 -1
- package/dist/ui/assets/go-BJwz_mda.js +0 -1
- package/dist/ui/assets/graphql-D5gcC_Jk.js +0 -1
- package/dist/ui/assets/groovy-CacY0gHj.js +0 -1
- package/dist/ui/assets/gruvbox-dark-hard-C820rvS2.js +0 -1
- package/dist/ui/assets/gruvbox-dark-medium-BPjhmG05.js +0 -1
- package/dist/ui/assets/gruvbox-dark-soft-MrdJrrXF.js +0 -1
- package/dist/ui/assets/gruvbox-light-hard-BC_s9l72.js +0 -1
- package/dist/ui/assets/gruvbox-light-medium-BAWPOn9u.js +0 -1
- package/dist/ui/assets/gruvbox-light-soft-BSMLrYjP.js +0 -1
- package/dist/ui/assets/hack-BJXY27dt.js +0 -1
- package/dist/ui/assets/haml-BLfFoZf7.js +0 -1
- package/dist/ui/assets/handlebars-Dw6CWkvN.js +0 -1
- package/dist/ui/assets/haskell-D8IpX4py.js +0 -1
- package/dist/ui/assets/haxe-OTjmBuCE.js +0 -1
- package/dist/ui/assets/hcl-Dh228itO.js +0 -1
- package/dist/ui/assets/heavy-payload-Dcg0-F-S.js +0 -4
- package/dist/ui/assets/hjson-CxZEssPk.js +0 -1
- package/dist/ui/assets/hlsl-Cvrh5tZx.js +0 -1
- package/dist/ui/assets/horizon-CE9ld1lL.js +0 -1
- package/dist/ui/assets/horizon-bright-Br1oVSNq.js +0 -1
- package/dist/ui/assets/houston-CsvMBhTu.js +0 -1
- package/dist/ui/assets/html-CAcAWvoN.js +0 -1
- package/dist/ui/assets/html-derivative-8aSW2E_7.js +0 -1
- package/dist/ui/assets/http-B2YR_3V1.js +0 -1
- package/dist/ui/assets/hurl-BnDJ9Zhf.js +0 -1
- package/dist/ui/assets/hxml-B0Qn7Nwc.js +0 -1
- package/dist/ui/assets/hy-CZbG8q4J.js +0 -1
- package/dist/ui/assets/imba-DsUTQ-LC.js +0 -1
- package/dist/ui/assets/ini-B5eOa1yu.js +0 -1
- package/dist/ui/assets/java-Doxi4W8u.js +0 -1
- package/dist/ui/assets/javascript-BbRdEqti.js +0 -1
- package/dist/ui/assets/jinja-CS3Tpv_Q.js +0 -1
- package/dist/ui/assets/jison-BkPGYVHR.js +0 -1
- package/dist/ui/assets/json-BMt1m3m8.js +0 -1
- package/dist/ui/assets/json5-BR5RXkoi.js +0 -1
- package/dist/ui/assets/jsonc-CYpm1nAK.js +0 -1
- package/dist/ui/assets/jsonl-CmCQp5Yx.js +0 -1
- package/dist/ui/assets/jsonnet-CJTPZ8u_.js +0 -1
- package/dist/ui/assets/jssm-DXw9l8Rf.js +0 -1
- package/dist/ui/assets/jsx-CQKrJXXY.js +0 -1
- package/dist/ui/assets/julia-BuN7i2du.js +0 -1
- package/dist/ui/assets/just-BswEPFPu.js +0 -1
- package/dist/ui/assets/kanagawa-dragon-CXtmUGW6.js +0 -1
- package/dist/ui/assets/kanagawa-lotus-BN08jTvb.js +0 -1
- package/dist/ui/assets/kanagawa-wave-CTweb8Dz.js +0 -1
- package/dist/ui/assets/kdl-CsD5j6eV.js +0 -1
- package/dist/ui/assets/kotlin-DhhofPvG.js +0 -1
- package/dist/ui/assets/kusto-BUv0MjJC.js +0 -1
- package/dist/ui/assets/laserwave-C_8bwKvT.js +0 -1
- package/dist/ui/assets/latex-DU2VyFfA.js +0 -1
- package/dist/ui/assets/lean-CewbzKMR.js +0 -1
- package/dist/ui/assets/less-DVTAwKKz.js +0 -1
- package/dist/ui/assets/light-plus-DVQuIRkW.js +0 -1
- package/dist/ui/assets/liquid-Cmz1L3dq.js +0 -1
- package/dist/ui/assets/llvm-Cm23YOpf.js +0 -1
- package/dist/ui/assets/log-BNLmms1o.js +0 -1
- package/dist/ui/assets/logo-Cluzi2Zq.js +0 -1
- package/dist/ui/assets/lua-CfVXhkaJ.js +0 -1
- package/dist/ui/assets/luau-CNKltnaQ.js +0 -1
- package/dist/ui/assets/make-Dixweg8N.js +0 -1
- package/dist/ui/assets/markdown-BYOwaDjH.js +0 -1
- package/dist/ui/assets/marko-C5bfqGiA.js +0 -1
- package/dist/ui/assets/material-theme-Bm3Qr25_.js +0 -1
- package/dist/ui/assets/material-theme-darker-2IIEA8gg.js +0 -1
- package/dist/ui/assets/material-theme-lighter-uhdI0v04.js +0 -1
- package/dist/ui/assets/material-theme-ocean-CHQ94UKr.js +0 -1
- package/dist/ui/assets/material-theme-palenight-B5W6OYN7.js +0 -1
- package/dist/ui/assets/matlab-D7qyCx1q.js +0 -1
- package/dist/ui/assets/mdc-CVBXYfyq.js +0 -1
- package/dist/ui/assets/mdx-DQZ5AkYe.js +0 -1
- package/dist/ui/assets/mermaid-Bk4SNUv9.js +0 -1
- package/dist/ui/assets/min-dark-BSWPekZh.js +0 -1
- package/dist/ui/assets/min-light-DDpmG2fV.js +0 -1
- package/dist/ui/assets/mipsasm-BMqwQI7S.js +0 -1
- package/dist/ui/assets/mojo-BgCJLMeH.js +0 -1
- package/dist/ui/assets/monokai-CdkpiU2Y.js +0 -1
- package/dist/ui/assets/moonbit-CaWjb8XO.js +0 -1
- package/dist/ui/assets/move-B1IS1UjX.js +0 -1
- package/dist/ui/assets/narrat-_X_XdTYD.js +0 -1
- package/dist/ui/assets/nextflow-Bbiyy34d.js +0 -1
- package/dist/ui/assets/nextflow-groovy-Dc_ddanL.js +0 -1
- package/dist/ui/assets/nginx-CzJafxLa.js +0 -1
- package/dist/ui/assets/night-owl-DhmEMT88.js +0 -1
- package/dist/ui/assets/night-owl-light-eJ-hLW7d.js +0 -1
- package/dist/ui/assets/nim-DABKtHtM.js +0 -1
- package/dist/ui/assets/nix-IvuFDN5E.js +0 -1
- package/dist/ui/assets/nord-Cb4Vim4T.js +0 -1
- package/dist/ui/assets/nushell-DcLAeLz5.js +0 -1
- package/dist/ui/assets/objective-c-D1A_Heim.js +0 -1
- package/dist/ui/assets/objective-cpp-BsSzOQcm.js +0 -1
- package/dist/ui/assets/ocaml-O90oeIOV.js +0 -1
- package/dist/ui/assets/odin-B1RWQWA5.js +0 -1
- package/dist/ui/assets/one-dark-pro-CLwyXe_n.js +0 -1
- package/dist/ui/assets/one-light-D7Lr4KcI.js +0 -1
- package/dist/ui/assets/openscad-BUDT5pXO.js +0 -1
- package/dist/ui/assets/pascal-4ZHwLPI5.js +0 -1
- package/dist/ui/assets/perl-CBh7L3lZ.js +0 -1
- package/dist/ui/assets/php-DFbI9q5p.js +0 -1
- package/dist/ui/assets/pierre-dark-sU4Zdns8.js +0 -1
- package/dist/ui/assets/pierre-dark-soft-HXgun5vs.js +0 -1
- package/dist/ui/assets/pierre-light-DWBk51d8.js +0 -1
- package/dist/ui/assets/pierre-light-soft-CodEzPxf.js +0 -1
- package/dist/ui/assets/pkl-ot-7Btpt.js +0 -1
- package/dist/ui/assets/plastic-DQwYfKfQ.js +0 -1
- package/dist/ui/assets/plsql-DGHpHOYJ.js +0 -1
- package/dist/ui/assets/po-BiJDBrnU.js +0 -1
- package/dist/ui/assets/poimandres-DRFjx7u4.js +0 -1
- package/dist/ui/assets/polar-C7UOKdEL.js +0 -1
- package/dist/ui/assets/postcss-BXeXVLqQ.js +0 -1
- package/dist/ui/assets/powerquery-DNMTfnFr.js +0 -1
- package/dist/ui/assets/powershell-DshXNtvi.js +0 -1
- package/dist/ui/assets/prisma-BsRQq5mF.js +0 -1
- package/dist/ui/assets/prolog-iXnhIJG7.js +0 -1
- package/dist/ui/assets/proto-DB4EqR-F.js +0 -1
- package/dist/ui/assets/pug-C_PxC7gO.js +0 -1
- package/dist/ui/assets/puppet-CDv2pdJW.js +0 -1
- package/dist/ui/assets/purescript-9MfHhQsQ.js +0 -1
- package/dist/ui/assets/python-gzcpVVnB.js +0 -1
- package/dist/ui/assets/qml-DtngoFFK.js +0 -1
- package/dist/ui/assets/qmldir-DCQb3MpD.js +0 -1
- package/dist/ui/assets/qss-Fe1Jh2GI.js +0 -1
- package/dist/ui/assets/r-DohkcevW.js +0 -1
- package/dist/ui/assets/racket-DcIDlBhZ.js +0 -1
- package/dist/ui/assets/raku-B3gFvitq.js +0 -1
- package/dist/ui/assets/razor-C4t8J0_E.js +0 -1
- package/dist/ui/assets/red-CJ3rzSJv.js +0 -1
- package/dist/ui/assets/reg-CRGYupPL.js +0 -1
- package/dist/ui/assets/regexp-OGbTbjgY.js +0 -1
- package/dist/ui/assets/rel-BtDbiS_P.js +0 -1
- package/dist/ui/assets/review-payload-C5Qz60Kq.js +0 -1
- package/dist/ui/assets/riscv-Ckw8ddFX.js +0 -1
- package/dist/ui/assets/ron-VUp2lXgN.js +0 -1
- package/dist/ui/assets/rose-pine-BthvhNj6.js +0 -1
- package/dist/ui/assets/rose-pine-dawn-Dg85fqjY.js +0 -1
- package/dist/ui/assets/rose-pine-moon-hon4tzzS.js +0 -1
- package/dist/ui/assets/rosmsg-CAekHB0j.js +0 -1
- package/dist/ui/assets/rst-CfBbbcvC.js +0 -1
- package/dist/ui/assets/ruby-Bw0mpxHY.js +0 -1
- package/dist/ui/assets/rust-Cfkwpbl8.js +0 -1
- package/dist/ui/assets/sas-Cs3s9JOf.js +0 -1
- package/dist/ui/assets/sass-DXrisJhu.js +0 -1
- package/dist/ui/assets/scala-DKOlJaKm.js +0 -1
- package/dist/ui/assets/scheme-DQCgrYNe.js +0 -1
- package/dist/ui/assets/scss-sRxNJS54.js +0 -1
- package/dist/ui/assets/sdbl-bTVj8UrX.js +0 -1
- package/dist/ui/assets/shaderlab-TOUzSsQk.js +0 -1
- package/dist/ui/assets/shellscript-B0X6wh0R.js +0 -1
- package/dist/ui/assets/shellsession-D2FdOioR.js +0 -1
- package/dist/ui/assets/slack-dark-DnToyrRv.js +0 -1
- package/dist/ui/assets/slack-ochin-B2OO5cIa.js +0 -1
- package/dist/ui/assets/smalltalk-B16xEiuN.js +0 -1
- package/dist/ui/assets/snazzy-light-4G7pJPwS.js +0 -1
- package/dist/ui/assets/solarized-dark-DV17i1UV.js +0 -1
- package/dist/ui/assets/solarized-light-DSh2HLQt.js +0 -1
- package/dist/ui/assets/solidity-CKzVLygQ.js +0 -1
- package/dist/ui/assets/soy-s6g9OjJ1.js +0 -1
- package/dist/ui/assets/sparql-D_iOobhT.js +0 -1
- package/dist/ui/assets/splunk-BC2Px7Mm.js +0 -1
- package/dist/ui/assets/sql-DVTnh5V-.js +0 -1
- package/dist/ui/assets/ssh-config-BgfXC-Er.js +0 -1
- package/dist/ui/assets/stata-DFIDiXF9.js +0 -1
- package/dist/ui/assets/stylus-B6D30XZt.js +0 -1
- package/dist/ui/assets/surrealql-DVfrsLyg.js +0 -1
- package/dist/ui/assets/svelte-D5GsxESq.js +0 -1
- package/dist/ui/assets/swift-DonLKvLd.js +0 -1
- package/dist/ui/assets/synthwave-84-nFMaYfgc.js +0 -1
- package/dist/ui/assets/system-verilog-DJ5XKQeo.js +0 -1
- package/dist/ui/assets/systemd-BxMlprV5.js +0 -1
- package/dist/ui/assets/talonscript-CohzipZa.js +0 -1
- package/dist/ui/assets/tasl-DMoTqEGO.js +0 -1
- package/dist/ui/assets/tcl-CZd0xW_V.js +0 -1
- package/dist/ui/assets/templ-DI-Zyqzd.js +0 -1
- package/dist/ui/assets/terraform-DswuEJGm.js +0 -1
- package/dist/ui/assets/tex-WHHmlbJI.js +0 -1
- package/dist/ui/assets/tokyo-night-oM2G3aXe.js +0 -1
- package/dist/ui/assets/toml-CcmNWLt0.js +0 -1
- package/dist/ui/assets/ts-tags-Dwpo2RFJ.js +0 -1
- package/dist/ui/assets/tsv-sltzmVWM.js +0 -1
- package/dist/ui/assets/tsx-ph_idaAW.js +0 -1
- package/dist/ui/assets/turtle-ByJddavk.js +0 -1
- package/dist/ui/assets/twig-YO17jFjR.js +0 -1
- package/dist/ui/assets/typescript-CbAxjhkl.js +0 -1
- package/dist/ui/assets/typespec-B88KGewJ.js +0 -1
- package/dist/ui/assets/typst-DI99ib-x.js +0 -1
- package/dist/ui/assets/useFileDiffInstance-B2DLX3Vg.js +0 -244
- package/dist/ui/assets/v-DETTlOr0.js +0 -1
- package/dist/ui/assets/vala-zf12oZj6.js +0 -1
- package/dist/ui/assets/vb-Djn5o6TS.js +0 -1
- package/dist/ui/assets/verilog-CiiDBU1e.js +0 -1
- package/dist/ui/assets/vesper-D5bVUKB1.js +0 -1
- package/dist/ui/assets/vhdl-BroJfC0k.js +0 -1
- package/dist/ui/assets/viml-DvXPmvsu.js +0 -1
- package/dist/ui/assets/vitesse-black-fwtXNY1n.js +0 -1
- package/dist/ui/assets/vitesse-dark-BZCL-v6S.js +0 -1
- package/dist/ui/assets/vitesse-light-VbXTXTou.js +0 -1
- package/dist/ui/assets/vue-CraHL-Ps.js +0 -1
- package/dist/ui/assets/vue-html-e9tyZNtS.js +0 -1
- package/dist/ui/assets/vue-vine-CofmxaUb.js +0 -1
- package/dist/ui/assets/vyper-CgoNMtux.js +0 -1
- package/dist/ui/assets/wasm-BnjxR4X6.js +0 -1
- package/dist/ui/assets/wasm-ByWQv1Qj.js +0 -1
- package/dist/ui/assets/wenyan-C8pVoKbM.js +0 -1
- package/dist/ui/assets/wgsl-BsKzXJz4.js +0 -1
- package/dist/ui/assets/wikitext-ClFFjSW2.js +0 -1
- package/dist/ui/assets/wit-DdvCle-K.js +0 -1
- package/dist/ui/assets/wolfram-DLL8P-h_.js +0 -1
- package/dist/ui/assets/workspace-app-8--oTbCd.css +0 -1
- package/dist/ui/assets/xml-BWSdPZHm.js +0 -1
- package/dist/ui/assets/xsl-BtCt7Hx8.js +0 -1
- package/dist/ui/assets/yaml-BZiTw7cQ.js +0 -1
- package/dist/ui/assets/zenscript-BnlCZFoB.js +0 -1
- package/dist/ui/assets/zig-CMLA9XwU.js +0 -1
- package/docs/assets/auvrynt-logo-light.png +0 -0
- package/docs/assets/auvrynt-screenshot.png +0 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
local C = require("live_common")
|
|
2
|
+
local M = {}
|
|
3
|
+
|
|
4
|
+
local function draw_symmetry(sprite, params)
|
|
5
|
+
local count = C.sequence_length(params.points)
|
|
6
|
+
if not count or count < 1 or count > 8192 then C.fail("points must contain 1-8192 entries") end
|
|
7
|
+
if type(params.color) ~= "string" then C.fail("color is required") end
|
|
8
|
+
local layer, frame_number = C.active_target(sprite, params)
|
|
9
|
+
local pixel = C.color_to_pixel(sprite, C.color_from_hex(params.color))
|
|
10
|
+
local axis_x = tonumber(params.axisX) or ((sprite.width - 1) / 2)
|
|
11
|
+
local axis_y = tonumber(params.axisY) or ((sprite.height - 1) / 2)
|
|
12
|
+
local mirror_x = params.horizontal ~= false
|
|
13
|
+
local mirror_y = params.vertical == true
|
|
14
|
+
local coordinates, unique = {}, {}
|
|
15
|
+
local function add(x, y)
|
|
16
|
+
x, y = C.integer(x, -1), C.integer(y, -1)
|
|
17
|
+
if x < 0 or y < 0 or x >= sprite.width or y >= sprite.height then return end
|
|
18
|
+
local key = x .. ":" .. y
|
|
19
|
+
if unique[key] then return end
|
|
20
|
+
unique[key] = true
|
|
21
|
+
coordinates[#coordinates+1] = {x=x,y=y}
|
|
22
|
+
end
|
|
23
|
+
for index=1,count do
|
|
24
|
+
local point = params.points[index]
|
|
25
|
+
local x, y = C.integer(point.x, -1), C.integer(point.y, -1)
|
|
26
|
+
add(x, y)
|
|
27
|
+
if mirror_x then add(math.floor(2*axis_x-x+0.5), y) end
|
|
28
|
+
if mirror_y then add(x, math.floor(2*axis_y-y+0.5)) end
|
|
29
|
+
if mirror_x and mirror_y then add(math.floor(2*axis_x-x+0.5), math.floor(2*axis_y-y+0.5)) end
|
|
30
|
+
end
|
|
31
|
+
local written = 0
|
|
32
|
+
app.transaction("Auvrynt Live Symmetry", function()
|
|
33
|
+
local cel = C.get_canvas_cel(sprite, layer, frame_number, true)
|
|
34
|
+
for _, point in ipairs(coordinates) do
|
|
35
|
+
if C.selection_allows(sprite, point.x, point.y) then
|
|
36
|
+
cel.image:drawPixel(point.x, point.y, pixel)
|
|
37
|
+
written = written + 1
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end)
|
|
41
|
+
return { written=written, layer=layer.name, frame=frame_number, axisX=axis_x, axisY=axis_y, horizontal=mirror_x, vertical=mirror_y }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
local BAYER = {
|
|
45
|
+
[2]={0,2,3,1},
|
|
46
|
+
[4]={0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5},
|
|
47
|
+
[8]={
|
|
48
|
+
0,32,8,40,2,34,10,42,48,16,56,24,50,18,58,26,
|
|
49
|
+
12,44,4,36,14,46,6,38,60,28,52,20,62,30,54,22,
|
|
50
|
+
3,35,11,43,1,33,9,41,51,19,59,27,49,17,57,25,
|
|
51
|
+
15,47,7,39,13,45,5,37,63,31,55,23,61,29,53,21,
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
local function apply_dither(sprite, params)
|
|
56
|
+
if type(params.colorA) ~= "string" or type(params.colorB) ~= "string" then C.fail("colorA and colorB are required") end
|
|
57
|
+
local matrix_size = C.integer(params.matrixSize, 4)
|
|
58
|
+
if not BAYER[matrix_size] then C.fail("matrixSize must be 2, 4, or 8") end
|
|
59
|
+
local amount = C.clamp(tonumber(params.amount) or 0.5, 0, 1)
|
|
60
|
+
local region = params.region or {}
|
|
61
|
+
local x = C.clamp(C.integer(region.x, 0), 0, sprite.width-1)
|
|
62
|
+
local y = C.clamp(C.integer(region.y, 0), 0, sprite.height-1)
|
|
63
|
+
local width = C.clamp(C.integer(region.width, sprite.width-x), 1, sprite.width-x)
|
|
64
|
+
local height = C.clamp(C.integer(region.height, sprite.height-y), 1, sprite.height-y)
|
|
65
|
+
local layer, frame_number = C.active_target(sprite, params)
|
|
66
|
+
local a = C.color_to_pixel(sprite, C.color_from_hex(params.colorA))
|
|
67
|
+
local b = C.color_to_pixel(sprite, C.color_from_hex(params.colorB))
|
|
68
|
+
local matrix = BAYER[matrix_size]
|
|
69
|
+
local changed = 0
|
|
70
|
+
app.transaction("Auvrynt Live Ordered Dither", function()
|
|
71
|
+
local cel = C.get_canvas_cel(sprite, layer, frame_number, true)
|
|
72
|
+
for yy=y,y+height-1 do
|
|
73
|
+
for xx=x,x+width-1 do
|
|
74
|
+
if C.selection_allows(sprite, xx, yy) then
|
|
75
|
+
local index = (yy % matrix_size) * matrix_size + (xx % matrix_size) + 1
|
|
76
|
+
local threshold = (matrix[index] + 0.5) / (matrix_size * matrix_size)
|
|
77
|
+
cel.image:drawPixel(xx, yy, threshold < amount and b or a)
|
|
78
|
+
changed = changed + 1
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end)
|
|
83
|
+
return { changed=changed, matrixSize=matrix_size, amount=amount, region={x=x,y=y,width=width,height=height}, layer=layer.name, frame=frame_number }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
M.handlers = {
|
|
87
|
+
draw_symmetry=draw_symmetry,
|
|
88
|
+
apply_dither=apply_dither,
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return M
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
local C = require("live_common")
|
|
2
|
+
local M = {}
|
|
3
|
+
|
|
4
|
+
local function get_palette(sprite, _)
|
|
5
|
+
local palette = sprite.palettes[1]
|
|
6
|
+
local colors = {}
|
|
7
|
+
for index=0,#palette-1 do
|
|
8
|
+
local color = palette:getColor(index)
|
|
9
|
+
local alpha = index == sprite.transparentColor and 0 or color.alpha
|
|
10
|
+
colors[index+1] = C.color_to_hex(Color{r=color.red,g=color.green,b=color.blue,a=alpha})
|
|
11
|
+
end
|
|
12
|
+
return { size=#palette, transparentIndex=sprite.transparentColor, colors=colors }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
local function set_palette_color(sprite, params)
|
|
16
|
+
if type(params.color) ~= "string" then C.fail("color is required") end
|
|
17
|
+
local palette = sprite.palettes[1]
|
|
18
|
+
local index = C.integer(params.index, -1)
|
|
19
|
+
if index < 0 or index > 255 then C.fail("Palette index must be between 0 and 255") end
|
|
20
|
+
app.transaction("Auvrynt Live Palette Entry", function()
|
|
21
|
+
if index >= #palette then palette:resize(index + 1) end
|
|
22
|
+
palette:setColor(index, C.color_from_hex(params.color))
|
|
23
|
+
end)
|
|
24
|
+
return { index=index, color=C.color_to_hex(palette:getColor(index)), size=#palette }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
local function set_palette(sprite, params)
|
|
28
|
+
local count = C.sequence_length(params.colors)
|
|
29
|
+
if not count or count < 1 or count > 256 then C.fail("colors must contain 1-256 entries") end
|
|
30
|
+
local palette = sprite.palettes[1]
|
|
31
|
+
app.transaction("Auvrynt Live Set Palette", function()
|
|
32
|
+
palette:resize(count)
|
|
33
|
+
for index=1,count do palette:setColor(index - 1, C.color_from_hex(params.colors[index])) end
|
|
34
|
+
end)
|
|
35
|
+
return get_palette(sprite, {})
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
local function generate_color_ramp(sprite, params)
|
|
39
|
+
if type(params.startColor) ~= "string" or type(params.endColor) ~= "string" then C.fail("startColor and endColor are required") end
|
|
40
|
+
local start, finish = C.color_from_hex(params.startColor), C.color_from_hex(params.endColor)
|
|
41
|
+
local steps = C.clamp(C.integer(params.steps, 5), 2, 256)
|
|
42
|
+
local colors = {}
|
|
43
|
+
for index=0,steps-1 do
|
|
44
|
+
local t = index / (steps - 1)
|
|
45
|
+
colors[index+1] = C.color_to_hex(Color {
|
|
46
|
+
r=math.floor(start.red + (finish.red-start.red)*t + 0.5),
|
|
47
|
+
g=math.floor(start.green + (finish.green-start.green)*t + 0.5),
|
|
48
|
+
b=math.floor(start.blue + (finish.blue-start.blue)*t + 0.5),
|
|
49
|
+
a=math.floor(start.alpha + (finish.alpha-start.alpha)*t + 0.5),
|
|
50
|
+
})
|
|
51
|
+
end
|
|
52
|
+
if params.apply == true then
|
|
53
|
+
local palette, start_index = sprite.palettes[1], C.clamp(C.integer(params.startIndex, 0), 0, 255)
|
|
54
|
+
if start_index + steps > 256 then C.fail("Color ramp exceeds the 256-entry palette limit") end
|
|
55
|
+
app.transaction("Auvrynt Live Color Ramp", function()
|
|
56
|
+
if #palette < start_index + steps then palette:resize(start_index + steps) end
|
|
57
|
+
for index=1,steps do palette:setColor(start_index + index - 1, C.color_from_hex(colors[index])) end
|
|
58
|
+
end)
|
|
59
|
+
end
|
|
60
|
+
return { colors=colors, steps=steps, applied=params.apply == true }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
local function sort_palette(sprite, params)
|
|
64
|
+
local palette = sprite.palettes[1]
|
|
65
|
+
local sort_by = tostring(params.sortBy or "hue")
|
|
66
|
+
local reverse = params.reverse == true
|
|
67
|
+
local entries = {}
|
|
68
|
+
for index=0,#palette-1 do
|
|
69
|
+
local color = palette:getColor(index)
|
|
70
|
+
entries[#entries+1] = { old=index, color=color }
|
|
71
|
+
end
|
|
72
|
+
local function value(entry)
|
|
73
|
+
local color = entry.color
|
|
74
|
+
if sort_by == "hue" then return color.hslHue
|
|
75
|
+
elseif sort_by == "saturation" then return color.hslSaturation
|
|
76
|
+
elseif sort_by == "lightness" or sort_by == "brightness" then return color.hslLightness
|
|
77
|
+
elseif sort_by == "red" then return color.red
|
|
78
|
+
elseif sort_by == "green" then return color.green
|
|
79
|
+
elseif sort_by == "blue" then return color.blue
|
|
80
|
+
elseif sort_by == "alpha" then return color.alpha
|
|
81
|
+
else C.fail("sortBy must be hue, saturation, lightness, brightness, red, green, blue, or alpha") end
|
|
82
|
+
end
|
|
83
|
+
table.sort(entries, function(a, b)
|
|
84
|
+
local av, bv = value(a), value(b)
|
|
85
|
+
if av == bv then return a.old < b.old end
|
|
86
|
+
return reverse and av > bv or av < bv
|
|
87
|
+
end)
|
|
88
|
+
local mapping = {}
|
|
89
|
+
for new_index, entry in ipairs(entries) do mapping[entry.old] = new_index - 1 end
|
|
90
|
+
local old_transparent = sprite.transparentColor
|
|
91
|
+
app.transaction("Auvrynt Live Sort Palette", function()
|
|
92
|
+
if sprite.colorMode == ColorMode.INDEXED then
|
|
93
|
+
local seen = {}
|
|
94
|
+
for _, cel in ipairs(sprite.cels) do
|
|
95
|
+
if not cel.layer.isTilemap then
|
|
96
|
+
local image = cel.image
|
|
97
|
+
local key = tostring(image.id)
|
|
98
|
+
if not seen[key] then
|
|
99
|
+
seen[key] = true
|
|
100
|
+
for y=0,image.height-1 do
|
|
101
|
+
for x=0,image.width-1 do
|
|
102
|
+
local old = image:getPixel(x, y)
|
|
103
|
+
image:drawPixel(x, y, mapping[old] or old)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
for new_index, entry in ipairs(entries) do palette:setColor(new_index - 1, entry.color) end
|
|
111
|
+
if sprite.colorMode == ColorMode.INDEXED then sprite.transparentColor = mapping[old_transparent] or old_transparent end
|
|
112
|
+
end)
|
|
113
|
+
local result = get_palette(sprite, {})
|
|
114
|
+
result.sortBy = sort_by
|
|
115
|
+
result.reverse = reverse
|
|
116
|
+
return result
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
local function create_character_template(_, params)
|
|
120
|
+
local width = C.clamp(C.integer(params.width, params.size or 64), 8, 512)
|
|
121
|
+
local height = C.clamp(C.integer(params.height, params.size or 64), 8, 512)
|
|
122
|
+
local sprite = Sprite(width, height, ColorMode.RGB)
|
|
123
|
+
app.activeSprite = sprite
|
|
124
|
+
local definitions = params.animations
|
|
125
|
+
local count = C.sequence_length(definitions)
|
|
126
|
+
if not count or count == 0 then
|
|
127
|
+
definitions = {
|
|
128
|
+
{ name="idle", frames=4, durationMs=140 },
|
|
129
|
+
{ name="run", frames=8, durationMs=90 },
|
|
130
|
+
{ name="attack", frames=6, durationMs=80 },
|
|
131
|
+
}
|
|
132
|
+
count = 3
|
|
133
|
+
end
|
|
134
|
+
local total_frames = 0
|
|
135
|
+
for index=1,count do total_frames = total_frames + C.clamp(C.integer(definitions[index].frames, 1), 1, 64) end
|
|
136
|
+
app.transaction("Auvrynt Character Template", function()
|
|
137
|
+
sprite.layers[1].name = "04 Body"
|
|
138
|
+
local shadow = sprite:newLayer() shadow.name = "01 Shadow" shadow.stackIndex = 1 shadow.opacity = 128
|
|
139
|
+
local silhouette = sprite:newLayer() silhouette.name = "02 Silhouette"
|
|
140
|
+
local outfit = sprite:newLayer() outfit.name = "03 Outfit"
|
|
141
|
+
local weapon = sprite:newLayer() weapon.name = "05 Weapon"
|
|
142
|
+
local effects = sprite:newLayer() effects.name = "06 Effects"
|
|
143
|
+
for frame=2,total_frames do sprite:newEmptyFrame(frame) end
|
|
144
|
+
local offset = 1
|
|
145
|
+
for index=1,count do
|
|
146
|
+
local definition = definitions[index]
|
|
147
|
+
local frames = C.clamp(C.integer(definition.frames, 1), 1, 64)
|
|
148
|
+
local duration = C.clamp(C.integer(definition.durationMs, 100), 1, 60000) / 1000
|
|
149
|
+
local tag = sprite:newTag(offset, offset + frames - 1)
|
|
150
|
+
tag.name = tostring(definition.name or ("animation_" .. index))
|
|
151
|
+
for frame=offset,offset+frames-1 do sprite.frames[frame].duration = duration end
|
|
152
|
+
offset = offset + frames
|
|
153
|
+
end
|
|
154
|
+
end)
|
|
155
|
+
return { id=tostring(sprite.id), width=width, height=height, frames=#sprite.frames, tags=#sprite.tags }
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
M.handlers = {
|
|
159
|
+
get_palette=get_palette,
|
|
160
|
+
set_palette_color=set_palette_color,
|
|
161
|
+
set_palette=set_palette,
|
|
162
|
+
generate_color_ramp=generate_color_ramp,
|
|
163
|
+
sort_palette=sort_palette,
|
|
164
|
+
create_character_template=create_character_template,
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return M
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
local C = require("live_common")
|
|
2
|
+
local M = {}
|
|
3
|
+
|
|
4
|
+
local function apply_mask(sprite, mask, mode)
|
|
5
|
+
local selection = sprite.selection
|
|
6
|
+
mode = mode or "replace"
|
|
7
|
+
if mode == "replace" then selection:select(mask)
|
|
8
|
+
elseif mode == "add" then selection:add(mask)
|
|
9
|
+
elseif mode == "subtract" then selection:subtract(mask)
|
|
10
|
+
elseif mode == "intersect" then selection:intersect(mask)
|
|
11
|
+
else C.fail("Unsupported selection mode") end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
local function selection_result(sprite)
|
|
15
|
+
local selection = sprite.selection
|
|
16
|
+
if not selection or selection.isEmpty then return { empty=true } end
|
|
17
|
+
local bounds = selection.bounds
|
|
18
|
+
return {
|
|
19
|
+
empty=false,
|
|
20
|
+
x=bounds.x,
|
|
21
|
+
y=bounds.y,
|
|
22
|
+
width=bounds.width,
|
|
23
|
+
height=bounds.height,
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
local function get_selection(sprite, _)
|
|
28
|
+
return selection_result(sprite)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
local function select_all(sprite, _)
|
|
32
|
+
sprite.selection:selectAll()
|
|
33
|
+
return selection_result(sprite)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
local function deselect(sprite, _)
|
|
37
|
+
sprite.selection:deselect()
|
|
38
|
+
return { empty=true }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
local function invert_selection(sprite, _)
|
|
42
|
+
local inverted = Selection(Rectangle(0, 0, sprite.width, sprite.height))
|
|
43
|
+
if not sprite.selection.isEmpty then inverted:subtract(sprite.selection) end
|
|
44
|
+
sprite.selection:select(inverted)
|
|
45
|
+
return selection_result(sprite)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
local function select_ellipse(sprite, params)
|
|
49
|
+
local x = C.integer(params.x, 0)
|
|
50
|
+
local y = C.integer(params.y, 0)
|
|
51
|
+
local width = C.integer(params.width, 1)
|
|
52
|
+
local height = C.integer(params.height, 1)
|
|
53
|
+
if width < 1 or height < 1 then C.fail("width and height must be positive") end
|
|
54
|
+
local mask = Selection()
|
|
55
|
+
local rx, ry = width / 2, height / 2
|
|
56
|
+
local cx = x + (width - 1) / 2
|
|
57
|
+
local cy = y + (height - 1) / 2
|
|
58
|
+
for row=0,height-1 do
|
|
59
|
+
local dy = ((y + row) - cy) / ry
|
|
60
|
+
local inside = 1 - dy * dy
|
|
61
|
+
if inside >= 0 then
|
|
62
|
+
local half = math.floor(rx * math.sqrt(inside))
|
|
63
|
+
local left = math.max(0, math.floor(cx - half))
|
|
64
|
+
local right = math.min(sprite.width - 1, math.ceil(cx + half))
|
|
65
|
+
local yy = y + row
|
|
66
|
+
if yy >= 0 and yy < sprite.height and right >= left then
|
|
67
|
+
mask:add(Rectangle(left, yy, right - left + 1, 1))
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
apply_mask(sprite, mask, params.mode)
|
|
72
|
+
return selection_result(sprite)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
local function select_by_color(sprite, params)
|
|
76
|
+
if type(params.color) ~= "string" then C.fail("color is required") end
|
|
77
|
+
if sprite.width * sprite.height > 1048576 then C.fail("Color selection is limited to 1,048,576 canvas pixels") end
|
|
78
|
+
local image = C.read_canvas(sprite, params)
|
|
79
|
+
local target = C.color_to_pixel(sprite, C.color_from_hex(params.color))
|
|
80
|
+
local mask = Selection()
|
|
81
|
+
local matched = 0
|
|
82
|
+
for y=0,sprite.height-1 do
|
|
83
|
+
local run_start = nil
|
|
84
|
+
for x=0,sprite.width do
|
|
85
|
+
local equal = x < sprite.width and image:getPixel(x, y) == target
|
|
86
|
+
if equal and run_start == nil then run_start = x end
|
|
87
|
+
if not equal and run_start ~= nil then
|
|
88
|
+
mask:add(Rectangle(run_start, y, x - run_start, 1))
|
|
89
|
+
matched = matched + (x - run_start)
|
|
90
|
+
run_start = nil
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
apply_mask(sprite, mask, params.mode)
|
|
95
|
+
local result = selection_result(sprite)
|
|
96
|
+
result.matched = matched
|
|
97
|
+
result.composite = params.composite == true
|
|
98
|
+
return result
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
M.handlers = {
|
|
102
|
+
get_selection=get_selection,
|
|
103
|
+
select_all=select_all,
|
|
104
|
+
deselect=deselect,
|
|
105
|
+
invert_selection=invert_selection,
|
|
106
|
+
select_ellipse=select_ellipse,
|
|
107
|
+
select_by_color=select_by_color,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return M
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
local C = require("live_common")
|
|
2
|
+
local M = {}
|
|
3
|
+
|
|
4
|
+
local BLEND_MODES = {
|
|
5
|
+
normal=BlendMode.NORMAL, multiply=BlendMode.MULTIPLY, screen=BlendMode.SCREEN,
|
|
6
|
+
overlay=BlendMode.OVERLAY, darken=BlendMode.DARKEN, lighten=BlendMode.LIGHTEN,
|
|
7
|
+
addition=BlendMode.ADDITION, subtract=BlendMode.SUBTRACT, divide=BlendMode.DIVIDE,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
local function target_any_layer(sprite, params)
|
|
11
|
+
local layer = params.layer and C.find_layer(sprite.layers, params.layer) or app.activeLayer
|
|
12
|
+
if not layer then C.fail("Layer was not found") end
|
|
13
|
+
return layer
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
local function set_layer_properties(sprite, params)
|
|
17
|
+
local layer = target_any_layer(sprite, params)
|
|
18
|
+
app.transaction("Auvrynt Live Layer Properties", function()
|
|
19
|
+
if params.name ~= nil then layer.name = tostring(params.name) end
|
|
20
|
+
if params.visible ~= nil then layer.isVisible = params.visible == true end
|
|
21
|
+
if params.editable ~= nil then layer.isEditable = params.editable == true end
|
|
22
|
+
if params.opacity ~= nil then layer.opacity = C.clamp(C.integer(params.opacity, layer.opacity), 0, 255) end
|
|
23
|
+
if params.blendMode ~= nil then
|
|
24
|
+
local mode = BLEND_MODES[tostring(params.blendMode)]
|
|
25
|
+
if not mode then C.fail("Unsupported blend mode") end
|
|
26
|
+
layer.blendMode = mode
|
|
27
|
+
end
|
|
28
|
+
end)
|
|
29
|
+
return { id=tostring(layer.id), name=layer.name, visible=layer.isVisible, editable=layer.isEditable, opacity=layer.opacity, blendMode=tostring(layer.blendMode) }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
local function reorder_layer(sprite, params)
|
|
33
|
+
local layer = target_any_layer(sprite, params)
|
|
34
|
+
local siblings = layer.parent and layer.parent.layers or sprite.layers
|
|
35
|
+
local index = C.clamp(C.integer(params.stackIndex, layer.stackIndex), 1, #siblings)
|
|
36
|
+
app.transaction("Auvrynt Live Reorder Layer", function() layer.stackIndex = index end)
|
|
37
|
+
return { id=tostring(layer.id), name=layer.name, stackIndex=layer.stackIndex }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
local function get_cel(sprite, params)
|
|
41
|
+
local layer = C.target_layer(sprite, params)
|
|
42
|
+
local frame_number = C.target_frame_number(sprite, params)
|
|
43
|
+
local cel = layer:cel(frame_number)
|
|
44
|
+
if not cel then return { exists=false, layer=layer.name, frame=frame_number } end
|
|
45
|
+
return { exists=true, layer=layer.name, frame=frame_number, x=cel.position.x, y=cel.position.y, width=cel.image.width, height=cel.image.height, opacity=cel.opacity, zIndex=cel.zIndex }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
local function set_cel(sprite, params)
|
|
49
|
+
local layer = C.target_layer(sprite, params)
|
|
50
|
+
local frame_number = C.target_frame_number(sprite, params)
|
|
51
|
+
local cel = layer:cel(frame_number)
|
|
52
|
+
if not cel and params.create ~= true then C.fail("Cel does not exist; set create=true") end
|
|
53
|
+
app.transaction("Auvrynt Live Cel Properties", function()
|
|
54
|
+
cel = cel or C.get_canvas_cel(sprite, layer, frame_number, true)
|
|
55
|
+
if params.x ~= nil or params.y ~= nil then cel.position = Point(C.integer(params.x, cel.position.x), C.integer(params.y, cel.position.y)) end
|
|
56
|
+
if params.opacity ~= nil then cel.opacity = C.clamp(C.integer(params.opacity, cel.opacity), 0, 255) end
|
|
57
|
+
if params.zIndex ~= nil then cel.zIndex = C.integer(params.zIndex, cel.zIndex) end
|
|
58
|
+
end)
|
|
59
|
+
return get_cel(sprite, { layer=layer.name, frame=frame_number })
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
local function find_tag(sprite, name)
|
|
63
|
+
for _, tag in ipairs(sprite.tags) do if tag.name == name then return tag end end
|
|
64
|
+
return nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
local ANI_DIRECTIONS = {
|
|
68
|
+
forward=AniDir.FORWARD, reverse=AniDir.REVERSE,
|
|
69
|
+
ping_pong=AniDir.PING_PONG, ping_pong_reverse=AniDir.PING_PONG_REVERSE,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
local function apply_tag_fields(sprite, tag, params)
|
|
73
|
+
if params.name ~= nil then tag.name = tostring(params.name) end
|
|
74
|
+
if params.from ~= nil or params.to ~= nil then
|
|
75
|
+
local from = C.clamp(C.integer(params.from, tag.fromFrame.frameNumber), 1, #sprite.frames)
|
|
76
|
+
local to = C.clamp(C.integer(params.to, tag.toFrame.frameNumber), from, #sprite.frames)
|
|
77
|
+
tag.fromFrame, tag.toFrame = sprite.frames[from], sprite.frames[to]
|
|
78
|
+
end
|
|
79
|
+
if params.direction ~= nil then
|
|
80
|
+
local direction = ANI_DIRECTIONS[tostring(params.direction)]
|
|
81
|
+
if not direction then C.fail("Unsupported tag direction") end
|
|
82
|
+
tag.aniDir = direction
|
|
83
|
+
end
|
|
84
|
+
if params.repeats ~= nil then tag.repeats = C.clamp(C.integer(params.repeats, 0), 0, 65535) end
|
|
85
|
+
if params.color ~= nil then tag.color = C.color_from_hex(params.color) end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
local function tag_result(tag)
|
|
89
|
+
return { name=tag.name, from=tag.fromFrame.frameNumber, to=tag.toFrame.frameNumber, direction=tostring(tag.aniDir), repeats=tag.repeats, color=C.color_to_hex(tag.color) }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
local function create_tag(sprite, params)
|
|
93
|
+
local from = C.clamp(C.integer(params.from, 1), 1, #sprite.frames)
|
|
94
|
+
local to = C.clamp(C.integer(params.to, from), from, #sprite.frames)
|
|
95
|
+
local tag
|
|
96
|
+
app.transaction("Auvrynt Live Create Tag", function()
|
|
97
|
+
tag = sprite:newTag(from, to)
|
|
98
|
+
tag.name = tostring(params.name or "tag")
|
|
99
|
+
apply_tag_fields(sprite, tag, params)
|
|
100
|
+
end)
|
|
101
|
+
return tag_result(tag)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
local function update_tag(sprite, params)
|
|
105
|
+
local tag = find_tag(sprite, tostring(params.tag or params.name or ""))
|
|
106
|
+
if not tag then C.fail("Tag was not found") end
|
|
107
|
+
app.transaction("Auvrynt Live Update Tag", function() apply_tag_fields(sprite, tag, params) end)
|
|
108
|
+
return tag_result(tag)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
local function delete_tag(sprite, params)
|
|
112
|
+
local tag = find_tag(sprite, tostring(params.tag or params.name or ""))
|
|
113
|
+
if not tag then C.fail("Tag was not found") end
|
|
114
|
+
local name = tag.name
|
|
115
|
+
app.transaction("Auvrynt Live Delete Tag", function() sprite:deleteTag(tag) end)
|
|
116
|
+
return { deleted=name }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
M.handlers = {
|
|
120
|
+
set_layer_properties=set_layer_properties,
|
|
121
|
+
reorder_layer=reorder_layer,
|
|
122
|
+
get_cel=get_cel,
|
|
123
|
+
set_cel=set_cel,
|
|
124
|
+
create_tag=create_tag,
|
|
125
|
+
update_tag=update_tag,
|
|
126
|
+
delete_tag=delete_tag,
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return M
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "auvrynt-bridge",
|
|
3
|
+
"displayName": "Auvrynt Bridge",
|
|
4
|
+
"description": "Authenticated local bridge for structured Auvrynt access to the active Aseprite editor.",
|
|
5
|
+
"version": "1.2.0",
|
|
6
|
+
"author": "Auvrynt",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"categories": ["Scripts"],
|
|
9
|
+
"contributes": {
|
|
10
|
+
"scripts": [
|
|
11
|
+
{
|
|
12
|
+
"id": "auvrynt-bridge",
|
|
13
|
+
"path": "./auvrynt_bridge.lua"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# ASEPRITE_AGENT_GUIDE.md
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
Use this guide for Aseprite source assets and pixel-art work, including:
|
|
6
|
+
|
|
7
|
+
- `.aseprite` and `.ase` documents
|
|
8
|
+
- exact pixel edits
|
|
9
|
+
- frame-by-frame 2D animation
|
|
10
|
+
- layers, palettes, tags, and frame timing
|
|
11
|
+
- sprite-sheet and metadata export
|
|
12
|
+
- format conversion, nearest-neighbor scaling, crop, and trim
|
|
13
|
+
|
|
14
|
+
Auvrynt uses Aseprite's native executable, batch CLI, and parameterized Lua API. A GUI plugin is not required for these operations.
|
|
15
|
+
|
|
16
|
+
## Detection
|
|
17
|
+
|
|
18
|
+
Configure either the executable directly or the source/build directory:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
AUVRYNT_ASEPRITE_PATH=C:\path\to\aseprite.exe
|
|
22
|
+
AUVRYNT_ASEPRITE_SOURCE_PATH=C:\path\to\aseprite
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
For a source directory, Auvrynt checks:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
build/bin/aseprite.exe
|
|
29
|
+
bin/aseprite.exe
|
|
30
|
+
aseprite.exe
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The equivalent config keys are:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"executables": {
|
|
38
|
+
"aseprite": "C:\\path\\to\\aseprite.exe",
|
|
39
|
+
"asepriteSource": "C:\\path\\to\\aseprite"
|
|
40
|
+
},
|
|
41
|
+
"integrations": {
|
|
42
|
+
"aseprite": true
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Tools
|
|
48
|
+
|
|
49
|
+
Auvrynt exposes 36 grouped Aseprite tools.
|
|
50
|
+
|
|
51
|
+
Detection, inspection, capture, and QA:
|
|
52
|
+
|
|
53
|
+
- `aseprite_detect` — executable, source path, version, and process state.
|
|
54
|
+
- `aseprite_live_editor` — install/status the authenticated extension bridge and inspect or control the current unsaved editor state.
|
|
55
|
+
- `aseprite_capture_current` — capture the visible Aseprite window with editor UI.
|
|
56
|
+
- `aseprite_capture_canvas` — capture only the live unsaved canvas at native or nearest-neighbor scale.
|
|
57
|
+
- `aseprite_inspect_file` — document structure, timing, tags, slices, and palette size.
|
|
58
|
+
- `aseprite_read_pixels` — exact RGBA or indexed pixel readback, regions, histograms, and alpha bounds.
|
|
59
|
+
- `aseprite_audit_sprite` — isolated/semi-transparent pixels, duplicate/empty frames, palette waste, tags, linked cels, and canvas occupancy.
|
|
60
|
+
- `aseprite_compare_documents` — structural and per-frame pixel comparison of two `.aseprite` documents.
|
|
61
|
+
- `aseprite_animation_audit` — timing outliers, silhouette/anchor movement, duplicates, and loop continuity.
|
|
62
|
+
|
|
63
|
+
Source safety and maintenance:
|
|
64
|
+
|
|
65
|
+
- `aseprite_file_safety` — SHA-256 status/assertion, checkpoints, rollback, and checkpoint deletion.
|
|
66
|
+
- `aseprite_maintenance` — decode validation, repaired copy, and lossy-format round-trip analysis.
|
|
67
|
+
- `aseprite_batch_process` — bounded dry-run or batch audit, convert, export, and repair.
|
|
68
|
+
- `aseprite_recovery` — list/archive/discard native recovery sessions or open Aseprite's recovery UI.
|
|
69
|
+
- `aseprite_extensions` — inspect resources/extensions/startup errors and explicitly manage user extensions.
|
|
70
|
+
|
|
71
|
+
Pixel drawing and regions:
|
|
72
|
+
|
|
73
|
+
- `aseprite_create_sprite` — create a document.
|
|
74
|
+
- `aseprite_set_pixels` — surgical exact-coordinate edits.
|
|
75
|
+
- `aseprite_draw_shapes` — points, Bresenham lines, and rectangles.
|
|
76
|
+
- `aseprite_draw_stroke` — native brushes, pencil/eraser/bucket, inks, pixel-perfect mode, symmetry, and tiled drawing.
|
|
77
|
+
- `aseprite_draw_advanced` — ellipse, polygon, gradient, outline, and flood fill.
|
|
78
|
+
- `aseprite_edit_region` — copy/composite/scale/rotate/flip regions across files, layers, and frames.
|
|
79
|
+
- `aseprite_manage_mask` — persistent rectangular/color/content masks and masked move/clear/fill operations.
|
|
80
|
+
- `aseprite_run_safe_command` — curated allowlisted document commands; never arbitrary Lua.
|
|
81
|
+
|
|
82
|
+
Document structure and animation:
|
|
83
|
+
|
|
84
|
+
- `aseprite_manage_layers` — basic layer creation, naming, visibility, deletion, and opacity.
|
|
85
|
+
- `aseprite_compose_layers` — groups, duplicate/merge/flatten, background conversion, ordering, locking, blending, and soloing.
|
|
86
|
+
- `aseprite_manage_frames` — add, duplicate, delete, and retime frames.
|
|
87
|
+
- `aseprite_manage_animation` — frame movement/copy/reversal, bulk timing, tag range/direction/repeat updates, and guarded cel-position tweening with linear/ease-in/ease-out/smoothstep easing.
|
|
88
|
+
- `aseprite_manage_tags` — basic tag creation, rename, and deletion.
|
|
89
|
+
- `aseprite_manage_cels` — inspect/create/delete/move/duplicate/link/unlink cels and edit opacity/z-index.
|
|
90
|
+
- `aseprite_manage_document` — resize/crop/trim, grid, pixel ratio, user data, slices, pivots, and nine-slice data.
|
|
91
|
+
|
|
92
|
+
Color, palettes, tilemaps, import, and export:
|
|
93
|
+
|
|
94
|
+
- `aseprite_set_palette` — replace the complete document palette.
|
|
95
|
+
- `aseprite_manage_color` — inspect/edit palette entries, transparent index, remap colors, ICC profiles, palette files, quantization, dithering, and built-in Game Boy, PICO-8, CGA, C64, DawnBringer16, grayscale, and monochrome presets.
|
|
96
|
+
- `aseprite_import_sprite_sheet` — convert a gridded image into frames, timing, and tags.
|
|
97
|
+
- `aseprite_manage_tilemap` — native tilesets, tilemap layers, tile pixels, map cells/flip flags, metadata, import, and export.
|
|
98
|
+
- `aseprite_export_sprite_sheet` — standard sheet and JSON export.
|
|
99
|
+
- `aseprite_manage_export_preset` — reusable full-option export presets, repeat export, and output validation.
|
|
100
|
+
- `aseprite_convert_file` — nearest-neighbor conversion, crop, trim, palette, frame/tag/layer filtering, and color mode.
|
|
101
|
+
|
|
102
|
+
## Required Workflow
|
|
103
|
+
|
|
104
|
+
1. Call `open_workspace` for the project containing the sprite sources.
|
|
105
|
+
2. Call `aseprite_detect` once.
|
|
106
|
+
3. Inspect with `aseprite_inspect_file`; use `aseprite_read_pixels` or the audit tools when exact evidence matters.
|
|
107
|
+
4. Call `aseprite_file_safety` with `action="status"` and retain the returned SHA-256 version.
|
|
108
|
+
5. Pass `expectedVersion` into destructive calls. Leave `checkpoint` enabled unless the user explicitly rejects backups.
|
|
109
|
+
6. Make the smallest focused edit.
|
|
110
|
+
7. Re-inspect and run the relevant audit or comparison.
|
|
111
|
+
8. Export with a project preset and validate the result.
|
|
112
|
+
9. Keep project inputs/outputs inside the workspace. Global recovery or extension mutations require explicit `allowGlobalWrite=true`.
|
|
113
|
+
|
|
114
|
+
## Drawing Rules
|
|
115
|
+
|
|
116
|
+
- Use integer coordinates only.
|
|
117
|
+
- Use `#RRGGBB` or `#RRGGBBAA` colors.
|
|
118
|
+
- Prefer `aseprite_set_pixels` for surgical corrections and cluster construction.
|
|
119
|
+
- Prefer `aseprite_draw_shapes` for deliberate geometric primitives, not organic automatic tracing.
|
|
120
|
+
- Preserve the document palette and pixel scale unless the user asks to change them.
|
|
121
|
+
- Do not resample pixel art with smoothing. Aseprite CLI scaling is nearest-neighbor.
|
|
122
|
+
- Inspect neighboring frames before changing animation silhouettes.
|
|
123
|
+
- Do not overwrite source documents with exported sheets.
|
|
124
|
+
|
|
125
|
+
## Native Integration and Live Bridge
|
|
126
|
+
|
|
127
|
+
Native CLI/Lua remains the default for deterministic saved-file operations. The bundled `auvrynt-bridge` extension adds structured access to the already-running editor without opening a network port. It uses an authenticated filesystem request queue under Aseprite's user-data directory.
|
|
128
|
+
|
|
129
|
+
Use `aseprite_live_editor` for active unsaved document state, document/tab selection, save/undo/redo, playback, onion skin, zoom, active tool/brush/colors, selection, live pixel/stroke edits, and constrained safe commands. Bridge v1.2 adds 46 allowlisted `run_live_command` operations covering exact pixel/image readback; lines, shapes, fill, replace, clear and outline; layer/cel/tag edits; palette ramps and character templates; ellipse/by-color/invert selections; frame duplication/reversal/timing; cel shifting, sprite flip/rotation and cross-document copying; live resize/crop/flatten/grid and tileset templates; symmetry and ordered dithering; palette sorting that preserves indexed pixel appearance; plus live bounds, color statistics, frame comparison and animation validation. Use `aseprite_capture_canvas` for a clean canvas-only capture.
|
|
130
|
+
|
|
131
|
+
The dashboard uses three distinct states. **Connected** means the live bridge answered an authenticated status request. **Available** means the native executable is usable, or Aseprite is running without a responding bridge. Merely detecting `aseprite.exe` is not a live connection. The bridge is installed by `auvrynt setup aseprite ...` and self-healed at Auvrynt startup; Aseprite must be restarted once after first installation or a bridge upgrade so the extension code is loaded.
|
|
132
|
+
|
|
133
|
+
MCP clients can cache their tool catalog. After enabling Aseprite or upgrading Auvrynt, reconnect the MCP connector when `aseprite_*` tools do not appear even though the dashboard reports the profile enabled. Auvrynt sends the standard tool-list-changed notification, but not every client refreshes dynamically.
|