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,594 @@
|
|
|
1
|
+
local BRIDGE_VERSION = "1.2.0"
|
|
2
|
+
local live_commands = nil
|
|
3
|
+
local POLL_INTERVAL = 0.10
|
|
4
|
+
local timer = nil
|
|
5
|
+
local bridge_root = nil
|
|
6
|
+
local requests_dir = nil
|
|
7
|
+
local responses_dir = nil
|
|
8
|
+
local auth_path = nil
|
|
9
|
+
local auth_token = nil
|
|
10
|
+
|
|
11
|
+
local function read_file(path)
|
|
12
|
+
local file = io.open(path, "rb")
|
|
13
|
+
if not file then return nil end
|
|
14
|
+
local value = file:read("*a")
|
|
15
|
+
file:close()
|
|
16
|
+
return value
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
local function write_file(path, value)
|
|
20
|
+
local file, err = io.open(path, "wb")
|
|
21
|
+
if not file then error(err or "Unable to open output file", 0) end
|
|
22
|
+
file:write(value)
|
|
23
|
+
file:flush()
|
|
24
|
+
file:close()
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
local function write_json_atomic(path, value)
|
|
28
|
+
local temporary = path .. ".tmp"
|
|
29
|
+
write_file(temporary, json.encode(value))
|
|
30
|
+
os.remove(path)
|
|
31
|
+
local ok, err = os.rename(temporary, path)
|
|
32
|
+
if not ok then
|
|
33
|
+
os.remove(temporary)
|
|
34
|
+
error(err or "Unable to publish bridge response", 0)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
local function ensure_directories()
|
|
39
|
+
bridge_root = app.fs.joinPath(app.fs.userConfigPath, "auvrynt-bridge")
|
|
40
|
+
requests_dir = app.fs.joinPath(bridge_root, "requests")
|
|
41
|
+
responses_dir = app.fs.joinPath(bridge_root, "responses")
|
|
42
|
+
auth_path = app.fs.joinPath(bridge_root, "auth.json")
|
|
43
|
+
app.fs.makeAllDirectories(requests_dir)
|
|
44
|
+
app.fs.makeAllDirectories(responses_dir)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
local function is_json_object(value)
|
|
48
|
+
local kind = type(value)
|
|
49
|
+
return kind == "table" or kind == "userdata"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
local function refresh_auth_token()
|
|
53
|
+
local raw = read_file(auth_path)
|
|
54
|
+
if not raw then auth_token = nil return end
|
|
55
|
+
local ok, value = pcall(json.decode, raw)
|
|
56
|
+
auth_token = ok and is_json_object(value) and value.token or nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
local function sequence_length(value)
|
|
60
|
+
if value == nil then return nil end
|
|
61
|
+
local ok, count = pcall(function() return #value end)
|
|
62
|
+
return ok and count or nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
local function color_table(color)
|
|
66
|
+
if not color then return nil end
|
|
67
|
+
return { r=color.red, g=color.green, b=color.blue, a=color.alpha }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
local function color_from_request(value, fallback)
|
|
71
|
+
-- NOTE: this JSON decoder represents decoded objects as either "table" or
|
|
72
|
+
-- "userdata" (see is_json_object below, used elsewhere for the same
|
|
73
|
+
-- reason). The previous type(value) ~= "table" check rejected the
|
|
74
|
+
-- userdata case, silently discarding every color sent by the MCP client
|
|
75
|
+
-- and falling back to fully-transparent black (or the untouched current
|
|
76
|
+
-- foreground), which is why live strokes/pixels/set_colors appeared to
|
|
77
|
+
-- draw nothing.
|
|
78
|
+
if not is_json_object(value) then return fallback or Color() end
|
|
79
|
+
return Color{
|
|
80
|
+
r=math.max(0, math.min(255, tonumber(value.r) or 0)),
|
|
81
|
+
g=math.max(0, math.min(255, tonumber(value.g) or 0)),
|
|
82
|
+
b=math.max(0, math.min(255, tonumber(value.b) or 0)),
|
|
83
|
+
a=math.max(0, math.min(255, tonumber(value.a) or 255)),
|
|
84
|
+
}
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
local function plain_properties(properties)
|
|
88
|
+
local result = {}
|
|
89
|
+
if not properties then return result end
|
|
90
|
+
for key, value in pairs(properties) do
|
|
91
|
+
local value_type = type(value)
|
|
92
|
+
if value_type == "string" or value_type == "number" or value_type == "boolean" then
|
|
93
|
+
result[tostring(key)] = value
|
|
94
|
+
else
|
|
95
|
+
result[tostring(key)] = tostring(value)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
return result
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
local function flatten_layers(items, parent, result)
|
|
102
|
+
for _, layer in ipairs(items) do
|
|
103
|
+
table.insert(result, {
|
|
104
|
+
id=tostring(layer.id),
|
|
105
|
+
name=layer.name,
|
|
106
|
+
parent=parent,
|
|
107
|
+
isGroup=layer.isGroup,
|
|
108
|
+
isTilemap=layer.isTilemap,
|
|
109
|
+
isVisible=layer.isVisible,
|
|
110
|
+
isEditable=layer.isEditable,
|
|
111
|
+
opacity=layer.opacity,
|
|
112
|
+
blendMode=tostring(layer.blendMode),
|
|
113
|
+
celCount=#layer.cels,
|
|
114
|
+
data=layer.data,
|
|
115
|
+
properties=plain_properties(layer.properties),
|
|
116
|
+
})
|
|
117
|
+
if layer.isGroup then flatten_layers(layer.layers, layer.name, result) end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
local function find_layer(items, name_or_id)
|
|
122
|
+
if name_or_id == nil then return nil end
|
|
123
|
+
for _, layer in ipairs(items) do
|
|
124
|
+
if layer.name == name_or_id or tostring(layer.id) == tostring(name_or_id) then return layer end
|
|
125
|
+
if layer.isGroup then
|
|
126
|
+
local nested = find_layer(layer.layers, name_or_id)
|
|
127
|
+
if nested then return nested end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
return nil
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
local function find_sprite(request)
|
|
134
|
+
local target = request.documentId or request.filename
|
|
135
|
+
if target == nil then return app.activeSprite end
|
|
136
|
+
for _, sprite in ipairs(app.sprites) do
|
|
137
|
+
if tostring(sprite.id) == tostring(target) or sprite.filename == target then return sprite end
|
|
138
|
+
end
|
|
139
|
+
return nil
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
local function normalize_path(path)
|
|
143
|
+
if type(path) ~= "string" or path == "" then return nil end
|
|
144
|
+
return path:gsub("\\", "/"):lower()
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
local function find_open_sprite_by_path(path)
|
|
148
|
+
local normalized = normalize_path(path)
|
|
149
|
+
if not normalized then return nil end
|
|
150
|
+
for _, sprite in ipairs(app.sprites) do
|
|
151
|
+
if normalize_path(sprite.filename) == normalized then return sprite end
|
|
152
|
+
end
|
|
153
|
+
return nil
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
local function palette_rows(sprite)
|
|
157
|
+
local result = {}
|
|
158
|
+
if #sprite.palettes == 0 then return result end
|
|
159
|
+
local palette = sprite.palettes[1]
|
|
160
|
+
for index=0,#palette-1 do
|
|
161
|
+
local color = palette:getColor(index)
|
|
162
|
+
table.insert(result, {
|
|
163
|
+
index=index,
|
|
164
|
+
r=color.red,
|
|
165
|
+
g=color.green,
|
|
166
|
+
b=color.blue,
|
|
167
|
+
a=index == sprite.transparentColor and 0 or color.alpha,
|
|
168
|
+
})
|
|
169
|
+
end
|
|
170
|
+
return result
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
local function sprite_state(sprite)
|
|
174
|
+
if not sprite then return nil end
|
|
175
|
+
local layers = {}
|
|
176
|
+
flatten_layers(sprite.layers, nil, layers)
|
|
177
|
+
local frames = {}
|
|
178
|
+
for _, frame in ipairs(sprite.frames) do
|
|
179
|
+
table.insert(frames, { frame=frame.frameNumber, durationMs=math.floor(frame.duration*1000+0.5) })
|
|
180
|
+
end
|
|
181
|
+
local tags = {}
|
|
182
|
+
for _, tag in ipairs(sprite.tags) do
|
|
183
|
+
table.insert(tags, {
|
|
184
|
+
name=tag.name,
|
|
185
|
+
from=tag.fromFrame.frameNumber,
|
|
186
|
+
to=tag.toFrame.frameNumber,
|
|
187
|
+
direction=tostring(tag.aniDir),
|
|
188
|
+
repeats=tag.repeats,
|
|
189
|
+
data=tag.data,
|
|
190
|
+
properties=plain_properties(tag.properties),
|
|
191
|
+
})
|
|
192
|
+
end
|
|
193
|
+
local selection = sprite.selection
|
|
194
|
+
local selection_bounds = nil
|
|
195
|
+
if selection and not selection.isEmpty then
|
|
196
|
+
selection_bounds = {
|
|
197
|
+
x=selection.bounds.x,
|
|
198
|
+
y=selection.bounds.y,
|
|
199
|
+
width=selection.bounds.width,
|
|
200
|
+
height=selection.bounds.height,
|
|
201
|
+
}
|
|
202
|
+
end
|
|
203
|
+
local onionskin = app.preferences.document(sprite).onionskin
|
|
204
|
+
local editor = app.editor
|
|
205
|
+
local brush = app.activeBrush
|
|
206
|
+
return {
|
|
207
|
+
id=tostring(sprite.id),
|
|
208
|
+
filename=sprite.filename,
|
|
209
|
+
hasAssociatedFile=sprite.hasAssociatedFile,
|
|
210
|
+
isModified=sprite.isModified,
|
|
211
|
+
width=sprite.width,
|
|
212
|
+
height=sprite.height,
|
|
213
|
+
colorMode=tostring(sprite.colorMode),
|
|
214
|
+
colorSpace=sprite.colorSpace and sprite.colorSpace.name or nil,
|
|
215
|
+
transparentColor=sprite.transparentColor,
|
|
216
|
+
pixelRatio={ width=sprite.pixelRatio.width, height=sprite.pixelRatio.height },
|
|
217
|
+
grid={ x=sprite.gridBounds.x, y=sprite.gridBounds.y, width=sprite.gridBounds.width, height=sprite.gridBounds.height },
|
|
218
|
+
frameCount=#sprite.frames,
|
|
219
|
+
activeFrame=app.activeFrame and app.activeFrame.frameNumber or nil,
|
|
220
|
+
activeLayer=app.activeLayer and { id=tostring(app.activeLayer.id), name=app.activeLayer.name } or nil,
|
|
221
|
+
activeTool=app.activeTool and app.activeTool.id or nil,
|
|
222
|
+
activeBrush=brush and { type=tostring(brush.type), size=brush.size, angle=brush.angle } or nil,
|
|
223
|
+
foreground=color_table(app.fgColor),
|
|
224
|
+
background=color_table(app.bgColor),
|
|
225
|
+
editorZoom=editor and editor.zoom or nil,
|
|
226
|
+
selection=selection_bounds,
|
|
227
|
+
onionskin={
|
|
228
|
+
active=onionskin.active,
|
|
229
|
+
prevFrames=onionskin.prev_frames,
|
|
230
|
+
nextFrames=onionskin.next_frames,
|
|
231
|
+
opacityBase=onionskin.opacity_base,
|
|
232
|
+
opacityStep=onionskin.opacity_step,
|
|
233
|
+
loopTag=onionskin.loop_tag,
|
|
234
|
+
currentLayer=onionskin.current_layer,
|
|
235
|
+
type=tostring(onionskin.type),
|
|
236
|
+
position=tostring(onionskin.position),
|
|
237
|
+
},
|
|
238
|
+
layers=layers,
|
|
239
|
+
frames=frames,
|
|
240
|
+
tags=tags,
|
|
241
|
+
palette=palette_rows(sprite),
|
|
242
|
+
data=sprite.data,
|
|
243
|
+
properties=plain_properties(sprite.properties),
|
|
244
|
+
}
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
local function document_list()
|
|
248
|
+
local result = {}
|
|
249
|
+
for _, sprite in ipairs(app.sprites) do
|
|
250
|
+
table.insert(result, {
|
|
251
|
+
id=tostring(sprite.id),
|
|
252
|
+
filename=sprite.filename,
|
|
253
|
+
width=sprite.width,
|
|
254
|
+
height=sprite.height,
|
|
255
|
+
frames=#sprite.frames,
|
|
256
|
+
modified=sprite.isModified,
|
|
257
|
+
active=sprite == app.activeSprite,
|
|
258
|
+
})
|
|
259
|
+
end
|
|
260
|
+
return result
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
local function ensure_canvas_cel(sprite, layer, frame_number)
|
|
264
|
+
local cel = layer:cel(frame_number)
|
|
265
|
+
if cel == nil then
|
|
266
|
+
local image = Image(sprite.spec)
|
|
267
|
+
image:clear()
|
|
268
|
+
cel = sprite:newCel(layer, frame_number, image, Point(0, 0))
|
|
269
|
+
elseif cel.position.x ~= 0 or cel.position.y ~= 0 or cel.image.width ~= sprite.width or cel.image.height ~= sprite.height then
|
|
270
|
+
local image = Image(sprite.spec)
|
|
271
|
+
image:clear()
|
|
272
|
+
image:drawImage(cel.image, cel.position)
|
|
273
|
+
cel.image = image
|
|
274
|
+
cel.position = Point(0, 0)
|
|
275
|
+
end
|
|
276
|
+
return cel
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
local function rgba_pixel(sprite, color)
|
|
280
|
+
if sprite.colorMode == ColorMode.RGB then
|
|
281
|
+
return app.pixelColor.rgba(color.red, color.green, color.blue, color.alpha)
|
|
282
|
+
elseif sprite.colorMode == ColorMode.GRAY then
|
|
283
|
+
local gray = math.floor((color.red*299 + color.green*587 + color.blue*114)/1000)
|
|
284
|
+
return app.pixelColor.graya(gray, color.alpha)
|
|
285
|
+
else
|
|
286
|
+
local palette = sprite.palettes[1]
|
|
287
|
+
local best = 0
|
|
288
|
+
local distance = math.huge
|
|
289
|
+
for index=0,#palette-1 do
|
|
290
|
+
local candidate = palette:getColor(index)
|
|
291
|
+
local dr=candidate.red-color.red
|
|
292
|
+
local dg=candidate.green-color.green
|
|
293
|
+
local db=candidate.blue-color.blue
|
|
294
|
+
local da=(index == sprite.transparentColor and 0 or candidate.alpha)-color.alpha
|
|
295
|
+
local current=dr*dr+dg*dg+db*db+da*da
|
|
296
|
+
if current<distance then best=index distance=current end
|
|
297
|
+
end
|
|
298
|
+
return best
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
local function set_active_target(sprite, request)
|
|
303
|
+
app.activeSprite = sprite
|
|
304
|
+
if request.layer then
|
|
305
|
+
local layer = find_layer(sprite.layers, request.layer)
|
|
306
|
+
if not layer then error("Layer was not found", 0) end
|
|
307
|
+
app.activeLayer = layer
|
|
308
|
+
end
|
|
309
|
+
if request.frame then
|
|
310
|
+
local frame_number = math.floor(tonumber(request.frame) or 0)
|
|
311
|
+
if frame_number < 1 or frame_number > #sprite.frames then error("Frame is outside the sprite", 0) end
|
|
312
|
+
app.activeFrame = sprite.frames[frame_number]
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
local function capture_canvas(sprite, request)
|
|
317
|
+
local frame_number = math.floor(tonumber(request.frame) or (app.activeFrame and app.activeFrame.frameNumber) or 1)
|
|
318
|
+
if frame_number < 1 or frame_number > #sprite.frames then error("Frame is outside the sprite", 0) end
|
|
319
|
+
local output_path = request.outputPath
|
|
320
|
+
if type(output_path) ~= "string" or output_path == "" then error("outputPath is required", 0) end
|
|
321
|
+
local scale = math.max(1, math.min(32, math.floor(tonumber(request.scale) or 1)))
|
|
322
|
+
local render = Image(sprite.spec)
|
|
323
|
+
render:clear()
|
|
324
|
+
render:drawSprite(sprite, frame_number, Point(0, 0))
|
|
325
|
+
if scale == 1 then
|
|
326
|
+
if not render:saveAs(output_path) then error("Unable to save canvas capture", 0) end
|
|
327
|
+
else
|
|
328
|
+
local output = Image(sprite.width*scale, sprite.height*scale, ColorMode.RGB)
|
|
329
|
+
output:clear()
|
|
330
|
+
local palette = #sprite.palettes > 0 and sprite.palettes[1] or nil
|
|
331
|
+
for y=0,sprite.height-1 do
|
|
332
|
+
for x=0,sprite.width-1 do
|
|
333
|
+
local source_pixel = render:getPixel(x,y)
|
|
334
|
+
local color
|
|
335
|
+
if sprite.colorMode == ColorMode.RGB then
|
|
336
|
+
color = Color{
|
|
337
|
+
r=app.pixelColor.rgbaR(source_pixel),
|
|
338
|
+
g=app.pixelColor.rgbaG(source_pixel),
|
|
339
|
+
b=app.pixelColor.rgbaB(source_pixel),
|
|
340
|
+
a=app.pixelColor.rgbaA(source_pixel),
|
|
341
|
+
}
|
|
342
|
+
elseif sprite.colorMode == ColorMode.GRAY then
|
|
343
|
+
local gray=app.pixelColor.grayaV(source_pixel)
|
|
344
|
+
color=Color{r=gray,g=gray,b=gray,a=app.pixelColor.grayaA(source_pixel)}
|
|
345
|
+
else
|
|
346
|
+
local palette_color=palette:getColor(source_pixel)
|
|
347
|
+
color=Color{r=palette_color.red,g=palette_color.green,b=palette_color.blue,a=source_pixel==sprite.transparentColor and 0 or palette_color.alpha}
|
|
348
|
+
end
|
|
349
|
+
local pixel=app.pixelColor.rgba(color.red,color.green,color.blue,color.alpha)
|
|
350
|
+
for dy=0,scale-1 do for dx=0,scale-1 do output:drawPixel(x*scale+dx,y*scale+dy,pixel) end end
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
if not output:saveAs(output_path) then error("Unable to save scaled canvas capture", 0) end
|
|
354
|
+
end
|
|
355
|
+
return { outputPath=output_path, frame=frame_number, width=sprite.width*scale, height=sprite.height*scale, scale=scale }
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
local SAFE_COMMANDS = {
|
|
359
|
+
DuplicateLayer=true,
|
|
360
|
+
MergeDownLayer=true,
|
|
361
|
+
FlattenLayers=true,
|
|
362
|
+
BackgroundFromLayer=true,
|
|
363
|
+
LayerFromBackground=true,
|
|
364
|
+
ReverseFrames=true,
|
|
365
|
+
ClearCel=true,
|
|
366
|
+
NewFrame=true,
|
|
367
|
+
RemoveFrame=true,
|
|
368
|
+
NewLayer=true,
|
|
369
|
+
RemoveLayer=true,
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
local function handle_request(request)
|
|
373
|
+
local action = request.action
|
|
374
|
+
if action == "status" then
|
|
375
|
+
return { bridgeVersion=BRIDGE_VERSION, asepriteVersion=tostring(app.version), apiVersion=app.apiVersion, uiAvailable=app.isUIAvailable, documents=#app.sprites, liveCommands=live_commands.names(), active=sprite_state(app.activeSprite) }
|
|
376
|
+
elseif action == "list_documents" then
|
|
377
|
+
return { documents=document_list() }
|
|
378
|
+
elseif action == "new_document" then
|
|
379
|
+
local width=math.max(1,math.min(8192,math.floor(tonumber(request.width) or 1)))
|
|
380
|
+
local height=math.max(1,math.min(8192,math.floor(tonumber(request.height) or 1)))
|
|
381
|
+
local mode=request.colorMode == "indexed" and ColorMode.INDEXED or request.colorMode == "grayscale" and ColorMode.GRAY or ColorMode.RGB
|
|
382
|
+
local sprite=Sprite(width,height,mode)
|
|
383
|
+
app.activeSprite=sprite
|
|
384
|
+
return { document=sprite_state(sprite) }
|
|
385
|
+
elseif action == "open_document" then
|
|
386
|
+
if type(request.path)~="string" or request.path=="" then error("path is required",0) end
|
|
387
|
+
-- Reuse an already-open document for this path instead of calling
|
|
388
|
+
-- app.open() again. This makes the action idempotent: if a caller times
|
|
389
|
+
-- out waiting for a slow open and retries with a new request id, the
|
|
390
|
+
-- retry attaches to the same sprite instead of opening a duplicate tab.
|
|
391
|
+
local sprite=find_open_sprite_by_path(request.path)
|
|
392
|
+
if not sprite then
|
|
393
|
+
sprite=app.open(request.path)
|
|
394
|
+
if not sprite then error("Unable to open document",0) end
|
|
395
|
+
end
|
|
396
|
+
app.activeSprite=sprite
|
|
397
|
+
return { document=sprite_state(sprite) }
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
local sprite = find_sprite(request)
|
|
401
|
+
if not sprite then error("Aseprite document was not found", 0) end
|
|
402
|
+
set_active_target(sprite, request)
|
|
403
|
+
|
|
404
|
+
if action == "inspect" or action == "select_document" or action == "select_layer" or action == "select_frame" then
|
|
405
|
+
return { document=sprite_state(sprite) }
|
|
406
|
+
elseif action == "save" then
|
|
407
|
+
if sprite.filename == "" then error("Document has no associated filename; use save_as", 0) end
|
|
408
|
+
if not sprite:saveAs(sprite.filename) then error("Unable to save document", 0) end
|
|
409
|
+
elseif action == "save_as" then
|
|
410
|
+
if type(request.path)~="string" or request.path=="" then error("path is required",0) end
|
|
411
|
+
if not sprite:saveAs(request.path) then error("Unable to save document",0) end
|
|
412
|
+
elseif action == "close_document" then
|
|
413
|
+
if sprite.isModified and request.discardChanges ~= true then error("Document has unsaved changes; set discardChanges=true to close it",0) end
|
|
414
|
+
sprite:close()
|
|
415
|
+
return { closed=true, documents=document_list() }
|
|
416
|
+
elseif action == "undo" then app.undo()
|
|
417
|
+
elseif action == "redo" then app.redo()
|
|
418
|
+
elseif action == "toggle_playback" then app.command.PlayAnimation()
|
|
419
|
+
elseif action == "set_zoom" then
|
|
420
|
+
if not app.editor then error("No active editor",0) end
|
|
421
|
+
app.editor.zoom=math.max(0.01,math.min(64,tonumber(request.zoom) or 1))
|
|
422
|
+
elseif action == "set_onion_skin" then
|
|
423
|
+
local prefs=app.preferences.document(sprite).onionskin
|
|
424
|
+
if request.active~=nil then prefs.active=request.active==true end
|
|
425
|
+
if request.prevFrames~=nil then prefs.prev_frames=math.max(0,math.floor(request.prevFrames)) end
|
|
426
|
+
if request.nextFrames~=nil then prefs.next_frames=math.max(0,math.floor(request.nextFrames)) end
|
|
427
|
+
if request.opacityBase~=nil then prefs.opacity_base=math.max(0,math.min(255,math.floor(request.opacityBase))) end
|
|
428
|
+
if request.opacityStep~=nil then prefs.opacity_step=math.max(0,math.min(255,math.floor(request.opacityStep))) end
|
|
429
|
+
if request.loopTag~=nil then prefs.loop_tag=request.loopTag==true end
|
|
430
|
+
if request.currentLayer~=nil then prefs.current_layer=request.currentLayer==true end
|
|
431
|
+
elseif action == "set_tool" then
|
|
432
|
+
if type(request.tool)~="string" or request.tool=="" then error("tool is required",0) end
|
|
433
|
+
app.activeTool=request.tool
|
|
434
|
+
elseif action == "set_colors" then
|
|
435
|
+
if request.foreground then app.fgColor=color_from_request(request.foreground,app.fgColor) end
|
|
436
|
+
if request.background then app.bgColor=color_from_request(request.background,app.bgColor) end
|
|
437
|
+
elseif action == "set_brush" then
|
|
438
|
+
local brush_type=request.brushType=="square" and BrushType.SQUARE or request.brushType=="line" and BrushType.LINE or BrushType.CIRCLE
|
|
439
|
+
app.activeBrush=Brush{type=brush_type,size=math.max(1,math.min(256,math.floor(tonumber(request.size) or 1))),angle=math.floor(tonumber(request.angle) or 0)}
|
|
440
|
+
elseif action == "set_selection" then
|
|
441
|
+
local bounds=request.bounds
|
|
442
|
+
if type(bounds)~="table" then error("bounds is required",0) end
|
|
443
|
+
local rectangle=Rectangle(math.floor(bounds.x or 0),math.floor(bounds.y or 0),math.max(1,math.floor(bounds.width or 1)),math.max(1,math.floor(bounds.height or 1)))
|
|
444
|
+
local selection=sprite.selection
|
|
445
|
+
local mode=request.mode or "replace"
|
|
446
|
+
if mode=="replace" then selection:select(rectangle)
|
|
447
|
+
elseif mode=="add" then selection:add(rectangle)
|
|
448
|
+
elseif mode=="subtract" then selection:subtract(rectangle)
|
|
449
|
+
elseif mode=="intersect" then selection:intersect(rectangle)
|
|
450
|
+
else error("Unsupported selection mode",0) end
|
|
451
|
+
elseif action == "clear_selection" then sprite.selection:deselect()
|
|
452
|
+
elseif action == "capture_canvas" then return capture_canvas(sprite,request)
|
|
453
|
+
elseif action == "run_live_command" then
|
|
454
|
+
local result = live_commands.run(sprite, request)
|
|
455
|
+
app.refresh()
|
|
456
|
+
return { command=request.liveCommand, result=result, document=sprite_state(app.activeSprite) }
|
|
457
|
+
elseif action == "set_pixels" then
|
|
458
|
+
local layer=app.activeLayer or sprite.layers[1]
|
|
459
|
+
if layer.isGroup or layer.isTilemap then error("A normal drawable layer is required",0) end
|
|
460
|
+
local frame_number=app.activeFrame and app.activeFrame.frameNumber or 1
|
|
461
|
+
local image=ensure_canvas_cel(sprite,layer,frame_number).image
|
|
462
|
+
local pixels=request.pixels
|
|
463
|
+
local pixel_count=sequence_length(pixels)
|
|
464
|
+
if not pixel_count or pixel_count>8192 then error("pixels must contain at most 8192 entries",0) end
|
|
465
|
+
for index=1,pixel_count do
|
|
466
|
+
local entry=pixels[index]
|
|
467
|
+
local x=math.floor(tonumber(entry.x) or -1) local y=math.floor(tonumber(entry.y) or -1)
|
|
468
|
+
if x<0 or y<0 or x>=sprite.width or y>=sprite.height then error("Pixel is outside the sprite",0) end
|
|
469
|
+
image:drawPixel(x,y,rgba_pixel(sprite,color_from_request(entry.color)))
|
|
470
|
+
end
|
|
471
|
+
elseif action == "draw_stroke" then
|
|
472
|
+
local points={}
|
|
473
|
+
local point_count=sequence_length(request.points)
|
|
474
|
+
if not point_count or point_count<1 or point_count>16384 then error("points must contain 1-16384 entries",0) end
|
|
475
|
+
for index=1,point_count do local entry=request.points[index] table.insert(points,Point(math.floor(entry.x),math.floor(entry.y))) end
|
|
476
|
+
app.useTool{
|
|
477
|
+
tool=request.tool or "pencil",
|
|
478
|
+
color=color_from_request(request.color,app.fgColor),
|
|
479
|
+
opacity=math.max(0,math.min(255,math.floor(tonumber(request.opacity) or 255))),
|
|
480
|
+
brush=Brush{type=BrushType.CIRCLE,size=math.max(1,math.min(256,math.floor(tonumber(request.size) or 1)))},
|
|
481
|
+
freehandAlgorithm=request.pixelPerfect==true and 1 or 0,
|
|
482
|
+
points=points,
|
|
483
|
+
}
|
|
484
|
+
elseif action == "create_layer" then
|
|
485
|
+
local layer=request.group==true and sprite:newGroup() or sprite:newLayer()
|
|
486
|
+
layer.name=request.name or (request.group==true and "Group" or "Layer")
|
|
487
|
+
app.activeLayer=layer
|
|
488
|
+
elseif action == "create_frame" then
|
|
489
|
+
local index=math.max(1,math.min(#sprite.frames+1,math.floor(tonumber(request.frame) or (#sprite.frames+1))))
|
|
490
|
+
local frame=request.duplicate==true and sprite:newFrame(math.min(index,#sprite.frames)) or sprite:newEmptyFrame(index)
|
|
491
|
+
if request.durationMs then frame.duration=math.max(1,math.floor(request.durationMs))/1000 end
|
|
492
|
+
app.activeFrame=frame
|
|
493
|
+
elseif action == "delete_frame" then
|
|
494
|
+
local frame_number=app.activeFrame and app.activeFrame.frameNumber or 1
|
|
495
|
+
if #sprite.frames<=1 then error("Cannot delete the only frame",0) end
|
|
496
|
+
sprite:deleteFrame(frame_number)
|
|
497
|
+
elseif action == "set_frame_duration" then
|
|
498
|
+
local frame=app.activeFrame or sprite.frames[1]
|
|
499
|
+
frame.duration=math.max(1,math.min(60000,math.floor(tonumber(request.durationMs) or 100)))/1000
|
|
500
|
+
elseif action == "safe_command" then
|
|
501
|
+
local command=request.command
|
|
502
|
+
if not SAFE_COMMANDS[command] then error("Command is not allowlisted",0) end
|
|
503
|
+
local fn=app.command[command]
|
|
504
|
+
if type(fn)~="function" then error("Aseprite command is unavailable",0) end
|
|
505
|
+
fn(request.params or {})
|
|
506
|
+
else
|
|
507
|
+
error("Unsupported Auvrynt bridge action: "..tostring(action),0)
|
|
508
|
+
end
|
|
509
|
+
app.refresh()
|
|
510
|
+
return { document=sprite_state(sprite) }
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
local function process_request_file(filename)
|
|
514
|
+
local request_path=app.fs.joinPath(requests_dir,filename)
|
|
515
|
+
local claimed_path=request_path..".processing"
|
|
516
|
+
-- Claim the request file (rename it out of the requests directory) before
|
|
517
|
+
-- doing any work, rather than after. Previously the file was only removed
|
|
518
|
+
-- once handle_request finished, so a slow handler (e.g. open_document on a
|
|
519
|
+
-- large sprite) left it visible to the requests listing for the whole
|
|
520
|
+
-- duration of the call. Claiming it up front closes that window entirely.
|
|
521
|
+
if not os.rename(request_path,claimed_path) then return end
|
|
522
|
+
local raw=read_file(claimed_path)
|
|
523
|
+
if not raw then os.remove(claimed_path) return end
|
|
524
|
+
local response={ok=false}
|
|
525
|
+
local request_id=app.fs.fileTitle(filename)
|
|
526
|
+
local decode_ok,request=pcall(json.decode,raw)
|
|
527
|
+
if not decode_ok or not is_json_object(request) then
|
|
528
|
+
response.error="Invalid request JSON"
|
|
529
|
+
elseif not auth_token or request.token~=auth_token then
|
|
530
|
+
response.error="Invalid bridge token"
|
|
531
|
+
elseif tostring(request.id or "")~=request_id then
|
|
532
|
+
response.error="Request ID mismatch"
|
|
533
|
+
else
|
|
534
|
+
local ok,result=pcall(handle_request,request)
|
|
535
|
+
if ok then response.ok=true response.result=result
|
|
536
|
+
else response.error=tostring(result) end
|
|
537
|
+
end
|
|
538
|
+
response.id=request_id
|
|
539
|
+
response.bridgeVersion=BRIDGE_VERSION
|
|
540
|
+
local response_path=app.fs.joinPath(responses_dir,request_id..".json")
|
|
541
|
+
pcall(write_json_atomic,response_path,response)
|
|
542
|
+
os.remove(claimed_path)
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
local function poll_requests()
|
|
546
|
+
if not auth_token then refresh_auth_token() end
|
|
547
|
+
local files=app.fs.listFiles(requests_dir)
|
|
548
|
+
table.sort(files)
|
|
549
|
+
local processed=0
|
|
550
|
+
for _,filename in ipairs(files) do
|
|
551
|
+
if filename:match("^[%w%-_]+%.json$") then
|
|
552
|
+
process_request_file(filename)
|
|
553
|
+
processed=processed+1
|
|
554
|
+
if processed>=16 then break end
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
function init(plugin)
|
|
560
|
+
-- Aseprite does not guarantee that an extension's directory is in Lua's
|
|
561
|
+
-- module search path. Configure it before loading the bridge's sibling
|
|
562
|
+
-- modules; otherwise the plugin fails during initialization and its timer
|
|
563
|
+
-- never starts polling the request queue.
|
|
564
|
+
local extension_module_path = app.fs.joinPath(plugin.path, "?.lua")
|
|
565
|
+
if not package.path:find(extension_module_path, 1, true) then
|
|
566
|
+
package.path = extension_module_path .. ";" .. package.path
|
|
567
|
+
end
|
|
568
|
+
live_commands = require("live_commands")
|
|
569
|
+
ensure_directories()
|
|
570
|
+
refresh_auth_token()
|
|
571
|
+
timer=Timer{interval=POLL_INTERVAL,ontick=poll_requests}
|
|
572
|
+
timer:start()
|
|
573
|
+
pcall(function()
|
|
574
|
+
plugin:newCommand{
|
|
575
|
+
id="auvrynt_bridge_status",
|
|
576
|
+
title="Auvrynt Bridge Status",
|
|
577
|
+
group="cel_properties",
|
|
578
|
+
onclick=function()
|
|
579
|
+
app.alert{
|
|
580
|
+
title="Auvrynt Bridge",
|
|
581
|
+
text={
|
|
582
|
+
"Bridge version: "..BRIDGE_VERSION,
|
|
583
|
+
auth_token and "Authenticated request queue is ready." or "Waiting for Auvrynt authentication file.",
|
|
584
|
+
bridge_root,
|
|
585
|
+
},
|
|
586
|
+
}
|
|
587
|
+
end,
|
|
588
|
+
}
|
|
589
|
+
end)
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
function exit(plugin)
|
|
593
|
+
if timer then timer:stop() timer=nil end
|
|
594
|
+
end
|