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,219 @@
1
+ import { copyFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { eq } from "drizzle-orm";
4
+ import { databasePath, openDatabase } from "../db/client.js";
5
+ import { workspaceSessions, } from "../db/schema.js";
6
+ const WORKSPACE_SESSION_TTL_MS = 30 * 24 * 60 * 60 * 1000;
7
+ const MAX_PERSISTED_WORKSPACE_SESSIONS = 512;
8
+ export class SqliteWorkspaceStore {
9
+ database;
10
+ stateDir;
11
+ constructor(stateDir) {
12
+ this.database = openDatabase(stateDir);
13
+ this.stateDir = stateDir;
14
+ this.migrate();
15
+ this.pruneStaleSessions();
16
+ }
17
+ createSession(input) {
18
+ const now = new Date().toISOString();
19
+ const session = {
20
+ id: input.id,
21
+ root: input.root,
22
+ status: "active",
23
+ mode: input.mode ?? "checkout",
24
+ sourceRoot: input.sourceRoot,
25
+ baseRef: input.baseRef,
26
+ baseSha: input.baseSha,
27
+ managed: input.managed ?? false,
28
+ createdAt: now,
29
+ lastUsedAt: now,
30
+ };
31
+ this.database.db
32
+ .insert(workspaceSessions)
33
+ .values({
34
+ id: session.id,
35
+ root: session.root,
36
+ status: session.status,
37
+ mode: session.mode,
38
+ sourceRoot: session.sourceRoot ?? null,
39
+ baseRef: session.baseRef ?? null,
40
+ baseSha: session.baseSha ?? null,
41
+ managed: String(session.managed),
42
+ createdAt: session.createdAt,
43
+ lastUsedAt: session.lastUsedAt,
44
+ })
45
+ .run();
46
+ return session;
47
+ }
48
+ getSession(id) {
49
+ const row = this.database.db
50
+ .select()
51
+ .from(workspaceSessions)
52
+ .where(eq(workspaceSessions.id, id))
53
+ .get();
54
+ return row ? rowToWorkspaceSession(row) : undefined;
55
+ }
56
+ touchSession(id) {
57
+ this.database.db
58
+ .update(workspaceSessions)
59
+ .set({ lastUsedAt: new Date().toISOString() })
60
+ .where(eq(workspaceSessions.id, id))
61
+ .run();
62
+ }
63
+ updateSession(id, updates) {
64
+ const toSet = {};
65
+ if (updates.status !== undefined)
66
+ toSet.status = updates.status;
67
+ if (updates.mode !== undefined)
68
+ toSet.mode = updates.mode;
69
+ if (updates.root !== undefined)
70
+ toSet.root = updates.root;
71
+ if (Object.keys(toSet).length === 0)
72
+ return;
73
+ this.database.db
74
+ .update(workspaceSessions)
75
+ .set(toSet)
76
+ .where(eq(workspaceSessions.id, id))
77
+ .run();
78
+ }
79
+ getDatabase() {
80
+ return this.database;
81
+ }
82
+ close() {
83
+ this.database.close();
84
+ }
85
+ migrate() {
86
+ this.database.sqlite.exec(`
87
+ create table if not exists _migrations (
88
+ name text primary key,
89
+ applied_at text not null
90
+ )
91
+ `);
92
+ const applied = new Set(this.database.sqlite.prepare("select name from _migrations").all().map((r) => r.name));
93
+ this.database.sqlite.transaction(() => {
94
+ if (!applied.has("v1_core_tables")) {
95
+ this.database.sqlite.exec(`
96
+ create table if not exists workspace_sessions (
97
+ id text primary key,
98
+ root text not null,
99
+ status text not null default 'active',
100
+ mode text not null default 'checkout',
101
+ source_root text,
102
+ base_ref text,
103
+ base_sha text,
104
+ managed text not null default 'false',
105
+ created_at text not null,
106
+ last_used_at text not null
107
+ );
108
+
109
+ create index if not exists workspace_sessions_root_idx
110
+ on workspace_sessions(root, last_used_at desc);
111
+
112
+ create index if not exists workspace_sessions_status_idx
113
+ on workspace_sessions(status, last_used_at desc);
114
+
115
+ create table if not exists loaded_agent_files (
116
+ workspace_session_id text not null,
117
+ path text not null,
118
+ content_hash text not null,
119
+ content text not null,
120
+ loaded_at text not null,
121
+ last_seen_at text not null,
122
+ primary key (workspace_session_id, path),
123
+ foreign key (workspace_session_id)
124
+ references workspace_sessions(id)
125
+ on delete cascade
126
+ );
127
+
128
+ create index if not exists loaded_agent_files_path_idx
129
+ on loaded_agent_files(path);
130
+
131
+ create table if not exists rooms (
132
+ id text primary key,
133
+ owner_client_id text not null,
134
+ workspace_id text not null unique,
135
+ state text not null default 'active',
136
+ created_at text not null,
137
+ last_activity_at text not null,
138
+ closed_at text
139
+ );
140
+
141
+ create index if not exists rooms_workspace_idx
142
+ on rooms(workspace_id);
143
+
144
+ create index if not exists rooms_owner_idx
145
+ on rooms(owner_client_id);
146
+ `);
147
+ this.database.sqlite
148
+ .prepare("insert into _migrations (name, applied_at) values (?, ?)")
149
+ .run("v1_core_tables", new Date().toISOString());
150
+ }
151
+ const alterMigrations = [
152
+ { name: "v1_add_mode", column: "mode", def: "text not null default 'checkout'" },
153
+ { name: "v1_add_source_root", column: "source_root", def: "text" },
154
+ { name: "v1_add_base_ref", column: "base_ref", def: "text" },
155
+ { name: "v1_add_base_sha", column: "base_sha", def: "text" },
156
+ { name: "v1_add_managed", column: "managed", def: "text not null default 'false'" },
157
+ ];
158
+ for (const m of alterMigrations) {
159
+ if (!applied.has(m.name)) {
160
+ this.backupDb();
161
+ this.addColumnIfMissing("workspace_sessions", m.column, m.def);
162
+ this.database.sqlite
163
+ .prepare("insert into _migrations (name, applied_at) values (?, ?)")
164
+ .run(m.name, new Date().toISOString());
165
+ }
166
+ }
167
+ })();
168
+ }
169
+ backupDb() {
170
+ const dbPath = databasePath(this.stateDir);
171
+ const backupPath = join(this.stateDir, "auvrynt.sqlite.migrate.bak");
172
+ try {
173
+ copyFileSync(dbPath, backupPath);
174
+ }
175
+ catch {
176
+ // Backup is best-effort
177
+ }
178
+ }
179
+ addColumnIfMissing(table, column, definition) {
180
+ const columns = this.database.sqlite.prepare(`pragma table_info(${table})`).all();
181
+ if (columns.some((existingColumn) => existingColumn.name === column))
182
+ return;
183
+ this.database.sqlite.exec(`alter table ${table} add column ${column} ${definition}`);
184
+ }
185
+ pruneStaleSessions() {
186
+ const cutoff = new Date(Date.now() - WORKSPACE_SESSION_TTL_MS).toISOString();
187
+ const transaction = this.database.sqlite.transaction(() => {
188
+ this.database.sqlite
189
+ .prepare("delete from workspace_sessions where last_used_at < ?")
190
+ .run(cutoff);
191
+ this.database.sqlite.prepare(`
192
+ delete from workspace_sessions
193
+ where id in (
194
+ select id from workspace_sessions
195
+ order by last_used_at desc
196
+ limit -1 offset ?
197
+ )
198
+ `).run(MAX_PERSISTED_WORKSPACE_SESSIONS);
199
+ });
200
+ transaction();
201
+ }
202
+ }
203
+ export function createWorkspaceStore(stateDir) {
204
+ return new SqliteWorkspaceStore(stateDir);
205
+ }
206
+ function rowToWorkspaceSession(row) {
207
+ return {
208
+ id: row.id,
209
+ root: row.root,
210
+ status: row.status,
211
+ mode: row.mode === "worktree" ? "worktree" : "checkout",
212
+ sourceRoot: row.sourceRoot ?? undefined,
213
+ baseRef: row.baseRef ?? undefined,
214
+ baseSha: row.baseSha ?? undefined,
215
+ managed: row.managed === "true",
216
+ createdAt: row.createdAt,
217
+ lastUsedAt: row.lastUsedAt,
218
+ };
219
+ }
@@ -0,0 +1,314 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { existsSync } from "node:fs";
3
+ import { mkdir, opendir, stat } from "node:fs/promises";
4
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
5
+ import { loadProjectContextFiles } from "@earendil-works/pi-coding-agent";
6
+ import { createManagedWorktree } from "./git-worktrees.js";
7
+ import { AccessDeniedError, assertAllowedPath, isPathInsideRoot, resolveAllowedPath } from "./roots.js";
8
+ import { loadWorkspaceSkills, markSkillActivated, resolveSkillReadPath, } from "./skills.js";
9
+ const MAX_ACTIVE_WORKSPACES = 128;
10
+ const ARTIFACT_DIRECTORY = "auvrynt-logs";
11
+ export class WorkspaceRegistry {
12
+ config;
13
+ store;
14
+ workspaces = new Map();
15
+ maxActiveWorkspaces;
16
+ pendingWorkspaceOpens = 0;
17
+ constructor(config, store, options = {}) {
18
+ this.config = config;
19
+ this.store = store;
20
+ this.maxActiveWorkspaces = Number.isInteger(options.maxActiveWorkspaces)
21
+ && options.maxActiveWorkspaces > 0
22
+ ? options.maxActiveWorkspaces
23
+ : MAX_ACTIVE_WORKSPACES;
24
+ }
25
+ async openWorkspace(input) {
26
+ if (this.workspaces.size + this.pendingWorkspaceOpens >= this.maxActiveWorkspaces) {
27
+ throw new Error(`Workspace capacity reached (max ${this.maxActiveWorkspaces} active workspaces). Close an unused workspace before opening another.`);
28
+ }
29
+ this.pendingWorkspaceOpens += 1;
30
+ try {
31
+ const options = typeof input === "string" ? { path: input } : input;
32
+ const mode = options.mode ?? "checkout";
33
+ if (mode === "worktree") {
34
+ return await this.openWorktreeWorkspace(options.path, options.baseRef);
35
+ }
36
+ return await this.openCheckoutWorkspace(options.path);
37
+ }
38
+ finally {
39
+ this.pendingWorkspaceOpens = Math.max(0, this.pendingWorkspaceOpens - 1);
40
+ }
41
+ }
42
+ markClosed(workspaceId) {
43
+ const workspace = this.workspaces.get(workspaceId);
44
+ if (workspace)
45
+ workspace.closed = true;
46
+ this.workspaces.delete(workspaceId);
47
+ this.store?.updateSession(workspaceId, { status: "closed" });
48
+ }
49
+ getWorkspace(workspaceId) {
50
+ const workspace = this.workspaces.get(workspaceId);
51
+ if (workspace) {
52
+ if (workspace.closed) {
53
+ throw new Error(`Workspace ${workspaceId} has been closed. Call open_workspace to reopen.`);
54
+ }
55
+ this.store?.touchSession(workspaceId);
56
+ return workspace;
57
+ }
58
+ const session = this.store?.getSession(workspaceId);
59
+ if (!session) {
60
+ throw new Error(`Unknown workspaceId: ${workspaceId}. Call open_workspace first.`);
61
+ }
62
+ if (session.status !== "active") {
63
+ throw new Error(`Workspace ${workspaceId} has been closed. Call open_workspace to reopen.`);
64
+ }
65
+ const root = this.assertWorkspaceRootAllowed(session.root, session.mode, session.sourceRoot);
66
+ if (this.workspaces.size + this.pendingWorkspaceOpens >= this.maxActiveWorkspaces) {
67
+ throw new Error(`Workspace capacity reached (max ${this.maxActiveWorkspaces} active workspaces).`);
68
+ }
69
+ if (session.mode === "worktree" && !existsSync(root)) {
70
+ console.warn(`[auvrynt] Worktree directory for session ${session.id} no longer exists at ${root}. Falling back to checkout mode.`);
71
+ session.mode = "checkout";
72
+ this.store?.updateSession(session.id, { mode: "checkout" });
73
+ }
74
+ const restoredWorkspace = {
75
+ id: session.id,
76
+ root,
77
+ mode: session.mode,
78
+ sourceRoot: session.sourceRoot,
79
+ worktree: session.mode === "worktree"
80
+ ? {
81
+ path: root,
82
+ baseRef: session.baseRef ?? "HEAD",
83
+ baseSha: session.baseSha ?? "",
84
+ dirtySource: false,
85
+ detached: true,
86
+ managed: session.managed,
87
+ }
88
+ : undefined,
89
+ ...this.loadSkillsForWorkspace(root),
90
+ activatedSkillDirs: new Set(),
91
+ };
92
+ this.store?.touchSession(workspaceId);
93
+ this.workspaces.set(restoredWorkspace.id, restoredWorkspace);
94
+ return restoredWorkspace;
95
+ }
96
+ resolvePath(workspace, inputPath) {
97
+ const absolutePath = resolveAllowedPath(inputPath, workspace.root, [workspace.root]);
98
+ if (!isPathInsideRoot(absolutePath, workspace.root)) {
99
+ throw new Error(`Path is outside workspace root: ${inputPath}`);
100
+ }
101
+ return absolutePath;
102
+ }
103
+ resolveArtifactPath(workspace, inputPath, category) {
104
+ const normalized = inputPath.replace(/\\/g, "/").replace(/^\.\/+/, "");
105
+ if (isAbsolute(inputPath) ||
106
+ /^[a-zA-Z]:\//.test(normalized) ||
107
+ normalized.startsWith("//") ||
108
+ normalized.split("/").some((segment) => segment === "..")) {
109
+ throw new AccessDeniedError(`Path is outside allowed roots: ${inputPath}`);
110
+ }
111
+ const withoutRoot = normalized === ARTIFACT_DIRECTORY
112
+ ? ""
113
+ : normalized.startsWith(`${ARTIFACT_DIRECTORY}/`)
114
+ ? normalized.slice(ARTIFACT_DIRECTORY.length + 1)
115
+ : normalized;
116
+ const categoryPath = category && withoutRoot !== category && !withoutRoot.startsWith(`${category}/`)
117
+ ? `${category}/${withoutRoot}`
118
+ : withoutRoot;
119
+ const artifactRoot = join(workspace.root, ARTIFACT_DIRECTORY);
120
+ return resolveAllowedPath(categoryPath || ".", artifactRoot, [artifactRoot]);
121
+ }
122
+ resolveReadPath(workspace, inputPath) {
123
+ try {
124
+ return {
125
+ absolutePath: this.resolvePath(workspace, inputPath),
126
+ readRoots: [workspace.root],
127
+ };
128
+ }
129
+ catch (workspaceError) {
130
+ const skillRead = resolveSkillReadPath(workspace.skills, workspace.activatedSkillDirs, inputPath);
131
+ if (!skillRead)
132
+ throw workspaceError;
133
+ return {
134
+ absolutePath: skillRead.absolutePath,
135
+ readRoots: [workspace.root, skillRead.skill.baseDir],
136
+ skillRead,
137
+ };
138
+ }
139
+ }
140
+ markReadPathLoaded(workspace, readPath) {
141
+ if (readPath.skillRead?.isSkillFile) {
142
+ markSkillActivated(workspace.activatedSkillDirs, readPath.skillRead.skill);
143
+ }
144
+ }
145
+ resolveWorkingDirectory(workspace, workingDirectory) {
146
+ const directory = workingDirectory ? this.resolvePath(workspace, workingDirectory) : workspace.root;
147
+ return assertAllowedPath(directory, [workspace.root]);
148
+ }
149
+ async openCheckoutWorkspace(path) {
150
+ const root = assertAllowedPath(path, this.config.allowedRoots);
151
+ await mkdir(root, { recursive: true });
152
+ const rootStats = await stat(root);
153
+ if (!rootStats.isDirectory()) {
154
+ throw new Error(`Workspace root must be a directory: ${path}`);
155
+ }
156
+ return this.createWorkspaceContext({ root, mode: "checkout" });
157
+ }
158
+ async openWorktreeWorkspace(path, baseRef) {
159
+ const worktree = await createManagedWorktree({
160
+ sourcePath: path,
161
+ baseRef,
162
+ config: this.config,
163
+ });
164
+ return this.createWorkspaceContext({
165
+ root: worktree.path,
166
+ mode: "worktree",
167
+ sourceRoot: worktree.sourceRoot,
168
+ worktree,
169
+ });
170
+ }
171
+ async createWorkspaceContext(input) {
172
+ const workspace = {
173
+ id: `ws_${randomUUID()}`,
174
+ root: input.root,
175
+ mode: input.mode,
176
+ sourceRoot: input.sourceRoot,
177
+ worktree: input.worktree,
178
+ ...this.loadSkillsForWorkspace(input.root),
179
+ activatedSkillDirs: new Set(),
180
+ };
181
+ const agentsFiles = this.loadInitialAgentsFiles(workspace.root);
182
+ const availableAgentsFiles = await this.findAvailableAgentsFiles(workspace.root, agentsFiles);
183
+ this.store?.createSession({
184
+ id: workspace.id,
185
+ root: workspace.root,
186
+ mode: workspace.mode,
187
+ sourceRoot: workspace.sourceRoot,
188
+ baseRef: workspace.worktree?.baseRef,
189
+ baseSha: workspace.worktree?.baseSha,
190
+ managed: workspace.worktree?.managed,
191
+ });
192
+ this.workspaces.set(workspace.id, workspace);
193
+ return { workspace, agentsFiles, availableAgentsFiles };
194
+ }
195
+ replaceAllowedRoots(roots) {
196
+ this.config.allowedRoots.splice(0, this.config.allowedRoots.length, ...roots);
197
+ const closedWorkspaceIds = [];
198
+ for (const [workspaceId, workspace] of this.workspaces) {
199
+ try {
200
+ this.assertWorkspaceRootAllowed(workspace.root, workspace.mode, workspace.sourceRoot);
201
+ }
202
+ catch (error) {
203
+ if (!(error instanceof AccessDeniedError))
204
+ throw error;
205
+ this.markClosed(workspaceId);
206
+ closedWorkspaceIds.push(workspaceId);
207
+ }
208
+ }
209
+ return closedWorkspaceIds;
210
+ }
211
+ loadSkillsForWorkspace(root) {
212
+ const result = loadWorkspaceSkills(this.config, root);
213
+ return {
214
+ skills: result.skills,
215
+ skillDiagnostics: result.diagnostics,
216
+ };
217
+ }
218
+ assertWorkspaceRootAllowed(root, mode, sourceRoot) {
219
+ if (mode === "worktree") {
220
+ if (!sourceRoot) {
221
+ throw new Error(`Stored worktree workspace is missing sourceRoot: ${root}`);
222
+ }
223
+ assertAllowedPath(sourceRoot, this.config.allowedRoots);
224
+ return assertAllowedPath(root, [this.config.worktreeRoot]);
225
+ }
226
+ return assertAllowedPath(root, this.config.allowedRoots);
227
+ }
228
+ loadInitialAgentsFiles(root) {
229
+ const agentDir = resolve(this.config.agentDir);
230
+ return loadProjectContextFiles({ cwd: root, agentDir })
231
+ .filter((file) => {
232
+ const path = resolve(file.path);
233
+ if (isPathInsideRoot(path, agentDir))
234
+ return true;
235
+ return isPathInsideRoot(path, root) && dirname(path) === root;
236
+ })
237
+ .map((file) => ({
238
+ path: resolve(file.path),
239
+ content: file.content,
240
+ }));
241
+ }
242
+ async findAvailableAgentsFiles(root, loadedFiles) {
243
+ const loadedPaths = new Set(loadedFiles.map((file) => resolve(file.path)));
244
+ const discovered = [];
245
+ await walkWorkspace(root, async (path, entry) => {
246
+ if (!entry.isFile())
247
+ return;
248
+ if (!CONTEXT_FILE_NAMES.has(entry.name))
249
+ return;
250
+ if (loadedPaths.has(path))
251
+ return;
252
+ if (discovered.length >= MAX_DISCOVERED_CONTEXT_FILES)
253
+ return;
254
+ discovered.push({ path });
255
+ });
256
+ return discovered.sort((a, b) => a.path.localeCompare(b.path));
257
+ }
258
+ }
259
+ const CONTEXT_FILE_NAMES = new Set(["AGENTS.md", "AGENTS.MD", "CLAUDE.md", "CLAUDE.MD"]);
260
+ const MAX_CONTEXT_SCAN_ENTRIES = 50_000;
261
+ const MAX_CONTEXT_SCAN_DEPTH = 16;
262
+ const MAX_DISCOVERED_CONTEXT_FILES = 256;
263
+ const SKIPPED_CONTEXT_DIRS = new Set([
264
+ ".git",
265
+ ".hg",
266
+ ".svn",
267
+ ".auvrynt",
268
+ "node_modules",
269
+ "dist",
270
+ "build",
271
+ ".next",
272
+ ".turbo",
273
+ ".cache",
274
+ ]);
275
+ export function formatAgentsPath(path, workspaceRoot) {
276
+ if (!workspaceRoot)
277
+ return path.split(sep).join("/");
278
+ const relationship = relative(workspaceRoot, path);
279
+ if (relationship === "" ||
280
+ relationship.startsWith("..") ||
281
+ relationship === ".." ||
282
+ relationship.includes(`..${sep}`)) {
283
+ return path.split(sep).join("/");
284
+ }
285
+ return relationship.split(sep).join("/");
286
+ }
287
+ async function walkWorkspace(directory, visit, state = { entries: 0, stopped: false }, depth = 0) {
288
+ if (state.stopped || depth > MAX_CONTEXT_SCAN_DEPTH)
289
+ return;
290
+ let entries;
291
+ try {
292
+ entries = await opendir(directory);
293
+ }
294
+ catch {
295
+ return;
296
+ }
297
+ for await (const entry of entries) {
298
+ if (state.stopped)
299
+ break;
300
+ state.entries += 1;
301
+ if (state.entries > MAX_CONTEXT_SCAN_ENTRIES) {
302
+ state.stopped = true;
303
+ break;
304
+ }
305
+ const path = join(directory, entry.name);
306
+ if (entry.isDirectory()) {
307
+ if (!SKIPPED_CONTEXT_DIRS.has(entry.name)) {
308
+ await walkWorkspace(path, visit, state, depth + 1);
309
+ }
310
+ continue;
311
+ }
312
+ await visit(path, entry);
313
+ }
314
+ }
@@ -1,125 +1 @@
1
- import { eq } from "drizzle-orm";
2
- import { openDatabase } from "./db/client.js";
3
- import { workspaceSessions, } from "./db/schema.js";
4
- export class SqliteWorkspaceStore {
5
- database;
6
- constructor(stateDir) {
7
- this.database = openDatabase(stateDir);
8
- this.migrate();
9
- }
10
- createSession(input) {
11
- const now = new Date().toISOString();
12
- const session = {
13
- id: input.id,
14
- root: input.root,
15
- status: "active",
16
- mode: input.mode ?? "checkout",
17
- sourceRoot: input.sourceRoot,
18
- baseRef: input.baseRef,
19
- baseSha: input.baseSha,
20
- managed: input.managed ?? false,
21
- createdAt: now,
22
- lastUsedAt: now,
23
- };
24
- this.database.db
25
- .insert(workspaceSessions)
26
- .values({
27
- id: session.id,
28
- root: session.root,
29
- status: session.status,
30
- mode: session.mode,
31
- sourceRoot: session.sourceRoot ?? null,
32
- baseRef: session.baseRef ?? null,
33
- baseSha: session.baseSha ?? null,
34
- managed: String(session.managed),
35
- createdAt: session.createdAt,
36
- lastUsedAt: session.lastUsedAt,
37
- })
38
- .run();
39
- return session;
40
- }
41
- getSession(id) {
42
- const row = this.database.db
43
- .select()
44
- .from(workspaceSessions)
45
- .where(eq(workspaceSessions.id, id))
46
- .get();
47
- return row ? rowToWorkspaceSession(row) : undefined;
48
- }
49
- touchSession(id) {
50
- this.database.db
51
- .update(workspaceSessions)
52
- .set({ lastUsedAt: new Date().toISOString() })
53
- .where(eq(workspaceSessions.id, id))
54
- .run();
55
- }
56
- close() {
57
- this.database.close();
58
- }
59
- migrate() {
60
- this.database.sqlite.exec(`
61
- create table if not exists workspace_sessions (
62
- id text primary key,
63
- root text not null,
64
- status text not null default 'active',
65
- mode text not null default 'checkout',
66
- source_root text,
67
- base_ref text,
68
- base_sha text,
69
- managed text not null default 'false',
70
- created_at text not null,
71
- last_used_at text not null
72
- );
73
-
74
- create index if not exists workspace_sessions_root_idx
75
- on workspace_sessions(root, last_used_at desc);
76
-
77
- create index if not exists workspace_sessions_status_idx
78
- on workspace_sessions(status, last_used_at desc);
79
-
80
- create table if not exists loaded_agent_files (
81
- workspace_session_id text not null,
82
- path text not null,
83
- content_hash text not null,
84
- content text not null,
85
- loaded_at text not null,
86
- last_seen_at text not null,
87
- primary key (workspace_session_id, path),
88
- foreign key (workspace_session_id)
89
- references workspace_sessions(id)
90
- on delete cascade
91
- );
92
-
93
- create index if not exists loaded_agent_files_path_idx
94
- on loaded_agent_files(path);
95
- `);
96
- this.addColumnIfMissing("workspace_sessions", "mode", "text not null default 'checkout'");
97
- this.addColumnIfMissing("workspace_sessions", "source_root", "text");
98
- this.addColumnIfMissing("workspace_sessions", "base_ref", "text");
99
- this.addColumnIfMissing("workspace_sessions", "base_sha", "text");
100
- this.addColumnIfMissing("workspace_sessions", "managed", "text not null default 'false'");
101
- }
102
- addColumnIfMissing(table, column, definition) {
103
- const columns = this.database.sqlite.prepare(`pragma table_info(${table})`).all();
104
- if (columns.some((existingColumn) => existingColumn.name === column))
105
- return;
106
- this.database.sqlite.exec(`alter table ${table} add column ${column} ${definition}`);
107
- }
108
- }
109
- export function createWorkspaceStore(stateDir) {
110
- return new SqliteWorkspaceStore(stateDir);
111
- }
112
- function rowToWorkspaceSession(row) {
113
- return {
114
- id: row.id,
115
- root: row.root,
116
- status: row.status,
117
- mode: row.mode === "worktree" ? "worktree" : "checkout",
118
- sourceRoot: row.sourceRoot ?? undefined,
119
- baseRef: row.baseRef ?? undefined,
120
- baseSha: row.baseSha ?? undefined,
121
- managed: row.managed === "true",
122
- createdAt: row.createdAt,
123
- lastUsedAt: row.lastUsedAt,
124
- };
125
- }
1
+ export * from "./workspace/workspace-store.js";