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.
Files changed (550) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +366 -233
  3. package/addons/auvrynt_bridge/auvrynt_bridge.gd +500 -0
  4. package/addons/auvrynt_bridge/plugin.cfg +7 -0
  5. package/bin/auvrynt-launcher.cjs +77 -0
  6. package/dist/artifact-registry.js +1 -0
  7. package/dist/aseprite-tools.js +1 -0
  8. package/dist/auth/connection-registry.js +145 -0
  9. package/dist/auth/connection-status.js +176 -0
  10. package/dist/auth/oauth-provider.js +617 -0
  11. package/dist/auth/room-registry.js +131 -0
  12. package/dist/auth/session-registry.js +531 -0
  13. package/dist/background-lifecycle.js +1 -0
  14. package/dist/blender-client.js +1 -109
  15. package/dist/blender-tools.js +1 -930
  16. package/dist/browser-stability.js +1 -0
  17. package/dist/cli/commands/help-command.js +10 -0
  18. package/dist/cli/commands/init-command.js +190 -0
  19. package/dist/cli/commands/integration-commands.js +88 -0
  20. package/dist/cli/commands/serve-command.js +83 -0
  21. package/dist/cli/commands/setup-command.js +81 -0
  22. package/dist/cli/commands/status-commands.js +166 -0
  23. package/dist/cli/commands/tunnel-command.js +127 -0
  24. package/dist/cli/commands/user-config-commands.js +105 -0
  25. package/dist/cli/dashboard-actions.js +516 -0
  26. package/dist/cli/dashboard-native-actions.js +282 -0
  27. package/dist/cli/foreground-server.js +270 -0
  28. package/dist/cli/instance-control.js +21 -0
  29. package/dist/cli/instance-lock.js +123 -0
  30. package/dist/cli/integration-bootstrap.js +206 -0
  31. package/dist/cli/lifecycle-manager.js +493 -0
  32. package/dist/cli/runtime-support.js +74 -0
  33. package/dist/cli/serena-detected-default.js +27 -0
  34. package/dist/cli/tunnel-health-monitor.js +182 -0
  35. package/dist/cli.js +82 -739
  36. package/dist/config.js +1 -243
  37. package/dist/connection-registry.js +1 -73
  38. package/dist/connection-status.js +1 -139
  39. package/dist/control-retry.js +1 -0
  40. package/dist/crash-recovery.js +1 -0
  41. package/dist/db/client.js +16 -3
  42. package/dist/db/schema.js +30 -0
  43. package/dist/dotnet-tools.js +1 -223
  44. package/dist/git-worktrees.js +1 -134
  45. package/dist/git.js +1 -41
  46. package/dist/godot-animation-tilemap.js +1 -82
  47. package/dist/godot-csharp-build.js +1 -93
  48. package/dist/godot-csharp-project.js +1 -157
  49. package/dist/godot-csharp-runner.js +1 -146
  50. package/dist/godot-csharp-semantic.js +1 -161
  51. package/dist/godot-csharp-validate.js +1 -71
  52. package/dist/godot-dotnet-env.js +1 -169
  53. package/dist/godot-editor-bridge.js +1 -140
  54. package/dist/godot-gdscript.js +1 -824
  55. package/dist/godot-project-settings.js +1 -223
  56. package/dist/godot-runtime-testing.js +1 -249
  57. package/dist/godot-tools.js +1 -183
  58. package/dist/http-rate-limit.js +1 -0
  59. package/dist/http-server-hardening.js +1 -0
  60. package/dist/image-tools.js +1 -157
  61. package/dist/infrastructure/command-reference.js +32 -0
  62. package/dist/infrastructure/config.js +424 -0
  63. package/dist/infrastructure/context7-auth.js +55 -0
  64. package/dist/infrastructure/http-rate-limit.js +42 -0
  65. package/dist/infrastructure/http-server-hardening.js +23 -0
  66. package/dist/infrastructure/integration-queue.js +46 -0
  67. package/dist/infrastructure/logger.js +129 -0
  68. package/dist/infrastructure/mcp-event-store.js +103 -0
  69. package/dist/infrastructure/ngrok-auth-pool.js +208 -0
  70. package/dist/infrastructure/request-context.js +14 -0
  71. package/dist/infrastructure/shutdown.js +37 -0
  72. package/dist/infrastructure/sse-heartbeat.js +47 -0
  73. package/dist/infrastructure/tool-capabilities.js +67 -0
  74. package/dist/infrastructure/tool-result-budget.js +175 -0
  75. package/dist/infrastructure/user-config.js +167 -0
  76. package/dist/integration-discovery.js +1 -98
  77. package/dist/integration-queue.js +1 -0
  78. package/dist/integrations/agent-reach/agent-reach-tools.js +196 -0
  79. package/dist/integrations/agent-reach/native-channels.js +468 -0
  80. package/dist/integrations/aseprite/aseprite-analysis-tools.js +368 -0
  81. package/dist/integrations/aseprite/aseprite-editing-tools.js +647 -0
  82. package/dist/integrations/aseprite/aseprite-live-tools.js +297 -0
  83. package/dist/integrations/aseprite/aseprite-safety-tools.js +594 -0
  84. package/dist/integrations/aseprite/aseprite-specialized-tools.js +289 -0
  85. package/dist/integrations/aseprite/aseprite-tools.js +837 -0
  86. package/dist/integrations/blender/blender-catalog-mesh.js +593 -0
  87. package/dist/integrations/blender/blender-catalog-object.js +906 -0
  88. package/dist/integrations/blender/blender-catalog-scene.js +266 -0
  89. package/dist/integrations/blender/blender-catalog-select.js +581 -0
  90. package/dist/integrations/blender/blender-catalog-stubs.js +7512 -0
  91. package/dist/integrations/blender/blender-catalog.js +165 -0
  92. package/dist/integrations/blender/blender-client.js +105 -0
  93. package/dist/integrations/blender/blender-tools.js +2243 -0
  94. package/dist/integrations/context7/context7-tools.js +106 -0
  95. package/dist/integrations/dotnet/dotnet-tools.js +195 -0
  96. package/dist/integrations/godot/godot-animation-tilemap.js +74 -0
  97. package/dist/integrations/godot/godot-csharp-build.js +91 -0
  98. package/dist/integrations/godot/godot-csharp-project.js +155 -0
  99. package/dist/integrations/godot/godot-csharp-runner.js +118 -0
  100. package/dist/integrations/godot/godot-csharp-semantic.js +146 -0
  101. package/dist/integrations/godot/godot-csharp-validate.js +71 -0
  102. package/dist/integrations/godot/godot-dotnet-env.js +134 -0
  103. package/dist/integrations/godot/godot-editor-bridge.js +328 -0
  104. package/dist/integrations/godot/godot-gdscript.js +536 -0
  105. package/dist/integrations/godot/godot-project-settings.js +178 -0
  106. package/dist/integrations/godot/godot-runtime-testing.js +263 -0
  107. package/dist/integrations/godot/godot-tools.js +193 -0
  108. package/dist/integrations/images/image-tools.js +414 -0
  109. package/dist/integrations/images/png-codec.js +251 -0
  110. package/dist/integrations/images/view-image.js +99 -0
  111. package/dist/integrations/images/window-capture.js +148 -0
  112. package/dist/integrations/integration-discovery.js +185 -0
  113. package/dist/integrations/obsidian/obsidian-tools.js +205 -0
  114. package/dist/integrations/playwright/browser-session.js +516 -0
  115. package/dist/integrations/playwright/browser-stability.js +36 -0
  116. package/dist/integrations/playwright/playwright-runtime.js +105 -0
  117. package/dist/integrations/playwright/web-tools.js +504 -0
  118. package/dist/integrations/roblox/roblox-helpers.js +381 -0
  119. package/dist/integrations/roblox/roblox-studio-client.js +112 -0
  120. package/dist/integrations/roblox/roblox-tools.js +106 -0
  121. package/dist/integrations/serena/serena-manager.js +464 -0
  122. package/dist/integrations/serena/serena-tools.js +411 -0
  123. package/dist/logger.js +1 -76
  124. package/dist/mcp-event-store.js +1 -0
  125. package/dist/oauth-provider.js +1 -377
  126. package/dist/pi-tools.js +1 -81
  127. package/dist/playwright-runtime.js +1 -0
  128. package/dist/process/background-lifecycle.js +189 -0
  129. package/dist/process/control-retry.js +42 -0
  130. package/dist/process/crash-recovery.js +23 -0
  131. package/dist/process/processes.js +456 -0
  132. package/dist/processes.js +1 -218
  133. package/dist/request-context.js +1 -0
  134. package/dist/review-checkpoints.js +1 -142
  135. package/dist/room-registry.js +1 -0
  136. package/dist/roots.js +1 -53
  137. package/dist/search-discovery.js +1 -271
  138. package/dist/serena-manager.js +1 -443
  139. package/dist/serena-tools.js +1 -411
  140. package/dist/server/dashboard-page-styles.js +331 -0
  141. package/dist/server/dashboard-page.js +1509 -0
  142. package/dist/server/dashboard-routes.js +46 -0
  143. package/dist/server/dashboard.js +240 -0
  144. package/dist/server/http-helpers.js +30 -0
  145. package/dist/server/integration-profile-update.js +37 -0
  146. package/dist/server/mcp-policy.js +169 -0
  147. package/dist/server/mcp-server-factory.js +127 -0
  148. package/dist/server/mcp-tool-registrar.js +182 -0
  149. package/dist/server/openai-session-hint.js +14 -0
  150. package/dist/server/tool-groups.js +29 -0
  151. package/dist/server/tool-logging.js +33 -0
  152. package/dist/server/tool-registration-shared.js +59 -0
  153. package/dist/server/tools/aseprite-advanced-tools-registration.js +547 -0
  154. package/dist/server/tools/aseprite-tools-registration.js +213 -0
  155. package/dist/server/tools/blender-tools-registration.js +690 -0
  156. package/dist/server/tools/core-file-tools-registration.js +459 -0
  157. package/dist/server/tools/dotnet-godot-window-tools-registration.js +120 -0
  158. package/dist/server/tools/godot-csharp-tools-registration.js +252 -0
  159. package/dist/server/tools/godot-gdscript-tools-registration.js +189 -0
  160. package/dist/server/tools/process-project-tools-registration.js +155 -0
  161. package/dist/server/tools/roblox-tools-registration.js +514 -0
  162. package/dist/server/tools/web-image-tools-registration.js +326 -0
  163. package/dist/server/tools/workspace-lifecycle-tools-registration.js +130 -0
  164. package/dist/server/ui-assets.js +97 -0
  165. package/dist/server/workspace-analytics.js +92 -0
  166. package/dist/server.js +453 -2713
  167. package/dist/session-registry.js +1 -0
  168. package/dist/shutdown.js +1 -0
  169. package/dist/skills.js +1 -45
  170. package/dist/sse-heartbeat.js +1 -0
  171. package/dist/tool-capabilities.js +1 -0
  172. package/dist/tool-result-budget.js +1 -0
  173. package/dist/tools/pi-tools.js +81 -0
  174. package/dist/tunnels/cloudflare-tunnel.js +217 -0
  175. package/dist/tunnels/cloudflared-service.js +174 -0
  176. package/dist/tunnels/ngrok-tunnel.js +220 -0
  177. package/dist/tunnels/tunnel-manager.js +186 -0
  178. package/dist/tunnels/tunnel-types.js +1 -0
  179. package/dist/tunnels/tunnel-utils.js +62 -0
  180. package/dist/ui/.vite/manifest.json +9 -2487
  181. package/dist/ui/assets/heavy-payload-D42A9ceL.js +1 -0
  182. package/dist/ui/assets/lightweight-diff-Cv4g9Hdr.js +13 -0
  183. package/dist/ui/assets/review-payload-DKIg1cKF.js +1 -0
  184. package/dist/ui/assets/workspace-app-CeK3NhmB.css +1 -0
  185. package/dist/ui/assets/{workspace-app-C5QsE314.js → workspace-app-CkUXnpl4.js} +6 -6
  186. package/dist/ui/brand-theme.js +23 -0
  187. package/dist/ui/workspace-app.html +15 -15
  188. package/dist/user-config.js +1 -57
  189. package/dist/view-image.js +1 -104
  190. package/dist/web-tools.js +1 -200
  191. package/dist/window-capture.js +1 -74
  192. package/dist/workspace/artifact-registry.js +69 -0
  193. package/dist/workspace/git-worktrees.js +141 -0
  194. package/dist/workspace/git.js +42 -0
  195. package/dist/workspace/review-checkpoints.js +142 -0
  196. package/dist/workspace/roots.js +56 -0
  197. package/dist/workspace/search-discovery.js +264 -0
  198. package/dist/workspace/skills.js +45 -0
  199. package/dist/workspace/workspace-store.js +219 -0
  200. package/dist/workspace/workspaces.js +314 -0
  201. package/dist/workspace-store.js +1 -125
  202. package/dist/workspaces.js +1 -226
  203. package/docs/CREATOR_STORE_FREE_ASSETS.md +162 -0
  204. package/docs/DEVELOPMENT_TOOLS.md +136 -93
  205. package/docs/assets/auvrynt-icon.png +0 -0
  206. package/docs/assets/auvrynt-icon.svg +20 -0
  207. package/docs/chatgpt-coding-workflow.md +143 -143
  208. package/docs/configuration.md +156 -124
  209. package/docs/diagnostics.md +79 -0
  210. package/docs/gotchas.md +244 -202
  211. package/docs/multi-agent-and-long-projects.md +91 -0
  212. package/docs/security.md +138 -100
  213. package/docs/setup.md +171 -131
  214. package/docs/source-layout.md +60 -0
  215. package/extensions/auvrynt_bridge/auvrynt_bridge.lua +594 -0
  216. package/extensions/auvrynt_bridge/live_analysis.lua +181 -0
  217. package/extensions/auvrynt_bridge/live_animation.lua +134 -0
  218. package/extensions/auvrynt_bridge/live_commands.lua +24 -0
  219. package/extensions/auvrynt_bridge/live_common.lua +130 -0
  220. package/extensions/auvrynt_bridge/live_document.lua +78 -0
  221. package/extensions/auvrynt_bridge/live_drawing.lua +125 -0
  222. package/extensions/auvrynt_bridge/live_effects.lua +91 -0
  223. package/extensions/auvrynt_bridge/live_palette_template.lua +167 -0
  224. package/extensions/auvrynt_bridge/live_selection.lua +110 -0
  225. package/extensions/auvrynt_bridge/live_structure.lua +129 -0
  226. package/extensions/auvrynt_bridge/package.json +17 -0
  227. package/guides/ASEPRITE_AGENT_GUIDE.md +133 -0
  228. package/guides/BLENDER_AGENT_GUIDE.md +472 -0
  229. package/guides/GODOT_AGENT_GUIDE.md +298 -0
  230. package/guides/PROJECT_ROUTER.md +165 -0
  231. package/guides/ROBLOX_AGENT_GUIDE.md +75 -0
  232. package/guides/SOFTWARE_AGENT_GUIDE.md +104 -0
  233. package/guides/WEB_AGENT_GUIDE.md +287 -0
  234. package/package.json +78 -70
  235. package/scripts/dev-server.mjs +121 -120
  236. package/scripts/live-tunnel-smoke.mjs +538 -0
  237. package/scripts/repo-hygiene.mjs +74 -0
  238. package/scripts/restart-after-crash.mjs +49 -0
  239. package/scripts/run-tests.mjs +166 -0
  240. package/dist/ui/assets/abap-CLvhMVsD.js +0 -1
  241. package/dist/ui/assets/actionscript-3--17pq3dv.js +0 -1
  242. package/dist/ui/assets/ada-C5qYipkI.js +0 -1
  243. package/dist/ui/assets/andromeeda-vGVdxbeo.js +0 -1
  244. package/dist/ui/assets/angular-html-BJqQFYI6.js +0 -1
  245. package/dist/ui/assets/angular-ts-CMJECO0Y.js +0 -1
  246. package/dist/ui/assets/apache-U0d_L8uA.js +0 -1
  247. package/dist/ui/assets/apex-CGTLDQj6.js +0 -1
  248. package/dist/ui/assets/apl-DWeXpBBr.js +0 -1
  249. package/dist/ui/assets/applescript-CCn79oCD.js +0 -1
  250. package/dist/ui/assets/ara-4CJ0cIlV.js +0 -1
  251. package/dist/ui/assets/asciidoc-DE70LPWp.js +0 -1
  252. package/dist/ui/assets/asm-Cmm7eHzH.js +0 -1
  253. package/dist/ui/assets/astro-CLbttLOq.js +0 -1
  254. package/dist/ui/assets/aurora-x-CDeNXAV0.js +0 -1
  255. package/dist/ui/assets/awk-BWXHIvNe.js +0 -1
  256. package/dist/ui/assets/ayu-dark-DluEY0Gj.js +0 -1
  257. package/dist/ui/assets/ayu-light-C3h-C4tm.js +0 -1
  258. package/dist/ui/assets/ayu-mirage-Bqwy1Gya.js +0 -1
  259. package/dist/ui/assets/ballerina-B7ZEbQpA.js +0 -1
  260. package/dist/ui/assets/bat-Bo4NYOV-.js +0 -1
  261. package/dist/ui/assets/beancount-D-usSTwE.js +0 -1
  262. package/dist/ui/assets/berry-DKpUyyne.js +0 -1
  263. package/dist/ui/assets/bibtex-Ci_nEsc7.js +0 -1
  264. package/dist/ui/assets/bicep-CUHmPFLl.js +0 -1
  265. package/dist/ui/assets/bird2-C2hNVINV.js +0 -1
  266. package/dist/ui/assets/blade-BOzY0P2V.js +0 -1
  267. package/dist/ui/assets/bsl-BkkzgIyY.js +0 -1
  268. package/dist/ui/assets/c-BG-8uJvh.js +0 -1
  269. package/dist/ui/assets/c3-CnJL0r0V.js +0 -1
  270. package/dist/ui/assets/cadence-CQ2zXKGN.js +0 -1
  271. package/dist/ui/assets/cairo-DLTphjLi.js +0 -1
  272. package/dist/ui/assets/catppuccin-frappe-3VR1Za6u.js +0 -1
  273. package/dist/ui/assets/catppuccin-latte-DwIHMF0Q.js +0 -1
  274. package/dist/ui/assets/catppuccin-macchiato-DYnBP6_5.js +0 -1
  275. package/dist/ui/assets/catppuccin-mocha-DYhrFGRu.js +0 -1
  276. package/dist/ui/assets/clarity-SemFz856.js +0 -1
  277. package/dist/ui/assets/clojure-DqKBuwfJ.js +0 -1
  278. package/dist/ui/assets/cmake-Bj61d0ZC.js +0 -1
  279. package/dist/ui/assets/cobol-I_17IuGe.js +0 -1
  280. package/dist/ui/assets/codeowners-C8r90Shi.js +0 -1
  281. package/dist/ui/assets/codeql-oeQT6MSM.js +0 -1
  282. package/dist/ui/assets/coffee-C0B8hmok.js +0 -1
  283. package/dist/ui/assets/common-lisp-Cv5bFMCO.js +0 -1
  284. package/dist/ui/assets/coq-BrsZFFmf.js +0 -1
  285. package/dist/ui/assets/cpp-DDJXt6Vs.js +0 -1
  286. package/dist/ui/assets/crystal-Bexqace6.js +0 -1
  287. package/dist/ui/assets/csharp-Ct8U2NOr.js +0 -1
  288. package/dist/ui/assets/css-DSQhw_9R.js +0 -1
  289. package/dist/ui/assets/csv-Dx-8-gkx.js +0 -1
  290. package/dist/ui/assets/cue-CE9AQfxI.js +0 -1
  291. package/dist/ui/assets/cypher-ClKdZ_lG.js +0 -1
  292. package/dist/ui/assets/d-qD-0Kul2.js +0 -1
  293. package/dist/ui/assets/dark-plus-Cs2F2srj.js +0 -1
  294. package/dist/ui/assets/dart-DkHntEIa.js +0 -1
  295. package/dist/ui/assets/dax-BkyTk9wS.js +0 -1
  296. package/dist/ui/assets/desktop-Dlh5hvp9.js +0 -1
  297. package/dist/ui/assets/diff-woXpYk--.js +0 -1
  298. package/dist/ui/assets/docker-IyjqRm3v.js +0 -1
  299. package/dist/ui/assets/dotenv-_5a1GRtc.js +0 -1
  300. package/dist/ui/assets/dracula-BHWKrbxM.js +0 -1
  301. package/dist/ui/assets/dracula-soft-5eyTD99u.js +0 -1
  302. package/dist/ui/assets/dream-maker-DW3nJb8Q.js +0 -1
  303. package/dist/ui/assets/edge-Z8YYkHOr.js +0 -1
  304. package/dist/ui/assets/elixir-CG9uKtAF.js +0 -1
  305. package/dist/ui/assets/elm-GfWG2IfT.js +0 -1
  306. package/dist/ui/assets/emacs-lisp-C9PiwqqW.js +0 -1
  307. package/dist/ui/assets/erb-xe89e73J.js +0 -1
  308. package/dist/ui/assets/erlang-Cphh6RMH.js +0 -1
  309. package/dist/ui/assets/everforest-dark-sB-x3p7T.js +0 -1
  310. package/dist/ui/assets/everforest-light-Df2xbC6M.js +0 -1
  311. package/dist/ui/assets/fennel-DQxkIbk2.js +0 -1
  312. package/dist/ui/assets/fish-BJitypiv.js +0 -1
  313. package/dist/ui/assets/fluent-C03EYrpw.js +0 -1
  314. package/dist/ui/assets/fortran-fixed-form-DEKoE2YW.js +0 -1
  315. package/dist/ui/assets/fortran-free-form-CYNrtFtB.js +0 -1
  316. package/dist/ui/assets/fsharp-D13ZGOAj.js +0 -1
  317. package/dist/ui/assets/gdresource-C0sCabJj.js +0 -1
  318. package/dist/ui/assets/gdscript-Cp2uCuqX.js +0 -1
  319. package/dist/ui/assets/gdshader-CBce3t8t.js +0 -1
  320. package/dist/ui/assets/genie-CV2tkWYe.js +0 -1
  321. package/dist/ui/assets/gherkin-DExj1W_8.js +0 -1
  322. package/dist/ui/assets/git-commit-BSykSTBG.js +0 -1
  323. package/dist/ui/assets/git-rebase-CoTL_uSE.js +0 -1
  324. package/dist/ui/assets/github-dark-C-LZuMrd.js +0 -1
  325. package/dist/ui/assets/github-dark-default-DXG-b-1a.js +0 -1
  326. package/dist/ui/assets/github-dark-dimmed-Bx1FflLF.js +0 -1
  327. package/dist/ui/assets/github-dark-high-contrast-B_tTalzw.js +0 -1
  328. package/dist/ui/assets/github-light-EUqPIrTm.js +0 -1
  329. package/dist/ui/assets/github-light-default-BXViO-2h.js +0 -1
  330. package/dist/ui/assets/github-light-high-contrast-B68TUdTA.js +0 -1
  331. package/dist/ui/assets/gleam-CSRkHgEL.js +0 -1
  332. package/dist/ui/assets/glimmer-js-DAn4UCSu.js +0 -1
  333. package/dist/ui/assets/glimmer-ts-Tjyi6Gh5.js +0 -1
  334. package/dist/ui/assets/glsl-CtTDZoqR.js +0 -1
  335. package/dist/ui/assets/gn-ilITqXS6.js +0 -1
  336. package/dist/ui/assets/gnuplot-7GGW24-e.js +0 -1
  337. package/dist/ui/assets/go-BJwz_mda.js +0 -1
  338. package/dist/ui/assets/graphql-D5gcC_Jk.js +0 -1
  339. package/dist/ui/assets/groovy-CacY0gHj.js +0 -1
  340. package/dist/ui/assets/gruvbox-dark-hard-C820rvS2.js +0 -1
  341. package/dist/ui/assets/gruvbox-dark-medium-BPjhmG05.js +0 -1
  342. package/dist/ui/assets/gruvbox-dark-soft-MrdJrrXF.js +0 -1
  343. package/dist/ui/assets/gruvbox-light-hard-BC_s9l72.js +0 -1
  344. package/dist/ui/assets/gruvbox-light-medium-BAWPOn9u.js +0 -1
  345. package/dist/ui/assets/gruvbox-light-soft-BSMLrYjP.js +0 -1
  346. package/dist/ui/assets/hack-BJXY27dt.js +0 -1
  347. package/dist/ui/assets/haml-BLfFoZf7.js +0 -1
  348. package/dist/ui/assets/handlebars-Dw6CWkvN.js +0 -1
  349. package/dist/ui/assets/haskell-D8IpX4py.js +0 -1
  350. package/dist/ui/assets/haxe-OTjmBuCE.js +0 -1
  351. package/dist/ui/assets/hcl-Dh228itO.js +0 -1
  352. package/dist/ui/assets/heavy-payload-Dcg0-F-S.js +0 -4
  353. package/dist/ui/assets/hjson-CxZEssPk.js +0 -1
  354. package/dist/ui/assets/hlsl-Cvrh5tZx.js +0 -1
  355. package/dist/ui/assets/horizon-CE9ld1lL.js +0 -1
  356. package/dist/ui/assets/horizon-bright-Br1oVSNq.js +0 -1
  357. package/dist/ui/assets/houston-CsvMBhTu.js +0 -1
  358. package/dist/ui/assets/html-CAcAWvoN.js +0 -1
  359. package/dist/ui/assets/html-derivative-8aSW2E_7.js +0 -1
  360. package/dist/ui/assets/http-B2YR_3V1.js +0 -1
  361. package/dist/ui/assets/hurl-BnDJ9Zhf.js +0 -1
  362. package/dist/ui/assets/hxml-B0Qn7Nwc.js +0 -1
  363. package/dist/ui/assets/hy-CZbG8q4J.js +0 -1
  364. package/dist/ui/assets/imba-DsUTQ-LC.js +0 -1
  365. package/dist/ui/assets/ini-B5eOa1yu.js +0 -1
  366. package/dist/ui/assets/java-Doxi4W8u.js +0 -1
  367. package/dist/ui/assets/javascript-BbRdEqti.js +0 -1
  368. package/dist/ui/assets/jinja-CS3Tpv_Q.js +0 -1
  369. package/dist/ui/assets/jison-BkPGYVHR.js +0 -1
  370. package/dist/ui/assets/json-BMt1m3m8.js +0 -1
  371. package/dist/ui/assets/json5-BR5RXkoi.js +0 -1
  372. package/dist/ui/assets/jsonc-CYpm1nAK.js +0 -1
  373. package/dist/ui/assets/jsonl-CmCQp5Yx.js +0 -1
  374. package/dist/ui/assets/jsonnet-CJTPZ8u_.js +0 -1
  375. package/dist/ui/assets/jssm-DXw9l8Rf.js +0 -1
  376. package/dist/ui/assets/jsx-CQKrJXXY.js +0 -1
  377. package/dist/ui/assets/julia-BuN7i2du.js +0 -1
  378. package/dist/ui/assets/just-BswEPFPu.js +0 -1
  379. package/dist/ui/assets/kanagawa-dragon-CXtmUGW6.js +0 -1
  380. package/dist/ui/assets/kanagawa-lotus-BN08jTvb.js +0 -1
  381. package/dist/ui/assets/kanagawa-wave-CTweb8Dz.js +0 -1
  382. package/dist/ui/assets/kdl-CsD5j6eV.js +0 -1
  383. package/dist/ui/assets/kotlin-DhhofPvG.js +0 -1
  384. package/dist/ui/assets/kusto-BUv0MjJC.js +0 -1
  385. package/dist/ui/assets/laserwave-C_8bwKvT.js +0 -1
  386. package/dist/ui/assets/latex-DU2VyFfA.js +0 -1
  387. package/dist/ui/assets/lean-CewbzKMR.js +0 -1
  388. package/dist/ui/assets/less-DVTAwKKz.js +0 -1
  389. package/dist/ui/assets/light-plus-DVQuIRkW.js +0 -1
  390. package/dist/ui/assets/liquid-Cmz1L3dq.js +0 -1
  391. package/dist/ui/assets/llvm-Cm23YOpf.js +0 -1
  392. package/dist/ui/assets/log-BNLmms1o.js +0 -1
  393. package/dist/ui/assets/logo-Cluzi2Zq.js +0 -1
  394. package/dist/ui/assets/lua-CfVXhkaJ.js +0 -1
  395. package/dist/ui/assets/luau-CNKltnaQ.js +0 -1
  396. package/dist/ui/assets/make-Dixweg8N.js +0 -1
  397. package/dist/ui/assets/markdown-BYOwaDjH.js +0 -1
  398. package/dist/ui/assets/marko-C5bfqGiA.js +0 -1
  399. package/dist/ui/assets/material-theme-Bm3Qr25_.js +0 -1
  400. package/dist/ui/assets/material-theme-darker-2IIEA8gg.js +0 -1
  401. package/dist/ui/assets/material-theme-lighter-uhdI0v04.js +0 -1
  402. package/dist/ui/assets/material-theme-ocean-CHQ94UKr.js +0 -1
  403. package/dist/ui/assets/material-theme-palenight-B5W6OYN7.js +0 -1
  404. package/dist/ui/assets/matlab-D7qyCx1q.js +0 -1
  405. package/dist/ui/assets/mdc-CVBXYfyq.js +0 -1
  406. package/dist/ui/assets/mdx-DQZ5AkYe.js +0 -1
  407. package/dist/ui/assets/mermaid-Bk4SNUv9.js +0 -1
  408. package/dist/ui/assets/min-dark-BSWPekZh.js +0 -1
  409. package/dist/ui/assets/min-light-DDpmG2fV.js +0 -1
  410. package/dist/ui/assets/mipsasm-BMqwQI7S.js +0 -1
  411. package/dist/ui/assets/mojo-BgCJLMeH.js +0 -1
  412. package/dist/ui/assets/monokai-CdkpiU2Y.js +0 -1
  413. package/dist/ui/assets/moonbit-CaWjb8XO.js +0 -1
  414. package/dist/ui/assets/move-B1IS1UjX.js +0 -1
  415. package/dist/ui/assets/narrat-_X_XdTYD.js +0 -1
  416. package/dist/ui/assets/nextflow-Bbiyy34d.js +0 -1
  417. package/dist/ui/assets/nextflow-groovy-Dc_ddanL.js +0 -1
  418. package/dist/ui/assets/nginx-CzJafxLa.js +0 -1
  419. package/dist/ui/assets/night-owl-DhmEMT88.js +0 -1
  420. package/dist/ui/assets/night-owl-light-eJ-hLW7d.js +0 -1
  421. package/dist/ui/assets/nim-DABKtHtM.js +0 -1
  422. package/dist/ui/assets/nix-IvuFDN5E.js +0 -1
  423. package/dist/ui/assets/nord-Cb4Vim4T.js +0 -1
  424. package/dist/ui/assets/nushell-DcLAeLz5.js +0 -1
  425. package/dist/ui/assets/objective-c-D1A_Heim.js +0 -1
  426. package/dist/ui/assets/objective-cpp-BsSzOQcm.js +0 -1
  427. package/dist/ui/assets/ocaml-O90oeIOV.js +0 -1
  428. package/dist/ui/assets/odin-B1RWQWA5.js +0 -1
  429. package/dist/ui/assets/one-dark-pro-CLwyXe_n.js +0 -1
  430. package/dist/ui/assets/one-light-D7Lr4KcI.js +0 -1
  431. package/dist/ui/assets/openscad-BUDT5pXO.js +0 -1
  432. package/dist/ui/assets/pascal-4ZHwLPI5.js +0 -1
  433. package/dist/ui/assets/perl-CBh7L3lZ.js +0 -1
  434. package/dist/ui/assets/php-DFbI9q5p.js +0 -1
  435. package/dist/ui/assets/pierre-dark-sU4Zdns8.js +0 -1
  436. package/dist/ui/assets/pierre-dark-soft-HXgun5vs.js +0 -1
  437. package/dist/ui/assets/pierre-light-DWBk51d8.js +0 -1
  438. package/dist/ui/assets/pierre-light-soft-CodEzPxf.js +0 -1
  439. package/dist/ui/assets/pkl-ot-7Btpt.js +0 -1
  440. package/dist/ui/assets/plastic-DQwYfKfQ.js +0 -1
  441. package/dist/ui/assets/plsql-DGHpHOYJ.js +0 -1
  442. package/dist/ui/assets/po-BiJDBrnU.js +0 -1
  443. package/dist/ui/assets/poimandres-DRFjx7u4.js +0 -1
  444. package/dist/ui/assets/polar-C7UOKdEL.js +0 -1
  445. package/dist/ui/assets/postcss-BXeXVLqQ.js +0 -1
  446. package/dist/ui/assets/powerquery-DNMTfnFr.js +0 -1
  447. package/dist/ui/assets/powershell-DshXNtvi.js +0 -1
  448. package/dist/ui/assets/prisma-BsRQq5mF.js +0 -1
  449. package/dist/ui/assets/prolog-iXnhIJG7.js +0 -1
  450. package/dist/ui/assets/proto-DB4EqR-F.js +0 -1
  451. package/dist/ui/assets/pug-C_PxC7gO.js +0 -1
  452. package/dist/ui/assets/puppet-CDv2pdJW.js +0 -1
  453. package/dist/ui/assets/purescript-9MfHhQsQ.js +0 -1
  454. package/dist/ui/assets/python-gzcpVVnB.js +0 -1
  455. package/dist/ui/assets/qml-DtngoFFK.js +0 -1
  456. package/dist/ui/assets/qmldir-DCQb3MpD.js +0 -1
  457. package/dist/ui/assets/qss-Fe1Jh2GI.js +0 -1
  458. package/dist/ui/assets/r-DohkcevW.js +0 -1
  459. package/dist/ui/assets/racket-DcIDlBhZ.js +0 -1
  460. package/dist/ui/assets/raku-B3gFvitq.js +0 -1
  461. package/dist/ui/assets/razor-C4t8J0_E.js +0 -1
  462. package/dist/ui/assets/red-CJ3rzSJv.js +0 -1
  463. package/dist/ui/assets/reg-CRGYupPL.js +0 -1
  464. package/dist/ui/assets/regexp-OGbTbjgY.js +0 -1
  465. package/dist/ui/assets/rel-BtDbiS_P.js +0 -1
  466. package/dist/ui/assets/review-payload-C5Qz60Kq.js +0 -1
  467. package/dist/ui/assets/riscv-Ckw8ddFX.js +0 -1
  468. package/dist/ui/assets/ron-VUp2lXgN.js +0 -1
  469. package/dist/ui/assets/rose-pine-BthvhNj6.js +0 -1
  470. package/dist/ui/assets/rose-pine-dawn-Dg85fqjY.js +0 -1
  471. package/dist/ui/assets/rose-pine-moon-hon4tzzS.js +0 -1
  472. package/dist/ui/assets/rosmsg-CAekHB0j.js +0 -1
  473. package/dist/ui/assets/rst-CfBbbcvC.js +0 -1
  474. package/dist/ui/assets/ruby-Bw0mpxHY.js +0 -1
  475. package/dist/ui/assets/rust-Cfkwpbl8.js +0 -1
  476. package/dist/ui/assets/sas-Cs3s9JOf.js +0 -1
  477. package/dist/ui/assets/sass-DXrisJhu.js +0 -1
  478. package/dist/ui/assets/scala-DKOlJaKm.js +0 -1
  479. package/dist/ui/assets/scheme-DQCgrYNe.js +0 -1
  480. package/dist/ui/assets/scss-sRxNJS54.js +0 -1
  481. package/dist/ui/assets/sdbl-bTVj8UrX.js +0 -1
  482. package/dist/ui/assets/shaderlab-TOUzSsQk.js +0 -1
  483. package/dist/ui/assets/shellscript-B0X6wh0R.js +0 -1
  484. package/dist/ui/assets/shellsession-D2FdOioR.js +0 -1
  485. package/dist/ui/assets/slack-dark-DnToyrRv.js +0 -1
  486. package/dist/ui/assets/slack-ochin-B2OO5cIa.js +0 -1
  487. package/dist/ui/assets/smalltalk-B16xEiuN.js +0 -1
  488. package/dist/ui/assets/snazzy-light-4G7pJPwS.js +0 -1
  489. package/dist/ui/assets/solarized-dark-DV17i1UV.js +0 -1
  490. package/dist/ui/assets/solarized-light-DSh2HLQt.js +0 -1
  491. package/dist/ui/assets/solidity-CKzVLygQ.js +0 -1
  492. package/dist/ui/assets/soy-s6g9OjJ1.js +0 -1
  493. package/dist/ui/assets/sparql-D_iOobhT.js +0 -1
  494. package/dist/ui/assets/splunk-BC2Px7Mm.js +0 -1
  495. package/dist/ui/assets/sql-DVTnh5V-.js +0 -1
  496. package/dist/ui/assets/ssh-config-BgfXC-Er.js +0 -1
  497. package/dist/ui/assets/stata-DFIDiXF9.js +0 -1
  498. package/dist/ui/assets/stylus-B6D30XZt.js +0 -1
  499. package/dist/ui/assets/surrealql-DVfrsLyg.js +0 -1
  500. package/dist/ui/assets/svelte-D5GsxESq.js +0 -1
  501. package/dist/ui/assets/swift-DonLKvLd.js +0 -1
  502. package/dist/ui/assets/synthwave-84-nFMaYfgc.js +0 -1
  503. package/dist/ui/assets/system-verilog-DJ5XKQeo.js +0 -1
  504. package/dist/ui/assets/systemd-BxMlprV5.js +0 -1
  505. package/dist/ui/assets/talonscript-CohzipZa.js +0 -1
  506. package/dist/ui/assets/tasl-DMoTqEGO.js +0 -1
  507. package/dist/ui/assets/tcl-CZd0xW_V.js +0 -1
  508. package/dist/ui/assets/templ-DI-Zyqzd.js +0 -1
  509. package/dist/ui/assets/terraform-DswuEJGm.js +0 -1
  510. package/dist/ui/assets/tex-WHHmlbJI.js +0 -1
  511. package/dist/ui/assets/tokyo-night-oM2G3aXe.js +0 -1
  512. package/dist/ui/assets/toml-CcmNWLt0.js +0 -1
  513. package/dist/ui/assets/ts-tags-Dwpo2RFJ.js +0 -1
  514. package/dist/ui/assets/tsv-sltzmVWM.js +0 -1
  515. package/dist/ui/assets/tsx-ph_idaAW.js +0 -1
  516. package/dist/ui/assets/turtle-ByJddavk.js +0 -1
  517. package/dist/ui/assets/twig-YO17jFjR.js +0 -1
  518. package/dist/ui/assets/typescript-CbAxjhkl.js +0 -1
  519. package/dist/ui/assets/typespec-B88KGewJ.js +0 -1
  520. package/dist/ui/assets/typst-DI99ib-x.js +0 -1
  521. package/dist/ui/assets/useFileDiffInstance-B2DLX3Vg.js +0 -244
  522. package/dist/ui/assets/v-DETTlOr0.js +0 -1
  523. package/dist/ui/assets/vala-zf12oZj6.js +0 -1
  524. package/dist/ui/assets/vb-Djn5o6TS.js +0 -1
  525. package/dist/ui/assets/verilog-CiiDBU1e.js +0 -1
  526. package/dist/ui/assets/vesper-D5bVUKB1.js +0 -1
  527. package/dist/ui/assets/vhdl-BroJfC0k.js +0 -1
  528. package/dist/ui/assets/viml-DvXPmvsu.js +0 -1
  529. package/dist/ui/assets/vitesse-black-fwtXNY1n.js +0 -1
  530. package/dist/ui/assets/vitesse-dark-BZCL-v6S.js +0 -1
  531. package/dist/ui/assets/vitesse-light-VbXTXTou.js +0 -1
  532. package/dist/ui/assets/vue-CraHL-Ps.js +0 -1
  533. package/dist/ui/assets/vue-html-e9tyZNtS.js +0 -1
  534. package/dist/ui/assets/vue-vine-CofmxaUb.js +0 -1
  535. package/dist/ui/assets/vyper-CgoNMtux.js +0 -1
  536. package/dist/ui/assets/wasm-BnjxR4X6.js +0 -1
  537. package/dist/ui/assets/wasm-ByWQv1Qj.js +0 -1
  538. package/dist/ui/assets/wenyan-C8pVoKbM.js +0 -1
  539. package/dist/ui/assets/wgsl-BsKzXJz4.js +0 -1
  540. package/dist/ui/assets/wikitext-ClFFjSW2.js +0 -1
  541. package/dist/ui/assets/wit-DdvCle-K.js +0 -1
  542. package/dist/ui/assets/wolfram-DLL8P-h_.js +0 -1
  543. package/dist/ui/assets/workspace-app-8--oTbCd.css +0 -1
  544. package/dist/ui/assets/xml-BWSdPZHm.js +0 -1
  545. package/dist/ui/assets/xsl-BtCt7Hx8.js +0 -1
  546. package/dist/ui/assets/yaml-BZiTw7cQ.js +0 -1
  547. package/dist/ui/assets/zenscript-BnlCZFoB.js +0 -1
  548. package/dist/ui/assets/zig-CMLA9XwU.js +0 -1
  549. package/docs/assets/auvrynt-logo-light.png +0 -0
  550. 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.