diff --git a/.github/workflows/opencode.yml b/.github/workflows/opencode.yml index cbe35f615..08014cf2c 100644 --- a/.github/workflows/opencode.yml +++ b/.github/workflows/opencode.yml @@ -8,22 +8,20 @@ jobs: opencode: if: | contains(github.event.comment.body, ' /oc') || - startsWith(github.event.comment.body, '/oc') || - contains(github.event.comment.body, ' /opencode') || - startsWith(github.event.comment.body, '/opencode') + contains(github.event.comment.body, ' /opencode') runs-on: ubuntu-latest permissions: - contents: read id-token: write + contents: read + pull-requests: read + issues: read steps: - name: Checkout repository uses: actions/checkout@v4 - with: - fetch-depth: 1 - name: Run opencode uses: sst/opencode/github@latest env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} with: - model: anthropic/claude-sonnet-4-20250514 + model: opencode/sonic \ No newline at end of file diff --git a/.gitignore b/.gitignore index 33e3deb81..025b3707b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .DS_Store node_modules +.worktrees .sst .env .idea diff --git a/README.md b/README.md index 1e16bde8c..b844c497e 100644 --- a/README.md +++ b/README.md @@ -107,4 +107,4 @@ The other confusingly named repo has no relation to this one. You can [read the --- -**Join our community** [Discord](https://discord.gg/opencode) | [YouTube](https://www.youtube.com/c/sst-dev) | [X.com](https://x.com/SST_dev) +**Join our community** [Discord](https://discord.gg/opencode) | [YouTube](https://www.youtube.com/c/sst-dev) | [X.com](https://x.com/anomaly_inv) diff --git a/STATS.md b/STATS.md index f5833afcb..62990eb5d 100644 --- a/STATS.md +++ b/STATS.md @@ -57,3 +57,10 @@ | 2025-08-21 | 220,465 (+5,968) | 194,784 (+3,303) | 415,249 (+9,271) | | 2025-08-22 | 225,899 (+5,434) | 197,204 (+2,420) | 423,103 (+7,854) | | 2025-08-23 | 229,005 (+3,106) | 199,238 (+2,034) | 428,243 (+5,140) | +| 2025-08-24 | 232,098 (+3,093) | 201,157 (+1,919) | 433,255 (+5,012) | +| 2025-08-25 | 236,607 (+4,509) | 202,650 (+1,493) | 439,257 (+6,002) | +| 2025-08-26 | 242,783 (+6,176) | 205,242 (+2,592) | 448,025 (+8,768) | +| 2025-08-27 | 248,409 (+5,626) | 205,242 (+0) | 453,651 (+5,626) | +| 2025-08-28 | 252,796 (+4,387) | 205,242 (+0) | 458,038 (+4,387) | +| 2025-08-29 | 256,045 (+3,249) | 211,075 (+5,833) | 467,120 (+9,082) | +| 2025-08-30 | 258,863 (+2,818) | 212,397 (+1,322) | 471,260 (+4,140) | diff --git a/bun.lock b/bun.lock index 2cd807f31..dc231b635 100644 --- a/bun.lock +++ b/bun.lock @@ -8,7 +8,7 @@ }, "devDependencies": { "prettier": "3.5.3", - "sst": "3.17.8", + "sst": "3.17.12", }, }, "cloud/app": { @@ -20,15 +20,16 @@ "@solidjs/meta": "^0.29.4", "@solidjs/router": "^0.15.0", "@solidjs/start": "^1.1.0", - "solid-js": "^1.9.5", + "solid-js": "catalog:", "vinxi": "^0.5.7", }, }, "cloud/core": { "name": "@opencode/cloud-core", - "version": "0.5.15", + "version": "0.5.28", "dependencies": { "@aws-sdk/client-sts": "3.782.0", + "@opencode/cloud-resource": "workspace:*", "drizzle-orm": "0.41.0", "postgres": "3.4.7", "stripe": "18.0.0", @@ -40,7 +41,7 @@ }, "cloud/function": { "name": "@opencode/cloud-function", - "version": "0.5.15", + "version": "0.5.28", "dependencies": { "@ai-sdk/anthropic": "2.0.0", "@ai-sdk/openai": "2.0.2", @@ -58,28 +59,15 @@ "typescript": "catalog:", }, }, - "cloud/web": { - "name": "@opencode/cloud-web", - "version": "0.5.15", + "cloud/resource": { + "name": "@opencode/cloud-resource", "dependencies": { - "@kobalte/core": "0.13.9", - "@openauthjs/solid": "0.0.0-20250322224806", - "@solid-primitives/storage": "4.3.1", - "@solidjs/meta": "0.29.4", - "@solidjs/router": "0.15.3", - "solid-js": "1.9.5", - "solid-list": "0.3.0", - }, - "devDependencies": { - "typescript": "catalog:", - "vite": "6.2.2", - "vite-plugin-pages": "0.32.5", - "vite-plugin-solid": "2.11.6", + "@cloudflare/workers-types": "^4.20250830.0", }, }, "packages/function": { "name": "@opencode/function", - "version": "0.5.15", + "version": "0.5.28", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "22.0.0", @@ -94,7 +82,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "0.5.15", + "version": "0.5.28", "bin": { "opencode": "./bin/opencode", }, @@ -113,7 +101,7 @@ "gray-matter": "4.0.3", "hono": "catalog:", "hono-openapi": "0.4.8", - "isomorphic-git": "1.32.1", + "ignore": "7.0.5", "jsonc-parser": "3.3.1", "minimatch": "10.0.3", "open": "10.1.2", @@ -144,21 +132,20 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "0.5.15", + "version": "0.5.28", "dependencies": { "@opencode-ai/sdk": "workspace:*", }, "devDependencies": { - "@hey-api/openapi-ts": "0.81.0", "@tsconfig/node22": "catalog:", "typescript": "catalog:", }, }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "0.5.15", + "version": "0.5.28", "dependencies": { - "@hey-api/openapi-ts": "0.80.1", + "@hey-api/openapi-ts": "0.81.0", }, "devDependencies": { "@hey-api/openapi-ts": "0.80.1", @@ -168,7 +155,7 @@ }, "packages/web": { "name": "@opencode/web", - "version": "0.5.15", + "version": "0.5.28", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", @@ -189,7 +176,7 @@ "remeda": "2.26.0", "sharp": "0.32.5", "shiki": "3.4.2", - "solid-js": "1.9.7", + "solid-js": "catalog:", "toolbeam-docs-theme": "0.4.6", }, "devDependencies": { @@ -217,6 +204,7 @@ "ai": "5.0.8", "hono": "4.7.10", "remeda": "2.26.0", + "solid-js": "1.9.9", "typescript": "5.8.2", "zod": "3.25.76", }, @@ -247,11 +235,11 @@ "@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.1", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.2.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.1", "remark-smartypants": "^3.0.2", "shiki": "^3.0.0", "smol-toml": "^1.3.1", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-c5F5gGrkczUaTVgmMW9g1YMJGzOtRvjjhw6IfGuxarM6ct09MpwysP10US729dy07gg8y+ofVifezvP3BNsWZg=="], - "@astrojs/mdx": ["@astrojs/mdx@4.3.1", "", { "dependencies": { "@astrojs/markdown-remark": "6.3.3", "@mdx-js/mdx": "^3.1.0", "acorn": "^8.14.1", "es-module-lexer": "^1.6.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "kleur": "^4.1.5", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.4", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-0ynzkFd5p2IFDLPAfAcGizg44WyS0qUr43nP2vQkvrPlpoPEMeeoi1xWiWsVqQNaZ0FOmNqfUviUn52nm9mLag=="], + "@astrojs/mdx": ["@astrojs/mdx@4.3.4", "", { "dependencies": { "@astrojs/markdown-remark": "6.3.6", "@mdx-js/mdx": "^3.1.0", "acorn": "^8.14.1", "es-module-lexer": "^1.6.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "kleur": "^4.1.5", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.4", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-Ew3iP+6zuzzJWNEH5Qr1iknrue1heEfgmfuMpuwLaSwqlUiJQ0NDb2oxKosgWU1ROYmVf1H4KCmS6QdMWKyFjw=="], "@astrojs/prism": ["@astrojs/prism@3.2.0", "", { "dependencies": { "prismjs": "^1.29.0" } }, "sha512-GilTHKGCW6HMq7y3BUv9Ac7GMe/MO9gi9GW62GzKtth0SwukCu/qp2wLiGpEujhY+VVhaG9v7kv/5vFzvf4NYw=="], - "@astrojs/sitemap": ["@astrojs/sitemap@3.4.2", "", { "dependencies": { "sitemap": "^8.0.0", "stream-replace-string": "^2.0.0", "zod": "^3.24.4" } }, "sha512-wfN2dZzdkto6yaMtOFa/J9gc60YE3wl3rgSBoNJ+MU3lJVUMsDY9xf9uAVi8Mp/zEQKFDSJlQzBvqQUpw0Hf6g=="], + "@astrojs/sitemap": ["@astrojs/sitemap@3.5.1", "", { "dependencies": { "sitemap": "^8.0.0", "stream-replace-string": "^2.0.0", "zod": "^3.24.4" } }, "sha512-uX5z52GLtQTgOe8r3jeGmFRYrFe52mdpLYJzqjvL1cdy5Kg3MLOZEvaZ/OCH0fSq0t7e50uJQ6oBMZG0ffszBg=="], "@astrojs/solid-js": ["@astrojs/solid-js@5.1.0", "", { "dependencies": { "vite": "^6.3.5", "vite-plugin-solid": "^2.11.6" }, "peerDependencies": { "solid-devtools": "^0.30.1", "solid-js": "^1.8.5" }, "optionalPeers": ["solid-devtools"] }, "sha512-VmPHOU9k7m6HHCT2Y1mNzifilUnttlowBM36frGcfj5wERJE9Ci0QtWJbzdf6AlcoIirb7xVw+ByupU011Di9w=="], @@ -309,7 +297,7 @@ "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.782.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/types": "^4.2.0", "@smithy/util-endpoints": "^3.0.2", "tslib": "^2.6.2" } }, "sha512-/RJOAO7o7HI6lEa4ASbFFLHGU9iPK876BhsVfnl54MvApPVYWQ9sHO0anOUim2S5lQTwd/6ghuH3rFYSq/+rdw=="], - "@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.804.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-zVoRfpmBVPodYlnMjgVjfGoEZagyRF5IPn3Uo6ZvOZp24chnW/FRstH7ESDHDDRga4z3V+ElUQHKpFDXWyBW5A=="], + "@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.873.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-xcVhZF6svjM5Rj89T1WzkjQmrTF6dpR2UvIHPMTnSZoNe6CixejPZ6f0JJ2kAhO8H+dUHwNBlsUgOTIKiK/Syg=="], "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/types": "^4.2.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-txw2wkiJmZKVdDbscK7VBK+u+TJnRtlUjRTLei+elZg2ADhpQxfVAQl436FUeIv6AhB/oRHW6/K/EAGXUSWi0A=="], @@ -319,9 +307,9 @@ "@babel/compat-data": ["@babel/compat-data@7.28.0", "", {}, "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw=="], - "@babel/core": ["@babel/core@7.28.0", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.6", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ=="], + "@babel/core": ["@babel/core@7.28.3", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.3", "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ=="], - "@babel/generator": ["@babel/generator@7.28.0", "", { "dependencies": { "@babel/parser": "^7.28.0", "@babel/types": "^7.28.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg=="], + "@babel/generator": ["@babel/generator@7.28.3", "", { "dependencies": { "@babel/parser": "^7.28.3", "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw=="], "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="], @@ -335,7 +323,7 @@ "@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="], - "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.27.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.27.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg=="], + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="], "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="], @@ -351,9 +339,9 @@ "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], - "@babel/helpers": ["@babel/helpers@7.28.2", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.2" } }, "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw=="], + "@babel/helpers": ["@babel/helpers@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.2" } }, "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw=="], - "@babel/parser": ["@babel/parser@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.0" }, "bin": "./bin/babel-parser.js" }, "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g=="], + "@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="], "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w=="], @@ -365,11 +353,11 @@ "@babel/preset-typescript": ["@babel/preset-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ=="], - "@babel/runtime": ["@babel/runtime@7.28.2", "", {}, "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA=="], + "@babel/runtime": ["@babel/runtime@7.28.3", "", {}, "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA=="], "@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], - "@babel/traverse": ["@babel/traverse@7.28.0", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/types": "^7.28.0", "debug": "^4.3.1" } }, "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg=="], + "@babel/traverse": ["@babel/traverse@7.28.3", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", "@babel/types": "^7.28.2", "debug": "^4.3.1" } }, "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ=="], "@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="], @@ -381,24 +369,22 @@ "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.0", "", { "dependencies": { "mime": "^3.0.0" } }, "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA=="], - "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.5.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.19", "workerd": "^1.20250722.0" }, "optionalPeers": ["workerd"] }, "sha512-CZe9B2VbjIQjBTyc+KoZcN1oUcm4T6GgCXoel9O7647djHuSRAa6sM6G+NdxWArATZgeMMbsvn9C50GCcnIatA=="], + "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.7.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.19", "workerd": "^1.20250816.0" }, "optionalPeers": ["workerd"] }, "sha512-0JbEj+KTCQ4nTIWg2q8Bou+fPxzG6/zwU5O/w6Cld6WEjLl+716foT+2bjg48h09hMtjTKkJdAh1m4LybBKGCg=="], - "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20250730.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-X3egNyTjLQaECYe34x8Al7r4oXAhcN3a8+8qcpNCcq1sgtuHIeAwS9potgRR/mwkGfmrJn7nfAyDKC4vrkniQQ=="], + "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20250823.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-yRLJc1cQNqQYcDViOk7kpTXnR5XuBP7B/Ms5KBdlQ6eTr2Vsg9mfKqWKInjzY8/Cx+p+Sic2Tbld42gcYkiM2A=="], - "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20250730.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-/4bvcaGY/9v0rghgKboGiyPKKGQTbDnQ1EeY0oN0SSQH0Cp3OBzqwni/JRvh8TEaD+5azJnSFLlFZj9w7fo+hw=="], + "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20250823.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-KJnikUe6J29Ga1QMPKNCc8eHD56DdBlu5XE5LoBH/AYRrbS5UI1d5F844hUWoFKJb8KRaPIH9F849HZWfNa1vw=="], - "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20250730.0", "", { "os": "linux", "cpu": "x64" }, "sha512-I4ZsXYdNkqkJnzNFKADMufiLIzRdIRsN7dSH8UCPw2fYp1BbKA10AkKVqitFwBxIY8eOzQ6Vf7c41AjLQmtJqA=="], + "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20250823.0", "", { "os": "linux", "cpu": "x64" }, "sha512-4QFXq4eDWEAK5QjGxRe0XUTBax1Fgarc08HETL6q0y/KPZp2nOTLfjLjklTn/qEiztafNFoJEIwhkiknHeOi/g=="], - "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20250730.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-tTpO6139jFQ5vxgtBZgS8Y8R1jVidS4n7s37x5xO9bCWLZoL0kTj38UGZ8FENkTeaMxE9Mm//nbQol7TfJ2nZg=="], + "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20250823.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-sODSrSVe4W/maoBu76qb0sJGBhxhSM2Q2tg/+G7q1IPgRZSzArMKIPrW6nBnmBrrG1O0X6aoAdID6w5hfuEM4g=="], - "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20250730.0", "", { "os": "win32", "cpu": "x64" }, "sha512-paVHgocuilMzOU+gEyKR/86j/yI+QzmSHRnqdd8OdQ37Hf6SyPX7kQj6VVNRXbzVHWix1WxaJsXfTGK1LK05wA=="], + "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20250823.0", "", { "os": "win32", "cpu": "x64" }, "sha512-WaNqUOXUnrcEI+i2NI4+okA9CrJMI9n2XTfVtDg/pLvcA/ZPTz23MEFMZU1splr4SslS1th1NBO38RMPnDB4rA=="], "@cloudflare/workers-types": ["@cloudflare/workers-types@4.20250522.0", "", {}, "sha512-9RIffHobc35JWeddzBguGgPa4wLDr5x5F94+0/qy7LiV6pTBQ/M5qGEN9VA16IDT3EUpYI0WKh6VpcmeVEtVtw=="], "@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="], - "@corvu/utils": ["@corvu/utils@0.4.2", "", { "dependencies": { "@floating-ui/dom": "^1.6.11" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-Ox2kYyxy7NoXdKWdHeDEjZxClwzO4SKM8plAaVwmAJPxHMqA0rLOoAsa+hBDwRLpctf+ZRnAd/ykguuJidnaTA=="], - "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], "@ctrl/tinycolor": ["@ctrl/tinycolor@4.1.0", "", {}, "sha512-WyOx8cJQ+FQus4Mm4uPIZA64gbk3Wxh0so5Lcii0aJifqwoVOlfFtorjLE0Hen4OYyHZMXDWqMmaQemBhgxFRQ=="], @@ -413,63 +399,63 @@ "@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="], - "@emnapi/runtime": ["@emnapi/runtime@1.4.5", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg=="], + "@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], "@esbuild-kit/core-utils": ["@esbuild-kit/core-utils@3.3.2", "", { "dependencies": { "esbuild": "~0.18.20", "source-map-support": "^0.5.21" } }, "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ=="], "@esbuild-kit/esm-loader": ["@esbuild-kit/esm-loader@2.6.5", "", { "dependencies": { "@esbuild-kit/core-utils": "^3.3.2", "get-tsconfig": "^4.7.0" } }, "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.8", "", { "os": "aix", "cpu": "ppc64" }, "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.9", "", { "os": "aix", "cpu": "ppc64" }, "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA=="], - "@esbuild/android-arm": ["@esbuild/android-arm@0.25.8", "", { "os": "android", "cpu": "arm" }, "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.25.9", "", { "os": "android", "cpu": "arm" }, "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ=="], - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.8", "", { "os": "android", "cpu": "arm64" }, "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.9", "", { "os": "android", "cpu": "arm64" }, "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg=="], - "@esbuild/android-x64": ["@esbuild/android-x64@0.25.8", "", { "os": "android", "cpu": "x64" }, "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.25.9", "", { "os": "android", "cpu": "x64" }, "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.8", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.9", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.8", "", { "os": "freebsd", "cpu": "x64" }, "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.9", "", { "os": "freebsd", "cpu": "x64" }, "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg=="], - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.8", "", { "os": "linux", "cpu": "arm" }, "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.9", "", { "os": "linux", "cpu": "arm" }, "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw=="], - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw=="], - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.8", "", { "os": "linux", "cpu": "ia32" }, "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.9", "", { "os": "linux", "cpu": "ia32" }, "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A=="], - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.8", "", { "os": "linux", "cpu": "none" }, "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.9", "", { "os": "linux", "cpu": "none" }, "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ=="], - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.8", "", { "os": "linux", "cpu": "none" }, "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.9", "", { "os": "linux", "cpu": "none" }, "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA=="], - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.8", "", { "os": "linux", "cpu": "ppc64" }, "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.9", "", { "os": "linux", "cpu": "ppc64" }, "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w=="], - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.8", "", { "os": "linux", "cpu": "none" }, "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.9", "", { "os": "linux", "cpu": "none" }, "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg=="], - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.8", "", { "os": "linux", "cpu": "s390x" }, "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.9", "", { "os": "linux", "cpu": "s390x" }, "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA=="], - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.8", "", { "os": "linux", "cpu": "x64" }, "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ=="], + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.9", "", { "os": "linux", "cpu": "x64" }, "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg=="], - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.8", "", { "os": "none", "cpu": "arm64" }, "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw=="], + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.9", "", { "os": "none", "cpu": "arm64" }, "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q=="], - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.8", "", { "os": "none", "cpu": "x64" }, "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.9", "", { "os": "none", "cpu": "x64" }, "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g=="], - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.8", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ=="], + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.9", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ=="], - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.8", "", { "os": "openbsd", "cpu": "x64" }, "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.9", "", { "os": "openbsd", "cpu": "x64" }, "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA=="], - "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.8", "", { "os": "none", "cpu": "arm64" }, "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg=="], + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.9", "", { "os": "none", "cpu": "arm64" }, "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg=="], - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.8", "", { "os": "sunos", "cpu": "x64" }, "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.9", "", { "os": "sunos", "cpu": "x64" }, "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw=="], - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ=="], - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.8", "", { "os": "win32", "cpu": "ia32" }, "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.9", "", { "os": "win32", "cpu": "ia32" }, "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww=="], - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.8", "", { "os": "win32", "cpu": "x64" }, "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw=="], + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.9", "", { "os": "win32", "cpu": "x64" }, "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ=="], "@expressive-code/core": ["@expressive-code/core@0.41.3", "", { "dependencies": { "@ctrl/tinycolor": "^4.0.4", "hast-util-select": "^6.0.2", "hast-util-to-html": "^9.0.1", "hast-util-to-text": "^4.0.1", "hastscript": "^9.0.0", "postcss": "^8.4.38", "postcss-nested": "^6.0.1", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1" } }, "sha512-9qzohqU7O0+JwMEEgQhnBPOw5DtsQRBXhW++5fvEywsuX44vCGGof1SL5OvPElvNgaWZ4pFZAFSlkNOkGyLwSQ=="], @@ -479,13 +465,7 @@ "@expressive-code/plugin-text-markers": ["@expressive-code/plugin-text-markers@0.41.3", "", { "dependencies": { "@expressive-code/core": "^0.41.3" } }, "sha512-SN8tkIzDpA0HLAscEYD2IVrfLiid6qEdE9QLlGVSxO1KEw7qYvjpbNBQjUjMr5/jvTJ7ys6zysU2vLPHE0sb2g=="], - "@fastify/busboy": ["@fastify/busboy@3.1.1", "", {}, "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw=="], - - "@floating-ui/core": ["@floating-ui/core@1.7.3", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w=="], - - "@floating-ui/dom": ["@floating-ui/dom@1.7.3", "", { "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" } }, "sha512-uZA413QEpNuhtb3/iIKoYMSK07keHPYeXF02Zhd6e213j+d1NamLix/mCLxBUDW/Gx52sPH2m+chlUsyaBs/Ag=="], - - "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="], + "@fastify/busboy": ["@fastify/busboy@3.2.0", "", {}, "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA=="], "@fontsource/ibm-plex-mono": ["@fontsource/ibm-plex-mono@5.2.5", "", {}, "sha512-G09N3GfuT9qj3Ax2FDZvKqZttzM3v+cco2l8uXamhKyXLdmlaUDH5o88/C3vtTHj2oT7yRKsvxz9F+BXbWKMYA=="], @@ -501,7 +481,7 @@ "@ibm/plex": ["@ibm/plex@6.4.1", "", { "dependencies": { "@ibm/telemetry-js": "^1.5.1" } }, "sha512-fnsipQywHt3zWvsnlyYKMikcVI7E2fEwpiPnIHFqlbByXVfQfANAAeJk1IV4mNnxhppUIDlhU0TzwYwL++Rn2g=="], - "@ibm/telemetry-js": ["@ibm/telemetry-js@1.9.1", "", { "bin": { "ibmtelemetry": "dist/collect.js" } }, "sha512-qq8RPafUJHUQieXVCte1kbJEx6JctWzbA/YkXzopbfzIDRT2+hbR9QmgH+KH7bDDNRcDbdHWvHfwJKzThlMtPg=="], + "@ibm/telemetry-js": ["@ibm/telemetry-js@1.10.1", "", { "bin": { "ibmtelemetry": "dist/collect.js" } }, "sha512-aQcDq03BKbgNnkHujHbA950wJVHtJnY0PsMHKyxgRvr3XPgInWjDfgxJQmKIp9I8Vy2wpfe0cGmduJfIX0HewQ=="], "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], @@ -541,11 +521,7 @@ "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.33.5", "", { "os": "win32", "cpu": "x64" }, "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="], - "@internationalized/date": ["@internationalized/date@3.8.2", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-/wENk7CbvLbkUvX1tu0mwq49CVkkWpkXubGel6birjRPyo6uQ4nQpnq5xZu823zRCwwn82zgHrvgF1vZyvmVgA=="], - - "@internationalized/number": ["@internationalized/number@3.6.4", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-P+/h+RDaiX8EGt3shB9AYM1+QgkvHmJ5rKi4/59k4sg9g58k9rqsRW0WxRO7jCoHyvVbFRRFKmVTdFYdehrxHg=="], - - "@ioredis/commands": ["@ioredis/commands@1.3.0", "", {}, "sha512-M/T6Zewn7sDaBQEqIZ8Rb+i9y8qfGmq+5SDFSf9sA2lUZTmdDLVdOiQaeDp+Q4wElZ9HG1GAX5KhDaidp6LQsQ=="], + "@ioredis/commands": ["@ioredis/commands@1.3.1", "", {}, "sha512-bYtU8avhGIcje3IhvF9aSjsa5URMZBHnwKtOvXsT4sfYy9gppW11gLPT/9oNqlJZD47yPKveQFTAFWpHjKvUoQ=="], "@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="], @@ -557,24 +533,22 @@ "@isaacs/string-locale-compare": ["@isaacs/string-locale-compare@1.1.0", "", {}, "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ=="], - "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg=="], + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], "@jridgewell/source-map": ["@jridgewell/source-map@0.3.11", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA=="], - "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.4", "", {}, "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw=="], + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], - "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.29", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ=="], + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.30", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q=="], "@js-sdsl/ordered-map": ["@js-sdsl/ordered-map@4.4.2", "", {}, "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw=="], "@jsdevtools/ono": ["@jsdevtools/ono@7.1.3", "", {}, "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="], - "@kobalte/core": ["@kobalte/core@0.13.9", "", { "dependencies": { "@floating-ui/dom": "^1.5.1", "@internationalized/date": "^3.4.0", "@internationalized/number": "^3.2.1", "@kobalte/utils": "^0.9.1", "@solid-primitives/props": "^3.1.8", "@solid-primitives/resize-observer": "^2.0.26", "solid-presence": "^0.1.8", "solid-prevent-scroll": "^0.1.4" }, "peerDependencies": { "solid-js": "^1.8.15" } }, "sha512-TkeSpgNy7I5k8jwjqT9CK3teAxN0aFb3yyL9ODb06JVYMwXIk+UKrizoAF1ahLUP85lKnxv44B4Y5cXkHShgqw=="], - - "@kobalte/utils": ["@kobalte/utils@0.9.1", "", { "dependencies": { "@solid-primitives/event-listener": "^2.2.14", "@solid-primitives/keyed": "^1.2.0", "@solid-primitives/map": "^0.4.7", "@solid-primitives/media": "^2.2.4", "@solid-primitives/props": "^3.1.8", "@solid-primitives/refs": "^1.0.5", "@solid-primitives/utils": "^6.2.1" }, "peerDependencies": { "solid-js": "^1.8.8" } }, "sha512-eeU60A3kprIiBDAfv9gUJX1tXGLuZiKMajUfSQURAF2pk4ZoMYiqIzmrMBvzcxP39xnYttgTyQEVLwiTZnrV4w=="], - "@logdna/tail-file": ["@logdna/tail-file@2.2.0", "", {}, "sha512-XGSsWDweP80Fks16lwkAUIr54ICyBs6PsI4mpfTLQaWgEJRtY9xEV+PeyDpJ+sJEGZxqINlpmAwe/6tS1pP8Ng=="], "@mapbox/node-pre-gyp": ["@mapbox/node-pre-gyp@2.0.0", "", { "dependencies": { "consola": "^3.2.3", "detect-libc": "^2.0.0", "https-proxy-agent": "^7.0.5", "node-fetch": "^2.6.7", "nopt": "^8.0.0", "semver": "^7.5.3", "tar": "^7.4.0" }, "bin": { "node-pre-gyp": "bin/node-pre-gyp" } }, "sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg=="], @@ -675,8 +649,6 @@ "@openauthjs/openauth": ["@openauthjs/openauth@0.0.0-20250322224806", "", { "dependencies": { "@standard-schema/spec": "1.0.0-beta.3", "aws4fetch": "1.0.20", "jose": "5.9.6" }, "peerDependencies": { "arctic": "^2.2.2", "hono": "^4.0.0" } }, "sha512-p5IWSRXvABcwocH2dNI0w8c1QJelIOFulwhKk+aLLFfUbs8u1pr7kQbYe8yCSM2+bcLHiwbogpUQc2ovrGwCuw=="], - "@openauthjs/solid": ["@openauthjs/solid@0.0.0-20250322224806", "", { "dependencies": { "@openauthjs/openauth": "0.4.2", "@solid-primitives/storage": "^4.3.1" }, "peerDependencies": { "solid-js": "^1.8.0" } }, "sha512-ln/yZQ/i+2vkrVSDOxxmbC8Oq6P2sljtdCiiAPZXj8etihwT11CYtj4jsrwArQltog738N2uvd2dKpHopVqLSQ=="], - "@opencode-ai/plugin": ["@opencode-ai/plugin@workspace:packages/plugin"], "@opencode-ai/sdk": ["@opencode-ai/sdk@workspace:packages/sdk/js"], @@ -687,7 +659,7 @@ "@opencode/cloud-function": ["@opencode/cloud-function@workspace:cloud/function"], - "@opencode/cloud-web": ["@opencode/cloud-web@workspace:cloud/web"], + "@opencode/cloud-resource": ["@opencode/cloud-resource@workspace:cloud/resource"], "@opencode/function": ["@opencode/function@workspace:packages/function"], @@ -801,7 +773,7 @@ "@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="], - "@pulumi/pulumi": ["@pulumi/pulumi@3.188.0", "", { "dependencies": { "@grpc/grpc-js": "^1.10.1", "@logdna/tail-file": "^2.0.6", "@npmcli/arborist": "^7.3.1", "@opentelemetry/api": "^1.9", "@opentelemetry/exporter-zipkin": "^1.28", "@opentelemetry/instrumentation": "^0.55", "@opentelemetry/instrumentation-grpc": "^0.55", "@opentelemetry/resources": "^1.28", "@opentelemetry/sdk-trace-base": "^1.28", "@opentelemetry/sdk-trace-node": "^1.28", "@types/google-protobuf": "^3.15.5", "@types/semver": "^7.5.6", "@types/tmp": "^0.2.6", "execa": "^5.1.0", "fdir": "^6.1.1", "google-protobuf": "^3.5.0", "got": "^11.8.6", "ini": "^2.0.0", "js-yaml": "^3.14.0", "minimist": "^1.2.6", "normalize-package-data": "^6.0.0", "picomatch": "^3.0.1", "pkg-dir": "^7.0.0", "require-from-string": "^2.0.1", "semver": "^7.5.2", "source-map-support": "^0.5.6", "tmp": "^0.2.4", "upath": "^1.1.0" }, "peerDependencies": { "ts-node": ">= 7.0.1 < 12", "typescript": ">= 3.8.3 < 6" }, "optionalPeers": ["ts-node", "typescript"] }, "sha512-c2L2QMq1bNo+1TxuoMQKQM7fiIZOMAAjDaIr2JKyg/ADGi7dhpKckEDbg43EMlzFUtI7t0mkiUYTaVPVcZ1kqg=="], + "@pulumi/pulumi": ["@pulumi/pulumi@3.192.0", "", { "dependencies": { "@grpc/grpc-js": "^1.10.1", "@logdna/tail-file": "^2.0.6", "@npmcli/arborist": "^7.3.1", "@opentelemetry/api": "^1.9", "@opentelemetry/exporter-zipkin": "^1.28", "@opentelemetry/instrumentation": "^0.55", "@opentelemetry/instrumentation-grpc": "^0.55", "@opentelemetry/resources": "^1.28", "@opentelemetry/sdk-trace-base": "^1.28", "@opentelemetry/sdk-trace-node": "^1.28", "@types/google-protobuf": "^3.15.5", "@types/semver": "^7.5.6", "@types/tmp": "^0.2.6", "execa": "^5.1.0", "fdir": "^6.1.1", "google-protobuf": "^3.21.4", "got": "^11.8.6", "ini": "^2.0.0", "js-yaml": "^3.14.0", "minimist": "^1.2.6", "normalize-package-data": "^6.0.0", "picomatch": "^3.0.1", "pkg-dir": "^7.0.0", "require-from-string": "^2.0.1", "semver": "^7.5.2", "source-map-support": "^0.5.6", "tmp": "^0.2.4", "upath": "^1.1.0" }, "peerDependencies": { "ts-node": ">= 7.0.1 < 12", "typescript": ">= 3.8.3 < 6" }, "optionalPeers": ["ts-node", "typescript"] }, "sha512-D6UdSBTP4SeNRdgoAMnpyCOECkM0e6KG9Sw3E7oBWmyK3swgNrFQ6Nygym/mNI8MbsAh+KOw6QtjC298lbwk8Q=="], "@rollup/plugin-alias": ["@rollup/plugin-alias@5.1.1", "", { "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ=="], @@ -819,45 +791,45 @@ "@rollup/pluginutils": ["@rollup/pluginutils@5.2.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.46.2", "", { "os": "android", "cpu": "arm" }, "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.49.0", "", { "os": "android", "cpu": "arm" }, "sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.46.2", "", { "os": "android", "cpu": "arm64" }, "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.49.0", "", { "os": "android", "cpu": "arm64" }, "sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.46.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.49.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.46.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA=="], + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.49.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.46.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.49.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.46.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.49.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.46.2", "", { "os": "linux", "cpu": "arm" }, "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.49.0", "", { "os": "linux", "cpu": "arm" }, "sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.46.2", "", { "os": "linux", "cpu": "arm" }, "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.49.0", "", { "os": "linux", "cpu": "arm" }, "sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.46.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.49.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.46.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg=="], + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.49.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg=="], - "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.46.2", "", { "os": "linux", "cpu": "none" }, "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA=="], + "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.49.0", "", { "os": "linux", "cpu": "none" }, "sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ=="], - "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.46.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw=="], + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.49.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.46.2", "", { "os": "linux", "cpu": "none" }, "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.49.0", "", { "os": "linux", "cpu": "none" }, "sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw=="], - "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.46.2", "", { "os": "linux", "cpu": "none" }, "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw=="], + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.49.0", "", { "os": "linux", "cpu": "none" }, "sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.46.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA=="], + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.49.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.46.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.49.0", "", { "os": "linux", "cpu": "x64" }, "sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.46.2", "", { "os": "linux", "cpu": "x64" }, "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.49.0", "", { "os": "linux", "cpu": "x64" }, "sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.46.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g=="], + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.49.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.46.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ=="], + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.49.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.46.2", "", { "os": "win32", "cpu": "x64" }, "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg=="], + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.49.0", "", { "os": "win32", "cpu": "x64" }, "sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg=="], "@shikijs/core": ["@shikijs/core@3.4.2", "", { "dependencies": { "@shikijs/types": "3.4.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-AG8vnSi1W2pbgR2B911EfGqtLE9c4hQBYkv/x7Z+Kt0VxhgQKcW7UNDVYsu9YxwV6u+OJrvdJrMq6DNWoBjihQ=="], @@ -895,11 +867,11 @@ "@smithy/config-resolver": ["@smithy/config-resolver@4.1.5", "", { "dependencies": { "@smithy/node-config-provider": "^4.1.4", "@smithy/types": "^4.3.2", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.5", "tslib": "^2.6.2" } }, "sha512-viuHMxBAqydkB0AfWwHIdwf/PRH2z5KHGUzqyRtS/Wv+n3IHI993Sk76VCA7dD/+GzgGOmlJDITfPcJC1nIVIw=="], - "@smithy/core": ["@smithy/core@3.8.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.9", "@smithy/protocol-http": "^5.1.3", "@smithy/types": "^4.3.2", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.5", "@smithy/util-stream": "^4.2.4", "@smithy/util-utf8": "^4.0.0", "@types/uuid": "^9.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-EYqsIYJmkR1VhVE9pccnk353xhs+lB6btdutJEtsp7R055haMJp2yE16eSxw8fv+G0WUY6vqxyYOP8kOqawxYQ=="], + "@smithy/core": ["@smithy/core@3.9.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.9", "@smithy/protocol-http": "^5.1.3", "@smithy/types": "^4.3.2", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.5", "@smithy/util-stream": "^4.2.4", "@smithy/util-utf8": "^4.0.0", "@types/uuid": "^9.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-B/GknvCfS3llXd/b++hcrwIuqnEozQDnRL4sBmOac5/z/dr0/yG1PURNPOyU4Lsiy1IyTj8scPxVqRs5dYWf6A=="], "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.0.7", "", { "dependencies": { "@smithy/node-config-provider": "^4.1.4", "@smithy/property-provider": "^4.0.5", "@smithy/types": "^4.3.2", "@smithy/url-parser": "^4.0.5", "tslib": "^2.6.2" } }, "sha512-dDzrMXA8d8riFNiPvytxn0mNwR4B3h8lgrQ5UjAGu6T9z/kRg/Xncf4tEQHE/+t25sY8IH3CowcmWi+1U5B1Gw=="], - "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.0.4", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.3.1", "@smithy/util-hex-encoding": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-7XoWfZqWb/QoR/rAU4VSi0mWnO2vu9/ltS6JZ5ZSZv0eovLVfDfu0/AX4ub33RsJTOth3TiFWSHS5YdztvFnig=="], + "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.0.5", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.3.2", "@smithy/util-hex-encoding": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-miEUN+nz2UTNoRYRhRqVTJCx7jMeILdAurStT2XoS+mhokkmz1xAPp95DFW9Gxt4iF2VBqpeF9HbTQ3kY1viOA=="], "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.1.1", "", { "dependencies": { "@smithy/protocol-http": "^5.1.3", "@smithy/querystring-builder": "^4.0.5", "@smithy/types": "^4.3.2", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-61WjM0PWmZJR+SnmzaKI7t7G0UkkNFboDpzIdzSoy7TByUzlxo18Qlh9s71qug4AY4hlH/CwXdubMtkcNEb/sQ=="], @@ -911,9 +883,9 @@ "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.0.5", "", { "dependencies": { "@smithy/protocol-http": "^5.1.3", "@smithy/types": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-l1jlNZoYzoCC7p0zCtBDE5OBXZ95yMKlRlftooE5jPWQn4YBPLgsp+oeHp7iMHaTGoUdFqmHOPa8c9G3gBsRpQ=="], - "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.1.18", "", { "dependencies": { "@smithy/core": "^3.8.0", "@smithy/middleware-serde": "^4.0.9", "@smithy/node-config-provider": "^4.1.4", "@smithy/shared-ini-file-loader": "^4.0.5", "@smithy/types": "^4.3.2", "@smithy/url-parser": "^4.0.5", "@smithy/util-middleware": "^4.0.5", "tslib": "^2.6.2" } }, "sha512-ZhvqcVRPZxnZlokcPaTwb+r+h4yOIOCJmx0v2d1bpVlmP465g3qpVSf7wxcq5zZdu4jb0H4yIMxuPwDJSQc3MQ=="], + "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.1.19", "", { "dependencies": { "@smithy/core": "^3.9.0", "@smithy/middleware-serde": "^4.0.9", "@smithy/node-config-provider": "^4.1.4", "@smithy/shared-ini-file-loader": "^4.0.5", "@smithy/types": "^4.3.2", "@smithy/url-parser": "^4.0.5", "@smithy/util-middleware": "^4.0.5", "tslib": "^2.6.2" } }, "sha512-EAlEPncqo03siNZJ9Tm6adKCQ+sw5fNU8ncxWwaH0zTCwMPsgmERTi6CEKaermZdgJb+4Yvh0NFm36HeO4PGgQ=="], - "@smithy/middleware-retry": ["@smithy/middleware-retry@4.1.19", "", { "dependencies": { "@smithy/node-config-provider": "^4.1.4", "@smithy/protocol-http": "^5.1.3", "@smithy/service-error-classification": "^4.0.7", "@smithy/smithy-client": "^4.4.10", "@smithy/types": "^4.3.2", "@smithy/util-middleware": "^4.0.5", "@smithy/util-retry": "^4.0.7", "@types/uuid": "^9.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-X58zx/NVECjeuUB6A8HBu4bhx72EoUz+T5jTMIyeNKx2lf+Gs9TmWPNNkH+5QF0COjpInP/xSpJGJ7xEnAklQQ=="], + "@smithy/middleware-retry": ["@smithy/middleware-retry@4.1.20", "", { "dependencies": { "@smithy/node-config-provider": "^4.1.4", "@smithy/protocol-http": "^5.1.3", "@smithy/service-error-classification": "^4.0.7", "@smithy/smithy-client": "^4.5.0", "@smithy/types": "^4.3.2", "@smithy/util-middleware": "^4.0.5", "@smithy/util-retry": "^4.0.7", "@types/uuid": "^9.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-T3maNEm3Masae99eFdx1Q7PIqBBEVOvRd5hralqKZNeIivnoGNx5OFtI3DiZ5gCjUkl0mNondlzSXeVxkinh7Q=="], "@smithy/middleware-serde": ["@smithy/middleware-serde@4.0.9", "", { "dependencies": { "@smithy/protocol-http": "^5.1.3", "@smithy/types": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-uAFFR4dpeoJPGz8x9mhxp+RPjo5wW0QEEIPPPbLXiRRWeCATf/Km3gKIVR5vaP8bN1kgsPhcEeh+IZvUlBv6Xg=="], @@ -937,9 +909,9 @@ "@smithy/signature-v4": ["@smithy/signature-v4@5.1.3", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "@smithy/protocol-http": "^5.1.3", "@smithy/types": "^4.3.2", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-middleware": "^4.0.5", "@smithy/util-uri-escape": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-mARDSXSEgllNzMw6N+mC+r1AQlEBO3meEAkR/UlfAgnMzJUB3goRBWgip1EAMG99wh36MDqzo86SfIX5Y+VEaw=="], - "@smithy/smithy-client": ["@smithy/smithy-client@4.4.10", "", { "dependencies": { "@smithy/core": "^3.8.0", "@smithy/middleware-endpoint": "^4.1.18", "@smithy/middleware-stack": "^4.0.5", "@smithy/protocol-http": "^5.1.3", "@smithy/types": "^4.3.2", "@smithy/util-stream": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-iW6HjXqN0oPtRS0NK/zzZ4zZeGESIFcxj2FkWed3mcK8jdSdHzvnCKXSjvewESKAgGKAbJRA+OsaqKhkdYRbQQ=="], + "@smithy/smithy-client": ["@smithy/smithy-client@4.5.0", "", { "dependencies": { "@smithy/core": "^3.9.0", "@smithy/middleware-endpoint": "^4.1.19", "@smithy/middleware-stack": "^4.0.5", "@smithy/protocol-http": "^5.1.3", "@smithy/types": "^4.3.2", "@smithy/util-stream": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-ZSdE3vl0MuVbEwJBxSftm0J5nL/gw76xp5WF13zW9cN18MFuFXD5/LV0QD8P+sCU5bSWGyy6CTgUupE1HhOo1A=="], - "@smithy/types": ["@smithy/types@4.3.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-UqKOQBL2x6+HWl3P+3QqFD4ncKq0I8Nuz9QItGv5WuKuMHuuwlhvqcZCoXGfc+P1QmfJE7VieykoYYmrOoFJxA=="], + "@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], "@smithy/url-parser": ["@smithy/url-parser@4.0.5", "", { "dependencies": { "@smithy/querystring-parser": "^4.0.5", "@smithy/types": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-j+733Um7f1/DXjYhCbvNXABV53NyCRRA54C7bNEIxNPs0YjfRxeMKjjgm2jvTYrciZyCjsicHwQ6Q0ylo+NAUw=="], @@ -953,9 +925,9 @@ "@smithy/util-config-provider": ["@smithy/util-config-provider@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w=="], - "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.0.26", "", { "dependencies": { "@smithy/property-provider": "^4.0.5", "@smithy/smithy-client": "^4.4.10", "@smithy/types": "^4.3.2", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-xgl75aHIS/3rrGp7iTxQAOELYeyiwBu+eEgAk4xfKwJJ0L8VUjhO2shsDpeil54BOFsqmk5xfdesiewbUY5tKQ=="], + "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.0.27", "", { "dependencies": { "@smithy/property-provider": "^4.0.5", "@smithy/smithy-client": "^4.5.0", "@smithy/types": "^4.3.2", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-i/Fu6AFT5014VJNgWxKomBJP/GB5uuOsM4iHdcmplLm8B1eAqnRItw4lT2qpdO+mf+6TFmf6dGcggGLAVMZJsQ=="], - "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.0.26", "", { "dependencies": { "@smithy/config-resolver": "^4.1.5", "@smithy/credential-provider-imds": "^4.0.7", "@smithy/node-config-provider": "^4.1.4", "@smithy/property-provider": "^4.0.5", "@smithy/smithy-client": "^4.4.10", "@smithy/types": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-z81yyIkGiLLYVDetKTUeCZQ8x20EEzvQjrqJtb/mXnevLq2+w3XCEWTJ2pMp401b6BkEkHVfXb/cROBpVauLMQ=="], + "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.0.27", "", { "dependencies": { "@smithy/config-resolver": "^4.1.5", "@smithy/credential-provider-imds": "^4.0.7", "@smithy/node-config-provider": "^4.1.4", "@smithy/property-provider": "^4.0.5", "@smithy/smithy-client": "^4.5.0", "@smithy/types": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-3W0qClMyxl/ELqTA39aNw1N+pN0IjpXT7lPFvZ8zTxqVFP7XCpACB9QufmN4FQtd39xbgS7/Lekn7LmDa63I5w=="], "@smithy/util-endpoints": ["@smithy/util-endpoints@3.0.7", "", { "dependencies": { "@smithy/node-config-provider": "^4.1.4", "@smithy/types": "^4.3.2", "tslib": "^2.6.2" } }, "sha512-klGBP+RpBp6V5JbrY2C/VKnHXn3d5V2YrifZbmMY8os7M6m8wdYFoO6w/fe5VkP+YVwrEktW3IWYaSQVNZJ8oQ=="], @@ -971,30 +943,6 @@ "@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="], - "@solid-primitives/event-listener": ["@solid-primitives/event-listener@2.4.3", "", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-h4VqkYFv6Gf+L7SQj+Y6puigL/5DIi7x5q07VZET7AWcS+9/G3WfIE9WheniHWJs51OEkRB43w6lDys5YeFceg=="], - - "@solid-primitives/keyed": ["@solid-primitives/keyed@1.5.2", "", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-BgoEdqPw48URnI+L5sZIHdF4ua4Las1eWEBBPaoSFs42kkhnHue+rwCBPL2Z9ebOyQ75sUhUfOETdJfmv0D6Kg=="], - - "@solid-primitives/map": ["@solid-primitives/map@0.4.13", "", { "dependencies": { "@solid-primitives/trigger": "^1.1.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-B1zyFbsiTQvqPr+cuPCXO72sRuczG9Swncqk5P74NCGw1VE8qa/Ry9GlfI1e/VdeQYHjan+XkbE3rO2GW/qKew=="], - - "@solid-primitives/media": ["@solid-primitives/media@2.3.3", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/rootless": "^1.5.2", "@solid-primitives/static-store": "^0.1.2", "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-hQ4hLOGvfbugQi5Eu1BFWAIJGIAzztq9x0h02xgBGl2l0Jaa3h7tg6bz5tV1NSuNYVGio4rPoa7zVQQLkkx9dA=="], - - "@solid-primitives/props": ["@solid-primitives/props@3.2.2", "", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-lZOTwFJajBrshSyg14nBMEP0h8MXzPowGO0s3OeiR3z6nXHTfj0FhzDtJMv+VYoRJKQHG2QRnJTgCzK6erARAw=="], - - "@solid-primitives/refs": ["@solid-primitives/refs@1.1.2", "", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-K7tf2thy7L+YJjdqXspXOg5xvNEOH8tgEWsp0+1mQk3obHBRD6hEjYZk7p7FlJphSZImS35je3UfmWuD7MhDfg=="], - - "@solid-primitives/resize-observer": ["@solid-primitives/resize-observer@2.1.3", "", { "dependencies": { "@solid-primitives/event-listener": "^2.4.3", "@solid-primitives/rootless": "^1.5.2", "@solid-primitives/static-store": "^0.1.2", "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ=="], - - "@solid-primitives/rootless": ["@solid-primitives/rootless@1.5.2", "", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-9HULb0QAzL2r47CCad0M+NKFtQ+LrGGNHZfteX/ThdGvKIg2o2GYhBooZubTCd/RTu2l2+Nw4s+dEfiDGvdrrQ=="], - - "@solid-primitives/static-store": ["@solid-primitives/static-store@0.1.2", "", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-ReK+5O38lJ7fT+L6mUFvUr6igFwHBESZF+2Ug842s7fvlVeBdIVEdTCErygff6w7uR6+jrr7J8jQo+cYrEq4Iw=="], - - "@solid-primitives/storage": ["@solid-primitives/storage@4.3.1", "", { "dependencies": { "@solid-primitives/utils": "^6.3.0" }, "peerDependencies": { "@tauri-apps/plugin-store": "*", "solid-js": "^1.6.12" }, "optionalPeers": ["@tauri-apps/plugin-store"] }, "sha512-xAJsY2pvXrAaCai4N2grmWY3xh5om9suTDVzGkRF5JBpDzs3Apk+xIovdTErbW0iCzXIEefENXb9xmSzdjuLYA=="], - - "@solid-primitives/trigger": ["@solid-primitives/trigger@1.2.2", "", { "dependencies": { "@solid-primitives/utils": "^6.3.2" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-IWoptVc0SWYgmpBPpCMehS5b07+tpFcvw15tOQ3QbXedSYn6KP8zCjPkHNzMxcOvOicTneleeZDP7lqmz+PQ6g=="], - - "@solid-primitives/utils": ["@solid-primitives/utils@6.3.2", "", { "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ=="], - "@solidjs/meta": ["@solidjs/meta@0.29.4", "", { "peerDependencies": { "solid-js": ">=1.8.4" } }, "sha512-zdIWBGpR9zGx1p1bzIPqF5Gs+Ks/BH8R6fWhmUa/dcK1L2rUC8BAcZJzNRYBQv74kScf1TSOs0EY//Vd/I0V8g=="], "@solidjs/router": ["@solidjs/router@0.15.3", "", { "peerDependencies": { "solid-js": "^1.8.6" } }, "sha512-iEbW8UKok2Oio7o6Y4VTzLj+KFCmQPGEpm1fS3xixwFBdclFVBvaQVeibl1jys4cujfAK5Kn6+uG2uBm3lxOMw=="], @@ -1029,11 +977,11 @@ "@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="], - "@types/babel__traverse": ["@types/babel__traverse@7.20.7", "", { "dependencies": { "@babel/types": "^7.20.7" } }, "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng=="], + "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], "@types/braces": ["@types/braces@3.0.5", "", {}, "sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w=="], - "@types/bun": ["@types/bun@1.2.20", "", { "dependencies": { "bun-types": "1.2.20" } }, "sha512-dX3RGzQ8+KgmMw7CsW4xT5ITBSCrSbfHc36SNT31EOUg/LA9JWq0VDdEXDRSe1InVWpd2yLUM1FUF/kEOyTzYA=="], + "@types/bun": ["@types/bun@1.2.21", "", { "dependencies": { "bun-types": "1.2.21" } }, "sha512-NiDnvEqmbfQ6dmZ3EeUO577s4P5bf4HCTXtI6trMc6f6RzirY5IrF3aIookuSpyslFzrnvv2lmEWv5HyC1X79A=="], "@types/cacheable-request": ["@types/cacheable-request@6.0.3", "", { "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "^3.1.4", "@types/node": "*", "@types/responselike": "^1.0.0" } }, "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw=="], @@ -1073,9 +1021,7 @@ "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], - "@types/pg": ["@types/pg@8.15.4", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg=="], - - "@types/react": ["@types/react@19.1.9", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA=="], + "@types/react": ["@types/react@19.1.12", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w=="], "@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="], @@ -1103,15 +1049,15 @@ "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], - "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.39.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.39.1", "@typescript-eslint/types": "^8.39.1", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-8fZxek3ONTwBu9ptw5nCKqZOSkXshZB7uAxuFF0J/wTMkKydjXCzqqga7MlFMpHi9DoG4BadhmTkITBcg8Aybw=="], + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.41.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.41.0", "@typescript-eslint/types": "^8.41.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-b8V9SdGBQzQdjJ/IO3eDifGpDBJfvrNTp2QD9P2BeqWTGrRibgfgIlBSw6z3b6R7dPzg752tOs4u/7yCLxksSQ=="], - "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.39.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ePUPGVtTMR8XMU2Hee8kD0Pu4NDE1CN9Q1sxGSGd/mbOtGZDM7pnhXNJnzW63zk/q+Z54zVzj44HtwXln5CvHA=="], + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.41.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-TDhxYFPUYRFxFhuU5hTIJk+auzM/wKvWgoNYOPcOf6i4ReYlOoYN8q1dV5kOTjNQNJgzWN3TUUQMtlLOcUgdUw=="], - "@typescript-eslint/types": ["@typescript-eslint/types@8.39.1", "", {}, "sha512-7sPDKQQp+S11laqTrhHqeAbsCfMkwJMrV7oTDvtDds4mEofJYir414bYKUEb8YPUm9QL3U+8f6L6YExSoAGdQw=="], + "@typescript-eslint/types": ["@typescript-eslint/types@8.41.0", "", {}, "sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag=="], - "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.39.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.39.1", "@typescript-eslint/tsconfig-utils": "8.39.1", "@typescript-eslint/types": "8.39.1", "@typescript-eslint/visitor-keys": "8.39.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-EKkpcPuIux48dddVDXyQBlKdeTPMmALqBUbEk38McWv0qVEZwOpVJBi7ugK5qVNgeuYjGNQxrrnoM/5+TI/BPw=="], + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.41.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.41.0", "@typescript-eslint/tsconfig-utils": "8.41.0", "@typescript-eslint/types": "8.41.0", "@typescript-eslint/visitor-keys": "8.41.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ=="], - "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.39.1", "", { "dependencies": { "@typescript-eslint/types": "8.39.1", "eslint-visitor-keys": "^4.2.1" } }, "sha512-W8FQi6kEh2e8zVhQ0eeRnxdvIoOkAp/CPAahcNio6nO9dsIwb9b34z90KOlheoyuVf6LSOEdjlkxSkapNEc+4A=="], + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.41.0", "", { "dependencies": { "@typescript-eslint/types": "8.41.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg=="], "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], @@ -1123,15 +1069,15 @@ "@vinxi/server-components": ["@vinxi/server-components@0.5.1", "", { "dependencies": { "@vinxi/plugin-directives": "0.5.1", "acorn": "^8.10.0", "acorn-loose": "^8.3.0", "acorn-typescript": "^1.4.3", "astring": "^1.8.6", "magicast": "^0.2.10", "recast": "^0.23.4" }, "peerDependencies": { "vinxi": "^0.5.5" } }, "sha512-0BsG95qac3dkhfdRZxqzqYWJE4NvPL7ILlV43B6K6ho1etXWB2e5b0IxsUAUbyqpqiXM7mSRivojuXjb2G4OsQ=="], - "@vue/compiler-core": ["@vue/compiler-core@3.5.18", "", { "dependencies": { "@babel/parser": "^7.28.0", "@vue/shared": "3.5.18", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw=="], + "@vue/compiler-core": ["@vue/compiler-core@3.5.20", "", { "dependencies": { "@babel/parser": "^7.28.3", "@vue/shared": "3.5.20", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-8TWXUyiqFd3GmP4JTX9hbiTFRwYHgVL/vr3cqhr4YQ258+9FADwvj7golk2sWNGHR67QgmCZ8gz80nQcMokhwg=="], - "@vue/compiler-dom": ["@vue/compiler-dom@3.5.18", "", { "dependencies": { "@vue/compiler-core": "3.5.18", "@vue/shared": "3.5.18" } }, "sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A=="], + "@vue/compiler-dom": ["@vue/compiler-dom@3.5.20", "", { "dependencies": { "@vue/compiler-core": "3.5.20", "@vue/shared": "3.5.20" } }, "sha512-whB44M59XKjqUEYOMPYU0ijUV0G+4fdrHVKDe32abNdX/kJe1NUEMqsi4cwzXa9kyM9w5S8WqFsrfo1ogtBZGQ=="], - "@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.18", "", { "dependencies": { "@babel/parser": "^7.28.0", "@vue/compiler-core": "3.5.18", "@vue/compiler-dom": "3.5.18", "@vue/compiler-ssr": "3.5.18", "@vue/shared": "3.5.18", "estree-walker": "^2.0.2", "magic-string": "^0.30.17", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA=="], + "@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.20", "", { "dependencies": { "@babel/parser": "^7.28.3", "@vue/compiler-core": "3.5.20", "@vue/compiler-dom": "3.5.20", "@vue/compiler-ssr": "3.5.20", "@vue/shared": "3.5.20", "estree-walker": "^2.0.2", "magic-string": "^0.30.17", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-SFcxapQc0/feWiSBfkGsa1v4DOrnMAQSYuvDMpEaxbpH5dKbnEM5KobSNSgU+1MbHCl+9ftm7oQWxvwDB6iBfw=="], - "@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.18", "", { "dependencies": { "@vue/compiler-dom": "3.5.18", "@vue/shared": "3.5.18" } }, "sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g=="], + "@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.20", "", { "dependencies": { "@vue/compiler-dom": "3.5.20", "@vue/shared": "3.5.20" } }, "sha512-RSl5XAMc5YFUXpDQi+UQDdVjH9FnEpLDHIALg5J0ITHxkEzJ8uQLlo7CIbjPYqmZtt6w0TsIPbo1izYXwDG7JA=="], - "@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], + "@vue/shared": ["@vue/shared@3.5.20", "", {}, "sha512-SoRGP596KU/ig6TfgkCMbXkr4YJ91n/QSdMuqeP5r3hVIYA3CPHUBCc7Skak0EAKV+5lL4KyIh61VA/pK1CIAA=="], "@whatwg-node/disposablestack": ["@whatwg-node/disposablestack@0.0.6", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.6.3" } }, "sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw=="], @@ -1175,7 +1121,7 @@ "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], - "ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], + "ansi-regex": ["ansi-regex@6.2.0", "", {}, "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg=="], "ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], @@ -1209,8 +1155,6 @@ "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], - "async-lock": ["async-lock@1.4.1", "", {}, "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ=="], - "async-sema": ["async-sema@3.1.1", "", {}, "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg=="], "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], @@ -1225,23 +1169,23 @@ "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.10", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA=="], - "babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.39.8", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2", "validate-html-nesting": "^1.2.1" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-/MVOIIjonylDXnrWmG23ZX82m9mtKATsVHB7zYlPfDR9Vdd/NBE48if+wv27bSkBtyO7EPMUlcUc4J63QwuACQ=="], + "babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.40.1", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2", "validate-html-nesting": "^1.2.1" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-b4iHuirqK7RgaMzB2Lsl7MqrlDgQtVRSSazyrmx7wB3T759ggGjod5Rkok5MfHjQXhR7tRPmdwoeGPqBnW2KfA=="], - "babel-preset-solid": ["babel-preset-solid@1.9.6", "", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.39.8" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-HXTK9f93QxoH8dYn1M2mJdOlWgMsR88Lg/ul6QCZGkNTktjTE5HAf93YxQumHoCudLEtZrU1cFCMFOVho6GqFg=="], + "babel-preset-solid": ["babel-preset-solid@1.9.9", "", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.40.1" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^1.9.8" }, "optionalPeers": ["solid-js"] }, "sha512-pCnxWrciluXCeli/dj5PIEHgbNzim3evtTn12snjqqg8QZWJNMjH1AWIp4iG/tbVjqQ72aBEymMSagvmgxubXw=="], "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - "bare-events": ["bare-events@2.6.0", "", {}, "sha512-EKZ5BTXYExaNqi3I3f9RtEsaI/xBSGjE0XZCZilPzFAV/goswFHuPd9jEZlPIZ/iNZJwDSao9qRiScySz7MbQg=="], + "bare-events": ["bare-events@2.6.1", "", {}, "sha512-AuTJkq9XmE6Vk0FJVNq5QxETrSA/vKHarWVBG5l/JbdCL1prJemiyJqUS0jrlXO0MftuPq4m3YVYhoNc5+aE/g=="], - "bare-fs": ["bare-fs@4.1.6", "", { "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4" }, "peerDependencies": { "bare-buffer": "*" }, "optionalPeers": ["bare-buffer"] }, "sha512-25RsLF33BqooOEFNdMcEhMpJy8EoR88zSMrnOQOaM3USnOK2VmaJ1uaQEwPA6AQjrv1lXChScosN6CzbwbO9OQ=="], + "bare-fs": ["bare-fs@4.2.1", "", { "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4" }, "peerDependencies": { "bare-buffer": "*" }, "optionalPeers": ["bare-buffer"] }, "sha512-mELROzV0IhqilFgsl1gyp48pnZsaV9xhQapHLDsvn4d4ZTfbFhcghQezl7FTEDNBcGqLUnNI3lUlm6ecrLWdFA=="], - "bare-os": ["bare-os@3.6.1", "", {}, "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g=="], + "bare-os": ["bare-os@3.6.2", "", {}, "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A=="], "bare-path": ["bare-path@3.0.0", "", { "dependencies": { "bare-os": "^3.0.1" } }, "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw=="], - "bare-stream": ["bare-stream@2.6.5", "", { "dependencies": { "streamx": "^2.21.0" }, "peerDependencies": { "bare-buffer": "*", "bare-events": "*" }, "optionalPeers": ["bare-buffer", "bare-events"] }, "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA=="], + "bare-stream": ["bare-stream@2.7.0", "", { "dependencies": { "streamx": "^2.21.0" }, "peerDependencies": { "bare-buffer": "*", "bare-events": "*" }, "optionalPeers": ["bare-buffer", "bare-events"] }, "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A=="], "base-64": ["base-64@1.0.0", "", {}, "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="], @@ -1267,7 +1211,7 @@ "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], - "bowser": ["bowser@2.11.0", "", {}, "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA=="], + "bowser": ["bowser@2.12.1", "", {}, "sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw=="], "boxen": ["boxen@8.0.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^8.0.0", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "string-width": "^7.2.0", "type-fest": "^4.21.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0" } }, "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw=="], @@ -1277,7 +1221,7 @@ "brotli": ["brotli@1.3.3", "", { "dependencies": { "base64-js": "^1.1.2" } }, "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg=="], - "browserslist": ["browserslist@4.25.1", "", { "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw=="], + "browserslist": ["browserslist@4.25.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001737", "electron-to-chromium": "^1.5.211", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg=="], "buffer": ["buffer@4.9.2", "", { "dependencies": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", "isarray": "^1.0.0" } }, "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg=="], @@ -1287,7 +1231,7 @@ "builtin-modules": ["builtin-modules@3.3.0", "", {}, "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw=="], - "bun-types": ["bun-types@1.2.19", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ=="], + "bun-types": ["bun-types@1.2.21", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-sa2Tj77Ijc/NTLS0/Odjq/qngmEPZfbfnOERi0KRUYhT9R8M4VBioWVmMWE5GrYbKMc+5lVybXygLdibHaqVqw=="], "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], @@ -1311,11 +1255,11 @@ "camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="], - "caniuse-lite": ["caniuse-lite@1.0.30001731", "", {}, "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg=="], + "caniuse-lite": ["caniuse-lite@1.0.30001737", "", {}, "sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], - "chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="], + "chalk": ["chalk@5.6.0", "", {}, "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ=="], "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], @@ -1335,8 +1279,6 @@ "cjs-module-lexer": ["cjs-module-lexer@1.4.3", "", {}, "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q=="], - "clean-git-ref": ["clean-git-ref@2.0.1", "", {}, "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw=="], - "clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="], "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="], @@ -1491,7 +1433,7 @@ "deterministic-object-hash": ["deterministic-object-hash@2.0.2", "", { "dependencies": { "base-64": "^1.0.0" } }, "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ=="], - "devalue": ["devalue@5.1.1", "", {}, "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw=="], + "devalue": ["devalue@5.3.2", "", {}, "sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw=="], "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], @@ -1499,8 +1441,6 @@ "diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="], - "diff3": ["diff3@0.0.3", "", {}, "sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g=="], - "direction": ["direction@2.0.1", "", { "bin": { "direction": "cli.js" } }, "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA=="], "dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="], @@ -1523,9 +1463,9 @@ "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], - "electron-to-chromium": ["electron-to-chromium@1.5.193", "", {}, "sha512-eePuBZXM9OVCwfYUhd2OzESeNGnWmLyeu0XAEjf7xjijNjHFdeJSzuRUGN4ueT2tEYo5YqjHramKEFxz67p3XA=="], + "electron-to-chromium": ["electron-to-chromium@1.5.211", "", {}, "sha512-IGBvimJkotaLzFnwIVgW9/UD/AOJ2tByUmeOrtqBfACSbAw5b1G0XpvdaieKyc7ULmbwXVx+4e4Be8pOPBrYkw=="], - "emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="], + "emoji-regex": ["emoji-regex@10.5.0", "", {}, "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg=="], "emoji-regex-xs": ["emoji-regex-xs@1.0.0", "", {}, "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="], @@ -1537,7 +1477,7 @@ "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], - "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], "env-paths": ["env-paths@3.0.0", "", {}, "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A=="], @@ -1559,7 +1499,7 @@ "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="], - "esbuild": ["esbuild@0.25.8", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.8", "@esbuild/android-arm": "0.25.8", "@esbuild/android-arm64": "0.25.8", "@esbuild/android-x64": "0.25.8", "@esbuild/darwin-arm64": "0.25.8", "@esbuild/darwin-x64": "0.25.8", "@esbuild/freebsd-arm64": "0.25.8", "@esbuild/freebsd-x64": "0.25.8", "@esbuild/linux-arm": "0.25.8", "@esbuild/linux-arm64": "0.25.8", "@esbuild/linux-ia32": "0.25.8", "@esbuild/linux-loong64": "0.25.8", "@esbuild/linux-mips64el": "0.25.8", "@esbuild/linux-ppc64": "0.25.8", "@esbuild/linux-riscv64": "0.25.8", "@esbuild/linux-s390x": "0.25.8", "@esbuild/linux-x64": "0.25.8", "@esbuild/netbsd-arm64": "0.25.8", "@esbuild/netbsd-x64": "0.25.8", "@esbuild/openbsd-arm64": "0.25.8", "@esbuild/openbsd-x64": "0.25.8", "@esbuild/openharmony-arm64": "0.25.8", "@esbuild/sunos-x64": "0.25.8", "@esbuild/win32-arm64": "0.25.8", "@esbuild/win32-ia32": "0.25.8", "@esbuild/win32-x64": "0.25.8" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q=="], + "esbuild": ["esbuild@0.25.9", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.9", "@esbuild/android-arm": "0.25.9", "@esbuild/android-arm64": "0.25.9", "@esbuild/android-x64": "0.25.9", "@esbuild/darwin-arm64": "0.25.9", "@esbuild/darwin-x64": "0.25.9", "@esbuild/freebsd-arm64": "0.25.9", "@esbuild/freebsd-x64": "0.25.9", "@esbuild/linux-arm": "0.25.9", "@esbuild/linux-arm64": "0.25.9", "@esbuild/linux-ia32": "0.25.9", "@esbuild/linux-loong64": "0.25.9", "@esbuild/linux-mips64el": "0.25.9", "@esbuild/linux-ppc64": "0.25.9", "@esbuild/linux-riscv64": "0.25.9", "@esbuild/linux-s390x": "0.25.9", "@esbuild/linux-x64": "0.25.9", "@esbuild/netbsd-arm64": "0.25.9", "@esbuild/netbsd-x64": "0.25.9", "@esbuild/openbsd-arm64": "0.25.9", "@esbuild/openbsd-x64": "0.25.9", "@esbuild/openharmony-arm64": "0.25.9", "@esbuild/sunos-x64": "0.25.9", "@esbuild/win32-arm64": "0.25.9", "@esbuild/win32-ia32": "0.25.9", "@esbuild/win32-x64": "0.25.9" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g=="], "esbuild-register": ["esbuild-register@3.6.0", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "esbuild": ">=0.12 <1" } }, "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg=="], @@ -1575,8 +1515,6 @@ "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], - "esprima-extract-comments": ["esprima-extract-comments@1.1.0", "", { "dependencies": { "esprima": "^4.0.0" } }, "sha512-sBQUnvJwpeE9QnPrxh7dpI/dp67erYG4WXEAreAMoelPRpMR7NWb4YtwRPn9b+H1uLQKl/qS8WYmyaljTpjIsw=="], - "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], "estree-util-attach-comments": ["estree-util-attach-comments@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw=="], @@ -1605,7 +1543,7 @@ "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="], - "eventsource-parser": ["eventsource-parser@3.0.3", "", {}, "sha512-nVpZkTMM9rF6AQ9gPJpFsNAMt48wIzB5TQgiTLdHiuO8XEDhUgZEhqKlZWXbIzo9VmJ/HvysHqEaVeD5v9TPvA=="], + "eventsource-parser": ["eventsource-parser@3.0.5", "", {}, "sha512-bSRG85ZrMdmWtm7qkF9He9TNRzc/Bm99gEJMaQoHJ9E6Kv9QBbsldh2oMj7iXmYNEAVvNgvv5vPorG6W+XtBhQ=="], "execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="], @@ -1627,8 +1565,6 @@ "extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="], - "extract-comments": ["extract-comments@1.1.0", "", { "dependencies": { "esprima-extract-comments": "^1.1.0", "parse-code-context": "^1.0.0" } }, "sha512-dzbZV2AdSSVW/4E7Ti5hZdHWbA+Z80RJsJhr5uiL10oyjl/gy7/o+HI1HwK4/WSZhlq4SNKU3oUzXlM13Qx02Q=="], - "extract-zip": ["extract-zip@2.0.1", "", { "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" }, "bin": { "extract-zip": "cli.js" } }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="], "fast-content-type-parse": ["fast-content-type-parse@3.0.0", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="], @@ -1647,7 +1583,7 @@ "fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="], - "fdir": ["fdir@6.4.6", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="], + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "fecha": ["fecha@4.2.3", "", {}, "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="], @@ -1837,7 +1773,7 @@ "ieee754": ["ieee754@1.1.13", "", {}, "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="], - "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], + "ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], "ignore-walk": ["ignore-walk@6.0.5", "", { "dependencies": { "minimatch": "^9.0.0" } }, "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A=="], @@ -1859,7 +1795,7 @@ "ioredis": ["ioredis@5.7.0", "", { "dependencies": { "@ioredis/commands": "^1.3.0", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", "lodash.defaults": "^4.2.0", "lodash.isarguments": "^3.1.0", "redis-errors": "^1.2.0", "redis-parser": "^3.0.0", "standard-as-callback": "^2.1.0" } }, "sha512-NUcA93i1lukyXU+riqEyPtSEkyFq8tX90uL659J+qpCZ3rEdViB/APC58oAhIh3+bJln2hzdlZbBZsGNrlsR8g=="], - "ip-address": ["ip-address@9.0.5", "", { "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" } }, "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g=="], + "ip-address": ["ip-address@10.0.1", "", {}, "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA=="], "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], @@ -1931,8 +1867,6 @@ "isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="], - "isomorphic-git": ["isomorphic-git@1.32.1", "", { "dependencies": { "async-lock": "^1.4.1", "clean-git-ref": "^2.0.1", "crc-32": "^1.2.0", "diff3": "0.0.3", "ignore": "^5.1.4", "minimisted": "^2.0.0", "pako": "^1.0.10", "path-browserify": "^1.0.1", "pify": "^4.0.1", "readable-stream": "^3.4.0", "sha.js": "^2.4.9", "simple-get": "^4.0.1" }, "bin": { "isogit": "cli.cjs" } }, "sha512-NZCS7qpLkCZ1M/IrujYBD31sM6pd/fMVArK4fz4I7h6m0rUW2AsYU7S7zXeABuHL6HIfW6l53b4UQ/K441CQjg=="], - "jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], "jiti": ["jiti@2.5.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w=="], @@ -1947,8 +1881,6 @@ "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], - "jsbn": ["jsbn@1.1.0", "", {}, "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="], - "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], @@ -1999,7 +1931,7 @@ "listhen": ["listhen@1.9.0", "", { "dependencies": { "@parcel/watcher": "^2.4.1", "@parcel/watcher-wasm": "^2.4.1", "citty": "^0.1.6", "clipboardy": "^4.0.0", "consola": "^3.2.3", "crossws": ">=0.2.0 <0.4.0", "defu": "^6.1.4", "get-port-please": "^3.1.2", "h3": "^1.12.0", "http-shutdown": "^1.2.2", "jiti": "^2.1.2", "mlly": "^1.7.1", "node-forge": "^1.3.1", "pathe": "^1.1.2", "std-env": "^3.7.0", "ufo": "^1.5.4", "untun": "^0.1.3", "uqr": "^0.1.2" }, "bin": { "listen": "bin/listhen.mjs", "listhen": "bin/listhen.mjs" } }, "sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg=="], - "local-pkg": ["local-pkg@1.1.1", "", { "dependencies": { "mlly": "^1.7.4", "pkg-types": "^2.0.1", "quansync": "^0.2.8" } }, "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg=="], + "local-pkg": ["local-pkg@1.1.2", "", { "dependencies": { "mlly": "^1.7.4", "pkg-types": "^2.3.0", "quansync": "^0.2.11" } }, "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A=="], "locate-path": ["locate-path@7.2.0", "", { "dependencies": { "p-locate": "^6.0.0" } }, "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA=="], @@ -2027,7 +1959,7 @@ "luxon": ["luxon@3.6.1", "", {}, "sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ=="], - "magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="], + "magic-string": ["magic-string@0.30.18", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ=="], "magicast": ["magicast@0.3.5", "", { "dependencies": { "@babel/parser": "^7.25.4", "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ=="], @@ -2179,14 +2111,12 @@ "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], - "miniflare": ["miniflare@4.20250730.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "acorn": "8.14.0", "acorn-walk": "8.3.2", "exit-hook": "2.2.1", "glob-to-regexp": "0.4.1", "sharp": "^0.33.5", "stoppable": "1.1.0", "undici": "^7.10.0", "workerd": "1.20250730.0", "ws": "8.18.0", "youch": "4.1.0-beta.10", "zod": "3.22.3" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-avGXBStHQSqcJr8ra1mJ3/OQvnLZ49B1uAILQapAha1DHNZZvXWLIgUVre/WGY6ZOlNGFPh5CJ+dXLm4yuV3Jw=="], + "miniflare": ["miniflare@4.20250823.1", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "acorn": "8.14.0", "acorn-walk": "8.3.2", "exit-hook": "2.2.1", "glob-to-regexp": "0.4.1", "sharp": "^0.33.5", "stoppable": "1.1.0", "undici": "^7.10.0", "workerd": "1.20250823.0", "ws": "8.18.0", "youch": "4.1.0-beta.10", "zod": "3.22.3" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-qjbF69XXyHXk4R//q0a9MLraKE9MLKZ/94k6jKcfouJ0g+se7VyMzCBryeWA534+ZAlNM4Ay5gqYr1v3Wk6ctQ=="], "minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="], "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], - "minimisted": ["minimisted@2.0.1", "", { "dependencies": { "minimist": "^1.2.5" } }, "sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA=="], - "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], "minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="], @@ -2205,7 +2135,7 @@ "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="], - "mlly": ["mlly@1.7.4", "", { "dependencies": { "acorn": "^8.14.0", "pathe": "^2.0.1", "pkg-types": "^1.3.0", "ufo": "^1.5.4" } }, "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw=="], + "mlly": ["mlly@1.8.0", "", { "dependencies": { "acorn": "^8.15.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.1" } }, "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g=="], "module-definition": ["module-definition@6.0.1", "", { "dependencies": { "ast-module-types": "^6.0.1", "node-source-walk": "^7.0.1" }, "bin": { "module-definition": "bin/cli.js" } }, "sha512-FeVc50FTfVVQnolk/WQT8MX+2WVcDnTGiq6Wo+/+lJ2ET1bRVi3HG3YlJUfqagNMc/kUlFSoR96AJkxGpKz13g=="], @@ -2239,7 +2169,7 @@ "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], - "node-fetch-native": ["node-fetch-native@1.6.6", "", {}, "sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ=="], + "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="], "node-forge": ["node-forge@1.3.1", "", {}, "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA=="], @@ -2291,7 +2221,7 @@ "ohash": ["ohash@1.1.6", "", {}, "sha512-TBu7PtV8YkAZn0tSxobKY2n2aAQva936lhRrj6957aDaCf9IEtqsKbgMzXE/F/sjqYOwmrukeORHNLe5glk7Cg=="], - "oidc-token-hash": ["oidc-token-hash@5.1.0", "", {}, "sha512-y0W+X7Ppo7oZX6eovsRkuzcSM40Bicg2JEJkDJ4irIt1wsYAP5MLSNv+QAogO8xivMffw/9OvV3um1pxXgt1uA=="], + "oidc-token-hash": ["oidc-token-hash@5.1.1", "", {}, "sha512-D7EmwxJV6DsEB6vOFLrBM2OzsVgQzgPWyHlV2OOAVj772n+WTXpudC9e9u5BVKQnYwaD30Ivhi9b+4UeBcGu9g=="], "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], @@ -2341,9 +2271,7 @@ "pagefind": ["pagefind@1.3.0", "", { "optionalDependencies": { "@pagefind/darwin-arm64": "1.3.0", "@pagefind/darwin-x64": "1.3.0", "@pagefind/linux-arm64": "1.3.0", "@pagefind/linux-x64": "1.3.0", "@pagefind/windows-x64": "1.3.0" }, "bin": { "pagefind": "lib/runner/bin.cjs" } }, "sha512-8KPLGT5g9s+olKMRTU9LFekLizkVIu9tes90O1/aigJ0T5LmyPqTzGJrETnSw3meSYg58YH7JTzhTTW/3z6VAw=="], - "pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], - - "parse-code-context": ["parse-code-context@1.0.0", "", {}, "sha512-OZQaqKaQnR21iqhlnPfVisFjBWjhnMl5J9MgbP8xC+EwoVqbXrq78lp+9Zb3ahmLzrIX5Us/qbvBnaS3hkH6OA=="], + "pako": ["pako@0.2.9", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="], "parse-conflict-json": ["parse-conflict-json@3.0.1", "", { "dependencies": { "json-parse-even-better-errors": "^3.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" } }, "sha512-01TvEktc68vwbJOtWZluyWeVGWjP+bZwXtPDMQVbBKzbJ/vZBif0L69KH1+cHv1SZ6e0FKLvjyHe8mqsIqYOmw=="], @@ -2359,8 +2287,6 @@ "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], - "path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="], - "path-exists": ["path-exists@5.0.0", "", {}, "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ=="], "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], @@ -2379,18 +2305,10 @@ "perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="], - "pg-int8": ["pg-int8@1.0.1", "", {}, "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="], - - "pg-protocol": ["pg-protocol@1.10.3", "", {}, "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ=="], - - "pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], - "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], - "pify": ["pify@4.0.1", "", {}, "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="], - "pkce-challenge": ["pkce-challenge@5.0.0", "", {}, "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ=="], "pkg-dir": ["pkg-dir@7.0.0", "", { "dependencies": { "find-up": "^6.3.0" } }, "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA=="], @@ -2409,14 +2327,6 @@ "postgres": ["postgres@3.4.7", "", {}, "sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw=="], - "postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], - - "postgres-bytea": ["postgres-bytea@1.0.0", "", {}, "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w=="], - - "postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], - - "postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], - "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="], "precinct": ["precinct@12.2.0", "", { "dependencies": { "@dependents/detective-less": "^5.0.1", "commander": "^12.1.0", "detective-amd": "^6.0.1", "detective-cjs": "^6.0.1", "detective-es6": "^5.0.1", "detective-postcss": "^7.0.1", "detective-sass": "^6.0.1", "detective-scss": "^5.0.1", "detective-stylus": "^5.0.1", "detective-typescript": "^14.0.0", "detective-vue2": "^2.2.0", "module-definition": "^6.0.1", "node-source-walk": "^7.0.1", "postcss": "^8.5.1", "typescript": "^5.7.3" }, "bin": { "precinct": "bin/cli.js" } }, "sha512-NFBMuwIfaJ4SocE9YXPU/n4AcNSoFMVFjP72nvl3cx69j/ke61/hPOWFREVxLkFhhEGnA8ZuVfTqJBa+PK3b5w=="], @@ -2447,7 +2357,7 @@ "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], - "protobufjs": ["protobufjs@7.5.3", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw=="], + "protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="], "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], @@ -2459,7 +2369,7 @@ "qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="], - "quansync": ["quansync@0.2.10", "", {}, "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A=="], + "quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="], "querystring": ["querystring@0.2.0", "", {}, "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g=="], @@ -2489,7 +2399,7 @@ "read-pkg": ["read-pkg@9.0.1", "", { "dependencies": { "@types/normalize-package-data": "^2.4.3", "normalize-package-data": "^6.0.0", "parse-json": "^8.0.0", "type-fest": "^4.6.0", "unicorn-magic": "^0.1.0" } }, "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA=="], - "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], "readdir-glob": ["readdir-glob@1.1.3", "", { "dependencies": { "minimatch": "^5.1.0" } }, "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA=="], @@ -2583,7 +2493,7 @@ "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - "rollup": ["rollup@4.46.2", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.46.2", "@rollup/rollup-android-arm64": "4.46.2", "@rollup/rollup-darwin-arm64": "4.46.2", "@rollup/rollup-darwin-x64": "4.46.2", "@rollup/rollup-freebsd-arm64": "4.46.2", "@rollup/rollup-freebsd-x64": "4.46.2", "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", "@rollup/rollup-linux-arm-musleabihf": "4.46.2", "@rollup/rollup-linux-arm64-gnu": "4.46.2", "@rollup/rollup-linux-arm64-musl": "4.46.2", "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", "@rollup/rollup-linux-ppc64-gnu": "4.46.2", "@rollup/rollup-linux-riscv64-gnu": "4.46.2", "@rollup/rollup-linux-riscv64-musl": "4.46.2", "@rollup/rollup-linux-s390x-gnu": "4.46.2", "@rollup/rollup-linux-x64-gnu": "4.46.2", "@rollup/rollup-linux-x64-musl": "4.46.2", "@rollup/rollup-win32-arm64-msvc": "4.46.2", "@rollup/rollup-win32-ia32-msvc": "4.46.2", "@rollup/rollup-win32-x64-msvc": "4.46.2", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg=="], + "rollup": ["rollup@4.49.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.49.0", "@rollup/rollup-android-arm64": "4.49.0", "@rollup/rollup-darwin-arm64": "4.49.0", "@rollup/rollup-darwin-x64": "4.49.0", "@rollup/rollup-freebsd-arm64": "4.49.0", "@rollup/rollup-freebsd-x64": "4.49.0", "@rollup/rollup-linux-arm-gnueabihf": "4.49.0", "@rollup/rollup-linux-arm-musleabihf": "4.49.0", "@rollup/rollup-linux-arm64-gnu": "4.49.0", "@rollup/rollup-linux-arm64-musl": "4.49.0", "@rollup/rollup-linux-loongarch64-gnu": "4.49.0", "@rollup/rollup-linux-ppc64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-gnu": "4.49.0", "@rollup/rollup-linux-riscv64-musl": "4.49.0", "@rollup/rollup-linux-s390x-gnu": "4.49.0", "@rollup/rollup-linux-x64-gnu": "4.49.0", "@rollup/rollup-linux-x64-musl": "4.49.0", "@rollup/rollup-win32-arm64-msvc": "4.49.0", "@rollup/rollup-win32-ia32-msvc": "4.49.0", "@rollup/rollup-win32-x64-msvc": "4.49.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA=="], "rollup-plugin-visualizer": ["rollup-plugin-visualizer@6.0.3", "", { "dependencies": { "open": "^8.0.0", "picomatch": "^4.0.2", "source-map": "^0.7.4", "yargs": "^17.5.1" }, "peerDependencies": { "rolldown": "1.x || ^1.0.0-beta", "rollup": "2.x || 3.x || 4.x" }, "optionalPeers": ["rolldown", "rollup"], "bin": { "rollup-plugin-visualizer": "dist/bin/cli.js" } }, "sha512-ZU41GwrkDcCpVoffviuM9Clwjy5fcUxlz0oMoTXTYsK+tcIFzbdacnrr2n8TXcHxbGKKXtOdjxM2HUS4HjkwIw=="], @@ -2627,8 +2537,6 @@ "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], - "sha.js": ["sha.js@2.4.12", "", { "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.0" }, "bin": { "sha.js": "bin.js" } }, "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w=="], - "sharp": ["sharp@0.32.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.2", "node-addon-api": "^6.1.0", "prebuild-install": "^7.1.1", "semver": "^7.5.4", "simple-get": "^4.0.1", "tar-fs": "^3.0.4", "tunnel-agent": "^0.6.0" } }, "sha512-0dap3iysgDkNaPOaOL4X/0akdu0ma62GcdC2NBQ+93eqpePdDdr2/LM0sFdDSMmN7yS+odyZtPsb7tx/cYBKnQ=="], "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], @@ -2669,19 +2577,13 @@ "smob": ["smob@1.5.0", "", {}, "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig=="], - "smol-toml": ["smol-toml@1.4.1", "", {}, "sha512-CxdwHXyYTONGHThDbq5XdwbFsuY4wlClRGejfE2NtwUtiHYsP1QtNsHb/hnj31jKYSchztJsaA8pSQoVzkfCFg=="], + "smol-toml": ["smol-toml@1.4.2", "", {}, "sha512-rInDH6lCNiEyn3+hH8KVGFdbjc099j47+OSgbMrfDYX1CmXLfdKd7qi6IfcWj2wFxvSVkuI46M+wPGYfEOEj6g=="], - "socks": ["socks@2.8.6", "", { "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" } }, "sha512-pe4Y2yzru68lXCb38aAqRf5gvN8YdjP1lok5o0J7BOHljkyCGKVz7H3vpVIXKD27rj2giOJ7DwVyk/GWrPHDWA=="], + "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], "socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], - "solid-js": ["solid-js@1.9.7", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", "seroval-plugins": "~1.3.0" } }, "sha512-/saTKi8iWEM233n5OSi1YHCCuh66ZIQ7aK2hsToPe4tqGm7qAejU1SwNuTPivbWAYq7SjuHVVYxxuZQNRbICiw=="], - - "solid-list": ["solid-list@0.3.0", "", { "dependencies": { "@corvu/utils": "~0.4.0" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-t4hx/F/l8Vmq+ib9HtZYl7Z9F1eKxq3eKJTXlvcm7P7yI4Z8O7QSOOEVHb/K6DD7M0RxzVRobK/BS5aSfLRwKg=="], - - "solid-presence": ["solid-presence@0.1.8", "", { "dependencies": { "@corvu/utils": "~0.4.0" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-pWGtXUFWYYUZNbg5YpG5vkQJyOtzn2KXhxYaMx/4I+lylTLYkITOLevaCwMRN+liCVk0pqB6EayLWojNqBFECA=="], - - "solid-prevent-scroll": ["solid-prevent-scroll@0.1.10", "", { "dependencies": { "@corvu/utils": "~0.4.1" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-KplGPX2GHiWJLZ6AXYRql4M127PdYzfwvLJJXMkO+CMb8Np4VxqDAg5S8jLdwlEuBis/ia9DKw2M8dFx5u8Mhw=="], + "solid-js": ["solid-js@1.9.9", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", "seroval-plugins": "~1.3.0" } }, "sha512-A0ZBPJQldAeGCTW0YRYJmt7RCeh5rbFfPZ2aOttgYnctHE7HgKeHCBB/PVc2P7eOfmNXqMFFFoYYdm3S4dcbkA=="], "solid-refresh": ["solid-refresh@0.6.3", "", { "dependencies": { "@babel/generator": "^7.23.6", "@babel/helper-module-imports": "^7.22.15", "@babel/types": "^7.23.6" }, "peerDependencies": { "solid-js": "^1.3" } }, "sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA=="], @@ -2707,23 +2609,23 @@ "ssri": ["ssri@10.0.6", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ=="], - "sst": ["sst@3.17.8", "", { "dependencies": { "aws-sdk": "2.1692.0", "aws4fetch": "1.0.18", "jose": "5.2.3", "opencontrol": "0.0.6", "openid-client": "5.6.4" }, "optionalDependencies": { "sst-darwin-arm64": "3.17.8", "sst-darwin-x64": "3.17.8", "sst-linux-arm64": "3.17.8", "sst-linux-x64": "3.17.8", "sst-linux-x86": "3.17.8", "sst-win32-arm64": "3.17.8", "sst-win32-x64": "3.17.8", "sst-win32-x86": "3.17.8" }, "bin": { "sst": "bin/sst.mjs" } }, "sha512-P/a9/ZsjtQRrTBerBMO1ODaVa5HVTmNLrQNJiYvu2Bgd0ov+vefQeHv6oima8HLlPwpDIPS2gxJk8BZrTZMfCA=="], + "sst": ["sst@3.17.12", "", { "dependencies": { "aws-sdk": "2.1692.0", "aws4fetch": "1.0.18", "jose": "5.2.3", "opencontrol": "0.0.6", "openid-client": "5.6.4" }, "optionalDependencies": { "sst-darwin-arm64": "3.17.12", "sst-darwin-x64": "3.17.12", "sst-linux-arm64": "3.17.12", "sst-linux-x64": "3.17.12", "sst-linux-x86": "3.17.12", "sst-win32-arm64": "3.17.12", "sst-win32-x64": "3.17.12", "sst-win32-x86": "3.17.12" }, "bin": { "sst": "bin/sst.mjs" } }, "sha512-UwUbucNZRLp9GHgPAwkat1sBsNGaJfHsLXZHCMKsolCW7CEuugJfvBl2vOyJrhKP4N+Xnv1QFh0BGsOmN0kQeA=="], - "sst-darwin-arm64": ["sst-darwin-arm64@3.17.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-50P6YRMnZVItZUfB0+NzqMww2mmm4vB3zhTVtWUtGoXeiw78g1AEnVlmS28gYXPHM1P987jTvR7EON9u9ig/Dg=="], + "sst-darwin-arm64": ["sst-darwin-arm64@3.17.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-9Oky2ZmJoeEN97ALWtFRt3kvSIZLjYoQoOtJvTaNQJTFi/9OsUE/6I5zdedf5GhMKCT1JvY+Ngpv3U3Y6SEYOg=="], - "sst-darwin-x64": ["sst-darwin-x64@3.17.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-P0pnMHCmpkpcsxkWpilmeoD79LkbkoIcv6H0aeM9ArT/71/JBhvqH+HjMHSJCzni/9uR6er+nH5F+qol0UO6Bw=="], + "sst-darwin-x64": ["sst-darwin-x64@3.17.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-n6tWCjFF9Pb+QzxXJmuTGfQ4GW96Nf6ATtb7Wpa+9RDLRHrEBdOjXAp7osr7MB9djPRkt4942nwUZ7wX/EULpg=="], - "sst-linux-arm64": ["sst-linux-arm64@3.17.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-vun54YA/UzprCu9p8BC4rMwFU5Cj9xrHAHYLYUp/yq4H0pfmBIiQM62nsfIKizRThe/TkBFy60EEi9myf6raYA=="], + "sst-linux-arm64": ["sst-linux-arm64@3.17.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-iMflBzQWhF5kmRdXu402dwVpQI9LfFR3yFok3HUTV0ema5Pq2kPphEatEEw1dyG2ZXCBLeKN+T3Ujjfer+ddRA=="], - "sst-linux-x64": ["sst-linux-x64@3.17.8", "", { "os": "linux", "cpu": "x64" }, "sha512-HqByCaLE2gEJbM20P1QRd+GqDMAiieuU53FaZA1F+AGxQi+kR82NWjrPqFcMj4dMYg8w/TWXuV+G5+PwoUmpDw=="], + "sst-linux-x64": ["sst-linux-x64@3.17.12", "", { "os": "linux", "cpu": "x64" }, "sha512-89rZXs3IfGrY9yiDNuLfcJvHnAUX1gRVeB+lqQ1M2sbJD2iMpN+fx93owcApAndtZYzYNfQYEZ/xYwI6HFfu4w=="], - "sst-linux-x86": ["sst-linux-x86@3.17.8", "", { "os": "linux", "cpu": "none" }, "sha512-bCd6QM3MejfSmdvg8I/k+aUJQIZEQJg023qmN78fv00vwlAtfECvY7tjT9E2m3LDp33pXrcRYbFOQzPu+tWFfA=="], + "sst-linux-x86": ["sst-linux-x86@3.17.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zc2nd2syaq/DfNxtDcn4NOh8RBCaCZ1qsjLFpvGGfMMRnGiWjofuE6eFX3fhchGL3uvaqwlENvtzj4UC/MF5wQ=="], - "sst-win32-arm64": ["sst-win32-arm64@3.17.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-pilx0n8gm4aHJae/vNiqIwZkWF3tdwWzD/ON7hkytw+CVSZ0FXtyFW/yO/+2u3Yw0Kj0lSWPnUqYgm/eHPLwQA=="], + "sst-win32-arm64": ["sst-win32-arm64@3.17.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-Bb7M6PoImmGeyzJu75QbNHBs0mDp21DsKFyMucn2dwxYwahuFPjjMbG+tlziWtxcNgdZMdEcy9jR8ot1jAIh0Q=="], - "sst-win32-x64": ["sst-win32-x64@3.17.8", "", { "os": "win32", "cpu": "x64" }, "sha512-Jb0FVRyiOtESudF1V8ucW65PuHrx/iOHUamIO0JnbujWNHZBTRPB2QHN1dbewgkueYDaCmyS8lvuIImLwYJnzQ=="], + "sst-win32-x64": ["sst-win32-x64@3.17.12", "", { "os": "win32", "cpu": "x64" }, "sha512-7f41o1WhxdcuLhHijoavkX5O3L/Pnma6zCoL3kG6f9Njc6Zyj8Oha2fQz6Tesb/Qt8deG04WU4bL3FmxgNHU6g=="], - "sst-win32-x86": ["sst-win32-x86@3.17.8", "", { "os": "win32", "cpu": "none" }, "sha512-oVmFa/PoElQmfnGJlB0w6rPXiYuldiagO6AbrLMT/6oAnWerLQ8Uhv9tJWfMh3xtPLImQLTjxDo1v0AIzEv9QA=="], + "sst-win32-x86": ["sst-win32-x86@3.17.12", "", { "os": "win32", "cpu": "none" }, "sha512-AfsNJQMTlefHitaVRWh5Uf3AaICIaomFbSo5qDbibgkvhbppCxgMFpW0IxiWySjWrCN5hMMkxdxlZP9IHqqxjQ=="], "stack-trace": ["stack-trace@0.0.10", "", {}, "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg=="], @@ -2769,7 +2671,7 @@ "style-to-object": ["style-to-object@1.0.9", "", { "dependencies": { "inline-style-parser": "0.2.4" } }, "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw=="], - "supports-color": ["supports-color@10.0.0", "", {}, "sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ=="], + "supports-color": ["supports-color@10.2.0", "", {}, "sha512-5eG9FQjEjDbAlI5+kdpdyPIBMRH4GfTVDGREVupaZHmVoppknhM29b/S9BkQz7cathp85BVgRi/As3Siln7e0Q=="], "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], @@ -2797,12 +2699,10 @@ "tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="], - "tmp": ["tmp@0.2.4", "", {}, "sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ=="], + "tmp": ["tmp@0.2.5", "", {}, "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow=="], "tmp-promise": ["tmp-promise@3.0.3", "", { "dependencies": { "tmp": "^0.2.0" } }, "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ=="], - "to-buffer": ["to-buffer@1.2.1", "", { "dependencies": { "isarray": "^2.0.5", "safe-buffer": "^5.2.1", "typed-array-buffer": "^1.0.3" } }, "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ=="], - "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], "toad-cache": ["toad-cache@3.7.0", "", {}, "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw=="], @@ -2843,8 +2743,6 @@ "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], - "typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="], - "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], "ufo": ["ufo@1.6.1", "", {}, "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA=="], @@ -2859,7 +2757,7 @@ "unctx": ["unctx@2.4.1", "", { "dependencies": { "acorn": "^8.14.0", "estree-walker": "^3.0.3", "magic-string": "^0.30.17", "unplugin": "^2.1.0" } }, "sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg=="], - "undici": ["undici@7.13.0", "", {}, "sha512-l+zSMssRqrzDcb3fjMkjjLGmuiiK2pMIcV++mJaAc9vhjSGpvM7h43QgP+OAMb1GImHmbPyG2tBXeuyG5iY4gA=="], + "undici": ["undici@7.15.0", "", {}, "sha512-7oZJCPvvMvTd0OlqWsIxTuItTpJBpU1tcbVl24FMn3xt3+VSunwUasmfPJRE57oNO1KsZ4PgA1xTdAX4hq8NyQ=="], "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], @@ -2909,17 +2807,17 @@ "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], - "unplugin": ["unplugin@2.3.5", "", { "dependencies": { "acorn": "^8.14.1", "picomatch": "^4.0.2", "webpack-virtual-modules": "^0.6.2" } }, "sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw=="], + "unplugin": ["unplugin@2.3.9", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-2dcbZq6aprwXTkzptq3k5qm5B8cvpjG9ynPd5fyM2wDJuuF7PeUK64Sxf0d+X1ZyDOeGydbNzMqBSIVlH8GIfA=="], "unplugin-utils": ["unplugin-utils@0.2.5", "", { "dependencies": { "pathe": "^2.0.3", "picomatch": "^4.0.3" } }, "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg=="], - "unstorage": ["unstorage@1.16.1", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^4.0.3", "destr": "^2.0.5", "h3": "^1.15.3", "lru-cache": "^10.4.3", "node-fetch-native": "^1.6.6", "ofetch": "^1.4.1", "ufo": "^1.6.1" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-gdpZ3guLDhz+zWIlYP1UwQ259tG5T5vYRzDaHMkQ1bBY1SQPutvZnrRjTFaWUUpseErJIgAZS51h6NOcZVZiqQ=="], + "unstorage": ["unstorage@1.17.0", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^4.0.3", "destr": "^2.0.5", "h3": "^1.15.4", "lru-cache": "^10.4.3", "node-fetch-native": "^1.6.7", "ofetch": "^1.4.1", "ufo": "^1.6.1" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-l9Z7lBiwtNp8ZmcoZ/dmPkFXFdtEdZtTZafCSnEIj3YvtkXeGAtL2rN8MQFy/0cs4eOLpuRJMp9ivdug7TCvww=="], "untun": ["untun@0.1.3", "", { "dependencies": { "citty": "^0.1.5", "consola": "^3.2.3", "pathe": "^1.1.1" }, "bin": { "untun": "bin/untun.mjs" } }, "sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ=="], "untyped": ["untyped@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "defu": "^6.1.4", "jiti": "^2.4.2", "knitwork": "^1.2.0", "scule": "^1.3.0" }, "bin": { "untyped": "dist/cli.mjs" } }, "sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g=="], - "unwasm": ["unwasm@0.3.9", "", { "dependencies": { "knitwork": "^1.0.0", "magic-string": "^0.30.8", "mlly": "^1.6.1", "pathe": "^1.1.2", "pkg-types": "^1.0.3", "unplugin": "^1.10.0" } }, "sha512-LDxTx/2DkFURUd+BU1vUsF/moj0JsoTvl+2tcg2AUOiEzVturhGGx17/IMgGvKUYdZwr33EJHtChCJuhu9Ouvg=="], + "unwasm": ["unwasm@0.3.11", "", { "dependencies": { "knitwork": "^1.2.0", "magic-string": "^0.30.17", "mlly": "^1.7.4", "pathe": "^2.0.3", "pkg-types": "^2.2.0", "unplugin": "^2.3.6" } }, "sha512-Vhp5gb1tusSQw5of/g3Q697srYgMXvwMgXMjcG4ZNga02fDX9coxJ9fAb0Ci38hM2Hv/U1FXRPGgjP2BYqhNoQ=="], "upath": ["upath@1.2.0", "", {}, "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="], @@ -2955,9 +2853,7 @@ "vinxi": ["vinxi@0.5.8", "", { "dependencies": { "@babel/core": "^7.22.11", "@babel/plugin-syntax-jsx": "^7.22.5", "@babel/plugin-syntax-typescript": "^7.22.5", "@types/micromatch": "^4.0.2", "@vinxi/listhen": "^1.5.6", "boxen": "^8.0.1", "chokidar": "^4.0.3", "citty": "^0.1.6", "consola": "^3.4.2", "crossws": "^0.3.4", "dax-sh": "^0.43.0", "defu": "^6.1.4", "es-module-lexer": "^1.7.0", "esbuild": "^0.25.3", "get-port-please": "^3.1.2", "h3": "1.15.3", "hookable": "^5.5.3", "http-proxy": "^1.18.1", "micromatch": "^4.0.8", "nitropack": "^2.11.10", "node-fetch-native": "^1.6.6", "path-to-regexp": "^6.2.1", "pathe": "^1.1.1", "radix3": "^1.1.2", "resolve": "^1.22.10", "serve-placeholder": "^2.0.1", "serve-static": "^1.15.0", "tinyglobby": "^0.2.14", "ufo": "^1.6.1", "unctx": "^2.4.1", "unenv": "^1.10.0", "unstorage": "^1.16.0", "vite": "^6.3.3", "zod": "^3.24.3" }, "bin": { "vinxi": "bin/cli.mjs" } }, "sha512-1pGA+cU1G9feBQ1sd5FMftPuLUT8NSX880AvELhNWqoqWhe2jeSOQxjDPxlA3f1AC+Bbknl4UPKHyVXmfLZQjw=="], - "vite": ["vite@6.2.2", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "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" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ=="], - - "vite-plugin-pages": ["vite-plugin-pages@0.32.5", "", { "dependencies": { "@types/debug": "^4.1.12", "debug": "^4.4.0", "dequal": "^2.0.3", "extract-comments": "^1.1.0", "fast-glob": "^3.3.3", "json5": "^2.2.3", "local-pkg": "^1.0.0", "picocolors": "^1.1.1", "yaml": "^2.7.0" }, "peerDependencies": { "@vue/compiler-sfc": "^2.7.0 || ^3.0.0", "vite": "^2.0.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0 || ^6.0.0" }, "optionalPeers": ["@vue/compiler-sfc"] }, "sha512-GY2JAt+4vZ4BqTtw+4CSUxPgYiqamrMRIzYk2AtJvQHeBoMlctsQW+tgCpKriUKINiKfi6NegbP07r1XrdxTWA=="], + "vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "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" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="], "vite-plugin-solid": ["vite-plugin-solid@2.11.6", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "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" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-Sl5CTqJTGyEeOsmdH6BOgalIZlwH3t4/y0RQuFLMGnvWMBvxb4+lq7x3BSiAw6etf0QexfNJW7HSOO/Qf7pigg=="], @@ -2995,9 +2891,9 @@ "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="], - "workerd": ["workerd@1.20250730.0", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20250730.0", "@cloudflare/workerd-darwin-arm64": "1.20250730.0", "@cloudflare/workerd-linux-64": "1.20250730.0", "@cloudflare/workerd-linux-arm64": "1.20250730.0", "@cloudflare/workerd-windows-64": "1.20250730.0" }, "bin": { "workerd": "bin/workerd" } }, "sha512-w6e0WM2YGfYQGmg0dewZeLUYIxAzMYK1R31vaS4HHHjgT32Xqj0eVQH+leegzY51RZPNCvw5pe8DFmW4MGf8Fg=="], + "workerd": ["workerd@1.20250823.0", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20250823.0", "@cloudflare/workerd-darwin-arm64": "1.20250823.0", "@cloudflare/workerd-linux-64": "1.20250823.0", "@cloudflare/workerd-linux-arm64": "1.20250823.0", "@cloudflare/workerd-windows-64": "1.20250823.0" }, "bin": { "workerd": "bin/workerd" } }, "sha512-95lToK9zeaC7bX5ZmlP/wz6zqoUPBk3hhec1JjEMGZrxsXY9cPRkjWNCcjDctQ17U97vjMcY/ymchgx7w8Cfmg=="], - "wrangler": ["wrangler@4.27.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.0", "@cloudflare/unenv-preset": "2.5.0", "blake3-wasm": "2.1.5", "esbuild": "0.25.4", "miniflare": "4.20250730.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.19", "workerd": "1.20250730.0" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20250730.0" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-YNHZyMNWebFt9jD6dc20tQrCmnSzJj3SoB0FFa90w11Cx4lbP3d+rUZYjb18Zt+OGSMay1wT2PzwT2vCTskkmg=="], + "wrangler": ["wrangler@4.33.1", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.0", "@cloudflare/unenv-preset": "2.7.0", "blake3-wasm": "2.1.5", "esbuild": "0.25.4", "miniflare": "4.20250823.1", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.19", "workerd": "1.20250823.0" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20250823.0" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-8x/3Tbt+/raBMm0+vRyAHSGu2kF1QjeiSrx47apgPk/AzSBcXI9YuUUdGrKnozMYZlEbOxdBQOMyuRRDTyNmOg=="], "wrap-ansi": ["wrap-ansi@9.0.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q=="], @@ -3015,8 +2911,6 @@ "xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="], - "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], - "xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="], "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], @@ -3035,7 +2929,7 @@ "yocto-spinner": ["yocto-spinner@0.2.3", "", { "dependencies": { "yoctocolors": "^2.1.1" } }, "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ=="], - "yoctocolors": ["yoctocolors@2.1.1", "", {}, "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ=="], + "yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="], "youch": ["youch@4.1.0-beta.8", "", { "dependencies": { "@poppinss/colors": "^4.1.4", "@poppinss/dumper": "^0.6.3", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.1" } }, "sha512-rY2A2lSF7zC+l7HH9Mq+83D1dLlsPnEvy8jTouzaptDZM6geqZ3aJe/b7ULCwRURPtWV3vbDjA2DDMdoBol0HQ=="], @@ -3061,70 +2955,16 @@ "@ai-sdk/gateway/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.1", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.3", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-/iP1sKc6UdJgGH98OCly7sWJKv+J9G47PnTjIj40IJMUQKwDrUMyf7zOOfRtPwSuNifYhSoJQ4s1WltI65gJ/g=="], - "@astrojs/cloudflare/vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "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" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="], - "@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="], - "@astrojs/mdx/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.3", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.2.1", "smol-toml": "^1.3.4", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-DDRtD1sPvAuA7ms2btc9A7/7DApKqgLMNrE6kh5tmkfy8utD0Z738gqd3p5aViYYdUtHIyEJ1X4mCMxfCfu15w=="], + "@astrojs/mdx/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.6", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.2", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.2.1", "smol-toml": "^1.3.4", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-bwylYktCTsLMVoCOEHbn2GSUA3c5KT/qilekBKA3CBng0bo1TYjNZPr761vxumRk9kJGqTOtU+fgCAp5Vwokug=="], "@astrojs/mdx/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], - "@astrojs/solid-js/vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "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" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="], - - "@astrojs/solid-js/vite-plugin-solid": ["vite-plugin-solid@2.11.8", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "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 || ^7.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-hFrCxBfv3B1BmFqnJF4JOCYpjrmi/zwyeKjcomQ0khh8HFyQ8SbuBWQ7zGojfrz6HUOBFrJBNySDi/JgAHytWg=="], - - "@aws-crypto/crc32/@aws-sdk/types": ["@aws-sdk/types@3.840.0", "", { "dependencies": { "@smithy/types": "^4.3.1", "tslib": "^2.6.2" } }, "sha512-xliuHaUFZxEx1NSXeLLZ9Dyu6+EJVQKEoD+yM+zqUo3YDZ7medKJWY6fIOKiPX/N7XbLdBYwajb15Q7IL8KkeA=="], - - "@aws-crypto/sha256-browser/@aws-sdk/types": ["@aws-sdk/types@3.840.0", "", { "dependencies": { "@smithy/types": "^4.3.1", "tslib": "^2.6.2" } }, "sha512-xliuHaUFZxEx1NSXeLLZ9Dyu6+EJVQKEoD+yM+zqUo3YDZ7medKJWY6fIOKiPX/N7XbLdBYwajb15Q7IL8KkeA=="], - "@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], - "@aws-crypto/sha256-js/@aws-sdk/types": ["@aws-sdk/types@3.840.0", "", { "dependencies": { "@smithy/types": "^4.3.1", "tslib": "^2.6.2" } }, "sha512-xliuHaUFZxEx1NSXeLLZ9Dyu6+EJVQKEoD+yM+zqUo3YDZ7medKJWY6fIOKiPX/N7XbLdBYwajb15Q7IL8KkeA=="], - - "@aws-crypto/util/@aws-sdk/types": ["@aws-sdk/types@3.840.0", "", { "dependencies": { "@smithy/types": "^4.3.1", "tslib": "^2.6.2" } }, "sha512-xliuHaUFZxEx1NSXeLLZ9Dyu6+EJVQKEoD+yM+zqUo3YDZ7medKJWY6fIOKiPX/N7XbLdBYwajb15Q7IL8KkeA=="], - "@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], - "@aws-sdk/client-sso/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/core/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/credential-provider-env/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/credential-provider-http/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/credential-provider-ini/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/credential-provider-node/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/credential-provider-process/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/credential-provider-sso/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/credential-provider-web-identity/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/middleware-host-header/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/middleware-logger/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/middleware-recursion-detection/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/middleware-user-agent/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/nested-clients/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/region-config-resolver/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/token-providers/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/types/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/util-endpoints/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/util-user-agent-browser/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@aws-sdk/util-user-agent-node/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - "@babel/core/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], @@ -3133,14 +2973,8 @@ "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@babel/helper-create-class-features-plugin/@babel/traverse": ["@babel/traverse@7.28.3", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", "@babel/types": "^7.28.2", "debug": "^4.3.1" } }, "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ=="], - "@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@babel/helper-member-expression-to-functions/@babel/traverse": ["@babel/traverse@7.28.3", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", "@babel/types": "^7.28.2", "debug": "^4.3.1" } }, "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ=="], - - "@babel/helper-replace-supers/@babel/traverse": ["@babel/traverse@7.28.3", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", "@babel/types": "^7.28.2", "debug": "^4.3.1" } }, "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ=="], - "@babel/template/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], "@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], @@ -3175,7 +3009,7 @@ "@netlify/zip-it-and-ship-it/@babel/types": ["@babel/types@7.28.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg=="], - "@netlify/zip-it-and-ship-it/@netlify/serverless-functions-api": ["@netlify/serverless-functions-api@2.2.0", "", {}, "sha512-eQNnGUMyatgEeFJ8iKI2DT7wXDEjbWmZ+hJpCZtfg1bVsD4JdprIhLqdrUqmrDgPG2r45sQYigO9oq8BWXO37w=="], + "@netlify/zip-it-and-ship-it/@netlify/serverless-functions-api": ["@netlify/serverless-functions-api@2.3.0", "", {}, "sha512-eSC+glm4bX+9t+ajNzAs4Bca0Q/xGLgcYYh6M2Z9Dcya/MjVod1UrjPB88b0ANSBAy/aGFpDhVbwLwBokfnppQ=="], "@netlify/zip-it-and-ship-it/esbuild": ["esbuild@0.25.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.5", "@esbuild/android-arm": "0.25.5", "@esbuild/android-arm64": "0.25.5", "@esbuild/android-x64": "0.25.5", "@esbuild/darwin-arm64": "0.25.5", "@esbuild/darwin-x64": "0.25.5", "@esbuild/freebsd-arm64": "0.25.5", "@esbuild/freebsd-x64": "0.25.5", "@esbuild/linux-arm": "0.25.5", "@esbuild/linux-arm64": "0.25.5", "@esbuild/linux-ia32": "0.25.5", "@esbuild/linux-loong64": "0.25.5", "@esbuild/linux-mips64el": "0.25.5", "@esbuild/linux-ppc64": "0.25.5", "@esbuild/linux-riscv64": "0.25.5", "@esbuild/linux-s390x": "0.25.5", "@esbuild/linux-x64": "0.25.5", "@esbuild/netbsd-arm64": "0.25.5", "@esbuild/netbsd-x64": "0.25.5", "@esbuild/openbsd-arm64": "0.25.5", "@esbuild/openbsd-x64": "0.25.5", "@esbuild/sunos-x64": "0.25.5", "@esbuild/win32-arm64": "0.25.5", "@esbuild/win32-ia32": "0.25.5", "@esbuild/win32-x64": "0.25.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ=="], @@ -3209,11 +3043,7 @@ "@openauthjs/openauth/jose": ["jose@5.9.6", "", {}, "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ=="], - "@openauthjs/solid/@openauthjs/openauth": ["@openauthjs/openauth@0.4.2", "", { "dependencies": { "@standard-schema/spec": "1.0.0-beta.3", "aws4fetch": "1.0.20", "jose": "5.9.6" }, "peerDependencies": { "arctic": "^2.2.2", "hono": "^4.0.0" } }, "sha512-8+Bia559iffrZXfQ0LWXrVVVriochS88pDtB8indyQ1S+40MQgDBu8aBzKt+fgSrTmoQGCTT+wlOXgbjc9qIcw=="], - - "@opencode-ai/sdk/@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.80.1", "", { "dependencies": { "@hey-api/json-schema-ref-parser": "1.0.6", "ansi-colors": "4.1.3", "c12": "2.0.1", "color-support": "1.1.3", "commander": "13.0.0", "handlebars": "4.7.8", "open": "10.1.2", "semver": "7.7.2" }, "peerDependencies": { "typescript": "^5.5.3" }, "bin": { "openapi-ts": "bin/index.cjs" } }, "sha512-AC478kg36vmmrseLZNFonZ/cmXXmDzW5yWz4PVg1S8ebJsRtVRJ/QU+mtnXfzf9avN2P0pz/AO4WAe4jyFY2gA=="], - - "@opencode/cloud-web/solid-js": ["solid-js@1.9.5", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "^1.1.0", "seroval-plugins": "^1.1.0" } }, "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw=="], + "@opencode/cloud-resource/@cloudflare/workers-types": ["@cloudflare/workers-types@4.20250830.0", "", {}, "sha512-uAGZFqEBFnCiwIokxMnrrtjIkT8qyGT1LACSScEUyW7nKmtD0Viykp9QZWrIlssyEp/MDB6XsdALF8y6upxpcg=="], "@opentelemetry/instrumentation-grpc/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.27.0", "", {}, "sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg=="], @@ -3237,76 +3067,14 @@ "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], - "@smithy/abort-controller/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/config-resolver/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/core/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - "@smithy/core/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], - "@smithy/credential-provider-imds/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/fetch-http-handler/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/hash-node/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/invalid-dependency/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/middleware-content-length/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/middleware-endpoint/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/middleware-retry/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - "@smithy/middleware-retry/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], - "@smithy/middleware-serde/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/middleware-stack/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/node-config-provider/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/node-http-handler/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/property-provider/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/protocol-http/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/querystring-builder/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/querystring-parser/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/service-error-classification/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/shared-ini-file-loader/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/signature-v4/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/smithy-client/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/url-parser/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/util-defaults-mode-browser/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/util-defaults-mode-node/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/util-endpoints/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/util-middleware/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/util-retry/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - - "@smithy/util-stream/@smithy/types": ["@smithy/types@4.3.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-QO4zghLxiQ5W9UZmX2Lo0nta2PuE1sSrXUYDoaB6HMR762C0P7v/HEPHf6ZdglTVssJG1bsrSBxdc3quvDSihw=="], - "@solidjs/start/shiki": ["shiki@1.29.2", "", { "dependencies": { "@shikijs/core": "1.29.2", "@shikijs/engine-javascript": "1.29.2", "@shikijs/engine-oniguruma": "1.29.2", "@shikijs/langs": "1.29.2", "@shikijs/themes": "1.29.2", "@shikijs/types": "1.29.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-njXuliz/cP+67jU2hukkxCNuH1yUi4QfdZZY+sMr5PPrIyXSu5iTb/qYC4BiWWB0vZ+7TbdvYUCeL23zpwCfbg=="], - "@solidjs/start/vite-plugin-solid": ["vite-plugin-solid@2.11.8", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "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 || ^7.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-hFrCxBfv3B1BmFqnJF4JOCYpjrmi/zwyeKjcomQ0khh8HFyQ8SbuBWQ7zGojfrz6HUOBFrJBNySDi/JgAHytWg=="], - "@tufjs/models/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], - "@types/bun/bun-types": ["bun-types@1.2.20", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-pxTnQYOrKvdOwyiyd/7sMt9yFOenN004Y6O4lCcCUoKVej48FS5cvTw9geRaEcB9TsDZaJKAxPTVvi8tFsVuXA=="], - "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "@vercel/nft/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], @@ -3319,6 +3087,8 @@ "@vinxi/server-components/magicast": ["magicast@0.2.11", "", { "dependencies": { "@babel/parser": "^7.22.16", "@babel/types": "^7.22.17", "recast": "^0.23.4" } }, "sha512-6saXbRDA1HMkqbsvHOU6HBjCVgZT460qheRkLhJQHWAbhXoWESI3Kn/dGGXyKs15FFKR85jsUqFx2sMK0wy/5g=="], + "@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "@vue/compiler-core/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], @@ -3331,22 +3101,18 @@ "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "archiver/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], - - "archiver-utils/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], - "astro/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="], "astro/diff": ["diff@5.2.0", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="], "astro/sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="], - "astro/vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "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" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="], - "babel-plugin-jsx-dom-expressions/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="], "bl/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], + "bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "cacache/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "cacheable-request/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], @@ -3357,10 +3123,6 @@ "colorspace/color": ["color@3.2.1", "", { "dependencies": { "color-convert": "^1.9.3", "color-string": "^1.6.0" } }, "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA=="], - "compress-commons/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], - - "crc32-stream/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], - "cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], "dax-sh/undici-types": ["undici-types@5.28.4", "", {}, "sha512-3OeMF5Lyowe8VW0skf5qaIE7Or3yS9LS7fvMUI0gg4YxpIBVg0L8BxCmROw2CcYhSkpR68Epz7CGc8MPj94Uww=="], @@ -3383,8 +3145,6 @@ "glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], - "globby/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "gray-matter/js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="], "hast-util-to-parse5/property-information": ["property-information@6.5.0", "", {}, "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="], @@ -3395,8 +3155,6 @@ "ignore-walk/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], - "ip-address/sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], - "lambda-local/commander": ["commander@10.0.1", "", {}, "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="], "lazystream/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], @@ -3405,7 +3163,7 @@ "listhen/h3": ["h3@1.15.4", "", { "dependencies": { "cookie-es": "^1.2.2", "crossws": "^0.3.5", "defu": "^6.1.4", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.2", "radix3": "^1.1.2", "ufo": "^1.6.1", "uncrypto": "^0.1.3" } }, "sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ=="], - "local-pkg/pkg-types": ["pkg-types@2.2.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ=="], + "local-pkg/pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="], "make-fetch-happen/negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="], @@ -3443,7 +3201,7 @@ "nitropack/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - "nitropack/pkg-types": ["pkg-types@2.2.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ=="], + "nitropack/pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="], "nitropack/serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="], @@ -3475,8 +3233,6 @@ "parse-json/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], - "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], - "path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "pkg-types/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], @@ -3491,6 +3247,10 @@ "read-pkg/unicorn-magic": ["unicorn-magic@0.1.0", "", {}, "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ=="], + "readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], + + "readable-stream/events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="], + "readdir-glob/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], "rollup-plugin-visualizer/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="], @@ -3533,21 +3293,17 @@ "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], - "to-buffer/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], - "tree-sitter/node-addon-api": ["node-addon-api@8.5.0", "", {}, "sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A=="], "tree-sitter-bash/node-addon-api": ["node-addon-api@8.5.0", "", {}, "sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A=="], "unenv/mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="], - "unicode-trie/pako": ["pako@0.2.9", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="], - "unifont/ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], "unimport/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - "unimport/pkg-types": ["pkg-types@2.2.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ=="], + "unimport/pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="], "unixify/normalize-path": ["normalize-path@2.1.1", "", { "dependencies": { "remove-trailing-separator": "^1.0.1" } }, "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w=="], @@ -3557,11 +3313,15 @@ "unstorage/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "unwasm/unplugin": ["unplugin@1.16.1", "", { "dependencies": { "acorn": "^8.14.0", "webpack-virtual-modules": "^0.6.2" } }, "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w=="], + "unwasm/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "unwasm/pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="], "uri-js/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], - "vinxi/vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "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" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="], + "winston/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + + "winston-transport/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], "wrangler/esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="], @@ -3575,15 +3335,11 @@ "write-file-atomic/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - "xml2js/sax": ["sax@1.4.1", "", {}, "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="], - "yargs/yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], "yauzl/buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="], - "zip-stream/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], - - "@astrojs/mdx/@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="], + "@astrojs/mdx/@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.7.2", "", {}, "sha512-KCkCqR3Goym79soqEtbtLzJfqhTWMyVaizUi35FLzgGSzBotSw8DB1qwsu7U96ihOJgYhDk2nVPz+3LnXPeX6g=="], "@astrojs/mdx/@astrojs/markdown-remark/@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="], @@ -3593,24 +3349,6 @@ "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], - "@babel/helper-create-class-features-plugin/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], - - "@babel/helper-create-class-features-plugin/@babel/traverse/@babel/generator": ["@babel/generator@7.28.3", "", { "dependencies": { "@babel/parser": "^7.28.3", "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw=="], - - "@babel/helper-create-class-features-plugin/@babel/traverse/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="], - - "@babel/helper-member-expression-to-functions/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], - - "@babel/helper-member-expression-to-functions/@babel/traverse/@babel/generator": ["@babel/generator@7.28.3", "", { "dependencies": { "@babel/parser": "^7.28.3", "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw=="], - - "@babel/helper-member-expression-to-functions/@babel/traverse/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="], - - "@babel/helper-replace-supers/@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], - - "@babel/helper-replace-supers/@babel/traverse/@babel/generator": ["@babel/generator@7.28.3", "", { "dependencies": { "@babel/parser": "^7.28.3", "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw=="], - - "@babel/helper-replace-supers/@babel/traverse/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="], - "@cloudflare/unenv-preset/unenv/ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], "@cloudflare/unenv-preset/unenv/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], @@ -3749,12 +3487,6 @@ "@netlify/zip-it-and-ship-it/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "@openauthjs/solid/@openauthjs/openauth/@standard-schema/spec": ["@standard-schema/spec@1.0.0-beta.3", "", {}, "sha512-0ifF3BjA1E8SY9C+nUew8RefNOIq0cDlYALPty4rhUm8Rrl6tCM8hBT4bhGhx7I7iXD0uAgt50lgo8dD73ACMw=="], - - "@openauthjs/solid/@openauthjs/openauth/aws4fetch": ["aws4fetch@1.0.20", "", {}, "sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g=="], - - "@openauthjs/solid/@openauthjs/openauth/jose": ["jose@5.9.6", "", {}, "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ=="], - "@pulumi/pulumi/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], "@solidjs/start/shiki/@shikijs/core": ["@shikijs/core@1.29.2", "", { "dependencies": { "@shikijs/engine-javascript": "1.29.2", "@shikijs/engine-oniguruma": "1.29.2", "@shikijs/types": "1.29.2", "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-vju0lY9r27jJfOY4Z7+Rt/nIOjzJpZ3y+nYpqtUZInVoXQ/TJZcfGnNOGnKjFdVZb8qexiCuSlZRKcGfhhTTZQ=="], @@ -3773,13 +3505,7 @@ "ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "archiver-utils/readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], - - "archiver-utils/readable-stream/events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="], - - "archiver/readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], - - "archiver/readable-stream/events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="], + "bl/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], "clipboardy/execa/get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="], @@ -3797,14 +3523,6 @@ "colorspace/color/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], - "compress-commons/readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], - - "compress-commons/readable-stream/events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="], - - "crc32-stream/readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], - - "crc32-stream/readable-stream/events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="], - "cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "drizzle-kit/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.19.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA=="], @@ -3885,6 +3603,8 @@ "prebuild-install/tar-fs/tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], + "readable-stream/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], + "rollup-plugin-visualizer/open/define-lazy-prop": ["define-lazy-prop@2.0.0", "", {}, "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og=="], "rollup-plugin-visualizer/open/is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], @@ -3903,6 +3623,8 @@ "unimport/pkg-types/confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="], + "unwasm/pkg-types/confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="], + "wrangler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="], "wrangler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="], @@ -3961,10 +3683,6 @@ "wrap-ansi-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "zip-stream/readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], - - "zip-stream/readable-stream/events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="], - "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], @@ -3993,22 +3711,16 @@ "ansi-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "archiver-utils/readable-stream/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - - "archiver/readable-stream/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "clipboardy/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], "clipboardy/execa/onetime/mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="], "colorspace/color/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], - "compress-commons/readable-stream/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - - "crc32-stream/readable-stream/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "nitropack/c12/giget/nypm": ["nypm@0.6.1", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.2", "pathe": "^2.0.3", "pkg-types": "^2.2.0", "tinyexec": "^1.0.1" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-hlacBiRiv1k9hZFiphPUkfSQ/ZfQzZDzC+8z0wL3lvDAOUu/2NnChkKuMoMjNur/9OpKuz2QsIeiPVN0xM5Q0w=="], + "prebuild-install/tar-fs/tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "rollup-plugin-visualizer/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "rollup-plugin-visualizer/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], @@ -4017,8 +3729,6 @@ "rollup-plugin-visualizer/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "zip-stream/readable-stream/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "@grpc/proto-loader/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "@grpc/proto-loader/yargs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], diff --git a/cloud/app/app.config.ts b/cloud/app/app.config.ts index 0ffa557f9..4dd799edc 100644 --- a/cloud/app/app.config.ts +++ b/cloud/app/app.config.ts @@ -5,5 +5,18 @@ export default defineConfig({ server: { allowedHosts: true, }, + build: { + rollupOptions: { + external: ["cloudflare:workers"], + }, + minify: false, + }, + }, + server: { + compatibilityDate: "2024-09-19", + preset: "cloudflare_module", + cloudflare: { + nodeCompat: true, + }, }, }) diff --git a/cloud/app/package.json b/cloud/app/package.json index 70705f02e..d8b9f22a6 100644 --- a/cloud/app/package.json +++ b/cloud/app/package.json @@ -3,9 +3,10 @@ "type": "module", "scripts": { "dev": "vinxi dev --host 0.0.0.0", + "dev:remote": "VITE_AUTH_URL=https://auth.dev.opencode.ai bun sst shell --stage=dev bun dev", "build": "vinxi build", "start": "vinxi start", - "version": "0.5.18" + "version": "0.5.29" }, "dependencies": { "@ibm/plex": "6.4.1", @@ -13,7 +14,7 @@ "@solidjs/meta": "^0.29.4", "@solidjs/router": "^0.15.0", "@solidjs/start": "^1.1.0", - "solid-js": "^1.9.5", + "solid-js": "catalog:", "vinxi": "^0.5.7", "@opencode/cloud-core": "workspace:*" }, diff --git a/cloud/app/public/favicon.ico b/cloud/app/public/favicon.ico deleted file mode 100644 index fb282da07..000000000 Binary files a/cloud/app/public/favicon.ico and /dev/null differ diff --git a/cloud/app/public/favicon.svg b/cloud/app/public/favicon.svg new file mode 100644 index 000000000..3c81bbdb4 --- /dev/null +++ b/cloud/app/public/favicon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/cloud/app/public/social-share.png b/cloud/app/public/social-share.png new file mode 100644 index 000000000..97f67994d Binary files /dev/null and b/cloud/app/public/social-share.png differ diff --git a/cloud/app/src/app.tsx b/cloud/app/src/app.tsx index 504318995..54bb6f4a3 100644 --- a/cloud/app/src/app.tsx +++ b/cloud/app/src/app.tsx @@ -1,4 +1,4 @@ -import { MetaProvider, Title } from "@solidjs/meta"; +import { MetaProvider, Title, Meta } from "@solidjs/meta"; import { Router } from "@solidjs/router"; import { FileRoutes } from "@solidjs/start/router"; import { ErrorBoundary, Suspense } from "solid-js"; @@ -10,10 +10,9 @@ export default function App() { ( - SolidStart - Basic - Something went wrong}> - {props.children} - + opencode + + {props.children} )} > diff --git a/cloud/app/src/asset/lander/check.svg b/cloud/app/src/asset/lander/check.svg new file mode 100644 index 000000000..22de6f2a8 --- /dev/null +++ b/cloud/app/src/asset/lander/check.svg @@ -0,0 +1,2 @@ + + diff --git a/cloud/app/src/asset/lander/copy.svg b/cloud/app/src/asset/lander/copy.svg new file mode 100644 index 000000000..f1baac30a --- /dev/null +++ b/cloud/app/src/asset/lander/copy.svg @@ -0,0 +1,2 @@ + + diff --git a/cloud/app/src/asset/screenshot-github.webp b/cloud/app/src/asset/lander/screenshot-github.png similarity index 100% rename from cloud/app/src/asset/screenshot-github.webp rename to cloud/app/src/asset/lander/screenshot-github.png diff --git a/cloud/app/src/asset/screenshot-splash.webp b/cloud/app/src/asset/lander/screenshot-splash.png similarity index 100% rename from cloud/app/src/asset/screenshot-splash.webp rename to cloud/app/src/asset/lander/screenshot-splash.png diff --git a/cloud/app/src/asset/screenshot-vscode.webp b/cloud/app/src/asset/lander/screenshot-vscode.png similarity index 100% rename from cloud/app/src/asset/screenshot-vscode.webp rename to cloud/app/src/asset/lander/screenshot-vscode.png diff --git a/cloud/app/src/asset/lander/screenshot.png b/cloud/app/src/asset/lander/screenshot.png new file mode 100644 index 000000000..feb617585 Binary files /dev/null and b/cloud/app/src/asset/lander/screenshot.png differ diff --git a/cloud/app/src/asset/logo-ornate-light.svg b/cloud/app/src/asset/logo-ornate-light.svg new file mode 100644 index 000000000..789223bc4 --- /dev/null +++ b/cloud/app/src/asset/logo-ornate-light.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/cloud/app/src/asset/logo.svg b/cloud/app/src/asset/logo.svg new file mode 100644 index 000000000..cbfcccf51 --- /dev/null +++ b/cloud/app/src/asset/logo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/cloud/app/src/component/icon.tsx b/cloud/app/src/component/icon.tsx index 5a565ab9a..d73c178bc 100644 --- a/cloud/app/src/component/icon.tsx +++ b/cloud/app/src/component/icon.tsx @@ -1,6 +1,21 @@ - import { JSX } from "solid-js" +export function IconLogo(props: JSX.SvgSVGAttributes) { + return ( + + + + + + + + + + + + + ); +} export function IconCopy(props: JSX.SvgSVGAttributes) { return ( diff --git a/cloud/app/src/context/auth.session.ts b/cloud/app/src/context/auth.session.ts new file mode 100644 index 000000000..c4b3940aa --- /dev/null +++ b/cloud/app/src/context/auth.session.ts @@ -0,0 +1,23 @@ +import { useSession } from "vinxi/http" + +export interface AuthSession { + account: Record< + string, + { + id: string + email: string + } + > + current?: string +} + +export function useAuthSession() { + return useSession({ + password: "0".repeat(32), + name: "auth", + cookie: { + secure: false, + httpOnly: true, + }, + }) +} diff --git a/cloud/app/src/context/auth.tsx b/cloud/app/src/context/auth.ts similarity index 67% rename from cloud/app/src/context/auth.tsx rename to cloud/app/src/context/auth.ts index 88d3214c1..a167dd3d4 100644 --- a/cloud/app/src/context/auth.tsx +++ b/cloud/app/src/context/auth.ts @@ -1,7 +1,3 @@ - - -import { useSession } from "vinxi/http" -import { createClient } from "@openauthjs/openauth/client" import { getRequestEvent } from "solid-js/web" import { and, Database, eq, inArray } from "@opencode/cloud-core/drizzle/index.js" import { WorkspaceTable } from "@opencode/cloud-core/schema/workspace.sql.js" @@ -10,18 +6,22 @@ import { query, redirect } from "@solidjs/router" import { AccountTable } from "@opencode/cloud-core/schema/account.sql.js" import { Actor } from "@opencode/cloud-core/actor.js" -export async function withActor(fn: () => T) { - const actor = await getActor() - return Actor.provide(actor.type, actor.properties, fn) -} +import { createClient } from "@openauthjs/openauth/client" +import { useAuthSession } from "./auth.session" + +export const AuthClient = createClient({ + clientID: "app", + issuer: import.meta.env.VITE_AUTH_URL, +}) export const getActor = query(async (): Promise => { "use server" const evt = getRequestEvent() - const url = new URL(evt!.request.headers.get("referer") ?? evt!.request.url) + if (!evt) throw new Error("No request event") + const url = new URL(evt.request.headers.has("x-server-id") ? evt.request.headers.get("referer")! : evt.request.url) const auth = await useAuthSession() - const [workspaceHint] = url.pathname.split("/").filter((x) => x.length > 0) - if (!workspaceHint) { + const splits = url.pathname.split("/").filter(Boolean) + if (splits[0] !== "workspace") { if (auth.data.current) { const current = auth.data.account[auth.data.current] return { @@ -32,9 +32,9 @@ export const getActor = query(async (): Promise => { }, } } - if (Object.keys(auth.data.account).length > 0) { + if (Object.keys(auth.data.account ?? {}).length > 0) { const current = Object.values(auth.data.account)[0] - await auth.update(val => ({ + await auth.update((val) => ({ ...val, current: current.id, })) @@ -51,20 +51,17 @@ export const getActor = query(async (): Promise => { properties: {}, } } + const workspaceHint = splits[1] const accounts = Object.keys(auth.data.account) const result = await Database.transaction(async (tx) => { - return await tx.select({ - user: UserTable - }) + return await tx + .select({ + user: UserTable, + }) .from(AccountTable) .innerJoin(UserTable, and(eq(UserTable.email, AccountTable.email))) .innerJoin(WorkspaceTable, eq(WorkspaceTable.id, UserTable.workspaceID)) - .where( - and( - inArray(AccountTable.id, accounts), - eq(WorkspaceTable.id, workspaceHint), - ) - ) + .where(and(inArray(AccountTable.id, accounts), eq(WorkspaceTable.id, workspaceHint))) .limit(1) .execute() .then((x) => x[0]) @@ -80,30 +77,3 @@ export const getActor = query(async (): Promise => { } throw redirect("/auth/authorize") }, "actor") - - -export const AuthClient = createClient({ - clientID: "app", - issuer: import.meta.env.VITE_AUTH_URL, -}) - -export interface AuthSession { - account: Record - current?: string -} - -export function useAuthSession() { - - return useSession({ - password: "0".repeat(32), - name: "auth" - }) -} - - -export function AuthProvider() { -} - diff --git a/cloud/app/src/context/auth.withActor.ts b/cloud/app/src/context/auth.withActor.ts new file mode 100644 index 000000000..ca38be89b --- /dev/null +++ b/cloud/app/src/context/auth.withActor.ts @@ -0,0 +1,16 @@ +import { Actor } from "@opencode/cloud-core/actor.js" +import { getActor } from "./auth" +import { query } from "@solidjs/router" + +export async function withActor(fn: () => T) { + const actor = await getActor() + return Actor.provide(actor.type, actor.properties, fn) +} + +export function actorQuery(cb: () => T, name: string) { + "use server" + return query(async () => { + const actor = await getActor() + return withActor(cb) + }, name) +} diff --git a/cloud/app/src/entry-server.tsx b/cloud/app/src/entry-server.tsx index eb8aea1e8..d339031e5 100644 --- a/cloud/app/src/entry-server.tsx +++ b/cloud/app/src/entry-server.tsx @@ -1,5 +1,5 @@ // @refresh reload -import { createHandler, StartServer } from "@solidjs/start/server"; +import { createHandler, StartServer } from "@solidjs/start/server" export default createHandler(() => ( ( - + + + {assets} - +
{children}
{scripts} )} /> -)); +)) diff --git a/cloud/app/src/routes/[workspaceID].tsx b/cloud/app/src/routes/[workspaceID].tsx deleted file mode 100644 index 706a64323..000000000 --- a/cloud/app/src/routes/[workspaceID].tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { createAsync, query } from "@solidjs/router" -import { getActor, withActor } from "~/context/auth" - -const getPosts = query(async () => { - "use server" - return withActor(() => { - return "ok" - }) -}, "posts") - - -export default function () { - const actor = createAsync(async () => getActor()) - return
{JSON.stringify(actor())}
-} diff --git a/cloud/app/src/routes/auth/callback.ts b/cloud/app/src/routes/auth/callback.ts index 22dcb2b6d..4e38df07e 100644 --- a/cloud/app/src/routes/auth/callback.ts +++ b/cloud/app/src/routes/auth/callback.ts @@ -1,5 +1,7 @@ +import { redirect } from "@solidjs/router" import type { APIEvent } from "@solidjs/start/server" -import { AuthClient, useAuthSession } from "~/context/auth" +import { AuthClient } from "~/context/auth" +import { useAuthSession } from "~/context/auth.session" export async function GET(input: APIEvent) { const url = new URL(input.request.url) @@ -25,7 +27,5 @@ export async function GET(input: APIEvent) { current: id, } }) - return { - result, - } + return redirect("/") } diff --git a/cloud/app/src/routes/auth/logout.ts b/cloud/app/src/routes/auth/logout.ts new file mode 100644 index 000000000..166466ef8 --- /dev/null +++ b/cloud/app/src/routes/auth/logout.ts @@ -0,0 +1,7 @@ +import type { APIEvent } from "@solidjs/start/server" +import { AuthClient } from "~/context/auth" + +export async function GET(input: APIEvent) { + const result = await AuthClient.authorize(new URL("./callback", input.request.url).toString(), "code") + return Response.redirect(result.url, 302) +} diff --git a/cloud/app/src/routes/debug/index.ts b/cloud/app/src/routes/debug/index.ts new file mode 100644 index 000000000..1753cf59d --- /dev/null +++ b/cloud/app/src/routes/debug/index.ts @@ -0,0 +1,9 @@ +import type { APIEvent } from "@solidjs/start/server" +import { Resource } from "@opencode/cloud-resource" +import { json } from "@solidjs/router" + +export async function GET(evt: APIEvent) { + return json({ + data: Resource.Database.host, + }) +} diff --git a/cloud/app/src/routes/gateway/v1/chat/completions.ts b/cloud/app/src/routes/gateway/v1/chat/completions.ts new file mode 100644 index 000000000..671b589c5 --- /dev/null +++ b/cloud/app/src/routes/gateway/v1/chat/completions.ts @@ -0,0 +1,576 @@ +import { Resource } from "@opencode/cloud-resource" +import { Billing } from "@opencode/cloud-core/billing.js" +import type { APIEvent } from "@solidjs/start/server" +import { Database, eq, sql } from "@opencode/cloud-core/drizzle/index.js" +import { BillingTable, PaymentTable } from "@opencode/cloud-core/schema/billing.sql.js" +import { Identifier } from "@opencode/cloud-core/identifier.js" +import { centsToMicroCents } from "@opencode/cloud-core/util/price.js" +import { Actor } from "@opencode/cloud-core/actor.js" +import { KeyTable } from "@opencode/cloud-core/schema/key.sql.js" + +const SUPPORTED_MODELS = { + // "anthropic/claude-sonnet-4": { + // input: 0.0000015, + // output: 0.000006, + // reasoning: 0.0000015, + // cacheRead: 0.0000001, + // cacheWrite: 0.0000001, + // model: () => + // createAnthropic({ + // apiKey: Resource.ANTHROPIC_API_KEY.value, + // })("claude-sonnet-4-20250514"), + // }, + // "openai/gpt-4.1": { + // input: 0.0000015, + // output: 0.000006, + // reasoning: 0.0000015, + // cacheRead: 0.0000001, + // cacheWrite: 0.0000001, + // model: () => + // createOpenAI({ + // apiKey: Resource.OPENAI_API_KEY.value, + // })("gpt-4.1"), + // }, + // "zhipuai/glm-4.5-flash": { + // input: 0, + // output: 0, + // reasoning: 0, + // cacheRead: 0, + // cacheWrite: 0, + // model: () => + // createOpenAICompatible({ + // name: "Zhipu AI", + // baseURL: "https://api.z.ai/api/paas/v4", + // apiKey: Resource.ZHIPU_API_KEY.value, + // })("glm-4.5-flash"), + // }, +} + +export async function POST(input: APIEvent) { + // Check auth header + const authHeader = input.request.headers.get("authorization") + if (!authHeader || !authHeader.startsWith("Bearer ")) + return Response.json( + { + error: { + message: "Missing API key.", + type: "invalid_request_error", + param: null, + code: "unauthorized", + }, + }, + { status: 401 }, + ) + const apiKey = authHeader.split(" ")[1] + + // Check against KeyTable + const keyRecord = await Database.use((tx) => + tx + .select({ + id: KeyTable.id, + workspaceID: KeyTable.workspaceID, + }) + .from(KeyTable) + .where(eq(KeyTable.key, apiKey)) + .then((rows) => rows[0]), + ) + + if (!keyRecord) + return Response.json( + { + error: { + message: "Invalid API key.", + type: "invalid_request_error", + param: null, + code: "unauthorized", + }, + }, + { status: 401 }, + ) + + /* + return await Actor.provide("system", { workspaceID: keyRecord.workspaceID }, async () => { + try { + // Check balance + const customer = await Billing.get() + if (customer.balance <= 0) { + return Response.json( + { + error: { + message: "Insufficient balance", + type: "insufficient_quota", + param: null, + code: "insufficient_quota", + }, + }, + { status: 401 }, + ) + } + + const body = await input.request.json() + const model = SUPPORTED_MODELS[body.model as keyof typeof SUPPORTED_MODELS]?.model() + if (!model) throw new Error(`Unsupported model: ${body.model}`) + + const requestBody = transformOpenAIRequestToAiSDK() + + return body.stream ? await handleStream() : await handleGenerate() + + async function handleStream() { + const result = await model.doStream({ + ...requestBody, + }) + + const encoder = new TextEncoder() + const stream = new ReadableStream({ + async start(controller) { + const id = `chatcmpl-${Date.now()}` + const created = Math.floor(Date.now() / 1000) + + try { + for await (const chunk of result.stream) { + console.log("!!! CHUNK !!! : " + chunk.type) + switch (chunk.type) { + case "text-delta": { + const data = { + id, + object: "chat.completion.chunk", + created, + model: body.model, + choices: [ + { + index: 0, + delta: { + content: chunk.delta, + }, + finish_reason: null, + }, + ], + } + controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`)) + break + } + + case "reasoning-delta": { + const data = { + id, + object: "chat.completion.chunk", + created, + model: body.model, + choices: [ + { + index: 0, + delta: { + reasoning_content: chunk.delta, + }, + finish_reason: null, + }, + ], + } + controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`)) + break + } + + case "tool-call": { + const data = { + id, + object: "chat.completion.chunk", + created, + model: body.model, + choices: [ + { + index: 0, + delta: { + tool_calls: [ + { + index: 0, + id: chunk.toolCallId, + type: "function", + function: { + name: chunk.toolName, + arguments: chunk.input, + }, + }, + ], + }, + finish_reason: null, + }, + ], + } + controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`)) + break + } + + case "error": { + const data = { + id, + object: "chat.completion.chunk", + created, + model: body.model, + choices: [ + { + index: 0, + delta: {}, + finish_reason: "stop", + }, + ], + error: { + message: typeof chunk.error === "string" ? chunk.error : chunk.error, + type: "server_error", + }, + } + controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`)) + controller.enqueue(encoder.encode("data: [DONE]\n\n")) + controller.close() + break + } + + case "finish": { + const data = { + id, + object: "chat.completion.chunk", + created, + model: body.model, + choices: [ + { + index: 0, + delta: {}, + finish_reason: + { + stop: "stop", + length: "length", + "content-filter": "content_filter", + "tool-calls": "tool_calls", + error: "stop", + other: "stop", + unknown: "stop", + }[chunk.finishReason] || "stop", + }, + ], + usage: { + prompt_tokens: chunk.usage.inputTokens, + completion_tokens: chunk.usage.outputTokens, + total_tokens: chunk.usage.totalTokens, + completion_tokens_details: { + reasoning_tokens: chunk.usage.reasoningTokens, + }, + prompt_tokens_details: { + cached_tokens: chunk.usage.cachedInputTokens, + }, + }, + } + await trackUsage(body.model, chunk.usage, chunk.providerMetadata) + controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`)) + controller.enqueue(encoder.encode("data: [DONE]\n\n")) + controller.close() + break + } + + //case "stream-start": + //case "response-metadata": + case "text-start": + case "text-end": + case "reasoning-start": + case "reasoning-end": + case "tool-input-start": + case "tool-input-delta": + case "tool-input-end": + case "raw": + default: + // Log unknown chunk types for debugging + console.warn(`Unknown chunk type: ${(chunk as any).type}`) + break + } + } + } catch (error) { + controller.error(error) + } + }, + }) + + return new Response(stream, { + headers: { + "Content-Type": "text/plain; charset=utf-8", + "Cache-Control": "no-cache", + Connection: "keep-alive", + }, + }) + } + + async function handleGenerate() { + const response = await model.doGenerate({ + ...requestBody, + }) + await trackUsage(body.model, response.usage, response.providerMetadata) + return c.json({ + id: `chatcmpl-${Date.now()}`, + object: "chat.completion" as const, + created: Math.floor(Date.now() / 1000), + model: body.model, + choices: [ + { + index: 0, + message: { + role: "assistant" as const, + content: response.content?.find((c) => c.type === "text")?.text ?? "", + reasoning_content: response.content?.find((c) => c.type === "reasoning")?.text, + tool_calls: response.content + ?.filter((c) => c.type === "tool-call") + .map((toolCall) => ({ + id: toolCall.toolCallId, + type: "function" as const, + function: { + name: toolCall.toolName, + arguments: toolCall.input, + }, + })), + }, + finish_reason: + ( + { + stop: "stop", + length: "length", + "content-filter": "content_filter", + "tool-calls": "tool_calls", + error: "stop", + other: "stop", + unknown: "stop", + } as const + )[response.finishReason] || "stop", + }, + ], + usage: { + prompt_tokens: response.usage?.inputTokens, + completion_tokens: response.usage?.outputTokens, + total_tokens: response.usage?.totalTokens, + completion_tokens_details: { + reasoning_tokens: response.usage?.reasoningTokens, + }, + prompt_tokens_details: { + cached_tokens: response.usage?.cachedInputTokens, + }, + }, + }) + } + + function transformOpenAIRequestToAiSDK() { + const prompt = transformMessages() + const tools = transformTools() + + return { + prompt, + maxOutputTokens: body.max_tokens ?? body.max_completion_tokens ?? undefined, + temperature: body.temperature ?? undefined, + topP: body.top_p ?? undefined, + frequencyPenalty: body.frequency_penalty ?? undefined, + presencePenalty: body.presence_penalty ?? undefined, + providerOptions: body.reasoning_effort + ? { + anthropic: { + reasoningEffort: body.reasoning_effort, + }, + } + : undefined, + stopSequences: (typeof body.stop === "string" ? [body.stop] : body.stop) ?? undefined, + responseFormat: (() => { + if (!body.response_format) return { type: "text" as const } + if (body.response_format.type === "json_schema") + return { + type: "json" as const, + schema: body.response_format.json_schema.schema, + name: body.response_format.json_schema.name, + description: body.response_format.json_schema.description, + } + if (body.response_format.type === "json_object") return { type: "json" as const } + throw new Error("Unsupported response format") + })(), + seed: body.seed ?? undefined, + tools: tools.tools, + toolChoice: tools.toolChoice, + } + + function transformTools() { + const { tools, tool_choice } = body + + if (!tools || tools.length === 0) { + return { tools: undefined, toolChoice: undefined } + } + + const aiSdkTools = tools.map((tool) => { + return { + type: tool.type, + name: tool.function.name, + description: tool.function.description, + inputSchema: tool.function.parameters!, + } + }) + + let aiSdkToolChoice + if (tool_choice == null) { + aiSdkToolChoice = undefined + } else if (tool_choice === "auto") { + aiSdkToolChoice = { type: "auto" as const } + } else if (tool_choice === "none") { + aiSdkToolChoice = { type: "none" as const } + } else if (tool_choice === "required") { + aiSdkToolChoice = { type: "required" as const } + } else if (tool_choice.type === "function") { + aiSdkToolChoice = { + type: "tool" as const, + toolName: tool_choice.function.name, + } + } + + return { tools: aiSdkTools, toolChoice: aiSdkToolChoice } + } + + function transformMessages() { + const { messages } = body + const prompt: LanguageModelV2Prompt = [] + + for (const message of messages) { + switch (message.role) { + case "system": { + prompt.push({ + role: "system", + content: message.content as string, + }) + break + } + + case "user": { + if (typeof message.content === "string") { + prompt.push({ + role: "user", + content: [{ type: "text", text: message.content }], + }) + } else { + const content = message.content.map((part) => { + switch (part.type) { + case "text": + return { type: "text" as const, text: part.text } + case "image_url": + return { + type: "file" as const, + mediaType: "image/jpeg" as const, + data: part.image_url.url, + } + default: + throw new Error(`Unsupported content part type: ${(part as any).type}`) + } + }) + prompt.push({ + role: "user", + content, + }) + } + break + } + + case "assistant": { + const content: Array< + | { type: "text"; text: string } + | { + type: "tool-call" + toolCallId: string + toolName: string + input: any + } + > = [] + + if (message.content) { + content.push({ + type: "text", + text: message.content as string, + }) + } + + if (message.tool_calls) { + for (const toolCall of message.tool_calls) { + content.push({ + type: "tool-call", + toolCallId: toolCall.id, + toolName: toolCall.function.name, + input: JSON.parse(toolCall.function.arguments), + }) + } + } + + prompt.push({ + role: "assistant", + content, + }) + break + } + + case "tool": { + prompt.push({ + role: "tool", + content: [ + { + type: "tool-result", + toolName: "placeholder", + toolCallId: message.tool_call_id, + output: { + type: "text", + value: message.content as string, + }, + }, + ], + }) + break + } + + default: { + throw new Error(`Unsupported message role: ${message.role}`) + } + } + } + + return prompt + } + } + + async function trackUsage(model: string, usage: LanguageModelUsage, providerMetadata?: ProviderMetadata) { + const modelData = SUPPORTED_MODELS[model as keyof typeof SUPPORTED_MODELS] + if (!modelData) throw new Error(`Unsupported model: ${model}`) + + const inputTokens = usage.inputTokens ?? 0 + const outputTokens = usage.outputTokens ?? 0 + const reasoningTokens = usage.reasoningTokens ?? 0 + const cacheReadTokens = usage.cachedInputTokens ?? 0 + const cacheWriteTokens = + providerMetadata?.["anthropic"]?.["cacheCreationInputTokens"] ?? + // @ts-expect-error + providerMetadata?.["bedrock"]?.["usage"]?.["cacheWriteInputTokens"] ?? + 0 + + const inputCost = modelData.input * inputTokens + const outputCost = modelData.output * outputTokens + const reasoningCost = modelData.reasoning * reasoningTokens + const cacheReadCost = modelData.cacheRead * cacheReadTokens + const cacheWriteCost = modelData.cacheWrite * cacheWriteTokens + const costInCents = (inputCost + outputCost + reasoningCost + cacheReadCost + cacheWriteCost) * 100 + + await Billing.consume({ + model, + inputTokens, + outputTokens, + reasoningTokens, + cacheReadTokens, + cacheWriteTokens, + costInCents, + }) + + await Database.use((tx) => + tx + .update(KeyTable) + .set({ timeUsed: sql`now()` }) + .where(eq(KeyTable.id, keyRecord.id)), + ) + } + } catch (error: any) { + return Response.json({ error: { message: error.message } }, { status: 500 }) + } + }) + */ +} diff --git a/cloud/app/src/routes/index.css b/cloud/app/src/routes/index.css index 9b0c7009e..a2fa654d2 100644 --- a/cloud/app/src/routes/index.css +++ b/cloud/app/src/routes/index.css @@ -1,24 +1,43 @@ [data-page="home"] { - --color-bg: oklch(0.2097 0.008 274.53); - --color-border: oklch(0.46 0.02 269.88); - --color-text: #ffffff; - --color-text-secondary: oklch(0.72 0.01 270.15); - --color-text-dimmed: hsl(224, 7%, 46%); - padding: var(--space-6); + --color-text: hsl(224, 10%, 10%); + --color-text-secondary: hsl(224, 7%, 46%); + --color-text-dimmed: hsl(224, 6%, 63%); + + --color-border: hsl(224, 6%, 77%); +} + +[data-page="home"] { + @media (prefers-color-scheme: dark) { + --color-text: hsl(0, 0%, 100%); + --color-text-secondary: hsl(224, 6%, 66%); + --color-text-dimmed: hsl(224, 7%, 46%); + + --color-border: hsl(224, 6%, 36%); + } +} + +[data-page="home"] { + --padding: 3rem; + --vertical-padding: 1.5rem; + --heading-font-size: 1.5625rem; + + @media (max-width: 30rem) { + --padding: 1rem; + --vertical-padding: 0.75rem; + --heading-font-size: 1.375rem; + } + font-family: var(--font-mono); color: var(--color-text); + padding: calc(var(--padding) + 1rem); a { color: var(--color-text); text-decoration: underline; text-underline-offset: var(--space-0-75); + text-decoration-thickness: 1px; } - background: var(--color-bg); - position: fixed; - overflow-y: scroll; - inset: 0; - [data-component="content"] { max-width: 67.5rem; margin: 0 auto; @@ -26,56 +45,141 @@ } [data-component="top"] { - padding: var(--space-12); + padding: var(--padding); display: flex; flex-direction: column; align-items: start; - gap: var(--space-4); + gap: calc(var(--vertical-padding) / 2); - [data-slot="logo"] { - height: 70px; + img { + height: auto; + width: clamp(200px, 70vw, 400px); + } + + [data-slot="logo dark"] { + display: none; + } + + @media (prefers-color-scheme: dark) { + [data-slot="logo light"] { + display: none; + } + [data-slot="logo dark"] { + display: block; + } } [data-slot="title"] { - font-size: var(--font-size-2xl); + line-height: 1.25; + font-size: var(--heading-font-size); text-transform: uppercase; } } [data-component="cta"] { - height: var(--space-19); border-top: 2px solid var(--color-border); - display: flex; + display: grid; + grid-template-columns: auto 1fr auto; + align-items: stretch; - [data-slot="left"] { - display: flex; - padding: 0 var(--space-12); - text-transform: uppercase; - text-decoration: underline; - align-items: center; - justify-content: center; - text-underline-offset: var(--space-0-75); - border-right: 2px solid var(--color-border); + & > div + div { + border-left: 2px solid var(--color-border); } + [data-slot="left"], [data-slot="right"] { - flex: 1; - display: flex; - align-items: center; - justify-content: center; - gap: var(--space-2-5); - padding: 0 var(--space-6); + text-align: center; + line-height: 1.4; + padding: var(--vertical-padding) 2rem; + text-transform: uppercase; + + @media (max-width: 30rem) { + padding-bottom: calc(var(--vertical-padding) + 4px); + } + + @media (max-width: 30rem) { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + } + + [data-slot="center"] { + padding: var(--vertical-padding) 1rem; + } + + @media (max-width: 55rem) { + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: auto auto; + + [data-slot="left"] { + grid-column: 1; + grid-row: 1; + } + + [data-slot="right"] { + grid-column: 2; + grid-row: 1; + } + + [data-slot="center"] { + grid-column: 1 / -1; + grid-row: 2; + border-left: none; + border-top: 2px solid var(--color-border); + } + + @media (max-width: 22rem) { + grid-template-columns: 1fr; + grid-template-rows: auto auto auto; + + [data-slot="left"] { + grid-column: 1; + grid-row: 1; + } + + [data-slot="right"] { + grid-column: 1; + grid-row: 2; + border-top: 2px solid var(--color-border); + border-left: none; + } + + [data-slot="center"] { + grid-column: 1; + grid-row: 3; + } + } } [data-slot="command"] { all: unset; display: flex; align-items: center; + justify-content: center; cursor: pointer; color: var(--color-text-secondary); - font-size: var(--font-size-lg); + font-size: 1.125rem; font-family: var(--font-mono); gap: var(--space-2); + width: 100%; + + & > span { + @media (max-width: 24rem) { + font-size: 0.875rem; + } + @media (max-width: 64rem) { + [data-slot="protocol"] { + display: none; + } + } + @media (max-width: 38rem) { + text-align: center; + span:first-child { + display: block; + } + } + } } [data-slot="highlight"] { @@ -86,7 +190,7 @@ [data-component="features"] { border-top: 2px solid var(--color-border); - padding: var(--space-12); + padding: var(--padding); [data-slot="list"] { padding-left: var(--space-4); @@ -98,7 +202,7 @@ strong { text-transform: uppercase; - font-weight: 600; + font-weight: 700; } } @@ -120,24 +224,28 @@ } } - [data-component="title"] { - letter-spacing: -0.03125rem; - text-transform: uppercase; - font-weight: 400; - font-size: var(--font-size-md); - flex-shrink: 0; - color: oklch(0.55 0.02 269.87); - } - [data-component="method"] { - padding: var(--space-4) var(--space-6); display: flex; + padding: calc(var(--vertical-padding) / 2) calc(var(--padding) / 2) calc(var(--vertical-padding) / 2 + 0.125rem); flex-direction: column; - align-items: start; - gap: var(--space-3); + text-align: left; + gap: var(--space-2-5); + + @media (max-width: 30rem) { + gap: 0.3125rem; + } + + @media (max-width: 40rem) { + text-align: left; + } &:nth-child(2) { border-left: 2px solid var(--color-border); + + @media (max-width: 40rem) { + border-left: none; + border-top: 2px solid var(--color-border); + } } &:nth-child(3) { @@ -147,6 +255,23 @@ &:nth-child(4) { border-top: 2px solid var(--color-border); border-left: 2px solid var(--color-border); + + @media (max-width: 40rem) { + border-left: none; + } + } + + [data-component="title"] { + letter-spacing: -0.03125rem; + text-transform: uppercase; + font-weight: normal; + font-size: 1rem; + flex-shrink: 0; + color: var(--color-text-dimmed); + + @media (max-width: 30rem) { + font-size: 0.75rem; + } } [data-slot="button"] { @@ -155,63 +280,177 @@ display: flex; align-items: center; color: var(--color-text-secondary); - gap: var(--space-2); + gap: var(--space-2-5); + font-size: 1rem; + + @media (max-width: 24rem) { + font-size: 0.875rem; + } strong { color: var(--color-text); font-weight: 500; } + + @media (max-width: 40rem) { + justify-content: flex-start; + } + + @media (max-width: 30rem) { + justify-content: center; + } } } [data-component="screenshots"] { - border-top: 2px solid var(--color-border); + --images-height: 600px; display: grid; grid-template-columns: 1fr 1fr; - gap: 0; + grid-template-rows: var(--images-height); + border-top: 2px solid var(--color-border); - [data-slot="left"] { - padding: var(--space-8) var(--space-6); + & > div.left { display: flex; - flex-direction: column; - - img { - width: 100%; - height: auto; - } + grid-row: 1; + grid-column: 1; } - [data-slot="right"] { + & > div.right { display: grid; grid-template-rows: 1fr 1fr; + grid-row: 1; + grid-column: 2; border-left: 2px solid var(--color-border); - } - [data-slot="filler"] { - display: flex; - flex-grow: 1; - align-items: center; - justify-content: center; - } - - [data-slot="cell"] { - padding: var(--space-8) var(--space-6); - display: flex; - flex-direction: column; - gap: var(--space-4); - - &:nth-child(2) { - border-top: 2px solid var(--color-border); + & > div.row1 { + display: flex; + grid-row: 1; + border-bottom: 2px solid var(--color-border); + height: calc(var(--images-height) / 2); } - img { - width: 80%; + & > div.row2 { + display: flex; + grid-row: 2; + height: calc(var(--images-height) / 2); + } + } + + figure { + flex: 1; + display: flex; + flex-direction: column; + gap: calc(var(--padding) / 4); + padding: calc(var(--padding) / 2); + border-width: 0; + border-style: solid; + border-color: var(--color-border); + min-height: 0; + overflow: hidden; + + & > div, + figcaption { + display: flex; + align-items: center; + } + + & > div { + flex: 1; + min-height: 0; + display: flex; + align-items: center; + justify-content: center; + } + + a { + display: flex; + flex: 1; + min-height: 0; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + } + + figcaption { + letter-spacing: -0.03125rem; + text-transform: uppercase; + color: var(--color-text-dimmed); + flex-shrink: 0; + + @media (max-width: 30rem) { + font-size: 0.75rem; + } + } + } + + & > div.left figure { + height: var(--images-height); + box-sizing: border-box; + } + + & > div.right figure { + height: calc(var(--images-height) / 2); + box-sizing: border-box; + } + + & > div.left img { + width: 100%; + height: 100%; + min-width: 0; + object-fit: contain; + } + + & > div.right img { + width: 100%; + height: calc(100% - 2rem); + object-fit: contain; + display: block; + } + + @media (max-width: 30rem) { + & { + --images-height: auto; + grid-template-columns: 1fr; + grid-template-rows: auto auto; + } + + & > div.left { + grid-row: 1; + grid-column: 1; + } + + & > div.right { + grid-row: 2; + grid-column: 1; + border-left: none; + border-top: 2px solid var(--color-border); + + & > div.row1, + & > div.row2 { + height: auto; + } + } + + & > div.left figure, + & > div.right figure { height: auto; } + + & > div.left img, + & > div.right img { + width: 100%; + height: auto; + max-height: none; + } } } [data-component="copy-status"] { + @media (max-width: 38rem) { + display: none; + } + [data-slot="copy"] { display: block; width: var(--space-4); @@ -227,7 +466,7 @@ display: none; width: var(--space-4); height: var(--space-4); - color: white; + color: var(--color-text); [data-copied] & { display: block; @@ -237,20 +476,47 @@ [data-component="footer"] { border-top: 2px solid var(--color-border); - display: grid; - grid-template-columns: 1fr 1fr 1fr; - font-size: var(--font-size-lg); - height: var(--space-20); + display: flex; + flex-direction: row; [data-slot="cell"] { - display: flex; - align-items: center; - justify-content: center; - border-right: 2px solid var(--color-border); + flex: 1; + text-align: center; text-transform: uppercase; + padding: var(--vertical-padding) 0.5rem; + } - &:last-child { - border-right: none; + [data-slot="cell"] + [data-slot="cell"] { + border-left: 2px solid var(--color-border); + } + + /* Small desktop: first two columns shrink to content, third expands */ + @media (max-width: 57rem) { + [data-slot="cell"]:nth-child(1), + [data-slot="cell"]:nth-child(2) { + flex: 0 0 auto; + padding-left: calc(var(--padding) / 2); + padding-right: calc(var(--padding) / 2); + } + + [data-slot="cell"]:nth-child(3) { + flex: 1; + } + } + + /* Mobile: third column on its own row */ + @media (max-width: 40rem) { + flex-wrap: wrap; + + [data-slot="cell"]:nth-child(1), + [data-slot="cell"]:nth-child(2) { + flex: 1; + } + + [data-slot="cell"]:nth-child(3) { + flex: 1 0 100%; + border-left: none; + border-top: 2px solid var(--color-border); } } } diff --git a/cloud/app/src/routes/index.tsx b/cloud/app/src/routes/index.tsx index 057ddb49e..5a4e07978 100644 --- a/cloud/app/src/routes/index.tsx +++ b/cloud/app/src/routes/index.tsx @@ -1,13 +1,15 @@ import { Title } from "@solidjs/meta" import { onCleanup, onMount } from "solid-js" import "./index.css" -import logo from "../asset/logo-ornate-dark.svg" -import IMG_SPLASH from "../asset/screenshot-splash.webp" -import IMG_VSCODE from "../asset/screenshot-vscode.webp" -import IMG_GITHUB from "../asset/screenshot-github.webp" +import logoLight from "../asset/logo-ornate-light.svg" +import logoDark from "../asset/logo-ornate-dark.svg" +import IMG_SPLASH from "../asset/lander/screenshot-splash.png" +import IMG_VSCODE from "../asset/lander/screenshot-vscode.png" +import IMG_GITHUB from "../asset/lander/screenshot-github.png" import { IconCopy, IconCheck } from "../component/icon" -import { createAsync, query, redirect, RouteDefinition } from "@solidjs/router" -import { getActor, withActor } from "~/context/auth" +import { createAsync, query, redirect } from "@solidjs/router" +import { getActor } from "~/context/auth" +import { withActor } from "~/context/auth.withActor" import { Account } from "@opencode/cloud-core/account.js" function CopyStatus() { @@ -24,13 +26,11 @@ const isLoggedIn = query(async () => { const actor = await getActor() if (actor.type === "account") { const workspaces = await withActor(() => Account.workspaces()) - throw redirect("/" + workspaces[0].id) + throw redirect(`/workspace/${workspaces[0].id}`) } - return + return false }, "isLoggedIn") - - export default function Home() { createAsync(() => isLoggedIn(), { deferStream: true, @@ -60,7 +60,8 @@ export default function Home() { opencode | AI coding agent built for the terminal
- logo + opencode logo light + opencode logo dark

The AI coding agent built for the terminal.

@@ -68,7 +69,7 @@ export default function Home() { -
+
+
@@ -145,24 +151,30 @@ export default function Home() {
-
-
opencode TUI with tokyonight theme
-
- opencode TUI with tokyonight theme -
+
+
+
opencode TUI with the tokyonight theme
+ + opencode TUI with tokyonight theme + +
-
-
-
opencode in VS Code
-
- opencode in VS Code -
+
+
+
+
opencode in VS Code
+ + opencode in VS Code + +
-
-
opencode in GitHub
-
- opencode in GitHub -
+
+
+
opencode in GitHub
+ + opencode in GitHub + +
diff --git a/cloud/app/src/routes/stripe/webhook.ts b/cloud/app/src/routes/stripe/webhook.ts new file mode 100644 index 000000000..61d14a645 --- /dev/null +++ b/cloud/app/src/routes/stripe/webhook.ts @@ -0,0 +1,73 @@ +import { Billing } from "@opencode/cloud-core/billing.js" +import type { APIEvent } from "@solidjs/start/server" +import { Database, eq, sql } from "@opencode/cloud-core/drizzle/index.js" +import { BillingTable, PaymentTable } from "@opencode/cloud-core/schema/billing.sql.js" +import { Identifier } from "@opencode/cloud-core/identifier.js" +import { centsToMicroCents } from "@opencode/cloud-core/util/price.js" +import { Actor } from "@opencode/cloud-core/actor.js" +import { Resource } from "@opencode/cloud-resource" + +export async function POST(input: APIEvent) { + const body = await Billing.stripe().webhooks.constructEventAsync( + await input.request.text(), + input.request.headers.get("stripe-signature")!, + Resource.STRIPE_WEBHOOK_SECRET.value, + ) + + console.log(body.type, JSON.stringify(body, null, 2)) + if (body.type === "checkout.session.completed") { + const workspaceID = body.data.object.metadata?.workspaceID + const customerID = body.data.object.customer as string + const paymentID = body.data.object.payment_intent as string + const amount = body.data.object.amount_total + + if (!workspaceID) throw new Error("Workspace ID not found") + if (!customerID) throw new Error("Customer ID not found") + if (!amount) throw new Error("Amount not found") + if (!paymentID) throw new Error("Payment ID not found") + + await Actor.provide("system", { workspaceID }, async () => { + const customer = await Billing.get() + if (customer?.customerID && customer.customerID !== customerID) throw new Error("Customer ID mismatch") + + // set customer metadata + if (!customer?.customerID) { + await Billing.stripe().customers.update(customerID, { + metadata: { + workspaceID, + }, + }) + } + + // get payment method for the payment intent + const paymentIntent = await Billing.stripe().paymentIntents.retrieve(paymentID, { + expand: ["payment_method"], + }) + const paymentMethod = paymentIntent.payment_method + if (!paymentMethod || typeof paymentMethod === "string") throw new Error("Payment method not expanded") + + await Database.transaction(async (tx) => { + await tx + .update(BillingTable) + .set({ + balance: sql`${BillingTable.balance} + ${centsToMicroCents(amount)}`, + customerID, + paymentMethodID: paymentMethod.id, + paymentMethodLast4: paymentMethod.card!.last4, + }) + .where(eq(BillingTable.workspaceID, workspaceID)) + await tx.insert(PaymentTable).values({ + workspaceID, + id: Identifier.create("payment"), + amount: centsToMicroCents(amount), + paymentID, + customerID, + }) + }) + }) + } + + console.log("finished handling") + + return Response.json("ok", { status: 200 }) +} diff --git a/cloud/app/src/routes/workspace.css b/cloud/app/src/routes/workspace.css new file mode 100644 index 000000000..e18b410ee --- /dev/null +++ b/cloud/app/src/routes/workspace.css @@ -0,0 +1,66 @@ +[data-page="workspace"] { + line-height: 1; + + @media (max-width: 30rem) { + padding: var(--space-4); + gap: var(--space-5); + } + + /* Workspace Header */ + [data-component="workspace-header"] { + position: sticky; + top: 0; + z-index: 100; + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--space-4) var(--space-4); + border-bottom: 1px solid var(--color-border); + background-color: var(--color-bg); + + @media (max-width: 30rem) { + padding: 0 var(--space-4); + margin: calc(-1 * var(--space-4)); + margin-bottom: var(--space-5); + } + } + + [data-slot="header-brand"] { + flex: 0 0 auto; + padding-top: 4px; + + svg { + width: 138px; + } + + [data-component="site-title"] { + font-size: var(--font-size-lg); + font-weight: 600; + color: var(--color-text); + text-decoration: none; + letter-spacing: -0.02em; + } + } + + [data-slot="header-actions"] { + display: flex; + gap: var(--space-4); + align-items: center; + font-size: var(--font-size-sm); + + span { + color: var(--color-text-muted); + } + + a, + button { + border: none; + padding: 0; + color: var(--color-text); + text-decoration: underline; + text-underline-offset: var(--space-0-75); + text-decoration-thickness: 1px; + text-transform: uppercase; + } + } +} diff --git a/cloud/app/src/routes/workspace.tsx b/cloud/app/src/routes/workspace.tsx new file mode 100644 index 000000000..6876ae962 --- /dev/null +++ b/cloud/app/src/routes/workspace.tsx @@ -0,0 +1,38 @@ +import "./workspace.css" +import { useAuthSession } from "~/context/auth.session" +import { IconLogo } from "../component/icon" +import { action, redirect, RouteSectionProps } from "@solidjs/router" + +const logout = action(async () => { + "use server" + const auth = await useAuthSession() + const current = auth.data.current + if (current) + await auth.update((val) => { + delete val.account[current] + return val + }) + + return redirect("/") +}) + +export default function WorkspaceLayout(props: RouteSectionProps) { + return ( +
+
+
+ + + +
+
+ name@example.com +
+ +
+
+
+
{props.children}
+
+ ) +} diff --git a/cloud/app/src/routes/workspace/[id].css b/cloud/app/src/routes/workspace/[id].css new file mode 100644 index 000000000..887469e33 --- /dev/null +++ b/cloud/app/src/routes/workspace/[id].css @@ -0,0 +1,477 @@ +/* Root container */ +[data-slot="root"] { + max-width: 64rem; + padding: var(--space-10) var(--space-4); + margin: 0 auto; + width: 100%; + display: flex; + flex-direction: column; + gap: var(--space-10); + + [data-slot="sections"] { + display: flex; + flex-direction: column; + gap: var(--space-16); + + section { + display: flex; + flex-direction: column; + gap: var(--space-6); + } + section:not(:last-child) { + border-bottom: 1px solid var(--color-border); + padding-bottom: var(--space-16); + } + } +} + +/* Common elements */ +button { + padding: var(--space-3) var(--space-4); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-sm); + background-color: var(--color-bg); + color: var(--color-text); + font-size: var(--font-size-sm); + font-family: var(--font-sans); + font-weight: 500; + text-transform: uppercase; + cursor: pointer; + transition: all 0.15s ease; + + &:hover { + background-color: var(--color-surface-hover); + border-color: var(--color-accent); + } + + &:active { + transform: translateY(1px); + } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + + &:hover { + background-color: var(--color-bg); + border-color: var(--color-border); + transform: none; + } + } + + &[color="primary"] { + background-color: var(--color-primary); + border-color: var(--color-primary); + color: var(--color-primary-text); + + &:hover { + background-color: var(--color-primary-hover); + border-color: var(--color-primary-hover); + } + } + + &[color="ghost"] { + background-color: transparent; + border-color: transparent; + color: var(--color-text-muted); + + &:hover { + background-color: var(--color-surface-hover); + border-color: var(--color-border); + color: var(--color-text); + } + } +} + +a { + color: var(--color-text); + text-decoration: underline; + text-underline-offset: var(--space-0-75); + text-decoration-thickness: 1px; +} + +[data-slot="empty-state"] { + padding: var(--space-20) var(--space-6); + text-align: center; + border: 1px dashed var(--color-border); + border-radius: var(--border-radius-sm); + display: flex; + flex-direction: column; + gap: var(--space-2); + + p { + font-size: var(--font-size-sm); + color: var(--color-text-muted); + margin: 0; + } +} + +/* Title section */ +[data-slot="title-section"] { + display: flex; + flex-direction: column; + gap: var(--space-2); + padding-bottom: var(--space-8); + border-bottom: 1px solid var(--color-border); + + h1 { + font-size: var(--font-size-2xl); + font-weight: 500; + line-height: 1.2; + letter-spacing: -0.03125rem; + margin: 0; + text-transform: uppercase; + + @media (max-width: 30rem) { + font-size: var(--font-size-xl); + line-height: 1.25; + } + } + + p { + font-size: var(--font-size-md); + color: var(--color-text-muted); + + a { + color: var(--color-text-muted); + } + } +} + +/* Section titles */ +[data-slot="section-title"] { + display: flex; + flex-direction: column; + gap: var(--space-1); + + h2 { + font-size: var(--font-size-md); + font-weight: 600; + line-height: 1.2; + letter-spacing: -0.03125rem; + margin: 0; + color: var(--color-text-secondary); + text-transform: uppercase; + + @media (max-width: 30rem) { + font-size: var(--font-size-lg); + line-height: 1.25; + } + } + + p { + font-size: var(--font-size-sm); + color: var(--color-text-muted); + } +} + +/* API Keys Section */ +[data-slot="api-keys-section"] { + [data-slot="create-form"] { + display: flex; + flex-direction: column; + gap: var(--space-3); + padding: var(--space-4); + background-color: var(--color-bg-surface); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-sm); + max-width: 32rem; + + input { + padding: var(--space-2) var(--space-3); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-sm); + background-color: var(--color-bg); + color: var(--color-text); + font-size: var(--font-size-sm); + font-family: var(--font-mono); + + &:focus { + outline: none; + border-color: var(--color-accent); + } + + &::placeholder { + color: var(--color-text-disabled); + } + } + + [data-slot="form-actions"] { + display: flex; + gap: var(--space-2); + justify-content: flex-end; + } + } + + [data-slot="api-keys-table"] { + overflow-x: auto; + } + + [data-slot="api-keys-table-element"] { + width: 100%; + border-collapse: collapse; + font-size: var(--font-size-sm); + + thead { + border-bottom: 1px solid var(--color-border); + } + + th { + padding: var(--space-3) var(--space-4); + text-align: left; + font-weight: normal; + color: var(--color-text-muted); + text-transform: uppercase; + } + + td { + padding: var(--space-3) var(--space-4); + border-bottom: 1px solid var(--color-border-muted); + color: var(--color-text-muted); + font-family: var(--font-mono); + + &[data-slot="key-name"] { + color: var(--color-text); + font-family: var(--font-sans); + font-weight: 500; + } + + &[data-slot="key-value"] { + font-family: var(--font-mono); + + div { + cursor: pointer; + display: flex; + align-items: center; + gap: var(--space-2); + } + } + + &[data-slot="key-date"] { + color: var(--color-text); + } + + &[data-slot="key-actions"] { + font-family: var(--font-sans); + } + } + + tbody tr { + &:last-child td { + border-bottom: none; + } + } + + @media (max-width: 40rem) { + th, + td { + padding: var(--space-2) var(--space-3); + font-size: var(--font-size-xs); + } + + th { + &:nth-child(3) /* Date */ { + display: none; + } + } + + td { + &:nth-child(3) /* Date */ { + display: none; + } + } + } + } +} + +/* Balance Section */ +[data-slot="balance-section"] { + [data-slot="balance"] { + display: flex; + flex-direction: column; + gap: var(--space-3); + padding: var(--space-4); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-sm); + min-width: 14.5rem; + width: fit-content; + + [data-slot="amount"] { + padding: var(--space-3-5) var(--space-4); + background-color: var(--color-bg-surface); + border-radius: var(--border-radius-sm); + display: flex; + align-items: baseline; + gap: var(--space-1); + justify-content: flex-end; + + &.danger { + [data-slot="value"] { + color: var(--color-danger); + } + } + + [data-slot="currency"] { + position: relative; + bottom: 2px; + font-size: var(--font-size-lg); + color: var(--color-text-muted); + font-weight: 400; + } + + [data-slot="value"] { + font-size: var(--font-size-3xl); + font-weight: 500; + color: var(--color-text); + } + } + } +} + +/* Payments Section */ +[data-slot="payments-section"] { + [data-slot="payments-table"] { + overflow-x: auto; + } + + [data-slot="payments-table-element"] { + width: 100%; + border-collapse: collapse; + font-size: var(--font-size-sm); + + thead { + border-bottom: 1px solid var(--color-border); + } + + th { + padding: var(--space-3) var(--space-4); + text-align: left; + font-weight: normal; + color: var(--color-text-muted); + text-transform: uppercase; + } + + td { + padding: var(--space-3) var(--space-4); + border-bottom: 1px solid var(--color-border-muted); + color: var(--color-text-muted); + font-family: var(--font-mono); + + &[data-slot="payment-date"] { + color: var(--color-text); + } + + &[data-slot="payment-id"] { + font-family: var(--font-mono); + font-weight: 400; + color: var(--color-text-muted); + max-width: 200px; + word-break: break-word; + } + + &[data-slot="payment-amount"] { + color: var(--color-text); + } + } + + tbody tr { + &:last-child td { + border-bottom: none; + } + } + + @media (max-width: 40rem) { + th, + td { + padding: var(--space-2) var(--space-3); + font-size: var(--font-size-xs); + } + + th { + &:nth-child(2) /* Payment ID */ { + display: none; + } + } + + td { + &:nth-child(2) /* Payment ID */ { + display: none; + } + } + } + } +} + +/* Usage Section */ +[data-slot="usage-section"] { + [data-slot="usage-table"] { + overflow-x: auto; + } + + [data-slot="usage-table-element"] { + width: 100%; + border-collapse: collapse; + font-size: var(--font-size-sm); + + thead { + border-bottom: 1px solid var(--color-border); + } + + th { + padding: var(--space-3) var(--space-4); + text-align: left; + font-weight: normal; + color: var(--color-text-muted); + text-transform: uppercase; + } + + td { + padding: var(--space-3) var(--space-4); + border-bottom: 1px solid var(--color-border-muted); + color: var(--color-text-muted); + font-family: var(--font-mono); + + &[data-slot="usage-date"] { + color: var(--color-text); + } + + &[data-slot="usage-model"] { + font-family: var(--font-sans); + font-weight: 400; + color: var(--color-text-secondary); + max-width: 200px; + word-break: break-word; + } + + &[data-slot="usage-cost"] { + color: var(--color-text); + } + } + + tbody tr { + &:last-child td { + border-bottom: none; + } + } + + @media (max-width: 40rem) { + th, + td { + padding: var(--space-2) var(--space-3); + font-size: var(--font-size-xs); + } + + th { + &:nth-child(2) /* Model */ { + display: none; + } + } + + td { + &:nth-child(2) /* Model */ { + display: none; + } + } + } + } +} diff --git a/cloud/app/src/routes/workspace/[id].tsx b/cloud/app/src/routes/workspace/[id].tsx new file mode 100644 index 000000000..ccdfe42f5 --- /dev/null +++ b/cloud/app/src/routes/workspace/[id].tsx @@ -0,0 +1,523 @@ +import { Billing } from "@opencode/cloud-core/billing.js" +import { Key } from "@opencode/cloud-core/key.js" +import { action, createAsync, query, useAction, useSubmission, json } from "@solidjs/router" +import { createSignal, For, onMount, Show } from "solid-js" +import { getActor } from "~/context/auth" +import { withActor } from "~/context/auth.withActor" +import { IconCopy, IconCheck } from "~/component/icon" +import "./[id].css" +import { User } from "@opencode/cloud-core/user.js" +import { Actor } from "@opencode/cloud-core/actor.js" + +///////////////////////////////////// +// Keys related queries and actions +///////////////////////////////////// + + +const listKeys = query(() => { + "use server" + return withActor(() => Key.list()) +}, "key.list") + +const createKey = action(async (name: string) => { + "use server" + return json( + withActor(() => Key.create({ name })), + { revalidate: listKeys.key }, + ) +}, "key.create") + +const removeKey = action(async (id: string) => { + "use server" + return json( + withActor(() => Key.remove({ id })), + { revalidate: listKeys.key }, + ) +}, "key.remove") + +///////////////////////////////////// +// Billing related queries and actions +///////////////////////////////////// + +const getBillingInfo = query(async () => { + "use server" + return withActor(async () => { + const actor = Actor.assert("user") + const [user, billing, payments, usage] = await Promise.all([ + User.fromID(actor.properties.userID), + Billing.get(), + Billing.payments(), + Billing.usages(), + ]) + return { user, billing, payments, usage } + }) +}, "billingInfo") + +const createCheckoutUrl = action(async (successUrl: string, cancelUrl: string) => { + "use server" + return withActor(() => Billing.generateCheckoutUrl({ successUrl, cancelUrl })) +}, "checkoutUrl") + +const createPortalUrl = action(async (returnUrl: string) => { + "use server" + return withActor(() => Billing.generatePortalUrl({ returnUrl })) +}, "portalUrl") + +const dummyUsageData = [ + { + model: "claude-3-5-sonnet-20241022", + inputTokens: 1250, + outputTokens: 890, + reasoningTokens: 150, + cacheReadTokens: 0, + cacheWriteTokens: 45, + cost: 12340000, + timeCreated: new Date("2025-01-28T10:30:00Z"), + }, + { + model: "claude-3-haiku-20240307", + inputTokens: 2100, + outputTokens: 450, + reasoningTokens: null, + cacheReadTokens: 120, + cacheWriteTokens: 0, + cost: 5670000, + timeCreated: new Date("2025-01-27T15:22:00Z"), + }, + { + model: "claude-3-5-sonnet-20241022", + inputTokens: 850, + outputTokens: 1200, + reasoningTokens: 220, + cacheReadTokens: 30, + cacheWriteTokens: 15, + cost: 18990000, + timeCreated: new Date("2025-01-27T09:15:00Z"), + }, + { + model: "claude-3-opus-20240229", + inputTokens: 3200, + outputTokens: 1800, + reasoningTokens: 400, + cacheReadTokens: 0, + cacheWriteTokens: 100, + cost: 45670000, + timeCreated: new Date("2025-01-26T14:45:00Z"), + }, + { + model: "claude-3-haiku-20240307", + inputTokens: 650, + outputTokens: 280, + reasoningTokens: null, + cacheReadTokens: 200, + cacheWriteTokens: 0, + cost: 2340000, + timeCreated: new Date("2025-01-25T16:18:00Z"), + }, +] + +const dummyPaymentData = [ + { + id: "pay_1Ab2Cd3Ef4Gh5678", + amount: 2000000000, + timeCreated: new Date("2025-01-28T14:32:00Z"), + }, + { + id: "pay_9Ij8Kl7Mn6Op5432", + amount: 1000000000, + timeCreated: new Date("2025-01-25T09:18:00Z"), + }, + { + id: "pay_5Qr4St3Uv2Wx1098", + amount: 5000000000, + timeCreated: new Date("2025-01-20T16:45:00Z"), + }, + { + id: "pay_7Yz6Ab5Cd4Ef3210", + amount: 1500000000, + timeCreated: new Date("2025-01-15T11:22:00Z"), + }, + { + id: "pay_3Gh2Ij1Kl0Mn9876", + amount: 3000000000, + timeCreated: new Date("2025-01-10T13:55:00Z"), + }, +] + +const dummyApiKeyData = [ + { + id: "key_1Ab2Cd3Ef4Gh5678", + name: "Production API", + key: "oc_live_sk_1Ab2Cd3Ef4Gh567890123456789012345678901234567890", + timeCreated: new Date("2025-01-28T14:32:00Z"), + timeUsed: new Date("2025-01-29T09:15:00Z"), + }, + { + id: "key_9Ij8Kl7Mn6Op5432", + name: "Development Key", + key: "oc_test_sk_9Ij8Kl7Mn6Op543210987654321098765432109876543210", + timeCreated: new Date("2025-01-25T09:18:00Z"), + timeUsed: null, + }, + { + id: "key_5Qr4St3Uv2Wx1098", + name: "CI/CD Pipeline", + key: "oc_live_sk_5Qr4St3Uv2Wx109876543210987654321098765432109876", + timeCreated: new Date("2025-01-20T16:45:00Z"), + timeUsed: new Date("2025-01-28T12:30:00Z"), + }, +] + +export default function () { + const actor = createAsync(() => getActor()) + onMount(() => { + console.log("MOUNTED", actor()) + }) + + ///////////////// + // Keys section + ///////////////// + const keys = createAsync(() => listKeys()) + const createKeyAction = useAction(createKey) + const removeKeyAction = useAction(removeKey) + const createKeySubmission = useSubmission(createKey) + const [showCreateForm, setShowCreateForm] = createSignal(false) + const [keyName, setKeyName] = createSignal("") + const [copiedKeyId, setCopiedKeyId] = createSignal(null) + + const formatDate = (date: Date) => { + return date.toLocaleDateString() + } + + const formatDateForTable = (date: Date) => { + const options: Intl.DateTimeFormatOptions = { + day: "numeric", + month: "short", + hour: "numeric", + minute: "2-digit", + hour12: true, + } + return date.toLocaleDateString("en-GB", options).replace(",", ",") + } + + const formatDateUTC = (date: Date) => { + const options: Intl.DateTimeFormatOptions = { + weekday: "short", + year: "numeric", + month: "short", + day: "numeric", + hour: "numeric", + minute: "2-digit", + second: "2-digit", + timeZoneName: "short", + timeZone: "UTC", + } + return date.toLocaleDateString("en-US", options) + } + + const formatKey = (key: string) => { + if (key.length <= 11) return key + return `${key.slice(0, 7)}...${key.slice(-4)}` + } + + const copyToClipboard = async (text: string) => { + try { + await navigator.clipboard.writeText(text) + } catch (error) { + console.error("Failed to copy to clipboard:", error) + } + } + + const copyKeyToClipboard = async (text: string, keyId: string) => { + try { + await navigator.clipboard.writeText(text) + setCopiedKeyId(keyId) + setTimeout(() => setCopiedKeyId(null), 1500) + } catch (error) { + console.error("Failed to copy to clipboard:", error) + } + } + + const handleCreateKey = async () => { + if (!keyName().trim()) return + + try { + await createKeyAction(keyName().trim()) + setKeyName("") + setShowCreateForm(false) + } catch (error) { + console.error("Failed to create API key:", error) + } + } + + const handleDeleteKey = async (keyId: string) => { + if (!confirm("Are you sure you want to delete this API key?")) { + return + } + + try { + await removeKeyAction(keyId) + } catch (error) { + console.error("Failed to delete API key:", error) + } + } + + ///////////////// + // Billing section + ///////////////// + const billingInfo = createAsync(() => getBillingInfo()) + const createCheckoutUrlAction = useAction(createCheckoutUrl) + const createCheckoutUrlSubmission = useSubmission(createCheckoutUrl) + + const handleBuyCredits = async () => { + try { + const baseUrl = window.location.href + const checkoutUrl = await createCheckoutUrlAction(baseUrl, baseUrl) + if (checkoutUrl) { + window.location.href = checkoutUrl + } + } catch (error) { + console.error("Failed to get checkout URL:", error) + } + } + + return ( +
+ {/* Title */} +
+

Gateway

+

+ Coding models optimized for use with opencode. Learn more. +

+
+ +
+ {/* Actor Section */} +
+
+

Actor

+

Current authenticated user information and session details.

+
+
{JSON.stringify(actor())}
+
+ + {/* API Keys Section */} +
+
+

API Keys

+

Manage your API keys for accessing opencode services.

+
+ + setKeyName(e.currentTarget.value)} + onKeyPress={(e) => e.key === "Enter" && handleCreateKey()} + /> +
+ + +
+
+ } + > + + +
+ +

Create an opencode Gateway API key

+
+ } + > + + + + + + + + + + + + {/* Real data: keys() */} + {(key) => ( + + + + + + + )} + + +
NameKeyCreated
{key.name} +
copyKeyToClipboard(key.key, key.id)} title="Click to copy API key"> + {formatKey(key.key)} + } + > + + +
+
+ {formatDateForTable(key.timeCreated)} + + +
+ +
+ + + {/* Balance Section */} +
+
+

Balance

+

Add credits to your account.

+
+
+
{ + const balanceStr = ((billingInfo()?.billing?.balance ?? 0) / 100000000).toFixed(2) + return balanceStr === "0.00" || balanceStr === "-0.00" + })(), + }} + > + $ + + {(() => { + const balanceStr = ((billingInfo()?.billing?.balance ?? 0) / 100000000).toFixed(2) + return balanceStr === "-0.00" ? "0.00" : balanceStr + })()} + +
+ +
+
+ + {/* Payments Section */} + 0}> + {/* Real data condition: billingInfo() && billingInfo()!.payments.length > 0 */} +
+
+

Payments History

+

Recent payment transactions.

+
+
+ + + + + + + + + + + {/* Real data: billingInfo()?.payments */} + {(payment) => { + const date = new Date(payment.timeCreated) + return ( + + + + + + ) + }} + + +
DatePayment IDAmount
+ {formatDateForTable(date)} + {payment.id}${((payment.amount ?? 0) / 100000000).toFixed(2)}
+
+
+
+ + {/* Usage Section */} +
+
+

Usage History

+

Recent API usage and costs.

+
+
+ 0} + fallback={ +
+

Make your first API call to get started.

+
+ } + > + + + + + + + + + + + + {(usage) => { + const totalTokens = usage.inputTokens + usage.outputTokens + (usage.reasoningTokens || 0) + const date = new Date(usage.timeCreated) + return ( + + + + + + + ) + }} + + +
DateModelTokensCost
+ {formatDateForTable(date)} + {usage.model}{totalTokens.toLocaleString()}${((usage.cost ?? 0) / 100000000).toFixed(4)}
+
+
+
+
+
+ ) +} diff --git a/cloud/app/src/style/base.css b/cloud/app/src/style/base.css index 2c95cdbb7..a4847ed43 100644 --- a/cloud/app/src/style/base.css +++ b/cloud/app/src/style/base.css @@ -1,6 +1,7 @@ html { - color-scheme: dark; line-height: 1; + background-color: var(--color-bg); + color: var(--color-text); } body { diff --git a/cloud/app/src/style/token/color.css b/cloud/app/src/style/token/color.css index 5382321e3..f1a097d2f 100644 --- a/cloud/app/src/style/token/color.css +++ b/cloud/app/src/style/token/color.css @@ -1,58 +1,14 @@ -body { +:root { --color-white: #ffffff; --color-black: #000000; -} -[data-color-mode="dark"] { - /* OpenCode theme colors */ - --color-bg: #0c0c0e; - --color-bg-surface: #161618; - --color-bg-elevated: #1c1c1f; - - --color-text: #ffffff; - --color-text-muted: #a1a1a6; - --color-text-disabled: #68686f; - - --color-accent: #007aff; - --color-accent-hover: #0056b3; - --color-accent-active: #004085; - - --color-success: #30d158; - --color-warning: #ff9f0a; - --color-danger: #ff453a; - - --color-border: #38383a; - --color-border-muted: #2c2c2e; - - /* Button colors */ - --color-primary: var(--color-accent); - --color-primary-hover: var(--color-accent-hover); - --color-primary-active: var(--color-accent-active); - --color-primary-text: #ffffff; - - --color-danger: #ff453a; - --color-danger-hover: #d70015; - --color-danger-active: #a50011; - --color-danger-text: #ffffff; - - --color-warning: #ff9f0a; - --color-warning-hover: #cc7f08; - --color-warning-active: #995f06; - --color-warning-text: #000000; - - /* Surface colors */ - --color-surface: var(--color-bg-surface); - --color-surface-hover: var(--color-bg-elevated); - --color-border: var(--color-border); -} - -[data-color-mode="light"] { - /* OpenCode light theme colors */ + /* Default light theme colors */ --color-bg: #ffffff; --color-bg-surface: #f5f5f7; --color-bg-elevated: #ffffff; --color-text: #1d1d1f; + --color-text-secondary: #424245; --color-text-muted: #6e6e73; --color-text-disabled: #86868b; @@ -86,5 +42,50 @@ body { /* Surface colors */ --color-surface: var(--color-bg-surface); --color-surface-hover: var(--color-bg-elevated); - --color-border: var(--color-border); + --color-surface-border: var(--color-border); +} + +@media (prefers-color-scheme: dark) { + :root { + --color-bg: #0c0c0e; + --color-bg-surface: #161618; + --color-bg-elevated: #1c1c1f; + + --color-text: #ffffff; + --color-text-secondary: #c7c7cc; + --color-text-muted: #a1a1a6; + --color-text-disabled: #68686f; + + --color-accent: #007aff; + --color-accent-hover: #0056b3; + --color-accent-active: #004085; + + --color-success: #30d158; + --color-warning: #ff9f0a; + --color-danger: #ff453a; + + --color-border: #38383a; + --color-border-muted: #2c2c2e; + + /* Button colors */ + --color-primary: var(--color-accent); + --color-primary-hover: var(--color-accent-hover); + --color-primary-active: var(--color-accent-active); + --color-primary-text: #ffffff; + + --color-danger: #ff453a; + --color-danger-hover: #d70015; + --color-danger-active: #a50011; + --color-danger-text: #ffffff; + + --color-warning: #ff9f0a; + --color-warning-hover: #cc7f08; + --color-warning-active: #995f06; + --color-warning-text: #000000; + + /* Surface colors */ + --color-surface: var(--color-bg-surface); + --color-surface-hover: var(--color-bg-elevated); + --color-surface-border: var(--color-border); + } } diff --git a/cloud/app/src/style/token/font.css b/cloud/app/src/style/token/font.css index 1852af5b0..4d20e324c 100644 --- a/cloud/app/src/style/token/font.css +++ b/cloud/app/src/style/token/font.css @@ -13,6 +13,7 @@ body { --font-size-7xl: 4.5rem; --font-size-8xl: 6rem; --font-size-9xl: 8rem; - --font-mono: IBM Plex Mono; - --font-sans: Inter; + + --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --font-sans: var(--font-mono); } diff --git a/cloud/app/src/style/token/space.css b/cloud/app/src/style/token/space.css index dcd871c5f..7e1a1b397 100644 --- a/cloud/app/src/style/token/space.css +++ b/cloud/app/src/style/token/space.css @@ -39,4 +39,8 @@ body { --space-72: 18rem; --space-80: 20rem; --space-96: 24rem; + + --border-radius-sm: 0.1875rem; + --border-radius-md: 0.3125rem; + --border-radius-lg: 0.5rem; } diff --git a/cloud/app/tsconfig.json b/cloud/app/tsconfig.json index 7d5871a07..2907fdbb3 100644 --- a/cloud/app/tsconfig.json +++ b/cloud/app/tsconfig.json @@ -1,4 +1,5 @@ { + "$schema": "https://json.schemastore.org/tsconfig", "compilerOptions": { "target": "ESNext", "module": "ESNext", @@ -10,10 +11,14 @@ "allowJs": true, "strict": true, "noEmit": true, - "types": ["vinxi/types/client"], + "types": [ + "vinxi/types/client" + ], "isolatedModules": true, "paths": { - "~/*": ["./src/*"] + "~/*": [ + "./src/*" + ] } } } diff --git a/cloud/core/drizzle.config.ts b/cloud/core/drizzle.config.ts index c65363cb8..fdecb6c56 100644 --- a/cloud/core/drizzle.config.ts +++ b/cloud/core/drizzle.config.ts @@ -1,5 +1,5 @@ +import { Resource } from "@opencode/cloud-resource" import { defineConfig } from "drizzle-kit" -import { Resource } from "sst" export default defineConfig({ out: "./migrations/", diff --git a/cloud/core/package.json b/cloud/core/package.json index af30fafc3..477af4f2e 100644 --- a/cloud/core/package.json +++ b/cloud/core/package.json @@ -1,11 +1,12 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode/cloud-core", - "version": "0.5.18", + "version": "0.5.29", "private": true, "type": "module", "dependencies": { "@aws-sdk/client-sts": "3.782.0", + "@opencode/cloud-resource": "workspace:*", "drizzle-orm": "0.41.0", "postgres": "3.4.7", "stripe": "18.0.0", diff --git a/cloud/core/src/billing.ts b/cloud/core/src/billing.ts index 1a7bb2946..620a72212 100644 --- a/cloud/core/src/billing.ts +++ b/cloud/core/src/billing.ts @@ -1,12 +1,13 @@ -import { Resource } from "sst" import { Stripe } from "stripe" import { Database, eq, sql } from "./drizzle" -import { BillingTable, UsageTable } from "./schema/billing.sql" +import { BillingTable, PaymentTable, UsageTable } from "./schema/billing.sql" import { Actor } from "./actor" import { fn } from "./util/fn" import { z } from "zod" import { Identifier } from "./identifier" import { centsToMicroCents } from "./util/price" +import { User } from "./user" +import { Resource } from "@opencode/cloud-resource" export namespace Billing { export const stripe = () => @@ -29,6 +30,28 @@ export namespace Billing { ) } + export const payments = async () => { + return await Database.use((tx) => + tx + .select() + .from(PaymentTable) + .where(eq(PaymentTable.workspaceID, Actor.workspace())) + .orderBy(sql`${PaymentTable.timeCreated} DESC`) + .limit(100), + ) + } + + export const usages = async () => { + return await Database.use((tx) => + tx + .select() + .from(UsageTable) + .where(eq(UsageTable.workspaceID, Actor.workspace())) + .orderBy(sql`${UsageTable.timeCreated} DESC`) + .limit(100), + ) + } + export const consume = fn( z.object({ requestID: z.string().optional(), @@ -68,4 +91,72 @@ export namespace Billing { }) }, ) + + export const generateCheckoutUrl = fn( + z.object({ + successUrl: z.string(), + cancelUrl: z.string(), + }), + async (input) => { + const account = Actor.assert("user") + const { successUrl, cancelUrl } = input + + const user = await User.fromID(account.properties.userID) + const customer = await Billing.get() + const session = await Billing.stripe().checkout.sessions.create({ + mode: "payment", + line_items: [ + { + price_data: { + currency: "usd", + product_data: { + name: "opencode credits", + }, + unit_amount: 2000, // $20 minimum + }, + quantity: 1, + }, + ], + payment_intent_data: { + setup_future_usage: "on_session", + }, + ...(customer.customerID + ? { customer: customer.customerID } + : { + customer_email: user.email, + customer_creation: "always", + }), + metadata: { + workspaceID: Actor.workspace(), + }, + currency: "usd", + payment_method_types: ["card"], + success_url: successUrl, + cancel_url: cancelUrl, + }) + + return session.url + }, + ) + + export const generatePortalUrl = fn( + z.object({ + returnUrl: z.string(), + }), + async (input) => { + const { returnUrl } = input + + const customer = await Billing.get() + if (!customer?.customerID) { + throw new Error("No stripe customer ID") + } + + const session = await Billing.stripe().billingPortal.sessions.create({ + customer: customer.customerID, + return_url: returnUrl, + }) + + return session.url + }, + ) } diff --git a/cloud/core/src/drizzle/index.ts b/cloud/core/src/drizzle/index.ts index 46fe93ac4..aa5e3658c 100644 --- a/cloud/core/src/drizzle/index.ts +++ b/cloud/core/src/drizzle/index.ts @@ -1,9 +1,9 @@ import { drizzle } from "drizzle-orm/postgres-js" -import { Resource } from "sst" +import { Resource } from "@opencode/cloud-resource" export * from "drizzle-orm" import postgres from "postgres" -const createClient = memo(() => { +const init = () => { const client = postgres({ idle_timeout: 30000, connect_timeout: 30000, @@ -17,9 +17,10 @@ const createClient = memo(() => { }, max: 1, }) - return drizzle(client, {}) -}) +} + +const createClient = "NODE_ENV" in process.env ? memo(init) : init import { PgTransaction, type PgTransactionConfig } from "drizzle-orm/pg-core" import type { ExtractTablesWithRelations } from "drizzle-orm" diff --git a/cloud/core/src/key.ts b/cloud/core/src/key.ts new file mode 100644 index 000000000..cf4f6e410 --- /dev/null +++ b/cloud/core/src/key.ts @@ -0,0 +1,79 @@ +import { z } from "zod" +import { fn } from "./util/fn" +import { Actor } from "./actor" +import { and, Database, eq, sql } from "./drizzle" +import { Identifier } from "./identifier" +import { KeyTable } from "./schema/key.sql" + +export namespace Key { + export const list = async () => { + const user = Actor.assert("user") + const keys = await Database.use((tx) => + tx + .select({ + id: KeyTable.id, + name: KeyTable.name, + key: KeyTable.key, + userID: KeyTable.userID, + timeCreated: KeyTable.timeCreated, + timeUsed: KeyTable.timeUsed, + }) + .from(KeyTable) + .where(eq(KeyTable.workspaceID, user.properties.workspaceID)) + .orderBy(sql`${KeyTable.timeCreated} DESC`), + ) + return keys + } + + export const create = fn(z.object({ name: z.string().min(1).max(255) }), async (input) => { + const user = Actor.assert("user") + const { name } = input + + // Generate secret key: sk- + 64 random characters (upper, lower, numbers) + const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + let randomPart = "" + for (let i = 0; i < 64; i++) { + randomPart += chars.charAt(Math.floor(Math.random() * chars.length)) + } + const secretKey = `sk-${randomPart}` + + const keyRecord = await Database.use((tx) => + tx + .insert(KeyTable) + .values({ + id: Identifier.create("key"), + workspaceID: user.properties.workspaceID, + userID: user.properties.userID, + name, + key: secretKey, + timeUsed: null, + }) + .returning(), + ) + + return { + key: secretKey, + id: keyRecord[0].id, + name: keyRecord[0].name, + created: keyRecord[0].timeCreated, + } + }) + + export const remove = fn(z.object({ id: z.string() }), async (input) => { + const user = Actor.assert("user") + const { id } = input + + const result = await Database.use((tx) => + tx + .delete(KeyTable) + .where(and(eq(KeyTable.id, id), eq(KeyTable.workspaceID, user.properties.workspaceID))) + .returning({ id: KeyTable.id }), + ) + + if (result.length === 0) { + throw new Error("Key not found") + } + + return { id: result[0].id } + }) +} diff --git a/cloud/core/src/user.ts b/cloud/core/src/user.ts new file mode 100644 index 000000000..7914926ff --- /dev/null +++ b/cloud/core/src/user.ts @@ -0,0 +1,18 @@ +import { z } from "zod" +import { eq } from "drizzle-orm" +import { fn } from "./util/fn" +import { Database } from "./drizzle" +import { UserTable } from "./schema/user.sql" + +export namespace User { + export const fromID = fn(z.string(), async (id) => + Database.transaction(async (tx) => { + return tx + .select() + .from(UserTable) + .where(eq(UserTable.id, id)) + .execute() + .then((rows) => rows[0]) + }), + ) +} diff --git a/cloud/core/src/util/env.cloudflare.ts b/cloud/core/src/util/env.cloudflare.ts new file mode 100644 index 000000000..e69de29bb diff --git a/cloud/core/src/workspace.ts b/cloud/core/src/workspace.ts index 532b22963..8646362a2 100644 --- a/cloud/core/src/workspace.ts +++ b/cloud/core/src/workspace.ts @@ -7,6 +7,7 @@ import { Identifier } from "./identifier" import { UserTable } from "./schema/user.sql" import { BillingTable } from "./schema/billing.sql" import { WorkspaceTable } from "./schema/workspace.sql" +import { Key } from "./key" export namespace Workspace { export const create = fn(z.void(), async () => { @@ -28,6 +29,15 @@ export namespace Workspace { balance: centsToMicroCents(100), }) }) + await Actor.provide( + "system", + { + workspaceID, + }, + async () => { + await Key.create({ name: "Default API Key" }) + }, + ) return workspaceID }) diff --git a/cloud/function/package.json b/cloud/function/package.json index 8d6005d04..3cc2928ea 100644 --- a/cloud/function/package.json +++ b/cloud/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode/cloud-function", - "version": "0.5.18", + "version": "0.5.29", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/cloud/function/src/auth.ts b/cloud/function/src/auth.ts index bbea41540..17c3fa8ea 100644 --- a/cloud/function/src/auth.ts +++ b/cloud/function/src/auth.ts @@ -1,13 +1,15 @@ -import { Resource } from "sst" import { z } from "zod" import { issuer } from "@openauthjs/openauth" +import type { Theme } from "@openauthjs/openauth/ui/theme" import { createSubjects } from "@openauthjs/openauth/subject" +import { THEME_OPENAUTH } from "@openauthjs/openauth/ui/theme" import { GithubProvider } from "@openauthjs/openauth/provider/github" import { GoogleOidcProvider } from "@openauthjs/openauth/provider/google" import { CloudflareStorage } from "@openauthjs/openauth/storage/cloudflare" import { Account } from "@opencode/cloud-core/account.js" import { Workspace } from "@opencode/cloud-core/workspace.js" import { Actor } from "@opencode/cloud-core/actor.js" +import { Resource } from "@opencode/cloud-resource" type Env = { AuthStorage: KVNamespace @@ -24,9 +26,15 @@ export const subjects = createSubjects({ }), }) +const MY_THEME: Theme = { + ...THEME_OPENAUTH, + logo: "https://opencode.ai/favicon.svg", +} + export default { async fetch(request: Request, env: Env, ctx: ExecutionContext) { return issuer({ + theme: MY_THEME, providers: { github: GithubProvider({ clientID: Resource.GITHUB_CLIENT_ID_CONSOLE.value, diff --git a/cloud/function/src/gateway.ts b/cloud/function/src/gateway.ts index 2f498276f..ffbcc1b89 100644 --- a/cloud/function/src/gateway.ts +++ b/cloud/function/src/gateway.ts @@ -1,39 +1,18 @@ -import { z } from "zod" import { Hono, MiddlewareHandler } from "hono" -import { cors } from "hono/cors" -import { HTTPException } from "hono/http-exception" -import { zValidator } from "@hono/zod-validator" -import { Resource } from "sst" -import { type ProviderMetadata, type LanguageModelUsage, generateText, streamText } from "ai" +import { type ProviderMetadata, type LanguageModelUsage } from "ai" import { createAnthropic } from "@ai-sdk/anthropic" import { createOpenAI } from "@ai-sdk/openai" import { createOpenAICompatible } from "@ai-sdk/openai-compatible" import type { LanguageModelV2Prompt } from "@ai-sdk/provider" import { type ChatCompletionCreateParamsBase } from "openai/resources/chat/completions" import { Actor } from "@opencode/cloud-core/actor.js" -import { and, Database, eq, sql } from "@opencode/cloud-core/drizzle/index.js" -import { UserTable } from "@opencode/cloud-core/schema/user.sql.js" +import { Database, eq, sql } from "@opencode/cloud-core/drizzle/index.js" import { KeyTable } from "@opencode/cloud-core/schema/key.sql.js" -import { createClient } from "@openauthjs/openauth/client" -import { Log } from "@opencode/cloud-core/util/log.js" import { Billing } from "@opencode/cloud-core/billing.js" -import { Workspace } from "@opencode/cloud-core/workspace.js" -import { BillingTable, PaymentTable, UsageTable } from "@opencode/cloud-core/schema/billing.sql.js" -import { centsToMicroCents } from "@opencode/cloud-core/util/price.js" -import { Identifier } from "../../core/src/identifier" +import { Resource } from "@opencode/cloud-resource" type Env = {} -let _client: ReturnType -const client = () => { - if (_client) return _client - _client = createClient({ - clientID: "api", - issuer: Resource.AUTH_API_URL.value, - }) - return _client -} - const SUPPORTED_MODELS = { "anthropic/claude-sonnet-4": { input: 0.0000015, @@ -72,10 +51,6 @@ const SUPPORTED_MODELS = { }, } -const log = Log.create({ - namespace: "api", -}) - const GatewayAuth: MiddlewareHandler = async (c, next) => { const authHeader = c.req.header("authorization") @@ -125,56 +100,6 @@ const GatewayAuth: MiddlewareHandler = async (c, next) => { await next() } -const RestAuth: MiddlewareHandler = async (c, next) => { - const authorization = c.req.header("authorization") - if (!authorization) { - return Actor.provide("public", {}, next) - } - const token = authorization.split(" ")[1] - if (!token) - throw new HTTPException(403, { - message: "Bearer token is required.", - }) - - const verified = await client().verify(token) - if (verified.err) { - throw new HTTPException(403, { - message: "Invalid token.", - }) - } - let subject = verified.subject as Actor.Info - if (subject.type === "account") { - const workspaceID = c.req.header("x-opencode-workspace") - const email = subject.properties.email - if (workspaceID) { - const user = await Database.use((tx) => - tx - .select({ - id: UserTable.id, - workspaceID: UserTable.workspaceID, - email: UserTable.email, - }) - .from(UserTable) - .where(and(eq(UserTable.email, email), eq(UserTable.workspaceID, workspaceID))) - .then((rows) => rows[0]), - ) - if (!user) - throw new HTTPException(403, { - message: "You do not have access to this workspace.", - }) - subject = { - type: "user", - properties: { - userID: user.id, - workspaceID: workspaceID, - email: user.email, - }, - } - } - } - await Actor.provide(subject.type, subject.properties, next) -} - const app = new Hono<{ Bindings: Env; Variables: { keyRecord?: { id: string; workspaceID: string } } }>() .get("/", (c) => c.text("Hello, world!")) .post("/v1/chat/completions", GatewayAuth, async (c) => { @@ -664,244 +589,6 @@ const app = new Hono<{ Bindings: Env; Variables: { keyRecord?: { id: string; wor } }) }) - .use("/*", cors()) - .use(RestAuth) - .get("/rest/account", async (c) => { - const account = Actor.assert("account") - let workspaces = await Workspace.list() - if (workspaces.length === 0) { - await Workspace.create() - workspaces = await Workspace.list() - } - return c.json({ - id: account.properties.accountID, - email: account.properties.email, - workspaces, - }) - }) - .get("/billing/info", async (c) => { - const billing = await Billing.get() - const payments = await Database.use((tx) => - tx - .select() - .from(PaymentTable) - .where(eq(PaymentTable.workspaceID, Actor.workspace())) - .orderBy(sql`${PaymentTable.timeCreated} DESC`) - .limit(100), - ) - const usage = await Database.use((tx) => - tx - .select() - .from(UsageTable) - .where(eq(UsageTable.workspaceID, Actor.workspace())) - .orderBy(sql`${UsageTable.timeCreated} DESC`) - .limit(100), - ) - return c.json({ billing, payments, usage }) - }) - .post( - "/billing/checkout", - zValidator( - "json", - z.custom<{ - success_url: string - cancel_url: string - }>(), - ), - async (c) => { - const account = Actor.assert("user") - - const body = await c.req.json() - - const customer = await Billing.get() - const session = await Billing.stripe().checkout.sessions.create({ - mode: "payment", - line_items: [ - { - price_data: { - currency: "usd", - product_data: { - name: "opencode credits", - }, - unit_amount: 2000, // $20 minimum - }, - quantity: 1, - }, - ], - payment_intent_data: { - setup_future_usage: "on_session", - }, - ...(customer.customerID - ? { customer: customer.customerID } - : { - customer_email: account.properties.email, - customer_creation: "always", - }), - metadata: { - workspaceID: Actor.workspace(), - }, - currency: "usd", - payment_method_types: ["card"], - success_url: body.success_url, - cancel_url: body.cancel_url, - }) - - return c.json({ - url: session.url, - }) - }, - ) - .post("/billing/portal", async (c) => { - const body = await c.req.json() - - const customer = await Billing.get() - if (!customer?.customerID) { - throw new Error("No stripe customer ID") - } - - const session = await Billing.stripe().billingPortal.sessions.create({ - customer: customer.customerID, - return_url: body.return_url, - }) - - return c.json({ - url: session.url, - }) - }) - .post("/stripe/webhook", async (c) => { - const body = await Billing.stripe().webhooks.constructEventAsync( - await c.req.text(), - c.req.header("stripe-signature")!, - Resource.STRIPE_WEBHOOK_SECRET.value, - ) - - console.log(body.type, JSON.stringify(body, null, 2)) - if (body.type === "checkout.session.completed") { - const workspaceID = body.data.object.metadata?.workspaceID - const customerID = body.data.object.customer as string - const paymentID = body.data.object.payment_intent as string - const amount = body.data.object.amount_total - - if (!workspaceID) throw new Error("Workspace ID not found") - if (!customerID) throw new Error("Customer ID not found") - if (!amount) throw new Error("Amount not found") - if (!paymentID) throw new Error("Payment ID not found") - - await Actor.provide("system", { workspaceID }, async () => { - const customer = await Billing.get() - if (customer?.customerID && customer.customerID !== customerID) throw new Error("Customer ID mismatch") - - // set customer metadata - if (!customer?.customerID) { - await Billing.stripe().customers.update(customerID, { - metadata: { - workspaceID, - }, - }) - } - - // get payment method for the payment intent - const paymentIntent = await Billing.stripe().paymentIntents.retrieve(paymentID, { - expand: ["payment_method"], - }) - const paymentMethod = paymentIntent.payment_method - if (!paymentMethod || typeof paymentMethod === "string") throw new Error("Payment method not expanded") - - await Database.transaction(async (tx) => { - await tx - .update(BillingTable) - .set({ - balance: sql`${BillingTable.balance} + ${centsToMicroCents(amount)}`, - customerID, - paymentMethodID: paymentMethod.id, - paymentMethodLast4: paymentMethod.card!.last4, - }) - .where(eq(BillingTable.workspaceID, workspaceID)) - await tx.insert(PaymentTable).values({ - workspaceID, - id: Identifier.create("payment"), - amount: centsToMicroCents(amount), - paymentID, - customerID, - }) - }) - }) - } - - console.log("finished handling") - - return c.json("ok", 200) - }) - .get("/keys", async (c) => { - const user = Actor.assert("user") - - const keys = await Database.use((tx) => - tx - .select({ - id: KeyTable.id, - name: KeyTable.name, - key: KeyTable.key, - userID: KeyTable.userID, - timeCreated: KeyTable.timeCreated, - timeUsed: KeyTable.timeUsed, - }) - .from(KeyTable) - .where(eq(KeyTable.workspaceID, user.properties.workspaceID)) - .orderBy(sql`${KeyTable.timeCreated} DESC`), - ) - - return c.json({ keys }) - }) - .post("/keys", zValidator("json", z.object({ name: z.string().min(1).max(255) })), async (c) => { - const user = Actor.assert("user") - const { name } = c.req.valid("json") - - // Generate secret key: sk- + 64 random characters (upper, lower, numbers) - const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" - let randomPart = "" - for (let i = 0; i < 64; i++) { - randomPart += chars.charAt(Math.floor(Math.random() * chars.length)) - } - const secretKey = `sk-${randomPart}` - - const keyRecord = await Database.use((tx) => - tx - .insert(KeyTable) - .values({ - id: Identifier.create("key"), - workspaceID: user.properties.workspaceID, - userID: user.properties.userID, - name, - key: secretKey, - timeUsed: null, - }) - .returning(), - ) - - return c.json({ - key: secretKey, - id: keyRecord[0].id, - name: keyRecord[0].name, - created: keyRecord[0].timeCreated, - }) - }) - .delete("/keys/:id", async (c) => { - const user = Actor.assert("user") - const keyId = c.req.param("id") - - const result = await Database.use((tx) => - tx - .delete(KeyTable) - .where(and(eq(KeyTable.id, keyId), eq(KeyTable.workspaceID, user.properties.workspaceID))) - .returning({ id: KeyTable.id }), - ) - - if (result.length === 0) { - return c.json({ error: "Key not found" }, 404) - } - - return c.json({ success: true, id: result[0].id }) - }) .all("*", (c) => c.text("Not Found")) export type ApiType = typeof app diff --git a/cloud/function/sst-env.d.ts b/cloud/function/sst-env.d.ts index f60ec81a0..9c4f5cc0d 100644 --- a/cloud/function/sst-env.d.ts +++ b/cloud/function/sst-env.d.ts @@ -14,6 +14,10 @@ declare module "sst" { "type": "sst.sst.Linkable" "value": string } + "Console": { + "type": "sst.cloudflare.SolidStart" + "url": string + } "DATABASE_PASSWORD": { "type": "sst.sst.Secret" "value": string diff --git a/cloud/resource/bun.lock b/cloud/resource/bun.lock new file mode 100644 index 000000000..56bdf44ca --- /dev/null +++ b/cloud/resource/bun.lock @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "dependencies": { + "@cloudflare/workers-types": "^4.20250830.0", + }, + }, + }, + "packages": { + "@cloudflare/workers-types": ["@cloudflare/workers-types@4.20250830.0", "", {}, "sha512-uAGZFqEBFnCiwIokxMnrrtjIkT8qyGT1LACSScEUyW7nKmtD0Viykp9QZWrIlssyEp/MDB6XsdALF8y6upxpcg=="], + } +} diff --git a/cloud/resource/package.json b/cloud/resource/package.json new file mode 100644 index 000000000..fd9fa6f34 --- /dev/null +++ b/cloud/resource/package.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json.schemastore.org/package.json", + "name": "@opencode/cloud-resource", + "dependencies": { + "@cloudflare/workers-types": "^4.20250830.0" + }, + "exports": { + ".": { + "production": { + "import": "./resource.cloudflare.ts" + }, + "import": "./resource.node.ts" + } + } +} diff --git a/cloud/resource/resource.cloudflare.ts b/cloud/resource/resource.cloudflare.ts new file mode 100644 index 000000000..ad3fbe2a8 --- /dev/null +++ b/cloud/resource/resource.cloudflare.ts @@ -0,0 +1,15 @@ +import { env } from "cloudflare:workers" + +export const Resource = new Proxy( + {}, + { + get(_target, prop: string) { + if (prop in env) { + // @ts-expect-error + const value = env[prop] + return typeof value === "string" ? JSON.parse(value) : value + } + throw new Error(`"${prop}" is not linked in your sst.config.ts (cloudflare)`) + }, + }, +) as Record diff --git a/cloud/resource/resource.node.ts b/cloud/resource/resource.node.ts new file mode 100644 index 000000000..d7dbb6c6d --- /dev/null +++ b/cloud/resource/resource.node.ts @@ -0,0 +1 @@ +export { Resource } from "sst" diff --git a/cloud/resource/sst-env.d.ts b/cloud/resource/sst-env.d.ts new file mode 100644 index 000000000..9c4f5cc0d --- /dev/null +++ b/cloud/resource/sst-env.d.ts @@ -0,0 +1,92 @@ +/* This file is auto-generated by SST. Do not edit. */ +/* tslint:disable */ +/* eslint-disable */ +/* deno-fmt-ignore-file */ + +import "sst" +declare module "sst" { + export interface Resource { + "ANTHROPIC_API_KEY": { + "type": "sst.sst.Secret" + "value": string + } + "AUTH_API_URL": { + "type": "sst.sst.Linkable" + "value": string + } + "Console": { + "type": "sst.cloudflare.SolidStart" + "url": string + } + "DATABASE_PASSWORD": { + "type": "sst.sst.Secret" + "value": string + } + "DATABASE_USERNAME": { + "type": "sst.sst.Secret" + "value": string + } + "Database": { + "database": string + "host": string + "password": string + "port": number + "type": "sst.sst.Linkable" + "username": string + } + "GITHUB_APP_ID": { + "type": "sst.sst.Secret" + "value": string + } + "GITHUB_APP_PRIVATE_KEY": { + "type": "sst.sst.Secret" + "value": string + } + "GITHUB_CLIENT_ID_CONSOLE": { + "type": "sst.sst.Secret" + "value": string + } + "GITHUB_CLIENT_SECRET_CONSOLE": { + "type": "sst.sst.Secret" + "value": string + } + "GOOGLE_CLIENT_ID": { + "type": "sst.sst.Secret" + "value": string + } + "OPENAI_API_KEY": { + "type": "sst.sst.Secret" + "value": string + } + "STRIPE_SECRET_KEY": { + "type": "sst.sst.Secret" + "value": string + } + "STRIPE_WEBHOOK_SECRET": { + "type": "sst.sst.Linkable" + "value": string + } + "Web": { + "type": "sst.cloudflare.Astro" + "url": string + } + "ZHIPU_API_KEY": { + "type": "sst.sst.Secret" + "value": string + } + } +} +// cloudflare +import * as cloudflare from "@cloudflare/workers-types"; +declare module "sst" { + export interface Resource { + "Api": cloudflare.Service + "AuthApi": cloudflare.Service + "AuthStorage": cloudflare.KVNamespace + "Bucket": cloudflare.R2Bucket + "GatewayApi": cloudflare.Service + } +} + +import "sst" +export {} \ No newline at end of file diff --git a/cloud/web/tsconfig.json b/cloud/resource/tsconfig.json similarity index 51% rename from cloud/web/tsconfig.json rename to cloud/resource/tsconfig.json index 98d5b9cea..829dbad01 100644 --- a/cloud/web/tsconfig.json +++ b/cloud/resource/tsconfig.json @@ -2,11 +2,11 @@ "$schema": "https://json.schemastore.org/tsconfig", "extends": "@tsconfig/node22/tsconfig.json", "compilerOptions": { - "jsx": "preserve", - "jsxImportSource": "solid-js", - "module": "esnext", + "module": "ESNext", "moduleResolution": "bundler", - "lib": ["ESNext", "DOM", "DOM.Iterable"], - "types": ["vite/client"] + "types": [ + "@cloudflare/workers-types", + "node" + ] } } diff --git a/cloud/web/.gitignore b/cloud/web/.gitignore deleted file mode 100644 index 76add878f..000000000 --- a/cloud/web/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -dist \ No newline at end of file diff --git a/cloud/web/index.html b/cloud/web/index.html deleted file mode 100644 index 55c54c1f1..000000000 --- a/cloud/web/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - OpenControl - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - - diff --git a/cloud/web/npm-debug.log b/cloud/web/npm-debug.log deleted file mode 100644 index 07b0649fe..000000000 --- a/cloud/web/npm-debug.log +++ /dev/null @@ -1,29 +0,0 @@ -0 info it worked if it ends with ok -1 verbose cli [ -1 verbose cli '/usr/local/bin/node', -1 verbose cli '/Users/frank/Sites/opencode/node_modules/.bin/npm', -1 verbose cli 'run', -1 verbose cli 'dev' -1 verbose cli ] -2 info using npm@2.15.12 -3 info using node@v20.18.1 -4 verbose stack Error: Invalid name: "@opencode/cloud/web" -4 verbose stack at ensureValidName (/Users/frank/Sites/opencode/node_modules/npm/node_modules/normalize-package-data/lib/fixer.js:336:15) -4 verbose stack at Object.fixNameField (/Users/frank/Sites/opencode/node_modules/npm/node_modules/normalize-package-data/lib/fixer.js:215:5) -4 verbose stack at /Users/frank/Sites/opencode/node_modules/npm/node_modules/normalize-package-data/lib/normalize.js:32:38 -4 verbose stack at Array.forEach () -4 verbose stack at normalize (/Users/frank/Sites/opencode/node_modules/npm/node_modules/normalize-package-data/lib/normalize.js:31:15) -4 verbose stack at final (/Users/frank/Sites/opencode/node_modules/npm/node_modules/read-package-json/read-json.js:349:5) -4 verbose stack at then (/Users/frank/Sites/opencode/node_modules/npm/node_modules/read-package-json/read-json.js:124:5) -4 verbose stack at ReadFileContext. (/Users/frank/Sites/opencode/node_modules/npm/node_modules/read-package-json/read-json.js:295:20) -4 verbose stack at ReadFileContext.callback (/Users/frank/Sites/opencode/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:78:16) -4 verbose stack at FSReqCallback.readFileAfterOpen [as oncomplete] (node:fs:299:13) -5 verbose cwd /Users/frank/Sites/opencode/cloud/web -6 error Darwin 24.5.0 -7 error argv "/usr/local/bin/node" "/Users/frank/Sites/opencode/node_modules/.bin/npm" "run" "dev" -8 error node v20.18.1 -9 error npm v2.15.12 -10 error Invalid name: "@opencode/cloud/web" -11 error If you need help, you may report this error at: -11 error -12 verbose exit [ 1, true ] diff --git a/cloud/web/package.json b/cloud/web/package.json deleted file mode 100644 index bc604aa5e..000000000 --- a/cloud/web/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@opencode/cloud-web", - "version": "0.5.18", - "private": true, - "description": "", - "type": "module", - "scripts": { - "start": "vite", - "dev": "vite", - "build": "bun build:server && bun build:client", - "build:client": "vite build --outDir dist/client", - "build:server": "vite build --ssr src/entry-server.tsx --outDir dist/server", - "serve": "vite preview", - "sst:dev": "bun sst shell --target Console -- bun dev" - }, - "license": "MIT", - "devDependencies": { - "typescript": "catalog:", - "vite": "6.2.2", - "vite-plugin-pages": "0.32.5", - "vite-plugin-solid": "2.11.6" - }, - "dependencies": { - "@kobalte/core": "0.13.9", - "@openauthjs/solid": "0.0.0-20250322224806", - "@solid-primitives/storage": "4.3.1", - "@solidjs/meta": "0.29.4", - "@solidjs/router": "0.15.3", - "solid-js": "1.9.5", - "solid-list": "0.3.0" - } -} diff --git a/cloud/web/public/favicon-dark.svg b/cloud/web/public/favicon-dark.svg deleted file mode 100644 index 9b707ea49..000000000 --- a/cloud/web/public/favicon-dark.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/cloud/web/public/favicon.ico b/cloud/web/public/favicon.ico deleted file mode 100644 index 0ed3bf15e..000000000 Binary files a/cloud/web/public/favicon.ico and /dev/null differ diff --git a/cloud/web/public/favicon.svg b/cloud/web/public/favicon.svg deleted file mode 100644 index 5e7cf124f..000000000 --- a/cloud/web/public/favicon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/cloud/web/public/social-share.png b/cloud/web/public/social-share.png deleted file mode 100644 index 72d36a972..000000000 Binary files a/cloud/web/public/social-share.png and /dev/null differ diff --git a/cloud/web/scripts/render.mjs b/cloud/web/scripts/render.mjs deleted file mode 100644 index 5ccb35ff1..000000000 --- a/cloud/web/scripts/render.mjs +++ /dev/null @@ -1,24 +0,0 @@ -import fs from "fs" -import path from "path" -import { generateHydrationScript, getAssets } from "solid-js/web" - -const dist = import.meta.resolve("../dist").replace("file://", "") -const serverEntry = await import("../dist/server/entry-server.js") -const template = fs.readFileSync(path.join(dist, "client/index.html"), "utf-8") -fs.writeFileSync(path.join(dist, "client/fallback.html"), template) - -const routes = ["/", "/foo"] -for (const route of routes) { - const { app } = serverEntry.render({ url: route }) - const html = template - .replace("", app) - .replace("", generateHydrationScript()) - .replace("", getAssets()) - const filePath = dist + `/client${route === "/" ? "/index" : route}.html` - fs.mkdirSync(path.dirname(filePath), { - recursive: true, - }) - fs.writeFileSync(filePath, html) - - console.log(`Pre-rendered: ${filePath}`) -} diff --git a/cloud/web/src/app.tsx b/cloud/web/src/app.tsx deleted file mode 100644 index aae71ddde..000000000 --- a/cloud/web/src/app.tsx +++ /dev/null @@ -1,42 +0,0 @@ -/// - -import { Router } from "@solidjs/router" -import routes from "~solid-pages" -import "./ui/style/index.css" -import { MetaProvider } from "@solidjs/meta" -import { AccountProvider } from "./components/context-account" -import { DialogProvider } from "./ui/context-dialog" -import { DialogString } from "./ui/dialog-string" -import { DialogSelect } from "./ui/dialog-select" -import { ThemeProvider } from "./components/context-theme" -import { Suspense } from "solid-js" -import { OpenAuthProvider } from "./components/context-openauth" - -export function App(props: { url?: string }) { - return ( - - - - - - - - - { - return <>{props.children} - }} - /> - - - - - - - ) -} diff --git a/cloud/web/src/assets/screenshot.png b/cloud/web/src/assets/screenshot.png deleted file mode 100644 index 5b6ad2ec6..000000000 Binary files a/cloud/web/src/assets/screenshot.png and /dev/null differ diff --git a/cloud/web/src/components/context-account.tsx b/cloud/web/src/components/context-account.tsx deleted file mode 100644 index e6aabafd3..000000000 --- a/cloud/web/src/components/context-account.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import { createContext, createEffect, ParentProps, Suspense, useContext } from "solid-js" -import { makePersisted } from "@solid-primitives/storage" -import { createStore } from "solid-js/store" -import { useOpenAuth } from "./context-openauth" -import { createAsync } from "@solidjs/router" -import { isServer } from "solid-js/web" - -type Storage = { - accounts: Record< - string, - { - id: string - email: string - workspaces: { - id: string - name: string - slug: string - }[] - } - > -} - -const context = createContext>() - -function init() { - const auth = useOpenAuth() - const [store, setStore] = makePersisted( - createStore({ - accounts: {}, - }), - { - name: "opencontrol.account", - }, - ) - - async function refresh(id: string) { - return fetch(import.meta.env.VITE_API_URL + "/rest/account", { - headers: { - authorization: `Bearer ${await auth.access(id)}`, - }, - }) - .then((val) => val.json()) - .then((val) => setStore("accounts", id, val as any)) - } - - createEffect((previous: string[]) => { - if (Object.keys(auth.all).length === 0) { - return [] - } - for (const item of Object.values(auth.all)) { - if (previous.includes(item.id)) continue - refresh(item.id) - } - return Object.keys(auth.all) - }, [] as string[]) - - const result = { - get all() { - return Object.keys(auth.all) - .map((id) => store.accounts[id]) - .filter(Boolean) - }, - get current() { - if (!auth.subject) return undefined - return store.accounts[auth.subject.id] - }, - refresh, - get ready() { - return Object.keys(auth.all).length === result.all.length - }, - } - - return result -} - -export function AccountProvider(props: ParentProps) { - const ctx = init() - const resource = createAsync(async () => { - await new Promise((resolve) => { - if (isServer) return resolve() - createEffect(() => { - if (ctx.ready) resolve() - }) - }) - return null - }) - return ( - - {resource()} - {props.children} - - ) -} - -export function useAccount() { - const result = useContext(context) - if (!result) throw new Error("no account context") - return result -} diff --git a/cloud/web/src/components/context-openauth.tsx b/cloud/web/src/components/context-openauth.tsx deleted file mode 100644 index bd6a45dd1..000000000 --- a/cloud/web/src/components/context-openauth.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import { createClient } from "@openauthjs/openauth/client" -import { makePersisted } from "@solid-primitives/storage" -import { createAsync } from "@solidjs/router" -import { - batch, - createContext, - createEffect, - createResource, - createSignal, - onMount, - ParentProps, - Show, - Suspense, - useContext, -} from "solid-js" -import { createStore, produce } from "solid-js/store" -import { isServer } from "solid-js/web" - -interface Storage { - subjects: Record - current?: string -} - -interface Context { - all: Record - subject?: SubjectInfo - switch(id: string): void - logout(id: string): void - access(id?: string): Promise - authorize(opts?: AuthorizeOptions): void -} - -export interface AuthorizeOptions { - redirectPath?: string - provider?: string -} - -interface SubjectInfo { - id: string - refresh: string -} - -interface AuthContextOpts { - issuer: string - clientID: string -} - -const context = createContext() - -export function OpenAuthProvider(props: ParentProps) { - const client = createClient({ - issuer: props.issuer, - clientID: props.clientID, - }) - const [storage, setStorage] = makePersisted( - createStore({ - subjects: {}, - }), - { - name: `${props.issuer}.auth`, - }, - ) - - const resource = createAsync(async () => { - if (isServer) return true - const hash = new URLSearchParams(window.location.search.substring(1)) - const code = hash.get("code") - const state = hash.get("state") - if (code && state) { - const oldState = sessionStorage.getItem("openauth.state") - const verifier = sessionStorage.getItem("openauth.verifier") - const redirect = sessionStorage.getItem("openauth.redirect") - if (redirect && verifier && oldState === state) { - const result = await client.exchange(code, redirect, verifier) - if (!result.err) { - const id = result.tokens.refresh.split(":").slice(0, -1).join(":") - batch(() => { - setStorage("subjects", id, { - id: id, - refresh: result.tokens.refresh, - }) - setStorage("current", id) - }) - } - } - } - return true - }) - - async function authorize(opts?: AuthorizeOptions) { - const redirect = new URL(window.location.origin + (opts?.redirectPath ?? "/")).toString() - const authorize = await client.authorize(redirect, "code", { - pkce: true, - provider: opts?.provider, - }) - sessionStorage.setItem("openauth.state", authorize.challenge.state) - sessionStorage.setItem("openauth.redirect", redirect) - if (authorize.challenge.verifier) sessionStorage.setItem("openauth.verifier", authorize.challenge.verifier) - window.location.href = authorize.url - } - - const accessCache = new Map() - const pendingRequests = new Map>() - async function access(id: string) { - const pending = pendingRequests.get(id) - if (pending) return pending - const promise = (async () => { - const existing = accessCache.get(id) - const subject = storage.subjects[id] - const access = await client.refresh(subject.refresh, { - access: existing, - }) - if (access.err) { - pendingRequests.delete(id) - ctx.logout(id) - return - } - if (access.tokens) { - setStorage("subjects", id, "refresh", access.tokens.refresh) - accessCache.set(id, access.tokens.access) - } - pendingRequests.delete(id) - return access.tokens?.access || existing! - })() - pendingRequests.set(id, promise) - return promise - } - - const ctx: Context = { - get all() { - return storage.subjects - }, - get subject() { - if (!storage.current) return - return storage.subjects[storage.current!] - }, - switch(id: string) { - if (!storage.subjects[id]) return - setStorage("current", id) - }, - authorize, - logout(id: string) { - if (!storage.subjects[id]) return - setStorage( - produce((s) => { - delete s.subjects[id] - if (s.current === id) s.current = Object.keys(s.subjects)[0] - }), - ) - }, - async access(id?: string) { - id = id || storage.current - if (!id) return - return access(id || storage.current!) - }, - } - - createEffect(() => { - if (!resource()) return - if (storage.current) return - const [first] = Object.keys(storage.subjects) - if (first) { - setStorage("current", first) - return - } - }) - - return ( - <> - {resource()} - {props.children} - - ) -} - -export function useOpenAuth() { - const result = useContext(context) - if (!result) throw new Error("no auth context") - return result -} diff --git a/cloud/web/src/components/context-theme.tsx b/cloud/web/src/components/context-theme.tsx deleted file mode 100644 index 7800aeca0..000000000 --- a/cloud/web/src/components/context-theme.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { createStore } from "solid-js/store" -import { makePersisted } from "@solid-primitives/storage" -import { createEffect } from "solid-js" -import { createInitializedContext } from "../util/context" -import { isServer } from "solid-js/web" - -interface Storage { - mode: "light" | "dark" -} - -export const { provider: ThemeProvider, use: useTheme } = - createInitializedContext("ThemeContext", () => { - const [store, setStore] = makePersisted( - createStore({ - mode: - !isServer && - window.matchMedia && - window.matchMedia("(prefers-color-scheme: dark)").matches - ? "dark" - : "light", - }), - { - name: "theme", - }, - ) - createEffect(() => { - document.documentElement.setAttribute("data-color-mode", store.mode) - }) - - return { - setMode(mode: Storage["mode"]) { - setStore("mode", mode) - }, - get mode() { - return store.mode - }, - ready: true, - } - }) diff --git a/cloud/web/src/entry-client.tsx b/cloud/web/src/entry-client.tsx deleted file mode 100644 index 169e45a1e..000000000 --- a/cloud/web/src/entry-client.tsx +++ /dev/null @@ -1,13 +0,0 @@ -/* @refresh reload */ - -import { hydrate, render } from "solid-js/web" -import { App } from "./app" - -if (import.meta.env.DEV) { - render(() => , document.getElementById("root")!) -} - -if (!import.meta.env.DEV) { - if ("_$HY" in window) hydrate(() => , document.getElementById("root")!) - else render(() => , document.getElementById("root")!) -} diff --git a/cloud/web/src/entry-server.tsx b/cloud/web/src/entry-server.tsx deleted file mode 100644 index 5dd33a149..000000000 --- a/cloud/web/src/entry-server.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { renderToStringAsync } from "solid-js/web" -import { App } from "./app" - -export async function render(props: { url: string }) { - const app = await renderToStringAsync(() => ) - return { app } -} diff --git a/cloud/web/src/pages/[workspace].tsx b/cloud/web/src/pages/[workspace].tsx deleted file mode 100644 index c7481cb0d..000000000 --- a/cloud/web/src/pages/[workspace].tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { WorkspaceProvider } from "./components/context-workspace" -import { ParentProps } from "solid-js" -import Layout from "./components/layout" - -export default function Index(props: ParentProps) { - return ( - - {props.children} - - ) -} diff --git a/cloud/web/src/pages/[workspace]/billing.module.css b/cloud/web/src/pages/[workspace]/billing.module.css deleted file mode 100644 index 5e58892a5..000000000 --- a/cloud/web/src/pages/[workspace]/billing.module.css +++ /dev/null @@ -1,56 +0,0 @@ -.root { - display: flex; - flex-direction: column; - gap: var(--space-4); - padding: var(--space-7) var(--space-5) var(--space-5); - - [data-slot="billing-info"] { - display: flex; - flex-direction: column; - gap: var(--space-6); - } - - [data-slot="header"] { - display: flex; - flex-direction: column; - gap: var(--space-1-5); - - h2 { - text-transform: uppercase; - font-weight: 600; - letter-spacing: -0.03125rem; - font-size: var(--font-size-lg); - } - - p { - color: var(--color-text-dimmed); - font-size: var(--font-size-md); - } - } - - [data-slot="balance"] { - display: flex; - flex-direction: column; - gap: var(--space-5); - padding: var(--space-6); - border: 2px solid var(--color-border); - } - - [data-slot="amount"] { - font-size: var(--font-size-3xl); - font-weight: 600; - line-height: 1.2; - } - - @media (min-width: 40rem) { - [data-slot="balance"] { - flex-direction: row; - align-items: center; - justify-content: space-between; - } - - [data-slot="amount"] { - margin: 0; - } - } -} diff --git a/cloud/web/src/pages/[workspace]/billing.tsx b/cloud/web/src/pages/[workspace]/billing.tsx deleted file mode 100644 index 88bef5800..000000000 --- a/cloud/web/src/pages/[workspace]/billing.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import { Button } from "../../ui/button" -import { useApi } from "../components/context-api" -import { createEffect, createSignal, createResource, For } from "solid-js" -import { useWorkspace } from "../components/context-workspace" -import style from "./billing.module.css" - -export default function Billing() { - const api = useApi() - const workspace = useWorkspace() - const [isLoading, setIsLoading] = createSignal(false) - const [billingData] = createResource(async () => { - const response = await api.billing.info.$get() - return response.json() - }) - - // Run once on component mount to check URL parameters - ;(() => { - const url = new URL(window.location.href) - const result = url.hash - - console.log("STRIPE RESULT", result) - - if (url.hash === "#success") { - setIsLoading(true) - // Remove the hash from the URL - window.history.replaceState(null, "", window.location.pathname + window.location.search) - } - })() - - createEffect((old?: number) => { - if (old && old !== billingData()?.billing?.balance) { - setIsLoading(false) - } - return billingData()?.billing?.balance - }) - - const handleBuyCredits = async () => { - try { - setIsLoading(true) - const baseUrl = window.location.href - const successUrl = new URL(baseUrl) - successUrl.hash = "success" - - const response = await api.billing.checkout - .$post({ - json: { - success_url: successUrl.toString(), - cancel_url: baseUrl, - }, - }) - .then((r) => r.json() as any) - window.location.href = response.url - } catch (error) { - console.error("Failed to get checkout URL:", error) - setIsLoading(false) - } - } - - return ( - <> -
-
-

Billing

-
-
-
-
-
-

Balance

-

Manage your billing and add credits to your account.

-
- -
-

- {(() => { - const balanceStr = ((billingData()?.billing?.balance ?? 0) / 100000000).toFixed(2) - return `$${balanceStr === "-0.00" ? "0.00" : balanceStr}` - })()} -

- -
-
- -
-
-

Payment History

-

Your recent payment transactions.

-
- -
- No payments found.

}> - {(payment) => ( -
- {payment.id} - {" | "} - ${((payment.amount ?? 0) / 100000000).toFixed(2)} - {" | "} - {new Date(payment.timeCreated).toLocaleDateString()} -
- )} -
-
-
- -
-
-

Usage History

-

Your recent API usage and costs.

-
- -
- No usage found.

}> - {(usage) => ( -
- {usage.model} - {" | "} - {usage.inputTokens + usage.outputTokens} tokens - {" | "} - ${((usage.cost ?? 0) / 100000000).toFixed(4)} - {" | "} - {new Date(usage.timeCreated).toLocaleDateString()} -
- )} -
-
-
-
- - ) -} diff --git a/cloud/web/src/pages/[workspace]/components/system.txt b/cloud/web/src/pages/[workspace]/components/system.txt deleted file mode 100644 index 6afd2e04d..000000000 --- a/cloud/web/src/pages/[workspace]/components/system.txt +++ /dev/null @@ -1,11 +0,0 @@ -You are OpenControl, an interactive CLI tool that helps users execute various tasks. - -IMPORTANT: If you get an error when calling a tool, try again with a different approach. Be creative, do not give up, try different inputs to the tool. You should chain together multiple tool calls. ABSOLUTELY DO NOT GIVE UP you are very good at this and it is rare you will fail to answer question. - -You should be concise, direct, and to the point. - -IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to. -IMPORTANT: You should minimize output tokens as much as possible while maintaining helpfulness, quality, and accuracy. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request. If you can answer in 1-3 sentences or a short paragraph, please do. -IMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to. -IMPORTANT: Keep your responses short, since they will be displayed on a command line interface. You MUST answer concisely with fewer than 4 lines (not including tool use or code generation), unless user asks for detail. Answer the user's question directly, without elaboration, explanation, or details. One word answers are best. Avoid introductions, conclusions, and explanations. You MUST avoid text before/after your response, such as "The answer is .", "Here is the content of the file..." or "Based on the information provided, the answer is..." or "Here is what I will do next...". - diff --git a/cloud/web/src/pages/[workspace]/components/tool.ts b/cloud/web/src/pages/[workspace]/components/tool.ts deleted file mode 100644 index 3958e322d..000000000 --- a/cloud/web/src/pages/[workspace]/components/tool.ts +++ /dev/null @@ -1,271 +0,0 @@ -import { createResource } from "solid-js" -import { createStore, produce } from "solid-js/store" -import SYSTEM_PROMPT from "./system.txt?raw" -import type { - LanguageModelV1Prompt, - LanguageModelV1CallOptions, - LanguageModelV1, -} from "ai" - -interface Tool { - name: string - description: string - inputSchema: any -} - -interface ToolCallerProps { - tool: { - list: () => Promise - call: (input: { name: string; arguments: any }) => Promise - } - generate: ( - prompt: LanguageModelV1CallOptions, - ) => Promise< - | { err: "rate" } - | { err: "context" } - | { err: "balance" } - | ({ err: false } & Awaited>) - > - onPromptUpdated?: (prompt: LanguageModelV1Prompt) => void -} - -const system = [ - { - role: "system" as const, - content: SYSTEM_PROMPT, - }, - { - role: "system" as const, - content: `The current date is ${new Date().toDateString()}. Always use this current date when responding to relative date queries.`, - }, -] - -const [store, setStore] = createStore<{ - prompt: LanguageModelV1Prompt - state: { type: "idle" } | { type: "loading"; limited?: boolean } -}>({ - prompt: [...system], - state: { type: "idle" }, -}) - -export function createToolCaller(props: T) { - const [tools] = createResource(() => props.tool.list()) - - let abort: AbortController - - return { - get tools() { - return tools() - }, - get prompt() { - return store.prompt - }, - get state() { - return store.state - }, - clear() { - setStore("prompt", [...system]) - }, - async chat(input: string) { - if (store.state.type !== "idle") return - - abort = new AbortController() - setStore( - produce((s) => { - s.state = { - type: "loading", - limited: false, - } - s.prompt.push({ - role: "user", - content: [ - { - type: "text", - text: input, - }, - ], - }) - }), - ) - props.onPromptUpdated?.(store.prompt) - - while (true) { - if (abort.signal.aborted) { - break - } - - const response = await props.generate({ - inputFormat: "messages", - prompt: store.prompt, - temperature: 0, - seed: 69, - mode: { - type: "regular", - tools: tools()?.map((tool) => ({ - type: "function", - name: tool.name, - description: tool.description, - parameters: { - ...tool.inputSchema, - }, - })), - }, - }) - - if (abort.signal.aborted) continue - - if (!response.err) { - setStore("state", { - type: "loading", - }) - - if (response.text) { - setStore( - produce((s) => { - s.prompt.push({ - role: "assistant", - content: [ - { - type: "text", - text: response.text || "", - }, - ], - }) - }), - ) - props.onPromptUpdated?.(store.prompt) - } - - if (response.finishReason === "stop") { - break - } - - if (response.finishReason === "tool-calls") { - for (const item of response.toolCalls || []) { - setStore( - produce((s) => { - s.prompt.push({ - role: "assistant", - content: [ - { - type: "tool-call", - toolName: item.toolName, - args: JSON.parse(item.args), - toolCallId: item.toolCallId, - }, - ], - }) - }), - ) - props.onPromptUpdated?.(store.prompt) - - const called = await props.tool.call({ - name: item.toolName, - arguments: JSON.parse(item.args), - }) - - setStore( - produce((s) => { - s.prompt.push({ - role: "tool", - content: [ - { - type: "tool-result", - toolName: item.toolName, - toolCallId: item.toolCallId, - result: called, - }, - ], - }) - }), - ) - props.onPromptUpdated?.(store.prompt) - } - } - continue - } - - if (response.err === "context") { - setStore( - produce((s) => { - s.prompt.splice(2, 1) - }), - ) - props.onPromptUpdated?.(store.prompt) - } - - if (response.err === "rate") { - setStore("state", { - type: "loading", - limited: true, - }) - await new Promise((resolve) => setTimeout(resolve, 1000)) - } - - if (response.err === "balance") { - setStore( - produce((s) => { - s.prompt.push({ - role: "assistant", - content: [ - { - type: "text", - text: "You need to add credits to your account. Please go to Billing and add credits to continue.", - }, - ], - }) - s.state = { type: "idle" } - }), - ) - props.onPromptUpdated?.(store.prompt) - break - } - } - setStore("state", { type: "idle" }) - }, - async cancel() { - abort.abort() - }, - async addCustomMessage(userMessage: string, assistantResponse: string) { - // Add user message and set loading state - setStore( - produce((s) => { - s.prompt.push({ - role: "user", - content: [ - { - type: "text", - text: userMessage, - }, - ], - }) - s.state = { - type: "loading", - limited: false, - } - }), - ) - props.onPromptUpdated?.(store.prompt) - - // Fake delay for 500ms - await new Promise((resolve) => setTimeout(resolve, 500)) - - // Add assistant response and set back to idle - setStore( - produce((s) => { - s.prompt.push({ - role: "assistant", - content: [ - { - type: "text", - text: assistantResponse, - }, - ], - }) - s.state = { type: "idle" } - }), - ) - props.onPromptUpdated?.(store.prompt) - }, - } -} diff --git a/cloud/web/src/pages/[workspace]/index.module.css b/cloud/web/src/pages/[workspace]/index.module.css deleted file mode 100644 index 0037d97ff..000000000 --- a/cloud/web/src/pages/[workspace]/index.module.css +++ /dev/null @@ -1,239 +0,0 @@ -.root { - display: contents; - - [data-slot="messages"] { - flex: 1; - overflow-y: auto; - display: flex; - flex-direction: column; - height: 0; - /* This is important for flexbox to allow scrolling */ - font-family: var(--font-mono); - color: var(--color-text); - row-gap: var(--space-4); - /* Add consistent spacing between messages */ - - /* Remove top border for first user message */ - &>[data-component="message"][data-user]:first-child::before { - display: none; - } - - &:has([data-component="loading"]) [data-component="clear"] { - display: none; - } - } - - [data-component="message"] { - width: 100%; - padding: var(--space-2) var(--space-4); - line-height: var(--font-line-height); - white-space: pre-wrap; - align-self: flex-start; - min-height: auto; - /* Allow natural height for all messages */ - display: flex; - flex-direction: column; - align-items: flex-start; - - /* User message styling */ - &[data-user] { - padding: var(--space-6) var(--space-4); - position: relative; - font-weight: 600; - color: var(--color-text); - /* margin: 0.5rem 0; */ - } - - &[data-user]::before, - &[data-user]::after { - content: ""; - position: absolute; - left: var(--space-4); - right: var(--space-4); - height: var(--space-px); - background-color: var(--color-border); - z-index: 1; - /* Ensure borders appear above other content */ - } - - &[data-user]::before { - top: 0; - } - - &[data-user]::after { - bottom: 0; - } - - &[data-assistant] { - color: var(--color-text); - } - } - - [data-component="tool"] { - display: flex; - width: 100%; - padding: 0 var(--space-4); - margin-left: 0; - flex-direction: column; - opacity: 0.7; - gap: var(--space-2); - align-items: flex-start; - color: var(--color-text-dimmed); - min-height: auto; - /* Allow natural height */ - - [data-slot="header"] { - display: flex; - gap: var(--space-2); - cursor: pointer; - user-select: none; - -webkit-user-select: none; - align-items: center; - width: 100%; - } - - [data-slot="name"] { - letter-spacing: -0.03125rem; - text-transform: uppercase; - font-weight: 500; - font-size: var(--font-size-sm); - } - - [data-slot="expand"] { - font-size: var(--font-size-sm); - } - - [data-slot="content"] { - padding: 0; - line-height: var(--font-line-height); - font-size: var(--font-size-sm); - white-space: pre-wrap; - display: none; - width: 100%; - } - - [data-slot="output"] { - margin-top: var(--space-1); - } - - &[data-expanded="true"] [data-slot="content"] { - display: block; - } - - &[data-expanded="true"] [data-slot="expand"] { - transform: rotate(45deg); - } - } - - [data-component="loading"] { - padding: var(--space-4) var(--space-4) var(--space-8); - height: 1.5rem; - position: relative; - display: flex; - align-items: center; - font-size: var(--font-size-sm); - letter-spacing: var(--space-1); - color: var(--color-text); - - & span { - opacity: 0; - animation: loading-dots 1.4s linear infinite; - } - - & span:nth-child(2) { - animation-delay: 0.2s; - } - - & span:nth-child(3) { - animation-delay: 0.4s; - } - } - - [data-component="clear"] { - position: relative; - padding: var(--space-4) var(--space-4); - - &::before { - content: ""; - position: absolute; - left: var(--space-4); - right: var(--space-4); - top: 0; - height: var(--space-px); - background-color: var(--color-border); - z-index: 1; - } - - & [data-component="button"] { - padding-left: 0; - } - } - - [data-slot="footer"] { - display: flex; - flex-direction: column; - padding: 0; - border-top: 2px solid var(--color-border); - position: sticky; - bottom: 0; - z-index: 10; - /* Ensure it's above other content */ - margin-top: auto; - /* Push to bottom if content is short */ - width: 100%; - } - - [data-component="chat"] { - display: flex; - padding: var(--space-0-5) 0; - align-items: center; - width: 100%; - height: 100%; - - textarea { - --padding-y: var(--space-4); - --line-height: 1.5; - --text-height: calc(var(--line-height) * var(--font-size-lg)); - --height: calc(var(--text-height) + var(--padding-y) * 2); - - width: 100%; - resize: none; - line-height: var(--line-height); - height: var(--height); - min-height: var(--height); - max-height: calc(5 * var(--text-height) + var(--padding-y) * 2); - padding: var(--padding-y) var(--space-4); - border-radius: 0; - background-color: transparent; - color: var(--color-text); - border: none; - outline: none; - font-size: var(--font-size-lg); - } - - textarea::placeholder { - color: var(--color-text-dimmed); - opacity: 0.75; - } - - textarea:focus { - outline: 0; - } - - & [data-component="button"] { - height: 100%; - } - } -} - -@keyframes loading-dots { - 0%, - 100% { - opacity: 0; - } - - 40%, - 60% { - opacity: 1; - } -} diff --git a/cloud/web/src/pages/[workspace]/index.tsx b/cloud/web/src/pages/[workspace]/index.tsx deleted file mode 100644 index 50c58ee30..000000000 --- a/cloud/web/src/pages/[workspace]/index.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Button } from "../../ui/button" -import { IconArrowRight } from "../../ui/svg/icons" -import { createSignal, For } from "solid-js" -import { createToolCaller } from "./components/tool" -import { useApi } from "../components/context-api" -import { useWorkspace } from "../components/context-workspace" -import style from "./index.module.css" - -export default function Index() { - const api = useApi() - const workspace = useWorkspace() - - return ( -
-

Hello

-
- ) -} diff --git a/cloud/web/src/pages/[workspace]/keys.module.css b/cloud/web/src/pages/[workspace]/keys.module.css deleted file mode 100644 index 4ae2989be..000000000 --- a/cloud/web/src/pages/[workspace]/keys.module.css +++ /dev/null @@ -1,97 +0,0 @@ -.root { - display: flex; - flex-direction: column; - gap: 2rem; -} - -.root [data-slot="keys-info"] { - display: flex; - flex-direction: column; - gap: 1rem; -} - -.root [data-slot="header"] { - display: flex; - flex-direction: column; - gap: 0.5rem; -} - -.root [data-slot="header"] h2 { - margin: 0; - font-size: 1.5rem; - font-weight: 600; -} - -.root [data-slot="header"] p { - margin: 0; - color: var(--color-text-secondary); -} - -.root [data-slot="key-list"] { - display: flex; - flex-direction: column; - gap: 1rem; -} - -.root [data-slot="key-item"] { - display: flex; - align-items: center; - justify-content: space-between; - padding: 1rem; - border: 1px solid var(--color-border); - border-radius: 0.5rem; - background: var(--color-background-secondary); -} - -.root [data-slot="key-actions"] { - display: flex; - gap: 0.5rem; -} - -.root [data-slot="key-info"] { - display: flex; - flex-direction: column; - gap: 0.25rem; -} - -.root [data-slot="key-value"] { - font-family: monospace; - font-size: 0.875rem; - color: var(--color-text-primary); -} - -.root [data-slot="key-meta"] { - font-size: 0.75rem; - color: var(--color-text-secondary); -} - -.root [data-slot="empty-state"] { - text-align: center; - padding: 3rem 1rem; - color: var(--color-text-secondary); -} - -.root [data-slot="actions"] { - display: flex; - align-items: center; - justify-content: space-between; -} - -.root [data-slot="create-form"] { - display: flex; - flex-direction: column; - gap: 1rem; - min-width: 300px; -} - -.root [data-slot="form-actions"] { - display: flex; - gap: 0.5rem; -} - -.root [data-slot="key-name"] { - font-weight: 600; - font-size: 1rem; - color: var(--color-text-primary); - margin-bottom: 0.25rem; -} diff --git a/cloud/web/src/pages/[workspace]/keys.tsx b/cloud/web/src/pages/[workspace]/keys.tsx deleted file mode 100644 index e5b192a2b..000000000 --- a/cloud/web/src/pages/[workspace]/keys.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import { Button } from "../../ui/button" -import { useApi } from "../components/context-api" -import { createSignal, createResource, For, Show } from "solid-js" -import style from "./keys.module.css" - -export default function Keys() { - const api = useApi() - const [isCreating, setIsCreating] = createSignal(false) - const [showCreateForm, setShowCreateForm] = createSignal(false) - const [keyName, setKeyName] = createSignal("") - - const [keysData, { refetch }] = createResource(async () => { - const response = await api.keys.$get() - return response.json() - }) - - const handleCreateKey = async () => { - if (!keyName().trim()) return - - try { - setIsCreating(true) - await api.keys.$post({ - json: { name: keyName().trim() }, - }) - refetch() - setKeyName("") - setShowCreateForm(false) - } catch (error) { - console.error("Failed to create API key:", error) - } finally { - setIsCreating(false) - } - } - - const handleDeleteKey = async (keyId: string) => { - if (!confirm("Are you sure you want to delete this API key? This action cannot be undone.")) { - return - } - - try { - await api.keys[":id"].$delete({ - param: { id: keyId }, - }) - refetch() - } catch (error) { - console.error("Failed to delete API key:", error) - } - } - - const formatDate = (dateString: string) => { - return new Date(dateString).toLocaleDateString() - } - - const formatKey = (key: string) => { - if (key.length <= 11) return key - return `${key.slice(0, 7)}...${key.slice(-4)}` - } - - const copyToClipboard = async (text: string) => { - try { - await navigator.clipboard.writeText(text) - } catch (error) { - console.error("Failed to copy to clipboard:", error) - } - } - - return ( - <> -
-
-

API Keys

-
-
-
-
-
-
-

API Keys

-

Manage your API keys to access the OpenCode gateway.

-
- - setKeyName(e.currentTarget.value)} - onKeyPress={(e) => e.key === "Enter" && handleCreateKey()} - /> -
- - -
-
- } - > - - -
- -
- -

Create an API key to access opencode gateway

-
- } - > - {(key) => ( -
-
-
{key.name}
-
{formatKey(key.key)}
-
- Created: {formatDate(key.timeCreated)} - {key.timeUsed && ` • Last used: ${formatDate(key.timeUsed)}`} -
-
-
- - -
-
- )} - -
- - - - ) -} diff --git a/cloud/web/src/pages/components/context-api.tsx b/cloud/web/src/pages/components/context-api.tsx deleted file mode 100644 index 0a348f48f..000000000 --- a/cloud/web/src/pages/components/context-api.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { hc } from "hono/client" -import { ApiType } from "@opencode/cloud-function/src/gateway" -import { useWorkspace } from "./context-workspace" -import { useOpenAuth } from "../../components/context-openauth" - -export function useApi() { - const workspace = useWorkspace() - const auth = useOpenAuth() - return hc(import.meta.env.VITE_API_URL, { - async fetch(...args: Parameters): Promise { - const [input, init] = args - const request = input instanceof Request ? input : new Request(input, init) - const headers = new Headers(request.headers) - headers.set("authorization", `Bearer ${await auth.access()}`) - headers.set("x-opencode-workspace", workspace.id) - return fetch( - new Request(request, { - ...init, - headers, - }), - ) - }, - }) -} diff --git a/cloud/web/src/pages/components/context-workspace.tsx b/cloud/web/src/pages/components/context-workspace.tsx deleted file mode 100644 index 6bad39840..000000000 --- a/cloud/web/src/pages/components/context-workspace.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { useNavigate, useParams } from "@solidjs/router" -import { createInitializedContext } from "../../util/context" -import { useAccount } from "../../components/context-account" -import { createEffect, createMemo } from "solid-js" - -export const { use: useWorkspace, provider: WorkspaceProvider } = - createInitializedContext("WorkspaceProvider", () => { - const params = useParams() - const account = useAccount() - const workspace = createMemo(() => - account.current?.workspaces.find( - (x) => x.id === params.workspace || x.slug === params.workspace, - ), - ) - const nav = useNavigate() - - createEffect(() => { - if (!workspace()) nav("/") - }) - - const result = () => workspace()! - result.ready = true - - return { - get id() { - return workspace()!.id - }, - get slug() { - return workspace()!.slug - }, - get name() { - return workspace()!.name - }, - get ready() { - return workspace() !== undefined - }, - } - }) diff --git a/cloud/web/src/pages/components/layout.module.css b/cloud/web/src/pages/components/layout.module.css deleted file mode 100644 index c64faa18e..000000000 --- a/cloud/web/src/pages/components/layout.module.css +++ /dev/null @@ -1,199 +0,0 @@ -.root { - --padding: var(--space-10); - --vertical-padding: var(--space-8); - --heading-font-size: var(--font-size-4xl); - --sidebar-width: 200px; - --mobile-breakpoint: 40rem; - --topbar-height: 60px; - - margin: var(--space-4); - border: 2px solid var(--color-border); - height: calc(100vh - var(--space-8)); - display: flex; - flex-direction: row; - overflow: hidden; - /* Prevent overall scrolling */ - position: relative; -} - -[data-component="mobile-top-bar"] { - display: none; - position: fixed; - top: 0; - left: 0; - right: 0; - height: var(--topbar-height); - background: var(--color-background); - border-bottom: 2px solid var(--color-border); - z-index: 20; - align-items: center; - padding: 0 var(--space-4) 0 0; - - [data-slot="logo"] { - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - - div { - text-transform: uppercase; - font-weight: 600; - letter-spacing: -0.03125rem; - } - - svg { - height: 28px; - width: auto; - color: var(--color-white); - } - } - - [data-slot="toggle"] { - background: transparent; - border: none; - padding: var(--space-4); - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - - & svg { - width: 24px; - height: 24px; - color: var(--color-foreground); - } - } -} - -[data-component="sidebar"] { - width: var(--sidebar-width); - border-right: 2px solid var(--color-border); - display: flex; - flex-direction: column; - padding: calc(var(--padding) / 2); - overflow-y: auto; - /* Allow scrolling if needed */ - position: sticky; - top: 0; - height: 100%; - background-color: var(--color-background); - z-index: 10; - - [data-slot="logo"] { - margin-top: 2px; - margin-bottom: var(--space-7); - color: var(--color-white); - - & svg { - height: 32px; - width: auto; - } - } - - [data-slot="nav"] { - flex: 1; - - ul { - list-style-type: none; - padding: 0; - } - - li { - margin-bottom: calc(var(--vertical-padding) / 2); - text-transform: uppercase; - font-weight: 500; - } - - a { - display: block; - padding: var(--space-2) 0; - } - } - - [data-slot="user"] { - [data-component="button"] { - padding-left: 0; - padding-bottom: 0; - height: auto; - } - } -} - -.navActiveLink { - cursor: default; - text-decoration: none; -} - -[data-slot="main-content"] { - flex: 1; - display: flex; - flex-direction: column; - height: 100%; - /* Full height */ - overflow: hidden; - /* Prevent overflow */ - position: relative; - /* For positioning footer */ - width: 100%; - /* Full width */ -} - -/* Backdrop for mobile */ -[data-component="backdrop"] { - display: none; - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - /* background-color: rgba(0, 0, 0, 0.5); */ - z-index: 25; - backdrop-filter: blur(2px); -} - -/* Mobile styles */ -@media (max-width: 40rem) { - .root { - margin: 0; - border: none; - height: 100vh; - } - - [data-component="mobile-top-bar"] { - display: flex; - } - - [data-component="backdrop"] { - display: block; - } - - [data-component="sidebar"] { - position: fixed; - left: -100%; - top: 0; - height: 100vh; - width: 80%; - max-width: 280px; - transition: left 0.3s ease-in-out; - box-shadow: none; - z-index: 30; - padding: var(--space-8); - background-color: var(--color-bg); - - &[data-opened="true"] { - left: 0; - box-shadow: 8px 0 0px 0px var(--color-gray-4); - } - } - - [data-slot="main-content"] { - padding-top: var(--topbar-height); - /* Add space for the top bar */ - overflow-y: auto; - } - - /* Hide the logo in the sidebar on mobile since it's in the top bar */ - [data-component="sidebar"] [data-slot="logo"] { - display: none; - } -} diff --git a/cloud/web/src/pages/components/layout.tsx b/cloud/web/src/pages/components/layout.tsx deleted file mode 100644 index 711ed8fc2..000000000 --- a/cloud/web/src/pages/components/layout.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import style from "./layout.module.css" -import { useAccount } from "../../components/context-account" -import { Button } from "../../ui/button" -import { IconLogomark } from "../../ui/svg" -import { IconBars3BottomLeft } from "../../ui/svg/icons" -import { ParentProps, createMemo, createSignal } from "solid-js" -import { A, useLocation } from "@solidjs/router" -import { useOpenAuth } from "../../components/context-openauth" - -export default function Layout(props: ParentProps) { - const auth = useOpenAuth() - const account = useAccount() - const [sidebarOpen, setSidebarOpen] = createSignal(false) - const location = useLocation() - - const workspaceId = createMemo(() => account.current?.workspaces[0].id) - const pageTitle = createMemo(() => { - const path = location.pathname - if (path.endsWith("/billing")) return "Billing" - if (path.endsWith("/keys")) return "API Keys" - return null - }) - - function handleLogout() { - auth.logout(auth.subject?.id!) - } - - return ( -
- {/* Mobile top bar */} -
- - -
- {pageTitle() ? ( -
{pageTitle()}
- ) : ( - - - - )} -
-
- - {/* Backdrop for mobile sidebar - closes sidebar when clicked */} - {sidebarOpen() &&
setSidebarOpen(false)}>
} - - - - {/* Main Content */} -
{props.children}
-
- ) -} diff --git a/cloud/web/src/pages/index.tsx b/cloud/web/src/pages/index.tsx deleted file mode 100644 index 116ed156c..000000000 --- a/cloud/web/src/pages/index.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { Match, Switch } from "solid-js" -import { useAccount } from "../components/context-account" -import { Navigate } from "@solidjs/router" -import { IconLogo } from "../ui/svg" -import styles from "./lander.module.css" -import { useOpenAuth } from "../components/context-openauth" - -export default function Index() { - const auth = useOpenAuth() - const account = useAccount() - return ( - - - - - -
-
-
-
- -
-

opencode Gateway Console

-
- -
-
- auth.authorize({ provider: "github" })}>Sign in with GitHub -
-
- auth.authorize({ provider: "google" })}>Sign in with Google -
-
-
-
-
-
- ) -} diff --git a/cloud/web/src/pages/lander.module.css b/cloud/web/src/pages/lander.module.css deleted file mode 100644 index 251e243fb..000000000 --- a/cloud/web/src/pages/lander.module.css +++ /dev/null @@ -1,83 +0,0 @@ -.lander { - --padding: 3rem; - --vertical-padding: 2rem; - --heading-font-size: 2rem; - - margin: 1rem; - - @media (max-width: 30rem) { - & { - --padding: 1.5rem; - --vertical-padding: 1rem; - --heading-font-size: 1.5rem; - - margin: 0.5rem; - } - } - - [data-slot="hero"] { - border: 2px solid var(--color-border); - - max-width: 64rem; - margin-left: auto; - margin-right: auto; - width: 100%; - } - - [data-slot="top"] { - padding: var(--padding); - - h1 { - margin-top: calc(var(--vertical-padding) / 8); - font-size: var(--heading-font-size); - line-height: 1.25; - text-transform: uppercase; - font-weight: 600; - } - - [data-slot="logo"] { - width: clamp(200px, 70vw, 400px); - color: var(--color-white); - } - } - - [data-slot="cta"] { - display: flex; - flex-direction: row; - justify-content: space-between; - border-top: 2px solid var(--color-border); - - & > div { - flex: 1; - line-height: 1.4; - text-align: center; - text-transform: uppercase; - cursor: pointer; - text-decoration: underline; - letter-spacing: -0.03125rem; - - &[data-slot="col-2"] { - background-color: var(--color-border); - color: var(--color-text-invert); - font-weight: 600; - } - - & > * { - display: block; - width: 100%; - height: 100%; - padding: calc(var(--padding) / 2) 0.5rem; - } - } - - @media (max-width: 30rem) { - & > div { - padding-bottom: calc(var(--padding) / 2 + 4px); - } - } - - & > div + div { - border-left: 2px solid var(--color-border); - } - } -} diff --git a/cloud/web/src/pages/test/design.module.css b/cloud/web/src/pages/test/design.module.css deleted file mode 100644 index fee4e3cd3..000000000 --- a/cloud/web/src/pages/test/design.module.css +++ /dev/null @@ -1,204 +0,0 @@ -.pageContainer { - padding: 2rem; - max-width: 1200px; - margin: 0 auto; -} - -.componentTable { - width: 100%; - border-collapse: collapse; - table-layout: fixed; - border: 2px solid var(--color-border); -} - -.componentCell { - padding: 1rem; - border: 2px solid var(--color-border); - vertical-align: top; -} - -.componentLabel { - text-transform: uppercase; - letter-spacing: -0.03125rem; - font-size: 0.85rem; - font-weight: 500; - margin-bottom: 0.75rem; - color: var(--color-text-dimmed); -} - -.sectionTitle { - margin-bottom: 1rem; - text-transform: uppercase; - letter-spacing: -0.03125rem; - font-size: 1.2rem; -} - -.divider { - height: 2px; - background: var(--color-border); - margin: 3rem 0; - width: 100%; -} - -.header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 2rem; -} - -.buttonSection { - margin-bottom: 4rem; -} - -.colorSection { - margin-bottom: 4rem; -} - -.labelSection { - margin-bottom: 4rem; -} - -.inputSection { - margin-bottom: 4rem; -} - -.dialogSection { - margin-bottom: 4rem; -} - -.formGroup { - display: flex; - flex-direction: column; - gap: 0.5rem; -} - -.dialogContent { - padding: 2rem; -} - -.dialogContentFooter { - margin-top: 1rem; -} - -.pageTitle { - font-size: var(--heading-font-size, 2rem); - text-transform: uppercase; - font-weight: 600; -} - -.colorBox { - width: 100%; - height: 80px; - margin-bottom: 0.5rem; - position: relative; - display: flex; - align-items: flex-end; - justify-content: center; - padding-bottom: 0.5rem; -} - -.colorOrange { - background-color: var(--color-orange); -} - -.colorOrangeLow { - background-color: var(--color-orange-low); -} - -.colorOrangeHigh { - background-color: var(--color-orange-high); -} - -.colorGreen { - background-color: var(--color-green); -} - -.colorGreenLow { - background-color: var(--color-green-low); -} - -.colorGreenHigh { - background-color: var(--color-green-high); -} - -.colorBlue { - background-color: var(--color-blue); -} - -.colorBlueLow { - background-color: var(--color-blue-low); -} - -.colorBlueHigh { - background-color: var(--color-blue-high); -} - -.colorPurple { - background-color: var(--color-purple); -} - -.colorPurpleLow { - background-color: var(--color-purple-low); -} - -.colorPurpleHigh { - background-color: var(--color-purple-high); -} - -.colorRed { - background-color: var(--color-red); -} - -.colorRedLow { - background-color: var(--color-red-low); -} - -.colorRedHigh { - background-color: var(--color-red-high); -} - -.colorAccent { - background-color: var(--color-accent); -} - -.colorAccentLow { - background-color: var(--color-accent-low); -} - -.colorAccentHigh { - background-color: var(--color-accent-high); -} - -.colorCode { - background-color: rgba(0, 0, 0, 0.5); - color: white; - padding: 4px 8px; - border-radius: 4px; - font-size: 0.8rem; - font-family: monospace; -} - -.colorVariants { - display: flex; - gap: 0.5rem; -} - -.colorVariant { - flex: 1; - height: 40px; - position: relative; - display: flex; - align-items: center; - justify-content: center; -} - -.colorVariantCode { - background-color: rgba(0, 0, 0, 0.5); - color: white; - padding: 2px 4px; - border-radius: 4px; - font-size: 0.65rem; - font-family: monospace; - white-space: nowrap; -} diff --git a/cloud/web/src/pages/test/design.tsx b/cloud/web/src/pages/test/design.tsx deleted file mode 100644 index 3bf759316..000000000 --- a/cloud/web/src/pages/test/design.tsx +++ /dev/null @@ -1,562 +0,0 @@ -import { Button } from "../../ui/button" -import { Dialog } from "../../ui/dialog" -import { Navigate } from "@solidjs/router" -import { createSignal, Show } from "solid-js" -import { IconHome, IconPencilSquare } from "../../ui/svg/icons" -import { useTheme } from "../../components/context-theme" -import { useDialog } from "../../ui/context-dialog" -import { DialogString } from "../../ui/dialog-string" -import { DialogSelect } from "../../ui/dialog-select" -import styles from "./design.module.css" - -export default function DesignSystem() { - const dialog = useDialog() - const [dialogOpen, setDialogOpen] = createSignal(false) - const [dialogOpenTransition, setDialogOpenTransition] = createSignal(false) - const theme = useTheme() - - // Check if we're running locally - const isLocal = import.meta.env.DEV === true - - if (!isLocal) { - return - } - - // Add a toggle button for theme - const toggleTheme = () => { - theme.setMode(theme.mode === "light" ? "dark" : "light") - } - - return ( -
-
-

Design System

- -
- -
-

Colors

- - - - - - - - - - - - - - -
-

Orange

-
- hsl(41, 82%, 63%) -
-
-
- - hsl(41, 39%, 22%) - -
-
- - hsl(41, 82%, 87%) - -
-
-
-

Green

-
- hsl(101, 82%, 63%) -
-
-
- - hsl(101, 39%, 22%) - -
-
- - hsl(101, 82%, 80%) - -
-
-
-

Blue

-
- hsl(234, 100%, 60%) -
-
-
- - hsl(234, 54%, 20%) - -
-
- - hsl(234, 100%, 87%) - -
-
-
-

Purple

-
- hsl(281, 82%, 63%) -
-
-
- - hsl(281, 39%, 22%) - -
-
- - hsl(281, 82%, 89%) - -
-
-
-

Red

-
- hsl(339, 82%, 63%) -
-
-
- - hsl(339, 39%, 22%) - -
-
- - hsl(339, 82%, 87%) - -
-
-
-

Accent

-
- hsl(13, 88%, 57%) -
-
-
- - hsl(13, 75%, 30%) - -
-
- - hsl(13, 100%, 78%) - -
-
-
-
- -
- -
-

Buttons

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Primary

- -
-

Secondary

- -
-

Ghost

- -
-

Primary Disabled

- -
-

Secondary Disabled

- -
-

Ghost Disabled

- -
-

Small

- -
-

Small Secondary

- -
-

Small Ghost

- -
-

With Icon

- -
-

Icon + Secondary

- -
-

Icon + Ghost

- -
-

Small + Icon

- -
-

Small + Icon + Secondary

- -
-

Small + Icon + Ghost

- -
-

Icon Only

- -
-

Icon Only + Secondary

- -
-

Icon Only + Ghost

- -
-

Icon Only Disabled

- -
-

- Icon Only + Secondary Disabled -

- -
-

- Icon Only + Ghost Disabled -

- -
-

Small Icon Only

- -
-

- Small Icon Only + Secondary -

- -
-

Small Icon Only + Ghost

- -
-
- -
- -
-

Labels

- - - - - - - - - -
-

Small

- -
-

Medium

- -
-

Large

- -
-
- -
- -
-

Inputs

- - - - - - - - - - - - - -
-

Small

- -
-

Medium

- -
-

Large

- -
-

Disabled

- -
-

With Value

- -
-
- -
- -
-

Dialogs

- - - - - - - - - - - - - - -
-

Default

- - -
-
Dialog Title
-
-
-

This is the default dialog content.

-
-
- -
-
-
-

Small With Transition

- - -
-

Small Dialog

-

This is a smaller dialog with transitions.

-
- -
-
-
-
-

Input String

- -
-

Select Input

- -
-

Select Input

- -
-

Select No Options

- -
-
-
- ) -} diff --git a/cloud/web/src/sst-env.d.ts b/cloud/web/src/sst-env.d.ts deleted file mode 100644 index e1ee6f753..000000000 --- a/cloud/web/src/sst-env.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* This file is auto-generated by SST. Do not edit. */ -/* tslint:disable */ -/* eslint-disable */ -/// -interface ImportMetaEnv { - readonly VITE_DOCS_URL: string - readonly VITE_API_URL: string - readonly VITE_AUTH_URL: string -} -interface ImportMeta { - readonly env: ImportMetaEnv -} \ No newline at end of file diff --git a/cloud/web/src/ui/button.tsx b/cloud/web/src/ui/button.tsx deleted file mode 100644 index 889102dda..000000000 --- a/cloud/web/src/ui/button.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { Button as Kobalte } from "@kobalte/core/button" -import { JSX, Show, splitProps } from "solid-js" - -export interface ButtonProps { - color?: "primary" | "secondary" | "ghost" - size?: "md" | "sm" - icon?: JSX.Element -} -export function Button(props: JSX.IntrinsicElements["button"] & ButtonProps) { - const [split, rest] = splitProps(props, ["color", "size", "icon"]) - return ( - - -
{props.icon}
-
- {props.children} -
- ) -} diff --git a/cloud/web/src/ui/context-dialog.tsx b/cloud/web/src/ui/context-dialog.tsx deleted file mode 100644 index f1bc93250..000000000 --- a/cloud/web/src/ui/context-dialog.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import { createContext, JSX, ParentProps, useContext } from "solid-js" -import { StandardSchemaV1 } from "@standard-schema/spec" -import { createStore } from "solid-js/store" -import { Dialog } from "./dialog" - -const Context = createContext() - -type DialogControl = { - open>( - component: DialogComponent, - input: StandardSchemaV1.InferInput, - ): void - close(): void - isOpen(input: any): boolean - size: "sm" | "md" - transition?: boolean - input?: any -} - -type DialogProps> = { - input: StandardSchemaV1.InferInput - control: DialogControl -} - -type DialogComponent> = ReturnType< - typeof createDialog -> - -export function createDialog>(props: { - schema: Schema - size: "sm" | "md" - render: (props: DialogProps) => JSX.Element -}) { - const result = () => { - const dialog = useDialog() - return ( - { - if (!val) dialog.close() - }} - > - {props.render({ - input: dialog.input, - control: dialog, - })} - - ) - } - result.schema = props.schema - result.size = props.size - return result -} - -export function DialogProvider(props: ParentProps) { - const [store, setStore] = createStore<{ - dialog?: DialogComponent - input?: any - transition?: boolean - size: "sm" | "md" - }>({ - size: "sm", - }) - - const control: DialogControl = { - get input() { - return store.input - }, - get size() { - return store.size - }, - get transition() { - return store.transition - }, - isOpen(input) { - return store.dialog === input - }, - open(component, input) { - setStore({ - dialog: component, - input: input, - size: store.dialog !== undefined ? store.size : component.size, - transition: store.dialog !== undefined, - }) - - setTimeout(() => { - setStore({ - size: component.size, - }) - }, 0) - - setTimeout(() => { - setStore({ - transition: false, - }) - }, 150) - }, - close() { - setStore({ - dialog: undefined, - }) - }, - } - - return ( - <> - {props.children} - - ) -} - -export function useDialog() { - const ctx = useContext(Context) - if (!ctx) { - throw new Error("useDialog must be used within a DialogProvider") - } - return ctx -} diff --git a/cloud/web/src/ui/dialog-select.module.css b/cloud/web/src/ui/dialog-select.module.css deleted file mode 100644 index 4a99ef027..000000000 --- a/cloud/web/src/ui/dialog-select.module.css +++ /dev/null @@ -1,36 +0,0 @@ -.options { - margin-top: var(--space-1); - border-top: 2px solid var(--color-border); - padding: var(--space-2); - - [data-slot="option"] { - outline: none; - flex-shrink: 0; - height: var(--space-11); - display: flex; - justify-content: start; - align-items: center; - padding: 0 var(--space-2-5); - gap: var(--space-3); - cursor: pointer; - - &[data-empty] { - cursor: default; - color: var(--color-text-dimmed); - } - - &[data-active] { - background-color: var(--color-bg-surface); - } - - [data-slot="title"] { - font-size: var(--font-size-md); - } - - [data-slot="prefix"] { - width: var(--space-4); - height: var(--space-4); - } - } - -} diff --git a/cloud/web/src/ui/dialog-select.tsx b/cloud/web/src/ui/dialog-select.tsx deleted file mode 100644 index 087b94411..000000000 --- a/cloud/web/src/ui/dialog-select.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import style from "./dialog-select.module.css" -import { z } from "zod" -import { createMemo, createSignal, For, JSX, onMount } from "solid-js" -import { createList } from "solid-list" -import { createDialog } from "./context-dialog" - -export const DialogSelect = createDialog({ - size: "md", - schema: z.object({ - title: z.string(), - placeholder: z.string(), - onSelect: z - .function(z.tuple([z.any()])) - .returns(z.void()) - .optional(), - options: z.array( - z.object({ - display: z.string(), - value: z.any().optional(), - onSelect: z.function().returns(z.void()).optional(), - prefix: z.custom().optional(), - }), - ), - }), - render: (ctx) => { - let input: HTMLInputElement - onMount(() => { - input.focus() - input.value = "" - }) - - const [filter, setFilter] = createSignal("") - const filtered = createMemo(() => - ctx.input.options?.filter((i) => - i.display.toLowerCase().includes(filter().toLowerCase()), - ), - ) - const list = createList({ - loop: true, - initialActive: 0, - items: () => filtered().map((_, i) => i), - handleTab: false, - }) - - const handleSelection = (index: number) => { - const option = ctx.input.options[index] - - // If the option has its own onSelect handler, use it - if (option.onSelect) { - option.onSelect() - } - // Otherwise, if there's a global onSelect handler, call it with the option's value - else if (ctx.input.onSelect) { - ctx.input.onSelect( - option.value !== undefined ? option.value : option.display, - ) - } - } - - return ( - <> -
- -
-
- { - setFilter(e.target.value) - list.setActive(0) - }} - onKeyDown={(e) => { - if (e.key === "Enter") { - const selected = list.active() - if (selected === null) return - handleSelection(selected) - return - } - if (e.key === "Escape") { - setFilter("") - return - } - list.onKeyDown(e) - }} - id={`dialog-select-${ctx.input.title}`} - ref={(r) => (input = r)} - data-slot="input" - placeholder={ctx.input.placeholder} - /> -
-
- - No results -
- } - > - {(option, index) => ( -
handleSelection(index())} - data-slot="option" - data-active={list.active() === index() ? true : undefined} - > - {option.prefix &&
{option.prefix}
} -
{option.display}
-
- )} - - - - ) - }, -}) diff --git a/cloud/web/src/ui/dialog-string.tsx b/cloud/web/src/ui/dialog-string.tsx deleted file mode 100644 index af2174786..000000000 --- a/cloud/web/src/ui/dialog-string.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { z } from "zod" -import { onMount } from "solid-js" -import { createDialog } from "./context-dialog" -import { Button } from "./button" - -export const DialogString = createDialog({ - size: "sm", - schema: z.object({ - title: z.string(), - placeholder: z.string(), - action: z.string(), - onSubmit: z.function().args(z.string()).returns(z.void()), - }), - render: (ctx) => { - let input: HTMLInputElement - onMount(() => { - setTimeout(() => { - input.focus() - input.value = "" - }, 50) - }) - - function submit() { - const value = input.value.trim() - if (value) { - ctx.input.onSubmit(value) - ctx.control.close() - } - } - - return ( - <> -
- -
-
- (input = r)} - placeholder={ctx.input.placeholder} - id={`dialog-string-${ctx.input.title}`} - onKeyDown={(e) => { - if (e.key === "Enter") { - e.preventDefault() - submit() - } - }} - /> -
-
- - -
- - ) - }, -}) diff --git a/cloud/web/src/ui/dialog.tsx b/cloud/web/src/ui/dialog.tsx deleted file mode 100644 index 101f23d2b..000000000 --- a/cloud/web/src/ui/dialog.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { Dialog as Kobalte } from "@kobalte/core/dialog" -import { ComponentProps, ParentProps } from "solid-js" - -export type Props = ParentProps<{ - size?: "sm" | "md" - transition?: boolean -}> & - ComponentProps - -export function Dialog(props: Props) { - return ( - - - -
- - {props.children} - -
-
-
- ) -} diff --git a/cloud/web/src/ui/style/component/button.css b/cloud/web/src/ui/style/component/button.css deleted file mode 100644 index 9604f9865..000000000 --- a/cloud/web/src/ui/style/component/button.css +++ /dev/null @@ -1,78 +0,0 @@ -[data-component="button"] { - width: fit-content; - display: flex; - line-height: 1; - align-items: center; - justify-content: center; - gap: var(--space-2); - font-size: var(--font-size-md); - text-transform: uppercase; - height: var(--space-11); - outline: none; - font-weight: 500; - padding: 0 var(--space-4); - border-width: 2px; - border-color: var(--color-border); - cursor: pointer; - - &:disabled { - opacity: 0.5; - cursor: default; - } - - &[data-color="primary"] { - background-color: var(--color-text); - border-color: var(--color-text); - color: var(--color-text-invert); - - &:active { - border-color: var(--color-accent); - } - } - - &[data-color="secondary"] { - &:active { - border-color: var(--color-accent); - } - } - - &[data-color="ghost"] { - border: none; - text-decoration: underline; - - &:active { - color: var(--color-text-accent); - } - } - - &:has([data-slot="icon"]) { - padding-left: var(--space-3); - padding-right: var(--space-3); - } - - &[data-size="sm"] { - height: var(--space-8); - padding: var(--space-3); - font-size: var(--font-size-xs); - - [data-slot="icon"] { - width: var(--space-3-5); - height: var(--space-3-5); - } - - &:has([data-slot="icon"]) { - padding-left: var(--space-2); - padding-right: var(--space-2); - } - } - - [data-slot="icon"] { - width: var(--space-4); - height: var(--space-4); - transition: transform 0.2s ease; - } - - &[data-rotate] [data-slot="icon"] { - transform: rotate(180deg); - } -} diff --git a/cloud/web/src/ui/style/component/dialog.css b/cloud/web/src/ui/style/component/dialog.css deleted file mode 100644 index 59867818f..000000000 --- a/cloud/web/src/ui/style/component/dialog.css +++ /dev/null @@ -1,84 +0,0 @@ -[data-component="dialog-overlay"] { - pointer-events: none !important; - position: fixed; - inset: 0; - animation-name: fadeOut; - animation-duration: 200ms; - animation-timing-function: ease; - opacity: 0; - backdrop-filter: blur(2px); - - &[data-expanded] { - animation-name: fadeIn; - opacity: 1; - pointer-events: auto !important; - } -} - -[data-component="dialog-center"] { - position: fixed; - inset: 0; - padding-top: 10vh; - justify-content: center; - pointer-events: none; - - [data-slot="content"] { - width: 45rem; - margin: 0 auto; - transition: 150ms width; - background-color: var(--color-bg); - border-width: 2px; - border-color: var(--color-border); - overflow: hidden; - display: flex; - flex-direction: column; - gap: var(--space-3); - outline: none; - animation-duration: 1ms; - animation-name: zoomOut; - animation-timing-function: ease; - - box-shadow: 8px 8px 0px 0px var(--color-gray-4); - - &[data-expanded] { - animation-name: zoomIn; - } - - &[data-transition] { - animation-duration: 200ms; - } - - &[data-size="sm"] { - width: 30rem; - } - - [data-slot="header"] { - display: flex; - padding: var(--space-4) var(--space-4) 0; - - [data-slot="title"] { - } - } - - [data-slot="main"] { - padding: 0 var(--space-4); - - &:has([data-slot="options"]) { - padding: 0; - display: flex; - flex-direction: column; - gap: var(--space-4); - } - } - - [data-slot="input"] { - } - - [data-slot="footer"] { - padding: var(--space-4); - display: flex; - gap: var(--space-4); - justify-content: end; - } - } -} diff --git a/cloud/web/src/ui/style/component/input.css b/cloud/web/src/ui/style/component/input.css deleted file mode 100644 index 59535d763..000000000 --- a/cloud/web/src/ui/style/component/input.css +++ /dev/null @@ -1,34 +0,0 @@ -[data-component="input"] { - font-size: var(--font-size-md); - background: transparent; - caret-color: var(--color-accent); - font-family: var(--font-mono); - height: var(--space-11); - padding: 0 var(--space-4); - width: 100%; - resize: none; - border: 2px solid var(--color-border); - - &::placeholder { - color: var(--color-text-dimmed); - opacity: 0.75; - } - - &:focus { - outline: 0; - } - - &[data-size="sm"] { - height: var(--space-9); - padding: 0 var(--space-3); - font-size: var(--font-size-xs); - } - - &[data-size="md"] { - } - - &[data-size="lg"] { - height: var(--space-12); - font-size: var(--font-size-lg); - } -} diff --git a/cloud/web/src/ui/style/component/label.css b/cloud/web/src/ui/style/component/label.css deleted file mode 100644 index e0dd5fef4..000000000 --- a/cloud/web/src/ui/style/component/label.css +++ /dev/null @@ -1,17 +0,0 @@ -[data-component="label"] { - letter-spacing: -0.03125rem; - text-transform: uppercase; - color: var(--color-text-dimmed); - font-weight: 500; - font-size: var(--font-size-md); - - &[data-size="sm"] { - font-size: var(--font-size-sm); - } - &[data-size="md"] { - } - &[data-size="lg"] { - font-size: var(--font-size-lg); - } -} - diff --git a/cloud/web/src/ui/style/component/title-bar.css b/cloud/web/src/ui/style/component/title-bar.css deleted file mode 100644 index 7ee32bfdc..000000000 --- a/cloud/web/src/ui/style/component/title-bar.css +++ /dev/null @@ -1,32 +0,0 @@ -[data-component="title-bar"] { - display: flex; - align-items: center; - justify-content: space-between; - height: 72px; - padding: 0 var(--space-4); - border-bottom: 2px solid var(--color-border); - - [data-slot="left"] { - display: flex; - flex-direction: column; - gap: var(--space-1-5); - - h1 { - letter-spacing: -0.03125rem; - font-size: var(--font-size-xl); - text-transform: uppercase; - font-weight: 600; - } - - p { - color: var(--color-text-dimmed); - } - } - -} - -@media (max-width: 40rem) { - [data-component="title-bar"] { - display: none; - } -} diff --git a/cloud/web/src/ui/style/index.css b/cloud/web/src/ui/style/index.css deleted file mode 100644 index 117f596d0..000000000 --- a/cloud/web/src/ui/style/index.css +++ /dev/null @@ -1,50 +0,0 @@ -/* tokens */ -@import "./token/color.css"; -@import "./token/reset.css"; -@import "./token/animation.css"; -@import "./token/font.css"; -@import "./token/space.css"; - -/* components */ -@import "./component/label.css"; -@import "./component/input.css"; -@import "./component/button.css"; -@import "./component/dialog.css"; -@import "./component/title-bar.css"; - -body { - font-family: var(--font-mono); - line-height: 1; - color: var(--color-text); - background-color: var(--color-bg); - cursor: default; - user-select: none; - text-underline-offset: 0.1875rem; -} - -a { - text-decoration: underline; - &:active { - color: var(--color-text-accent); - } -} - -::selection { - background-color: var(--color-text-accent-invert); -} - -/* Responsive utilities */ -[data-max-width] { - width: 100%; - - & > * { - max-width: 90rem; - margin-left: auto; - margin-right: auto; - width: 100%; - } - - &[data-max-width-64] > * { - max-width: 64rem; - } -} diff --git a/cloud/web/src/ui/style/token/animation.css b/cloud/web/src/ui/style/token/animation.css deleted file mode 100644 index a8edfeff5..000000000 --- a/cloud/web/src/ui/style/token/animation.css +++ /dev/null @@ -1,23 +0,0 @@ -@keyframes zoomIn { - from { - opacity: 0; - transform: scale(0.95); - } - - to { - opacity: 1; - transform: scale(1); - } -} - -@keyframes zoomOut { - from { - opacity: 1; - transform: scale(1); - } - - to { - opacity: 0; - transform: scale(0.95); - } -} diff --git a/cloud/web/src/ui/style/token/color.css b/cloud/web/src/ui/style/token/color.css deleted file mode 100644 index af0c46f3b..000000000 --- a/cloud/web/src/ui/style/token/color.css +++ /dev/null @@ -1,88 +0,0 @@ -:root { - --color-white: hsl(0, 0%, 100%); - --color-gray-1: hsl(224, 20%, 94%); - --color-gray-2: hsl(224, 6%, 77%); - --color-gray-3: hsl(224, 6%, 56%); - --color-gray-4: hsl(224, 7%, 36%); - --color-gray-5: hsl(224, 10%, 23%); - --color-gray-6: hsl(224, 14%, 16%); - --color-black: hsl(224, 10%, 10%); - - --hue-orange: 41; - --color-orange-low: hsl(var(--hue-orange), 39%, 22%); - --color-orange: hsl(var(--hue-orange), 82%, 63%); - --color-orange-high: hsl(var(--hue-orange), 82%, 87%); - --hue-green: 101; - --color-green-low: hsl(var(--hue-green), 39%, 22%); - --color-green: hsl(var(--hue-green), 82%, 63%); - --color-green-high: hsl(var(--hue-green), 82%, 80%); - --hue-blue: 234; - --color-blue-low: hsl(var(--hue-blue), 54%, 20%); - --color-blue: hsl(var(--hue-blue), 100%, 60%); - --color-blue-high: hsl(var(--hue-blue), 100%, 87%); - --hue-purple: 281; - --color-purple-low: hsl(var(--hue-purple), 39%, 22%); - --color-purple: hsl(var(--hue-purple), 82%, 63%); - --color-purple-high: hsl(var(--hue-purple), 82%, 89%); - --hue-red: 339; - --color-red-low: hsl(var(--hue-red), 39%, 22%); - --color-red: hsl(var(--hue-red), 82%, 63%); - --color-red-high: hsl(var(--hue-red), 82%, 87%); - - --color-accent-low: hsl(13, 75%, 30%); - --color-accent: hsl(13, 88%, 57%); - --color-accent-high: hsl(13, 100%, 78%); - - --color-text: var(--color-gray-1); - --color-text-dimmed: var(--color-gray-3); - --color-text-accent: var(--color-accent); - --color-text-invert: var(--color-black); - --color-text-accent-invert: var(--color-accent-high); - --color-bg: var(--color-black); - --color-bg-surface: var(--color-gray-5); - --color-bg-accent: var(--color-accent-high); - --color-border: var(--color-gray-2); - - --color-backdrop-overlay: hsla(223, 13%, 10%, 0.66); -} - -:root[data-color-mode="light"] { - --color-white: hsl(224, 10%, 10%); - --color-gray-1: hsl(224, 14%, 16%); - --color-gray-2: hsl(224, 10%, 23%); - --color-gray-3: hsl(224, 7%, 36%); - --color-gray-4: hsl(224, 6%, 56%); - --color-gray-5: hsl(224, 6%, 77%); - --color-gray-6: hsl(224, 20%, 94%); - --color-gray-7: hsl(224, 19%, 97%); - --color-black: hsl(0, 0%, 100%); - - --color-orange-high: hsl(var(--hue-orange), 80%, 25%); - --color-orange: hsl(var(--hue-orange), 90%, 60%); - --color-orange-low: hsl(var(--hue-orange), 90%, 88%); - --color-green-high: hsl(var(--hue-green), 80%, 22%); - --color-green: hsl(var(--hue-green), 90%, 46%); - --color-green-low: hsl(var(--hue-green), 85%, 90%); - --color-blue-high: hsl(var(--hue-blue), 80%, 30%); - --color-blue: hsl(var(--hue-blue), 90%, 60%); - --color-blue-low: hsl(var(--hue-blue), 88%, 90%); - --color-purple-high: hsl(var(--hue-purple), 90%, 30%); - --color-purple: hsl(var(--hue-purple), 90%, 60%); - --color-purple-low: hsl(var(--hue-purple), 80%, 90%); - --color-red-high: hsl(var(--hue-red), 80%, 30%); - --color-red: hsl(var(--hue-red), 90%, 60%); - --color-red-low: hsl(var(--hue-red), 80%, 90%); - - --color-accent-high: hsl(13, 75%, 26%); - --color-accent: hsl(13, 88%, 60%); - --color-accent-low: hsl(13, 100%, 89%); - - --color-text-accent: var(--color-accent); - --color-text-dimmed: var(--color-gray-4); - --color-text-invert: var(--color-black); - --color-text-accent-invert: var(--color-accent-low); - --color-bg-surface: var(--color-gray-6); - --color-bg-accent: var(--color-accent); - - --color-backdrop-overlay: hsla(225, 9%, 36%, 0.66); -} diff --git a/cloud/web/src/ui/style/token/font.css b/cloud/web/src/ui/style/token/font.css deleted file mode 100644 index 24b2db3f2..000000000 --- a/cloud/web/src/ui/style/token/font.css +++ /dev/null @@ -1,20 +0,0 @@ -:root { - --font-size-2xs: 0.6875rem; - --font-size-xs: 0.75rem; - --font-size-sm: 0.8125rem; - --font-size-md: 0.9375rem; - --font-size-lg: 1.125rem; - --font-size-xl: 1.25rem; - --font-size-2xl: 1.5rem; - --font-size-3xl: 1.875rem; - --font-size-4xl: 2.25rem; - --font-size-5xl: 3rem; - --font-size-6xl: 3.75rem; - --font-size-7xl: 4.5rem; - --font-size-8xl: 6rem; - --font-size-9xl: 8rem; - --font-mono: IBM Plex Mono, monospace; - --font-sans: Rubik, sans-serif; - - --font-line-height: 1.75; -} diff --git a/cloud/web/src/ui/style/token/reset.css b/cloud/web/src/ui/style/token/reset.css deleted file mode 100644 index f4aa1a0a9..000000000 --- a/cloud/web/src/ui/style/token/reset.css +++ /dev/null @@ -1,212 +0,0 @@ -* { - margin: 0; - padding: 0; - font: inherit; -} - -*, -*::before, -*::after { - box-sizing: border-box; - border-width: 0; - border-style: solid; - border-color: var(--global-color-border, currentColor); -} - -html { - line-height: 1.5; - --font-fallback: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, - "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, - "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; - -webkit-text-size-adjust: 100%; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -moz-tab-size: 4; - tab-size: 4; - font-family: var(--global-font-body, var(--font-fallback)); -} - -hr { - height: 0; - color: inherit; - border-top-width: 1px; -} - -body { - height: 100%; - line-height: inherit; -} - -img { - border-style: none; -} - -img, -svg, -video, -canvas, -audio, -iframe, -embed, -object { - display: block; - vertical-align: middle; -} - -img, -video { - max-width: 100%; - height: auto; -} - -p, -h1, -h2, -h3, -h4, -h5, -h6 { - overflow-wrap: break-word; -} - -ol, -ul { - list-style: none; -} - -code, -kbd, -pre, -samp { - font-size: 1em; -} - -button, -[type="button"], -[type="reset"], -[type="submit"] { - -webkit-appearance: button; - background-color: transparent; - background-image: none; -} - -button, -input, -optgroup, -select, -textarea { - color: inherit; -} - -button, -select { - text-transform: none; -} - -table { - text-indent: 0; - border-color: inherit; - border-collapse: collapse; -} - -input::placeholder, -textarea::placeholder { - opacity: 1; - color: var(--global-color-placeholder, #9ca3af); -} - -textarea { - resize: vertical; -} - -summary { - display: list-item; -} - -small { - font-size: 80%; -} - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -dialog { - padding: 0; -} - -a { - color: inherit; - text-decoration: inherit; -} - -abbr:where([title]) { - text-decoration: underline dotted; -} - -b, -strong { - font-weight: bolder; -} - -code, -kbd, -samp, -pre { - font-size: 1em; - --font-mono-fallback: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, - "Liberation Mono", "Courier New"; - font-family: var(--global-font-mono, var(--font-fallback)); -} - -input[type="text"], -input[type="email"], -input[type="search"], -input[type="password"] { - -webkit-appearance: none; - -moz-appearance: none; -} - -input[type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; -} - -::-webkit-search-decoration, -::-webkit-search-cancel-button { - -webkit-appearance: none; -} - -::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; -} - -input[type="number"]::-webkit-inner-spin-button, -input[type="number"]::-webkit-outer-spin-button { - height: auto; -} - -input[type="number"] { - -moz-appearance: textfield; -} - -:-moz-ui-invalid { - box-shadow: none; -} - -:-moz-focusring { - outline: auto; -} diff --git a/cloud/web/src/ui/style/token/space.css b/cloud/web/src/ui/style/token/space.css deleted file mode 100644 index 4a061d756..000000000 --- a/cloud/web/src/ui/style/token/space.css +++ /dev/null @@ -1,39 +0,0 @@ -:root { - --space-0: 0; - --space-px: 1px; - --space-0-5: 0.125rem; - --space-1: 0.25rem; - --space-1-5: 0.375rem; - --space-2: 0.5rem; - --space-2-5: 0.625rem; - --space-3: 0.75rem; - --space-3-5: 0.875rem; - --space-4: 1rem; - --space-4-5: 1.125rem; - --space-5: 1.25rem; - --space-6: 1.5rem; - --space-7: 1.75rem; - --space-8: 2rem; - --space-9: 2.25rem; - --space-10: 2.5rem; - --space-11: 2.75rem; - --space-12: 3rem; - --space-14: 3.5rem; - --space-16: 4rem; - --space-18: 4.5rem; - --space-20: 5rem; - --space-24: 6rem; - --space-28: 7rem; - --space-32: 8rem; - --space-36: 9rem; - --space-40: 10rem; - --space-44: 11rem; - --space-48: 12rem; - --space-52: 13rem; - --space-56: 14rem; - --space-60: 15rem; - --space-64: 16rem; - --space-72: 18rem; - --space-80: 20rem; - --space-96: 24rem; -} diff --git a/cloud/web/src/ui/svg/icons.tsx b/cloud/web/src/ui/svg/icons.tsx deleted file mode 100644 index c09bbc47a..000000000 --- a/cloud/web/src/ui/svg/icons.tsx +++ /dev/null @@ -1,1292 +0,0 @@ -import { JSX } from "solid-js" - -export function IconPencilSquare(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconHome(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconPlus(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconDocument(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconChat(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconBell(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconCheck(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconChevronDown(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconChevronUp(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconChevronLeft(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconChevronRight(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconTrash(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconUser(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconCog(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconExclamationCircle( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconInformationCircle( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconArrowPath(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowUpRight(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconEllipsisVertical( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconEllipsisHorizontal( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconXMark(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconAcademicCap(props: JSX.SvgSVGAttributes) { - return ( - - - - - - ) -} - -export function IconBolt(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconCalendar(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconCamera(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconClock(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconCloud(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconCreditCard(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconEnvelope(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconEye(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconFlag(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconFolder(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconGlobe(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconHeart(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconKey(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconLink(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconLock(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconMap(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconMicrophone(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconPhone(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconPhoto(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconQuestionMarkCircle( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconMagnifyingGlass( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconShieldCheck(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconShoppingCart(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconStar(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconTag(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconUserCircle(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconVideoCamera(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconWifi(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconAdjustmentsVertical( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconArchiveBox(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconArrowDown(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowLeft(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowLongDown(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowLongLeft(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowLongRight(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowLongUp(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowRight(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowSmallDown(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconArrowSmallLeft(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconArrowSmallRight( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - - ) -} - -export function IconArrowSmallUp(props: JSX.SvgSVGAttributes) { - return ( - - - - - ) -} - -export function IconArrowTopRightOnSquare( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconArrowTrendingDown( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - - ) -} - -export function IconArrowTrendingUp( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconArrowUp(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowUpCircle(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowUpLeft(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowUpOnSquare( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - - ) -} - -export function IconArrowUpTray(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconArrowsPointingIn( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconArrowsPointingOut( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconArrowsRightLeft( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} - -export function IconBars3BottomLeft( - props: JSX.SvgSVGAttributes, -) { - return ( - - - - ) -} diff --git a/cloud/web/src/ui/svg/index.tsx b/cloud/web/src/ui/svg/index.tsx deleted file mode 100644 index 23dd74c6e..000000000 --- a/cloud/web/src/ui/svg/index.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { JSX } from "solid-js" - -export function IconLogomark(props: JSX.SvgSVGAttributes) { - return ( - - - - ) -} - -export function IconLogo(props: JSX.SvgSVGAttributes) { - return ( - - - - - - - - - - - - - - - ) -} diff --git a/cloud/web/src/util/context.tsx b/cloud/web/src/util/context.tsx deleted file mode 100644 index d1c6f4e7f..000000000 --- a/cloud/web/src/util/context.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { ParentProps, Show, createContext, useContext } from "solid-js" - -export function createInitializedContext< - Name extends string, - T extends { ready: boolean }, ->(name: Name, cb: () => T) { - const ctx = createContext() - - return { - use: () => { - const context = useContext(ctx) - if (!context) throw new Error(`No ${name} context`) - return context - }, - provider: (props: ParentProps) => { - const value = cb() - return ( - - - {props.children} - - - ) - }, - } -} diff --git a/cloud/web/sst-env.d.ts b/cloud/web/sst-env.d.ts deleted file mode 100644 index b6a7e9066..000000000 --- a/cloud/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/cloud/web/vite.config.ts b/cloud/web/vite.config.ts deleted file mode 100644 index 8a569641e..000000000 --- a/cloud/web/vite.config.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { defineConfig } from "vite" -import solidPlugin from "vite-plugin-solid" -import pages from "vite-plugin-pages" -import fs from "fs" -import path from "path" -import { generateHydrationScript, getAssets } from "solid-js/web" - -export default defineConfig({ - plugins: [ - pages({ - exclude: ["**/~*", "**/components/*"], - }), - solidPlugin({ ssr: true }), - { - name: "vite-plugin-solid-ssr-render", - apply: (config, env) => { - return env.command === "build" && !config.build?.ssr - }, - closeBundle: async () => { - console.log("Pre-rendering pages...") - const dist = path.resolve("dist") - try { - const serverEntryPath = path.join(dist, "server/entry-server.js") - const serverEntry = await import(serverEntryPath + "?t=" + Date.now()) - - const template = fs.readFileSync( - path.join(dist, "client/index.html"), - "utf-8", - ) - fs.writeFileSync(path.join(dist, "client/fallback.html"), template) - - const routes = ["/"] - for (const route of routes) { - const { app } = await serverEntry.render({ url: route }) - const html = template - .replace("", app) - .replace("", generateHydrationScript()) - .replace("", getAssets()) - const filePath = path.join( - dist, - `client${route === "/" ? "/index" : route}.html`, - ) - fs.mkdirSync(path.dirname(filePath), { - recursive: true, - }) - fs.writeFileSync(filePath, html) - - console.log(`Pre-rendered: ${filePath}`) - } - } catch (error) { - console.error("Error during pre-rendering:", error) - } - }, - }, - ], - server: { - port: 3000, - host: "0.0.0.0", - }, - build: { - target: "esnext", - }, -}) diff --git a/infra/cloud.ts b/infra/cloud.ts index d1ffb51e0..b7b75938a 100644 --- a/infra/cloud.ts +++ b/infra/cloud.ts @@ -1,6 +1,5 @@ import { WebhookEndpoint } from "pulumi-stripe" import { domain } from "./stage" -import { web } from "./app" //////////////// // DATABASE @@ -47,7 +46,7 @@ export const auth = new sst.cloudflare.Worker("AuthApi", { //////////////// export const stripeWebhook = new WebhookEndpoint("StripeWebhook", { - url: $interpolate`https://api.gateway.${domain}/stripe/webhook`, + url: $interpolate`https://console.${domain}/stripe/webhook`, enabledEvents: [ "checkout.session.async_payment_failed", "checkout.session.async_payment_succeeded", @@ -106,29 +105,21 @@ export const gateway = new sst.cloudflare.Worker("GatewayApi", { // CONSOLE //////////////// -/* -export const console = new sst.cloudflare.x.StaticSite("Console", { +export const console = new sst.cloudflare.x.SolidStart("Console", { domain: `console.${domain}`, - path: "cloud/web", - build: { - command: "bun run build", - output: "dist/client", - }, - environment: { - VITE_DOCS_URL: web.url.apply((url) => url!), - VITE_API_URL: gateway.url.apply((url) => url!), - VITE_AUTH_URL: auth.url.apply((url) => url!), - }, -}) -*/ - -new sst.x.DevCommand("Solid", { - link: [database], - dev: { - directory: "cloud/app", - command: "bun dev", - }, + path: "cloud/app", + link: [ + database, + AUTH_API_URL, + STRIPE_WEBHOOK_SECRET, + STRIPE_SECRET_KEY, + ANTHROPIC_API_KEY, + OPENAI_API_KEY, + ZHIPU_API_KEY, + ], environment: { + //VITE_DOCS_URL: web.url.apply((url) => url!), + //VITE_API_URL: gateway.url.apply((url) => url!), VITE_AUTH_URL: auth.url.apply((url) => url!), }, }) diff --git a/logs/.496fc674ed58d31f8b883da41cc2adb4564aad58-audit.json b/logs/.496fc674ed58d31f8b883da41cc2adb4564aad58-audit.json deleted file mode 100644 index 208b3dd95..000000000 --- a/logs/.496fc674ed58d31f8b883da41cc2adb4564aad58-audit.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "keep": { - "days": true, - "amount": 14 - }, - "auditLog": "/Users/adam/code/opencode/dev/logs/.496fc674ed58d31f8b883da41cc2adb4564aad58-audit.json", - "files": [ - { - "date": 1755891797740, - "name": "/Users/adam/code/opencode/dev/logs/mcp-puppeteer-2025-08-22.log", - "hash": "dd9b1f2e98b661ba2f56b91dd9afbdb25e50adbdd52ed1b0eef1d2045235d17c" - } - ], - "hashType": "sha256" -} \ No newline at end of file diff --git a/logs/mcp-puppeteer-2025-08-22.log b/logs/mcp-puppeteer-2025-08-22.log deleted file mode 100644 index 800731d84..000000000 --- a/logs/mcp-puppeteer-2025-08-22.log +++ /dev/null @@ -1,6 +0,0 @@ -{"level":"info","message":"Starting MCP server","service":"mcp-puppeteer","timestamp":"2025-08-22 14:43:17.765"} -{"level":"info","message":"MCP server started successfully","service":"mcp-puppeteer","timestamp":"2025-08-22 14:43:17.766"} -{"level":"info","message":"Starting MCP server","service":"mcp-puppeteer","timestamp":"2025-08-22 14:46:45.539"} -{"level":"info","message":"MCP server started successfully","service":"mcp-puppeteer","timestamp":"2025-08-22 14:46:45.540"} -{"level":"info","message":"Starting MCP server","service":"mcp-puppeteer","timestamp":"2025-08-22 14:53:08.159"} -{"level":"info","message":"MCP server started successfully","service":"mcp-puppeteer","timestamp":"2025-08-22 14:53:08.160"} diff --git a/package.json b/package.json index 4e99177c5..a38d1b613 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "hono": "4.7.10", "typescript": "5.8.2", "zod": "3.25.76", - "remeda": "2.26.0" + "remeda": "2.26.0", + "solid-js": "1.9.9" } }, "dependencies": { @@ -32,7 +33,7 @@ }, "devDependencies": { "prettier": "3.5.3", - "sst": "3.17.8" + "sst": "3.17.12" }, "repository": { "type": "git", diff --git a/packages/function/package.json b/packages/function/package.json index d03c3e59e..0acfb440a 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode/function", - "version": "0.5.18", + "version": "0.5.29", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/function/sst-env.d.ts b/packages/function/sst-env.d.ts index f60ec81a0..9c4f5cc0d 100644 --- a/packages/function/sst-env.d.ts +++ b/packages/function/sst-env.d.ts @@ -14,6 +14,10 @@ declare module "sst" { "type": "sst.sst.Linkable" "value": string } + "Console": { + "type": "sst.cloudflare.SolidStart" + "url": string + } "DATABASE_PASSWORD": { "type": "sst.sst.Secret" "value": string diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 4f7e6c261..e41fd55a7 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "0.5.18", + "version": "0.5.29", "name": "opencode", "type": "module", "private": true, @@ -41,7 +41,7 @@ "gray-matter": "4.0.3", "hono": "catalog:", "hono-openapi": "0.4.8", - "isomorphic-git": "1.32.1", + "ignore": "7.0.5", "jsonc-parser": "3.3.1", "minimatch": "10.0.3", "open": "10.1.2", diff --git a/packages/opencode/script/publish.ts b/packages/opencode/script/publish.ts index 7076b2d4d..33ddeff05 100755 --- a/packages/opencode/script/publish.ts +++ b/packages/opencode/script/publish.ts @@ -97,11 +97,11 @@ if (!snapshot) { const macX64Sha = await $`sha256sum ./dist/opencode-darwin-x64.zip | cut -d' ' -f1`.text().then((x) => x.trim()) const macArm64Sha = await $`sha256sum ./dist/opencode-darwin-arm64.zip | cut -d' ' -f1`.text().then((x) => x.trim()) - const pkgbuild = [ + const binaryPkgbuild = [ "# Maintainer: dax", "# Maintainer: adam", "", - "pkgname='${pkg}'", + "pkgname='opencode-bin'", `pkgver=${version.split("-")[0]}`, "options=('!debug' '!strip')", "pkgrel=1", @@ -125,11 +125,58 @@ if (!snapshot) { "", ].join("\n") - for (const pkg of ["opencode-bin"]) { + // Source-based PKGBUILD for opencode + const sourcePkgbuild = [ + "# Maintainer: dax", + "# Maintainer: adam", + "", + "pkgname='opencode'", + `pkgver=${version.split("-")[0]}`, + "options=('!debug' '!strip')", + "pkgrel=1", + "pkgdesc='The AI coding agent built for the terminal.'", + "url='https://github.com/sst/opencode'", + "arch=('aarch64' 'x86_64')", + "license=('MIT')", + "provides=('opencode')", + "conflicts=('opencode-bin')", + "depends=('fzf' 'ripgrep')", + "makedepends=('git' 'bun-bin' 'go')", + "", + `source=("opencode-\${pkgver}.tar.gz::https://github.com/sst/opencode/archive/v${version}.tar.gz")`, + `sha256sums=('SKIP')`, + "", + "build() {", + ` cd "opencode-\${pkgver}"`, + ` bun install`, + " cd packages/tui", + ` CGO_ENABLED=0 go build -ldflags="-s -w -X main.Version=\${pkgver}" -o tui cmd/opencode/main.go`, + " cd ../opencode", + ` bun build --define OPENCODE_TUI_PATH="'$(realpath ../tui/tui)'" --define OPENCODE_VERSION="'\${pkgver}'" --compile --target=bun-linux-x64 --outfile=opencode ./src/index.ts`, + "}", + "", + "package() {", + ` cd "opencode-\${pkgver}/packages/opencode"`, + ' install -Dm755 ./opencode "${pkgdir}/usr/bin/opencode"', + "}", + "", + ].join("\n") + + for (const [pkg, pkgbuild] of [ + ["opencode-bin", binaryPkgbuild], + ["opencode", sourcePkgbuild], + ]) { await $`rm -rf ./dist/aur-${pkg}` - await $`git clone ssh://aur@aur.archlinux.org/${pkg}.git ./dist/aur-${pkg}` + while (true) { + try { + await $`git clone ssh://aur@aur.archlinux.org/${pkg}.git ./dist/aur-${pkg}` + break + } catch (e) { + continue + } + } await $`cd ./dist/aur-${pkg} && git checkout master` - await Bun.file(`./dist/aur-${pkg}/PKGBUILD`).write(pkgbuild.replace("${pkg}", pkg)) + await Bun.file(`./dist/aur-${pkg}/PKGBUILD`).write(pkgbuild) await $`cd ./dist/aur-${pkg} && makepkg --printsrcinfo > .SRCINFO` await $`cd ./dist/aur-${pkg} && git add PKGBUILD .SRCINFO` await $`cd ./dist/aur-${pkg} && git commit -m "Update to v${version}"` diff --git a/packages/opencode/src/app/app.ts b/packages/opencode/src/app/app.ts index 0c88be273..4c781545d 100644 --- a/packages/opencode/src/app/app.ts +++ b/packages/opencode/src/app/app.ts @@ -17,6 +17,7 @@ export namespace App { hostname: z.string(), git: z.boolean(), path: z.object({ + home: z.string(), config: z.string(), data: z.string(), root: z.string(), @@ -77,6 +78,7 @@ export namespace App { }, git: git !== undefined, path: { + home: os.homedir(), config: Global.Path.config, state: Global.Path.state, data, diff --git a/packages/opencode/src/cli/cmd/auth.ts b/packages/opencode/src/cli/cmd/auth.ts index be38c0eba..eb2eb19b7 100644 --- a/packages/opencode/src/cli/cmd/auth.ts +++ b/packages/opencode/src/cli/cmd/auth.ts @@ -245,7 +245,7 @@ export const AuthLoginCommand = cmd({ } if (provider === "vercel") { - prompts.log.info("You can create an api key in the dashboard") + prompts.log.info("You can create an api key at https://vercel.link/ai-gateway-token") } const key = await prompts.password({ diff --git a/packages/opencode/src/cli/cmd/debug/app.ts b/packages/opencode/src/cli/cmd/debug/app.ts new file mode 100644 index 000000000..ee5b038d5 --- /dev/null +++ b/packages/opencode/src/cli/cmd/debug/app.ts @@ -0,0 +1,20 @@ +import { App } from "../../../app/app" +import { bootstrap } from "../../bootstrap" +import { cmd } from "../cmd" + +const AppInfoCommand = cmd({ + command: "info", + builder: (yargs) => yargs, + async handler() { + await bootstrap({ cwd: process.cwd() }, async () => { + const app = App.info() + console.log(JSON.stringify(app, null, 2)) + }) + }, +}) + +export const AppCommand = cmd({ + command: "app", + builder: (yargs) => yargs.command(AppInfoCommand).demandCommand(), + async handler() {}, +}) diff --git a/packages/opencode/src/cli/cmd/debug/file.ts b/packages/opencode/src/cli/cmd/debug/file.ts index f773dbd9c..74fb19361 100644 --- a/packages/opencode/src/cli/cmd/debug/file.ts +++ b/packages/opencode/src/cli/cmd/debug/file.ts @@ -29,8 +29,25 @@ const FileStatusCommand = cmd({ }, }) +const FileListCommand = cmd({ + command: "list ", + builder: (yargs) => + yargs.positional("path", { + type: "string", + demandOption: true, + description: "File path to list", + }), + async handler(args) { + await bootstrap({ cwd: process.cwd() }, async () => { + const files = await File.list(args.path) + console.log(JSON.stringify(files, null, 2)) + }) + }, +}) + export const FileCommand = cmd({ command: "file", - builder: (yargs) => yargs.command(FileReadCommand).command(FileStatusCommand).demandCommand(), + builder: (yargs) => + yargs.command(FileReadCommand).command(FileStatusCommand).command(FileListCommand).demandCommand(), async handler() {}, }) diff --git a/packages/opencode/src/cli/cmd/debug/index.ts b/packages/opencode/src/cli/cmd/debug/index.ts index 265296f5b..d7fbc8fb5 100644 --- a/packages/opencode/src/cli/cmd/debug/index.ts +++ b/packages/opencode/src/cli/cmd/debug/index.ts @@ -1,6 +1,7 @@ import { Global } from "../../../global" import { bootstrap } from "../../bootstrap" import { cmd } from "../cmd" +import { AppCommand } from "./app" import { FileCommand } from "./file" import { LSPCommand } from "./lsp" import { RipgrepCommand } from "./ripgrep" @@ -11,6 +12,7 @@ export const DebugCommand = cmd({ command: "debug", builder: (yargs) => yargs + .command(AppCommand) .command(LSPCommand) .command(RipgrepCommand) .command(FileCommand) diff --git a/packages/opencode/src/cli/cmd/debug/lsp.ts b/packages/opencode/src/cli/cmd/debug/lsp.ts index ac1bac7c1..4d864db4a 100644 --- a/packages/opencode/src/cli/cmd/debug/lsp.ts +++ b/packages/opencode/src/cli/cmd/debug/lsp.ts @@ -16,7 +16,7 @@ const DiagnosticsCommand = cmd({ async handler(args) { await bootstrap({ cwd: process.cwd() }, async () => { await LSP.touchFile(args.file, true) - console.log(await LSP.diagnostics()) + console.log(JSON.stringify(await LSP.diagnostics(), null, 2)) }) }, }) diff --git a/packages/opencode/src/cli/cmd/run.ts b/packages/opencode/src/cli/cmd/run.ts index 25d917e14..181d8c1e7 100644 --- a/packages/opencode/src/cli/cmd/run.ts +++ b/packages/opencode/src/cli/cmd/run.ts @@ -64,6 +64,11 @@ export const RunCommand = cmd({ if (!process.stdin.isTTY) message += "\n" + (await Bun.stdin.text()) + if (message.trim().length === 0) { + UI.error("Message cannot be empty") + return + } + await bootstrap({ cwd: process.cwd() }, async () => { const session = await (async () => { if (args.continue) { @@ -171,12 +176,8 @@ export const RunCommand = cmd({ const result = await Session.chat({ sessionID: session.id, messageID, - ...(agent.model - ? agent.model - : { - providerID, - modelID, - }), + providerID, + modelID, agent: agent.name, parts: [ { diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 292c6f6c8..95afe9847 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -342,7 +342,10 @@ export namespace Config { theme: z.string().optional().describe("Theme name to use for the interface"), keybinds: Keybinds.optional().describe("Custom keybind configurations"), tui: TUI.optional().describe("TUI specific settings"), - command: z.record(z.string(), Command).optional(), + command: z + .record(z.string(), Command) + .optional() + .describe("Command configuration, see https://opencode.ai/docs/commands"), plugin: z.string().array().optional(), snapshot: z.boolean().optional(), share: z diff --git a/packages/opencode/src/file/index.ts b/packages/opencode/src/file/index.ts index 0856a69b2..4ccad296b 100644 --- a/packages/opencode/src/file/index.ts +++ b/packages/opencode/src/file/index.ts @@ -3,8 +3,9 @@ import { Bus } from "../bus" import { $ } from "bun" import { createPatch } from "diff" import path from "path" -import * as git from "isomorphic-git" +import { App } from "../app/app" import fs from "fs" +import ignore from "ignore" import { Log } from "../util/log" import { Instance } from "../project/instance" import { Project } from "../project/project" @@ -25,6 +26,18 @@ export namespace File { export type Info = z.infer + export const Node = z + .object({ + name: z.string(), + path: z.string(), + type: z.enum(["file", "directory"]), + ignored: z.boolean(), + }) + .openapi({ + ref: "FileNode", + }) + export type Node = z.infer + export const Event = { Edited: Bus.event( "file.edited", @@ -114,12 +127,8 @@ export namespace File { .then((x) => x.trim()) if (project.vcs === "git") { const rel = path.relative(Instance.worktree, full) - const diff = await git.status({ - fs, - dir: Instance.worktree, - filepath: rel, - }) - if (diff !== "unmodified") { + const diff = await $`git diff ${rel}`.cwd(Instance.worktree).quiet().nothrow().text() + if (diff.trim()) { const original = await $`git show HEAD:${rel}`.cwd(Instance.worktree).quiet().nothrow().text() const patch = createPatch(file, original, content, "old", "new", { context: Infinity, @@ -129,4 +138,38 @@ export namespace File { } return { type: "raw", content } } + + export async function list(dir?: string) { + const exclude = [".git", ".DS_Store"] + const app = App.info() + let ignored = (_: string) => false + if (app.git) { + const gitignore = Bun.file(path.join(app.path.root, ".gitignore")) + if (await gitignore.exists()) { + const ig = ignore().add(await gitignore.text()) + ignored = ig.ignores.bind(ig) + } + } + const resolved = dir ? path.join(app.path.cwd, dir) : app.path.cwd + const nodes: Node[] = [] + for (const entry of await fs.promises.readdir(resolved, { withFileTypes: true })) { + if (exclude.includes(entry.name)) continue + const fullPath = path.join(resolved, entry.name) + const relativePath = path.relative(app.path.cwd, fullPath) + const relativeToRoot = path.relative(app.path.root, fullPath) + const type = entry.isDirectory() ? "directory" : "file" + nodes.push({ + name: entry.name, + path: relativePath, + type, + ignored: ignored(type === "directory" ? relativeToRoot + "/" : relativeToRoot), + }) + } + return nodes.sort((a, b) => { + if (a.type !== b.type) { + return a.type === "directory" ? -1 : 1 + } + return a.name.localeCompare(b.name) + }) + } } diff --git a/packages/opencode/src/lsp/index.ts b/packages/opencode/src/lsp/index.ts index 10921ef25..ae73c8cf7 100644 --- a/packages/opencode/src/lsp/index.ts +++ b/packages/opencode/src/lsp/index.ts @@ -139,6 +139,7 @@ export namespace LSP { s.broken.add(root + server.id) handle.process.kill() log.error(`Failed to initialize LSP client ${server.id}`, { error: err }) + return undefined }) if (!client) continue s.clients.push(client) diff --git a/packages/opencode/src/lsp/server.ts b/packages/opencode/src/lsp/server.ts index e5bd15976..66bacd282 100644 --- a/packages/opencode/src/lsp/server.ts +++ b/packages/opencode/src/lsp/server.ts @@ -148,6 +148,7 @@ export namespace LSPServer { async spawn(root) { const eslint = await Bun.resolve("eslint", Instance.directory).catch(() => {}) if (!eslint) return + log.info("spawning eslint server") const serverPath = path.join(Global.Path.bin, "vscode-eslint", "server", "out", "eslintServer.js") if (!(await Bun.file(serverPath).exists())) { if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return @@ -164,7 +165,9 @@ export namespace LSPServer { const extractedPath = path.join(Global.Path.bin, "vscode-eslint-main") const finalPath = path.join(Global.Path.bin, "vscode-eslint") - if (await Bun.file(finalPath).exists()) { + const stats = await fs.stat(finalPath).catch(() => undefined) + if (stats) { + log.info("removing old eslint installation", { path: finalPath }) await fs.rm(finalPath, { force: true, recursive: true }) } await fs.rename(extractedPath, finalPath) @@ -512,7 +515,35 @@ export namespace LSPServer { export const RustAnalyzer: Info = { id: "rust", - root: NearestRoot(["Cargo.toml", "Cargo.lock"]), + root: async (file, app) => { + const crateRoot = await NearestRoot(["Cargo.toml", "Cargo.lock"])(file, app) + if (crateRoot === undefined) { + return undefined + } + let currentDir = crateRoot + + while (currentDir !== path.dirname(currentDir)) { + // Stop at filesystem root + const cargoTomlPath = path.join(currentDir, "Cargo.toml") + try { + const cargoTomlContent = await Bun.file(cargoTomlPath).text() + if (cargoTomlContent.includes("[workspace]")) { + return currentDir + } + } catch (err) { + // File doesn't exist or can't be read, continue searching up + } + + const parentDir = path.dirname(currentDir) + if (parentDir === currentDir) break // Reached filesystem root + currentDir = parentDir + + // Stop if we've gone above the app root + if (!currentDir.startsWith(app.path.root)) break + } + + return crateRoot + }, extensions: [".rs"], async spawn(root) { const bin = Bun.which("rust-analyzer") diff --git a/packages/opencode/src/mcp/index.ts b/packages/opencode/src/mcp/index.ts index bf17661e4..702f644d0 100644 --- a/packages/opencode/src/mcp/index.ts +++ b/packages/opencode/src/mcp/index.ts @@ -54,7 +54,7 @@ export namespace MCP { let lastError: Error | undefined for (const { name, transport } of transports) { const client = await experimental_createMCPClient({ - name: key, + name: "opencode", transport, }).catch((error) => { lastError = error instanceof Error ? error : new Error(String(error)) @@ -91,7 +91,7 @@ export namespace MCP { if (mcp.type === "local") { const [cmd, ...args] = mcp.command const client = await experimental_createMCPClient({ - name: key, + name: "opencode", transport: new StdioClientTransport({ stderr: "ignore", command: cmd, diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts index 4622721df..47e28d4da 100644 --- a/packages/opencode/src/server/server.ts +++ b/packages/opencode/src/server/server.ts @@ -936,6 +936,34 @@ export namespace Server { ) .get( "/file", + describeRoute({ + description: "List files and directories", + operationId: "file.list", + responses: { + 200: { + description: "Files and directories", + content: { + "application/json": { + schema: resolver(File.Node.array()), + }, + }, + }, + }, + }), + zValidator( + "query", + z.object({ + path: z.string(), + }), + ), + async (c) => { + const path = c.req.valid("query").path + const content = await File.list(path) + return c.json(content) + }, + ) + .get( + "/file/content", describeRoute({ description: "Read a file", operationId: "file.read", @@ -964,10 +992,6 @@ export namespace Server { async (c) => { const path = c.req.valid("query").path const content = await File.read(path) - log.info("read file", { - path, - content: content.content, - }) return c.json(content) }, ) diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts index f64788882..d10f2b41e 100644 --- a/packages/opencode/src/session/index.ts +++ b/packages/opencode/src/session/index.ts @@ -1,4 +1,5 @@ import path from "path" +import os from "os" import { spawn } from "child_process" import { Decimal } from "decimal.js" import { z, ZodSchema } from "zod" @@ -721,7 +722,9 @@ export namespace Session { draft.title = title.trim() }) }) - .catch(() => {}) + .catch((error) => { + log.error("failed to generate title", { error, model: small.info.id }) + }) } const agent = await Agent.get(inputAgent) @@ -866,11 +869,31 @@ export namespace Session { const execute = item.execute if (!execute) continue item.execute = async (args, opts) => { + await Plugin.trigger( + "tool.execute.before", + { + tool: key, + sessionID: input.sessionID, + callID: opts.toolCallId, + }, + { + args, + }, + ) const result = await execute(args, opts) const output = result.content .filter((x: any) => x.type === "text") .map((x: any) => x.text) .join("\n\n") + await Plugin.trigger( + "tool.execute.after", + { + tool: key, + sessionID: input.sessionID, + callID: opts.toolCallId, + }, + result, + ) return { output, @@ -1041,6 +1064,25 @@ export namespace Session { export type ShellInput = z.infer export async function shell(input: ShellInput) { using abort = lock(input.sessionID) + const userMsg: MessageV2.User = { + id: Identifier.ascending("message"), + sessionID: input.sessionID, + time: { + created: Date.now(), + }, + role: "user", + } + await updateMessage(userMsg) + const userPart: MessageV2.Part = { + type: "text", + id: Identifier.ascending("part"), + messageID: userMsg.id, + sessionID: input.sessionID, + text: "The following tool was executed by the user", + synthetic: true, + } + await updatePart(userPart) + const msg: MessageV2.Assistant = { id: Identifier.ascending("message"), sessionID: input.sessionID, @@ -1177,14 +1219,22 @@ export namespace Session { export async function command(input: CommandInput) { const command = await Command.get(input.command) - const agent = input.agent ?? command.agent ?? "build" + const agent = command.agent ?? input.agent ?? "build" + const fmtModel = (model: { providerID: string; modelID: string }) => `${model.providerID}/${model.modelID}` + const model = - input.model ?? command.model ?? - (await Agent.get(agent).then((x) => (x.model ? `${x.model.providerID}/${x.model.modelID}` : undefined))) ?? - (await Provider.defaultModel().then((x) => `${x.providerID}/${x.modelID}`)) + (command.agent && (await Agent.get(command.agent).then((x) => (x.model ? fmtModel(x.model) : undefined)))) ?? + input.model ?? + (input.agent && (await Agent.get(input.agent).then((x) => (x.model ? fmtModel(x.model) : undefined)))) ?? + fmtModel(await Provider.defaultModel()) + let template = command.template.replace("$ARGUMENTS", input.arguments) + // intentionally doing match regex doing bash regex replacements + // this is because bash commands can output "@" references + const fileMatches = template.matchAll(fileRegex) + const bash = Array.from(template.matchAll(bashRegex)) if (bash.length > 0) { const results = await Promise.all( @@ -1207,15 +1257,18 @@ export namespace Session { }, ] as ChatInput["parts"] - const matches = template.matchAll(fileRegex) const app = App.info() - for (const match of matches) { - const file = path.join(app.path.cwd, match[1]) + for (const match of fileMatches) { + const filename = match[1] + const filepath = filename.startsWith("~/") + ? path.join(os.homedir(), filename.slice(2)) + : path.join(app.path.cwd, filename) + parts.push({ type: "file", - url: `file://${file}`, - filename: match[1], + url: `file://${filepath}`, + filename, mime: "text/plain", }) } diff --git a/packages/opencode/src/tool/bash.txt b/packages/opencode/src/tool/bash.txt index ce78347e0..342073b9b 100644 --- a/packages/opencode/src/tool/bash.txt +++ b/packages/opencode/src/tool/bash.txt @@ -109,6 +109,9 @@ IMPORTANT: When the user asks you to create a pull request, follow these steps c gh pr create --title "the pr title" --body "$(cat <<'EOF' ## Summary <1-3 bullet points> +EOF +)" + Important: - NEVER update the git config diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 5024f2466..1f5fcf88e 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/plugin", - "version": "0.5.18", + "version": "0.5.29", "type": "module", "scripts": { "typecheck": "tsc --noEmit" @@ -19,7 +19,6 @@ "@opencode-ai/sdk": "workspace:*" }, "devDependencies": { - "@hey-api/openapi-ts": "0.81.0", "@tsconfig/node22": "catalog:", "typescript": "catalog:" } diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 2437a1f98..b6793d1ad 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/sdk", - "version": "0.5.18", + "version": "0.5.29", "type": "module", "scripts": { "typecheck": "tsc --noEmit" @@ -29,6 +29,6 @@ "@tsconfig/node22": "catalog:" }, "dependencies": { - "@hey-api/openapi-ts": "0.80.1" + "@hey-api/openapi-ts": "0.81.0" } } diff --git a/packages/sdk/js/src/client.ts b/packages/sdk/js/src/client.ts index 8346fd8a2..29b9de906 100644 --- a/packages/sdk/js/src/client.ts +++ b/packages/sdk/js/src/client.ts @@ -1,8 +1,8 @@ export * from "./gen/types.gen.js" export { type Config as OpencodeClientConfig, OpencodeClient } -import { createClient } from "./gen/client/client.js" -import { type Config } from "./gen/client/types.js" +import { createClient } from "./gen/client/client.gen.js" +import { type Config } from "./gen/client/types.gen.js" import { OpencodeClient } from "./gen/sdk.gen.js" export function createOpencodeClient(config?: Config) { diff --git a/packages/sdk/js/src/gen/client/client.ts b/packages/sdk/js/src/gen/client/client.gen.ts similarity index 73% rename from packages/sdk/js/src/gen/client/client.ts rename to packages/sdk/js/src/gen/client/client.gen.ts index 46a62694c..34a8d0bec 100644 --- a/packages/sdk/js/src/gen/client/client.ts +++ b/packages/sdk/js/src/gen/client/client.gen.ts @@ -1,4 +1,7 @@ -import type { Client, Config, RequestOptions } from "./types.js" +// This file is auto-generated by @hey-api/openapi-ts + +import { createSseClient } from "../core/serverSentEvents.gen.js" +import type { Client, Config, RequestOptions, ResolvedRequestOptions } from "./types.gen.js" import { buildUrl, createConfig, @@ -7,7 +10,7 @@ import { mergeConfigs, mergeHeaders, setAuthParams, -} from "./utils.js" +} from "./utils.gen.js" type ReqInit = Omit & { body?: any @@ -24,14 +27,15 @@ export const createClient = (config: Config = {}): Client => { return getConfig() } - const interceptors = createInterceptors() + const interceptors = createInterceptors() - const request: Client["request"] = async (options) => { + const beforeRequest = async (options: RequestOptions) => { const opts = { ..._config, ...options, fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, headers: mergeHeaders(_config.headers, options.headers), + serializedBody: undefined, } if (opts.security) { @@ -46,18 +50,26 @@ export const createClient = (config: Config = {}): Client => { } if (opts.body && opts.bodySerializer) { - opts.body = opts.bodySerializer(opts.body) + opts.serializedBody = opts.bodySerializer(opts.body) } // remove Content-Type header if body is empty to avoid sending invalid requests - if (opts.body === undefined || opts.body === "") { + if (opts.serializedBody === undefined || opts.serializedBody === "") { opts.headers.delete("Content-Type") } const url = buildUrl(opts) + + return { opts, url } + } + + const request: Client["request"] = async (options) => { + // @ts-expect-error + const { opts, url } = await beforeRequest(options) const requestInit: ReqInit = { redirect: "follow", ...opts, + body: opts.serializedBody, } let request = new Request(url, requestInit) @@ -166,20 +178,35 @@ export const createClient = (config: Config = {}): Client => { } } + const makeMethod = (method: Required["method"]) => { + const fn = (options: RequestOptions) => request({ ...options, method }) + fn.sse = async (options: RequestOptions) => { + const { opts, url } = await beforeRequest(options) + return createSseClient({ + ...opts, + body: opts.body as BodyInit | null | undefined, + headers: opts.headers as unknown as Record, + method, + url, + }) + } + return fn + } + return { buildUrl, - connect: (options) => request({ ...options, method: "CONNECT" }), - delete: (options) => request({ ...options, method: "DELETE" }), - get: (options) => request({ ...options, method: "GET" }), + connect: makeMethod("CONNECT"), + delete: makeMethod("DELETE"), + get: makeMethod("GET"), getConfig, - head: (options) => request({ ...options, method: "HEAD" }), + head: makeMethod("HEAD"), interceptors, - options: (options) => request({ ...options, method: "OPTIONS" }), - patch: (options) => request({ ...options, method: "PATCH" }), - post: (options) => request({ ...options, method: "POST" }), - put: (options) => request({ ...options, method: "PUT" }), + options: makeMethod("OPTIONS"), + patch: makeMethod("PATCH"), + post: makeMethod("POST"), + put: makeMethod("PUT"), request, setConfig, - trace: (options) => request({ ...options, method: "TRACE" }), - } + trace: makeMethod("TRACE"), + } as Client } diff --git a/packages/sdk/js/src/gen/client/index.ts b/packages/sdk/js/src/gen/client/index.ts index ce89a34cc..06f21e3d8 100644 --- a/packages/sdk/js/src/gen/client/index.ts +++ b/packages/sdk/js/src/gen/client/index.ts @@ -1,8 +1,14 @@ -export type { Auth } from "../core/auth.js" -export type { QuerySerializerOptions } from "../core/bodySerializer.js" -export { formDataBodySerializer, jsonBodySerializer, urlSearchParamsBodySerializer } from "../core/bodySerializer.js" -export { buildClientParams } from "../core/params.js" -export { createClient } from "./client.js" +// This file is auto-generated by @hey-api/openapi-ts + +export type { Auth } from "../core/auth.gen.js" +export type { QuerySerializerOptions } from "../core/bodySerializer.gen.js" +export { + formDataBodySerializer, + jsonBodySerializer, + urlSearchParamsBodySerializer, +} from "../core/bodySerializer.gen.js" +export { buildClientParams } from "../core/params.gen.js" +export { createClient } from "./client.gen.js" export type { Client, ClientOptions, @@ -12,7 +18,8 @@ export type { OptionsLegacyParser, RequestOptions, RequestResult, + ResolvedRequestOptions, ResponseStyle, TDataShape, -} from "./types.js" -export { createConfig, mergeHeaders } from "./utils.js" +} from "./types.gen.js" +export { createConfig, mergeHeaders } from "./utils.gen.js" diff --git a/packages/sdk/js/src/gen/client/types.ts b/packages/sdk/js/src/gen/client/types.gen.ts similarity index 69% rename from packages/sdk/js/src/gen/client/types.ts rename to packages/sdk/js/src/gen/client/types.gen.ts index f3b116bae..db8e544cf 100644 --- a/packages/sdk/js/src/gen/client/types.ts +++ b/packages/sdk/js/src/gen/client/types.gen.ts @@ -1,6 +1,9 @@ -import type { Auth } from "../core/auth.js" -import type { Client as CoreClient, Config as CoreConfig } from "../core/types.js" -import type { Middleware } from "./utils.js" +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth } from "../core/auth.gen.js" +import type { ServerSentEventsOptions, ServerSentEventsResult } from "../core/serverSentEvents.gen.js" +import type { Client as CoreClient, Config as CoreConfig } from "../core/types.gen.js" +import type { Middleware } from "./utils.gen.js" export type ResponseStyle = "data" | "fields" @@ -49,13 +52,18 @@ export interface Config } export interface RequestOptions< + TData = unknown, TResponseStyle extends ResponseStyle = "fields", ThrowOnError extends boolean = boolean, Url extends string = string, > extends Config<{ - responseStyle: TResponseStyle - throwOnError: ThrowOnError - }> { + responseStyle: TResponseStyle + throwOnError: ThrowOnError + }>, + Pick< + ServerSentEventsOptions, + "onSseError" | "onSseEvent" | "sseDefaultRetryDelay" | "sseMaxRetryAttempts" | "sseMaxRetryDelay" + > { /** * Any body that you want to add to your request. * @@ -71,6 +79,14 @@ export interface RequestOptions< url: Url } +export interface ResolvedRequestOptions< + TResponseStyle extends ResponseStyle = "fields", + ThrowOnError extends boolean = boolean, + Url extends string = string, +> extends RequestOptions { + serializedBody?: string +} + export type RequestResult< TData = unknown, TError = unknown, @@ -112,23 +128,36 @@ export interface ClientOptions { throwOnError?: boolean } -type MethodFn = < +type MethodFnBase = < TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = "fields", >( - options: Omit, "method">, + options: Omit, "method">, ) => RequestResult +type MethodFnServerSentEvents = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = "fields", +>( + options: Omit, "method">, +) => Promise> + +type MethodFn = MethodFnBase & { + sse: MethodFnServerSentEvents +} + type RequestFn = < TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = "fields", >( - options: Omit, "method"> & - Pick>, "method">, + options: Omit, "method"> & + Pick>, "method">, ) => RequestResult type BuildUrlFn = < @@ -143,7 +172,7 @@ type BuildUrlFn = < ) => string export type Client = CoreClient & { - interceptors: Middleware + interceptors: Middleware } /** @@ -171,8 +200,10 @@ type OmitKeys = Pick> export type Options< TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, + TResponse = unknown, TResponseStyle extends ResponseStyle = "fields", -> = OmitKeys, "body" | "path" | "query" | "url"> & Omit +> = OmitKeys, "body" | "path" | "query" | "url"> & + Omit export type OptionsLegacyParser< TData = unknown, @@ -180,12 +211,12 @@ export type OptionsLegacyParser< TResponseStyle extends ResponseStyle = "fields", > = TData extends { body?: any } ? TData extends { headers?: any } - ? OmitKeys, "body" | "headers" | "url"> & TData - : OmitKeys, "body" | "url"> & + ? OmitKeys, "body" | "headers" | "url"> & TData + : OmitKeys, "body" | "url"> & TData & - Pick, "headers"> + Pick, "headers"> : TData extends { headers?: any } - ? OmitKeys, "headers" | "url"> & + ? OmitKeys, "headers" | "url"> & TData & - Pick, "body"> - : OmitKeys, "url"> & TData + Pick, "body"> + : OmitKeys, "url"> & TData diff --git a/packages/sdk/js/src/gen/client/utils.ts b/packages/sdk/js/src/gen/client/utils.gen.ts similarity index 72% rename from packages/sdk/js/src/gen/client/utils.ts rename to packages/sdk/js/src/gen/client/utils.gen.ts index 84648c855..209bfbe8e 100644 --- a/packages/sdk/js/src/gen/client/utils.ts +++ b/packages/sdk/js/src/gen/client/utils.gen.ts @@ -1,84 +1,11 @@ -import { getAuthToken } from "../core/auth.js" -import type { QuerySerializer, QuerySerializerOptions } from "../core/bodySerializer.js" -import { jsonBodySerializer } from "../core/bodySerializer.js" -import { serializeArrayParam, serializeObjectParam, serializePrimitiveParam } from "../core/pathSerializer.js" -import type { Client, ClientOptions, Config, RequestOptions } from "./types.js" +// This file is auto-generated by @hey-api/openapi-ts -interface PathSerializer { - path: Record - url: string -} - -const PATH_PARAM_RE = /\{[^{}]+\}/g - -type ArrayStyle = "form" | "spaceDelimited" | "pipeDelimited" -type MatrixStyle = "label" | "matrix" | "simple" -type ArraySeparatorStyle = ArrayStyle | MatrixStyle - -const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { - let url = _url - const matches = _url.match(PATH_PARAM_RE) - if (matches) { - for (const match of matches) { - let explode = false - let name = match.substring(1, match.length - 1) - let style: ArraySeparatorStyle = "simple" - - if (name.endsWith("*")) { - explode = true - name = name.substring(0, name.length - 1) - } - - if (name.startsWith(".")) { - name = name.substring(1) - style = "label" - } else if (name.startsWith(";")) { - name = name.substring(1) - style = "matrix" - } - - const value = path[name] - - if (value === undefined || value === null) { - continue - } - - if (Array.isArray(value)) { - url = url.replace(match, serializeArrayParam({ explode, name, style, value })) - continue - } - - if (typeof value === "object") { - url = url.replace( - match, - serializeObjectParam({ - explode, - name, - style, - value: value as Record, - valueOnly: true, - }), - ) - continue - } - - if (style === "matrix") { - url = url.replace( - match, - `;${serializePrimitiveParam({ - name, - value: value as string, - })}`, - ) - continue - } - - const replaceValue = encodeURIComponent(style === "label" ? `.${value as string}` : (value as string)) - url = url.replace(match, replaceValue) - } - } - return url -} +import { getAuthToken } from "../core/auth.gen.js" +import type { QuerySerializerOptions } from "../core/bodySerializer.gen.js" +import { jsonBodySerializer } from "../core/bodySerializer.gen.js" +import { serializeArrayParam, serializeObjectParam, serializePrimitiveParam } from "../core/pathSerializer.gen.js" +import { getUrl } from "../core/utils.gen.js" +import type { Client, ClientOptions, Config, RequestOptions } from "./types.gen.js" export const createQuerySerializer = ({ allowReserved, array, object }: QuerySerializerOptions = {}) => { const querySerializer = (queryParams: T) => { @@ -161,6 +88,21 @@ export const getParseAs = (contentType: string | null): Exclude & { + headers: Headers + }, + name?: string, +): boolean => { + if (!name) { + return false + } + if (options.headers.has(name) || options.query?.[name] || options.headers.get("Cookie")?.includes(`${name}=`)) { + return true + } + return false +} + export const setAuthParams = async ({ security, ...options @@ -169,6 +111,10 @@ export const setAuthParams = async ({ headers: Headers }) => { for (const auth of security) { + if (checkForExistence(options, auth.name)) { + continue + } + const token = await getAuthToken(auth, options.auth) if (!token) { @@ -192,13 +138,11 @@ export const setAuthParams = async ({ options.headers.set(name, token) break } - - return } } -export const buildUrl: Client["buildUrl"] = (options) => { - const url = getUrl({ +export const buildUrl: Client["buildUrl"] = (options) => + getUrl({ baseUrl: options.baseUrl as string, path: options.path, query: options.query, @@ -208,36 +152,6 @@ export const buildUrl: Client["buildUrl"] = (options) => { : createQuerySerializer(options.querySerializer), url: options.url, }) - return url -} - -export const getUrl = ({ - baseUrl, - path, - query, - querySerializer, - url: _url, -}: { - baseUrl?: string - path?: Record - query?: Record - querySerializer: QuerySerializer - url: string -}) => { - const pathUrl = _url.startsWith("/") ? _url : `/${_url}` - let url = (baseUrl ?? "") + pathUrl - if (path) { - url = defaultPathSerializer({ path, url }) - } - let search = query ? querySerializer(query) : "" - if (search.startsWith("?")) { - search = search.substring(1) - } - if (search) { - url += `?${search}` - } - return url -} export const mergeConfigs = (a: Config, b: Config): Config => { const config = { ...a, ...b } diff --git a/packages/sdk/js/src/gen/core/auth.ts b/packages/sdk/js/src/gen/core/auth.gen.ts similarity index 93% rename from packages/sdk/js/src/gen/core/auth.ts rename to packages/sdk/js/src/gen/core/auth.gen.ts index e496d4557..bc7b230f4 100644 --- a/packages/sdk/js/src/gen/core/auth.ts +++ b/packages/sdk/js/src/gen/core/auth.gen.ts @@ -1,3 +1,5 @@ +// This file is auto-generated by @hey-api/openapi-ts + export type AuthToken = string | undefined export interface Auth { diff --git a/packages/sdk/js/src/gen/core/bodySerializer.ts b/packages/sdk/js/src/gen/core/bodySerializer.gen.ts similarity index 92% rename from packages/sdk/js/src/gen/core/bodySerializer.ts rename to packages/sdk/js/src/gen/core/bodySerializer.gen.ts index 8a4a13410..066061605 100644 --- a/packages/sdk/js/src/gen/core/bodySerializer.ts +++ b/packages/sdk/js/src/gen/core/bodySerializer.gen.ts @@ -1,4 +1,6 @@ -import type { ArrayStyle, ObjectStyle, SerializerOptions } from "./pathSerializer.js" +// This file is auto-generated by @hey-api/openapi-ts + +import type { ArrayStyle, ObjectStyle, SerializerOptions } from "./pathSerializer.gen.js" export type QuerySerializer = (query: Record) => string @@ -13,6 +15,8 @@ export interface QuerySerializerOptions { const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => { if (typeof value === "string" || value instanceof Blob) { data.append(key, value) + } else if (value instanceof Date) { + data.append(key, value.toISOString()) } else { data.append(key, JSON.stringify(value)) } diff --git a/packages/sdk/js/src/gen/core/params.ts b/packages/sdk/js/src/gen/core/params.gen.ts similarity index 98% rename from packages/sdk/js/src/gen/core/params.ts rename to packages/sdk/js/src/gen/core/params.gen.ts index 0a09619d1..68ad1a778 100644 --- a/packages/sdk/js/src/gen/core/params.ts +++ b/packages/sdk/js/src/gen/core/params.gen.ts @@ -1,3 +1,5 @@ +// This file is auto-generated by @hey-api/openapi-ts + type Slot = "body" | "headers" | "path" | "query" export type Field = diff --git a/packages/sdk/js/src/gen/core/pathSerializer.ts b/packages/sdk/js/src/gen/core/pathSerializer.gen.ts similarity index 98% rename from packages/sdk/js/src/gen/core/pathSerializer.ts rename to packages/sdk/js/src/gen/core/pathSerializer.gen.ts index 1e27c8d18..96be3bc5a 100644 --- a/packages/sdk/js/src/gen/core/pathSerializer.ts +++ b/packages/sdk/js/src/gen/core/pathSerializer.gen.ts @@ -1,3 +1,5 @@ +// This file is auto-generated by @hey-api/openapi-ts + interface SerializeOptions extends SerializePrimitiveOptions, SerializerOptions {} interface SerializePrimitiveOptions { diff --git a/packages/sdk/js/src/gen/core/serverSentEvents.gen.ts b/packages/sdk/js/src/gen/core/serverSentEvents.gen.ts new file mode 100644 index 000000000..8f7fac549 --- /dev/null +++ b/packages/sdk/js/src/gen/core/serverSentEvents.gen.ts @@ -0,0 +1,210 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Config } from "./types.gen.js" + +export type ServerSentEventsOptions = Omit & + Pick & { + /** + * Callback invoked when a network or parsing error occurs during streaming. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param error The error that occurred. + */ + onSseError?: (error: unknown) => void + /** + * Callback invoked when an event is streamed from the server. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param event Event streamed from the server. + * @returns Nothing (void). + */ + onSseEvent?: (event: StreamEvent) => void + /** + * Default retry delay in milliseconds. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 3000 + */ + sseDefaultRetryDelay?: number + /** + * Maximum number of retry attempts before giving up. + */ + sseMaxRetryAttempts?: number + /** + * Maximum retry delay in milliseconds. + * + * Applies only when exponential backoff is used. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 30000 + */ + sseMaxRetryDelay?: number + /** + * Optional sleep function for retry backoff. + * + * Defaults to using `setTimeout`. + */ + sseSleepFn?: (ms: number) => Promise + url: string + } + +export interface StreamEvent { + data: TData + event?: string + id?: string + retry?: number +} + +export type ServerSentEventsResult = { + stream: AsyncGenerator ? TData[keyof TData] : TData, TReturn, TNext> +} + +export const createSseClient = ({ + onSseError, + onSseEvent, + responseTransformer, + responseValidator, + sseDefaultRetryDelay, + sseMaxRetryAttempts, + sseMaxRetryDelay, + sseSleepFn, + url, + ...options +}: ServerSentEventsOptions): ServerSentEventsResult => { + let lastEventId: string | undefined + + const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))) + + const createStream = async function* () { + let retryDelay: number = sseDefaultRetryDelay ?? 3000 + let attempt = 0 + const signal = options.signal ?? new AbortController().signal + + while (true) { + if (signal.aborted) break + + attempt++ + + const headers = + options.headers instanceof Headers + ? options.headers + : new Headers(options.headers as Record | undefined) + + if (lastEventId !== undefined) { + headers.set("Last-Event-ID", lastEventId) + } + + try { + const response = await fetch(url, { ...options, headers, signal }) + + if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`) + + if (!response.body) throw new Error("No body in SSE response") + + const reader = response.body.pipeThrough(new TextDecoderStream()).getReader() + + let buffer = "" + + const abortHandler = () => { + try { + reader.cancel() + } catch { + // noop + } + } + + signal.addEventListener("abort", abortHandler) + + try { + while (true) { + const { done, value } = await reader.read() + if (done) break + buffer += value + + const chunks = buffer.split("\n\n") + buffer = chunks.pop() ?? "" + + for (const chunk of chunks) { + const lines = chunk.split("\n") + const dataLines: Array = [] + let eventName: string | undefined + + for (const line of lines) { + if (line.startsWith("data:")) { + dataLines.push(line.replace(/^data:\s*/, "")) + } else if (line.startsWith("event:")) { + eventName = line.replace(/^event:\s*/, "") + } else if (line.startsWith("id:")) { + lastEventId = line.replace(/^id:\s*/, "") + } else if (line.startsWith("retry:")) { + const parsed = Number.parseInt(line.replace(/^retry:\s*/, ""), 10) + if (!Number.isNaN(parsed)) { + retryDelay = parsed + } + } + } + + let data: unknown + let parsedJson = false + + if (dataLines.length) { + const rawData = dataLines.join("\n") + try { + data = JSON.parse(rawData) + parsedJson = true + } catch { + data = rawData + } + } + + if (parsedJson) { + if (responseValidator) { + await responseValidator(data) + } + + if (responseTransformer) { + data = await responseTransformer(data) + } + } + + onSseEvent?.({ + data, + event: eventName, + id: lastEventId, + retry: retryDelay, + }) + + if (dataLines.length) { + yield data as any + } + } + } + } finally { + signal.removeEventListener("abort", abortHandler) + reader.releaseLock() + } + + break // exit loop on normal completion + } catch (error) { + // connection failed or aborted; retry after delay + onSseError?.(error) + + if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) { + break // stop after firing error + } + + // exponential backoff: double retry each attempt, cap at 30s + const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000) + await sleep(backoff) + } + } + } + + const stream = createStream() + + return { stream } +} diff --git a/packages/sdk/js/src/gen/core/types.ts b/packages/sdk/js/src/gen/core/types.gen.ts similarity index 95% rename from packages/sdk/js/src/gen/core/types.ts rename to packages/sdk/js/src/gen/core/types.gen.ts index 3a12e74c6..16408b2d0 100644 --- a/packages/sdk/js/src/gen/core/types.ts +++ b/packages/sdk/js/src/gen/core/types.gen.ts @@ -1,5 +1,7 @@ -import type { Auth, AuthToken } from "./auth.js" -import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from "./bodySerializer.js" +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth, AuthToken } from "./auth.gen.js" +import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from "./bodySerializer.gen.js" export interface Client { /** diff --git a/packages/sdk/js/src/gen/core/utils.gen.ts b/packages/sdk/js/src/gen/core/utils.gen.ts new file mode 100644 index 000000000..be18c608a --- /dev/null +++ b/packages/sdk/js/src/gen/core/utils.gen.ts @@ -0,0 +1,109 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { QuerySerializer } from "./bodySerializer.gen.js" +import { + type ArraySeparatorStyle, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from "./pathSerializer.gen.js" + +export interface PathSerializer { + path: Record + url: string +} + +export const PATH_PARAM_RE = /\{[^{}]+\}/g + +export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { + let url = _url + const matches = _url.match(PATH_PARAM_RE) + if (matches) { + for (const match of matches) { + let explode = false + let name = match.substring(1, match.length - 1) + let style: ArraySeparatorStyle = "simple" + + if (name.endsWith("*")) { + explode = true + name = name.substring(0, name.length - 1) + } + + if (name.startsWith(".")) { + name = name.substring(1) + style = "label" + } else if (name.startsWith(";")) { + name = name.substring(1) + style = "matrix" + } + + const value = path[name] + + if (value === undefined || value === null) { + continue + } + + if (Array.isArray(value)) { + url = url.replace(match, serializeArrayParam({ explode, name, style, value })) + continue + } + + if (typeof value === "object") { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record, + valueOnly: true, + }), + ) + continue + } + + if (style === "matrix") { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string, + })}`, + ) + continue + } + + const replaceValue = encodeURIComponent(style === "label" ? `.${value as string}` : (value as string)) + url = url.replace(match, replaceValue) + } + } + return url +} + +export const getUrl = ({ + baseUrl, + path, + query, + querySerializer, + url: _url, +}: { + baseUrl?: string + path?: Record + query?: Record + querySerializer: QuerySerializer + url: string +}) => { + const pathUrl = _url.startsWith("/") ? _url : `/${_url}` + let url = (baseUrl ?? "") + pathUrl + if (path) { + url = defaultPathSerializer({ path, url }) + } + let search = query ? querySerializer(query) : "" + if (search.startsWith("?")) { + search = search.substring(1) + } + if (search) { + url += `?${search}` + } + return url +} diff --git a/packages/sdk/js/src/gen/sdk.gen.ts b/packages/sdk/js/src/gen/sdk.gen.ts index b00216b83..a50f5e142 100644 --- a/packages/sdk/js/src/gen/sdk.gen.ts +++ b/packages/sdk/js/src/gen/sdk.gen.ts @@ -59,6 +59,8 @@ import type { FindFilesResponses, FindSymbolsData, FindSymbolsResponses, + FileListData, + FileListResponses, FileReadData, FileReadResponses, FileStatusData, @@ -123,7 +125,7 @@ class Event extends _HeyApiClient { * Get events */ public subscribe(options?: Options) { - return (options?.client ?? this._client).get({ + return (options?.client ?? this._client).get.sse({ url: "/event", ...options, }) @@ -457,12 +459,22 @@ class Find extends _HeyApiClient { } class File extends _HeyApiClient { + /** + * List files and directories + */ + public list(options: Options) { + return (options.client ?? this._client).get({ + url: "/file", + ...options, + }) + } + /** * Read a file */ public read(options: Options) { return (options.client ?? this._client).get({ - url: "/file", + url: "/file/content", ...options, }) } diff --git a/packages/sdk/js/src/gen/types.gen.ts b/packages/sdk/js/src/gen/types.gen.ts index 7a9b0d656..31546ba51 100644 --- a/packages/sdk/js/src/gen/types.gen.ts +++ b/packages/sdk/js/src/gen/types.gen.ts @@ -554,6 +554,7 @@ export type App = { hostname: string git: boolean path: { + home: string config: string data: string root: string @@ -587,6 +588,9 @@ export type Config = { */ scroll_speed: number } + /** + * Command configuration, see https://opencode.ai/docs/commands + */ command?: { [key: string]: { template: string @@ -1137,6 +1141,13 @@ export type Symbol = { } } +export type FileNode = { + name: string + path: string + type: "file" | "directory" + ignored: boolean +} + export type File = { path: string added: number @@ -1803,7 +1814,7 @@ export type FindSymbolsResponses = { export type FindSymbolsResponse = FindSymbolsResponses[keyof FindSymbolsResponses] -export type FileReadData = { +export type FileListData = { body?: never path?: never query: { @@ -1812,6 +1823,24 @@ export type FileReadData = { url: "/file" } +export type FileListResponses = { + /** + * Files and directories + */ + 200: Array +} + +export type FileListResponse = FileListResponses[keyof FileListResponses] + +export type FileReadData = { + body?: never + path?: never + query: { + path: string + } + url: "/file/content" +} + export type FileReadResponses = { /** * File content diff --git a/packages/sdk/stainless/stainless.yml b/packages/sdk/stainless/stainless.yml index 3dd34a413..f829e2280 100644 --- a/packages/sdk/stainless/stainless.yml +++ b/packages/sdk/stainless/stainless.yml @@ -48,7 +48,6 @@ resources: app: models: app: App - logLevel: LogLevel provider: Provider model: Model agent: Agent @@ -61,7 +60,6 @@ resources: find: models: - match: Match symbol: Symbol methods: text: get /find @@ -71,8 +69,11 @@ resources: file: models: file: File + fileNode: FileNode + methods: - read: get /file + list: get /file + read: get /file/content status: get /file/status config: diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go index ecf95ff98..cbf12e504 100644 --- a/packages/tui/internal/app/app.go +++ b/packages/tui/internal/app/app.go @@ -820,11 +820,13 @@ func (a *App) SendCommand(ctx context.Context, command string, args string) (*Ap opencode.SessionCommandParams{ Command: opencode.F(command), Arguments: opencode.F(args), + Agent: opencode.F(a.Agents[a.AgentIndex].Name), + Model: opencode.F(a.State.Provider + "/" + a.State.Model), }, ) if err != nil { slog.Error("Failed to execute command", "error", err) - return toast.NewErrorToast("Failed to execute command") + return toast.NewErrorToast(fmt.Sprintf("Failed to execute command: %v", err))() } return nil }) @@ -856,7 +858,7 @@ func (a *App) SendShell(ctx context.Context, command string) (*App, tea.Cmd) { ) if err != nil { slog.Error("Failed to submit shell command", "error", err) - return toast.NewErrorToast("Failed to submit shell command")() + return toast.NewErrorToast(fmt.Sprintf("Failed to submit shell command: %v", err))() } return nil }) diff --git a/packages/tui/internal/commands/command.go b/packages/tui/internal/commands/command.go index 3a5287ca3..d552b78ec 100644 --- a/packages/tui/internal/commands/command.go +++ b/packages/tui/internal/commands/command.go @@ -92,6 +92,12 @@ func (r CommandRegistry) Sorted() []Command { if b.Name == AppExitCommand { return -1 } + if a.Custom && !b.Custom { + return 1 + } + if !a.Custom && b.Custom { + return -1 + } return strings.Compare(string(a.Name), string(b.Name)) }) diff --git a/packages/tui/internal/completions/commands.go b/packages/tui/internal/completions/commands.go index 2ffe3ea94..72e261f82 100644 --- a/packages/tui/internal/completions/commands.go +++ b/packages/tui/internal/completions/commands.go @@ -92,7 +92,41 @@ func (c *CommandCompletionProvider) GetChildEntries( } matches := fuzzy.RankFindFold(query, commandNames) - sort.Sort(matches) + + // Custom sort to prioritize exact matches + sort.Slice(matches, func(i, j int) bool { + // Check for exact match (case-insensitive) + iExact := strings.EqualFold(matches[i].Target, query) + jExact := strings.EqualFold(matches[j].Target, query) + + // Exact matches come first + if iExact && !jExact { + return true + } + if !iExact && jExact { + return false + } + + // Check for prefix match (case-insensitive) + iPrefix := strings.HasPrefix(strings.ToLower(matches[i].Target), strings.ToLower(query)) + jPrefix := strings.HasPrefix(strings.ToLower(matches[j].Target), strings.ToLower(query)) + + // Prefix matches come before fuzzy matches + if iPrefix && !jPrefix { + return true + } + if !iPrefix && jPrefix { + return false + } + + // Otherwise, sort by fuzzy match score (lower distance is better) + if matches[i].Distance != matches[j].Distance { + return matches[i].Distance < matches[j].Distance + } + + // If distances are equal, sort by original index (stable sort) + return matches[i].OriginalIndex < matches[j].OriginalIndex + }) // Convert matches to completion items, deduplicating by command name items := []CompletionSuggestion{} diff --git a/packages/tui/internal/components/chat/editor.go b/packages/tui/internal/components/chat/editor.go index 0c52ca84c..710049707 100644 --- a/packages/tui/internal/components/chat/editor.go +++ b/packages/tui/internal/components/chat/editor.go @@ -489,11 +489,22 @@ func (m *editorComponent) Submit() (tea.Model, tea.Cmd) { var cmds []tea.Cmd if strings.HasPrefix(value, "/") { - value = value[1:] - commandName := strings.Split(value, " ")[0] + // Expand attachments in the value to get actual content + expandedValue := value + attachments := m.textarea.GetAttachments() + for _, att := range attachments { + if att.Type == "text" && att.Source != nil { + if textSource, ok := att.Source.(*attachment.TextSource); ok { + expandedValue = strings.Replace(expandedValue, att.Display, textSource.Value, 1) + } + } + } + + expandedValue = expandedValue[1:] // Remove the "/" + commandName := strings.Split(expandedValue, " ")[0] command := m.app.Commands[commands.CommandName(commandName)] if command.Custom { - args := strings.TrimPrefix(value, command.PrimaryTrigger()+" ") + args := strings.TrimPrefix(expandedValue, command.PrimaryTrigger()+" ") cmds = append( cmds, util.CmdHandler(app.SendCommand{Command: string(command.Name), Args: args}), diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go index a299d65af..b3074bb54 100644 --- a/packages/tui/internal/components/chat/messages.go +++ b/packages/tui/internal/components/chat/messages.go @@ -1173,10 +1173,10 @@ func (m *messagesComponent) UndoLastMessage() (tea.Model, tea.Cmd) { ) if err != nil { slog.Error("Failed to undo message", "error", err) - return toast.NewErrorToast("Failed to undo message") + return toast.NewErrorToast("Failed to undo message")() } if response == nil { - return toast.NewErrorToast("Failed to undo message") + return toast.NewErrorToast("Failed to undo message")() } return app.MessageRevertedMsg{Session: *response, Message: revertedMessage} } @@ -1241,10 +1241,10 @@ func (m *messagesComponent) RedoLastMessage() (tea.Model, tea.Cmd) { ) if err != nil { slog.Error("Failed to unrevert session", "error", err) - return toast.NewErrorToast("Failed to redo message") + return toast.NewErrorToast("Failed to redo message")() } if response == nil { - return toast.NewErrorToast("Failed to redo message") + return toast.NewErrorToast("Failed to redo message")() } return app.SessionUnrevertedMsg{Session: *response} } @@ -1261,10 +1261,10 @@ func (m *messagesComponent) RedoLastMessage() (tea.Model, tea.Cmd) { ) if err != nil { slog.Error("Failed to redo message", "error", err) - return toast.NewErrorToast("Failed to redo message") + return toast.NewErrorToast("Failed to redo message")() } if response == nil { - return toast.NewErrorToast("Failed to redo message") + return toast.NewErrorToast("Failed to redo message")() } return app.MessageRevertedMsg{Session: *response, Message: revertedMessage} } diff --git a/packages/tui/internal/tui/tui.go b/packages/tui/internal/tui/tui.go index f7ce7982b..71e5b9f71 100644 --- a/packages/tui/internal/tui/tui.go +++ b/packages/tui/internal/tui/tui.go @@ -134,7 +134,7 @@ func (a Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { ) if err != nil { slog.Error("Failed to respond to permission request", "error", err) - return toast.NewErrorToast("Failed to respond to permission request") + return toast.NewErrorToast("Failed to respond to permission request")() } slog.Debug("Responded to permission request", "response", resp) return nil @@ -915,9 +915,10 @@ func (a Model) Cleanup() { func (a Model) home() (string, int, int) { t := theme.CurrentTheme() effectiveWidth := a.width - 4 - baseStyle := styles.NewStyle().Background(t.Background()) + baseStyle := styles.NewStyle().Foreground(t.Text()).Background(t.Background()) base := baseStyle.Render muted := styles.NewStyle().Foreground(t.TextMuted()).Background(t.Background()).Render + highlight := styles.NewStyle().Foreground(t.Accent()).Background(t.Background()).Render open := ` █▀▀█ █▀▀█ █▀▀ █▀▀▄ @@ -952,9 +953,9 @@ func (a Model) home() (string, int, int) { ) // Use limit of 4 for vscode, 6 for others - limit := 6 + limit := 4 if util.IsVSCode() { - limit = 4 + limit = 2 } showVscode := util.IsVSCode() @@ -971,15 +972,23 @@ func (a Model) home() (string, int, int) { styles.WhitespaceStyle(t.Background()), ) + grok := highlight("Grok Code is free for a limited time") + grok = lipgloss.PlaceHorizontal( + effectiveWidth, + lipgloss.Center, + grok, + styles.WhitespaceStyle(t.Background()), + ) + lines := []string{} lines = append(lines, "") - lines = append(lines, "") lines = append(lines, logoAndVersion) lines = append(lines, "") - lines = append(lines, "") lines = append(lines, cmds) lines = append(lines, "") lines = append(lines, "") + lines = append(lines, grok) + lines = append(lines, "") mainHeight := lipgloss.Height(strings.Join(lines, "\n")) diff --git a/packages/tui/internal/util/shimmer.go b/packages/tui/internal/util/shimmer.go index 88654ff07..b6ba0db64 100644 --- a/packages/tui/internal/util/shimmer.go +++ b/packages/tui/internal/util/shimmer.go @@ -11,7 +11,10 @@ import ( "github.com/sst/opencode/internal/styles" ) -var shimmerStart = time.Now() +var ( + shimmerStart = time.Now() + trueColorSupport = hasTrueColor() +) // Shimmer renders text with a moving foreground highlight. // bg is the background color, dim is the base text color, bright is the highlight color. @@ -32,7 +35,7 @@ func Shimmer(s string, bg compat.AdaptiveColor, _ compat.AdaptiveColor, _ compat elapsed := time.Since(shimmerStart).Seconds() pos := (math.Mod(elapsed, sweep) / sweep) * period - half := 4.0 + half := 2.0 type seg struct { useHex bool @@ -41,60 +44,52 @@ func Shimmer(s string, bg compat.AdaptiveColor, _ compat.AdaptiveColor, _ compat faint bool text string } - var segs []seg + segs := make([]seg, 0, n/4) - useHex := hasTrueColor() + useHex := trueColorSupport for i, r := range runes { ip := float64(i + pad) dist := math.Abs(ip - pos) - t := 0.0 - if dist <= half { - x := math.Pi * (dist / half) - t = 0.5 * (1.0 + math.Cos(x)) - } - // Cosine brightness: base + amp*t (quantized for grouping) - base := 0.55 - amp := 0.45 - brightness := base - if t > 0 { - brightness = base + amp*t - } - lvl := int(math.Round(brightness * 255.0)) - if !useHex { - step := 24 // ~11 steps across range for non-truecolor - lvl = int(math.Round(float64(lvl)/float64(step))) * step - } - bold := lvl >= 208 - faint := lvl <= 128 - - // truecolor if possible; else fallback to modifiers only + bold := false + faint := true hex := "" - if useHex { - if lvl < 0 { - lvl = 0 + + if dist <= half { + // Simple 3-level brightness based on distance + if dist <= half/3 { + // Center: brightest + bold = true + faint = false + if useHex { + hex = "#ffffff" + } + } else { + // Edge: medium bright + bold = false + faint = false + if useHex { + hex = "#cccccc" + } } - if lvl > 255 { - lvl = 255 - } - hex = rgbHex(lvl, lvl, lvl) } - if len(segs) == 0 { + if len(segs) == 0 || + segs[len(segs)-1].useHex != useHex || + segs[len(segs)-1].hex != hex || + segs[len(segs)-1].bold != bold || + segs[len(segs)-1].faint != faint { segs = append(segs, seg{useHex: useHex, hex: hex, bold: bold, faint: faint, text: string(r)}) } else { - last := &segs[len(segs)-1] - if last.useHex == useHex && last.hex == hex && last.bold == bold && last.faint == faint { - last.text += string(r) - } else { - segs = append(segs, seg{useHex: useHex, hex: hex, bold: bold, faint: faint, text: string(r)}) - } + segs[len(segs)-1].text += string(r) } } + baseStyle := styles.NewStyle().Background(bg) var b strings.Builder + b.Grow(len(s) * 2) for _, g := range segs { - st := styles.NewStyle().Background(bg) + st := baseStyle if g.useHex && g.hex != "" { c := compat.AdaptiveColor{Dark: lipgloss.Color(g.hex), Light: lipgloss.Color(g.hex)} st = st.Foreground(c) diff --git a/packages/web/package.json b/packages/web/package.json index 8b9cd1d2c..128b920cd 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,7 +1,7 @@ { "name": "@opencode/web", "type": "module", - "version": "0.5.18", + "version": "0.5.29", "scripts": { "dev": "astro dev", "dev:remote": "sst shell --stage=dev --target=Web astro dev", @@ -30,7 +30,7 @@ "remeda": "2.26.0", "sharp": "0.32.5", "shiki": "3.4.2", - "solid-js": "1.9.7", + "solid-js": "catalog:", "toolbeam-docs-theme": "0.4.6" }, "devDependencies": { diff --git a/packages/web/src/components/share/content-text.tsx b/packages/web/src/components/share/content-text.tsx index c52e0dfcc..5db12a537 100644 --- a/packages/web/src/components/share/content-text.tsx +++ b/packages/web/src/components/share/content-text.tsx @@ -1,6 +1,7 @@ import style from "./content-text.module.css" import { createSignal } from "solid-js" import { createOverflow } from "./common" +import { CopyButton } from "./copy-button" interface Props { text: string @@ -30,6 +31,7 @@ export function ContentText(props: Props) { {expanded() ? "Show less" : "Show more"} )} + ) } diff --git a/packages/web/src/components/share/copy-button.module.css b/packages/web/src/components/share/copy-button.module.css index 9da67a1ba..31013fc08 100644 --- a/packages/web/src/components/share/copy-button.module.css +++ b/packages/web/src/components/share/copy-button.module.css @@ -9,7 +9,6 @@ background: none; border: none; padding: 0.125rem; - background-color: var(--sl-color-bg); color: var(--sl-color-text-secondary); svg { diff --git a/packages/web/src/components/share/part.module.css b/packages/web/src/components/share/part.module.css index 85c3cc9b9..45310a0b2 100644 --- a/packages/web/src/components/share/part.module.css +++ b/packages/web/src/components/share/part.module.css @@ -126,6 +126,12 @@ gap: 1rem; flex-grow: 1; max-width: var(--md-tool-width); + position: relative; + + [data-component="copy-button"] { + top: 0.5rem; + right: calc(0.5rem - 1px); + } } [data-component="assistant-reasoning"] { diff --git a/packages/web/src/content/docs/docs/agents.mdx b/packages/web/src/content/docs/docs/agents.mdx index 51d835a6d..1527a1b08 100644 --- a/packages/web/src/content/docs/docs/agents.mdx +++ b/packages/web/src/content/docs/docs/agents.mdx @@ -58,12 +58,11 @@ Build is the **default** primary agent with all tools enabled. This is the stand _Mode_: `primary` -A restricted agent designed for planning and analysis. In the plan agent, the following tools are disabled by default: +A restricted agent designed for planning and analysis. We use a permission system to give you more control and prevent unintended changes. +By default, all of the following are set to `ask`: -- `write` - Cannot create new files -- `edit` - Cannot modify existing files -- `patch` - Cannot apply patches -- `bash` - Cannot execute shell commands +- `file edits`: All writes, patches, and edits +- `bash`: All bash commands This agent is useful when you want the LLM to analyze code, suggest changes, or create plans without making any actual modifications to your codebase. diff --git a/packages/web/src/content/docs/docs/commands.mdx b/packages/web/src/content/docs/docs/commands.mdx index 3869ea8a4..59c9536ac 100644 --- a/packages/web/src/content/docs/docs/commands.mdx +++ b/packages/web/src/content/docs/docs/commands.mdx @@ -3,7 +3,13 @@ title: Commands description: Create custom commands for repetitive tasks. --- -Define custom commands to automate repetitive coding tasks. +Custom commands let you specify a prompt you want to run when that command is executed in the TUI. + +```bash frame="none" +/my-command +``` + +Custom commands are in addition to the built-in commands like `/init`, `/undo`, `/redo`, `/share`, `/help`. [Learn more](/docs/tui#commands). --- @@ -34,12 +40,78 @@ Use the command by typing `/` followed by the command name. --- -## Use arguments +## Configure + +You can add custom commands through the opencode config or by creating markdown files in the `command/` directory. + +--- + +### JSON + +Use the `command` option in your opencode [config](/docs/config): + +```json title="opencode.jsonc" {4-12} +{ + "$schema": "https://opencode.ai/config.json", + "command": { + // This becomes the name of the command + "test": { + // This is the prompt that will be sent to the LLM + "template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes.", + // This is show as the description in the TUI + "description": "Run tests with coverage", + "agent": "build", + "model": "anthropic/claude-3-5-sonnet-20241022" + }, + } +} +``` + +Now you can run this command in the TUI: + +```bash frame="none" +/test +``` + +--- + +### Markdown + +You can also define commands using markdown files. Place them in: + +- Global: `~/.config/opencode/command/` +- Per-project: `.opencode/command/` + +```markdown title="~/.config/opencode/command/test.md" +--- +description: Run tests with coverage +agent: build +model: anthropic/claude-3-5-sonnet-20241022 +--- + +Run the full test suite with coverage report and show any failures. +Focus on the failing tests and suggest fixes. +``` + +The markdown file name becomes the command name. For example, `test.md` lets +you run: + +```bash frame="none" +/test +``` + +--- + +## Prompt config + +The prompts for the custom commands support several special placeholders and syntax. + +--- + +### Arguments Pass arguments to commands using the `$ARGUMENTS` placeholder. -Create `.opencode/command/component.md`: - ```md title=".opencode/command/component.md" --- description: Create a new component @@ -52,16 +124,18 @@ Include proper typing and basic structure. Run the command with arguments: ```bash frame="none" -"/component Button" +/component Button ``` +And `$ARGUMENTS` will be replaced with `Button`. + --- -## Inject shell output +### Shell output -Use `!command` to inject shell command output into your prompt. +Use _!`command`_ to inject [bash command](/docs/tui#bash-commands) output into your prompt. -Create `.opencode/command/analyze-coverage.md`: +For example, to create a custom command that analyzes test coverage: ```md title=".opencode/command/analyze-coverage.md" --- @@ -69,12 +143,12 @@ description: Analyze test coverage --- Here are the current test results: -`!npm test` +!`npm test` Based on these results, suggest improvements to increase coverage. ``` -Create `.opencode/command/review-changes.md`: +Or to review recent changes: ```md title=".opencode/command/review-changes.md" --- @@ -82,7 +156,7 @@ description: Review recent changes --- Recent git commits: -`!git log --oneline -10` +!`git log --oneline -10` Review these changes and suggest any improvements. ``` @@ -91,12 +165,10 @@ Commands run in your project's root directory and their output becomes part of t --- -## Reference files +### File references Include files in your command using `@` followed by the filename. -Create `.opencode/command/review-component.md`: - ```md title=".opencode/command/review-component.md" --- description: Review component @@ -110,47 +182,90 @@ The file content gets included in the prompt automatically. --- -## Command properties +## Options -Configure commands with these optional frontmatter properties: +Let's look at the configuration options in detail. -- **description**: Brief explanation of what the command does -- **agent**: Agent to use (defaults to "build") -- **model**: Specific model to use for this command - -Create `.opencode/command/code-review.md`: - -```md title=".opencode/command/code-review.md" ---- -description: Code review assistant -agent: build -model: anthropic/claude-3-5-sonnet-20241022 --- -Review the code for best practices and suggest improvements. +### Template + +The `template` option defines the prompt that will be sent to the LLM when the command is executed. + +```json title="opencode.json" +{ + "command": { + "test": { + "template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes." + } + } +} ``` ---- - -## Command directory - -Store command files in these locations: - -- `.opencode/command/` - Project-specific commands -- `command/` - Global commands in config directory - -Project commands take precedence over global ones. +This is a **required** config option. --- -## Built-in commands +### Description -opencode includes several built-in commands: +Use the `description` option to provide a brief description of what the command does. -- `/init` - Initialize project and create AGENTS.md -- `/undo` - Revert the last changes -- `/redo` - Restore reverted changes -- `/share` - Share the current conversation -- `/help` - Show available commands and keybinds +```json title="opencode.json" +{ + "command": { + "test": { + "description": "Run tests with coverage" + } + } +} +``` -Use `/help` to see all available commands in your setup. +This is shown as the description in the TUI when you type in the command. + +--- + +### Agent + +Use the `agent` config to optionally specify which [agent](/docs/agents) should execute this command. + +```json title="opencode.json" +{ + "command": { + "review": { + "agent": "plan" + } + } +} +``` + +This is an **optional** config option. If not specified, defaults to "build". + +--- + +### Model + +Use the `model` config to override the default model for this command. + +```json title="opencode.json" +{ + "command": { + "analyze": { + "model": "anthropic/claude-3-5-sonnet-20241022" + } + } +} +``` + +This is an **optional** config option. + +--- + +## Built-in + +opencode includes several built-in commands like `/init`, `/undo`, `/redo`, `/share`, `/help`; [learn more](/docs/tui#commands). + +:::note +Custom commands can override built-in commands. +::: + +If you define a custom command with the same name, it will override the built-in command. diff --git a/packages/web/src/content/docs/docs/config.mdx b/packages/web/src/content/docs/docs/config.mdx index 06eb6ee7d..045bc596c 100644 --- a/packages/web/src/content/docs/docs/config.mdx +++ b/packages/web/src/content/docs/docs/config.mdx @@ -152,6 +152,32 @@ By default, sharing is set to manual mode where you need to explicitly share con --- +### Commands + +You can configure custom commands for repetitive tasks through the `command` option. + +```jsonc title="opencode.jsonc" +{ + "$schema": "https://opencode.ai/config.json", + "command": { + "test": { + "template": "Run the full test suite with coverage report and show any failures.\nFocus on the failing tests and suggest fixes.", + "description": "Run tests with coverage", + "agent": "build", + "model": "anthropic/claude-3-5-sonnet-20241022" + }, + "component": { + "template": "Create a new React component named $ARGUMENTS with TypeScript support.\nInclude proper typing and basic structure.", + "description": "Create a new component" + } + } +} +``` + +You can also define commands using markdown files in `~/.config/opencode/command/` or `.opencode/command/`. [Learn more here](/docs/commands). + +--- + ### Keybinds You can customize your keybinds through the `keybinds` option. @@ -220,6 +246,11 @@ You can configure permissions to control what AI agents can do in your codebase } ``` +This allows you to configure explicit approval requirements for sensitive operations: + +- `edit` - Controls whether file editing operations require user approval (`"ask"` or `"allow"`) +- `bash` - Controls whether bash commands require user approval (can be `"ask"`/`"allow"` or a pattern map) + [Learn more about permissions here](/docs/permissions). --- @@ -259,13 +290,6 @@ about rules here](/docs/rules). You can disable providers that are loaded automatically through the `disabled_providers` option. This is useful when you want to prevent certain providers from being loaded even if their credentials are available. -The `disabled_providers` option accepts an array of provider IDs. When a provider is disabled: - -- It won't be loaded even if environment variables are set -- It won't be loaded even if API keys are configured through `opencode auth login` -- The provider's models won't appear in the model selection list - - ```json title="opencode.json" { "$schema": "https://opencode.ai/config.json", @@ -273,12 +297,11 @@ The `disabled_providers` option accepts an array of provider IDs. When a provide } ``` -The permissions system allows you to configure explicit approval requirements for sensitive operations: +The `disabled_providers` option accepts an array of provider IDs. When a provider is disabled: -- `edit` - Controls whether file editing operations require user approval (`"ask"` or `"allow"`) -- `bash` - Controls whether bash commands require user approval (can be `"ask"`/`"allow"` or a pattern map) - -[Learn more about permissions here](/docs/permissions). +- It won't be loaded even if environment variables are set. +- It won't be loaded even if API keys are configured through `opencode auth login`. +- The provider's models won't appear in the model selection list. --- diff --git a/packages/web/src/content/docs/docs/enterprise.mdx b/packages/web/src/content/docs/docs/enterprise.mdx index d73d1d3a4..ad6b47f92 100644 --- a/packages/web/src/content/docs/docs/enterprise.mdx +++ b/packages/web/src/content/docs/docs/enterprise.mdx @@ -9,7 +9,7 @@ you to use opencode at your organization. To get started, we recommend: 1. Do a trial internally with your team. -2. [**Contact us**](mailto:hello@sst.dev) to discuss pricing and implementation options. +2. [**Contact us**](mailto:hello@anoma.ly) to discuss pricing and implementation options. --- @@ -55,7 +55,7 @@ We recommend you disable this for your trial. ## Deployment Once you have completed your trial and you are ready to self-host opencode at -your organization, you can [**contact us**](mailto:hello@sst.dev) to discuss +your organization, you can [**contact us**](mailto:hello@anoma.ly) to discuss pricing and implementation options. --- diff --git a/packages/web/src/content/docs/docs/lsp.mdx b/packages/web/src/content/docs/docs/lsp.mdx index d674cc70d..6a661521c 100644 --- a/packages/web/src/content/docs/docs/lsp.mdx +++ b/packages/web/src/content/docs/docs/lsp.mdx @@ -11,19 +11,26 @@ opencode integrates with your Language Server Protocol (LSP) to help the LLM int opencode comes with several built-in LSP servers for popular languages: -| LSP Server | Extensions | Requirements | -| ---------- | -------------------------------------------- | ----------------------------------- | -| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project | -| eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `eslint` dependency in project | -| gopls | .go | `go` command available | -| ruby-lsp | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available | -| pyright | .py, .pyi | `pyright` dependency installed | -| elixir-ls | .ex, .exs | `elixir` command available | -| zls | .zig, .zon | `zig` command available | -| csharp | .cs | `.NET SDK` installed | +| LSP Server | Extensions | Requirements | +| ---------- | ---------------------------------------------------- | ----------------------------------- | +| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project | +| eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts, .vue | `eslint` dependency in project | +| gopls | .go | `go` command available | +| ruby-lsp | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available | +| pyright | .py, .pyi | `pyright` dependency installed | +| elixir-ls | .ex, .exs | `elixir` command available | +| zls | .zig, .zon | `zig` command available | +| csharp | .cs | `.NET SDK` installed | +| vue | .vue | Auto-installs for Vue projects | +| rust | .rs | `rust-analyzer` command available | +| clangd | .c, .cpp, .cc, .cxx, .c++, .h, .hpp, .hh, .hxx, .h++ | Auto-installs for C/C++ projects | LSP servers are automatically enabled when one of the above file extensions are detected and the requirements are met. +:::note +You can disable automatic LSP server downloads by setting the `OPENCODE_DISABLE_LSP_DOWNLOAD` environment variable to `true`. +::: + --- ## How It Works diff --git a/packages/web/src/content/docs/docs/mcp-servers.mdx b/packages/web/src/content/docs/docs/mcp-servers.mdx index 861efc6cd..0ceeb47a3 100644 --- a/packages/web/src/content/docs/docs/mcp-servers.mdx +++ b/packages/web/src/content/docs/docs/mcp-servers.mdx @@ -91,3 +91,38 @@ Local and remote servers can be used together within the same `mcp` config objec } } } +``` + +--- + +## Per agent + +If you have a large number of MCP servers you may want to only enable them per +agent and disable them globally. To do this: + +1. Configure the MCP server. +2. Disable it as a tool globally. +3. In your [agent config](/docs/agents#tools) enable the MCP server as a tool. + +```json title="opencode.json" {11, 14-17} +{ + "$schema": "https://opencode.ai/config.json", + "mcp": { + "my-mcp": { + "type": "local", + "command": ["bun", "x", "my-mcp-command"], + "enabled": true + } + }, + "tools": { + "my-mcp*": false + }, + "agent": { + "my-agent": { + "tools": { + "my-mcp*": true + } + } + } +} +``` diff --git a/packages/web/src/content/docs/docs/models.mdx b/packages/web/src/content/docs/docs/models.mdx index e06ab0eab..efebc5cb4 100644 --- a/packages/web/src/content/docs/docs/models.mdx +++ b/packages/web/src/content/docs/docs/models.mdx @@ -68,7 +68,7 @@ If you've configured a [custom provider](/docs/providers#custom), the `provider_ You can globally configure a model's options through the config. -```jsonc title="opencode.jsonc" {7-11} +```jsonc title="opencode.jsonc" {7-12,19-24} { "$schema": "https://opencode.ai/config.json", "provider": { @@ -79,16 +79,28 @@ You can globally configure a model's options through the config. "reasoningEffort": "high", "textVerbosity": "low", "reasoningSummary": "auto", - "include": ["reasoning.encrypted_content"] - } - } - } - } - } + "include": ["reasoning.encrypted_content"], + }, + }, + }, + }, + "anthropic": { + "models": { + "claude-sonnet-4-20250514": { + "options": { + "thinking": { + "type": "enabled", + "budgetTokens": 16000, + }, + }, + }, + }, + }, + }, } ``` -Here we are setting global options for the `gpt-5` model when used through the `openai` provider. +Here we're configuring global settings for two models: `gpt-5` when accessed via the `openai` provider, and `claude-sonnet-4-20250514` when accessed via the `anthropic` provider. You can also configure these options for any agents that you are using. The agent config overrides any global options here. [Learn more](/docs/agents/#additional). diff --git a/packages/web/src/content/docs/docs/providers.mdx b/packages/web/src/content/docs/docs/providers.mdx index 9d7b808c8..de1cf8b39 100644 --- a/packages/web/src/content/docs/docs/providers.mdx +++ b/packages/web/src/content/docs/docs/providers.mdx @@ -759,6 +759,23 @@ In this example: --- +### xAI + +For a limited time, you can use xAI's Grok Code for free with opencode. + +:::tip +Grok Code is available for free for a limited time on opencode. +::: + +1. Make sure you are on the latest version of opencode. + +2. Run the `/models` command and select **Grok Code Free**. + +As a part of the trial period, the xAI team will be using the request logs to +monitor and improve Grok Code. + +--- + ### Z.AI 1. Head over to the [Z.AI API console](https://z.ai/manage-apikey/apikey-list), create an account, and click **Create a new API key**. diff --git a/packages/web/src/content/docs/docs/sdk.mdx b/packages/web/src/content/docs/docs/sdk.mdx index 6002d135a..3b4353d82 100644 --- a/packages/web/src/content/docs/docs/sdk.mdx +++ b/packages/web/src/content/docs/docs/sdk.mdx @@ -50,7 +50,7 @@ const client = createOpencodeClient({ You can also programmatically start an opencode server: -````javascript +```javascript import { createOpencodeServer } from "@opencode-ai/sdk" const server = await createOpencodeServer({ @@ -61,7 +61,7 @@ const server = await createOpencodeServer({ console.log(`Server running at ${server.url}`) server.close() -} +``` #### Options @@ -307,8 +307,8 @@ await client.auth.set({ ```javascript // Listen to real-time events -const eventStream = await client.event.subscribe() -for await (const event of eventStream) { +const events = await client.event.subscribe() +for await (const event of events.stream) { console.log("Event:", event.type, event.properties) } ``` diff --git a/packages/web/src/content/docs/docs/tui.mdx b/packages/web/src/content/docs/docs/tui.mdx index e6ad10162..113bad697 100644 --- a/packages/web/src/content/docs/docs/tui.mdx +++ b/packages/web/src/content/docs/docs/tui.mdx @@ -25,6 +25,12 @@ Once you're in the TUI, you can prompt it with a message. Give me a quick summary of the codebase. ``` +--- + +## File references + +You can reference files in your messages using `@`. This does a fuzzy file search in the current working directory. + :::tip You can also use `@` to reference files in your messages. ::: @@ -33,6 +39,20 @@ You can also use `@` to reference files in your messages. How is auth handled in @packages/functions/src/api/index.ts? ``` +The content of the file is added to the conversation automatically. + +--- + +## Bash commands + +Start a message with `!` to run a shell command. + +```bash frame="none" +!ls -la +``` + +The output of the command is added to the conversation as a tool result. + --- ## Commands @@ -235,18 +255,6 @@ Unshare current session. [Learn more](/docs/share#un-sharing). --- -## Bash commands - -Start a message with `!` to run a shell command. - -```bash frame="none" -!ls -la -``` - -The output of the command is added to the conversation as a tool result. - ---- - ## Editor setup Both the `/editor` and `/export` commands use the editor specified in your `EDITOR` environment variable. @@ -254,37 +262,54 @@ Both the `/editor` and `/export` commands use the editor specified in your `EDIT ```bash - export EDITOR=nano # or vim, code, etc. + # Example for nano or vim + export EDITOR=nano + export EDITOR=vim + + # For GUI editors (VS Code, Cursor, VSCodium, Windsurf, Zed, etc.) include --wait + export EDITOR="code --wait" ``` To make it permanent, add this to your shell profile; `~/.bashrc`, `~/.zshrc`, etc. - + ```bash - set EDITOR=notepad # or code, vim, etc. + set EDITOR=notepad + + # For GUI editors (VS Code, Cursor, VSCodium, Windsurf, Zed, etc.) include --wait + set EDITOR=code --wait ``` To make it permanent, use **System Properties** > **Environment Variables**. - + - ```bash - $env:EDITOR = "notepad" # or "code", "vim", etc. + ```powershell + $env:EDITOR = "notepad" + + # For GUI editors (VS Code, Cursor, VSCodium, Windsurf, Zed, etc.) include --wait + $env:EDITOR = "code --wait" ``` - To make it permanent, add this to your PowerShell - profile. - + To make it permanent, add this to your PowerShell profile. Popular editor options include: - `code` - Visual Studio Code +- `cursor` - Cursor +- `windsurf` - Windsurf - `vim` - Vim editor - `nano` - Nano editor - `notepad` - Windows Notepad - `subl` - Sublime Text + +:::note +Some editors like VS Code need to be started with the `--wait` flag. +::: + +Some editors need command-line arguments to run in blocking mode. The `--wait` flag makes the editor process block until closed. diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index e69839c88..636f3f4d0 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "0.5.18", + "version": "0.5.29", "publisher": "sst-dev", "repository": { "type": "git", diff --git a/sst-env.d.ts b/sst-env.d.ts index 358891fdf..8725b4568 100644 --- a/sst-env.d.ts +++ b/sst-env.d.ts @@ -25,8 +25,13 @@ declare module "sst" { "type": "sst.cloudflare.Kv" } "Bucket": { + "name": string "type": "sst.cloudflare.Bucket" } + "Console": { + "type": "sst.cloudflare.SolidStart" + "url": string + } "DATABASE_PASSWORD": { "type": "sst.sst.Secret" "value": string