@thevinci/web 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/README.md +197 -0
  2. package/bin/cli-entry.js +55 -0
  3. package/bin/cli-output.js +145 -0
  4. package/bin/cli.js +4887 -0
  5. package/bin/cli.test.js +64 -0
  6. package/dist/apple-touch-icon-120x120.png +0 -0
  7. package/dist/apple-touch-icon-152x152.png +0 -0
  8. package/dist/apple-touch-icon-167x167.png +0 -0
  9. package/dist/apple-touch-icon-180x180.png +0 -0
  10. package/dist/apple-touch-icon.png +0 -0
  11. package/dist/apple-touch-icon.svg +528 -0
  12. package/dist/assets/JsonTreeView-CSm9OzXG.js +1 -0
  13. package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  14. package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  15. package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  16. package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  17. package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  18. package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  19. package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  20. package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  21. package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  22. package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  23. package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  24. package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  25. package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  26. package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  27. package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  28. package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  29. package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  30. package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  31. package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  32. package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  33. package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  34. package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  35. package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  36. package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  37. package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  38. package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  39. package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  40. package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  41. package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  42. package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  43. package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  44. package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  45. package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  46. package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  47. package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  48. package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  49. package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  50. package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  51. package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  52. package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  53. package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  54. package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  55. package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  56. package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  57. package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  58. package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  59. package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  60. package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  61. package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  62. package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  63. package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  64. package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  65. package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  66. package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  67. package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  68. package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  69. package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  70. package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  71. package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  72. package/dist/assets/MarkdownRendererImpl-DensKOLc.js +6 -0
  73. package/dist/assets/MultiRunWindow-Bo7THayo.js +1 -0
  74. package/dist/assets/OnboardingScreen-BDqmzTVR.js +2 -0
  75. package/dist/assets/SettingsWindow-coz__Ykw.js +1 -0
  76. package/dist/assets/TerminalView-DrZ-i3Dr.js +1 -0
  77. package/dist/assets/ToolOutputDialog-Eglzslt3.js +16 -0
  78. package/dist/assets/es-4o9ciP61.js +15 -0
  79. package/dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  80. package/dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  81. package/dist/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  82. package/dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  83. package/dist/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  84. package/dist/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
  85. package/dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  86. package/dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  87. package/dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  88. package/dist/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  89. package/dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  90. package/dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  91. package/dist/assets/index-DLTDToSP.css +1 -0
  92. package/dist/assets/index-DgiFEKGN.js +1 -0
  93. package/dist/assets/ko-B20imCHE.js +15 -0
  94. package/dist/assets/main-BV3KOtdA.css +1 -0
  95. package/dist/assets/main-CDKJj0sH.js +226 -0
  96. package/dist/assets/main-LC-PSNVM.js +2 -0
  97. package/dist/assets/miniChat-CQUiG_cr.js +2 -0
  98. package/dist/assets/modelPrefsAutoSave-Dm799vzR.js +6986 -0
  99. package/dist/assets/pl-DQJ7LSzj.js +15 -0
  100. package/dist/assets/pt-BR-OmjHUz9y.js +15 -0
  101. package/dist/assets/renderElectronMiniChatApp-CARbeW0G.js +2 -0
  102. package/dist/assets/uk-BNFxOlO4.js +15 -0
  103. package/dist/assets/vendor--DBfsbEis.css +1 -0
  104. package/dist/assets/vendor-.bun-B9l0ZNi2.js +4094 -0
  105. package/dist/assets/wasm-CG6Dc4jp.js +1 -0
  106. package/dist/assets/wasmSttWorker-Dtlxac_K.js +1 -0
  107. package/dist/assets/wasmSttWorker-oo7Dm_jy.js +1806 -0
  108. package/dist/assets/worker-CbT6TVo7.js +155 -0
  109. package/dist/assets/zh-CN-C6T-Ac7F.js +15 -0
  110. package/dist/favicon-16.png +0 -0
  111. package/dist/favicon-32.png +0 -0
  112. package/dist/favicon.png +0 -0
  113. package/dist/favicon.svg +528 -0
  114. package/dist/index.html +607 -0
  115. package/dist/logo-dark-192x192.png +0 -0
  116. package/dist/logo-dark-512x512.png +0 -0
  117. package/dist/logo-dark-512x512.svg +528 -0
  118. package/dist/logo-light-192x192.png +0 -0
  119. package/dist/logo-light-512x512.png +0 -0
  120. package/dist/logo-light-512x512.svg +528 -0
  121. package/dist/mini-chat.html +16 -0
  122. package/dist/pwa-192.png +0 -0
  123. package/dist/pwa-512.png +0 -0
  124. package/dist/pwa-maskable-192.png +0 -0
  125. package/dist/pwa-maskable-512.png +0 -0
  126. package/dist/site.webmanifest +21 -0
  127. package/dist/sw.js +1 -0
  128. package/package.json +118 -0
  129. package/public/apple-touch-icon-120x120.png +0 -0
  130. package/public/apple-touch-icon-152x152.png +0 -0
  131. package/public/apple-touch-icon-167x167.png +0 -0
  132. package/public/apple-touch-icon-180x180.png +0 -0
  133. package/public/apple-touch-icon.png +0 -0
  134. package/public/apple-touch-icon.svg +528 -0
  135. package/public/favicon-16.png +0 -0
  136. package/public/favicon-32.png +0 -0
  137. package/public/favicon.png +0 -0
  138. package/public/favicon.svg +528 -0
  139. package/public/logo-dark-192x192.png +0 -0
  140. package/public/logo-dark-512x512.png +0 -0
  141. package/public/logo-dark-512x512.svg +528 -0
  142. package/public/logo-light-192x192.png +0 -0
  143. package/public/logo-light-512x512.png +0 -0
  144. package/public/logo-light-512x512.svg +528 -0
  145. package/public/pwa-192.png +0 -0
  146. package/public/pwa-512.png +0 -0
  147. package/public/pwa-maskable-192.png +0 -0
  148. package/public/pwa-maskable-512.png +0 -0
  149. package/public/site.webmanifest +21 -0
  150. package/server/TERMINAL_WS_PROTOCOL.md +48 -0
  151. package/server/index.d.ts +39 -0
  152. package/server/index.js +1311 -0
  153. package/server/lib/cloudflare-tunnel.js +650 -0
  154. package/server/lib/event-stream/DOCUMENTATION.md +61 -0
  155. package/server/lib/event-stream/directory-ws-bridge.js +185 -0
  156. package/server/lib/event-stream/global-hub.js +158 -0
  157. package/server/lib/event-stream/global-hub.test.js +140 -0
  158. package/server/lib/event-stream/global-ws-bridge.js +206 -0
  159. package/server/lib/event-stream/index.js +25 -0
  160. package/server/lib/event-stream/protocol.js +131 -0
  161. package/server/lib/event-stream/protocol.test.js +182 -0
  162. package/server/lib/event-stream/runtime.js +180 -0
  163. package/server/lib/event-stream/runtime.test.js +512 -0
  164. package/server/lib/event-stream/upstream-reader.js +226 -0
  165. package/server/lib/event-stream/upstream-reader.test.js +276 -0
  166. package/server/lib/fs/DOCUMENTATION.md +36 -0
  167. package/server/lib/fs/routes.js +1040 -0
  168. package/server/lib/fs/search.js +238 -0
  169. package/server/lib/git/DOCUMENTATION.md +152 -0
  170. package/server/lib/git/credentials.js +74 -0
  171. package/server/lib/git/identity-storage.js +112 -0
  172. package/server/lib/git/index.js +6 -0
  173. package/server/lib/git/routes.js +972 -0
  174. package/server/lib/git/service.js +3432 -0
  175. package/server/lib/git/service.test.js +39 -0
  176. package/server/lib/github/DOCUMENTATION.md +171 -0
  177. package/server/lib/github/auth.js +307 -0
  178. package/server/lib/github/device-flow.js +50 -0
  179. package/server/lib/github/index.js +24 -0
  180. package/server/lib/github/octokit.js +10 -0
  181. package/server/lib/github/pr-status.js +519 -0
  182. package/server/lib/github/repo/fork-detection.js +102 -0
  183. package/server/lib/github/repo/index.js +55 -0
  184. package/server/lib/github/routes.js +1560 -0
  185. package/server/lib/magic-prompts/routes.js +63 -0
  186. package/server/lib/magic-prompts/runtime.js +119 -0
  187. package/server/lib/notifications/DOCUMENTATION.md +122 -0
  188. package/server/lib/notifications/emitter-runtime.js +102 -0
  189. package/server/lib/notifications/index.js +4 -0
  190. package/server/lib/notifications/message.js +52 -0
  191. package/server/lib/notifications/message.test.js +34 -0
  192. package/server/lib/notifications/push-runtime.js +304 -0
  193. package/server/lib/notifications/routes.js +315 -0
  194. package/server/lib/notifications/runtime.js +566 -0
  195. package/server/lib/notifications/template-runtime.js +349 -0
  196. package/server/lib/notifications/template-runtime.test.js +26 -0
  197. package/server/lib/opencode/DOCUMENTATION.md +362 -0
  198. package/server/lib/opencode/agents.js +634 -0
  199. package/server/lib/opencode/auth-state-runtime.js +88 -0
  200. package/server/lib/opencode/auth.js +83 -0
  201. package/server/lib/opencode/bootstrap-runtime.js +131 -0
  202. package/server/lib/opencode/cli-entry-runtime.js +43 -0
  203. package/server/lib/opencode/cli-options.js +128 -0
  204. package/server/lib/opencode/commands.js +339 -0
  205. package/server/lib/opencode/config-entity-routes.js +370 -0
  206. package/server/lib/opencode/core-routes.js +500 -0
  207. package/server/lib/opencode/core-routes.test.js +26 -0
  208. package/server/lib/opencode/env-config.js +74 -0
  209. package/server/lib/opencode/env-keys.js +68 -0
  210. package/server/lib/opencode/env-runtime.js +1162 -0
  211. package/server/lib/opencode/env-runtime.test.js +116 -0
  212. package/server/lib/opencode/feature-routes-runtime.js +244 -0
  213. package/server/lib/opencode/hmr-state-runtime.js +85 -0
  214. package/server/lib/opencode/index.js +66 -0
  215. package/server/lib/opencode/lifecycle.js +1019 -0
  216. package/server/lib/opencode/lifecycle.test.js +240 -0
  217. package/server/lib/opencode/mcp.js +278 -0
  218. package/server/lib/opencode/network-runtime.js +104 -0
  219. package/server/lib/opencode/network-runtime.test.js +37 -0
  220. package/server/lib/opencode/opencode-resolution-runtime.js +71 -0
  221. package/server/lib/opencode/path-utils.js +100 -0
  222. package/server/lib/opencode/path-utils.test.js +71 -0
  223. package/server/lib/opencode/project-directory-runtime.js +124 -0
  224. package/server/lib/opencode/project-icon-routes.js +399 -0
  225. package/server/lib/opencode/project-icon-routes.test.js +107 -0
  226. package/server/lib/opencode/providers.js +96 -0
  227. package/server/lib/opencode/proxy.js +445 -0
  228. package/server/lib/opencode/pwa-manifest-routes.js +257 -0
  229. package/server/lib/opencode/pwa-manifest-routes.test.js +133 -0
  230. package/server/lib/opencode/routes.js +541 -0
  231. package/server/lib/opencode/server-startup-runtime.js +156 -0
  232. package/server/lib/opencode/server-utils-runtime.js +168 -0
  233. package/server/lib/opencode/server-utils-runtime.test.js +135 -0
  234. package/server/lib/opencode/session-runtime.js +356 -0
  235. package/server/lib/opencode/session-runtime.test.js +151 -0
  236. package/server/lib/opencode/settings-helpers.js +770 -0
  237. package/server/lib/opencode/settings-helpers.test.js +109 -0
  238. package/server/lib/opencode/settings-normalization-runtime.js +428 -0
  239. package/server/lib/opencode/settings-runtime.js +826 -0
  240. package/server/lib/opencode/settings-runtime.test.js +85 -0
  241. package/server/lib/opencode/shared.js +615 -0
  242. package/server/lib/opencode/shutdown-runtime.js +139 -0
  243. package/server/lib/opencode/shutdown-runtime.test.js +58 -0
  244. package/server/lib/opencode/skill-routes.js +701 -0
  245. package/server/lib/opencode/skills.js +548 -0
  246. package/server/lib/opencode/startup-pipeline-runtime.js +130 -0
  247. package/server/lib/opencode/static-routes-runtime.js +65 -0
  248. package/server/lib/opencode/theme-runtime.js +167 -0
  249. package/server/lib/opencode/tunnel-auth.js +591 -0
  250. package/server/lib/opencode/tunnel-wiring-runtime.js +94 -0
  251. package/server/lib/opencode/vinci-routes.js +76 -0
  252. package/server/lib/opencode/watcher.js +115 -0
  253. package/server/lib/opencode/watcher.test.js +239 -0
  254. package/server/lib/preview/proxy-runtime.js +1333 -0
  255. package/server/lib/preview/proxy-runtime.test.js +144 -0
  256. package/server/lib/projects/project-config.js +567 -0
  257. package/server/lib/projects/project-config.test.js +175 -0
  258. package/server/lib/projects/project-id.js +13 -0
  259. package/server/lib/quota/DOCUMENTATION.md +58 -0
  260. package/server/lib/quota/index.js +25 -0
  261. package/server/lib/quota/providers/claude.js +107 -0
  262. package/server/lib/quota/providers/codex.js +113 -0
  263. package/server/lib/quota/providers/copilot.js +165 -0
  264. package/server/lib/quota/providers/google/api.js +92 -0
  265. package/server/lib/quota/providers/google/auth.js +108 -0
  266. package/server/lib/quota/providers/google/index.js +124 -0
  267. package/server/lib/quota/providers/google/transforms.js +109 -0
  268. package/server/lib/quota/providers/index.js +168 -0
  269. package/server/lib/quota/providers/interface.js +55 -0
  270. package/server/lib/quota/providers/kimi.js +108 -0
  271. package/server/lib/quota/providers/minimax-cn-coding-plan.js +140 -0
  272. package/server/lib/quota/providers/minimax-coding-plan.js +139 -0
  273. package/server/lib/quota/providers/nanogpt.js +124 -0
  274. package/server/lib/quota/providers/ollama-cloud.js +112 -0
  275. package/server/lib/quota/providers/openai.js +91 -0
  276. package/server/lib/quota/providers/openrouter.js +92 -0
  277. package/server/lib/quota/providers/zai.js +91 -0
  278. package/server/lib/quota/providers/zhipuai-coding-plan.js +133 -0
  279. package/server/lib/quota/providers/zhipuai.js +114 -0
  280. package/server/lib/quota/routes.js +27 -0
  281. package/server/lib/quota/utils/auth.js +50 -0
  282. package/server/lib/quota/utils/formatters.js +85 -0
  283. package/server/lib/quota/utils/formatters.test.js +54 -0
  284. package/server/lib/quota/utils/index.js +10 -0
  285. package/server/lib/quota/utils/transformers.js +55 -0
  286. package/server/lib/scheduled-tasks/DOCUMENTATION.md +44 -0
  287. package/server/lib/scheduled-tasks/routes.js +235 -0
  288. package/server/lib/scheduled-tasks/runtime.js +773 -0
  289. package/server/lib/scheduled-tasks/runtime.test.js +100 -0
  290. package/server/lib/security/request-security.js +115 -0
  291. package/server/lib/session-folders/routes.js +63 -0
  292. package/server/lib/session-folders/routes.test.js +102 -0
  293. package/server/lib/skills-catalog/DOCUMENTATION.md +178 -0
  294. package/server/lib/skills-catalog/cache.js +29 -0
  295. package/server/lib/skills-catalog/clawdhub/api.js +158 -0
  296. package/server/lib/skills-catalog/clawdhub/index.js +30 -0
  297. package/server/lib/skills-catalog/clawdhub/install.js +238 -0
  298. package/server/lib/skills-catalog/clawdhub/scan.js +113 -0
  299. package/server/lib/skills-catalog/curated-sources.js +21 -0
  300. package/server/lib/skills-catalog/git.js +77 -0
  301. package/server/lib/skills-catalog/index.js +42 -0
  302. package/server/lib/skills-catalog/install.js +294 -0
  303. package/server/lib/skills-catalog/scan.js +221 -0
  304. package/server/lib/skills-catalog/source.js +87 -0
  305. package/server/lib/terminal/DOCUMENTATION.md +76 -0
  306. package/server/lib/terminal/index.js +31 -0
  307. package/server/lib/terminal/output-replay-buffer.js +78 -0
  308. package/server/lib/terminal/output-replay-buffer.test.js +75 -0
  309. package/server/lib/terminal/runtime.js +850 -0
  310. package/server/lib/terminal/runtime.test.js +96 -0
  311. package/server/lib/terminal/terminal-ws-protocol.js +68 -0
  312. package/server/lib/terminal/terminal-ws-protocol.test.js +145 -0
  313. package/server/lib/text/DOCUMENTATION.md +35 -0
  314. package/server/lib/text/summarization.js +138 -0
  315. package/server/lib/text/summarization.test.js +34 -0
  316. package/server/lib/tts/DOCUMENTATION.md +146 -0
  317. package/server/lib/tts/base-url.js +62 -0
  318. package/server/lib/tts/capability-runtime.js +31 -0
  319. package/server/lib/tts/index.js +19 -0
  320. package/server/lib/tts/routes.js +261 -0
  321. package/server/lib/tts/routes.test.js +53 -0
  322. package/server/lib/tts/service.js +178 -0
  323. package/server/lib/tts/stt.js +75 -0
  324. package/server/lib/tunnels/DOCUMENTATION.md +18 -0
  325. package/server/lib/tunnels/index.js +166 -0
  326. package/server/lib/tunnels/managed-config.js +201 -0
  327. package/server/lib/tunnels/providers/cloudflare.js +260 -0
  328. package/server/lib/tunnels/registry.js +51 -0
  329. package/server/lib/tunnels/routes.js +605 -0
  330. package/server/lib/tunnels/types.js +219 -0
  331. package/server/lib/ui-auth/DOCUMENTATION.md +38 -0
  332. package/server/lib/ui-auth/ui-auth.js +673 -0
  333. package/server/lib/ui-auth/ui-passkeys.js +545 -0
  334. package/server/opencode-proxy.test.js +151 -0
  335. package/server/proxy-headers.js +61 -0
  336. package/server/proxy-headers.test.js +58 -0
  337. package/server/sse-routes.test.js +152 -0
package/README.md ADDED
@@ -0,0 +1,197 @@
1
+ # <picture><source media="(prefers-color-scheme: dark)" srcset="https://github.com/jaygupta17/vinci/raw/HEAD/docs/references/badges/vinci-logo-dark.svg"><img src="https://github.com/jaygupta17/vinci/raw/HEAD/docs/references/badges/vinci-logo-light.svg" width="32" height="32" align="absmiddle" /></picture> @thevinci/web
2
+
3
+ [![GitHub stars](https://img.shields.io/github/stars/jaygupta17/vinci?style=flat&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0iI2YxZWNlYyIgdmlld0JveD0iMCAwIDI1NiAyNTYiPjxwYXRoIGQ9Ik0yMjkuMDYsMTA4Ljc5bC00OC43LDQyLDE0Ljg4LDYyLjc5YTguNCw4LjQsMCwwLDEtMTIuNTIsOS4xN0wxMjgsMTg5LjA5LDczLjI4LDIyMi43NGE4LjQsOC40LDAsMCwxLTEyLjUyLTkuMTdsMTQuODgtNjIuNzktNDguNy00MkE4LjQ2LDguNDYsMCwwLDEsMzEuNzMsOTRMOTUuNjQsODguOGwyNC42Mi01OS42YTguMzYsOC4zNiwwLDAsMSwxNS40OCwwbDI0LjYyLDU5LjZMMjI0LjI3LDk0QTguNDYsOC40NiwwLDAsMSwyMjkuMDYsMTA4Ljc5WiIgb3BhY2l0eT0iMC4yIj48L3BhdGg%2BPHBhdGggZD0iTTIzOS4xOCw5Ny4yNkExNi4zOCwxNi4zOCwwLDAsMCwyMjQuOTIsODZsLTU5LTQuNzZMMTQzLjE0LDI2LjE1YTE2LjM2LDE2LjM2LDAsMCwwLTMwLjI3LDBMOTAuMTEsODEuMjMsMzEuMDgsODZhMTYuNDYsMTYuNDYsMCwwLDAtOS4zNywyOC44Nmw0NSwzOC44M0w1MywyMTEuNzVhMTYuMzgsMTYuMzgsMCwwLDAsMjQuNSwxNy44MkwxMjgsMTk4LjQ5bDUwLjUzLDMxLjA4QTE2LjQsMTYuNCwwLDAsMCwyMDMsMjExLjc1bC0xMy43Ni01OC4wNyw0NS0zOC44M0ExNi40MywxNi40MywwLDAsMCwyMzkuMTgsOTcuMjZabS0xNS4zNCw1LjQ3LTQ4LjcsNDJhOCw4LDAsMCwwLTIuNTYsNy45MWwxNC44OCw2Mi44YS4zNy4zNywwLDAsMS0uMTcuNDhjLS4xOC4xNC0uMjMuMTEtLjM4LDBsLTU0LjcyLTMzLjY1YTgsOCwwLDAsMC04LjM4LDBMNjkuMDksMjE1Ljk0Yy0uMTUuMDktLjE5LjEyLS4zOCwwYS4zNy4zNywwLDAsMS0uMTctLjQ4bDE0Ljg4LTYyLjhhOCw4LDAsMCwwLTIuNTYtNy45MWwtNDguNy00MmMtLjEyLS4xLS4yMy0uMTktLjEzLS41cy4xOC0uMjcuMzMtLjI5bDYzLjkyLTUuMTZBOCw4LDAsMCwwLDEwMyw5MS44NmwyNC42Mi01OS42MWMuMDgtLjE3LjExLS4yNS4zNS0uMjVzLjI3LjA4LjM1LjI1TDE1Myw5MS44NmE4LDgsMCwwLDAsNi43NSw0LjkybDYzLjkyLDUuMTZjLjE1LDAsLjI0LDAsLjMzLjI5UzIyNCwxMDIuNjMsMjIzLjg0LDEwMi43M1oiPjwvcGF0aD48L3N2Zz4%3D&logoColor=FFFCF0&labelColor=100F0F&color=66800B)](https://github.com/jaygupta17/vinci/stargazers)
4
+ [![GitHub release](https://img.shields.io/github/v/release/jaygupta17/vinci?style=flat&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0iI2YxZWNlYyIgdmlld0JveD0iMCAwIDI1NiAyNTYiPjxwYXRoIGQ9Ik0xMjgsMTI5LjA5VjIzMmE4LDgsMCwwLDEtMy44NC0xbC04OC00OC4xOGE4LDgsMCwwLDEtNC4xNi03VjgwLjE4YTgsOCwwLDAsMSwuNy0zLjI1WiIgb3BhY2l0eT0iMC4yIj48L3BhdGg%2BPHBhdGggZD0iTTIyMy42OCw2Ni4xNSwxMzUuNjgsMThhMTUuODgsMTUuODgsMCwwLDAtMTUuMzYsMGwtODgsNDguMTdhMTYsMTYsMCwwLDAtOC4zMiwxNHY5NS42NGExNiwxNiwwLDAsMCw4LjMyLDE0bDg4LDQ4LjE3YTE1Ljg4LDE1Ljg4LDAsMCwwLDE1LjM2LDBsODgtNDguMTdhMTYsMTYsMCwwLDAsOC4zMi0xNFY4MC4xOEExNiwxNiwwLDAsMCwyMjMuNjgsNjYuMTVaTTEyOCwzMmw4MC4zNCw0NC0yOS43NywxNi4zLTgwLjM1LTQ0Wk0xMjgsMTIwLDQ3LjY2LDc2bDMzLjktMTguNTYsODAuMzQsNDRaTTQwLDkwbDgwLDQzLjc4djg1Ljc5TDQwLDE3NS44MlptMTc2LDg1Ljc4aDBsLTgwLDQzLjc5VjEzMy44MmwzMi0xNy41MVYxNTJhOCw4LDAsMCwwLDE2LDBWMTA3LjU1TDIxNiw5MHY4NS43N1oiPjwvcGF0aD48L3N2Zz4%3D&logoColor=FFFCF0&labelColor=100F0F&color=205EA6)](https://github.com/jaygupta17/vinci/releases/latest)
5
+ [![Discord](https://img.shields.io/badge/Discord-join.svg?style=flat&labelColor=100F0F&color=8B7EC8&logo=discord&logoColor=FFFCF0)](https://discord.gg/eSSmgeX8Q)
6
+
7
+ Run [OpenCode](https://opencode.ai) in your browser. Install the CLI, open `localhost:3000`, done. Works on desktop browsers, tablets, and phones as a PWA.
8
+
9
+ Full project overview, screenshots, and all features: [github.com/jaygupta17/vinci](https://github.com/jaygupta17/vinci)
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ curl -fsSL https://raw.githubusercontent.com/jaygupta17/vinci/main/scripts/install.sh | bash
15
+ ```
16
+
17
+ Or install manually: `bun add -g @thevinci/web` (or npm, pnpm, yarn).
18
+
19
+ > **Prerequisites:** [OpenCode CLI](https://opencode.ai) installed, Node.js 20+.
20
+
21
+ ## Usage
22
+
23
+ ```bash
24
+ vinci # Start on port 3000
25
+ vinci --port 8080 # Custom port
26
+ vinci --ui-password secret # Password-protect UI
27
+ vinci tunnel help # Tunnel lifecycle commands
28
+ vinci tunnel providers # Show provider capabilities
29
+ vinci tunnel profile add --provider cloudflare --mode managed-remote --name prod-main --hostname app.example.com --token <token>
30
+ vinci tunnel start --profile prod-main
31
+ vinci tunnel start --provider cloudflare --mode quick --qr
32
+ vinci tunnel start --provider cloudflare --mode managed-local --config ~/.cloudflared/config.yml
33
+ vinci tunnel status --all # Show tunnel state across instances
34
+ vinci tunnel stop --port 3000 # Stop tunnel only (server stays running)
35
+ vinci logs # Follow latest instance logs
36
+ OPENCODE_PORT=4096 OPENCODE_SKIP_START=true vinci # Connect to external OpenCode server
37
+ OPENCODE_HOST=https://myhost:4096 OPENCODE_SKIP_START=true vinci # Connect via custom host/HTTPS
38
+ vinci stop # Stop server
39
+ vinci update # Update to latest version
40
+ ```
41
+
42
+ ### Tunnel behavior notes
43
+
44
+ - One active tunnel per running Vinci instance (port).
45
+ - Starting a different tunnel mode/provider on the same instance replaces the active tunnel.
46
+ - Replacing or stopping a tunnel revokes existing connect links and invalidates remote tunnel sessions.
47
+ - Connect links are one-time tokens; generating a new link revokes the previous unused link.
48
+
49
+ <details>
50
+ <summary>Connect to external OpenCode server</summary>
51
+
52
+ ```bash
53
+ OPENCODE_PORT=4096 OPENCODE_SKIP_START=true vinci
54
+ OPENCODE_HOST=https://myhost:4096 OPENCODE_SKIP_START=true vinci
55
+ ```
56
+
57
+ | Variable | Description |
58
+ |----------|-------------|
59
+ | `OPENCODE_HOST` | Full base URL of external server (overrides `OPENCODE_PORT`) |
60
+ | `OPENCODE_PORT` | Port of external server |
61
+ | `OPENCODE_SKIP_START` | Skip starting embedded OpenCode server |
62
+ | `VINCI_OPENCODE_HOSTNAME` | Bind hostname for managed OpenCode server (default: `127.0.0.1`, use `0.0.0.0` for LAN/remote access — trusted networks only) |
63
+ | `VINCI_HOST` | Bind hostname for the Vinci web server (default: `127.0.0.1`; use `0.0.0.0` for LAN/remote access — trusted networks only) |
64
+ | `VINCI_VERBOSE_REQUEST_LOGS` | Set to `true` to log every HTTP request; disabled by default to keep user logs small |
65
+ | `VINCI_SKIP_API_COMPRESSION` | Set to `true` to disable gzip compression for `/api/*` responses |
66
+ | `VINCI_COMPRESS_API` | Set to `true` to force `/api/*` compression, or `false` to disable it. Desktop runtime disables API compression by default to reduce local sidecar CPU use |
67
+
68
+ </details>
69
+
70
+ <details>
71
+ <summary>Bind managed OpenCode to LAN / Tailscale</summary>
72
+
73
+ ```bash
74
+ VINCI_OPENCODE_HOSTNAME=0.0.0.0 vinci --port 3000
75
+ ```
76
+
77
+ **Security note:** binding to `0.0.0.0` exposes the server on all network interfaces — use only on trusted networks and protect with firewall rules or `--ui-password`.
78
+
79
+ </details>
80
+
81
+ **Optional env vars:**
82
+ ```yaml
83
+ environment:
84
+ UI_PASSWORD: your_secure_password
85
+ VINCI_TUNNEL_MODE: quick # quick | managed-remote | managed-local
86
+ VINCI_TUNNEL_PROVIDER: cloudflare
87
+ ```
88
+
89
+ For `managed-remote` mode, also set:
90
+
91
+ ```yaml
92
+ environment:
93
+ VINCI_TUNNEL_MODE: managed-remote
94
+ VINCI_TUNNEL_HOSTNAME: app.example.com
95
+ VINCI_TUNNEL_TOKEN: <token>
96
+ ```
97
+
98
+ For `managed-local` mode, you can set:
99
+
100
+ ```yaml
101
+ environment:
102
+ VINCI_TUNNEL_MODE: managed-local
103
+ VINCI_TUNNEL_CONFIG: /home/vinci/.cloudflared/config.yml
104
+ ```
105
+
106
+ Managed-local path note: `VINCI_TUNNEL_CONFIG` must use a container path under `/home/vinci/...`. If the config file references `credentials-file`, ensure that JSON path is also mounted and reachable inside the container.
107
+
108
+ **Data directory:** mount `data/` for persistent storage. Ensure permissions:
109
+ ```bash
110
+ mkdir -p data/vinci data/opencode/share data/opencode/config data/ssh
111
+ chown -R 1000:1000 data/
112
+ ```
113
+
114
+ </details>
115
+
116
+ <details>
117
+ <summary>Background & daemon mode</summary>
118
+
119
+ ```bash
120
+ vinci # Runs in background by default
121
+ vinci stop # Stop background server
122
+ ```
123
+
124
+ </details>
125
+
126
+ <details>
127
+ <summary>systemd service (VPN / LAN access)</summary>
128
+
129
+ Use `--foreground` to keep the CLI process alive so systemd (or any other process manager) can track and restart it. Combine with `OPENCODE_HOST` to connect to an OpenCode instance running as a separate service.
130
+
131
+ **`~/.config/systemd/user/opencode.service`**
132
+ ```ini
133
+ [Unit]
134
+ Description=OpenCode Server
135
+
136
+ [Service]
137
+ Type=simple
138
+ ExecStart=opencode serve --port 4095
139
+ Environment="PATH=/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/home/YOU/.local/bin:/home/YOU/.npm-global/bin:/usr/local/bin:/usr/bin:/bin"
140
+ Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
141
+ Restart=on-failure
142
+ RestartSec=5
143
+
144
+ [Install]
145
+ WantedBy=default.target
146
+ ```
147
+
148
+ > **Why set `PATH` and `SSH_AUTH_SOCK`?**
149
+ > systemd user services start with a minimal environment — no shell profile is sourced.
150
+ > Without an explicit `PATH`, OpenCode won't find tools installed via Homebrew, npm, or `~/.local/bin`.
151
+ > Without `SSH_AUTH_SOCK`, git operations over SSH (push, pull, clone) will fail.
152
+ > `%t` expands to `$XDG_RUNTIME_DIR` (e.g. `/run/user/1000`), where most SSH agents write their socket.
153
+
154
+ **`~/.config/systemd/user/vinci.service`**
155
+ ```ini
156
+ [Unit]
157
+ Description=Vinci Web Server
158
+ After=opencode.service
159
+
160
+ [Service]
161
+ Type=simple
162
+ ExecStart=vinci serve --port 3000 --host 0.0.0.0 --ui-password your-password --foreground
163
+ Environment="OPENCODE_HOST=http://localhost:4095"
164
+ Environment="OPENCODE_SKIP_START=true"
165
+ Restart=on-failure
166
+ RestartSec=5
167
+
168
+ [Install]
169
+ WantedBy=default.target
170
+ ```
171
+
172
+ ```bash
173
+ systemctl --user daemon-reload
174
+ systemctl --user enable --now opencode vinci
175
+ ```
176
+
177
+ `--host 0.0.0.0` is required to listen on all interfaces (the default is `127.0.0.1`). Use `--host <ip>` or `VINCI_HOST=<ip>` to bind to a specific interface instead.
178
+
179
+ </details>
180
+
181
+ ## What makes the web version special
182
+
183
+ - **Remote access** - Cloudflare tunnel with QR onboarding. Scan from your phone, start coding.
184
+ - **Mobile-first PWA** - optimized chat controls, keyboard-safe layouts, drag-to-reorder projects
185
+ - **Background notifications** - know when your agent finishes, even from another tab
186
+ - **Self-update** - update and restart from the UI, server settings stay intact
187
+ - **Cross-tab tracking** - session activity stays in sync across browser tabs
188
+
189
+ - Cloudflare tunnel access with quick, managed-remote, and managed-local modes
190
+ - One-scan onboarding with tunnel QR + password URL helpers
191
+ - Mobile-first experience: optimized chat controls, keyboard-safe layouts, and attachment-friendly UI
192
+ - Background notifications plus reliable cross-tab session activity tracking
193
+ - Built-in self-update + restart flow that keeps your server settings intact
194
+
195
+ ## License
196
+
197
+ MIT
@@ -0,0 +1,55 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { fileURLToPath, pathToFileURL } from 'url';
4
+
5
+ function normalizeCliEntryPath(filePath, realpath = fs.realpathSync) {
6
+ if (typeof filePath !== 'string' || filePath.trim().length === 0) {
7
+ return null;
8
+ }
9
+
10
+ const resolvedPath = path.resolve(filePath);
11
+ try {
12
+ return realpath(resolvedPath);
13
+ } catch {
14
+ return resolvedPath;
15
+ }
16
+ }
17
+
18
+ function isModuleCliExecution(
19
+ entryPath = process.argv[1],
20
+ moduleUrl,
21
+ realpath = fs.realpathSync,
22
+ expectedBinName,
23
+ ) {
24
+ if (typeof entryPath !== 'string' || entryPath.trim().length === 0) {
25
+ return false;
26
+ }
27
+ if (typeof moduleUrl !== 'string' || moduleUrl.trim().length === 0) {
28
+ return false;
29
+ }
30
+
31
+ try {
32
+ const normalizedEntryPath = normalizeCliEntryPath(entryPath, realpath);
33
+ const normalizedModulePath = normalizeCliEntryPath(fileURLToPath(moduleUrl), realpath);
34
+ if (!normalizedEntryPath || !normalizedModulePath) {
35
+ return false;
36
+ }
37
+ if (pathToFileURL(normalizedEntryPath).href === pathToFileURL(normalizedModulePath).href) {
38
+ return true;
39
+ }
40
+
41
+ if (typeof expectedBinName === 'string' && expectedBinName.trim().length > 0) {
42
+ const parsedEntryName = path.parse(normalizedEntryPath).name.toLowerCase();
43
+ return parsedEntryName === expectedBinName.trim().toLowerCase();
44
+ }
45
+
46
+ return false;
47
+ } catch {
48
+ return false;
49
+ }
50
+ }
51
+
52
+ export {
53
+ normalizeCliEntryPath,
54
+ isModuleCliExecution,
55
+ };
@@ -0,0 +1,145 @@
1
+ /**
2
+ * CLI output formatting adapter.
3
+ *
4
+ * Wraps @clack/prompts for structured, beautiful terminal output.
5
+ * Custom formatters (icons, redaction) live here to isolate the
6
+ * formatting dependency from the rest of the CLI.
7
+ */
8
+
9
+ import {
10
+ intro,
11
+ outro,
12
+ log,
13
+ note,
14
+ box,
15
+ progress,
16
+ spinner,
17
+ confirm,
18
+ select,
19
+ text,
20
+ password,
21
+ cancel,
22
+ isCancel,
23
+ } from '@clack/prompts';
24
+
25
+ // ── Provider icons ──────────────────────────────────────────────
26
+
27
+ const TUNNEL_PROVIDER_ICON = {
28
+ cloudflare: '☁',
29
+ };
30
+
31
+ function formatProviderWithIcon(provider) {
32
+ if (typeof provider !== 'string' || provider.trim().length === 0) {
33
+ return 'unknown';
34
+ }
35
+ const normalized = provider.trim().toLowerCase();
36
+ const icon = TUNNEL_PROVIDER_ICON[normalized];
37
+ return icon ? `${icon} ${normalized}` : normalized;
38
+ }
39
+
40
+ // ── Status-aware log dispatch ───────────────────────────────────
41
+
42
+ /**
43
+ * Print a status-tagged message using clack log primitives.
44
+ *
45
+ * @param {'success'|'warning'|'error'|'info'|'neutral'} status
46
+ * @param {string} message Primary line
47
+ * @param {string} [detail] Optional dim secondary line appended after newline
48
+ */
49
+ function logStatus(status, message, detail) {
50
+ const full = detail ? `${message}\n${detail}` : message;
51
+ switch (status) {
52
+ case 'success':
53
+ log.success(full);
54
+ break;
55
+ case 'warning':
56
+ log.warn(full);
57
+ break;
58
+ case 'error':
59
+ log.error(full);
60
+ break;
61
+ case 'info':
62
+ case 'neutral':
63
+ default:
64
+ log.info(full);
65
+ break;
66
+ }
67
+ }
68
+
69
+ // ── TTY detection ───────────────────────────────────────────────
70
+
71
+ /**
72
+ * Whether both stdout and stdin are interactive TTYs.
73
+ * Prompts must be disabled when stdin is piped (e.g. --token-stdin).
74
+ */
75
+ const isTTY = Boolean(process.stdout?.isTTY) && Boolean(process.stdin?.isTTY);
76
+
77
+ function isJsonMode(options) {
78
+ return Boolean(options?.json);
79
+ }
80
+
81
+ function isQuietMode(options) {
82
+ return Boolean(options?.quiet);
83
+ }
84
+
85
+ function shouldRenderHumanOutput(options) {
86
+ return !isJsonMode(options) && !isQuietMode(options);
87
+ }
88
+
89
+ function canPrompt(options) {
90
+ return shouldRenderHumanOutput(options) && isTTY;
91
+ }
92
+
93
+ function createSpinner(options) {
94
+ return canPrompt(options) ? spinner() : null;
95
+ }
96
+
97
+ async function createProgress(options, config) {
98
+ return canPrompt(options) ? progress(config) : null;
99
+ }
100
+
101
+ function printJson(payload) {
102
+ const base = payload && typeof payload === 'object' && !Array.isArray(payload)
103
+ ? { ...payload }
104
+ : { data: payload };
105
+
106
+ const messages = Array.isArray(base.messages) ? base.messages : undefined;
107
+ const hasWarning = Boolean(messages?.some((entry) => entry?.level === 'warning'));
108
+ const hasError = Boolean(messages?.some((entry) => entry?.level === 'error'));
109
+ const normalizedStatus = base.status === 'ok' || base.status === 'warning' || base.status === 'error'
110
+ ? base.status
111
+ : (hasError ? 'error' : (hasWarning ? 'warning' : 'ok'));
112
+
113
+ const output = {
114
+ status: normalizedStatus,
115
+ ...base,
116
+ };
117
+
118
+ process.stdout.write(`${JSON.stringify(output, null, 2)}\n`);
119
+ }
120
+
121
+ export {
122
+ intro,
123
+ outro,
124
+ log,
125
+ note,
126
+ box,
127
+ progress,
128
+ spinner,
129
+ confirm,
130
+ select,
131
+ text,
132
+ password,
133
+ cancel,
134
+ isCancel,
135
+ isTTY,
136
+ isJsonMode,
137
+ isQuietMode,
138
+ shouldRenderHumanOutput,
139
+ canPrompt,
140
+ createSpinner,
141
+ createProgress,
142
+ printJson,
143
+ formatProviderWithIcon,
144
+ logStatus,
145
+ };