@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.
- package/README.md +197 -0
- package/bin/cli-entry.js +55 -0
- package/bin/cli-output.js +145 -0
- package/bin/cli.js +4887 -0
- package/bin/cli.test.js +64 -0
- package/dist/apple-touch-icon-120x120.png +0 -0
- package/dist/apple-touch-icon-152x152.png +0 -0
- package/dist/apple-touch-icon-167x167.png +0 -0
- package/dist/apple-touch-icon-180x180.png +0 -0
- package/dist/apple-touch-icon.png +0 -0
- package/dist/apple-touch-icon.svg +528 -0
- package/dist/assets/JsonTreeView-CSm9OzXG.js +1 -0
- package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/assets/MarkdownRendererImpl-DensKOLc.js +6 -0
- package/dist/assets/MultiRunWindow-Bo7THayo.js +1 -0
- package/dist/assets/OnboardingScreen-BDqmzTVR.js +2 -0
- package/dist/assets/SettingsWindow-coz__Ykw.js +1 -0
- package/dist/assets/TerminalView-DrZ-i3Dr.js +1 -0
- package/dist/assets/ToolOutputDialog-Eglzslt3.js +16 -0
- package/dist/assets/es-4o9ciP61.js +15 -0
- package/dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- package/dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/dist/assets/index-DLTDToSP.css +1 -0
- package/dist/assets/index-DgiFEKGN.js +1 -0
- package/dist/assets/ko-B20imCHE.js +15 -0
- package/dist/assets/main-BV3KOtdA.css +1 -0
- package/dist/assets/main-CDKJj0sH.js +226 -0
- package/dist/assets/main-LC-PSNVM.js +2 -0
- package/dist/assets/miniChat-CQUiG_cr.js +2 -0
- package/dist/assets/modelPrefsAutoSave-Dm799vzR.js +6986 -0
- package/dist/assets/pl-DQJ7LSzj.js +15 -0
- package/dist/assets/pt-BR-OmjHUz9y.js +15 -0
- package/dist/assets/renderElectronMiniChatApp-CARbeW0G.js +2 -0
- package/dist/assets/uk-BNFxOlO4.js +15 -0
- package/dist/assets/vendor--DBfsbEis.css +1 -0
- package/dist/assets/vendor-.bun-B9l0ZNi2.js +4094 -0
- package/dist/assets/wasm-CG6Dc4jp.js +1 -0
- package/dist/assets/wasmSttWorker-Dtlxac_K.js +1 -0
- package/dist/assets/wasmSttWorker-oo7Dm_jy.js +1806 -0
- package/dist/assets/worker-CbT6TVo7.js +155 -0
- package/dist/assets/zh-CN-C6T-Ac7F.js +15 -0
- package/dist/favicon-16.png +0 -0
- package/dist/favicon-32.png +0 -0
- package/dist/favicon.png +0 -0
- package/dist/favicon.svg +528 -0
- package/dist/index.html +607 -0
- package/dist/logo-dark-192x192.png +0 -0
- package/dist/logo-dark-512x512.png +0 -0
- package/dist/logo-dark-512x512.svg +528 -0
- package/dist/logo-light-192x192.png +0 -0
- package/dist/logo-light-512x512.png +0 -0
- package/dist/logo-light-512x512.svg +528 -0
- package/dist/mini-chat.html +16 -0
- package/dist/pwa-192.png +0 -0
- package/dist/pwa-512.png +0 -0
- package/dist/pwa-maskable-192.png +0 -0
- package/dist/pwa-maskable-512.png +0 -0
- package/dist/site.webmanifest +21 -0
- package/dist/sw.js +1 -0
- package/package.json +118 -0
- package/public/apple-touch-icon-120x120.png +0 -0
- package/public/apple-touch-icon-152x152.png +0 -0
- package/public/apple-touch-icon-167x167.png +0 -0
- package/public/apple-touch-icon-180x180.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/apple-touch-icon.svg +528 -0
- package/public/favicon-16.png +0 -0
- package/public/favicon-32.png +0 -0
- package/public/favicon.png +0 -0
- package/public/favicon.svg +528 -0
- package/public/logo-dark-192x192.png +0 -0
- package/public/logo-dark-512x512.png +0 -0
- package/public/logo-dark-512x512.svg +528 -0
- package/public/logo-light-192x192.png +0 -0
- package/public/logo-light-512x512.png +0 -0
- package/public/logo-light-512x512.svg +528 -0
- package/public/pwa-192.png +0 -0
- package/public/pwa-512.png +0 -0
- package/public/pwa-maskable-192.png +0 -0
- package/public/pwa-maskable-512.png +0 -0
- package/public/site.webmanifest +21 -0
- package/server/TERMINAL_WS_PROTOCOL.md +48 -0
- package/server/index.d.ts +39 -0
- package/server/index.js +1311 -0
- package/server/lib/cloudflare-tunnel.js +650 -0
- package/server/lib/event-stream/DOCUMENTATION.md +61 -0
- package/server/lib/event-stream/directory-ws-bridge.js +185 -0
- package/server/lib/event-stream/global-hub.js +158 -0
- package/server/lib/event-stream/global-hub.test.js +140 -0
- package/server/lib/event-stream/global-ws-bridge.js +206 -0
- package/server/lib/event-stream/index.js +25 -0
- package/server/lib/event-stream/protocol.js +131 -0
- package/server/lib/event-stream/protocol.test.js +182 -0
- package/server/lib/event-stream/runtime.js +180 -0
- package/server/lib/event-stream/runtime.test.js +512 -0
- package/server/lib/event-stream/upstream-reader.js +226 -0
- package/server/lib/event-stream/upstream-reader.test.js +276 -0
- package/server/lib/fs/DOCUMENTATION.md +36 -0
- package/server/lib/fs/routes.js +1040 -0
- package/server/lib/fs/search.js +238 -0
- package/server/lib/git/DOCUMENTATION.md +152 -0
- package/server/lib/git/credentials.js +74 -0
- package/server/lib/git/identity-storage.js +112 -0
- package/server/lib/git/index.js +6 -0
- package/server/lib/git/routes.js +972 -0
- package/server/lib/git/service.js +3432 -0
- package/server/lib/git/service.test.js +39 -0
- package/server/lib/github/DOCUMENTATION.md +171 -0
- package/server/lib/github/auth.js +307 -0
- package/server/lib/github/device-flow.js +50 -0
- package/server/lib/github/index.js +24 -0
- package/server/lib/github/octokit.js +10 -0
- package/server/lib/github/pr-status.js +519 -0
- package/server/lib/github/repo/fork-detection.js +102 -0
- package/server/lib/github/repo/index.js +55 -0
- package/server/lib/github/routes.js +1560 -0
- package/server/lib/magic-prompts/routes.js +63 -0
- package/server/lib/magic-prompts/runtime.js +119 -0
- package/server/lib/notifications/DOCUMENTATION.md +122 -0
- package/server/lib/notifications/emitter-runtime.js +102 -0
- package/server/lib/notifications/index.js +4 -0
- package/server/lib/notifications/message.js +52 -0
- package/server/lib/notifications/message.test.js +34 -0
- package/server/lib/notifications/push-runtime.js +304 -0
- package/server/lib/notifications/routes.js +315 -0
- package/server/lib/notifications/runtime.js +566 -0
- package/server/lib/notifications/template-runtime.js +349 -0
- package/server/lib/notifications/template-runtime.test.js +26 -0
- package/server/lib/opencode/DOCUMENTATION.md +362 -0
- package/server/lib/opencode/agents.js +634 -0
- package/server/lib/opencode/auth-state-runtime.js +88 -0
- package/server/lib/opencode/auth.js +83 -0
- package/server/lib/opencode/bootstrap-runtime.js +131 -0
- package/server/lib/opencode/cli-entry-runtime.js +43 -0
- package/server/lib/opencode/cli-options.js +128 -0
- package/server/lib/opencode/commands.js +339 -0
- package/server/lib/opencode/config-entity-routes.js +370 -0
- package/server/lib/opencode/core-routes.js +500 -0
- package/server/lib/opencode/core-routes.test.js +26 -0
- package/server/lib/opencode/env-config.js +74 -0
- package/server/lib/opencode/env-keys.js +68 -0
- package/server/lib/opencode/env-runtime.js +1162 -0
- package/server/lib/opencode/env-runtime.test.js +116 -0
- package/server/lib/opencode/feature-routes-runtime.js +244 -0
- package/server/lib/opencode/hmr-state-runtime.js +85 -0
- package/server/lib/opencode/index.js +66 -0
- package/server/lib/opencode/lifecycle.js +1019 -0
- package/server/lib/opencode/lifecycle.test.js +240 -0
- package/server/lib/opencode/mcp.js +278 -0
- package/server/lib/opencode/network-runtime.js +104 -0
- package/server/lib/opencode/network-runtime.test.js +37 -0
- package/server/lib/opencode/opencode-resolution-runtime.js +71 -0
- package/server/lib/opencode/path-utils.js +100 -0
- package/server/lib/opencode/path-utils.test.js +71 -0
- package/server/lib/opencode/project-directory-runtime.js +124 -0
- package/server/lib/opencode/project-icon-routes.js +399 -0
- package/server/lib/opencode/project-icon-routes.test.js +107 -0
- package/server/lib/opencode/providers.js +96 -0
- package/server/lib/opencode/proxy.js +445 -0
- package/server/lib/opencode/pwa-manifest-routes.js +257 -0
- package/server/lib/opencode/pwa-manifest-routes.test.js +133 -0
- package/server/lib/opencode/routes.js +541 -0
- package/server/lib/opencode/server-startup-runtime.js +156 -0
- package/server/lib/opencode/server-utils-runtime.js +168 -0
- package/server/lib/opencode/server-utils-runtime.test.js +135 -0
- package/server/lib/opencode/session-runtime.js +356 -0
- package/server/lib/opencode/session-runtime.test.js +151 -0
- package/server/lib/opencode/settings-helpers.js +770 -0
- package/server/lib/opencode/settings-helpers.test.js +109 -0
- package/server/lib/opencode/settings-normalization-runtime.js +428 -0
- package/server/lib/opencode/settings-runtime.js +826 -0
- package/server/lib/opencode/settings-runtime.test.js +85 -0
- package/server/lib/opencode/shared.js +615 -0
- package/server/lib/opencode/shutdown-runtime.js +139 -0
- package/server/lib/opencode/shutdown-runtime.test.js +58 -0
- package/server/lib/opencode/skill-routes.js +701 -0
- package/server/lib/opencode/skills.js +548 -0
- package/server/lib/opencode/startup-pipeline-runtime.js +130 -0
- package/server/lib/opencode/static-routes-runtime.js +65 -0
- package/server/lib/opencode/theme-runtime.js +167 -0
- package/server/lib/opencode/tunnel-auth.js +591 -0
- package/server/lib/opencode/tunnel-wiring-runtime.js +94 -0
- package/server/lib/opencode/vinci-routes.js +76 -0
- package/server/lib/opencode/watcher.js +115 -0
- package/server/lib/opencode/watcher.test.js +239 -0
- package/server/lib/preview/proxy-runtime.js +1333 -0
- package/server/lib/preview/proxy-runtime.test.js +144 -0
- package/server/lib/projects/project-config.js +567 -0
- package/server/lib/projects/project-config.test.js +175 -0
- package/server/lib/projects/project-id.js +13 -0
- package/server/lib/quota/DOCUMENTATION.md +58 -0
- package/server/lib/quota/index.js +25 -0
- package/server/lib/quota/providers/claude.js +107 -0
- package/server/lib/quota/providers/codex.js +113 -0
- package/server/lib/quota/providers/copilot.js +165 -0
- package/server/lib/quota/providers/google/api.js +92 -0
- package/server/lib/quota/providers/google/auth.js +108 -0
- package/server/lib/quota/providers/google/index.js +124 -0
- package/server/lib/quota/providers/google/transforms.js +109 -0
- package/server/lib/quota/providers/index.js +168 -0
- package/server/lib/quota/providers/interface.js +55 -0
- package/server/lib/quota/providers/kimi.js +108 -0
- package/server/lib/quota/providers/minimax-cn-coding-plan.js +140 -0
- package/server/lib/quota/providers/minimax-coding-plan.js +139 -0
- package/server/lib/quota/providers/nanogpt.js +124 -0
- package/server/lib/quota/providers/ollama-cloud.js +112 -0
- package/server/lib/quota/providers/openai.js +91 -0
- package/server/lib/quota/providers/openrouter.js +92 -0
- package/server/lib/quota/providers/zai.js +91 -0
- package/server/lib/quota/providers/zhipuai-coding-plan.js +133 -0
- package/server/lib/quota/providers/zhipuai.js +114 -0
- package/server/lib/quota/routes.js +27 -0
- package/server/lib/quota/utils/auth.js +50 -0
- package/server/lib/quota/utils/formatters.js +85 -0
- package/server/lib/quota/utils/formatters.test.js +54 -0
- package/server/lib/quota/utils/index.js +10 -0
- package/server/lib/quota/utils/transformers.js +55 -0
- package/server/lib/scheduled-tasks/DOCUMENTATION.md +44 -0
- package/server/lib/scheduled-tasks/routes.js +235 -0
- package/server/lib/scheduled-tasks/runtime.js +773 -0
- package/server/lib/scheduled-tasks/runtime.test.js +100 -0
- package/server/lib/security/request-security.js +115 -0
- package/server/lib/session-folders/routes.js +63 -0
- package/server/lib/session-folders/routes.test.js +102 -0
- package/server/lib/skills-catalog/DOCUMENTATION.md +178 -0
- package/server/lib/skills-catalog/cache.js +29 -0
- package/server/lib/skills-catalog/clawdhub/api.js +158 -0
- package/server/lib/skills-catalog/clawdhub/index.js +30 -0
- package/server/lib/skills-catalog/clawdhub/install.js +238 -0
- package/server/lib/skills-catalog/clawdhub/scan.js +113 -0
- package/server/lib/skills-catalog/curated-sources.js +21 -0
- package/server/lib/skills-catalog/git.js +77 -0
- package/server/lib/skills-catalog/index.js +42 -0
- package/server/lib/skills-catalog/install.js +294 -0
- package/server/lib/skills-catalog/scan.js +221 -0
- package/server/lib/skills-catalog/source.js +87 -0
- package/server/lib/terminal/DOCUMENTATION.md +76 -0
- package/server/lib/terminal/index.js +31 -0
- package/server/lib/terminal/output-replay-buffer.js +78 -0
- package/server/lib/terminal/output-replay-buffer.test.js +75 -0
- package/server/lib/terminal/runtime.js +850 -0
- package/server/lib/terminal/runtime.test.js +96 -0
- package/server/lib/terminal/terminal-ws-protocol.js +68 -0
- package/server/lib/terminal/terminal-ws-protocol.test.js +145 -0
- package/server/lib/text/DOCUMENTATION.md +35 -0
- package/server/lib/text/summarization.js +138 -0
- package/server/lib/text/summarization.test.js +34 -0
- package/server/lib/tts/DOCUMENTATION.md +146 -0
- package/server/lib/tts/base-url.js +62 -0
- package/server/lib/tts/capability-runtime.js +31 -0
- package/server/lib/tts/index.js +19 -0
- package/server/lib/tts/routes.js +261 -0
- package/server/lib/tts/routes.test.js +53 -0
- package/server/lib/tts/service.js +178 -0
- package/server/lib/tts/stt.js +75 -0
- package/server/lib/tunnels/DOCUMENTATION.md +18 -0
- package/server/lib/tunnels/index.js +166 -0
- package/server/lib/tunnels/managed-config.js +201 -0
- package/server/lib/tunnels/providers/cloudflare.js +260 -0
- package/server/lib/tunnels/registry.js +51 -0
- package/server/lib/tunnels/routes.js +605 -0
- package/server/lib/tunnels/types.js +219 -0
- package/server/lib/ui-auth/DOCUMENTATION.md +38 -0
- package/server/lib/ui-auth/ui-auth.js +673 -0
- package/server/lib/ui-auth/ui-passkeys.js +545 -0
- package/server/opencode-proxy.test.js +151 -0
- package/server/proxy-headers.js +61 -0
- package/server/proxy-headers.test.js +58 -0
- 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
|
+
[](https://github.com/jaygupta17/vinci/stargazers)
|
|
4
|
+
[](https://github.com/jaygupta17/vinci/releases/latest)
|
|
5
|
+
[](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
|
package/bin/cli-entry.js
ADDED
|
@@ -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
|
+
};
|