From 66b18959ebc7b699a74ce69d3adfb4c4dcaa5fd1 Mon Sep 17 00:00:00 2001 From: Jay V Date: Mon, 26 May 2025 17:25:06 -0400 Subject: Merging docs and share app --- app/packages/web/.gitignore | 23 +- app/packages/web/README.md | 60 +- app/packages/web/astro.config.mjs | 65 ++ app/packages/web/index.html | 16 - app/packages/web/package.json | 33 +- app/packages/web/pnpm-lock.yaml | 1065 -------------------- app/packages/web/public/favicon.svg | 3 + app/packages/web/public/social-share.png | Bin 0 -> 25480 bytes app/packages/web/src/App.module.css | 33 - app/packages/web/src/app.tsx | 692 ------------- app/packages/web/src/assets/favicon.ico | Bin 15086 -> 0 bytes app/packages/web/src/assets/lander/check.svg | 2 + app/packages/web/src/assets/lander/copy.svg | 2 + app/packages/web/src/assets/logo-dark.svg | 11 + app/packages/web/src/assets/logo-light.svg | 11 + app/packages/web/src/components/Header.astro | 57 ++ app/packages/web/src/components/Hero.astro | 11 + app/packages/web/src/components/Lander.astro | 269 +++++ app/packages/web/src/components/Share.tsx | 691 +++++++++++++ app/packages/web/src/content.config.ts | 7 + app/packages/web/src/content/docs/docs/cli.mdx | 89 ++ app/packages/web/src/content/docs/docs/config.mdx | 88 ++ app/packages/web/src/content/docs/docs/index.mdx | 58 ++ .../web/src/content/docs/docs/lsp-servers.mdx | 34 + .../web/src/content/docs/docs/mcp-servers.mdx | 51 + app/packages/web/src/content/docs/docs/models.mdx | 34 + .../web/src/content/docs/docs/shortcuts.mdx | 68 ++ app/packages/web/src/content/docs/docs/themes.mdx | 75 ++ app/packages/web/src/content/docs/index.mdx | 12 + app/packages/web/src/index.css | 13 - app/packages/web/src/index.tsx | 24 - app/packages/web/src/logo.svg | 1 - app/packages/web/src/pages/share/index.astro | 39 + app/packages/web/src/sst-env.d.ts | 10 - app/packages/web/sst-env.d.ts | 9 - app/packages/web/tsconfig.json | 14 +- app/packages/web/vite.config.ts | 12 - 37 files changed, 1759 insertions(+), 1923 deletions(-) create mode 100644 app/packages/web/astro.config.mjs delete mode 100644 app/packages/web/index.html delete mode 100644 app/packages/web/pnpm-lock.yaml create mode 100644 app/packages/web/public/favicon.svg create mode 100644 app/packages/web/public/social-share.png delete mode 100644 app/packages/web/src/App.module.css delete mode 100644 app/packages/web/src/app.tsx delete mode 100644 app/packages/web/src/assets/favicon.ico create mode 100644 app/packages/web/src/assets/lander/check.svg create mode 100644 app/packages/web/src/assets/lander/copy.svg create mode 100644 app/packages/web/src/assets/logo-dark.svg create mode 100644 app/packages/web/src/assets/logo-light.svg create mode 100644 app/packages/web/src/components/Header.astro create mode 100644 app/packages/web/src/components/Hero.astro create mode 100644 app/packages/web/src/components/Lander.astro create mode 100644 app/packages/web/src/components/Share.tsx create mode 100644 app/packages/web/src/content.config.ts create mode 100644 app/packages/web/src/content/docs/docs/cli.mdx create mode 100644 app/packages/web/src/content/docs/docs/config.mdx create mode 100644 app/packages/web/src/content/docs/docs/index.mdx create mode 100644 app/packages/web/src/content/docs/docs/lsp-servers.mdx create mode 100644 app/packages/web/src/content/docs/docs/mcp-servers.mdx create mode 100644 app/packages/web/src/content/docs/docs/models.mdx create mode 100644 app/packages/web/src/content/docs/docs/shortcuts.mdx create mode 100644 app/packages/web/src/content/docs/docs/themes.mdx create mode 100644 app/packages/web/src/content/docs/index.mdx delete mode 100644 app/packages/web/src/index.css delete mode 100644 app/packages/web/src/index.tsx delete mode 100644 app/packages/web/src/logo.svg create mode 100644 app/packages/web/src/pages/share/index.astro delete mode 100644 app/packages/web/src/sst-env.d.ts delete mode 100644 app/packages/web/sst-env.d.ts delete mode 100644 app/packages/web/vite.config.ts (limited to 'app') diff --git a/app/packages/web/.gitignore b/app/packages/web/.gitignore index 76add878f..6240da8b1 100644 --- a/app/packages/web/.gitignore +++ b/app/packages/web/.gitignore @@ -1,2 +1,21 @@ -node_modules -dist \ No newline at end of file +# build output +dist/ +# generated types +.astro/ + +# dependencies +node_modules/ + +# logs +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + + +# environment variables +.env +.env.production + +# macOS-specific files +.DS_Store diff --git a/app/packages/web/README.md b/app/packages/web/README.md index 6a1764536..f9f6d31c6 100644 --- a/app/packages/web/README.md +++ b/app/packages/web/README.md @@ -1,34 +1,54 @@ -## Usage +# Starlight Starter Kit: Basics -Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`. +[![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build) -This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely be removed once you clone a template. - -```bash -$ npm install # or pnpm install or yarn install ``` +npm create astro@latest -- --template starlight +``` + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics) +[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics) +[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/withastro/starlight&create_from_path=examples/basics) +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs) -### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs) +> πŸ§‘β€πŸš€ **Seasoned astronaut?** Delete this file. Have fun! -## Available Scripts +## πŸš€ Project Structure -In the project directory, you can run: +Inside of your Astro + Starlight project, you'll see the following folders and files: + +``` +. +β”œβ”€β”€ public/ +β”œβ”€β”€ src/ +β”‚ β”œβ”€β”€ assets/ +β”‚ β”œβ”€β”€ content/ +β”‚ β”‚ β”œβ”€β”€ docs/ +β”‚ └── content.config.ts +β”œβ”€β”€ astro.config.mjs +β”œβ”€β”€ package.json +└── tsconfig.json +``` -### `npm run dev` or `npm start` +Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. -Runs the app in the development mode.
-Open [http://localhost:3000](http://localhost:3000) to view it in the browser. +Images can be added to `src/assets/` and embedded in Markdown with a relative link. -The page will reload if you make edits.
+Static assets, like favicons, can be placed in the `public/` directory. -### `npm run build` +## 🧞 Commands -Builds the app for production to the `dist` folder.
-It correctly bundles Solid in production mode and optimizes the build for the best performance. +All commands are run from the root of the project, from a terminal: -The build is minified and the filenames include the hashes.
-Your app is ready to be deployed! +| Command | Action | +| :------------------------ | :----------------------------------------------- | +| `npm install` | Installs dependencies | +| `npm run dev` | Starts local dev server at `localhost:4321` | +| `npm run build` | Build your production site to `./dist/` | +| `npm run preview` | Preview your build locally, before deploying | +| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | +| `npm run astro -- --help` | Get help using the Astro CLI | -## Deployment +## πŸ‘€ Want to learn more? -You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.) +Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat). diff --git a/app/packages/web/astro.config.mjs b/app/packages/web/astro.config.mjs new file mode 100644 index 000000000..78ddcdea8 --- /dev/null +++ b/app/packages/web/astro.config.mjs @@ -0,0 +1,65 @@ +// @ts-check +import { defineConfig } from "astro/config"; +import starlight from "@astrojs/starlight"; +import solidJs from "@astrojs/solid-js"; +import theme from "toolbeam-docs-theme"; +import { rehypeHeadingIds } from "@astrojs/markdown-remark"; +import rehypeAutolinkHeadings from "rehype-autolink-headings"; + +const discord = "https://discord.gg/sst"; +const github = "https://github.com/sst/opencode"; + +// https://astro.build/config +export default defineConfig({ + devToolbar: { + enabled: false, + }, + markdown: { + rehypePlugins: [ + rehypeHeadingIds, + [rehypeAutolinkHeadings, { behavior: "wrap" }], + ], + }, + integrations: [ + solidJs(), + starlight({ + title: "OpenCode", + social: [ + { icon: "discord", label: "Discord", href: discord }, + { icon: "github", label: "GitHub", href: github }, + ], + editLink: { + baseUrl: `${github}/edit/master/www/`, + }, + markdown: { + headingLinks: false, + }, + logo: { + light: "./src/assets/logo-light.svg", + dark: "./src/assets/logo-dark.svg", + replacesTitle: true, + }, + sidebar: [ + "docs", + "docs/cli", + "docs/config", + "docs/models", + "docs/themes", + "docs/shortcuts", + "docs/lsp-servers", + "docs/mcp-servers", + ], + components: { + Hero: "./src/components/Hero.astro", + Header: "./src/components/Header.astro", + }, + plugins: [theme({ + // Optionally, add your own header links + headerLinks: [ + { name: "Home", url: "/" }, + { name: "Docs", url: "/docs/" }, + ], + })], + }), + ], +}); diff --git a/app/packages/web/index.html b/app/packages/web/index.html deleted file mode 100644 index 48c59fc12..000000000 --- a/app/packages/web/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - Solid App - - - -
- - - - diff --git a/app/packages/web/package.json b/app/packages/web/package.json index 7d3a1674d..73c4fa698 100644 --- a/app/packages/web/package.json +++ b/app/packages/web/package.json @@ -1,23 +1,24 @@ { - "name": "vite-template-solid", - "version": "0.0.0", - "description": "", + "name": "web", "type": "module", + "version": "0.0.1", "scripts": { - "start": "vite", - "dev": "vite", - "build": "vite build", - "serve": "vite preview" - }, - "license": "MIT", - "devDependencies": { - "ai": "^5.0.0-alpha.2", - "typescript": "5.8.2", - "vite": "6.2.2", - "vite-plugin-solid": "2.11.6" + "dev": "astro dev", + "start": "astro dev", + "build": "astro build", + "preview": "astro preview", + "astro": "astro" }, "dependencies": { - "@solidjs/router": "0.15.3", - "solid-js": "1.9.5" + "@astrojs/markdown-remark": "^6.3.1", + "@astrojs/solid-js": "^5.1.0", + "@astrojs/starlight": "^0.34.3", + "@fontsource/ibm-plex-mono": "^5.2.5", + "ai": "^5.0.0-alpha.2", + "astro": "^5.7.13", + "rehype-autolink-headings": "^7.1.0", + "sharp": "^0.32.5", + "solid-js": "^1.9.7", + "toolbeam-docs-theme": "^0.2.4" } } diff --git a/app/packages/web/pnpm-lock.yaml b/app/packages/web/pnpm-lock.yaml deleted file mode 100644 index 0b9b47ba9..000000000 --- a/app/packages/web/pnpm-lock.yaml +++ /dev/null @@ -1,1065 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - solid-js: - specifier: ^1.9.5 - version: 1.9.5 - devDependencies: - typescript: - specifier: ^5.7.2 - version: 5.7.2 - vite: - specifier: ^6.0.0 - version: 6.0.0 - vite-plugin-solid: - specifier: ^2.11.6 - version: 2.11.6(solid-js@1.9.5)(vite@6.0.0) - -packages: - - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@babel/code-frame@7.26.2': - resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.26.2': - resolution: {integrity: sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.26.0': - resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.26.2': - resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.25.9': - resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.18.6': - resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.25.9': - resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.26.0': - resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-plugin-utils@7.25.9': - resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.25.9': - resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.25.9': - resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-option@7.25.9': - resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.26.0': - resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.26.2': - resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/plugin-syntax-jsx@7.25.9': - resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/template@7.25.9': - resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.25.9': - resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.26.0': - resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} - engines: {node: '>=6.9.0'} - - '@esbuild/aix-ppc64@0.24.0': - resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.24.0': - resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.24.0': - resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.24.0': - resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.24.0': - resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.24.0': - resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.24.0': - resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.24.0': - resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.24.0': - resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.24.0': - resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.24.0': - resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.24.0': - resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.24.0': - resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.24.0': - resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.24.0': - resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.24.0': - resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.24.0': - resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.24.0': - resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.24.0': - resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.24.0': - resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.24.0': - resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.24.0': - resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.24.0': - resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.24.0': - resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - - '@rollup/rollup-android-arm-eabi@4.27.4': - resolution: {integrity: sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.27.4': - resolution: {integrity: sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.27.4': - resolution: {integrity: sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.27.4': - resolution: {integrity: sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.27.4': - resolution: {integrity: sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.27.4': - resolution: {integrity: sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.27.4': - resolution: {integrity: sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.27.4': - resolution: {integrity: sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.27.4': - resolution: {integrity: sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.27.4': - resolution: {integrity: sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.27.4': - resolution: {integrity: sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.27.4': - resolution: {integrity: sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.27.4': - resolution: {integrity: sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.27.4': - resolution: {integrity: sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.27.4': - resolution: {integrity: sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.27.4': - resolution: {integrity: sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.27.4': - resolution: {integrity: sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.27.4': - resolution: {integrity: sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==} - cpu: [x64] - os: [win32] - - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - - '@types/babel__generator@7.6.8': - resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} - - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - - '@types/babel__traverse@7.20.6': - resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} - - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - - babel-plugin-jsx-dom-expressions@0.39.3: - resolution: {integrity: sha512-6RzmSu21zYPlV2gNwzjGG9FgODtt9hIWnx7L//OIioIEuRcnpDZoY8Tr+I81Cy1SrH4qoDyKpwHHo6uAMAeyPA==} - peerDependencies: - '@babel/core': ^7.20.12 - - babel-preset-solid@1.9.3: - resolution: {integrity: sha512-jvlx5wDp8s+bEF9sGFw/84SInXOA51ttkUEroQziKMbxplXThVKt83qB6bDTa1HuLNatdU9FHpFOiQWs1tLQIg==} - peerDependencies: - '@babel/core': ^7.0.0 - - browserslist@4.24.2: - resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - caniuse-lite@1.0.30001684: - resolution: {integrity: sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==} - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - - debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - electron-to-chromium@1.5.65: - resolution: {integrity: sha512-PWVzBjghx7/wop6n22vS2MLU8tKGd4Q91aCEGhG/TYmW6PP5OcSXcdnxTe1NNt0T66N8D6jxh4kC8UsdzOGaIw==} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - esbuild@0.24.0: - resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - - html-entities@2.3.3: - resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} - - is-what@4.1.16: - resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} - engines: {node: '>=12.13'} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - jsesc@3.0.2: - resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} - engines: {node: '>=6'} - hasBin: true - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - - merge-anything@5.1.7: - resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==} - engines: {node: '>=12.13'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - nanoid@3.3.8: - resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} - - parse5@7.2.1: - resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - postcss@8.4.49: - resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} - engines: {node: ^10 || ^12 || >=14} - - rollup@4.27.4: - resolution: {integrity: sha512-RLKxqHEMjh/RGLsDxAEsaLO3mWgyoU6x9w6n1ikAzet4B3gI2/3yP6PWY2p9QzRTh6MfEIXB3MwsOY0Iv3vNrw==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - - seroval-plugins@1.1.1: - resolution: {integrity: sha512-qNSy1+nUj7hsCOon7AO4wdAIo9P0jrzAMp18XhiOzA6/uO5TKtP7ScozVJ8T293oRIvi5wyCHSM4TrJo/c/GJA==} - engines: {node: '>=10'} - peerDependencies: - seroval: ^1.0 - - seroval@1.1.1: - resolution: {integrity: sha512-rqEO6FZk8mv7Hyv4UCj3FD3b6Waqft605TLfsCe/BiaylRpyyMC0b+uA5TJKawX3KzMrdi3wsLbCaLplrQmBvQ==} - engines: {node: '>=10'} - - solid-js@1.9.5: - resolution: {integrity: sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==} - - solid-refresh@0.6.3: - resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==} - peerDependencies: - solid-js: ^1.3 - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - typescript@5.7.2: - resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} - engines: {node: '>=14.17'} - hasBin: true - - update-browserslist-db@1.1.1: - resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - validate-html-nesting@1.2.2: - resolution: {integrity: sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==} - - vite-plugin-solid@2.11.6: - resolution: {integrity: sha512-Sl5CTqJTGyEeOsmdH6BOgalIZlwH3t4/y0RQuFLMGnvWMBvxb4+lq7x3BSiAw6etf0QexfNJW7HSOO/Qf7pigg==} - peerDependencies: - '@testing-library/jest-dom': ^5.16.6 || ^5.17.0 || ^6.* - solid-js: ^1.7.2 - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - peerDependenciesMeta: - '@testing-library/jest-dom': - optional: true - - vite@6.0.0: - resolution: {integrity: sha512-Q2+5yQV79EdnpbNxjD3/QHVMCBaQ3Kpd4/uL51UGuh38bIIM+s4o3FqyCzRvTRwFb+cWIUeZvaWwS9y2LD2qeQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitefu@1.0.4: - resolution: {integrity: sha512-y6zEE3PQf6uu/Mt6DTJ9ih+kyJLr4XcSgHR2zUkM8SWDhuixEJxfJ6CZGMHh1Ec3vPLoEA0IHU5oWzVqw8ulow==} - peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - peerDependenciesMeta: - vite: - optional: true - - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - -snapshots: - - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - - '@babel/code-frame@7.26.2': - dependencies: - '@babel/helper-validator-identifier': 7.25.9 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/compat-data@7.26.2': {} - - '@babel/core@7.26.0': - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.2 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helpers': 7.26.0 - '@babel/parser': 7.26.2 - '@babel/template': 7.25.9 - '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 - convert-source-map: 2.0.0 - debug: 4.3.7 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.26.2': - dependencies: - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 3.0.2 - - '@babel/helper-compilation-targets@7.25.9': - dependencies: - '@babel/compat-data': 7.26.2 - '@babel/helper-validator-option': 7.25.9 - browserslist: 4.24.2 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-module-imports@7.18.6': - dependencies: - '@babel/types': 7.26.0 - - '@babel/helper-module-imports@7.25.9': - dependencies: - '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.25.9 - transitivePeerDependencies: - - supports-color - - '@babel/helper-plugin-utils@7.25.9': {} - - '@babel/helper-string-parser@7.25.9': {} - - '@babel/helper-validator-identifier@7.25.9': {} - - '@babel/helper-validator-option@7.25.9': {} - - '@babel/helpers@7.26.0': - dependencies: - '@babel/template': 7.25.9 - '@babel/types': 7.26.0 - - '@babel/parser@7.26.2': - dependencies: - '@babel/types': 7.26.0 - - '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/template@7.25.9': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 - - '@babel/traverse@7.25.9': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.2 - '@babel/parser': 7.26.2 - '@babel/template': 7.25.9 - '@babel/types': 7.26.0 - debug: 4.3.7 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - - '@babel/types@7.26.0': - dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - - '@esbuild/aix-ppc64@0.24.0': - optional: true - - '@esbuild/android-arm64@0.24.0': - optional: true - - '@esbuild/android-arm@0.24.0': - optional: true - - '@esbuild/android-x64@0.24.0': - optional: true - - '@esbuild/darwin-arm64@0.24.0': - optional: true - - '@esbuild/darwin-x64@0.24.0': - optional: true - - '@esbuild/freebsd-arm64@0.24.0': - optional: true - - '@esbuild/freebsd-x64@0.24.0': - optional: true - - '@esbuild/linux-arm64@0.24.0': - optional: true - - '@esbuild/linux-arm@0.24.0': - optional: true - - '@esbuild/linux-ia32@0.24.0': - optional: true - - '@esbuild/linux-loong64@0.24.0': - optional: true - - '@esbuild/linux-mips64el@0.24.0': - optional: true - - '@esbuild/linux-ppc64@0.24.0': - optional: true - - '@esbuild/linux-riscv64@0.24.0': - optional: true - - '@esbuild/linux-s390x@0.24.0': - optional: true - - '@esbuild/linux-x64@0.24.0': - optional: true - - '@esbuild/netbsd-x64@0.24.0': - optional: true - - '@esbuild/openbsd-arm64@0.24.0': - optional: true - - '@esbuild/openbsd-x64@0.24.0': - optional: true - - '@esbuild/sunos-x64@0.24.0': - optional: true - - '@esbuild/win32-arm64@0.24.0': - optional: true - - '@esbuild/win32-ia32@0.24.0': - optional: true - - '@esbuild/win32-x64@0.24.0': - optional: true - - '@jridgewell/gen-mapping@0.3.5': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - - '@rollup/rollup-android-arm-eabi@4.27.4': - optional: true - - '@rollup/rollup-android-arm64@4.27.4': - optional: true - - '@rollup/rollup-darwin-arm64@4.27.4': - optional: true - - '@rollup/rollup-darwin-x64@4.27.4': - optional: true - - '@rollup/rollup-freebsd-arm64@4.27.4': - optional: true - - '@rollup/rollup-freebsd-x64@4.27.4': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.27.4': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.27.4': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.27.4': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.27.4': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.27.4': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.27.4': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.27.4': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.27.4': - optional: true - - '@rollup/rollup-linux-x64-musl@4.27.4': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.27.4': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.27.4': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.27.4': - optional: true - - '@types/babel__core@7.20.5': - dependencies: - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 - '@types/babel__generator': 7.6.8 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.6 - - '@types/babel__generator@7.6.8': - dependencies: - '@babel/types': 7.26.0 - - '@types/babel__template@7.4.4': - dependencies: - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 - - '@types/babel__traverse@7.20.6': - dependencies: - '@babel/types': 7.26.0 - - '@types/estree@1.0.6': {} - - babel-plugin-jsx-dom-expressions@0.39.3(@babel/core@7.26.0): - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.18.6 - '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) - '@babel/types': 7.26.0 - html-entities: 2.3.3 - parse5: 7.2.1 - validate-html-nesting: 1.2.2 - - babel-preset-solid@1.9.3(@babel/core@7.26.0): - dependencies: - '@babel/core': 7.26.0 - babel-plugin-jsx-dom-expressions: 0.39.3(@babel/core@7.26.0) - - browserslist@4.24.2: - dependencies: - caniuse-lite: 1.0.30001684 - electron-to-chromium: 1.5.65 - node-releases: 2.0.18 - update-browserslist-db: 1.1.1(browserslist@4.24.2) - - caniuse-lite@1.0.30001684: {} - - convert-source-map@2.0.0: {} - - csstype@3.1.3: {} - - debug@4.3.7: - dependencies: - ms: 2.1.3 - - electron-to-chromium@1.5.65: {} - - entities@4.5.0: {} - - esbuild@0.24.0: - optionalDependencies: - '@esbuild/aix-ppc64': 0.24.0 - '@esbuild/android-arm': 0.24.0 - '@esbuild/android-arm64': 0.24.0 - '@esbuild/android-x64': 0.24.0 - '@esbuild/darwin-arm64': 0.24.0 - '@esbuild/darwin-x64': 0.24.0 - '@esbuild/freebsd-arm64': 0.24.0 - '@esbuild/freebsd-x64': 0.24.0 - '@esbuild/linux-arm': 0.24.0 - '@esbuild/linux-arm64': 0.24.0 - '@esbuild/linux-ia32': 0.24.0 - '@esbuild/linux-loong64': 0.24.0 - '@esbuild/linux-mips64el': 0.24.0 - '@esbuild/linux-ppc64': 0.24.0 - '@esbuild/linux-riscv64': 0.24.0 - '@esbuild/linux-s390x': 0.24.0 - '@esbuild/linux-x64': 0.24.0 - '@esbuild/netbsd-x64': 0.24.0 - '@esbuild/openbsd-arm64': 0.24.0 - '@esbuild/openbsd-x64': 0.24.0 - '@esbuild/sunos-x64': 0.24.0 - '@esbuild/win32-arm64': 0.24.0 - '@esbuild/win32-ia32': 0.24.0 - '@esbuild/win32-x64': 0.24.0 - - escalade@3.2.0: {} - - fsevents@2.3.3: - optional: true - - gensync@1.0.0-beta.2: {} - - globals@11.12.0: {} - - html-entities@2.3.3: {} - - is-what@4.1.16: {} - - js-tokens@4.0.0: {} - - jsesc@3.0.2: {} - - json5@2.2.3: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - - merge-anything@5.1.7: - dependencies: - is-what: 4.1.16 - - ms@2.1.3: {} - - nanoid@3.3.8: {} - - node-releases@2.0.18: {} - - parse5@7.2.1: - dependencies: - entities: 4.5.0 - - picocolors@1.1.1: {} - - postcss@8.4.49: - dependencies: - nanoid: 3.3.8 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - rollup@4.27.4: - dependencies: - '@types/estree': 1.0.6 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.27.4 - '@rollup/rollup-android-arm64': 4.27.4 - '@rollup/rollup-darwin-arm64': 4.27.4 - '@rollup/rollup-darwin-x64': 4.27.4 - '@rollup/rollup-freebsd-arm64': 4.27.4 - '@rollup/rollup-freebsd-x64': 4.27.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.27.4 - '@rollup/rollup-linux-arm-musleabihf': 4.27.4 - '@rollup/rollup-linux-arm64-gnu': 4.27.4 - '@rollup/rollup-linux-arm64-musl': 4.27.4 - '@rollup/rollup-linux-powerpc64le-gnu': 4.27.4 - '@rollup/rollup-linux-riscv64-gnu': 4.27.4 - '@rollup/rollup-linux-s390x-gnu': 4.27.4 - '@rollup/rollup-linux-x64-gnu': 4.27.4 - '@rollup/rollup-linux-x64-musl': 4.27.4 - '@rollup/rollup-win32-arm64-msvc': 4.27.4 - '@rollup/rollup-win32-ia32-msvc': 4.27.4 - '@rollup/rollup-win32-x64-msvc': 4.27.4 - fsevents: 2.3.3 - - semver@6.3.1: {} - - seroval-plugins@1.1.1(seroval@1.1.1): - dependencies: - seroval: 1.1.1 - - seroval@1.1.1: {} - - solid-js@1.9.5: - dependencies: - csstype: 3.1.3 - seroval: 1.1.1 - seroval-plugins: 1.1.1(seroval@1.1.1) - - solid-refresh@0.6.3(solid-js@1.9.5): - dependencies: - '@babel/generator': 7.26.2 - '@babel/helper-module-imports': 7.25.9 - '@babel/types': 7.26.0 - solid-js: 1.9.5 - transitivePeerDependencies: - - supports-color - - source-map-js@1.2.1: {} - - typescript@5.7.2: {} - - update-browserslist-db@1.1.1(browserslist@4.24.2): - dependencies: - browserslist: 4.24.2 - escalade: 3.2.0 - picocolors: 1.1.1 - - validate-html-nesting@1.2.2: {} - - vite-plugin-solid@2.11.6(solid-js@1.9.5)(vite@6.0.0): - dependencies: - '@babel/core': 7.26.0 - '@types/babel__core': 7.20.5 - babel-preset-solid: 1.9.3(@babel/core@7.26.0) - merge-anything: 5.1.7 - solid-js: 1.9.5 - solid-refresh: 0.6.3(solid-js@1.9.5) - vite: 6.0.0 - vitefu: 1.0.4(vite@6.0.0) - transitivePeerDependencies: - - supports-color - - vite@6.0.0: - dependencies: - esbuild: 0.24.0 - postcss: 8.4.49 - rollup: 4.27.4 - optionalDependencies: - fsevents: 2.3.3 - - vitefu@1.0.4(vite@6.0.0): - optionalDependencies: - vite: 6.0.0 - - yallist@3.1.1: {} diff --git a/app/packages/web/public/favicon.svg b/app/packages/web/public/favicon.svg new file mode 100644 index 000000000..8b011db3f --- /dev/null +++ b/app/packages/web/public/favicon.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/packages/web/public/social-share.png b/app/packages/web/public/social-share.png new file mode 100644 index 000000000..23905086a Binary files /dev/null and b/app/packages/web/public/social-share.png differ diff --git a/app/packages/web/src/App.module.css b/app/packages/web/src/App.module.css deleted file mode 100644 index 48308b24a..000000000 --- a/app/packages/web/src/App.module.css +++ /dev/null @@ -1,33 +0,0 @@ -.App { - text-align: center; -} - -.logo { - animation: logo-spin infinite 20s linear; - height: 40vmin; - pointer-events: none; -} - -.header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.link { - color: #b318f0; -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/app/packages/web/src/app.tsx b/app/packages/web/src/app.tsx deleted file mode 100644 index 369bcfa41..000000000 --- a/app/packages/web/src/app.tsx +++ /dev/null @@ -1,692 +0,0 @@ -import { createSignal, onCleanup, onMount, Show, For } from "solid-js" -import { useParams } from "@solidjs/router" -import { type UIMessage } from "ai" - -type Message = { - key: string - content: string -} - -type SessionInfo = { - tokens?: { - input?: number - output?: number - reasoning?: number - } -} - -export default function App() { - const params = useParams<{ id: string }>() - const [connectionStatus, setConnectionStatus] = createSignal("Disconnected") - const [sessionInfo, setSessionInfo] = createSignal(null) - const [systemMessage, setSystemMessage] = createSignal(null) - const [messages, setMessages] = createSignal([]) - const [expandedSystemMessage, setExpandedSystemMessage] = createSignal(false) - - onMount(() => { - // Get the API URL from environment - const apiUrl = import.meta.env.VITE_API_URL - const shareId = params.id - - console.log("Mounting Share component with ID:", shareId) - console.log("API URL:", apiUrl) - - if (!shareId) { - console.error("Share ID not found in environment variables") - setConnectionStatus("Error: Share ID not found") - return - } - - if (!apiUrl) { - console.error("API URL not found in environment variables") - setConnectionStatus("Error: API URL not found") - return - } - - let reconnectTimer: number | undefined - let socket: WebSocket | null = null - - // Function to create and set up WebSocket with auto-reconnect - const setupWebSocket = () => { - // Close any existing connection - if (socket) { - socket.close() - } - - setConnectionStatus("Connecting...") - - // Always use secure WebSocket protocol (wss) - const wsBaseUrl = apiUrl.replace(/^https?:\/\//, "wss://") - const wsUrl = `${wsBaseUrl}/share_poll?shareID=${shareId}` - console.log("Connecting to WebSocket URL:", wsUrl) - - // Create WebSocket connection - socket = new WebSocket(wsUrl) - - // Handle connection opening - socket.onopen = () => { - setConnectionStatus("Connected") - console.log("WebSocket connection established") - } - - // Handle incoming messages - socket.onmessage = (event) => { - console.log("WebSocket message received") - try { - const data = JSON.parse(event.data) as Message - - // Check if this is a session info message - if (data.key.startsWith("session/info/")) { - const infoContent = JSON.parse(data.content) as SessionInfo - setSessionInfo(infoContent) - console.log("Session info updated:", infoContent) - return - } - - // Check if it's a system message - const msgContent = JSON.parse(data.content) as UIMessage - if (msgContent.role === "system") { - setSystemMessage(data) - console.log("System message updated:", data) - return - } - - // Non-system messages - setMessages((prev) => { - // Check if message with this key already exists - const existingIndex = prev.findIndex((msg) => msg.key === data.key) - if (existingIndex >= 0) { - // Update existing message - const updated = [...prev] - updated[existingIndex] = data - return updated - } else { - // Add new message - return [...prev, data] - } - }) - } catch (error) { - console.error("Error parsing WebSocket message:", error) - } - } - - // Handle errors - socket.onerror = (error) => { - console.error("WebSocket error:", error) - setConnectionStatus("Error: Connection failed") - } - - // Handle connection close and reconnection - socket.onclose = (event) => { - console.log(`WebSocket closed: ${event.code} ${event.reason}`) - setConnectionStatus("Disconnected, reconnecting...") - - // Try to reconnect after 2 seconds - clearTimeout(reconnectTimer) - reconnectTimer = window.setTimeout( - setupWebSocket, - 2000, - ) as unknown as number - } - } - - // Initial connection - setupWebSocket() - - // Clean up on component unmount - onCleanup(() => { - console.log("Cleaning up WebSocket connection") - if (socket) { - socket.close() - } - clearTimeout(reconnectTimer) - }) - }) - - return ( -
-

Share: {params.id}

- -
-

WebSocket Connection

-

- Status: {connectionStatus()} -

- -

Live Updates

- - -
-

Session Information

-
-
- Input Tokens:{" "} - {sessionInfo()?.tokens?.input || 0} -
-
- Output Tokens:{" "} - {sessionInfo()?.tokens?.output || 0} -
-
- Reasoning Tokens:{" "} - {sessionInfo()?.tokens?.reasoning || 0} -
-
-
-
- - {/* Display system message as context in the Session Information block */} - -
-

Context

- {(() => { - try { - const parsed = JSON.parse( - systemMessage()?.content || "", - ) as UIMessage - if ( - parsed.parts && - parsed.parts.length > 0 && - parsed.parts[0].type === "text" - ) { - const text = parsed.parts[0].text || "" - const lines = text.split("\n") - const visibleLines = expandedSystemMessage() - ? lines - : lines.slice(0, 5) - const hasMoreLines = lines.length > 5 - - return ( - <> -
- {/* Create a modified version of the text part for the system message */} - {(() => { - // Create a modified part with truncated text - const modifiedPart = { - ...parsed.parts[0], - text: visibleLines.join("\n"), - } - - return ( - <> -
{modifiedPart.text}
- {hasMoreLines && !expandedSystemMessage() && ( -
- {lines.length - 5} more lines... -
- )} - - ) - })()} -
- {hasMoreLines && ( - - )} - - ) - } - } catch (e) { - return
Error parsing system message
- } - - return null - })()} -
-
- -
- 0} - fallback={

Waiting for messages...

} - > -
    - - {(msg) => ( -
  • -
    - Key: {msg.key} -
    - - {(() => { - try { - const parsed = JSON.parse(msg.content) as UIMessage - const createdTime = parsed.metadata?.time?.created - ? new Date( - parsed.metadata.time.created, - ).toLocaleString() - : "Unknown time" - - return ( - <> -
    - Full Content: -
    -                                {JSON.stringify(parsed, null, 2)}
    -                              
    -
    - - {parsed.parts && parsed.parts.length > 0 && ( -
    -
    - - Role: {parsed.role || "Unknown"} - - - {createdTime} - -
    - -
    - part.type !== "step-start", - )} - > - {(part) => { - if (part.type === "text") { - //{ - // "type": "text", - // "text": "Hello! How can I help you today?" - //} - return ( -
    -                                            [{part.type}] {part.text}{" "}
    -                                          
    - ) - } - if (part.type === "reasoning") { - //{ - // "type": "reasoning", - // "text": "The user asked for a weather forecast. I should call the 'getWeather' tool with the location 'San Francisco'.", - // "providerMetadata": { "step_id": "reason_step_1" } - //} - return ( -
    -                                            [{part.type}] {part.text}
    -                                          
    - ) - } - if (part.type === "tool-invocation") { - return ( -
    -
    - -
    -                                                  [{part.type}]
    -                                                
    {" "} - Tool:{" "} - - {part.toolInvocation.toolName} - -
    - {parsed.metadata?.tool?.[ - part.toolInvocation.toolCallId - ]?.time?.start && - parsed.metadata?.tool?.[ - part.toolInvocation.toolCallId - ]?.time?.end && ( - - {( - (new Date( - parsed.metadata?.tool?.[ - part.toolInvocation.toolCallId - ].time.end, - ) - - new Date( - parsed.metadata?.tool?.[ - part.toolInvocation.toolCallId - ].time.start, - )) / - 1000 - ).toFixed(2)} - s - - )} -
    - {(() => { - if ( - part.toolInvocation.state === - "partial-call" - ) { - //{ - // "type": "tool-invocation", - // "toolInvocation": { - // "state": "partial-call", - // "toolCallId": "tool_abc123", - // "toolName": "searchWeb", - // "argsTextDelta": "{\"query\":\"latest AI news" - // } - //} - return ( - <> -
    -                                                      {
    -                                                        part.toolInvocation
    -                                                          .argsTextDelta
    -                                                      }
    -                                                    
    - ... - - ) - } - if ( - part.toolInvocation.state === - "call" - ) { - //{ - // "type": "tool-invocation", - // "toolInvocation": { - // "state": "call", - // "toolCallId": "tool_abc123", - // "toolName": "searchWeb", - // "args": { "query": "latest AI news", "count": 3 } - // } - //} - return ( -
    -                                                    {JSON.stringify(
    -                                                      part.toolInvocation.args,
    -                                                      null,
    -                                                      2,
    -                                                    )}
    -                                                  
    - ) - } - if ( - part.toolInvocation.state === - "result" - ) { - //{ - // "type": "tool-invocation", - // "toolInvocation": { - // "state": "result", - // "toolCallId": "tool_abc123", - // "toolName": "searchWeb", - // "args": { "query": "latest AI news", "count": 3 }, - // "result": [ - // { "title": "AI SDK v5 Announced", "url": "..." }, - // { "title": "New LLM Achieves SOTA", "url": "..." } - // ] - // } - //} - return ( - <> -
    -                                                      {JSON.stringify(
    -                                                        part.toolInvocation
    -                                                          .args,
    -                                                        null,
    -                                                        2,
    -                                                      )}
    -                                                    
    -
    -                                                      {JSON.stringify(
    -                                                        part.toolInvocation
    -                                                          .result,
    -                                                        null,
    -                                                        2,
    -                                                      )}
    -                                                    
    - - ) - } - if ( - part.toolInvocation.state === - "error" - ) { - //{ - // "type": "tool-invocation", - // "toolInvocation": { - // "state": "error", - // "toolCallId": "tool_abc123", - // "toolName": "searchWeb", - // "args": { "query": "latest AI news", "count": 3 }, - // "errorMessage": "API limit exceeded for searchWeb tool." - // } - //} - return ( - <> -
    -                                                      {JSON.stringify(
    -                                                        part.toolInvocation
    -                                                          .args,
    -                                                        null,
    -                                                        2,
    -                                                      )}
    -                                                    
    -
    -                                                      {
    -                                                        part.toolInvocation
    -                                                          .errorMessage
    -                                                      }
    -                                                    
    - - ) - } - })()} -
    - ) - } - if (part.type === "source") { - //{ - // "type": "source", - // "source": { - // "sourceType": "url", - // "id": "doc_xyz789", - // "url": "https://example.com/research-paper.pdf", - // "title": "Groundbreaking AI Research Paper" - // } - //} - return ( -
    -
    - -
    [{part.type}]
    -
    - - Source:{" "} - {part.source.title || - part.source.id} - -
    - {part.source.url && ( - - )} - {part.source.sourceType && ( -
    - Type: {part.source.sourceType} -
    - )} -
    - ) - } - if (part.type === "file") { - //{ - // "type": "file", - // "mediaType": "image/jpeg", - // "filename": "cat_photo.jpg", - // "url": "https://example-files.com/cats/cat_photo.jpg" - //} - const isImage = - part.mediaType?.startsWith("image/") - - return ( -
    -
    - -
    [{part.type}]
    -
    - File: {part.filename} - {part.mediaType} -
    - - {isImage && part.url ? ( -
    - { -
    - ) : ( -
    - {part.url ? ( - - Download: {part.filename} - - ) : ( -
    - File attachment (no URL - available) -
    - )} -
    - )} -
    - ) - } - return null - }} -
    -
    -
    - )} - - ) - } catch (e) { - return ( -
    - Content: -
    -                              {msg.content}
    -                            
    -
    - ) - } - })()} -
  • - )} -
    -
-
-
-
-
- ) -} diff --git a/app/packages/web/src/assets/favicon.ico b/app/packages/web/src/assets/favicon.ico deleted file mode 100644 index b836b2bcc..000000000 Binary files a/app/packages/web/src/assets/favicon.ico and /dev/null differ diff --git a/app/packages/web/src/assets/lander/check.svg b/app/packages/web/src/assets/lander/check.svg new file mode 100644 index 000000000..22de6f2a8 --- /dev/null +++ b/app/packages/web/src/assets/lander/check.svg @@ -0,0 +1,2 @@ + + diff --git a/app/packages/web/src/assets/lander/copy.svg b/app/packages/web/src/assets/lander/copy.svg new file mode 100644 index 000000000..f1baac30a --- /dev/null +++ b/app/packages/web/src/assets/lander/copy.svg @@ -0,0 +1,2 @@ + + diff --git a/app/packages/web/src/assets/logo-dark.svg b/app/packages/web/src/assets/logo-dark.svg new file mode 100644 index 000000000..8fd212081 --- /dev/null +++ b/app/packages/web/src/assets/logo-dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/app/packages/web/src/assets/logo-light.svg b/app/packages/web/src/assets/logo-light.svg new file mode 100644 index 000000000..0a9007e1a --- /dev/null +++ b/app/packages/web/src/assets/logo-light.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/app/packages/web/src/components/Header.astro b/app/packages/web/src/components/Header.astro new file mode 100644 index 000000000..f027d7274 --- /dev/null +++ b/app/packages/web/src/components/Header.astro @@ -0,0 +1,57 @@ +--- +import config from 'virtual:starlight/user-config'; +import { Icon } from '@astrojs/starlight/components'; +import { HeaderLinks } from 'toolbeam-docs-theme/components'; +import Default from 'toolbeam-docs-theme/overrides/Header.astro'; +import SiteTitle from '@astrojs/starlight/components/SiteTitle.astro'; + +const path = Astro.url.pathname; + +const links = config.social || []; +--- + +{ path.startsWith("/share") + ?
+
+ +
+
+ +
+
+ : +} + + + diff --git a/app/packages/web/src/components/Hero.astro b/app/packages/web/src/components/Hero.astro new file mode 100644 index 000000000..f80f85266 --- /dev/null +++ b/app/packages/web/src/components/Hero.astro @@ -0,0 +1,11 @@ +--- +import Default from '@astrojs/starlight/components/Hero.astro'; +import Lander from './Lander.astro'; + +const { slug } = Astro.locals.starlightRoute.entry; +--- + +{ slug === "" + ? + : +} diff --git a/app/packages/web/src/components/Lander.astro b/app/packages/web/src/components/Lander.astro new file mode 100644 index 000000000..d27358f8f --- /dev/null +++ b/app/packages/web/src/components/Lander.astro @@ -0,0 +1,269 @@ +--- +import { Image } from 'astro:assets'; +import config from "virtual:starlight/user-config"; +import type { Props } from '@astrojs/starlight/props'; + +import CopyIcon from "../assets/lander/copy.svg"; +import CheckIcon from "../assets/lander/check.svg"; + +const { data } = Astro.locals.starlightRoute.entry; +const { title = data.title, tagline, image, actions = [] } = data.hero || {}; + +const imageAttrs = { + loading: 'eager' as const, + decoding: 'async' as const, + width: 400, + alt: image?.alt || '', +}; + +const github = config.social.filter(s => s.icon === 'github')[0]; + +const command = "npm i -g"; +const pkg = "opencode"; + +let darkImage: ImageMetadata | undefined; +let lightImage: ImageMetadata | undefined; +let rawHtml: string | undefined; +if (image) { + if ('file' in image) { + darkImage = image.file; + } else if ('dark' in image) { + darkImage = image.dark; + lightImage = image.light; + } else { + rawHtml = image.html; + } +} +--- +
+
+ +

The AI coding agent built for the terminal.

+
+ +
+ +
+ +
+ +
+ +
+
    +
  • Native TUI: A native terminal UI for a smoother, snappier experience.
  • +
  • LSP enabled: Loads the right LSPs for your codebase. Helps the LLM make fewer mistakes.
  • +
  • Multi-session: Start multiple conversations in a project to have agents working in parallel.
  • +
  • Use any model: Supports all the models from OpenAI, Anthropic, Google, OpenRouter, and more.
  • +
  • Change tracking: View the file changes from the current conversation in the sidebar.
  • +
  • Edit with Vim: Use Vim as an external editor to compose longer messages.
  • +
+
+ + +
+ + + + + + diff --git a/app/packages/web/src/components/Share.tsx b/app/packages/web/src/components/Share.tsx new file mode 100644 index 000000000..906a9ab9c --- /dev/null +++ b/app/packages/web/src/components/Share.tsx @@ -0,0 +1,691 @@ +import { createSignal, onCleanup, onMount, Show, For } from "solid-js" +import { type UIMessage } from "ai" + +type Message = { + key: string + content: string +} + +type SessionInfo = { + tokens?: { + input?: number + output?: number + reasoning?: number + } +} + +export default function Share(props: { api: string }) { + let params = new URLSearchParams(document.location.search) + const shareId = params.get("id") + + const [connectionStatus, setConnectionStatus] = createSignal("Disconnected") + const [sessionInfo, setSessionInfo] = createSignal(null) + const [systemMessage, setSystemMessage] = createSignal(null) + const [messages, setMessages] = createSignal([]) + const [expandedSystemMessage, setExpandedSystemMessage] = createSignal(false) + + onMount(() => { + const apiUrl = props.api + + console.log("Mounting Share component with ID:", shareId) + console.log("API URL:", apiUrl) + + if (!shareId) { + console.error("Share ID not found in environment variables") + setConnectionStatus("Error: Share ID not found") + return + } + + if (!apiUrl) { + console.error("API URL not found in environment variables") + setConnectionStatus("Error: API URL not found") + return + } + + let reconnectTimer: number | undefined + let socket: WebSocket | null = null + + // Function to create and set up WebSocket with auto-reconnect + const setupWebSocket = () => { + // Close any existing connection + if (socket) { + socket.close() + } + + setConnectionStatus("Connecting...") + + // Always use secure WebSocket protocol (wss) + const wsBaseUrl = apiUrl.replace(/^https?:\/\//, "wss://") + const wsUrl = `${wsBaseUrl}/share_poll?shareID=${shareId}` + console.log("Connecting to WebSocket URL:", wsUrl) + + // Create WebSocket connection + socket = new WebSocket(wsUrl) + + // Handle connection opening + socket.onopen = () => { + setConnectionStatus("Connected") + console.log("WebSocket connection established") + } + + // Handle incoming messages + socket.onmessage = (event) => { + console.log("WebSocket message received") + try { + const data = JSON.parse(event.data) as Message + + // Check if this is a session info message + if (data.key.startsWith("session/info/")) { + const infoContent = JSON.parse(data.content) as SessionInfo + setSessionInfo(infoContent) + console.log("Session info updated:", infoContent) + return + } + + // Check if it's a system message + const msgContent = JSON.parse(data.content) as UIMessage + if (msgContent.role === "system") { + setSystemMessage(data) + console.log("System message updated:", data) + return + } + + // Non-system messages + setMessages((prev) => { + // Check if message with this key already exists + const existingIndex = prev.findIndex((msg) => msg.key === data.key) + if (existingIndex >= 0) { + // Update existing message + const updated = [...prev] + updated[existingIndex] = data + return updated + } else { + // Add new message + return [...prev, data] + } + }) + } catch (error) { + console.error("Error parsing WebSocket message:", error) + } + } + + // Handle errors + socket.onerror = (error) => { + console.error("WebSocket error:", error) + setConnectionStatus("Error: Connection failed") + } + + // Handle connection close and reconnection + socket.onclose = (event) => { + console.log(`WebSocket closed: ${event.code} ${event.reason}`) + setConnectionStatus("Disconnected, reconnecting...") + + // Try to reconnect after 2 seconds + clearTimeout(reconnectTimer) + reconnectTimer = window.setTimeout( + setupWebSocket, + 2000, + ) as unknown as number + } + } + + // Initial connection + setupWebSocket() + + // Clean up on component unmount + onCleanup(() => { + console.log("Cleaning up WebSocket connection") + if (socket) { + socket.close() + } + clearTimeout(reconnectTimer) + }) + }) + + return ( +
+

Share: {shareId}

+ +
+

WebSocket Connection

+

+ Status: {connectionStatus()} +

+ +

Live Updates

+ + +
+

Session Information

+
+
+ Input Tokens:{" "} + {sessionInfo()?.tokens?.input || 0} +
+
+ Output Tokens:{" "} + {sessionInfo()?.tokens?.output || 0} +
+
+ Reasoning Tokens:{" "} + {sessionInfo()?.tokens?.reasoning || 0} +
+
+
+
+ + {/* Display system message as context in the Session Information block */} + +
+

Context

+ {(() => { + try { + const parsed = JSON.parse( + systemMessage()?.content || "", + ) as UIMessage + if ( + parsed.parts && + parsed.parts.length > 0 && + parsed.parts[0].type === "text" + ) { + const text = parsed.parts[0].text || "" + const lines = text.split("\n") + const visibleLines = expandedSystemMessage() + ? lines + : lines.slice(0, 5) + const hasMoreLines = lines.length > 5 + + return ( + <> +
+ {/* Create a modified version of the text part for the system message */} + {(() => { + // Create a modified part with truncated text + const modifiedPart = { + ...parsed.parts[0], + text: visibleLines.join("\n"), + } + + return ( + <> +
{modifiedPart.text}
+ {hasMoreLines && !expandedSystemMessage() && ( +
+ {lines.length - 5} more lines... +
+ )} + + ) + })()} +
+ {hasMoreLines && ( + + )} + + ) + } + } catch (e) { + return
Error parsing system message
+ } + + return null + })()} +
+
+ +
+ 0} + fallback={

Waiting for messages...

} + > +
    + + {(msg) => ( +
  • +
    + Key: {msg.key} +
    + + {(() => { + try { + const parsed = JSON.parse(msg.content) as UIMessage + const createdTime = parsed.metadata?.time?.created + ? new Date( + parsed.metadata.time.created, + ).toLocaleString() + : "Unknown time" + + return ( + <> +
    + Full Content: +
    +                                {JSON.stringify(parsed, null, 2)}
    +                              
    +
    + + {parsed.parts && parsed.parts.length > 0 && ( +
    +
    + + Role: {parsed.role || "Unknown"} + + + {createdTime} + +
    + +
    + part.type !== "step-start", + )} + > + {(part) => { + if (part.type === "text") { + //{ + // "type": "text", + // "text": "Hello! How can I help you today?" + //} + return ( +
    +                                            [{part.type}] {part.text}{" "}
    +                                          
    + ) + } + if (part.type === "reasoning") { + //{ + // "type": "reasoning", + // "text": "The user asked for a weather forecast. I should call the 'getWeather' tool with the location 'San Francisco'.", + // "providerMetadata": { "step_id": "reason_step_1" } + //} + return ( +
    +                                            [{part.type}] {part.text}
    +                                          
    + ) + } + if (part.type === "tool-invocation") { + return ( +
    +
    + +
    +                                                  [{part.type}]
    +                                                
    {" "} + Tool:{" "} + + {part.toolInvocation.toolName} + +
    + {parsed.metadata?.tool?.[ + part.toolInvocation.toolCallId + ]?.time?.start && + parsed.metadata?.tool?.[ + part.toolInvocation.toolCallId + ]?.time?.end && ( + + {( + (new Date( + parsed.metadata?.tool?.[ + part.toolInvocation.toolCallId + ].time.end, + ) - + new Date( + parsed.metadata?.tool?.[ + part.toolInvocation.toolCallId + ].time.start, + )) / + 1000 + ).toFixed(2)} + s + + )} +
    + {(() => { + if ( + part.toolInvocation.state === + "partial-call" + ) { + //{ + // "type": "tool-invocation", + // "toolInvocation": { + // "state": "partial-call", + // "toolCallId": "tool_abc123", + // "toolName": "searchWeb", + // "argsTextDelta": "{\"query\":\"latest AI news" + // } + //} + return ( + <> +
    +                                                      {
    +                                                        part.toolInvocation
    +                                                          .argsTextDelta
    +                                                      }
    +                                                    
    + ... + + ) + } + if ( + part.toolInvocation.state === + "call" + ) { + //{ + // "type": "tool-invocation", + // "toolInvocation": { + // "state": "call", + // "toolCallId": "tool_abc123", + // "toolName": "searchWeb", + // "args": { "query": "latest AI news", "count": 3 } + // } + //} + return ( +
    +                                                    {JSON.stringify(
    +                                                      part.toolInvocation.args,
    +                                                      null,
    +                                                      2,
    +                                                    )}
    +                                                  
    + ) + } + if ( + part.toolInvocation.state === + "result" + ) { + //{ + // "type": "tool-invocation", + // "toolInvocation": { + // "state": "result", + // "toolCallId": "tool_abc123", + // "toolName": "searchWeb", + // "args": { "query": "latest AI news", "count": 3 }, + // "result": [ + // { "title": "AI SDK v5 Announced", "url": "..." }, + // { "title": "New LLM Achieves SOTA", "url": "..." } + // ] + // } + //} + return ( + <> +
    +                                                      {JSON.stringify(
    +                                                        part.toolInvocation
    +                                                          .args,
    +                                                        null,
    +                                                        2,
    +                                                      )}
    +                                                    
    +
    +                                                      {JSON.stringify(
    +                                                        part.toolInvocation
    +                                                          .result,
    +                                                        null,
    +                                                        2,
    +                                                      )}
    +                                                    
    + + ) + } + if ( + part.toolInvocation.state === + "error" + ) { + //{ + // "type": "tool-invocation", + // "toolInvocation": { + // "state": "error", + // "toolCallId": "tool_abc123", + // "toolName": "searchWeb", + // "args": { "query": "latest AI news", "count": 3 }, + // "errorMessage": "API limit exceeded for searchWeb tool." + // } + //} + return ( + <> +
    +                                                      {JSON.stringify(
    +                                                        part.toolInvocation
    +                                                          .args,
    +                                                        null,
    +                                                        2,
    +                                                      )}
    +                                                    
    +
    +                                                      {
    +                                                        part.toolInvocation
    +                                                          .errorMessage
    +                                                      }
    +                                                    
    + + ) + } + })()} +
    + ) + } + if (part.type === "source") { + //{ + // "type": "source", + // "source": { + // "sourceType": "url", + // "id": "doc_xyz789", + // "url": "https://example.com/research-paper.pdf", + // "title": "Groundbreaking AI Research Paper" + // } + //} + return ( +
    +
    + +
    [{part.type}]
    +
    + + Source:{" "} + {part.source.title || + part.source.id} + +
    + {part.source.url && ( + + )} + {part.source.sourceType && ( +
    + Type: {part.source.sourceType} +
    + )} +
    + ) + } + if (part.type === "file") { + //{ + // "type": "file", + // "mediaType": "image/jpeg", + // "filename": "cat_photo.jpg", + // "url": "https://example-files.com/cats/cat_photo.jpg" + //} + const isImage = + part.mediaType?.startsWith("image/") + + return ( +
    +
    + +
    [{part.type}]
    +
    + File: {part.filename} + {part.mediaType} +
    + + {isImage && part.url ? ( +
    + { +
    + ) : ( +
    + {part.url ? ( + + Download: {part.filename} + + ) : ( +
    + File attachment (no URL + available) +
    + )} +
    + )} +
    + ) + } + return null + }} +
    +
    +
    + )} + + ) + } catch (e) { + return ( +
    + Content: +
    +                              {msg.content}
    +                            
    +
    + ) + } + })()} +
  • + )} +
    +
+
+
+
+
+ ) +} diff --git a/app/packages/web/src/content.config.ts b/app/packages/web/src/content.config.ts new file mode 100644 index 000000000..d9ee8c9d1 --- /dev/null +++ b/app/packages/web/src/content.config.ts @@ -0,0 +1,7 @@ +import { defineCollection } from 'astro:content'; +import { docsLoader } from '@astrojs/starlight/loaders'; +import { docsSchema } from '@astrojs/starlight/schema'; + +export const collections = { + docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), +}; diff --git a/app/packages/web/src/content/docs/docs/cli.mdx b/app/packages/web/src/content/docs/docs/cli.mdx new file mode 100644 index 000000000..44a56e1fb --- /dev/null +++ b/app/packages/web/src/content/docs/docs/cli.mdx @@ -0,0 +1,89 @@ +--- +title: CLI +--- + +Once installed you can run the OpenCode CLI. + +```bash +opencode +``` + +Or pass in flags. For example, to start with debug logging: + +```bash +opencode -d +``` + +Or start with a specific working directory. + +```bash +opencode -c /path/to/project +``` + +## Flags + +The OpenCode CLI takes the following flags. + +| Flag | Short | Description | +| -- | -- | -- | +| `--help` | `-h` | Display help | +| `--debug` | `-d` | Enable debug mode | +| `--cwd` | `-c` | Set current working directory | +| `--prompt` | `-p` | Run a single prompt in non-interactive mode | +| `--output-format` | `-f` | Output format for non-interactive mode, `text` or `json` | +| `--quiet` | `-q` | Hide spinner in non-interactive mode | +| `--verbose` | | Display logs to stderr in non-interactive mode | +| `--allowedTools` | | Restrict the agent to only use specified tools | +| `--excludedTools` | | Prevent the agent from using specified tools | + +## Non-interactive + +By default, OpenCode runs in interactive mode. + +But you can also run OpenCode in non-interactive mode by passing a prompt directly as a command-line argument. This is useful for scripting, automation, or when you want a quick answer without launching the full TUI. + +For example, to run a single prompt use the `-p` flag. + +```bash "-p" +opencode -p "Explain the use of context in Go" +``` + +If you want to run without showing the spinner, use `-q`. + +```bash "-q" +opencode -p "Explain the use of context in Go" -q +``` + +In this mode, OpenCode will process your prompt, print the result to standard output, and then exit. All **permissions are auto-approved** for the session. + +#### Tool restrictions + +You can control which tools the AI assistant has access to in non-interactive mode. + +- `--allowedTools` + + A comma-separated list of tools that the agent is allowed to use. Only these tools will be available. + + ```bash "--allowedTools" + opencode -p "Explain the use of context in Go" --allowedTools=view,ls,glob + ``` + +- `--excludedTools` + + Comma-separated list of tools that the agent is not allowed to use. All other tools will be available. + + ```bash "--excludedTools" + opencode -p "Explain the use of context in Go" --excludedTools=bash,edit + ``` + +These flags are mutually exclusive. So you can either use `--allowedTools` or `--excludedTools`, but not both. + +#### Output formats + +In non-interactive mode, you can also set the CLI to return as JSON using `-f`. + +```bash "-f json" +opencode -p "Explain the use of context in Go" -f json +``` + +By default, this is set to `text`, to return plain text. diff --git a/app/packages/web/src/content/docs/docs/config.mdx b/app/packages/web/src/content/docs/docs/config.mdx new file mode 100644 index 000000000..288f194c5 --- /dev/null +++ b/app/packages/web/src/content/docs/docs/config.mdx @@ -0,0 +1,88 @@ +--- +title: Config +--- + +You can configure OpenCode using the OpenCode config. It can be places in: + +- `$HOME/.opencode.json` +- `$XDG_CONFIG_HOME/opencode/.opencode.json` + +Or in the current directory, `./.opencode.json`. + +## OpenCode config + +The config file has the following structure. + +```json title=".opencode.json" +{ + "data": { + "directory": ".opencode" + }, + "providers": { + "openai": { + "apiKey": "your-api-key", + "disabled": false + }, + "anthropic": { + "apiKey": "your-api-key", + "disabled": false + }, + "groq": { + "apiKey": "your-api-key", + "disabled": false + }, + "openrouter": { + "apiKey": "your-api-key", + "disabled": false + } + }, + "agents": { + "primary": { + "model": "claude-3.7-sonnet", + "maxTokens": 5000 + }, + "task": { + "model": "claude-3.7-sonnet", + "maxTokens": 5000 + }, + "title": { + "model": "claude-3.7-sonnet", + "maxTokens": 80 + } + }, + "mcpServers": { + "example": { + "type": "stdio", + "command": "path/to/mcp-server", + "env": [], + "args": [] + } + }, + "lsp": { + "go": { + "disabled": false, + "command": "gopls" + } + }, + "debug": false, + "debugLSP": false +} +``` + +## Environment variables + +For the providers, you can also specify the keys using environment variables. + +| Environment Variable | Models | +| -------------------------- | ----------- | +| `ANTHROPIC_API_KEY` | Claude | +| `OPENAI_API_KEY` | OpenAI | +| `GEMINI_API_KEY` | Google Gemini | +| `GROQ_API_KEY` | Groq | +| `AWS_ACCESS_KEY_ID` | Amazon Bedrock | +| `AWS_SECRET_ACCESS_KEY` | Amazon Bedrock | +| `AWS_REGION` | Amazon Bedrock | +| `AZURE_OPENAI_ENDPOINT` | Azure OpenAI | +| `AZURE_OPENAI_API_KEY` | Azure OpenAI, optional when using Entra ID | +| `AZURE_OPENAI_API_VERSION` | Azure OpenAI | + diff --git a/app/packages/web/src/content/docs/docs/index.mdx b/app/packages/web/src/content/docs/docs/index.mdx new file mode 100644 index 000000000..e6f71be19 --- /dev/null +++ b/app/packages/web/src/content/docs/docs/index.mdx @@ -0,0 +1,58 @@ +--- +title: Intro +--- + +OpenCode is an AI coding agent built natively for the terminal. It features: + +- Native TUI for a smoother, snappier experience +- Uses LSPs to help the LLM make fewer mistakes +- Opening multiple conversations with the same project +- Use of any model through the AI SDK +- Tracks and visualizes all the file changes +- Editing longer messages with Vim + +## Installation + +```bash +npm i -g opencode +``` + +If you don't have NPM installed, you can also install the OpenCode binary through the following. + +#### Using the install script + +```bash +curl -fsSL https://opencode.ai/install | bash +``` + +Or install a specific version. + +```bash +curl -fsSL https://opencode.ai/install | VERSION=0.1.0 bash +``` + +#### Using Homebrew on macOS and Linux + +```bash +brew install sst/tap/opencode +``` + +#### Using AUR in Arch Linux + +With yay. + +```bash +yay -S opencode-bin +``` + +Or with paru. + +```bash +paru -S opencode-bin +``` + +#### Using Go + +```bash +go install github.com/sst/opencode@latest +``` diff --git a/app/packages/web/src/content/docs/docs/lsp-servers.mdx b/app/packages/web/src/content/docs/docs/lsp-servers.mdx new file mode 100644 index 000000000..cd259dea7 --- /dev/null +++ b/app/packages/web/src/content/docs/docs/lsp-servers.mdx @@ -0,0 +1,34 @@ +--- +title: LSP servers +--- + +OpenCode integrates with _Language Server Protocol_, or LSP to improve how the LLM interacts with your codebase. + +LSP servers for different languages give the LLM: + +- **Diagnostics**: These include things like errors and lint warnings. So the LLM can generate code that has fewer mistakes without having to run the code. +- **Quick actions**: The LSP can allow the LLM to better navigate the codebase through features like _go-to-definition_ and _find references_. + +## Auto-detection + +By default, OpenCode will **automatically detect** the languages used in your project and add the right LSP servers. + +## Manual configuration + +You can also manually configure LSP servers by adding them under the `lsp` section in your OpenCode config. + +```json title=".opencode.json" +{ + "lsp": { + "go": { + "disabled": false, + "command": "gopls" + }, + "typescript": { + "disabled": false, + "command": "typescript-language-server", + "args": ["--stdio"] + } + } +} +``` diff --git a/app/packages/web/src/content/docs/docs/mcp-servers.mdx b/app/packages/web/src/content/docs/docs/mcp-servers.mdx new file mode 100644 index 000000000..28c6d2ab2 --- /dev/null +++ b/app/packages/web/src/content/docs/docs/mcp-servers.mdx @@ -0,0 +1,51 @@ +--- +title: MCP servers +--- + +You can add external tools to OpenCode using the _Model Context Protocol_, or MCP. OpenCode supports both: + +- Local servers that use standard input/output, `stdio` +- Remote servers that use server-sent events `sse` + +## Add MCP servers + +You can define MCP servers in your OpenCode config under the `mcpServers` section: + +### Local + +To add a local or `stdio` MCP server. + +```json title=".opencode.json" {4} +{ + "mcpServers": { + "local-example": { + "type": "stdio", + "command": "path/to/mcp-server", + "env": [], + "args": [] + } + } +} +``` + +### Remote + +To add a remote or `sse` MCP server. + +```json title=".opencode.json" {4} +{ + "mcpServers": { + "remote-example": { + "type": "sse", + "url": "https://example.com/mcp", + "headers": { + "Authorization": "Bearer token" + } + } + } +} +``` + +## Usage + +Once added, MCP tools are automatically available to the LLM alongside built-in tools. They follow the same permission model; requiring user approval before execution. diff --git a/app/packages/web/src/content/docs/docs/models.mdx b/app/packages/web/src/content/docs/docs/models.mdx new file mode 100644 index 000000000..c40216695 --- /dev/null +++ b/app/packages/web/src/content/docs/docs/models.mdx @@ -0,0 +1,34 @@ +--- +title: Models +--- + +OpenCode uses the [AI SDK](https://ai-sdk.dev/) to have the support for **all the AI models**. + +Start by setting the [keys for the providers](/docs/config) you want to use in your OpenCode config. + +## Model select + +You can now select the model you want from the menu by hitting `Ctrl+O`. + +## Multiple models + +You can also use specific models for specific tasks. For example, you can use a smaller model to generate the title of the conversation or to run a sub task. + +```json title=".opencode.json" +{ + "agents": { + "primary": { + "model": "gpt-4", + "maxTokens": 5000 + }, + "task": { + "model": "gpt-3.5-turbo", + "maxTokens": 5000 + }, + "title": { + "model": "gpt-3.5-turbo", + "maxTokens": 80 + } + } +} +``` diff --git a/app/packages/web/src/content/docs/docs/shortcuts.mdx b/app/packages/web/src/content/docs/docs/shortcuts.mdx new file mode 100644 index 000000000..dd866e0f3 --- /dev/null +++ b/app/packages/web/src/content/docs/docs/shortcuts.mdx @@ -0,0 +1,68 @@ +--- +title: Keyboard shortcuts +sidebar: + label: Shortcuts +--- + +Below are a list of keyboard shortcuts that OpenCode supports. + +## Global + +| Shortcut | Action | +| -------- | ------------------------------------------------------- | +| `Ctrl+C` | Quit application | +| `Ctrl+?` | Toggle help dialog | +| `?` | Toggle help dialog (when not in editing mode) | +| `Ctrl+L` | View logs | +| `Ctrl+A` | Switch session | +| `Ctrl+K` | Command dialog | +| `Ctrl+O` | Toggle model selection dialog | +| `Esc` | Close current overlay/dialog or return to previous mode | + +## Chat pane + +| Shortcut | Action | +| -------- | --------------------------------------- | +| `Ctrl+N` | Create new session | +| `Ctrl+X` | Cancel current operation/generation | +| `i` | Focus editor (when not in writing mode) | +| `Esc` | Exit writing mode and focus messages | + +## Editor view + +| Shortcut | Action | +| ------------------- | ----------------------------------------- | +| `Ctrl+S` | Send message (when editor is focused) | +| `Enter` or `Ctrl+S` | Send message (when editor is not focused) | +| `Ctrl+E` | Open external editor | +| `Esc` | Blur editor and focus messages | + +## Session dialog + +| Shortcut | Action | +| ---------- | ---------------- | +| `↑` or `k` | Previous session | +| `↓` or `j` | Next session | +| `Enter` | Select session | +| `Esc` | Close dialog | + +## Model dialog + +| Shortcut | Action | +| ---------- | ----------------- | +| `↑` or `k` | Move up | +| `↓` or `j` | Move down | +| `←` or `h` | Previous provider | +| `β†’` or `l` | Next provider | +| `Esc` | Close dialog | + +## Permission dialog + +| Shortcut | Action | +| ----------------------- | ---------------------------- | +| `←` or `left` | Switch options left | +| `β†’` or `right` or `tab` | Switch options right | +| `Enter` or `space` | Confirm selection | +| `a` | Allow permission | +| `A` | Allow permission for session | +| `d` | Deny permission | diff --git a/app/packages/web/src/content/docs/docs/themes.mdx b/app/packages/web/src/content/docs/docs/themes.mdx new file mode 100644 index 000000000..e691a22e7 --- /dev/null +++ b/app/packages/web/src/content/docs/docs/themes.mdx @@ -0,0 +1,75 @@ +--- +title: Themes +--- + +OpenCode supports most common terminal themes and you can create your own custom theme. + +## Built-in themes + +The following predefined themes are available: + +- `opencode` +- `catppuccin` +- `dracula` +- `flexoki` +- `gruvbox` +- `monokai` +- `onedark` +- `tokyonight` +- `tron` +- `custom` + +Where `opencode` is the default theme and `custom` let's you define your own theme. + +## Setting a theme + +You can set your theme in your OpenCode config. + +```json title=".opencode.json" +{ + "tui": { + "theme": "monokai" + } +} +``` + +## Create a theme + +You can create your own custom theme by setting the `theme: custom` and providing color definitions through the `customTheme`. + +```json title=".opencode.json" +{ + "tui": { + "theme": "custom", + "customTheme": { + "primary": "#ffcc00", + "secondary": "#00ccff", + "accent": { "dark": "#aa00ff", "light": "#ddccff" }, + "error": "#ff0000" + } + } +} +``` + +#### Color keys + +You can define any of the following color keys in your `customTheme`. + +| Type | Color keys | +| --- | --- | +| Base colors | `primary`, `secondary`, `accent` | +| Status colors | `error`, `warning`, `success`, `info` | +| Text colors | `text`, `textMuted`, `textEmphasized` | +| Background colors | `background`, `backgroundSecondary`, `backgroundDarker` | +| Border colors | `borderNormal`, `borderFocused`, `borderDim` | +| Diff view colors | `diffAdded`, `diffRemoved`, `diffContext`, etc. | + +You don't need to define all the color keys. Any undefined colors will fall back to the default `opencode` theme colors. + +#### Color definitions + +Color keys can take: + +1. **Hex string**: A single hex color string, like `"#aabbcc"`, that'll be used for both light and dark terminal backgrounds. + +2. **Light and dark colors**: An object with `dark` and `light` hex colors that'll be set based on the terminal's background. diff --git a/app/packages/web/src/content/docs/index.mdx b/app/packages/web/src/content/docs/index.mdx new file mode 100644 index 000000000..176520ec5 --- /dev/null +++ b/app/packages/web/src/content/docs/index.mdx @@ -0,0 +1,12 @@ +--- +title: OpenCode +description: The AI coding agent built for the terminal. +template: splash +hero: + title: The AI coding agent built for the terminal. + tagline: The AI coding agent built for the terminal. + image: + dark: ../../assets/logo-dark.svg + light: ../../assets/logo-light.svg + alt: OpenCode logo +--- diff --git a/app/packages/web/src/index.css b/app/packages/web/src/index.css deleted file mode 100644 index 85e778f43..000000000 --- a/app/packages/web/src/index.css +++ /dev/null @@ -1,13 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', - 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', - 'Helvetica Neue', sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} diff --git a/app/packages/web/src/index.tsx b/app/packages/web/src/index.tsx deleted file mode 100644 index 823bf0fb8..000000000 --- a/app/packages/web/src/index.tsx +++ /dev/null @@ -1,24 +0,0 @@ -/* @refresh reload */ -import { render } from "solid-js/web" -import { Router, Route } from "@solidjs/router" - -import "./index.css" -import App from "./App" - -const root = document.getElementById("root") - -if (import.meta.env.DEV && !(root instanceof HTMLElement)) { - throw new Error( - "Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?", - ) -} - -render( - () => ( - - - - - ), - root!, -) diff --git a/app/packages/web/src/logo.svg b/app/packages/web/src/logo.svg deleted file mode 100644 index 025aa303c..000000000 --- a/app/packages/web/src/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/packages/web/src/pages/share/index.astro b/app/packages/web/src/pages/share/index.astro new file mode 100644 index 000000000..f8364b616 --- /dev/null +++ b/app/packages/web/src/pages/share/index.astro @@ -0,0 +1,39 @@ +--- +import config from "virtual:starlight/user-config"; + +import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; +import Share from "../../components/Share.tsx"; + +// export const prerender = false; + +const { id } = Astro.params; +console.log(Astro.url); +console.log(import.meta.env.VITE_API_URL); + +//export function getStaticPaths() { +// return [ +// { params: { slug: undefined }} +// ]; +//} +--- + + + + + + diff --git a/app/packages/web/src/sst-env.d.ts b/app/packages/web/src/sst-env.d.ts deleted file mode 100644 index 4addc8ef9..000000000 --- a/app/packages/web/src/sst-env.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* This file is auto-generated by SST. Do not edit. */ -/* tslint:disable */ -/* eslint-disable */ -/// -interface ImportMetaEnv { - readonly VITE_API_URL: string -} -interface ImportMeta { - readonly env: ImportMetaEnv -} \ No newline at end of file diff --git a/app/packages/web/sst-env.d.ts b/app/packages/web/sst-env.d.ts deleted file mode 100644 index b6a7e9066..000000000 --- a/app/packages/web/sst-env.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* This file is auto-generated by SST. Do not edit. */ -/* tslint:disable */ -/* eslint-disable */ -/* deno-fmt-ignore-file */ - -/// - -import "sst" -export {} \ No newline at end of file diff --git a/app/packages/web/tsconfig.json b/app/packages/web/tsconfig.json index 249b2732a..973603872 100644 --- a/app/packages/web/tsconfig.json +++ b/app/packages/web/tsconfig.json @@ -1,15 +1,9 @@ { + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "**/*"], + "exclude": ["dist"], "compilerOptions": { - "strict": true, - "target": "ESNext", - "module": "ESNext", - "moduleResolution": "node", - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, "jsx": "preserve", - "jsxImportSource": "solid-js", - "types": ["vite/client"], - "noEmit": true, - "isolatedModules": true + "jsxImportSource": "solid-js" } } diff --git a/app/packages/web/vite.config.ts b/app/packages/web/vite.config.ts deleted file mode 100644 index 9ff59a172..000000000 --- a/app/packages/web/vite.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { defineConfig } from 'vite'; -import solidPlugin from 'vite-plugin-solid'; - -export default defineConfig({ - plugins: [solidPlugin()], - server: { - port: 3000, - }, - build: { - target: 'esnext', - }, -}); -- cgit v1.2.3