diff --git a/.cursor/CLOUD.md b/.cursor/CLOUD.md index 00ff83e892..f49d351926 100644 --- a/.cursor/CLOUD.md +++ b/.cursor/CLOUD.md @@ -23,7 +23,7 @@ A full-stack web application starter built on Cloudflare Workers with Remix 3 ## Architecture -- **Server**: Cloudflare Workers (see `worker/` and `server/`) +- **Server**: Cloudflare Workers (see `packages/worker/src/` and `server/`) - **Client**: Remix 3 components bundled with esbuild (see `client/`) - **Database**: Cloudflare D1 (SQLite, auto-handled locally by Wrangler) - **MCP Server**: Available at `/mcp` endpoint when worker runs diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 588d1ca531..a4afb8062a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -77,11 +77,12 @@ jobs: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} run: | set -euo pipefail - bun tools/ci/production-resources.ts ensure --out-config wrangler-production.generated.json | tee -a "$GITHUB_OUTPUT" + bun tools/ci/production-resources.ts ensure --out-config packages/worker/wrangler-production.generated.json | tee -a "$GITHUB_OUTPUT" - name: 🔐 Sync Cloudflare Secrets (bulk) env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + WRANGLER_CONFIG: ${{ steps.resources.outputs.wrangler_config }} COOKIE_SECRET: ${{ secrets.COOKIE_SECRET }} APP_BASE_URL: ${{ vars.APP_BASE_URL }} AI_GATEWAY_ID: ${{ secrets.AI_GATEWAY_ID }} @@ -93,13 +94,13 @@ jobs: CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} CAPABILITY_REINDEX_SECRET: ${{ secrets.CAPABILITY_REINDEX_SECRET }} run: > - bun tools/ci/sync-worker-secrets.ts --env production --set-from-env - COOKIE_SECRET --set-from-env AI_GATEWAY_ID --set-from-env-optional - APP_BASE_URL --set-from-env-optional RESEND_API_KEY - --set-from-env-optional RESEND_FROM_EMAIL --set-from-env-optional - SENTRY_DSN --set-from-env-optional GITHUB_TOKEN - --set-from-env-optional CURSOR_API_KEY --set-from-env-optional - CAPABILITY_REINDEX_SECRET + bun tools/ci/sync-worker-secrets.ts --env production --config + "$WRANGLER_CONFIG" --set-from-env COOKIE_SECRET --set-from-env + AI_GATEWAY_ID --set-from-env-optional APP_BASE_URL + --set-from-env-optional RESEND_API_KEY --set-from-env-optional + RESEND_FROM_EMAIL --set-from-env-optional SENTRY_DSN + --set-from-env-optional GITHUB_TOKEN --set-from-env-optional + CURSOR_API_KEY --set-from-env-optional CAPABILITY_REINDEX_SECRET - name: 🗄️ Apply D1 Migrations env: diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index e9b3c4f428..d5a35f5176 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -133,7 +133,7 @@ jobs: APP_WORKER_NAME: ${{ steps.names.outputs.worker_name }} run: | set -euo pipefail - bun tools/ci/preview-resources.ts ensure --worker-name "$APP_WORKER_NAME" --out-config wrangler-preview.generated.json | tee -a "$GITHUB_OUTPUT" + bun tools/ci/preview-resources.ts ensure --worker-name "$APP_WORKER_NAME" --out-config packages/worker/wrangler-preview.generated.json | tee -a "$GITHUB_OUTPUT" - name: 🗄️ Apply D1 Migrations (preview) env: @@ -159,7 +159,7 @@ jobs: mock_summary="" mock_comment_summary="" - for dir in mock-servers/*; do + for dir in packages/mock-servers/*; do if [ ! -d "$dir" ]; then continue fi @@ -219,6 +219,7 @@ jobs: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} APP_WORKER_NAME: ${{ steps.names.outputs.worker_name }} OVERRIDES_FILE: ${{ steps.deploy_mocks.outputs.overrides_file }} + WRANGLER_CONFIG: ${{ steps.resources.outputs.wrangler_config }} AI_GATEWAY_ID: ${{ secrets.AI_GATEWAY_ID_PREVIEW }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} run: | @@ -233,7 +234,7 @@ jobs: exit 1 fi - bun tools/ci/sync-worker-secrets.ts --env "" --name "$APP_WORKER_NAME" --from-dotenv "$ENV_FILE" --from-dotenv "$OVERRIDES_FILE" --set-from-env AI_GATEWAY_ID --set-from-env-optional SENTRY_DSN --generate-cookie-secret --include-empty + bun tools/ci/sync-worker-secrets.ts --env "" --name "$APP_WORKER_NAME" --config "$WRANGLER_CONFIG" --from-dotenv "$ENV_FILE" --from-dotenv "$OVERRIDES_FILE" --set-from-env AI_GATEWAY_ID --set-from-env-optional SENTRY_DSN --generate-cookie-secret --include-empty - name: ☁️ Deploy preview app Worker id: deploy_preview @@ -525,7 +526,7 @@ jobs: delete_worker "$APP_WORKER_NAME" - for dir in mock-servers/*; do + for dir in packages/mock-servers/*; do if [ ! -d "$dir" ]; then continue fi diff --git a/.gitignore b/.gitignore index d59cdbe619..da8c27c96f 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ package-lock.json *.sln *.sw? .wrangler +.nx .tmp .env mock-data @@ -31,3 +32,5 @@ playwright-report test-results public/client-entry.js public/mcp-apps/ +packages/worker/wrangler-preview.generated.json +packages/worker/wrangler-production.generated.json diff --git a/README.md b/README.md index 185b0e5385..0499178716 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ flows. This project is intentionally single-user right now and is being built for `me@kentcdodds.com`. +The repo is organized as an Nx monorepo, with shared modules in +`packages/shared` (`@kody-internal/shared`), the main app worker under +`packages/worker`, and mock Workers under `packages/mock-servers/*`. + ## Quick Start ```bash @@ -50,6 +54,7 @@ If you are trying to understand what this repository is for, start with | Runtime | [Cloudflare Workers](https://workers.cloudflare.com/) | | UI Framework | [Remix 3](https://remix.run/) (alpha) | | Package Manager | [Bun](https://bun.sh/) | +| Workspace | [Nx](https://nx.dev/) + Bun workspaces | | Database | [Cloudflare D1](https://developers.cloudflare.com/d1/) | | Session/OAuth | [Cloudflare KV](https://developers.cloudflare.com/kv/) | | MCP State | [Durable Objects](https://developers.cloudflare.com/durable-objects/) | @@ -67,7 +72,7 @@ If you are trying to understand what this repository is for, start with ## How It Works ``` -Request → worker/index.ts +Request → packages/worker/src/index.ts │ ├─→ OAuth handlers ├─→ MCP endpoints @@ -75,7 +80,7 @@ Request → worker/index.ts └─→ Server router → Remix components ``` -- `worker/index.ts` is the entrypoint for Cloudflare Workers +- `packages/worker/src/index.ts` is the entrypoint for Cloudflare Workers - OAuth requests are handled first, then MCP requests, then static assets - Non-asset requests fall through to the server handler and router - Client assets are bundled into `public/` and served via the `ASSETS` binding diff --git a/bun.lock b/bun.lock index 6b8dbbcda5..f0b6d8cfe0 100644 --- a/bun.lock +++ b/bun.lock @@ -9,6 +9,7 @@ "@cloudflare/codemode": "^0.2.1", "@cloudflare/workers-oauth-provider": "^0.3.0", "@epic-web/invariant": "^1.0.0", + "@kody-internal/shared": "workspace:*", "@mcp-ui/server": "6.1.0", "@modelcontextprotocol/ext-apps": "^1.2.2", "@modelcontextprotocol/sdk": "1.26.0", @@ -28,6 +29,7 @@ "@types/set-cookie-parser": "^2.4.10", "concurrently": "^9.2.1", "esbuild": "^0.27.4", + "nx": "^22.6.1", "oxlint": "^1.55.0", "prettier": "^3.8.1", "set-cookie-parser": "^3.0.1", @@ -35,6 +37,38 @@ "wrangler": "^4.72.0", }, }, + "packages/mock-servers/ai": { + "name": "@kody/mock-ai", + "dependencies": { + "@kody-internal/shared": "workspace:*", + "@kody/worker": "workspace:*", + }, + }, + "packages/mock-servers/cursor": { + "name": "@kody/mock-cursor", + }, + "packages/mock-servers/github": { + "name": "@kody/mock-github", + }, + "packages/mock-servers/resend": { + "name": "@kody/mock-resend", + "dependencies": { + "@kody-internal/shared": "workspace:*", + "@kody/worker": "workspace:*", + }, + }, + "packages/shared": { + "name": "@kody-internal/shared", + "dependencies": { + "remix": "3.0.0-alpha.3", + }, + }, + "packages/worker": { + "name": "@kody/worker", + "dependencies": { + "@kody-internal/shared": "workspace:*", + }, + }, }, "overrides": { "@modelcontextprotocol/sdk": "1.26.0", @@ -224,6 +258,12 @@ "@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.1", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ=="], + "@jest/diff-sequences": ["@jest/diff-sequences@30.3.0", "", {}, "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA=="], + + "@jest/get-type": ["@jest/get-type@30.1.0", "", {}, "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA=="], + + "@jest/schemas": ["@jest/schemas@30.0.5", "", { "dependencies": { "@sinclair/typebox": "^0.34.0" } }, "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA=="], + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], @@ -232,13 +272,47 @@ "@jsdevtools/ono": ["@jsdevtools/ono@7.1.3", "", {}, "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="], + "@kody-internal/shared": ["@kody-internal/shared@workspace:packages/shared"], + + "@kody/mock-ai": ["@kody/mock-ai@workspace:packages/mock-servers/ai"], + + "@kody/mock-cursor": ["@kody/mock-cursor@workspace:packages/mock-servers/cursor"], + + "@kody/mock-github": ["@kody/mock-github@workspace:packages/mock-servers/github"], + + "@kody/mock-resend": ["@kody/mock-resend@workspace:packages/mock-servers/resend"], + + "@kody/worker": ["@kody/worker@workspace:packages/worker"], + + "@ltd/j-toml": ["@ltd/j-toml@1.38.0", "", {}, "sha512-lYtBcmvHustHQtg4X7TXUu1Xa/tbLC3p2wLvgQI+fWVySguVZJF60Snxijw5EiohumxZbR10kWYFFebh1zotiw=="], + "@mcp-ui/server": ["@mcp-ui/server@6.1.0", "", { "dependencies": { "@modelcontextprotocol/ext-apps": "^0.3.1", "@modelcontextprotocol/sdk": "^1.25.1" } }, "sha512-uxv9JrzEzHfdGo/V/KTFKp5WeCOsaiAoQZ3V88jw1dSXUofONEw4rMwEvVP3612aj/unS2TIeM0o1I0asfIxtw=="], "@modelcontextprotocol/ext-apps": ["@modelcontextprotocol/ext-apps@1.2.2", "", { "peerDependencies": { "@modelcontextprotocol/sdk": "^1.24.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0", "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["react", "react-dom"] }, "sha512-qMnhIKb8tyPesl+kZU76Xz9Bi9putCO+LcgvBJ00fDdIniiLZsnQbAeTKoq+sTiYH1rba2Fvj8NPAFxij+gyxw=="], "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.26.0", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg=="], - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.4", "", { "dependencies": { "@emnapi/core": "^1.1.0", "@emnapi/runtime": "^1.1.0", "@tybys/wasm-util": "^0.9.0" } }, "sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ=="], + + "@nx/nx-darwin-arm64": ["@nx/nx-darwin-arm64@22.6.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-lixkEBGFdEsUiqEZg9LIyjfiTv12Sg1Es/yUgrdOQUAZu+5oiUPMoybyBwrvINl+fZw+PLh66jOmB4GSP2aUMQ=="], + + "@nx/nx-darwin-x64": ["@nx/nx-darwin-x64@22.6.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-HvgtOtuWnEf0dpfWb05N0ptdFg040YgzsKFhXg6+qaBJg5Hg0e0AXPKaSgh2PCqCIDlKu40YtwVgF7KXxXAGlA=="], + + "@nx/nx-freebsd-x64": ["@nx/nx-freebsd-x64@22.6.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-g2wUltGX+7/+mdTV5d6ODa0ylrNu/krgb9YdrsbhW6oZeXYm2LeLOAnYqIlL/Kx140NLrb5Kcz7bi7JrBAw4Ow=="], + + "@nx/nx-linux-arm-gnueabihf": ["@nx/nx-linux-arm-gnueabihf@22.6.1", "", { "os": "linux", "cpu": "arm" }, "sha512-TTqisFPAPrj35EihvzotBbajS+0bX++PQggmRVmDmGwSTrpySRJwZnKNHYDqP6s9tigDvkNJOJftK+GkBEFRRA=="], + + "@nx/nx-linux-arm64-gnu": ["@nx/nx-linux-arm64-gnu@22.6.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-uIkPcanSTIcyh7/6LOoX0YpGO/7GkVhMRgyM9Mg/7ItFjCtRaeuPEPrJESsaNeB5zIVVhI4cXbGrM9NDnagiiw=="], + + "@nx/nx-linux-arm64-musl": ["@nx/nx-linux-arm64-musl@22.6.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-eqkG8s/7remiRZ1Lo2zIrFLSNsQ/0x9fAj++CV1nqFE+rfykPQhC48F8pqsq6tUQpI5HqRQEfQgv4CnFNpLR+w=="], + + "@nx/nx-linux-x64-gnu": ["@nx/nx-linux-x64-gnu@22.6.1", "", { "os": "linux", "cpu": "x64" }, "sha512-6DhSupCcDa6BYzQ48qsMK4LIdIO+y4E+4xuUBkX2YTGOZh58gctELCv7Gi6/FhiC8rzVzM7hDcygOvHCGc30zA=="], + + "@nx/nx-linux-x64-musl": ["@nx/nx-linux-x64-musl@22.6.1", "", { "os": "linux", "cpu": "x64" }, "sha512-QqtfaBhdfLRKGucpP8RSv7KJ51XRWpfUcXPhkb/1dKP/b9/Z0kpaCgczGHdrAtX9m6haWw+sQXYGxnStZIg/TQ=="], + + "@nx/nx-win32-arm64-msvc": ["@nx/nx-win32-arm64-msvc@22.6.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-8pTWXphY5IIgY3edZ5SfzP8yPjBqoAxRV5snAYDctF4e0OC1nDOUims70jLesMle8DTSWiHPSfbLVfp2HkU9WQ=="], + + "@nx/nx-win32-x64-msvc": ["@nx/nx-win32-x64-msvc@22.6.1", "", { "os": "win32", "cpu": "x64" }, "sha512-XMYrtsR5O39uNR4fVpFs65rVB09FyLXvUM735r2rO7IUWWHxHWTAgVcc+gqQaAchBPqR9f1q+3u2i1Inub3Cdw=="], "@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="], @@ -412,6 +486,8 @@ "@sentry/core": ["@sentry/core@10.45.0", "", {}, "sha512-s69UXxvefeQxuZ5nY7/THtTrIEvJxNVCp3ns4kwoCw1qMpgpvn/296WCKVmM7MiwnaAdzEKnAvLAwaxZc2nM7Q=="], + "@sinclair/typebox": ["@sinclair/typebox@0.34.48", "", {}, "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA=="], + "@sindresorhus/is": ["@sindresorhus/is@7.2.0", "", {}, "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw=="], "@speed-highlight/core": ["@speed-highlight/core@1.2.14", "", {}, "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA=="], @@ -420,7 +496,7 @@ "@total-typescript/ts-reset": ["@total-typescript/ts-reset@0.6.1", "", {}, "sha512-cka47fVSo6lfQDIATYqb/vO1nvFfbPw7uWLayIXIhGETj0wcOOlrlkobOMDNQOFr9QOafegUPq13V2+6vtD7yg=="], - "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="], "@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="], @@ -496,6 +572,12 @@ "@vitest/eslint-plugin": ["@vitest/eslint-plugin@1.6.6", "", { "dependencies": { "@typescript-eslint/scope-manager": "^8.51.0", "@typescript-eslint/utils": "^8.51.0" }, "peerDependencies": { "eslint": ">=8.57.0", "typescript": ">=5.0.0", "vitest": "*" }, "optionalPeers": ["typescript", "vitest"] }, "sha512-bwgQxQWRtnTVzsUHK824tBmHzjV0iTx3tZaiQIYDjX3SA7TsQS8CuDVqxXrRY3FaOUMgbGavesCxI9MOfFLm7Q=="], + "@yarnpkg/lockfile": ["@yarnpkg/lockfile@1.1.0", "", {}, "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ=="], + + "@yarnpkg/parsers": ["@yarnpkg/parsers@3.0.2", "", { "dependencies": { "js-yaml": "^3.10.0", "tslib": "^2.4.0" } }, "sha512-/HcYgtUSiJiot/XWGLOlGxPYUG65+/31V8oqk17vZLW1xlCoR4PampyePljOxY2n8/3jz9+tIFzICsyGujJZoA=="], + + "@zkochan/js-yaml": ["@zkochan/js-yaml@0.0.7", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ=="], + "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], @@ -510,6 +592,8 @@ "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], + "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], + "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], @@ -530,19 +614,31 @@ "arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="], + "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], + "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="], + "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], + "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], "aws4fetch": ["aws4fetch@1.0.20", "", {}, "sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g=="], - "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + "axios": ["axios@1.13.6", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ=="], + + "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + + "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], "blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="], "body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="], - "brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], + "brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="], + + "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], "bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="], @@ -558,12 +654,20 @@ "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "cli-cursor": ["cli-cursor@3.1.0", "", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="], + + "cli-spinners": ["cli-spinners@2.6.1", "", {}, "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g=="], + "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + "clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], + "comment-parser": ["comment-parser@1.4.5", "", {}, "sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw=="], "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], @@ -596,10 +700,16 @@ "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], + "defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="], + "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], + "define-lazy-prop": ["define-lazy-prop@2.0.0", "", {}, "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og=="], + "define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="], + "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], + "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], @@ -608,14 +718,24 @@ "doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="], + "dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="], + + "dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="], + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], + "ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], + "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], + + "enquirer": ["enquirer@2.3.6", "", { "dependencies": { "ansi-colors": "^4.1.1" } }, "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg=="], + "error-stack-parser-es": ["error-stack-parser-es@1.0.5", "", {}, "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA=="], "es-abstract": ["es-abstract@1.24.1", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw=="], @@ -640,7 +760,7 @@ "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], - "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + "escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], "eslint": ["eslint@9.39.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.2", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw=="], @@ -664,6 +784,8 @@ "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + "esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="], "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], @@ -694,22 +816,36 @@ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "figures": ["figures@3.2.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg=="], + "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], + "filelist": ["filelist@1.0.6", "", { "dependencies": { "minimatch": "^5.0.1" } }, "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA=="], + "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], + "flat": ["flat@5.0.2", "", { "bin": { "flat": "cli.js" } }, "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="], + "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], + "follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="], + "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="], + "form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], + "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], + "front-matter": ["front-matter@4.0.2", "", { "dependencies": { "js-yaml": "^3.13.1" } }, "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg=="], + + "fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="], + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], @@ -762,7 +898,9 @@ "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], - "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], + "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], + + "ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], @@ -792,6 +930,8 @@ "is-date-object": ["is-date-object@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg=="], + "is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], "is-finalizationregistry": ["is-finalizationregistry@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg=="], @@ -802,6 +942,8 @@ "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + "is-interactive": ["is-interactive@1.0.0", "", {}, "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w=="], + "is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="], "is-negative-zero": ["is-negative-zero@2.0.3", "", {}, "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw=="], @@ -822,25 +964,33 @@ "is-typed-array": ["is-typed-array@1.1.15", "", { "dependencies": { "which-typed-array": "^1.1.16" } }, "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ=="], + "is-unicode-supported": ["is-unicode-supported@0.1.0", "", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="], + "is-weakmap": ["is-weakmap@2.0.2", "", {}, "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w=="], "is-weakref": ["is-weakref@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew=="], "is-weakset": ["is-weakset@2.0.4", "", { "dependencies": { "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ=="], + "is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], + "isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "iterator.prototype": ["iterator.prototype@1.1.5", "", { "dependencies": { "define-data-property": "^1.1.4", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "get-proto": "^1.0.0", "has-symbols": "^1.1.0", "set-function-name": "^2.0.2" } }, "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g=="], + "jake": ["jake@10.9.4", "", { "dependencies": { "async": "^3.2.6", "filelist": "^1.0.4", "picocolors": "^1.1.1" }, "bin": { "jake": "bin/cli.js" } }, "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA=="], + + "jest-diff": ["jest-diff@30.3.0", "", { "dependencies": { "@jest/diff-sequences": "30.3.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", "pretty-format": "30.3.0" } }, "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ=="], + "jose": ["jose@6.1.3", "", {}, "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ=="], "js-base64": ["js-base64@3.7.8", "", {}, "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], - "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], @@ -854,6 +1004,10 @@ "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], + "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + + "jsonc-parser": ["jsonc-parser@3.2.0", "", {}, "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w=="], + "jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="], "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], @@ -862,12 +1016,16 @@ "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], + "lines-and-columns": ["lines-and-columns@2.0.3", "", {}, "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w=="], + "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], "lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="], "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], + "log-symbols": ["log-symbols@4.1.0", "", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="], + "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], @@ -882,9 +1040,11 @@ "mimetext": ["mimetext@3.0.28", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@babel/runtime-corejs3": "^7.26.0", "js-base64": "^3.7.7", "mime-types": "^2.1.35" } }, "sha512-eQXpbNrtxLCjUtiVbR/qR09dbPgZ2o+KR1uA7QKqGhbn8QV7HIL16mXXsobBL4/8TqoYh1us31kfz+dNfCev9g=="], + "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + "miniflare": ["miniflare@4.20260310.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.18.2", "workerd": "1.20260310.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-uC5vNPenFpDSj5aUU3wGSABG6UUqMr+Xs1m4AkCrTHo37F4Z6xcQw5BXqViTfPDVT/zcYH1UgTVoXhr1l6ZMXw=="], - "minimatch": ["minimatch@10.1.2", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.1" } }, "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw=="], + "minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], @@ -898,6 +1058,10 @@ "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + "npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="], + + "nx": ["nx@22.6.1", "", { "dependencies": { "@ltd/j-toml": "^1.38.0", "@napi-rs/wasm-runtime": "0.2.4", "@yarnpkg/lockfile": "^1.1.0", "@yarnpkg/parsers": "3.0.2", "@zkochan/js-yaml": "0.0.7", "axios": "^1.12.0", "cli-cursor": "3.1.0", "cli-spinners": "2.6.1", "cliui": "^8.0.1", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", "ejs": "^3.1.7", "enquirer": "~2.3.6", "figures": "3.2.0", "flat": "^5.0.2", "front-matter": "^4.0.2", "ignore": "^7.0.5", "jest-diff": "^30.0.2", "jsonc-parser": "3.2.0", "lines-and-columns": "2.0.3", "minimatch": "10.2.4", "npm-run-path": "^4.0.1", "open": "^8.4.0", "ora": "5.3.0", "picocolors": "^1.1.0", "resolve.exports": "2.0.3", "semver": "^7.6.3", "string-width": "^4.2.3", "tar-stream": "~2.2.0", "tmp": "~0.2.1", "tree-kill": "^1.2.2", "tsconfig-paths": "^4.1.2", "tslib": "^2.3.0", "yaml": "^2.6.0", "yargs": "^17.6.2", "yargs-parser": "21.1.1" }, "optionalDependencies": { "@nx/nx-darwin-arm64": "22.6.1", "@nx/nx-darwin-x64": "22.6.1", "@nx/nx-freebsd-x64": "22.6.1", "@nx/nx-linux-arm-gnueabihf": "22.6.1", "@nx/nx-linux-arm64-gnu": "22.6.1", "@nx/nx-linux-arm64-musl": "22.6.1", "@nx/nx-linux-x64-gnu": "22.6.1", "@nx/nx-linux-x64-musl": "22.6.1", "@nx/nx-win32-arm64-msvc": "22.6.1", "@nx/nx-win32-x64-msvc": "22.6.1" }, "peerDependencies": { "@swc-node/register": "^1.11.1", "@swc/core": "^1.15.8" }, "optionalPeers": ["@swc-node/register", "@swc/core"], "bin": { "nx": "bin/nx.js", "nx-cloud": "bin/nx-cloud.js" } }, "sha512-b4eo52o5aCVt3oG6LPYvD2Cul3JFBMgr2p9OjMBIo6oU6QfSR693H2/UuUMepLtO6jcIniPKOcIrf6Ue8aXAww=="], + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], @@ -916,8 +1080,14 @@ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + + "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=="], + "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], + "ora": ["ora@5.3.0", "", { "dependencies": { "bl": "^4.0.3", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", "cli-spinners": "^2.5.0", "is-interactive": "^1.0.0", "log-symbols": "^4.0.0", "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" } }, "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g=="], + "own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="], "oxlint": ["oxlint@1.55.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.55.0", "@oxlint/binding-android-arm64": "1.55.0", "@oxlint/binding-darwin-arm64": "1.55.0", "@oxlint/binding-darwin-x64": "1.55.0", "@oxlint/binding-freebsd-x64": "1.55.0", "@oxlint/binding-linux-arm-gnueabihf": "1.55.0", "@oxlint/binding-linux-arm-musleabihf": "1.55.0", "@oxlint/binding-linux-arm64-gnu": "1.55.0", "@oxlint/binding-linux-arm64-musl": "1.55.0", "@oxlint/binding-linux-ppc64-gnu": "1.55.0", "@oxlint/binding-linux-riscv64-gnu": "1.55.0", "@oxlint/binding-linux-riscv64-musl": "1.55.0", "@oxlint/binding-linux-s390x-gnu": "1.55.0", "@oxlint/binding-linux-x64-gnu": "1.55.0", "@oxlint/binding-linux-x64-musl": "1.55.0", "@oxlint/binding-openharmony-arm64": "1.55.0", "@oxlint/binding-win32-arm64-msvc": "1.55.0", "@oxlint/binding-win32-ia32-msvc": "1.55.0", "@oxlint/binding-win32-x64-msvc": "1.55.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.15.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-T+FjepiyWpaZMhekqRpH8Z3I4vNM610p6w+Vjfqgj5TZUxHXl7N8N5IPvmOU8U4XdTRxqtNNTh9Y4hLtr7yvFg=="], @@ -944,6 +1114,8 @@ "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="], @@ -960,6 +1132,8 @@ "prettier-plugin-tailwindcss": ["prettier-plugin-tailwindcss@0.6.14", "", { "peerDependencies": { "@ianvs/prettier-plugin-sort-imports": "*", "@prettier/plugin-hermes": "*", "@prettier/plugin-oxc": "*", "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", "@zackad/prettier-plugin-twig": "*", "prettier": "^3.0", "prettier-plugin-astro": "*", "prettier-plugin-css-order": "*", "prettier-plugin-import-sort": "*", "prettier-plugin-jsdoc": "*", "prettier-plugin-marko": "*", "prettier-plugin-multiline-arrays": "*", "prettier-plugin-organize-attributes": "*", "prettier-plugin-organize-imports": "*", "prettier-plugin-sort-imports": "*", "prettier-plugin-style-order": "*", "prettier-plugin-svelte": "*" }, "optionalPeers": ["@ianvs/prettier-plugin-sort-imports", "@prettier/plugin-hermes", "@prettier/plugin-oxc", "@prettier/plugin-pug", "@shopify/prettier-plugin-liquid", "@trivago/prettier-plugin-sort-imports", "@zackad/prettier-plugin-twig", "prettier-plugin-astro", "prettier-plugin-css-order", "prettier-plugin-import-sort", "prettier-plugin-jsdoc", "prettier-plugin-marko", "prettier-plugin-multiline-arrays", "prettier-plugin-organize-attributes", "prettier-plugin-organize-imports", "prettier-plugin-sort-imports", "prettier-plugin-style-order", "prettier-plugin-svelte"] }, "sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg=="], + "pretty-format": ["pretty-format@30.3.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ=="], + "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], @@ -980,6 +1154,8 @@ "react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], + "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=="], + "reflect.getprototypeof": ["reflect.getprototypeof@1.0.10", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.9", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.7", "get-proto": "^1.0.1", "which-builtin-type": "^1.2.1" } }, "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw=="], "regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="], @@ -998,12 +1174,18 @@ "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], + "resolve.exports": ["resolve.exports@2.0.3", "", {}, "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A=="], + + "restore-cursor": ["restore-cursor@3.1.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA=="], + "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], "rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="], "safe-array-concat": ["safe-array-concat@1.1.3", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "get-intrinsic": "^1.2.6", "has-symbols": "^1.1.0", "isarray": "^2.0.5" } }, "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q=="], + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + "safe-push-apply": ["safe-push-apply@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "isarray": "^2.0.5" } }, "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA=="], "safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="], @@ -1042,6 +1224,10 @@ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + + "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], + "stable-hash-x": ["stable-hash-x@0.2.0", "", {}, "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ=="], "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], @@ -1060,8 +1246,12 @@ "string.prototype.trimstart": ["string.prototype.trimstart@1.0.8", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" } }, "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg=="], + "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], + "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], + "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], "supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], @@ -1070,16 +1260,22 @@ "swr": ["swr@2.4.1", "", { "dependencies": { "dequal": "^2.0.3", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-2CC6CiKQtEwaEeNiqWTAw9PGykW8SR5zZX8MZk6TeAvEAnVS7Visz8WzphqgtQ8v2xz/4Q5K+j+SeMaKXeeQIA=="], + "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=="], + "throttleit": ["throttleit@2.1.0", "", {}, "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw=="], "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], + "tmp": ["tmp@0.2.5", "", {}, "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow=="], + "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="], "ts-api-utils": ["ts-api-utils@2.4.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA=="], + "tsconfig-paths": ["tsconfig-paths@4.2.0", "", { "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg=="], + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], @@ -1114,8 +1310,12 @@ "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], + "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], "which-boxed-primitive": ["which-boxed-primitive@1.1.1", "", { "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", "is-number-object": "^1.1.1", "is-string": "^1.1.1", "is-symbol": "^1.1.1" } }, "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA=="], @@ -1142,6 +1342,8 @@ "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + "yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="], + "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], @@ -1160,6 +1362,8 @@ "@ai-sdk/react/ai": ["ai@6.0.116", "", { "dependencies": { "@ai-sdk/gateway": "3.0.66", "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.19", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-7yM+cTmyRLeNIXwt4Vj+mrrJgVQ9RMIW5WO0ydoLoYkewIvsMcvUmqS4j2RJTUXaF1HphwmSKUMQ/HypNRGOmA=="], + "@apidevtools/json-schema-ref-parser/js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@eslint/config-array/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], @@ -1168,16 +1372,20 @@ "@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], + "@eslint/eslintrc/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], + + "@eslint/eslintrc/js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "@eslint/eslintrc/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], "@mcp-ui/server/@modelcontextprotocol/ext-apps": ["@modelcontextprotocol/ext-apps@0.3.1", "", { "optionalDependencies": { "@oven/bun-darwin-aarch64": "^1.2.21", "@oven/bun-darwin-x64": "^1.2.21", "@oven/bun-darwin-x64-baseline": "^1.2.21", "@oven/bun-linux-aarch64": "^1.2.21", "@oven/bun-linux-aarch64-musl": "^1.2.21", "@oven/bun-linux-x64": "^1.2.21", "@oven/bun-linux-x64-baseline": "^1.2.21", "@oven/bun-linux-x64-musl": "^1.2.21", "@oven/bun-linux-x64-musl-baseline": "^1.2.21", "@oven/bun-windows-x64": "^1.2.21", "@oven/bun-windows-x64-baseline": "^1.2.21", "@rollup/rollup-darwin-arm64": "^4.53.3", "@rollup/rollup-darwin-x64": "^4.53.3", "@rollup/rollup-linux-arm64-gnu": "^4.53.3", "@rollup/rollup-linux-x64-gnu": "^4.53.3", "@rollup/rollup-win32-arm64-msvc": "^4.53.3", "@rollup/rollup-win32-x64-msvc": "^4.53.3" }, "peerDependencies": { "@modelcontextprotocol/sdk": "^1.24.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0", "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["react", "react-dom"] }, "sha512-Iivz2KwWK8xlRbiWwFB/C4NXqE8VJBoRCbBkJCN98ST2UbQvA6kfyebcLsypiqylJS467XOOaBcI9DeQ3t+zqA=="], "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], - "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + "@unrs/resolver-binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="], + "agents/yargs": ["yargs@18.0.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg=="], "ai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.14", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-7bzKd9lgiDeXM7O4U4nQ8iTxguAOkg8LZGD9AfDVZYjO5cKYRwBPwVjboFcVrxncRHu0tYxZtXZtiLKpG4pEng=="], @@ -1186,20 +1394,38 @@ "eslint/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], + "eslint/escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + + "eslint/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], + "eslint/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], + "eslint-plugin-import-x/minimatch": ["minimatch@10.1.2", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.1" } }, "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw=="], + "eslint-plugin-react/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], "eslint-plugin-react/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "espree/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + "filelist/minimatch": ["minimatch@5.1.9", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw=="], + + "form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + + "js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + + "json-schema-to-typescript/js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "mimetext/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], "miniflare/undici": ["undici@7.18.2", "", {}, "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw=="], "playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], + "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], + + "pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], + "router/path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="], "wrangler/esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], @@ -1208,18 +1434,32 @@ "@ai-sdk/react/ai/@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.66", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.19", "@vercel/oidc": "3.1.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-SIQ0YY0iMuv+07HLsZ+bB990zUJ6S4ujORAh+Jv1V2KGNn73qQKnGO0JBk+w+Res8YqOFSycwDoWcFlQrVxS4A=="], + "@eslint/config-array/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], + "@eslint/eslintrc/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + "@eslint/eslintrc/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + "@unrs/resolver-binding-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + "agents/yargs/cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="], "agents/yargs/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], "agents/yargs/yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], + "eslint-plugin-react/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], + "eslint/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + "eslint/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], + + "filelist/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + "mimetext/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], "wrangler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], @@ -1274,6 +1514,12 @@ "wrangler/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="], + "@eslint/config-array/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "@eslint/eslintrc/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + "agents/yargs/cliui/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], "agents/yargs/cliui/wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], @@ -1282,6 +1528,12 @@ "agents/yargs/string-width/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], + "eslint-plugin-react/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "eslint/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "filelist/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + "agents/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], "agents/yargs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], diff --git a/cli.ts b/cli.ts index 455e2b9fef..6468789c44 100644 --- a/cli.ts +++ b/cli.ts @@ -4,7 +4,7 @@ import { platform } from 'node:os' import readline from 'node:readline' import { setTimeout as delay } from 'node:timers/promises' import getPort, { clearLockedPorts } from 'get-port' -import { getRemoteAiLocalDevStartupError } from '#shared/ai-env-validation.ts' +import { getRemoteAiLocalDevStartupError } from '@kody-internal/shared/ai-env-validation.ts' const defaultWorkerPort = 3742 const defaultMockPort = 8788 diff --git a/client/chat-client.ts b/client/chat-client.ts index 3516b47cb9..24decf267c 100644 --- a/client/chat-client.ts +++ b/client/chat-client.ts @@ -6,7 +6,7 @@ import { import { type UIMessage } from 'ai' import { AgentClient } from 'agents/client' import { createInfiniteList } from '#client/infinite-list.ts' -import { chatAgentBasePath } from '#shared/chat-routes.ts' +import { chatAgentBasePath } from '@kody-internal/shared/chat-routes.ts' export type ChatClientSnapshot = { messages: Array diff --git a/client/routes/chat.tsx b/client/routes/chat.tsx index 36e3cd6d60..a162f97d73 100644 --- a/client/routes/chat.tsx +++ b/client/routes/chat.tsx @@ -30,7 +30,7 @@ import { type ChatThreadListResponse, type ChatThreadSummary, type ChatThreadUpdateResponse, -} from '#shared/chat.ts' +} from '@kody-internal/shared/chat.ts' type ThreadStatus = 'idle' | 'loading' | 'ready' | 'error' diff --git a/docs/agents/adding-capabilities.md b/docs/agents/adding-capabilities.md index b022235aea..e2732ef0d2 100644 --- a/docs/agents/adding-capabilities.md +++ b/docs/agents/adding-capabilities.md @@ -22,15 +22,18 @@ A **domain** is the single source of truth for: Authoring flow: 1. **`defineDomainCapability(domain, definition)`** — wrap each capability (from - `mcp/capabilities/define-domain-capability.ts`). Pass the domain id from - `capabilityDomainNames` in `mcp/capabilities/domain-metadata.ts`. Do **not** - put `domain` on the inner object; the helper supplies it. + `packages/worker/src/mcp/capabilities/define-domain-capability.ts`). Pass the + domain id from `capabilityDomainNames` in + `packages/worker/src/mcp/capabilities/domain-metadata.ts`. Do **not** put + `domain` on the inner object; the helper supplies it. 2. **`defineDomain({ name, description, keywords?, capabilities })`** — from - `mcp/capabilities/define-domain.ts`. Validates that every capability’s - `domain` matches `name` and that names are unique within the domain. -3. **`builtinDomains`** — in `mcp/capabilities/builtin-domains.ts`, list all - domains you want in the default server. Order controls the flattening order - of `capabilityList` (capabilities from earlier domains come first). + `packages/worker/src/mcp/capabilities/define-domain.ts`. Validates that every + capability’s `domain` matches `name` and that names are unique within the + domain. +3. **`builtinDomains`** — in + `packages/worker/src/mcp/capabilities/builtin-domains.ts`, list all domains + you want in the default server. Order controls the flattening order of + `capabilityList` (capabilities from earlier domains come first). 4. **`registry.ts`** — calls `buildCapabilityRegistry(builtinDomains)` and re-exports `capabilityList`, `capabilityMap`, `capabilitySpecs`, handlers, tool descriptors, and domain metadata for search/MCP instructions. @@ -39,14 +42,16 @@ To merge extra domains later (e.g. plugins), the seam is: `buildCapabilityRegistry([...builtinDomains, ...extraDomains])` with real `Capability` handlers (typical Workers model: snapshot at deploy). -`defineCapability()` in `mcp/capabilities/define-capability.ts` is still what +`defineCapability()` in +`packages/worker/src/mcp/capabilities/define-capability.ts` is still what normalizes Zod → JSON Schema and wraps handlers with logging; domain helpers call it for you. ## Capability shape -Each capability file lives under `mcp/capabilities//` and exports a -normalized capability from **`defineDomainCapability(...)`**. +Each capability file lives under +`packages/worker/src/mcp/capabilities//` and exports a normalized +capability from **`defineDomainCapability(...)`**. Required (inside the `definition` object): @@ -87,7 +92,7 @@ Organize capabilities by domain. Each domain folder should include a and one or more capability modules. ```text -mcp/capabilities/ +packages/worker/src/mcp/capabilities/ builtin-domains.ts build-capability-registry.ts define-capability.ts @@ -112,8 +117,8 @@ domain when you introduce a new system boundary or ownership area (e.g. 1. Add a new key to `capabilityDomainNames` in `domain-metadata.ts` (this extends the `CapabilityDomain` union). -2. Add `mcp/capabilities//domain.ts`, capability files, and `index.ts` if - you want a barrel. +2. Add `packages/worker/src/mcp/capabilities//domain.ts`, capability + files, and `index.ts` if you want a barrel. 3. Append the new domain to the `builtinDomains` array in `builtin-domains.ts`. You do not edit `registry.ts` for routine additions—only `builtin-domains` and @@ -129,7 +134,8 @@ the domain modules. `capabilities: [..., yourCapability]`. 5. If the domain uses `index.ts`, ensure it still exports `domain` / `codingCapabilities`-style aliases as needed for local imports. -6. Add or update tests in `mcp/mcp-server-e2e.test.ts` for MCP-visible behavior. +6. Add or update tests in `packages/worker/src/mcp/mcp-server-e2e.test.ts` for + MCP-visible behavior. Example (assuming `example` exists in `capabilityDomainNames`): @@ -204,11 +210,12 @@ Public MCP behavior should be verified through the compact tool surface: ranked results - use `execute` to confirm the capability runs correctly -Prefer E2E tests in `mcp/mcp-server-e2e.test.ts` for the real MCP contract. +Prefer E2E tests in `packages/worker/src/mcp/mcp-server-e2e.test.ts` for the +real MCP contract. Registry invariants (duplicate capability names, domain/capability mismatches, duplicate domain registration) are covered in -`mcp/capabilities/build-capability-registry.test.ts`. +`packages/worker/src/mcp/capabilities/build-capability-registry.test.ts`. ## Naming diff --git a/docs/agents/cloudflare-agents-sdk.md b/docs/agents/cloudflare-agents-sdk.md index e3a9f71425..eb7776a741 100644 --- a/docs/agents/cloudflare-agents-sdk.md +++ b/docs/agents/cloudflare-agents-sdk.md @@ -13,11 +13,11 @@ Installed in this repo as `agents` in `package.json` (currently `^0.7.4`). ## Quick pointers for this repo -- MCP server uses `McpAgent` in `mcp/index.ts` and is served via - `MCP.serve(...)` in `worker/index.ts`. +- MCP server uses `McpAgent` in `packages/worker/src/mcp/index.ts` and is served + via `MCP.serve(...)` in `packages/worker/src/index.ts`. - Capabilities exposed through the compact `search` / `execute` tools are - registered per-domain (`mcp/capabilities/*/domain.ts`) and merged in - `mcp/capabilities/builtin-domains.ts`; see + registered per-domain (`packages/worker/src/mcp/capabilities/*/domain.ts`) and + merged in `packages/worker/src/mcp/capabilities/builtin-domains.ts`; see [adding capabilities](./adding-capabilities.md). - This project is not organized around the React hook APIs from the SDK; for non-React clients, use `AgentClient` from `agents/client`. diff --git a/docs/agents/end-to-end-testing.md b/docs/agents/end-to-end-testing.md index 3f8bb1757a..e938ceaf75 100644 --- a/docs/agents/end-to-end-testing.md +++ b/docs/agents/end-to-end-testing.md @@ -42,15 +42,16 @@ Avoid `page.locator('css')` unless no accessible alternative exists. `PLAYWRIGHT_PORT`. - Playwright sets `CLOUDFLARE_ENV=test`; Wrangler still loads `.env` values for local secrets. -- Ensure the `env.test` section in `wrangler.jsonc` includes assets, KV, and - durable objects since these are not inherited from top-level Wrangler config. +- Ensure the `env.test` section in `packages/worker/wrangler.jsonc` includes + assets, KV, and durable objects since these are not inherited from top-level + Wrangler config. - Ensure `.env` includes a `COOKIE_SECRET` var for local sessions. - Client routes live in `client/app.tsx` and `client/routes/index.tsx`. - API endpoints are defined in `server/routes.ts` and mapped in `server/router.ts`. When adding endpoints that accept bodies, ensure POST/PUT requests are not -handled by the static asset fetcher in `worker/index.ts`. +handled by the static asset fetcher in `packages/worker/src/index.ts`. ## Test data diff --git a/docs/agents/mcp-apps-starter-guide.md b/docs/agents/mcp-apps-starter-guide.md index d845dde8c3..c6e623d483 100644 --- a/docs/agents/mcp-apps-starter-guide.md +++ b/docs/agents/mcp-apps-starter-guide.md @@ -18,24 +18,24 @@ UI and workflows. Use this file map as the default structure: -- `mcp/index.ts` +- `packages/worker/src/mcp/index.ts` - MCP server + `init()` registration entrypoint. -- `mcp/register-tools.ts` +- `packages/worker/src/mcp/register-tools.ts` - Aggregates tool registration. -- `mcp/register-resources.ts` +- `packages/worker/src/mcp/register-resources.ts` - Aggregates resource registration. -- `mcp/tools/*.ts` +- `packages/worker/src/mcp/tools/*.ts` - One tool per file. -- `mcp/resources/*.ts` +- `packages/worker/src/mcp/resources/*.ts` - One resource registration module per file. -- `mcp/apps/*.ts` +- `packages/worker/src/mcp/apps/*.ts` - UI entry-point modules that return HTML/JS payloads for `ui://` resources. ## Recommended implementation workflow ### 1) Create an app entry point -Create a dedicated module under `mcp/apps/`: +Create a dedicated module under `packages/worker/src/mcp/apps/`: - Export a stable `ui://` URI. - Export a render function that returns the app HTML. @@ -45,7 +45,7 @@ Keep file names lower-kebab-case and prefer one entry point per app. ### 2) Register the app resource -In `mcp/resources/.ts`: +In `packages/worker/src/mcp/resources/.ts`: - Use `registerAppResource(...)` from `@modelcontextprotocol/ext-apps/server`. - Return `text/html;profile=mcp-app`. @@ -59,7 +59,7 @@ In `mcp/resources/.ts`: ### 3) Register the app-opening tool -In `mcp/tools/.ts`: +In `packages/worker/src/mcp/tools/.ts`: - Use `registerAppTool(...)` from `@modelcontextprotocol/ext-apps/server`. - Set `_meta.ui.resourceUri` to the **same** `ui://` URI as the resource. @@ -68,9 +68,9 @@ In `mcp/tools/.ts`: ### 4) Wire registration in server init -- Add resource registration to `mcp/register-resources.ts`. -- Add tool registration to `mcp/register-tools.ts`. -- Ensure `mcp/index.ts` calls both in `init()`. +- Add resource registration to `packages/worker/src/mcp/register-resources.ts`. +- Add tool registration to `packages/worker/src/mcp/register-tools.ts`. +- Ensure `packages/worker/src/mcp/index.ts` calls both in `init()`. ### 5) Add or update MCP E2E coverage @@ -153,7 +153,8 @@ token values into widget CSS. If you do this in an MCP App resource, set When removing starter examples (for example calculator + math tool): -1. Delete example modules under `mcp/apps`, `mcp/tools`, and `mcp/resources`. +1. Delete example modules under `packages/worker/src/mcp/apps`, + `packages/worker/src/mcp/tools`, and `packages/worker/src/mcp/resources`. 2. Replace entries in registration modules. 3. Update MCP E2E tests to your new tool/resource names and behavior. 4. Update this guide (or adjacent docs) if your project-specific conventions @@ -174,4 +175,4 @@ Repo-specific implementation references: - MCP server patterns: `docs/mcp-server-patterns.md` - Cloudflare Agents SDK notes: `docs/agents/cloudflare-agents-sdk.md` -- Worker MCP entrypoint wiring: `worker/index.ts` +- Worker MCP entrypoint wiring: `packages/worker/src/index.ts` diff --git a/docs/agents/mock-api-servers.md b/docs/agents/mock-api-servers.md index d01cbc8e4f..b805abf28e 100644 --- a/docs/agents/mock-api-servers.md +++ b/docs/agents/mock-api-servers.md @@ -1,25 +1,26 @@ ## Mock API servers Mock servers emulate third-party APIs during local development and PR previews. -Each mock lives in `mock-servers//` as a dedicated Cloudflare Worker so -it can also be deployed alongside the main app. +Each mock lives in `packages/mock-servers//` as a dedicated Cloudflare +Worker package so it can also be deployed alongside the main app. ### Add a new third-party mock -1. Create a new directory under `mock-servers/`, for example - `mock-servers/acme/`. -2. Add a Worker entrypoint (for example `mock-servers/acme/worker.ts`) that - mirrors the third-party API (for example, `POST /resource`). -3. Add `mock-servers/acme/wrangler.jsonc` with the Worker config and any - bindings (D1/KV/etc). +1. Create a new directory under `packages/mock-servers/`, for example + `packages/mock-servers/acme/`. +2. Add a Worker entrypoint (for example + `packages/mock-servers/acme/src/worker.ts`) that mirrors the third-party API + (for example, `POST /resource`). +3. Add `packages/mock-servers/acme/wrangler.jsonc` with the Worker config and + any bindings (D1/KV/etc). 4. In `cli.ts`, start the mock Worker during `bun run dev` (via `wrangler dev`) and set `ACME_API_BASE_URL` to the mock Worker origin. -See `mock-servers/github/` for the GitHub REST + GraphQL subset mock used by the -`github_rest` and `github_graphql` capabilities (started by `bun run dev` unless -`SKIP_GITHUB_MOCK=1`). +See `packages/mock-servers/github/` for the GitHub REST + GraphQL subset mock +package used by the `github_rest` and `github_graphql` capabilities (started by +`bun run dev` unless `SKIP_GITHUB_MOCK=1`). -See `mock-servers/cursor/` for a small +See `packages/mock-servers/cursor/` for a small [Cursor Cloud Agents API](https://cursor.com/docs/cloud-agent/api/endpoints) subset mock used by the `cursor_cloud_rest` capability (started by `bun run dev` unless `SKIP_CURSOR_MOCK=1`). @@ -36,5 +37,6 @@ unless `SKIP_CURSOR_MOCK=1`). all mock Workers for request authentication. The preview workflow includes an authenticated dashboard link in the PR comment (href includes `?token=...`) so you can open `//__mocks` without manually copying secrets. -- Set `"preview_urls": true` in each mock Worker `wrangler.jsonc` so Cloudflare - emits version preview URLs in CI summaries when available. +- Set `"preview_urls": true` in each + `packages/mock-servers//wrangler.jsonc` so Cloudflare emits version + preview URLs in CI summaries when available. diff --git a/docs/agents/remix/data-table-sqlite.md b/docs/agents/remix/data-table-sqlite.md index 493cb219f3..e3b06c34d7 100644 --- a/docs/agents/remix/data-table-sqlite.md +++ b/docs/agents/remix/data-table-sqlite.md @@ -26,8 +26,9 @@ let db = createDatabase(createSqliteDatabaseAdapter(sqlite)) ## Cloudflare D1 note `remix/data-table-sqlite` expects a `better-sqlite3` connection object. For D1, -use a D1-specific adapter (for this repo, `worker/d1-data-table-adapter.ts`) -instead of `createSqliteDatabaseAdapter(...)`. +use a D1-specific adapter (for this repo, +`packages/worker/src/d1-data-table-adapter.ts`) instead of +`createSqliteDatabaseAdapter(...)`. ## Default capabilities diff --git a/docs/agents/remix/data-table.md b/docs/agents/remix/data-table.md index c5db347f23..696f204d4f 100644 --- a/docs/agents/remix/data-table.md +++ b/docs/agents/remix/data-table.md @@ -52,7 +52,8 @@ let allUsers = await db.query(users).select().all() This repository uses `remix/data-table` for D1-backed app and mock-server data access, but D1 is not a `better-sqlite3` connection. We use a custom adapter at -`worker/d1-data-table-adapter.ts` and build the runtime in `worker/db.ts`: +`packages/worker/src/d1-data-table-adapter.ts` and build the runtime in +`packages/worker/src/db.ts`: ```ts import { createDatabase } from 'remix/data-table' @@ -61,7 +62,7 @@ import { createD1DataTableAdapter } from '#worker/d1-data-table-adapter.ts' let db = createDatabase(createD1DataTableAdapter(env.APP_DB)) ``` -Table metadata and shared table definitions live in `worker/db.ts`. +Table metadata and shared table definitions live in `packages/worker/src/db.ts`. ## Adapter packages diff --git a/docs/agents/remix/index.md b/docs/agents/remix/index.md index c6a8cfce1b..3567941402 100644 --- a/docs/agents/remix/index.md +++ b/docs/agents/remix/index.md @@ -44,7 +44,8 @@ Docs for every package in https://github.com/remix-run/remix/tree/main/packages. - `remix/data-schema` - `remix/data-table` - D1 integration uses `remix/data-table` with a repository adapter - (`worker/d1-data-table-adapter.ts`) instead of `remix/data-table-sqlite`. + (`packages/worker/src/d1-data-table-adapter.ts`) instead of + `remix/data-table-sqlite`. - Package coverage audit against installed `remix@3.0.0-alpha.3` top-level exports: no missing Remix package docs in this index. diff --git a/docs/agents/setup.md b/docs/agents/setup.md index 0bd9a07dfc..efbc631fa7 100644 --- a/docs/agents/setup.md +++ b/docs/agents/setup.md @@ -10,6 +10,8 @@ Quick notes for getting a local kody environment running. ## Install - `bun install` +- The repo root hosts the Nx workspace metadata; runtime packages live under + `packages/`. ## Local development @@ -100,11 +102,11 @@ For preview environments, we do a full resource reset: 1. Delete preview resources: - `bun tools/ci/preview-resources.ts cleanup --worker-name ` 2. Recreate preview resources and config: - - `bun tools/ci/preview-resources.ts ensure --worker-name --out-config wrangler-preview.generated.json` + - `bun tools/ci/preview-resources.ts ensure --worker-name --out-config packages/worker/wrangler-preview.generated.json` 3. Re-apply remote migrations: - - `CLOUDFLARE_ENV=preview bun ./wrangler-env.ts d1 migrations apply APP_DB --remote --config wrangler-preview.generated.json` + - `CLOUDFLARE_ENV=preview bun ./wrangler-env.ts d1 migrations apply APP_DB --remote --config packages/worker/wrangler-preview.generated.json` 4. Seed test account: - - `CLOUDFLARE_ENV=preview bun tools/seed-test-data.ts --remote --config wrangler-preview.generated.json` + - `CLOUDFLARE_ENV=preview bun tools/seed-test-data.ts --remote --config packages/worker/wrangler-preview.generated.json` ## PR preview deployments diff --git a/docs/agents/testing-principles.md b/docs/agents/testing-principles.md index 9d2da92106..1f97eac918 100644 --- a/docs/agents/testing-principles.md +++ b/docs/agents/testing-principles.md @@ -18,9 +18,9 @@ magic. public internet and third-party services; prefer local fakes/fixtures. - Prefer fast unit tests for server logic; keep e2e tests focused on journeys. - Run server/unit tests with - `bun test ./server ./mock-servers ./mcp/github ./mcp/cursor ./mcp/capabilities` + `bun test ./server ./packages/mock-servers ./packages/worker/src/*.test.ts ./packages/worker/src/mcp/github ./packages/worker/src/mcp/cursor ./packages/worker/src/mcp/capabilities ./packages/worker/src/mcp/skills ./packages/worker/src/mcp/context.test.ts ./packages/worker/src/mcp/observability.test.ts` (same paths as `bun run test`) to avoid Playwright spec discovery and - accidental matches like `mcp-server-e2e`. + accidental matches like `packages/worker/src/mcp/mcp-server-e2e.test.ts`. ## Examples diff --git a/docs/agents/typescript-setup.md b/docs/agents/typescript-setup.md index 59d8fa9a08..569d64e860 100644 --- a/docs/agents/typescript-setup.md +++ b/docs/agents/typescript-setup.md @@ -23,16 +23,16 @@ We have **three** distinct TypeScript environments, each with its own - `wrangler-env.ts` - `cli.ts` - `docs/post-download.ts` - - `mcp/mcp-server-e2e.test.ts` + - `packages/worker/src/mcp/mcp-server-e2e.test.ts` - **Environment**: Node/Bun (scripts, configs, tests) ### Worker - **Config**: `types/tsconfig-worker.json` - **Files**: - - `worker/**/*.ts` + - `packages/worker/src/**/*.ts` - `server/**/*.ts` - - `mcp/**/*.ts` + - `packages/worker/src/mcp/**/*.ts` - `types/env.d.ts`, `types/env-schema.ts` - generated `types/worker-configuration.d.ts` (via `bun run generate-types`) - **Environment**: Cloudflare Workers (`WebWorker`, `WebWorker.Iterable`) @@ -57,8 +57,8 @@ hand. - This file is allowed to include relative `../...` imports since it is generated by Wrangler. - If you see this file change in a PR, it should be explainable by changes to - Worker bindings/config (for example `wrangler.jsonc`) or by re-running the - generation script. + Worker bindings/config (for example `packages/worker/wrangler.jsonc`) or by + re-running the generation script. ## Common gotchas diff --git a/docs/architecture/authentication.md b/docs/architecture/authentication.md index 1dbcf069f8..8dcde312a4 100644 --- a/docs/architecture/authentication.md +++ b/docs/architecture/authentication.md @@ -65,8 +65,8 @@ Password reset handlers are in `server/handlers/password-reset.ts`. ## OAuth for MCP -OAuth endpoints are implemented in `worker/oauth-handlers.ts` and routed from -`worker/index.ts`. +OAuth endpoints are implemented in `packages/worker/src/oauth-handlers.ts` and +routed from `packages/worker/src/index.ts`. - Authorization endpoint: `/oauth/authorize` - Token endpoint: `/oauth/token` (via provider) @@ -76,7 +76,7 @@ OAuth endpoints are implemented in `worker/oauth-handlers.ts` and routed from auth links; those links preserve the full authorize URL in `redirectTo` so successful login/signup returns to the original OAuth request -`/mcp` is protected by `worker/mcp-auth.ts`: +`/mcp` is protected by `packages/worker/src/mcp-auth.ts`: - Requires `Authorization: Bearer ` - Token is validated via OAuth provider helpers (`unwrapToken`) @@ -85,8 +85,8 @@ OAuth endpoints are implemented in `worker/oauth-handlers.ts` and routed from ## What to read when changing auth -- `worker/index.ts` for route order and integration points -- `worker/oauth-handlers.ts` for OAuth authorization logic -- `worker/mcp-auth.ts` for MCP token enforcement +- `packages/worker/src/index.ts` for route order and integration points +- `packages/worker/src/oauth-handlers.ts` for OAuth authorization logic +- `packages/worker/src/mcp-auth.ts` for MCP token enforcement - `server/auth-session.ts` for cookie format/signing - `server/handlers/auth.ts` for app login/signup flow diff --git a/docs/architecture/data-storage.md b/docs/architecture/data-storage.md index be002ae619..464f5e0bf1 100644 --- a/docs/architecture/data-storage.md +++ b/docs/architecture/data-storage.md @@ -14,8 +14,9 @@ Current schema is defined by migrations in `migrations/`: App access pattern: -- `worker/db.ts` defines shared `remix/data-table` table metadata and creates a - D1-backed database runtime via `worker/d1-data-table-adapter.ts` +- `packages/worker/src/db.ts` defines shared `remix/data-table` table metadata + and creates a D1-backed database runtime via + `packages/worker/src/d1-data-table-adapter.ts` - Database row validation and API payload parsing use `remix/data-schema` - app handlers and the mock Resend worker perform CRUD/query operations through `remix/data-table` (including `findOne`, `create`, `update`, `deleteMany`, and @@ -26,14 +27,14 @@ App access pattern: OAuth provider state is stored in KV through the `@cloudflare/workers-oauth-provider` integration. -- Binding is configured in `wrangler.jsonc` +- Binding is configured in `packages/worker/wrangler.jsonc` - This supports OAuth client and token flows without custom storage code in the app handlers ## Durable Objects (`MCP_OBJECT`) MCP server runtime state is hosted via a Durable Object class (`MCP`) in -`mcp/index.ts`, exposed through the `/mcp` route. +`packages/worker/src/mcp/index.ts`, exposed through the `/mcp` route. - The Worker forwards authorized MCP requests to `MCP.serve(...).fetch` - Durable Objects provide a stateful execution model for MCP operations @@ -50,7 +51,7 @@ Chat conversations run through a chat Agent Durable Object. ## Configuration reference -Bindings are configured per environment in `wrangler.jsonc`: +Bindings are configured per environment in `packages/worker/wrangler.jsonc`: - `APP_DB` (D1) - `OAUTH_KV` (KV) diff --git a/docs/architecture/index.md b/docs/architecture/index.md index 6841bea65b..7f7d199767 100644 --- a/docs/architecture/index.md +++ b/docs/architecture/index.md @@ -23,13 +23,14 @@ is trying to become. ## Source of truth in code -- Worker entrypoint: `worker/index.ts` +- Worker entrypoint: `packages/worker/src/index.ts` - Server request handler: `server/handler.ts` - Router and HTTP route mapping: `server/router.ts` and `server/routes.ts` -- OAuth handlers: `worker/oauth-handlers.ts` -- MCP auth checks: `worker/mcp-auth.ts` -- MCP capability catalog: domain modules under `mcp/capabilities/*/domain.ts`, - merged list in `mcp/capabilities/builtin-domains.ts`, built by - `mcp/capabilities/build-capability-registry.ts`, re-exported from - `mcp/capabilities/registry.ts` (see +- OAuth handlers: `packages/worker/src/oauth-handlers.ts` +- MCP auth checks: `packages/worker/src/mcp-auth.ts` +- MCP capability catalog: domain modules under + `packages/worker/src/mcp/capabilities/*/domain.ts`, merged list in + `packages/worker/src/mcp/capabilities/builtin-domains.ts`, built by + `packages/worker/src/mcp/capabilities/build-capability-registry.ts`, + re-exported from `packages/worker/src/mcp/capabilities/registry.ts` (see [`../agents/adding-capabilities.md`](../agents/adding-capabilities.md)). diff --git a/docs/architecture/request-lifecycle.md b/docs/architecture/request-lifecycle.md index 230a5a3ddc..0597e950a0 100644 --- a/docs/architecture/request-lifecycle.md +++ b/docs/architecture/request-lifecycle.md @@ -4,19 +4,20 @@ This document explains how an incoming request moves through the system. ## Entry point -All traffic enters the Worker at `worker/index.ts`. +All traffic enters the Worker at `packages/worker/src/index.ts`. The default `fetch` handler delegates to `OAuthProvider` from `@cloudflare/workers-oauth-provider`, which means OAuth endpoints and token infrastructure are available alongside normal app routes. Before that, `GET`/`HEAD`/`OPTIONS` on `/.well-known/oauth-protected-resource` -are handled in `worker/index.ts` itself. The OAuth provider library’s built-in -handler for that path advertises `resource` as the request **origin** only; this -app’s MCP server is identified by `/mcp`. Serving our own metadata on -that URL keeps the RFC 8707 `resource` value consistent for clients (e.g. some -MCP stacks) that discover metadata from the 401 `resource_metadata` URL and -would otherwise get `invalid_target` at the token endpoint. +are handled in `packages/worker/src/index.ts` itself. The OAuth provider +library’s built-in handler for that path advertises `resource` as the request +**origin** only; this app’s MCP server is identified by `/mcp`. Serving +our own metadata on that URL keeps the RFC 8707 `resource` value consistent for +clients (e.g. some MCP stacks) that discover metadata from the 401 +`resource_metadata` URL and would otherwise get `invalid_target` at the token +endpoint. ## Routing order @@ -66,7 +67,7 @@ Full page navigations still occur for: ## CORS behavior -`worker/index.ts` wraps the handler with `withCors`: +`packages/worker/src/index.ts` wraps the handler with `withCors`: - CORS headers are only added when `Origin` exactly matches the request origin. - Allowed methods are `GET, POST, OPTIONS`. @@ -78,27 +79,28 @@ and API requests. ## Observability (Sentry) The Worker default export is wrapped with `Sentry.withSentry` from -`@sentry/cloudflare` (see `worker/index.ts`) so incoming `fetch` requests are -traced and uncaught errors can be reported when `SENTRY_DSN` is configured. +`@sentry/cloudflare` (see `packages/worker/src/index.ts`) so incoming `fetch` +requests are traced and uncaught errors can be reported when `SENTRY_DSN` is +configured. The **MCP** (`MCP` / `MCP_OBJECT`) and **chat** (`ChatAgent`) Durable Objects are each wrapped with `Sentry.instrumentDurableObjectWithSentry` (see -`mcp/index.ts` and `worker/chat-agent.ts`) because they run in separate isolates -from the top-level Worker. +`packages/worker/src/mcp/index.ts` and `packages/worker/src/chat-agent.ts`) +because they run in separate isolates from the top-level Worker. Shared options are built in `sentry/cloudflare-options.ts`: **release** comes from `APP_COMMIT_SHA` when set (deploy workflows pass it as a var), and -**environment** defaults from `SENTRY_ENVIRONMENT` in `wrangler.jsonc` per -deploy target. +**environment** defaults from `SENTRY_ENVIRONMENT` in +`packages/worker/wrangler.jsonc` per deploy target. -MCP tools emit structured `mcp-event` logs via `mcp/observability.ts`. On -failures, the same module sends Sentry events (with MCP tags and context); -sandbox user-code failures are reported at **warning** severity, while -capability handler bugs use **error**. +MCP tools emit structured `mcp-event` logs via +`packages/worker/src/mcp/observability.ts`. On failures, the same module sends +Sentry events (with MCP tags and context); sandbox user-code failures are +reported at **warning** severity, while capability handler bugs use **error**. ### Source maps -`wrangler.jsonc` sets +`packages/worker/wrangler.jsonc` sets [`upload_source_maps`](https://developers.cloudflare.com/workers/wrangler/configuration/#source-maps), and `bun run deploy` passes `--outdir .wrangler/sentry-bundle --upload-source-maps` so the bundle + maps are diff --git a/docs/cloudflare-offerings.md b/docs/cloudflare-offerings.md index 357a890d51..881ebdc7e4 100644 --- a/docs/cloudflare-offerings.md +++ b/docs/cloudflare-offerings.md @@ -14,8 +14,8 @@ This guide covers how to add common Cloudflare offerings on top of the starter: - AI Gateway - An additional KV namespace for app data (separate from `OAUTH_KV`) -All examples assume you are using the template's `wrangler.jsonc` and that you -run commands from the repo root. +All examples assume you are using the template's +`packages/worker/wrangler.jsonc` and that you run commands from the repo root. ## Authentication: `wrangler login` vs API tokens @@ -69,12 +69,12 @@ Create separate buckets for production vs preview/testing: - `bunx wrangler r2 bucket create -uploads-preview` - `bunx wrangler r2 bucket list` -Wrangler can also update `wrangler.jsonc` for you: +Wrangler can also update `packages/worker/wrangler.jsonc` for you: - `bunx wrangler r2 bucket create -uploads --binding UPLOADS_BUCKET --env production --update-config` - `bunx wrangler r2 bucket create -uploads-preview --binding UPLOADS_BUCKET --env preview --update-config` -### Bind the bucket in `wrangler.jsonc` +### Bind the bucket in `packages/worker/wrangler.jsonc` Add an `r2_buckets` binding in each environment you want to use it: @@ -123,7 +123,7 @@ Workers AI lets your Worker call Cloudflare-hosted AI models. - `bunx wrangler ai models` - `bunx wrangler ai models --json` -### Bind Workers AI in `wrangler.jsonc` +### Bind Workers AI in `packages/worker/wrangler.jsonc` Add the AI binding per environment: @@ -213,9 +213,9 @@ Create a dedicated namespace for app data, for example `APP_KV`: - `bunx wrangler kv namespace create -app-preview --binding APP_KV --env production --preview --update-config` If you are not using `--update-config`, record the namespace IDs and add them to -`wrangler.jsonc` manually (see next section). +`packages/worker/wrangler.jsonc` manually (see next section). -### Bind the namespace in `wrangler.jsonc` +### Bind the namespace in `packages/worker/wrangler.jsonc` Add a second entry in `kv_namespaces` alongside `OAUTH_KV`: @@ -273,7 +273,7 @@ the TanStack provider packages you use (for example OpenAI or Anthropic): - `bun add @tanstack/ai-openai` - `bun add @tanstack/ai-anthropic` -#### Bindings (`wrangler.jsonc`) +#### Bindings (`packages/worker/wrangler.jsonc`) Add the Workers AI binding in each environment you want: diff --git a/docs/environment-variables.md b/docs/environment-variables.md index cc61b32f06..94f319f257 100644 --- a/docs/environment-variables.md +++ b/docs/environment-variables.md @@ -53,14 +53,15 @@ Optional Worker secret and vars (see `types/env-schema.ts` and skips `Sentry.withSentry`; Durable Objects use the same options builder and will not send events without a DSN. - `SENTRY_ENVIRONMENT` — also set as a Wrangler `var` per environment in - `wrangler.jsonc` for deploys. + `packages/worker/wrangler.jsonc` for deploys. - `SENTRY_TRACES_SAMPLE_RATE` — optional `0`–`1`; defaults to **`1.0`** (sample all traces). Set lower (e.g. `0.1`) for higher traffic or Sentry quota. ## GitHub (`github_rest` + `github_graphql` capabilities) Optional Worker secrets/vars (see `types/env-schema.ts`, -`mcp/github/github-rest-client.ts`, and `mcp/github/github-graphql-client.ts`): +`packages/worker/src/mcp/github/github-rest-client.ts`, and +`packages/worker/src/mcp/github/github-graphql-client.ts`): - `GITHUB_TOKEN` — Bearer token for `api.github.com` (fine-grained PAT recommended) for the `kody-bot` account. GitHub REST and GraphQL calls act as @@ -76,14 +77,15 @@ Optional Worker secrets/vars (see `types/env-schema.ts`, ## MCP capability search (Vectorize + Workers AI) -Worker bindings (see `wrangler.jsonc`): +Worker bindings (see `packages/worker/wrangler.jsonc`): - **`CAPABILITY_VECTOR_INDEX`** — Cloudflare Vectorize index for semantic retrieval (`kody-capabilities-prod` / `kody-capabilities-preview`). Create indexes with **`--dimensions=384 --metric=cosine`** to match - `@cf/baai/bge-small-en-v1.5` (see `mcp/capabilities/capability-search.ts`). - The **`test`** Wrangler environment omits this binding so `bun test` and e2e - use the deterministic offline fusion path (`offline: true` in search results). + `@cf/baai/bge-small-en-v1.5` (see + `packages/worker/src/mcp/capabilities/capability-search.ts`). The **`test`** + Wrangler environment omits this binding so `bun test` and e2e use the + deterministic offline fusion path (`offline: true` in search results). Optional Worker secret: @@ -95,7 +97,7 @@ Optional Worker secret: ## Cursor Cloud Agents (`cursor_cloud_rest` capability) Optional Worker secrets/vars (see `types/env-schema.ts` and -`mcp/cursor/cursor-cloud-client.ts`): +`packages/worker/src/mcp/cursor/cursor-cloud-client.ts`): - `CURSOR_API_KEY` — Cursor API key ([dashboard](https://cursor.com/settings)). The Cursor Cloud API uses **HTTP Basic** auth (key as username, empty diff --git a/docs/getting-started.md b/docs/getting-started.md index a394c95063..b88695cd07 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -32,8 +32,8 @@ bun install The setup flow assumes: - Bun is installed (uses `bun`/`bunx`). -- You run commands from the repo root (needs `wrangler.jsonc` and - `package.json`). +- You run commands from the repo root (needs `nx.json`, `package.json`, and + `packages/worker/wrangler.jsonc`). - You can write to files in the repository (the script updates config files and replaces template `kody` tokens across text files). - Wrangler is optional for post-download setup. It is only needed when you @@ -74,11 +74,11 @@ bun run dev bun ./docs/post-download.ts --guided ``` -This setup step does not create Cloudflare resources or rewrite `wrangler.jsonc` -resource IDs. The production deploy workflow creates missing D1/KV resources -automatically on first CI deploy. Cloudflare deploys do not auto-create those -resources from bindings alone, so the workflow runs an explicit ensure step -before migrations/deploy. +This setup step does not create Cloudflare resources or rewrite +`packages/worker/wrangler.jsonc` resource IDs. The production deploy workflow +creates missing D1/KV resources automatically on first CI deploy. Cloudflare +deploys do not auto-create those resources from bindings alone, so the workflow +runs an explicit ensure step before migrations/deploy. 2. Configure GitHub Actions secrets and variables for deploy: @@ -128,7 +128,7 @@ are missing (for example `--app-name` without `--defaults`, and init choice when - `--cookie-secret`: explicit `COOKIE_SECRET` value (otherwise generated). Cloudflare resources are managed during deploy. The setup script does not create -Cloudflare resources or rewrite `wrangler.jsonc` resource IDs. +Cloudflare resources or rewrite `packages/worker/wrangler.jsonc` resource IDs. ## Local development diff --git a/docs/mcp-server-patterns.md b/docs/mcp-server-patterns.md index 8007bc12c9..fd7a685e31 100644 --- a/docs/mcp-server-patterns.md +++ b/docs/mcp-server-patterns.md @@ -282,7 +282,7 @@ and handler colocated. Keep a small `register-tools` module that imports each tool module and registers them. ```typescript -// mcp/tools/do-math.ts +// packages/worker/src/mcp/tools/do-math.ts export async function registerDoMathTool(agent: MCP) { agent.server.registerTool( 'do_math', @@ -295,7 +295,7 @@ export async function registerDoMathTool(agent: MCP) { ) } -// mcp/register-tools.ts +// packages/worker/src/mcp/register-tools.ts import { registerDoMathTool } from './tools/do-math.ts' export async function registerTools(agent: MCP) { await registerDoMathTool(agent) @@ -308,9 +308,10 @@ export async function registerTools(agent: MCP) { - Tool docs/schemas/handler stay in sync - Easier to add/remove tools without touching unrelated tools -**Example in this repo:** Server instructions live in `mcp/index.ts`, and tool -metadata is colocated with tool registration + schemas in `mcp/tools/do-math.ts` -(with `mcp/register-tools.ts` as the small aggregator). +**Example in this repo:** Server instructions live in +`packages/worker/src/mcp/index.ts`, and tool metadata is colocated with tool +registration + schemas in `packages/worker/src/mcp/tools/do-math.ts` (with +`packages/worker/src/mcp/register-tools.ts` as the small aggregator). --- diff --git a/docs/setup-manifest.md b/docs/setup-manifest.md index 4efdc411b4..c2c0333a77 100644 --- a/docs/setup-manifest.md +++ b/docs/setup-manifest.md @@ -17,12 +17,13 @@ This project uses the following resources: - Create once per account, for example: `wrangler vectorize create kody-capabilities-prod --dimensions=384 --metric=cosine` (same for preview). **Dimensions must match** the embedding model in - `mcp/capabilities/capability-search.ts` (`@cf/baai/bge-small-en-v1.5`). + `packages/worker/src/mcp/capabilities/capability-search.ts` + (`@cf/baai/bge-small-en-v1.5`). Production CI deploys now ensure these resources exist and create them when missing. The post-download script does not create Cloudflare resources and does -not rewrite `wrangler.jsonc` resource IDs. Cloudflare deploys do not auto-create -these resources from bindings alone, so the deploy workflow runs +not rewrite `packages/worker/wrangler.jsonc` resource IDs. Cloudflare deploys do +not auto-create these resources from bindings alone, so the deploy workflow runs `bun tools/ci/production-resources.ts ensure` first. ## Optional Cloudflare offerings @@ -67,8 +68,9 @@ Local development uses `.env`, which Wrangler loads automatically: so Wrangler can authenticate Workers AI requests) - `SENTRY_DSN` (optional Cloudflare Worker secret; enables error reporting and tracing for the Worker and Durable Objects) -- `SENTRY_ENVIRONMENT` (set per deploy via `wrangler.jsonc` `vars` as - `production`, `preview`, or `test`; optional override via env for local dev) +- `SENTRY_ENVIRONMENT` (set per deploy via `packages/worker/wrangler.jsonc` + `vars` as `production`, `preview`, or `test`; optional override via env for + local dev) - `SENTRY_TRACES_SAMPLE_RATE` (optional `0`–`1`, defaults to **`1.0`** in code when unset — full sampling for low traffic; lower if volume grows) - `APP_COMMIT_SHA` (used as the Sentry **release** when present, in addition to diff --git a/nx.json b/nx.json new file mode 100644 index 0000000000..84527f4268 --- /dev/null +++ b/nx.json @@ -0,0 +1,24 @@ +{ + "$schema": "./node_modules/nx/schemas/nx-schema.json", + "defaultBase": "main", + "workspaceLayout": { + "libsDir": "packages" + }, + "targetDefaults": { + "dev": { + "cache": false + }, + "dev-client": { + "cache": false + }, + "dev-worker": { + "cache": false + }, + "preview": { + "cache": false + }, + "preview-e2e": { + "cache": false + } + } +} diff --git a/package.json b/package.json index f426030d18..9ec9e0bb0c 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,9 @@ "version": "0.0.0", "type": "module", "imports": { - "#*": "./*" + "#worker/*": "./packages/worker/src/*", + "#*": "./*", + "#mcp/*": "./packages/worker/src/mcp/*" }, "description": "A starter and reference for building full stack web applications", "scripts": { @@ -13,10 +15,10 @@ "dev:client:web": "esbuild client/entry.tsx --bundle --format=esm --target=es2022 --outdir=public --entry-names=client-entry --chunk-names=assets/[name] --asset-names=assets/[name] --jsx=automatic --jsx-import-source=remix/component --watch", "dev:mcp-apps": "esbuild client/mcp-apps/calculator-widget.ts --bundle --format=esm --target=es2022 --outdir=public/mcp-apps --platform=browser --watch", "dev:worker": "bun ./wrangler-env.ts dev --local", - "dev:mock-resend": "bun ./wrangler-env.ts dev --local --config mock-servers/resend/wrangler.jsonc", - "dev:mock-ai": "bun ./wrangler-env.ts dev --local --config mock-servers/ai/wrangler.jsonc", - "dev:mock-github": "bun ./wrangler-env.ts dev --local --config mock-servers/github/wrangler.jsonc", - "dev:mock-cursor": "bun ./wrangler-env.ts dev --local --config mock-servers/cursor/wrangler.jsonc", + "dev:mock-resend": "bun ./wrangler-env.ts dev --local --config packages/mock-servers/resend/wrangler.jsonc", + "dev:mock-ai": "bun ./wrangler-env.ts dev --local --config packages/mock-servers/ai/wrangler.jsonc", + "dev:mock-github": "bun ./wrangler-env.ts dev --local --config packages/mock-servers/github/wrangler.jsonc", + "dev:mock-cursor": "bun ./wrangler-env.ts dev --local --config packages/mock-servers/cursor/wrangler.jsonc", "deploy": "bun run build && bun ./wrangler-env.ts deploy --outdir .wrangler/sentry-bundle --upload-source-maps", "sentry:upload-sourcemaps": "bun tools/sentry-upload-sourcemaps.ts", "build:mcp-apps": "esbuild client/mcp-apps/calculator-widget.ts --bundle --format=esm --target=es2022 --outdir=public/mcp-apps --platform=browser", @@ -33,13 +35,15 @@ "preview:e2e": "bun run build:mcp-apps && bun run migrate:e2e && bun ./wrangler-env.ts dev --local --persist-to .wrangler/state/e2e", "generate-types": "bun ./wrangler-env.ts types ./types/worker-configuration.d.ts", "typecheck": "tsc -b --noEmit", - "test": "bun test ./server ./mock-servers ./mcp/github ./mcp/cursor ./mcp/capabilities", + "test": "bun test ./server ./packages/mock-servers ./packages/shared ./packages/worker/src/*.test.ts ./packages/worker/src/mcp/github ./packages/worker/src/mcp/cursor ./packages/worker/src/mcp/capabilities ./packages/worker/src/mcp/skills ./packages/worker/src/mcp/context.test.ts ./packages/worker/src/mcp/observability.test.ts", "inspect": "bunx -p @mcpjam/inspector inspector", "validate": "concurrently --kill-others-on-fail -n format,lint,build,typecheck,test,test:mcp -c green,yellow,blue,magenta,cyan,red \"bun run format:check\" \"bun run lint:fix\" \"bun run build\" \"bun run typecheck\" \"bun run test:e2e\" \"bun run test:mcp\"", "test:e2e": "bun tools/prepare-e2e-env.ts && playwright test", "test:e2e:ui": "bun tools/prepare-e2e-env.ts && playwright test --ui", "test:e2e:install": "playwright install chromium --with-deps", - "test:mcp": "bun run build:mcp-apps && bun test mcp/mcp-server-e2e.test.ts" + "test:mcp": "bun run build:mcp-apps && bun test packages/worker/src/mcp/mcp-server-e2e.test.ts", + "nx:graph": "nx graph", + "nx:show-projects": "nx show projects" }, "devDependencies": { "@epic-web/config": "^1.24.1", @@ -49,6 +53,7 @@ "@types/set-cookie-parser": "^2.4.10", "concurrently": "^9.2.1", "esbuild": "^0.27.4", + "nx": "^22.6.1", "oxlint": "^1.55.0", "prettier": "^3.8.1", "set-cookie-parser": "^3.0.1", @@ -60,6 +65,7 @@ "@modelcontextprotocol/sdk": "1.26.0" }, "dependencies": { + "@kody-internal/shared": "workspace:*", "@cloudflare/ai-chat": "^0.1.8", "@cloudflare/codemode": "^0.2.1", "@cloudflare/workers-oauth-provider": "^0.3.0", @@ -74,5 +80,11 @@ "remix": "3.0.0-alpha.3", "workers-ai-provider": "^3.1.2", "zod": "^4.3.6" - } + }, + "packageManager": "bun@1.3.11", + "workspaces": [ + "packages/shared", + "packages/worker", + "packages/mock-servers/*" + ] } diff --git a/packages/mock-servers/ai/package.json b/packages/mock-servers/ai/package.json new file mode 100644 index 0000000000..cf09ed790e --- /dev/null +++ b/packages/mock-servers/ai/package.json @@ -0,0 +1,9 @@ +{ + "name": "@kody/mock-ai", + "private": true, + "type": "module", + "dependencies": { + "@kody-internal/shared": "workspace:*", + "@kody/worker": "workspace:*" + } +} diff --git a/packages/mock-servers/ai/project.json b/packages/mock-servers/ai/project.json new file mode 100644 index 0000000000..b960603ff2 --- /dev/null +++ b/packages/mock-servers/ai/project.json @@ -0,0 +1,15 @@ +{ + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "name": "mock-ai", + "projectType": "application", + "sourceRoot": "packages/mock-servers/ai/src", + "targets": { + "dev": { + "executor": "nx:run-commands", + "options": { + "command": "bun run dev:mock-ai" + } + } + }, + "tags": ["scope:mock-server", "service:ai"] +} diff --git a/mock-servers/ai/worker.ts b/packages/mock-servers/ai/src/worker.ts similarity index 98% rename from mock-servers/ai/worker.ts rename to packages/mock-servers/ai/src/worker.ts index 41f455b003..a3bdefbaba 100644 --- a/mock-servers/ai/worker.ts +++ b/packages/mock-servers/ai/src/worker.ts @@ -1,5 +1,5 @@ -import { createDb, mockAiRequestsTable } from '#worker/db.ts' -import { buildMockAiScenario } from '#shared/mock-ai.ts' +import { createDb, mockAiRequestsTable } from '@kody/worker/db.ts' +import { buildMockAiScenario } from '@kody-internal/shared/mock-ai.ts' type MockAiEnv = { APP_DB: D1Database diff --git a/mock-servers/ai/wrangler.jsonc b/packages/mock-servers/ai/wrangler.jsonc similarity index 76% rename from mock-servers/ai/wrangler.jsonc rename to packages/mock-servers/ai/wrangler.jsonc index 071b2273be..5fe0daca4d 100644 --- a/mock-servers/ai/wrangler.jsonc +++ b/packages/mock-servers/ai/wrangler.jsonc @@ -1,9 +1,9 @@ { - "$schema": "../../node_modules/wrangler/config-schema.json", + "$schema": "../../../node_modules/wrangler/config-schema.json", "name": "kody-mock-ai", "compatibility_date": "2026-01-31", "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"], - "main": "./worker.ts", + "main": "./src/worker.ts", "preview_urls": true, "observability": { "enabled": true }, "env": { @@ -13,7 +13,7 @@ "binding": "APP_DB", "database_name": "kody", "database_id": "c64eb497-a93d-4af4-bfb7-62beda9552b6", - "migrations_dir": "../../migrations", + "migrations_dir": "../../../migrations", }, ], }, @@ -23,7 +23,7 @@ "binding": "APP_DB", "database_name": "kody-preview", "database_id": "0e2f1e31-b7c4-42bc-8133-04627230a25f", - "migrations_dir": "../../migrations", + "migrations_dir": "../../../migrations", }, ], }, @@ -33,7 +33,7 @@ "binding": "APP_DB", "database_name": "kody-preview", "database_id": "0e2f1e31-b7c4-42bc-8133-04627230a25f", - "migrations_dir": "../../migrations", + "migrations_dir": "../../../migrations", }, ], }, diff --git a/packages/mock-servers/cursor/package.json b/packages/mock-servers/cursor/package.json new file mode 100644 index 0000000000..f9536a74ec --- /dev/null +++ b/packages/mock-servers/cursor/package.json @@ -0,0 +1,5 @@ +{ + "name": "@kody/mock-cursor", + "private": true, + "type": "module" +} diff --git a/packages/mock-servers/cursor/project.json b/packages/mock-servers/cursor/project.json new file mode 100644 index 0000000000..4c99bfee85 --- /dev/null +++ b/packages/mock-servers/cursor/project.json @@ -0,0 +1,15 @@ +{ + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "name": "mock-cursor", + "projectType": "application", + "sourceRoot": "packages/mock-servers/cursor/src", + "targets": { + "dev": { + "executor": "nx:run-commands", + "options": { + "command": "bun run dev:mock-cursor" + } + } + }, + "tags": ["scope:mock-server", "service:cursor"] +} diff --git a/mock-servers/cursor/worker.ts b/packages/mock-servers/cursor/src/worker.ts similarity index 100% rename from mock-servers/cursor/worker.ts rename to packages/mock-servers/cursor/src/worker.ts diff --git a/mock-servers/cursor/wrangler.jsonc b/packages/mock-servers/cursor/wrangler.jsonc similarity index 69% rename from mock-servers/cursor/wrangler.jsonc rename to packages/mock-servers/cursor/wrangler.jsonc index 6ffd9da7fc..e8f34f71ac 100644 --- a/mock-servers/cursor/wrangler.jsonc +++ b/packages/mock-servers/cursor/wrangler.jsonc @@ -1,9 +1,9 @@ { - "$schema": "../../node_modules/wrangler/config-schema.json", + "$schema": "../../../node_modules/wrangler/config-schema.json", "name": "kody-mock-cursor", "compatibility_date": "2026-01-31", "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"], - "main": "./worker.ts", + "main": "./src/worker.ts", "preview_urls": true, "observability": { "enabled": true }, } diff --git a/packages/mock-servers/github/package.json b/packages/mock-servers/github/package.json new file mode 100644 index 0000000000..702eb5c080 --- /dev/null +++ b/packages/mock-servers/github/package.json @@ -0,0 +1,5 @@ +{ + "name": "@kody/mock-github", + "private": true, + "type": "module" +} diff --git a/packages/mock-servers/github/project.json b/packages/mock-servers/github/project.json new file mode 100644 index 0000000000..7a7c154e68 --- /dev/null +++ b/packages/mock-servers/github/project.json @@ -0,0 +1,15 @@ +{ + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "name": "mock-github", + "projectType": "application", + "sourceRoot": "packages/mock-servers/github/src", + "targets": { + "dev": { + "executor": "nx:run-commands", + "options": { + "command": "bun run dev:mock-github" + } + } + }, + "tags": ["scope:mock-server", "service:github"] +} diff --git a/mock-servers/github/github-mock.test.ts b/packages/mock-servers/github/src/github-mock.test.ts similarity index 98% rename from mock-servers/github/github-mock.test.ts rename to packages/mock-servers/github/src/github-mock.test.ts index 5e6a42a57b..a2d8385a91 100644 --- a/mock-servers/github/github-mock.test.ts +++ b/packages/mock-servers/github/src/github-mock.test.ts @@ -3,7 +3,7 @@ import { expect, test } from 'bun:test' import getPort from 'get-port' import { setTimeout as delay } from 'node:timers/promises' -const workerConfig = 'mock-servers/github/wrangler.jsonc' +const workerConfig = 'packages/mock-servers/github/wrangler.jsonc' const bunBin = process.execPath const projectRoot = process.cwd() const defaultTimeoutMs = 60_000 diff --git a/mock-servers/github/worker.ts b/packages/mock-servers/github/src/worker.ts similarity index 100% rename from mock-servers/github/worker.ts rename to packages/mock-servers/github/src/worker.ts diff --git a/mock-servers/github/wrangler.jsonc b/packages/mock-servers/github/wrangler.jsonc similarity index 69% rename from mock-servers/github/wrangler.jsonc rename to packages/mock-servers/github/wrangler.jsonc index 7c2ea9d38d..1f88a287e1 100644 --- a/mock-servers/github/wrangler.jsonc +++ b/packages/mock-servers/github/wrangler.jsonc @@ -1,9 +1,9 @@ { - "$schema": "../../node_modules/wrangler/config-schema.json", + "$schema": "../../../node_modules/wrangler/config-schema.json", "name": "kody-mock-github", "compatibility_date": "2026-01-31", "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"], - "main": "./worker.ts", + "main": "./src/worker.ts", "preview_urls": true, "observability": { "enabled": true }, } diff --git a/packages/mock-servers/resend/package.json b/packages/mock-servers/resend/package.json new file mode 100644 index 0000000000..6e2a107dcb --- /dev/null +++ b/packages/mock-servers/resend/package.json @@ -0,0 +1,9 @@ +{ + "name": "@kody/mock-resend", + "private": true, + "type": "module", + "dependencies": { + "@kody-internal/shared": "workspace:*", + "@kody/worker": "workspace:*" + } +} diff --git a/packages/mock-servers/resend/project.json b/packages/mock-servers/resend/project.json new file mode 100644 index 0000000000..acbccc55ff --- /dev/null +++ b/packages/mock-servers/resend/project.json @@ -0,0 +1,15 @@ +{ + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "name": "mock-resend", + "projectType": "application", + "sourceRoot": "packages/mock-servers/resend/src", + "targets": { + "dev": { + "executor": "nx:run-commands", + "options": { + "command": "bun run dev:mock-resend" + } + } + }, + "tags": ["scope:mock-server", "service:resend"] +} diff --git a/mock-servers/resend/resend-mock.test.ts b/packages/mock-servers/resend/src/resend-mock.test.ts similarity index 98% rename from mock-servers/resend/resend-mock.test.ts rename to packages/mock-servers/resend/src/resend-mock.test.ts index 11153c0730..30d8cd7dbd 100644 --- a/mock-servers/resend/resend-mock.test.ts +++ b/packages/mock-servers/resend/src/resend-mock.test.ts @@ -2,9 +2,9 @@ import { expect, test } from 'bun:test' import getPort from 'get-port' import { setTimeout as delay } from 'node:timers/promises' -import { createTemporaryDirectory } from '#tools/temp-directory.ts' +import { createTemporaryDirectory } from '../../../../tools/temp-directory.ts' -const workerConfig = 'mock-servers/resend/wrangler.jsonc' +const workerConfig = 'packages/mock-servers/resend/wrangler.jsonc' const bunBin = process.execPath const projectRoot = process.cwd() const defaultTimeoutMs = 60_000 diff --git a/mock-servers/resend/worker.ts b/packages/mock-servers/resend/src/worker.ts similarity index 98% rename from mock-servers/resend/worker.ts rename to packages/mock-servers/resend/src/worker.ts index 83c8825976..fe0af575be 100644 --- a/mock-servers/resend/worker.ts +++ b/packages/mock-servers/resend/src/worker.ts @@ -1,6 +1,6 @@ import { parseSafe } from 'remix/data-schema' -import { resendEmailSchema } from '#shared/resend-email.ts' -import { createDb, mockResendMessagesTable } from '#worker/db.ts' +import { resendEmailSchema } from '@kody-internal/shared/resend-email.ts' +import { createDb, mockResendMessagesTable } from '@kody/worker/db.ts' type MockResendEnv = { APP_DB: D1Database diff --git a/mock-servers/resend/wrangler.jsonc b/packages/mock-servers/resend/wrangler.jsonc similarity index 76% rename from mock-servers/resend/wrangler.jsonc rename to packages/mock-servers/resend/wrangler.jsonc index 2c9317156d..232e066692 100644 --- a/mock-servers/resend/wrangler.jsonc +++ b/packages/mock-servers/resend/wrangler.jsonc @@ -1,9 +1,9 @@ { - "$schema": "../../node_modules/wrangler/config-schema.json", + "$schema": "../../../node_modules/wrangler/config-schema.json", "name": "kody-mock-resend", "compatibility_date": "2026-01-31", "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"], - "main": "./worker.ts", + "main": "./src/worker.ts", "preview_urls": true, "observability": { "enabled": true }, "env": { @@ -13,7 +13,7 @@ "binding": "APP_DB", "database_name": "kody", "database_id": "c64eb497-a93d-4af4-bfb7-62beda9552b6", - "migrations_dir": "../../migrations", + "migrations_dir": "../../../migrations", }, ], }, @@ -23,7 +23,7 @@ "binding": "APP_DB", "database_name": "kody-preview", "database_id": "0e2f1e31-b7c4-42bc-8133-04627230a25f", - "migrations_dir": "../../migrations", + "migrations_dir": "../../../migrations", }, ], }, @@ -33,7 +33,7 @@ "binding": "APP_DB", "database_name": "kody-preview", "database_id": "0e2f1e31-b7c4-42bc-8133-04627230a25f", - "migrations_dir": "../../migrations", + "migrations_dir": "../../../migrations", }, ], }, diff --git a/packages/shared/package.json b/packages/shared/package.json new file mode 100644 index 0000000000..8ddf44ae81 --- /dev/null +++ b/packages/shared/package.json @@ -0,0 +1,11 @@ +{ + "name": "@kody-internal/shared", + "private": true, + "type": "module", + "exports": { + "./*": "./src/*" + }, + "dependencies": { + "remix": "3.0.0-alpha.3" + } +} diff --git a/shared/ai-env-validation.test.ts b/packages/shared/src/ai-env-validation.test.ts similarity index 100% rename from shared/ai-env-validation.test.ts rename to packages/shared/src/ai-env-validation.test.ts diff --git a/shared/ai-env-validation.ts b/packages/shared/src/ai-env-validation.ts similarity index 100% rename from shared/ai-env-validation.ts rename to packages/shared/src/ai-env-validation.ts diff --git a/shared/chat-routes.ts b/packages/shared/src/chat-routes.ts similarity index 100% rename from shared/chat-routes.ts rename to packages/shared/src/chat-routes.ts diff --git a/shared/chat.ts b/packages/shared/src/chat.ts similarity index 100% rename from shared/chat.ts rename to packages/shared/src/chat.ts diff --git a/shared/hex.ts b/packages/shared/src/hex.ts similarity index 100% rename from shared/hex.ts rename to packages/shared/src/hex.ts diff --git a/shared/mock-ai.test.ts b/packages/shared/src/mock-ai.test.ts similarity index 100% rename from shared/mock-ai.test.ts rename to packages/shared/src/mock-ai.test.ts diff --git a/shared/mock-ai.ts b/packages/shared/src/mock-ai.ts similarity index 100% rename from shared/mock-ai.ts rename to packages/shared/src/mock-ai.ts diff --git a/shared/password-hash.test.ts b/packages/shared/src/password-hash.test.ts similarity index 100% rename from shared/password-hash.test.ts rename to packages/shared/src/password-hash.test.ts diff --git a/shared/password-hash.ts b/packages/shared/src/password-hash.ts similarity index 100% rename from shared/password-hash.ts rename to packages/shared/src/password-hash.ts diff --git a/shared/resend-email.ts b/packages/shared/src/resend-email.ts similarity index 100% rename from shared/resend-email.ts rename to packages/shared/src/resend-email.ts diff --git a/packages/shared/tsconfig.json b/packages/shared/tsconfig.json new file mode 100644 index 0000000000..a5ba5ab333 --- /dev/null +++ b/packages/shared/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "@epic-web/config/typescript", + "compilerOptions": { + "allowImportingTsExtensions": true, + "tsBuildInfoFile": "../../node_modules/.tmp/tsconfig.shared.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023", "WebWorker", "WebWorker.Iterable"], + "module": "ESNext", + "moduleResolution": "bundler", + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + "noEmit": true + }, + "include": ["src/**/*.ts"], + "exclude": ["**/*.test.ts"] +} diff --git a/packages/worker/package.json b/packages/worker/package.json new file mode 100644 index 0000000000..cb1953ea8c --- /dev/null +++ b/packages/worker/package.json @@ -0,0 +1,15 @@ +{ + "name": "@kody/worker", + "private": true, + "type": "module", + "exports": { + "./*": "./src/*" + }, + "dependencies": { + "@kody-internal/shared": "workspace:*" + }, + "imports": { + "#worker/*": "./src/*", + "#mcp/*": "./src/mcp/*" + } +} diff --git a/packages/worker/project.json b/packages/worker/project.json new file mode 100644 index 0000000000..3c49fe62f0 --- /dev/null +++ b/packages/worker/project.json @@ -0,0 +1,87 @@ +{ + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "name": "worker", + "projectType": "application", + "sourceRoot": "packages/worker/src", + "targets": { + "dev": { + "executor": "nx:run-commands", + "options": { + "command": "bun run dev" + } + }, + "dev-client": { + "executor": "nx:run-commands", + "options": { + "command": "bun run dev:client" + } + }, + "dev-worker": { + "executor": "nx:run-commands", + "options": { + "command": "bun run dev:worker" + } + }, + "build-client-web": { + "executor": "nx:run-commands", + "options": { + "command": "bun run build:client:web" + } + }, + "build-mcp-apps": { + "executor": "nx:run-commands", + "options": { + "command": "bun run build:mcp-apps" + } + }, + "build-client": { + "executor": "nx:run-commands", + "options": { + "command": "bun run build:client" + } + }, + "build": { + "executor": "nx:run-commands", + "options": { + "command": "bun run build" + } + }, + "deploy": { + "executor": "nx:run-commands", + "options": { + "command": "bun run deploy" + } + }, + "migrate-local": { + "executor": "nx:run-commands", + "options": { + "command": "bun run migrate:local" + } + }, + "migrate-e2e": { + "executor": "nx:run-commands", + "options": { + "command": "bun run migrate:e2e" + } + }, + "preview": { + "executor": "nx:run-commands", + "options": { + "command": "bun run preview" + } + }, + "preview-e2e": { + "executor": "nx:run-commands", + "options": { + "command": "bun run preview:e2e" + } + }, + "generate-types": { + "executor": "nx:run-commands", + "options": { + "command": "bun run generate-types" + } + } + }, + "tags": ["scope:worker"] +} diff --git a/worker/ai-runtime.test.ts b/packages/worker/src/ai-runtime.test.ts similarity index 100% rename from worker/ai-runtime.test.ts rename to packages/worker/src/ai-runtime.test.ts diff --git a/worker/ai-runtime.ts b/packages/worker/src/ai-runtime.ts similarity index 93% rename from worker/ai-runtime.ts rename to packages/worker/src/ai-runtime.ts index 0ed076d807..75aec20cb6 100644 --- a/worker/ai-runtime.ts +++ b/packages/worker/src/ai-runtime.ts @@ -6,9 +6,12 @@ import { type UIMessage, } from 'ai' import { createWorkersAI } from 'workers-ai-provider' -import { getRemoteAiLocalDevCredentialsError } from '#shared/ai-env-validation.ts' -import { type AiMode } from '#shared/chat.ts' -import { buildMockAiScenario, type MockAiResponse } from '#shared/mock-ai.ts' +import { getRemoteAiLocalDevCredentialsError } from '@kody-internal/shared/ai-env-validation.ts' +import { type AiMode } from '@kody-internal/shared/chat.ts' +import { + buildMockAiScenario, + type MockAiResponse, +} from '@kody-internal/shared/mock-ai.ts' const defaultModel = '@cf/zai-org/glm-4.7-flash' diff --git a/worker/capability-maintenance.ts b/packages/worker/src/capability-maintenance.ts similarity index 85% rename from worker/capability-maintenance.ts rename to packages/worker/src/capability-maintenance.ts index dcf66a6500..1cf3215f00 100644 --- a/worker/capability-maintenance.ts +++ b/packages/worker/src/capability-maintenance.ts @@ -1,5 +1,5 @@ -import { capabilitySpecs } from '#mcp/capabilities/registry.ts' -import { reindexCapabilityVectors } from '#mcp/capabilities/capability-reindex.ts' +import { capabilitySpecs } from './mcp/capabilities/registry.ts' +import { reindexCapabilityVectors } from './mcp/capabilities/capability-reindex.ts' export async function handleCapabilityReindexRequest( request: Request, diff --git a/worker/chat-agent-routing.ts b/packages/worker/src/chat-agent-routing.ts similarity index 92% rename from worker/chat-agent-routing.ts rename to packages/worker/src/chat-agent-routing.ts index 18c7fe75d0..680d282d88 100644 --- a/worker/chat-agent-routing.ts +++ b/packages/worker/src/chat-agent-routing.ts @@ -1,7 +1,7 @@ import { getAgentByName, routeAgentRequest } from 'agents' -import { readAuthenticatedAppUser } from '#server/authenticated-user.ts' -import { createChatThreadsStore } from '#server/chat-threads.ts' -import { chatAgentBasePath } from '#shared/chat-routes.ts' +import { readAuthenticatedAppUser } from '../../../server/authenticated-user.ts' +import { createChatThreadsStore } from '../../../server/chat-threads.ts' +import { chatAgentBasePath } from '@kody-internal/shared/chat-routes.ts' function createJsonResponse(data: unknown, init?: ResponseInit) { return new Response(JSON.stringify(data), { diff --git a/worker/chat-agent.ts b/packages/worker/src/chat-agent.ts similarity index 97% rename from worker/chat-agent.ts rename to packages/worker/src/chat-agent.ts index 26493eac04..ae8ed23648 100644 --- a/worker/chat-agent.ts +++ b/packages/worker/src/chat-agent.ts @@ -1,15 +1,15 @@ import * as Sentry from '@sentry/cloudflare' import { AIChatAgent } from '@cloudflare/ai-chat' -import { buildSentryOptions } from '#sentry/cloudflare-options.ts' +import { buildSentryOptions } from '../../../sentry/cloudflare-options.ts' import { type StreamTextOnFinishCallback, type ToolSet, type UIMessage, } from 'ai' import { type Connection, type ConnectionContext } from 'agents' -import { createMcpCallerContext } from '#mcp/context.ts' -import { readAuthenticatedAppUser } from '#server/authenticated-user.ts' -import { createChatThreadsStore } from '#server/chat-threads.ts' +import { createMcpCallerContext } from './mcp/context.ts' +import { readAuthenticatedAppUser } from '../../../server/authenticated-user.ts' +import { createChatThreadsStore } from '../../../server/chat-threads.ts' import { createAiRuntime, type AiRuntimeResult } from './ai-runtime.ts' function buildSystemPrompt() { diff --git a/worker/d1-data-table-adapter.ts b/packages/worker/src/d1-data-table-adapter.ts similarity index 100% rename from worker/d1-data-table-adapter.ts rename to packages/worker/src/d1-data-table-adapter.ts diff --git a/worker/db.ts b/packages/worker/src/db.ts similarity index 100% rename from worker/db.ts rename to packages/worker/src/db.ts diff --git a/worker/index.ts b/packages/worker/src/index.ts similarity index 94% rename from worker/index.ts rename to packages/worker/src/index.ts index e9543e408e..941d11bb24 100644 --- a/worker/index.ts +++ b/packages/worker/src/index.ts @@ -1,10 +1,10 @@ import * as Sentry from '@sentry/cloudflare' import { OAuthProvider } from '@cloudflare/workers-oauth-provider' -import { getWorkerSentryOptions } from '#sentry/cloudflare-options.ts' -import { ChatAgent } from '#worker/chat-agent.ts' -import { MCP } from '#mcp/index.ts' -import { chatAgentBasePath } from '#shared/chat-routes.ts' -import { handleRequest } from '#server/handler.ts' +import { getWorkerSentryOptions } from '../../../sentry/cloudflare-options.ts' +import { ChatAgent } from './chat-agent.ts' +import { MCP } from './mcp/index.ts' +import { chatAgentBasePath } from '@kody-internal/shared/chat-routes.ts' +import { handleRequest } from '../../../server/handler.ts' import { handleChatAgentRequest } from './chat-agent-routing.ts' import { apiHandler, @@ -106,7 +106,7 @@ const appHandler = withCors({ (request.method === 'GET' || request.method === 'HEAD') ) { const { renderCalculatorUiEntryPoint } = - await import('#mcp/apps/calculator-ui-entry-point.ts') + await import('./mcp/apps/calculator-ui-entry-point.ts') const baseUrl = new URL('/', url.origin) const html = renderCalculatorUiEntryPoint(baseUrl) return new Response(html, { diff --git a/worker/mcp-auth.test.ts b/packages/worker/src/mcp-auth.test.ts similarity index 100% rename from worker/mcp-auth.test.ts rename to packages/worker/src/mcp-auth.test.ts diff --git a/worker/mcp-auth.ts b/packages/worker/src/mcp-auth.ts similarity index 97% rename from worker/mcp-auth.ts rename to packages/worker/src/mcp-auth.ts index af34465814..9f2aa1d06b 100644 --- a/worker/mcp-auth.ts +++ b/packages/worker/src/mcp-auth.ts @@ -2,7 +2,7 @@ import { type OAuthHelpers, type TokenSummary, } from '@cloudflare/workers-oauth-provider' -import { createMcpCallerContext, type McpServerProps } from '#mcp/context.ts' +import { createMcpCallerContext, type McpServerProps } from './mcp/context.ts' import { oauthScopes } from './oauth-handlers.ts' export const mcpResourcePath = '/mcp' diff --git a/mcp/apps/calculator-ui-entry-point.ts b/packages/worker/src/mcp/apps/calculator-ui-entry-point.ts similarity index 100% rename from mcp/apps/calculator-ui-entry-point.ts rename to packages/worker/src/mcp/apps/calculator-ui-entry-point.ts diff --git a/mcp/capabilities/build-capability-registry.test.ts b/packages/worker/src/mcp/capabilities/build-capability-registry.test.ts similarity index 100% rename from mcp/capabilities/build-capability-registry.test.ts rename to packages/worker/src/mcp/capabilities/build-capability-registry.test.ts diff --git a/mcp/capabilities/build-capability-registry.ts b/packages/worker/src/mcp/capabilities/build-capability-registry.ts similarity index 100% rename from mcp/capabilities/build-capability-registry.ts rename to packages/worker/src/mcp/capabilities/build-capability-registry.ts diff --git a/mcp/capabilities/builtin-domains.ts b/packages/worker/src/mcp/capabilities/builtin-domains.ts similarity index 100% rename from mcp/capabilities/builtin-domains.ts rename to packages/worker/src/mcp/capabilities/builtin-domains.ts diff --git a/mcp/capabilities/capability-reindex.ts b/packages/worker/src/mcp/capabilities/capability-reindex.ts similarity index 100% rename from mcp/capabilities/capability-reindex.ts rename to packages/worker/src/mcp/capabilities/capability-reindex.ts diff --git a/mcp/capabilities/capability-search.test.ts b/packages/worker/src/mcp/capabilities/capability-search.test.ts similarity index 100% rename from mcp/capabilities/capability-search.test.ts rename to packages/worker/src/mcp/capabilities/capability-search.test.ts diff --git a/mcp/capabilities/capability-search.ts b/packages/worker/src/mcp/capabilities/capability-search.ts similarity index 100% rename from mcp/capabilities/capability-search.ts rename to packages/worker/src/mcp/capabilities/capability-search.ts diff --git a/mcp/capabilities/coding/coding-capabilities.test.ts b/packages/worker/src/mcp/capabilities/coding/coding-capabilities.test.ts similarity index 98% rename from mcp/capabilities/coding/coding-capabilities.test.ts rename to packages/worker/src/mcp/capabilities/coding/coding-capabilities.test.ts index 07539eb6af..fe2a5bdfb9 100644 --- a/mcp/capabilities/coding/coding-capabilities.test.ts +++ b/packages/worker/src/mcp/capabilities/coding/coding-capabilities.test.ts @@ -6,8 +6,8 @@ import { cursorCloudRestCapability } from './cursor-cloud-rest.ts' import { githubGraphqlCapability } from './github-graphql.ts' import { githubRestCapability } from './github-rest.ts' -const workerConfig = 'mock-servers/github/wrangler.jsonc' -const cursorWorkerConfig = 'mock-servers/cursor/wrangler.jsonc' +const workerConfig = 'packages/mock-servers/github/wrangler.jsonc' +const cursorWorkerConfig = 'packages/mock-servers/cursor/wrangler.jsonc' const bunBin = process.execPath const projectRoot = process.cwd() const timeoutMs = 60_000 diff --git a/mcp/capabilities/coding/cursor-cloud-agent-docs.ts b/packages/worker/src/mcp/capabilities/coding/cursor-cloud-agent-docs.ts similarity index 100% rename from mcp/capabilities/coding/cursor-cloud-agent-docs.ts rename to packages/worker/src/mcp/capabilities/coding/cursor-cloud-agent-docs.ts diff --git a/mcp/capabilities/coding/cursor-cloud-rest.ts b/packages/worker/src/mcp/capabilities/coding/cursor-cloud-rest.ts similarity index 100% rename from mcp/capabilities/coding/cursor-cloud-rest.ts rename to packages/worker/src/mcp/capabilities/coding/cursor-cloud-rest.ts diff --git a/mcp/capabilities/coding/domain.ts b/packages/worker/src/mcp/capabilities/coding/domain.ts similarity index 100% rename from mcp/capabilities/coding/domain.ts rename to packages/worker/src/mcp/capabilities/coding/domain.ts diff --git a/mcp/capabilities/coding/fetch-markdown-doc.ts b/packages/worker/src/mcp/capabilities/coding/fetch-markdown-doc.ts similarity index 100% rename from mcp/capabilities/coding/fetch-markdown-doc.ts rename to packages/worker/src/mcp/capabilities/coding/fetch-markdown-doc.ts diff --git a/mcp/capabilities/coding/github-docs-path.ts b/packages/worker/src/mcp/capabilities/coding/github-docs-path.ts similarity index 100% rename from mcp/capabilities/coding/github-docs-path.ts rename to packages/worker/src/mcp/capabilities/coding/github-docs-path.ts diff --git a/mcp/capabilities/coding/github-graphql-api-docs.ts b/packages/worker/src/mcp/capabilities/coding/github-graphql-api-docs.ts similarity index 100% rename from mcp/capabilities/coding/github-graphql-api-docs.ts rename to packages/worker/src/mcp/capabilities/coding/github-graphql-api-docs.ts diff --git a/mcp/capabilities/coding/github-graphql.ts b/packages/worker/src/mcp/capabilities/coding/github-graphql.ts similarity index 100% rename from mcp/capabilities/coding/github-graphql.ts rename to packages/worker/src/mcp/capabilities/coding/github-graphql.ts diff --git a/mcp/capabilities/coding/github-rest-api-docs.ts b/packages/worker/src/mcp/capabilities/coding/github-rest-api-docs.ts similarity index 100% rename from mcp/capabilities/coding/github-rest-api-docs.ts rename to packages/worker/src/mcp/capabilities/coding/github-rest-api-docs.ts diff --git a/mcp/capabilities/coding/github-rest.ts b/packages/worker/src/mcp/capabilities/coding/github-rest.ts similarity index 100% rename from mcp/capabilities/coding/github-rest.ts rename to packages/worker/src/mcp/capabilities/coding/github-rest.ts diff --git a/mcp/capabilities/coding/index.ts b/packages/worker/src/mcp/capabilities/coding/index.ts similarity index 100% rename from mcp/capabilities/coding/index.ts rename to packages/worker/src/mcp/capabilities/coding/index.ts diff --git a/mcp/capabilities/define-capability.ts b/packages/worker/src/mcp/capabilities/define-capability.ts similarity index 100% rename from mcp/capabilities/define-capability.ts rename to packages/worker/src/mcp/capabilities/define-capability.ts diff --git a/mcp/capabilities/define-domain-capability.ts b/packages/worker/src/mcp/capabilities/define-domain-capability.ts similarity index 100% rename from mcp/capabilities/define-domain-capability.ts rename to packages/worker/src/mcp/capabilities/define-domain-capability.ts diff --git a/mcp/capabilities/define-domain.ts b/packages/worker/src/mcp/capabilities/define-domain.ts similarity index 100% rename from mcp/capabilities/define-domain.ts rename to packages/worker/src/mcp/capabilities/define-domain.ts diff --git a/mcp/capabilities/domain-metadata.ts b/packages/worker/src/mcp/capabilities/domain-metadata.ts similarity index 100% rename from mcp/capabilities/domain-metadata.ts rename to packages/worker/src/mcp/capabilities/domain-metadata.ts diff --git a/mcp/capabilities/math/do-math.ts b/packages/worker/src/mcp/capabilities/math/do-math.ts similarity index 100% rename from mcp/capabilities/math/do-math.ts rename to packages/worker/src/mcp/capabilities/math/do-math.ts diff --git a/mcp/capabilities/math/domain.ts b/packages/worker/src/mcp/capabilities/math/domain.ts similarity index 100% rename from mcp/capabilities/math/domain.ts rename to packages/worker/src/mcp/capabilities/math/domain.ts diff --git a/mcp/capabilities/math/index.ts b/packages/worker/src/mcp/capabilities/math/index.ts similarity index 100% rename from mcp/capabilities/math/index.ts rename to packages/worker/src/mcp/capabilities/math/index.ts diff --git a/mcp/capabilities/meta/domain.ts b/packages/worker/src/mcp/capabilities/meta/domain.ts similarity index 100% rename from mcp/capabilities/meta/domain.ts rename to packages/worker/src/mcp/capabilities/meta/domain.ts diff --git a/mcp/capabilities/meta/meta-delete-skill.ts b/packages/worker/src/mcp/capabilities/meta/meta-delete-skill.ts similarity index 100% rename from mcp/capabilities/meta/meta-delete-skill.ts rename to packages/worker/src/mcp/capabilities/meta/meta-delete-skill.ts diff --git a/mcp/capabilities/meta/meta-get-skill.ts b/packages/worker/src/mcp/capabilities/meta/meta-get-skill.ts similarity index 100% rename from mcp/capabilities/meta/meta-get-skill.ts rename to packages/worker/src/mcp/capabilities/meta/meta-get-skill.ts diff --git a/mcp/capabilities/meta/meta-run-skill.ts b/packages/worker/src/mcp/capabilities/meta/meta-run-skill.ts similarity index 86% rename from mcp/capabilities/meta/meta-run-skill.ts rename to packages/worker/src/mcp/capabilities/meta/meta-run-skill.ts index 960f04f2e7..e91ab168a2 100644 --- a/mcp/capabilities/meta/meta-run-skill.ts +++ b/packages/worker/src/mcp/capabilities/meta/meta-run-skill.ts @@ -33,7 +33,7 @@ export const metaRunSkillCapability = defineDomainCapability( { name: 'meta_run_skill', description: - "Execute a saved skill's codemode in the same sandbox as the MCP execute tool. When the skill defines parameters, pass them in params; the code receives them via the params variable or the first function argument. Example: meta_run_skill({ \"skill_id\": \"\", \"params\": { \"owner\": \"kentcdodds\", \"days\": 3 } }). On failure, the structured result includes a hint for updating the skill (meta_update_skill).", + 'Execute a saved skill\'s codemode in the same sandbox as the MCP execute tool. When the skill defines parameters, pass them in params; the code receives them via the params variable or the first function argument. Example: meta_run_skill({ "skill_id": "", "params": { "owner": "kentcdodds", "days": 3 } }). On failure, the structured result includes a hint for updating the skill (meta_update_skill).', keywords: ['skill', 'run', 'execute'], readOnly: false, idempotent: false, diff --git a/mcp/capabilities/meta/meta-save-skill.ts b/packages/worker/src/mcp/capabilities/meta/meta-save-skill.ts similarity index 100% rename from mcp/capabilities/meta/meta-save-skill.ts rename to packages/worker/src/mcp/capabilities/meta/meta-save-skill.ts diff --git a/mcp/capabilities/meta/meta-update-skill.ts b/packages/worker/src/mcp/capabilities/meta/meta-update-skill.ts similarity index 100% rename from mcp/capabilities/meta/meta-update-skill.ts rename to packages/worker/src/mcp/capabilities/meta/meta-update-skill.ts diff --git a/mcp/capabilities/meta/require-user.ts b/packages/worker/src/mcp/capabilities/meta/require-user.ts similarity index 72% rename from mcp/capabilities/meta/require-user.ts rename to packages/worker/src/mcp/capabilities/meta/require-user.ts index 6ab2ba3d08..ffd27c9ebe 100644 --- a/mcp/capabilities/meta/require-user.ts +++ b/packages/worker/src/mcp/capabilities/meta/require-user.ts @@ -1,4 +1,4 @@ -import { type McpCallerContext } from '#shared/chat.ts' +import { type McpCallerContext } from '@kody-internal/shared/chat.ts' export function requireMcpUser(context: McpCallerContext) { if (!context.user) { diff --git a/mcp/capabilities/registry.ts b/packages/worker/src/mcp/capabilities/registry.ts similarity index 100% rename from mcp/capabilities/registry.ts rename to packages/worker/src/mcp/capabilities/registry.ts diff --git a/mcp/capabilities/types.ts b/packages/worker/src/mcp/capabilities/types.ts similarity index 97% rename from mcp/capabilities/types.ts rename to packages/worker/src/mcp/capabilities/types.ts index d586a028c4..f0f40870ba 100644 --- a/mcp/capabilities/types.ts +++ b/packages/worker/src/mcp/capabilities/types.ts @@ -1,7 +1,7 @@ import { type JsonSchemaToolDescriptor } from '@cloudflare/codemode' import { type ZodType } from 'zod' import { type CapabilityDomain } from './domain-metadata.ts' -import { type McpCallerContext } from '#shared/chat.ts' +import { type McpCallerContext } from '@kody-internal/shared/chat.ts' export type CapabilityContext = { env: Env diff --git a/mcp/capabilities/unified-search.test.ts b/packages/worker/src/mcp/capabilities/unified-search.test.ts similarity index 100% rename from mcp/capabilities/unified-search.test.ts rename to packages/worker/src/mcp/capabilities/unified-search.test.ts diff --git a/mcp/capabilities/unified-search.ts b/packages/worker/src/mcp/capabilities/unified-search.ts similarity index 100% rename from mcp/capabilities/unified-search.ts rename to packages/worker/src/mcp/capabilities/unified-search.ts diff --git a/mcp/context.test.ts b/packages/worker/src/mcp/context.test.ts similarity index 100% rename from mcp/context.test.ts rename to packages/worker/src/mcp/context.test.ts diff --git a/mcp/context.ts b/packages/worker/src/mcp/context.ts similarity index 94% rename from mcp/context.ts rename to packages/worker/src/mcp/context.ts index 494bf33654..93c8103a6f 100644 --- a/mcp/context.ts +++ b/packages/worker/src/mcp/context.ts @@ -3,7 +3,7 @@ import { mcpCallerContextSchema, type McpCallerContext, type McpUserContext, -} from '#shared/chat.ts' +} from '@kody-internal/shared/chat.ts' export type McpServerProps = McpCallerContext diff --git a/mcp/cursor/cursor-cloud-client.test.ts b/packages/worker/src/mcp/cursor/cursor-cloud-client.test.ts similarity index 98% rename from mcp/cursor/cursor-cloud-client.test.ts rename to packages/worker/src/mcp/cursor/cursor-cloud-client.test.ts index bd3b9bb0d0..54313a22a8 100644 --- a/mcp/cursor/cursor-cloud-client.test.ts +++ b/packages/worker/src/mcp/cursor/cursor-cloud-client.test.ts @@ -7,7 +7,7 @@ import { createCursorCloudClient, } from './cursor-cloud-client.ts' -const workerConfig = 'mock-servers/cursor/wrangler.jsonc' +const workerConfig = 'packages/mock-servers/cursor/wrangler.jsonc' const bunBin = process.execPath const projectRoot = process.cwd() const timeoutMs = 60_000 diff --git a/mcp/cursor/cursor-cloud-client.ts b/packages/worker/src/mcp/cursor/cursor-cloud-client.ts similarity index 100% rename from mcp/cursor/cursor-cloud-client.ts rename to packages/worker/src/mcp/cursor/cursor-cloud-client.ts diff --git a/mcp/executor.ts b/packages/worker/src/mcp/executor.ts similarity index 100% rename from mcp/executor.ts rename to packages/worker/src/mcp/executor.ts diff --git a/mcp/github/github-client.test.ts b/packages/worker/src/mcp/github/github-client.test.ts similarity index 98% rename from mcp/github/github-client.test.ts rename to packages/worker/src/mcp/github/github-client.test.ts index 6ddcb517e3..93f57bca86 100644 --- a/mcp/github/github-client.test.ts +++ b/packages/worker/src/mcp/github/github-client.test.ts @@ -7,7 +7,7 @@ import { GitHubRestClient, } from './github-rest-client.ts' -const workerConfig = 'mock-servers/github/wrangler.jsonc' +const workerConfig = 'packages/mock-servers/github/wrangler.jsonc' const bunBin = process.execPath const projectRoot = process.cwd() const timeoutMs = 60_000 diff --git a/mcp/github/github-graphql-client.test.ts b/packages/worker/src/mcp/github/github-graphql-client.test.ts similarity index 98% rename from mcp/github/github-graphql-client.test.ts rename to packages/worker/src/mcp/github/github-graphql-client.test.ts index ed877d1fbf..64f3da7365 100644 --- a/mcp/github/github-graphql-client.test.ts +++ b/packages/worker/src/mcp/github/github-graphql-client.test.ts @@ -7,7 +7,7 @@ import { GitHubGraphqlClient, } from './github-graphql-client.ts' -const workerConfig = 'mock-servers/github/wrangler.jsonc' +const workerConfig = 'packages/mock-servers/github/wrangler.jsonc' const bunBin = process.execPath const projectRoot = process.cwd() const timeoutMs = 60_000 diff --git a/mcp/github/github-graphql-client.ts b/packages/worker/src/mcp/github/github-graphql-client.ts similarity index 100% rename from mcp/github/github-graphql-client.ts rename to packages/worker/src/mcp/github/github-graphql-client.ts diff --git a/mcp/github/github-rest-client.ts b/packages/worker/src/mcp/github/github-rest-client.ts similarity index 100% rename from mcp/github/github-rest-client.ts rename to packages/worker/src/mcp/github/github-rest-client.ts diff --git a/mcp/index.ts b/packages/worker/src/mcp/index.ts similarity index 98% rename from mcp/index.ts rename to packages/worker/src/mcp/index.ts index 889283748f..12306e9bbd 100644 --- a/mcp/index.ts +++ b/packages/worker/src/mcp/index.ts @@ -4,7 +4,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/sdk/validation/cfworker-provider.js' import { McpAgent } from 'agents/mcp' import { capabilityDomains } from '#mcp/capabilities/registry.ts' -import { buildSentryOptions } from '#sentry/cloudflare-options.ts' +import { buildSentryOptions } from '../../../../sentry/cloudflare-options.ts' import { parseMcpCallerContext, type McpServerProps } from './context.ts' import { registerResources } from './register-resources.ts' import { registerTools } from './register-tools.ts' diff --git a/mcp/mcp-server-e2e.test.ts b/packages/worker/src/mcp/mcp-server-e2e.test.ts similarity index 97% rename from mcp/mcp-server-e2e.test.ts rename to packages/worker/src/mcp/mcp-server-e2e.test.ts index 8fead466ef..a987287229 100644 --- a/mcp/mcp-server-e2e.test.ts +++ b/packages/worker/src/mcp/mcp-server-e2e.test.ts @@ -18,12 +18,14 @@ import { mkdtemp, readdir, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import { fileURLToPath } from 'node:url' +import { syncDotenvForConfig } from '../../../../tools/wrangler-dotenv-sync.ts' -const projectRoot = fileURLToPath(new URL('..', import.meta.url)) +const projectRoot = fileURLToPath(new URL('../../../../', import.meta.url)) const migrationsDir = join(projectRoot, 'migrations') const bunBin = process.execPath const defaultTimeoutMs = 60_000 const calculatorUiResourceUri = 'ui://calculator-app/entry-point.html' +const workerConfig = 'packages/worker/wrangler.jsonc' const primaryUserEmail = 'me@kentcdodds.com' const primaryUserPassword = 'iliketwix' @@ -71,8 +73,12 @@ function escapeSql(value: string) { } async function runWrangler(args: Array) { + syncDotenvForConfig({ + workspaceRoot: projectRoot, + configPath: workerConfig, + }) const proc = Bun.spawn({ - cmd: [bunBin, 'x', 'wrangler', ...args], + cmd: [bunBin, 'x', 'wrangler', '--config', workerConfig, ...args], cwd: projectRoot, stdout: 'pipe', stderr: 'pipe', @@ -260,6 +266,10 @@ async function stopProcess(proc: ReturnType) { } async function startDevServer(persistDir: string) { + syncDotenvForConfig({ + workspaceRoot: projectRoot, + configPath: workerConfig, + }) const port = await getPort({ host: '127.0.0.1' }) const inspectorPortBase = port + 10_000 <= 65_535 ? port + 10_000 : Math.max(1, port - 10_000) @@ -276,6 +286,8 @@ async function startDevServer(persistDir: string) { bunBin, 'x', 'wrangler', + '--config', + workerConfig, 'dev', '--local', '--env', diff --git a/mcp/observability.test.ts b/packages/worker/src/mcp/observability.test.ts similarity index 100% rename from mcp/observability.test.ts rename to packages/worker/src/mcp/observability.test.ts diff --git a/mcp/observability.ts b/packages/worker/src/mcp/observability.ts similarity index 97% rename from mcp/observability.ts rename to packages/worker/src/mcp/observability.ts index 52ba1d9596..3d5c414f21 100644 --- a/mcp/observability.ts +++ b/packages/worker/src/mcp/observability.ts @@ -1,5 +1,5 @@ import * as Sentry from '@sentry/cloudflare' -import { type McpCallerContext } from '#shared/chat.ts' +import { type McpCallerContext } from '@kody-internal/shared/chat.ts' export type McpToolKind = 'search' | 'execute' | 'capability' diff --git a/mcp/register-resources.ts b/packages/worker/src/mcp/register-resources.ts similarity index 100% rename from mcp/register-resources.ts rename to packages/worker/src/mcp/register-resources.ts diff --git a/mcp/register-tools.ts b/packages/worker/src/mcp/register-tools.ts similarity index 100% rename from mcp/register-tools.ts rename to packages/worker/src/mcp/register-tools.ts diff --git a/mcp/resources/calculator-app-resource.ts b/packages/worker/src/mcp/resources/calculator-app-resource.ts similarity index 100% rename from mcp/resources/calculator-app-resource.ts rename to packages/worker/src/mcp/resources/calculator-app-resource.ts diff --git a/mcp/run-codemode-registry.ts b/packages/worker/src/mcp/run-codemode-registry.ts similarity index 93% rename from mcp/run-codemode-registry.ts rename to packages/worker/src/mcp/run-codemode-registry.ts index 25d1630134..447799a0a2 100644 --- a/mcp/run-codemode-registry.ts +++ b/packages/worker/src/mcp/run-codemode-registry.ts @@ -1,4 +1,4 @@ -import { type McpCallerContext } from '#shared/chat.ts' +import { type McpCallerContext } from '@kody-internal/shared/chat.ts' import { buildParameterizedSkillCode } from '#mcp/skills/skill-parameters.ts' export async function buildCodemodeFns( diff --git a/mcp/skills/infer-codemode-capabilities.test.ts b/packages/worker/src/mcp/skills/infer-codemode-capabilities.test.ts similarity index 100% rename from mcp/skills/infer-codemode-capabilities.test.ts rename to packages/worker/src/mcp/skills/infer-codemode-capabilities.test.ts diff --git a/mcp/skills/infer-codemode-capabilities.ts b/packages/worker/src/mcp/skills/infer-codemode-capabilities.ts similarity index 100% rename from mcp/skills/infer-codemode-capabilities.ts rename to packages/worker/src/mcp/skills/infer-codemode-capabilities.ts diff --git a/mcp/skills/mcp-skills-repo.ts b/packages/worker/src/mcp/skills/mcp-skills-repo.ts similarity index 100% rename from mcp/skills/mcp-skills-repo.ts rename to packages/worker/src/mcp/skills/mcp-skills-repo.ts diff --git a/mcp/skills/mcp-skills-types.ts b/packages/worker/src/mcp/skills/mcp-skills-types.ts similarity index 100% rename from mcp/skills/mcp-skills-types.ts rename to packages/worker/src/mcp/skills/mcp-skills-types.ts diff --git a/mcp/skills/skill-embed-and-flags.test.ts b/packages/worker/src/mcp/skills/skill-embed-and-flags.test.ts similarity index 100% rename from mcp/skills/skill-embed-and-flags.test.ts rename to packages/worker/src/mcp/skills/skill-embed-and-flags.test.ts diff --git a/mcp/skills/skill-embed-and-flags.ts b/packages/worker/src/mcp/skills/skill-embed-and-flags.ts similarity index 100% rename from mcp/skills/skill-embed-and-flags.ts rename to packages/worker/src/mcp/skills/skill-embed-and-flags.ts diff --git a/mcp/skills/skill-mutation.ts b/packages/worker/src/mcp/skills/skill-mutation.ts similarity index 100% rename from mcp/skills/skill-mutation.ts rename to packages/worker/src/mcp/skills/skill-mutation.ts diff --git a/mcp/skills/skill-parameters.test.ts b/packages/worker/src/mcp/skills/skill-parameters.test.ts similarity index 100% rename from mcp/skills/skill-parameters.test.ts rename to packages/worker/src/mcp/skills/skill-parameters.test.ts diff --git a/mcp/skills/skill-parameters.ts b/packages/worker/src/mcp/skills/skill-parameters.ts similarity index 100% rename from mcp/skills/skill-parameters.ts rename to packages/worker/src/mcp/skills/skill-parameters.ts diff --git a/mcp/skills/skill-vectorize.ts b/packages/worker/src/mcp/skills/skill-vectorize.ts similarity index 100% rename from mcp/skills/skill-vectorize.ts rename to packages/worker/src/mcp/skills/skill-vectorize.ts diff --git a/mcp/tools/execute.ts b/packages/worker/src/mcp/tools/execute.ts similarity index 100% rename from mcp/tools/execute.ts rename to packages/worker/src/mcp/tools/execute.ts diff --git a/mcp/tools/open-calculator-ui.ts b/packages/worker/src/mcp/tools/open-calculator-ui.ts similarity index 100% rename from mcp/tools/open-calculator-ui.ts rename to packages/worker/src/mcp/tools/open-calculator-ui.ts diff --git a/mcp/tools/search.ts b/packages/worker/src/mcp/tools/search.ts similarity index 100% rename from mcp/tools/search.ts rename to packages/worker/src/mcp/tools/search.ts diff --git a/worker/oauth-handlers.test.ts b/packages/worker/src/oauth-handlers.test.ts similarity index 97% rename from worker/oauth-handlers.test.ts rename to packages/worker/src/oauth-handlers.test.ts index fac86afc55..b6e10a15b5 100644 --- a/worker/oauth-handlers.test.ts +++ b/packages/worker/src/oauth-handlers.test.ts @@ -6,8 +6,11 @@ import { type CompleteAuthorizationOptions, type OAuthHelpers, } from '@cloudflare/workers-oauth-provider' -import { createAuthCookie, setAuthSessionSecret } from '#server/auth-session.ts' -import { createPasswordHash } from '#server/password-hash.ts' +import { + createAuthCookie, + setAuthSessionSecret, +} from '../../../server/auth-session.ts' +import { createPasswordHash } from '../../../server/password-hash.ts' import { handleAuthorizeInfo, handleAuthorizeRequest, diff --git a/worker/oauth-handlers.ts b/packages/worker/src/oauth-handlers.ts similarity index 95% rename from worker/oauth-handlers.ts rename to packages/worker/src/oauth-handlers.ts index cd150a7c8b..950b42c056 100644 --- a/worker/oauth-handlers.ts +++ b/packages/worker/src/oauth-handlers.ts @@ -2,16 +2,16 @@ import { type AuthRequest, type OAuthHelpers, } from '@cloudflare/workers-oauth-provider' -import { getRequestIp, logAuditEvent } from '#server/audit-log.ts' +import { getRequestIp, logAuditEvent } from '../../../server/audit-log.ts' import { readAuthSessionResult, setAuthSessionSecret, -} from '#server/auth-session.ts' -import { getEnv } from '#server/env.ts' -import { toHex } from '#server/hex.ts' -import { verifyPassword } from '#server/password-hash.ts' -import { Layout } from '#server/layout.ts' -import { render } from '#server/render.ts' +} from '../../../server/auth-session.ts' +import { getEnv } from '../../../server/env.ts' +import { toHex } from '../../../server/hex.ts' +import { verifyPassword } from '../../../server/password-hash.ts' +import { Layout } from '../../../server/layout.ts' +import { render } from '../../../server/render.ts' import { createDb, usersTable } from './db.ts' import { wantsJson } from './utils.ts' diff --git a/worker/utils.ts b/packages/worker/src/utils.ts similarity index 100% rename from worker/utils.ts rename to packages/worker/src/utils.ts diff --git a/wrangler.jsonc b/packages/worker/wrangler.jsonc similarity index 91% rename from wrangler.jsonc rename to packages/worker/wrangler.jsonc index 203b1554ff..a51b5fa4b2 100644 --- a/wrangler.jsonc +++ b/packages/worker/wrangler.jsonc @@ -1,9 +1,9 @@ { - "$schema": "node_modules/wrangler/config-schema.json", + "$schema": "../../node_modules/wrangler/config-schema.json", "name": "kody", "compatibility_date": "2026-01-31", "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"], - "main": "./worker/index.ts", + "main": "./src/index.ts", "upload_source_maps": true, "migrations": [ { @@ -31,7 +31,7 @@ }, ], "assets": { - "directory": "./public", + "directory": "../../public", "binding": "ASSETS", "run_worker_first": ["/mcp-apps/*", "/styles.css"], }, @@ -52,7 +52,7 @@ "binding": "APP_DB", "database_name": "kody", "database_id": "c64eb497-a93d-4af4-bfb7-62beda9552b6", - "migrations_dir": "migrations", + "migrations_dir": "../../migrations", }, ], "kv_namespaces": [ @@ -85,7 +85,7 @@ }, ], "assets": { - "directory": "./public", + "directory": "../../public", "binding": "ASSETS", "run_worker_first": ["/mcp-apps/*", "/styles.css"], }, @@ -106,7 +106,7 @@ "binding": "APP_DB", "database_name": "kody-preview", "database_id": "0e2f1e31-b7c4-42bc-8133-04627230a25f", - "migrations_dir": "migrations", + "migrations_dir": "../../migrations", }, ], "kv_namespaces": [ @@ -139,7 +139,7 @@ }, ], "assets": { - "directory": "./public", + "directory": "../../public", "binding": "ASSETS", "run_worker_first": ["/mcp-apps/*", "/styles.css"], }, @@ -160,7 +160,7 @@ "binding": "APP_DB", "database_name": "kody-preview", "database_id": "0e2f1e31-b7c4-42bc-8133-04627230a25f", - "migrations_dir": "migrations", + "migrations_dir": "../../migrations", }, ], "kv_namespaces": [ diff --git a/server/authenticated-user.ts b/server/authenticated-user.ts index d9469a675d..c4f8a10ea9 100644 --- a/server/authenticated-user.ts +++ b/server/authenticated-user.ts @@ -3,7 +3,7 @@ import { setAuthSessionSecret, } from '#server/auth-session.ts' import { getEnv } from '#server/env.ts' -import { type McpUserContext } from '#shared/chat.ts' +import { type McpUserContext } from '@kody-internal/shared/chat.ts' export type AuthenticatedAppUser = { sessionUserId: string diff --git a/server/chat-threads.ts b/server/chat-threads.ts index 0d93a97022..074c201b02 100644 --- a/server/chat-threads.ts +++ b/server/chat-threads.ts @@ -1,5 +1,5 @@ import { chatThreadsTable, createDb } from '#worker/db.ts' -import { type ChatThreadSummary } from '#shared/chat.ts' +import { type ChatThreadSummary } from '@kody-internal/shared/chat.ts' function toIsoTimestamp(date = new Date()) { return date.toISOString() diff --git a/server/email/resend.ts b/server/email/resend.ts index 2bde4a1682..812e2534c6 100644 --- a/server/email/resend.ts +++ b/server/email/resend.ts @@ -1,5 +1,8 @@ import { parseSafe } from 'remix/data-schema' -import { resendEmailSchema, type ResendEmail } from '#shared/resend-email.ts' +import { + resendEmailSchema, + type ResendEmail, +} from '@kody-internal/shared/resend-email.ts' type ResendClientConfig = { apiBaseUrl: string diff --git a/server/password-hash.ts b/server/password-hash.ts index ea5611b5db..ad9883fc5c 100644 --- a/server/password-hash.ts +++ b/server/password-hash.ts @@ -1 +1,4 @@ -export { createPasswordHash, verifyPassword } from '#shared/password-hash.ts' +export { + createPasswordHash, + verifyPassword, +} from '@kody-internal/shared/password-hash.ts' diff --git a/tools/ci/preview-resources.ts b/tools/ci/preview-resources.ts index 7c2d7492bb..e2cd6bb55f 100644 --- a/tools/ci/preview-resources.ts +++ b/tools/ci/preview-resources.ts @@ -30,8 +30,8 @@ function parseArgs(argv: Array): { const options: CliOptions = { workerName: '', - wranglerConfigPath: 'wrangler.jsonc', - outConfigPath: 'wrangler-preview.generated.json', + wranglerConfigPath: 'packages/worker/wrangler.jsonc', + outConfigPath: 'packages/worker/wrangler-preview.generated.json', dryRun: false, d1Location: undefined, } diff --git a/tools/ci/production-resources.ts b/tools/ci/production-resources.ts index 61e3a4a640..e6bee50fa8 100644 --- a/tools/ci/production-resources.ts +++ b/tools/ci/production-resources.ts @@ -39,8 +39,8 @@ function parseArgs(argv: Array): { } const options: CliOptions = { - wranglerConfigPath: 'wrangler.jsonc', - outConfigPath: 'wrangler-production.generated.json', + wranglerConfigPath: 'packages/worker/wrangler.jsonc', + outConfigPath: 'packages/worker/wrangler-production.generated.json', dryRun: false, d1Location: undefined, kvTitleOverride: undefined, diff --git a/tools/prepare-e2e-env.ts b/tools/prepare-e2e-env.ts index d738133067..ed60c740a2 100644 --- a/tools/prepare-e2e-env.ts +++ b/tools/prepare-e2e-env.ts @@ -1,18 +1,98 @@ -import { copyFileSync, existsSync } from 'node:fs' +import { copyFileSync, existsSync, readFileSync, writeFileSync } from 'node:fs' import { join } from 'node:path' const envPath = join(process.cwd(), '.env') -if (existsSync(envPath)) { +const examplePath = join(process.cwd(), '.env.example') + +function escapeForRegExp(value: string) { + return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +} + +function stripSurroundingQuotes(value: string) { + if ( + (value.startsWith('"') && value.endsWith('"')) || + (value.startsWith("'") && value.endsWith("'")) + ) { + return value.slice(1, -1) + } + return value +} + +function parseDotenvValue(content: string, key: string) { + const keyPattern = new RegExp( + `^\\s*(?:export\\s+)?${escapeForRegExp(key)}\\s*=\\s*(.*)$`, + ) + let matchedValue: string | null = null + + for (const rawLine of content.split(/\r?\n/)) { + const line = rawLine.trim() + if (!line || line.startsWith('#')) continue + + const match = rawLine.match(keyPattern) + if (!match) continue + + matchedValue = stripSurroundingQuotes(match[1]?.trim() ?? '') + } + + return matchedValue +} + +function setDotenvValue(content: string, key: string, value: string) { + const lines = content.split(/\r?\n/) + const keyPattern = new RegExp( + `^(\\s*(?:export\\s+)?${escapeForRegExp(key)}\\s*=\\s*).*$`, + ) + + let lastMatchIndex = -1 + let lastPrefix = `${key}=` + for (const [index, line] of lines.entries()) { + const match = line.match(keyPattern) + if (!match) continue + lastMatchIndex = index + lastPrefix = match[1] ?? lastPrefix + } + + if (lastMatchIndex >= 0) { + lines[lastMatchIndex] = `${lastPrefix}${value}` + return `${lines.join('\n').replace(/\n*$/, '\n')}` + } + + return `${content.replace(/\n*$/, '\n')}${key}=${value}\n` +} + +if (!existsSync(envPath)) { + if (!existsSync(examplePath)) { + console.error('Missing .env.example; cannot prepare E2E environment.') + process.exit(1) + } + copyFileSync(examplePath, envPath) + console.log('Created .env from .env.example for E2E tests.') +} + +const envContents = readFileSync(envPath, 'utf8') +const existingCookieSecret = parseDotenvValue(envContents, 'COOKIE_SECRET') +if (existingCookieSecret && existingCookieSecret.length > 0) { process.exit(0) } -const examplePath = join(process.cwd(), '.env.example') if (!existsSync(examplePath)) { + console.error('Missing .env.example; cannot prepare E2E environment.') + process.exit(1) +} + +const exampleContents = readFileSync(examplePath, 'utf8') +const fallbackCookieSecret = parseDotenvValue(exampleContents, 'COOKIE_SECRET') +if (!fallbackCookieSecret || fallbackCookieSecret.length === 0) { console.error( - 'Missing .env and .env.example; cannot prepare E2E environment.', + 'Missing COOKIE_SECRET in .env.example; cannot prepare E2E env.', ) process.exit(1) } -copyFileSync(examplePath, envPath) -console.log('Created .env from .env.example for E2E tests.') +const nextContents = setDotenvValue( + envContents, + 'COOKIE_SECRET', + fallbackCookieSecret, +) +writeFileSync(envPath, nextContents, 'utf8') +console.log('Backfilled COOKIE_SECRET in .env for E2E tests.') diff --git a/tools/seed-test-data.test.ts b/tools/seed-test-data.test.ts index 91161f085e..4c4bca0432 100644 --- a/tools/seed-test-data.test.ts +++ b/tools/seed-test-data.test.ts @@ -38,7 +38,7 @@ test('parseArgs defaults the Wrangler env to production', () => { test('resolveWranglerEnv infers preview from generated config names', () => { const env = resolveWranglerEnv({ - config: 'wrangler-preview.generated.json', + config: 'packages/worker/wrangler-preview.generated.json', }) expect(env).toBe('preview') diff --git a/tools/seed-test-data.ts b/tools/seed-test-data.ts index 76916a0248..2ac7f9355f 100644 --- a/tools/seed-test-data.ts +++ b/tools/seed-test-data.ts @@ -1,6 +1,6 @@ import { basename } from 'node:path' import { fail, runWrangler } from './ci/resource-utils.ts' -import { createPasswordHash } from '#shared/password-hash.ts' +import { createPasswordHash } from '@kody-internal/shared/password-hash.ts' type CliOptions = { email: string diff --git a/tools/wrangler-dotenv-sync.ts b/tools/wrangler-dotenv-sync.ts new file mode 100644 index 0000000000..ccb14b6e9e --- /dev/null +++ b/tools/wrangler-dotenv-sync.ts @@ -0,0 +1,41 @@ +import { copyFileSync, existsSync, readFileSync } from 'node:fs' +import path from 'node:path' + +function resolveConfigEnvPath(workspaceRoot: string, configPath: string) { + const resolvedConfigPath = path.resolve(workspaceRoot, configPath) + return path.join(path.dirname(resolvedConfigPath), '.env') +} + +export function syncDotenvForConfig(input: { + workspaceRoot: string + configPath: string | undefined + logger?: Pick +}) { + if (!input.configPath) return + + const rootEnvPath = path.join(input.workspaceRoot, '.env') + if (!existsSync(rootEnvPath)) return + + const configEnvPath = resolveConfigEnvPath( + input.workspaceRoot, + input.configPath, + ) + if (path.resolve(configEnvPath) === path.resolve(rootEnvPath)) { + return + } + + if (existsSync(configEnvPath)) { + const rootEnv = readFileSync(rootEnvPath, 'utf8') + const configEnv = readFileSync(configEnvPath, 'utf8') + if (configEnv === rootEnv) { + return + } + + input.logger?.warn( + `Skipping .env sync because "${configEnvPath}" already differs from the root .env.`, + ) + return + } + + copyFileSync(rootEnvPath, configEnvPath) +} diff --git a/types/env-schema.ts b/types/env-schema.ts index d86ab35a55..be2f409dbc 100644 --- a/types/env-schema.ts +++ b/types/env-schema.ts @@ -5,7 +5,7 @@ import { string, type InferOutput, } from 'remix/data-schema' -import { aiModeValues } from '#shared/chat.ts' +import { aiModeValues } from '@kody-internal/shared/chat.ts' const d1DatabaseSchema = createSchema((value, context) => { if (value) { diff --git a/types/tsconfig-client.json b/types/tsconfig-client.json index b9518f9bc5..497b29c6b8 100644 --- a/types/tsconfig-client.json +++ b/types/tsconfig-client.json @@ -9,5 +9,9 @@ "jsx": "react-jsx", "jsxImportSource": "remix/component" }, - "include": ["../client/**/*.ts", "../client/**/*.tsx", "../shared/**/*.ts"] + "include": [ + "../client/**/*.ts", + "../client/**/*.tsx", + "../packages/shared/src/**/*.ts" + ] } diff --git a/types/tsconfig-tools.json b/types/tsconfig-tools.json index a8f1217182..702a3003df 100644 --- a/types/tsconfig-tools.json +++ b/types/tsconfig-tools.json @@ -33,8 +33,8 @@ "../wrangler-env.ts", "../cli.ts", "../docs/post-download.ts", - "../mcp/mcp-server-e2e.test.ts", + "../packages/worker/src/mcp/mcp-server-e2e.test.ts", "../tools/**/*.ts", - "../shared/**/*.ts" + "../packages/shared/src/**/*.ts" ] } diff --git a/types/tsconfig-worker.json b/types/tsconfig-worker.json index b95ff713ab..98b9243b38 100644 --- a/types/tsconfig-worker.json +++ b/types/tsconfig-worker.json @@ -32,12 +32,11 @@ "./env.d.ts", "./env-schema.ts", "./worker-configuration.d.ts", - "../shared/**/*.ts", - "../mock-servers/**/*.ts", + "../packages/shared/src/**/*.ts", + "../packages/mock-servers/**/*.ts", "../sentry/**/*.ts", - "../worker/**/*.ts", - "../server/**/*.ts", - "../mcp/**/*.ts" + "../packages/worker/src/**/*.ts", + "../server/**/*.ts" ], "exclude": [ "**/*.test.ts", diff --git a/types/worker-configuration.d.ts b/types/worker-configuration.d.ts index e2abac1e45..221225f02a 100644 --- a/types/worker-configuration.d.ts +++ b/types/worker-configuration.d.ts @@ -1,9 +1,9 @@ /* eslint-disable */ -// Generated by Wrangler by running `wrangler types ./types/worker-configuration.d.ts --env production` (hash: 0d2ffe162eae54daebbdc53d29e731ad) +// Generated by Wrangler by running `wrangler types ./types/worker-configuration.d.ts --config packages/worker/wrangler.jsonc --env production` (hash: 46efb12294672bd278faed94b25c7b45) // Runtime types generated with workerd@1.20260310.1 2026-01-31 global_fetch_strictly_public,nodejs_compat declare namespace Cloudflare { interface GlobalProps { - mainModule: typeof import("../worker/index"); + mainModule: typeof import("../packages/worker/src/index"); durableNamespaces: "MCP" | "ChatAgent"; } interface Env { @@ -16,17 +16,8 @@ declare namespace Cloudflare { AI_MODE: "remote"; AI_MODEL: "@cf/zai-org/glm-4.7-flash"; SENTRY_ENVIRONMENT: "production"; - COOKIE_SECRET: string; - APP_BASE_URL: string; - RESEND_API_BASE_URL: string; - RESEND_API_KEY: string; - RESEND_FROM_EMAIL: string; - AI_GATEWAY_ID: string; - CLOUDFLARE_API_TOKEN: string; - CLOUDFLARE_ACCOUNT_ID: string; - SENTRY_DSN: string; - MCP_OBJECT: DurableObjectNamespace; - ChatAgent: DurableObjectNamespace; + MCP_OBJECT: DurableObjectNamespace; + ChatAgent: DurableObjectNamespace; } } interface Env extends Cloudflare.Env {} @@ -34,7 +25,7 @@ type StringifyValues> = { [Binding in keyof EnvType]: EnvType[Binding] extends string ? EnvType[Binding] : string; }; declare namespace NodeJS { - interface ProcessEnv extends StringifyValues> {} + interface ProcessEnv extends StringifyValues> {} } // Begin runtime types diff --git a/wrangler-env.ts b/wrangler-env.ts index 494c6f58b3..1c81411b37 100644 --- a/wrangler-env.ts +++ b/wrangler-env.ts @@ -3,16 +3,21 @@ import path from 'node:path' import { setTimeout as delay } from 'node:timers/promises' import net from 'node:net' import getPort from 'get-port' -import { getRemoteAiLocalDevStartupError } from '#shared/ai-env-validation.ts' +import { getRemoteAiLocalDevStartupError } from '@kody-internal/shared/ai-env-validation.ts' +import { syncDotenvForConfig } from '#tools/wrangler-dotenv-sync.ts' const envName = process.env.CLOUDFLARE_ENV ?? 'production' const portWaitTimeoutMs = 5000 const args = process.argv.slice(2) +const defaultWranglerConfigPath = 'packages/worker/wrangler.jsonc' const hasEnvFlag = args.includes('--env') || args.includes('-e') const isDevCommand = args[0] === 'dev' const isLocalDevCommand = isDevCommand && args.includes('--local') const hasPortFlag = args.includes('--port') +const hasConfigFlag = args.some( + (arg) => arg === '--config' || arg.startsWith('--config='), +) const hasInspectorPortFlag = args.some( (arg) => arg === '--inspector-port' || arg.startsWith('--inspector-port='), ) @@ -26,6 +31,13 @@ if (isLocalDevCommand) { const commandArgs = [...args] +if ( + !hasConfigFlag && + existsSync(path.join(process.cwd(), defaultWranglerConfigPath)) +) { + commandArgs.push('--config', defaultWranglerConfigPath) +} + if (!hasEnvFlag) { commandArgs.push('--env', envName) } @@ -82,6 +94,12 @@ if (isDevCommand && !hasInspectorPortFlag) { commandArgs.push('--inspector-port', resolvedInspectorPort) } +syncDotenvForConfig({ + workspaceRoot: process.cwd(), + configPath: getConfigArg(commandArgs), + logger: console, +}) + const processEnv = { ...process.env, CLOUDFLARE_ENV: envName, @@ -137,15 +155,25 @@ if (isDevCommand && resolvedPort) { process.exit(exitCode) function getPortArg(argumentList: ReadonlyArray) { - const inlinePortArg = argumentList.find((arg) => arg.startsWith('--port=')) - if (inlinePortArg) { - const [, value] = inlinePortArg.split('=') + return getArgValue(argumentList, '--port') +} + +function getConfigArg(argumentList: ReadonlyArray) { + return getArgValue(argumentList, '--config') +} + +function getArgValue(argumentList: ReadonlyArray, flagName: string) { + const inlineArg = argumentList.find((arg) => arg.startsWith(`${flagName}=`)) + if (inlineArg) { + const separatorIndex = inlineArg.indexOf('=') + const value = + separatorIndex >= 0 ? inlineArg.slice(separatorIndex + 1) : undefined return value || undefined } - const portIndex = argumentList.findIndex((arg) => arg === '--port') - if (portIndex >= 0) { - const value = argumentList[portIndex + 1] + const flagIndex = argumentList.findIndex((arg) => arg === flagName) + if (flagIndex >= 0) { + const value = argumentList[flagIndex + 1] return value || undefined }