Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cursor/CLOUD.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 9 additions & 8 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand All @@ -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:
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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: |
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ package-lock.json
*.sln
*.sw?
.wrangler
.nx
.tmp
.env
mock-data
playwright-report
test-results
public/client-entry.js
public/mcp-apps/
packages/worker/wrangler-preview.generated.json
packages/worker/wrangler-production.generated.json
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ 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 the main app worker under
`packages/worker` and mock Workers under `packages/mock-servers/*`.

## Quick Start

```bash
Expand All @@ -50,6 +53,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/) |
Expand All @@ -67,15 +71,15 @@ 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
β”œβ”€β†’ Static assets (public/)
└─→ 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
Expand Down
Loading
Loading