deepspace
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBuild real-time collaborative apps on Cloudflare Workers in one package: SQLite-backed Durable Objects, RBAC, WebSocket subscriptions, Better Auth. Scaffolds with sensible defaults — generouted file-based routing, shadcn-style primitives, Vite + Tailwind v4. Apps deploy to .
<name>.app.space在Cloudflare Workers上一键构建实时协作应用:基于SQLite的Durable Objects、RBAC权限控制、WebSocket订阅、Better Auth。脚手架提供合理默认配置——generouted文件路由、shadcn风格组件、Vite + Tailwind v4。应用部署至。
<name>.app.spaceQuickstart — the development lifecycle
快速入门——开发生命周期
CLI commands, in order. Each step is rerunnable. and rewrite only the 9 SDK-managed keys in (auth + worker URLs + owner JWT + per-app identity token + debug flag); anything else you add — third-party tokens, custom flags — is preserved verbatim across runs and ships to prod as bindings on . See "Login, test, deploy" for the contract.
devtest.dev.varssecret_textdeploybash
undefined按顺序执行以下CLI命令,每个步骤均可重复运行。和仅重写中的9个SDK管理密钥(认证信息+Worker URL+所有者JWT+每个应用的身份令牌+调试标志);您添加的其他内容——第三方令牌、自定义标志——将在运行过程中完整保留,并在时作为绑定部署到生产环境。请查看“登录、测试、部署”部分了解具体约定。
devtest.dev.varsdeploysecret_textbash
undefined1. Scaffold (no auth required — npm fetches create-deepspace via npx on demand)
1. Scaffold (no auth required — npm fetches create-deepspace via npx on demand)
npm create deepspace@latest <app-name>
cd <app-name>
npm create deepspace@latest <app-name>
cd <app-name>
<app-name> seeds the directory AND wrangler.toml's name
(= deploy subdomain),
name<app-name> seeds the directory AND wrangler.toml's name
(= deploy subdomain),
namebut both are editable after scaffold — see references/architecture.md § App-name
but both are editable after scaffold — see references/architecture.md § App-name
rules. Scaffold into the directory you want; don't scaffold-then-move.
rules. Scaffold into the directory you want; don't scaffold-then-move.
CLI is non-interactive by default (agent-friendly): omitting <app-name> prints
CLI is non-interactive by default (agent-friendly): omitting <app-name> prints
usage and exits 1 instead of prompting on stdin. Pass --interactive
/ -i
--interactive-iusage and exits 1 instead of prompting on stdin. Pass --interactive
/ -i
--interactive-ifor the prompt-driven wizard. Probe with --help
/ -h
(plain stdout, no
--help-hfor the prompt-driven wizard. Probe with --help
/ -h
(plain stdout, no
--help-hANSI) or --version
/ -v
before invoking when scripting.
--version-vANSI) or --version
/ -v
before invoking when scripting.
--version-vThree invocation forms work — the scaffolder is permissive about target state:
Three invocation forms work — the scaffolder is permissive about target state:
a) From a parent dir, target does not exist: creates <app-name>/ fresh.
a) From a parent dir, target does not exist: creates <app-name>/ fresh.
b) From a parent dir, target is near-empty: scaffolds in-place into <app-name>/.
b) From a parent dir, target is near-empty: scaffolds in-place into <app-name>/.
c) From inside the target dir (any near-empty): scaffolds in-place into cwd; pass .
.c) From inside the target dir (any near-empty): scaffolds in-place into cwd; pass .
.to inherit the dir's name (lowercased).
to inherit the dir's name (lowercased).
"Near-empty" = only boilerplate is allowed: .git, .gitignore, .gitattributes,
"Near-empty" = only boilerplate is allowed: .git, .gitignore, .gitattributes,
.github/, LICENSE*, README*, any *.md, .vite, .wrangler, .dev.vars, .DS_Store.
.github/, LICENSE*, README*, any *.md, .vite, .wrangler, .dev.vars, .DS_Store.
Anything else triggers Directory <name> already exists
and the scaffolder bails.
Directory <name> already existsAnything else triggers Directory <name> already exists
and the scaffolder bails.
Directory <name> already exists.git
is allowed but not required — empty / unversioned dirs scaffold fine,
.git.git
is allowed but not required — empty / unversioned dirs scaffold fine,
.gitand a trailing git init
runs only when no .git
exists yet.
git init.gitand a trailing git init
runs only when no .git
exists yet.
git init.git2. One-time login — opens browser, polls up to 10 minutes. Interactive; pause and
2. One-time login — opens browser, polls up to 10 minutes. Interactive; pause and
have the user complete the OAuth flow at the keyboard.
have the user complete the OAuth flow at the keyboard.
npx deepspace login
npx deepspace login
3. Local dev (Vite + worker in-process; HMR on localhost:5173, --strictPort fails loudly on clash)
3. Local dev (Vite + worker in-process; HMR on localhost:5173, --strictPort fails loudly on clash)
npx deepspace dev # default
npx deepspace dev --port 5180 # parallel apps
npx deepspace dev --prod # same UI, but workers point at production
npx deepspace dev # default
npx deepspace dev --port 5180 # parallel apps
npx deepspace dev --prod # same UI, but workers point at production
3a. Clean up leaked workerd/vite (your own — never a sibling session's):
3a. Clean up leaked workerd/vite (your own — never a sibling session's):
npx deepspace kill # kills listener on 5173 + its workerd children
npx deepspace kill --port 5180 # different port
npx deepspace kill --all # sweeps every workerd/wrangler/vite on the box
npx deepspace kill # kills listener on 5173 + its workerd children
npx deepspace kill --port 5180 # different port
npx deepspace kill --all # sweeps every workerd/wrangler/vite on the box
4. Provision test accounts (one-time per machine; pool is shared across all apps, hard cap of 10)
4. Provision test accounts (one-time per machine; pool is shared across all apps, hard cap of 10)
npx deepspace test-accounts list # check what's already there
npx deepspace test-accounts create --email <…@deepspace.test> --password <p> --name <n>
npx deepspace test-accounts list # check what's already there
npx deepspace test-accounts create --email <…@deepspace.test> --password <p> --name <n>
5. Run tests (auto-installs Playwright + chromium on first run; always uses dev workers)
5. Run tests (auto-installs Playwright + chromium on first run; always uses dev workers)
npx deepspace test # default suite (smoke + api)
npx deepspace test e2e # all Playwright specs
npx deepspace test unit # vitest
npx deepspace test # default suite (smoke + api)
npx deepspace test e2e # all Playwright specs
npx deepspace test unit # vitest
5a. Capture a Playwright screenshot of any URL (shares the same chromium install as test
).
test5a. Capture a Playwright screenshot of any URL (shares the same chromium install as test
).
testnpx deepspace screenshot http://localhost:5173/ out.png
npx deepspace screenshot http://localhost:5173/ out.png --full-page --wait-for-timeout 500
npx deepspace screenshot http://localhost:5173/ out.png
npx deepspace screenshot http://localhost:5173/ out.png --full-page --wait-for-timeout 500
6. Install scaffold features
6. Install scaffold features
MUST run add --list
in THIS session before hand-rolling any non-trivial UI —
add --listMUST run add --list
in THIS session before hand-rolling any non-trivial UI —
add --listbuilding from scratch when a scaffold feature exists is a defect. Never claim
building from scratch when a scaffold feature exists is a defect. Never claim
to have run it without actually executing it and quoting the output; prior
to have run it without actually executing it and quoting the output; prior
knowledge of the feature set does not count.
knowledge of the feature set does not count.
npx deepspace add --list # REQUIRED first — discover available features
npx deepspace add --info <name> # inspect what a feature installs
npx deepspace add <feature> # install into current app
npx deepspace add --list # REQUIRED first — discover available features
npx deepspace add --info <name> # inspect what a feature installs
npx deepspace add <feature> # install into current app
7. Discover & test platform integrations from the CLI
7. Discover & test platform integrations from the CLI
Discovery is free (no login, no app dir, no dev server) — agents can probe the
Discovery is free (no login, no app dir, no dev server) — agents can probe the
catalog cold. Only invoke <ep> --body
actually calls the endpoint and is
invoke <ep> --bodycatalog cold. Only invoke <ep> --body
actually calls the endpoint and is
invoke <ep> --bodybilled to the logged-in user.
billed to the logged-in user.
npx deepspace integrations list # NO AUTH — full catalog
npx deepspace integrations info openai/chat-completion # NO AUTH — schema + example body for one endpoint
npx deepspace invoke openai/chat-completion --body '{...}' # AUTH REQUIRED — actually call it (billed to caller)
npx deepspace invoke openai/chat-completion --body-file - # AUTH REQUIRED — body via stdin (cat req.json | …)
npx deepspace integrations list # NO AUTH — full catalog
npx deepspace integrations info openai/chat-completion # NO AUTH — schema + example body for one endpoint
npx deepspace invoke openai/chat-completion --body '{...}' # AUTH REQUIRED — actually call it (billed to caller)
npx deepspace invoke openai/chat-completion --body-file - # AUTH REQUIRED — body via stdin (cat req.json | …)
npx deepspace invoke --list
and --info
are aliases for the no-auth forms above.
npx deepspace invoke --list--infonpx deepspace invoke --list
and --info
are aliases for the no-auth forms above.
npx deepspace invoke --list--info8. Deploy (subdomain comes from wrangler.toml's name
field — rename there, not at deploy time)
name8. Deploy (subdomain comes from wrangler.toml's name
field — rename there, not at deploy time)
namenpx deepspace deploy # → <wrangler.name>.app.space
npx deepspace deploy # → <wrangler.name>.app.space
9. (Optional) Buy & attach a custom domain to the deployed app
9. (Optional) Buy & attach a custom domain to the deployed app
npx deepspace domain search <query> # find available domains and prices
npx deepspace domain buy <domain> # buy via Stripe Checkout (browser opens)
npx deepspace domain list # list domains you own
npx deepspace domain attach <domain> --app <name> # re-point a domain at a different app
npx deepspace domain search <query> # find available domains and prices
npx deepspace domain buy <domain> # buy via Stripe Checkout (browser opens)
npx deepspace domain list # list domains you own
npx deepspace domain attach <domain> --app <name> # re-point a domain at a different app
10. (Optional) Publish the deployed app to the DeepSpace community library
10. (Optional) Publish the deployed app to the DeepSpace community library
npx deepspace library publish [--name "<title>"] [--description "<short>"] [--category <cat>]
npx deepspace library unpublish <handle>
npx deepspace library publish [--name "<title>"] [--description "<short>"] [--category <cat>]
npx deepspace library unpublish <handle>
11. (Optional) Provision a DeepSpace-managed GitHub repo for users without their own GitHub account
11. (Optional) Provision a DeepSpace-managed GitHub repo for users without their own GitHub account
npx deepspace managed-repos list
npx deepspace managed-repos create <app-name> # platform-owned private repo
npx deepspace managed-repos token <repo-id> # short-lived clone token
npx deepspace managed-repos delete <repo-id> --yes # per-day quota applies
**Login state is shared across all apps on the machine.** One `deepspace login` covers `dev`, `test-accounts`, and `deploy` for any app. Probe login state with `npx deepspace whoami` (`--json` for agents); don't stat `~/.deepspace/session` — that's a CLI implementation detail. Re-login only when `whoami` reports not-signed-in or the session has expired. See "Login, test, deploy" below for the full contract.npx deepspace managed-repos list
npx deepspace managed-repos create <app-name> # platform-owned private repo
npx deepspace managed-repos token <repo-id> # short-lived clone token
npx deepspace managed-repos delete <repo-id> --yes # per-day quota applies
**登录状态在同一台机器的所有应用间共享**。一次`deepspace login`即可覆盖任意应用的`dev`、`test-accounts`和`deploy`操作。使用`npx deepspace whoami`(代理可添加`--json`参数)查看登录状态;不要通过查看`~/.deepspace/session`文件判断——这是CLI的实现细节。仅当`whoami`显示未登录或会话过期时,才需要重新登录。请查看下方“登录、测试、部署”部分了解完整约定。Two imports
两个核心导入
typescript
// Frontend (React)
import { RecordProvider, RecordScope, useQuery, useMutations, useAuth } from 'deepspace'
// Worker (Cloudflare Worker)
import { RecordRoom, verifyJwt, CHANNELS_SCHEMA } from 'deepspace/worker'Two more entry points exist for narrower use cases: for worker-side helpers backed by the platform (payments helpers + — see / ), and for the Playwright multi-user fixture (see ).
'deepspace/server'captureScreenshotreferences/payments.mdreferences/sdk-reference.md'deepspace/testing'references/testing.mdtypescript
// Frontend (React)
import { RecordProvider, RecordScope, useQuery, useMutations, useAuth } from 'deepspace'
// Worker (Cloudflare Worker)
import { RecordRoom, verifyJwt, CHANNELS_SCHEMA } from 'deepspace/worker'针对更细分的使用场景,还有另外两个入口: 用于平台提供的Worker端辅助工具(支付辅助函数+——详见 / ),以及**** 用于Playwright多用户测试夹具(详见)。
'deepspace/server'captureScreenshotreferences/payments.mdreferences/sdk-reference.md'deepspace/testing'references/testing.mdProject layout
项目结构
The scaffold generates a Vite + Cloudflare-Worker app. Files you'll touch most often:
| Path | Purpose |
|---|---|
| Hono app worker; |
| Cloudflare config. |
| Provider stack: |
| File-based routes via generouted. |
| Collection schemas. Ships |
| 15 theme presets; active one set on |
| Tailwind v4 entry; |
| Top-nav entries — add new pages here so |
| |
| Server-action handlers. |
| Scheduled tasks for |
| Background-job handlers for |
| Per-integration billing config ( |
| System prompt + tool allowlist for |
| Hono handlers for the 4 AI chat endpoints ( |
| Playwright |
脚手架会生成一个Vite + Cloudflare Worker应用。您最常接触的文件如下:
| 路径 | 用途 |
|---|---|
| Hono应用Worker; |
| Cloudflare配置文件。 |
| Provider栈: |
| 通过generouted实现的文件路由。 |
| 集合Schema。默认包含 |
| 15个主题预设;当前激活主题在 |
| Tailwind v4入口文件; |
| 顶部导航条目——在此添加新页面, |
| |
| 服务器动作处理器。 |
| |
| |
| 每个集成的计费配置( |
| |
| 4个AI聊天端点的Hono处理器( |
| Playwright测试文件 |
Build a new app
构建新应用
Steps run in dependency order. Each links its deep-dive reference; load that reference only when you reach the step.
- Scaffold — see Quickstart.
- Schemas — define collections with ,
name,columns. Add topermissions, register insrc/schemas/alongsidesrc/schemas.ts(required — usesusersSchemafromUSERS_COLUMNS;deepspace/worker/useUser/ auth depend on auseUserscollection with this exact shape, so never rename or remove it). The scaffold also ships'users'as a starter admin key/value store — keep, customize, or drop freely; no SDK feature depends on it. For messaging, also addsettingsSchema/CHANNELS_SCHEMA/MESSAGES_SCHEMAfromREACTIONS_SCHEMA. →deepspace/workerreferences/schemas.md - Cross-app data sharing? — if the app needs to read/write ,
workspace:*, ordir:*scopes shared across DeepSpace apps (e.g., the email-handle workspace, cross-app inbox), the scaffoldedconv:*handler routes everything to the local DO and won't see shared data. Add the/ws/:roomIdproxy edit. →PLATFORM_WORKER§ Cross-app shared scopes. Skip otherwise.references/architecture.md - Auth model — pick public, gated, or mixed (the default; gated routes drop into ). →
src/pages/(protected)/references/auth.md - Theme — pick a preset on in
<html data-theme="...">, updateindex.html/favicon. Don't ship the default<title>. →slate§2references/uiux.md - Pages and features — pages in . Ready-made features ship inside the
src/pages/SDK (deepspace); install withnode_modules/deepspace/features/(usenpx deepspace add <feature>to enumerate). →--listfor UI primitives.references/uiux.md - Tests — read and apply the Step 8 checklist before extending
references/testing.md/smoke.spec.ts/api.spec.ts. Multi-user features need a 2-user Playwright spec, not justcollab.spec.tsor unit tests.tsc - Deploy — . Pre-deploy checklist: home replaced, theme picked, browser-default primitives removed, toasts wired to mutations. →
npx deepspace deploy§5references/uiux.md
For maintenance work on an existing app, jump straight to the relevant reference.
按依赖顺序执行以下步骤,每个步骤都链接了对应的深度参考文档;仅当执行到该步骤时,才需要加载对应的参考文档。
- 搭建脚手架——详见快速入门。
- 定义Schema——使用、
name、columns定义集合。添加到permissions目录,并在src/schemas/中与src/schemas.ts一起注册(usersSchema是必需的——它使用usersSchema中的deepspace/worker;USERS_COLUMNS/useUser/ 认证功能依赖名为useUsers且结构完全一致的集合,因此请勿重命名或删除它)。脚手架还提供了'users'作为初始的管理员键值存储——可保留、自定义或删除;没有SDK功能依赖它。如果需要消息功能,还需添加settingsSchema中的deepspace/worker/CHANNELS_SCHEMA/MESSAGES_SCHEMA。→REACTIONS_SCHEMAreferences/schemas.md - 跨应用数据共享?——如果应用需要读写DeepSpace应用间共享的、
workspace:*或dir:*范围(例如,邮箱句柄工作区、跨应用收件箱),则脚手架生成的conv:*处理器会将所有请求路由到本地DO,无法读取共享数据。需添加/ws/:roomId代理配置。→PLATFORM_WORKER§ 跨应用共享范围。否则可跳过此步骤。references/architecture.md - 认证模型——选择公开、 gated 或 混合(默认;gated路由放在目录下)。→
src/pages/(protected)/references/auth.md - 主题设置——在的
index.html中选择一个预设主题,更新<html data-theme="...">/图标。请勿直接使用默认的<title>主题。→slate§2references/uiux.md - 页面与功能——页面放在目录下。现成功能包含在
src/pages/SDK中(deepspace);使用node_modules/deepspace/features/安装(使用npx deepspace add <feature>查看所有可用功能)。→--list了解UI组件。references/uiux.md - 测试——阅读并在扩展
references/testing.md/smoke.spec.ts/api.spec.ts前应用步骤8的检查清单。多用户功能需要2用户Playwright测试,而不仅仅是collab.spec.ts或单元测试。tsc - 部署——执行。部署前检查清单:替换默认首页、选择主题、移除浏览器默认组件、将toast与变更操作关联。→
npx deepspace deploy§5references/uiux.md
对于现有应用的维护工作,可直接跳转到对应的参考文档。
Frontend hooks
前端钩子
The three core auth + data hooks. is universal (every page that has a sign-in state uses it); / show up the moment a page reads or writes a collection. For everything else (messaging, directory, R2, Yjs, presence, canvas, cron monitor, jobs, theme, env), see .
useAuthuseQueryuseMutationsreferences/sdk-reference.mdtypescript
const { records, status } = useQuery<Item>('items', { where: { status: 'published' }, orderBy: 'createdAt' })
const { create, put, remove } = useMutations<Item>('items') // create returns Promise<string> (the new recordId — capture it)
const { isSignedIn, isLoaded } = useAuth() // primary auth checkEach record is an envelope — . User fields live under (, never ). Pass to / .
{ recordId, data: T, createdBy, createdAt, updatedAt }.datar.data.titler.titler.recordIdputremoveputPartial<T>{...existing, ...patch}put(id, { completed: true })createTFor anything beyond these three (messaging, presence, R2, Yjs, canvas, game rooms, cron, jobs, AI chat, integrations, theming, RBAC), read first; only then drop into (frontend) or (worker) for exact type signatures. Do not guess hook names or argument shapes.
references/sdk-reference.mdnode_modules/deepspace/dist/index.d.tsnode_modules/deepspace/dist/worker.d.ts三个核心的认证+数据钩子。是通用钩子(所有涉及登录状态的页面都会用到);当页面需要读取或写入集合时,会用到 / 。其他功能(消息、目录、R2、Yjs、在线状态、画布、定时任务监控、作业、主题、环境变量)请查看。
useAuthuseQueryuseMutationsreferences/sdk-reference.mdtypescript
const { records, status } = useQuery<Item>('items', { where: { status: 'published' }, orderBy: 'createdAt' })
const { create, put, remove } = useMutations<Item>('items') // create returns Promise<string> (the new recordId — capture it)
const { isSignedIn, isLoaded } = useAuth() // primary auth check每条记录都是一个信封结构——。用户字段位于下(,不要使用)。将传递给 / 方法。
{ recordId, data: T, createdBy, createdAt, updatedAt }.datar.data.titler.titler.recordIdputremoveputPartial<T>{...existing, ...patch}put(id, { completed: true })createT除这三个钩子外的其他功能(消息、在线状态、R2、Yjs、画布、游戏房间、定时任务、作业、AI聊天、集成、主题、RBAC),请先阅读;之后再查看(前端)或(Worker)获取精确的类型签名。请勿猜测钩子名称或参数格式。
references/sdk-reference.mdnode_modules/deepspace/dist/index.d.tsnode_modules/deepspace/dist/worker.d.tsWorker-side extensions
Worker端扩展
Seven independent surfaces. Load only what you need:
- Server actions (privileged writes that bypass caller RBAC) →
references/server-actions.md - AI chat (streamed Claude / OpenAI / Cerebras with multi-turn tool use, persistent chat history, context-window compaction) →
references/ai-chat.md - Cron (scheduled tasks via +
AppCronRoom) →useCronMonitorreferences/cron.md - Jobs (durable background work via +
AppJobRoom— anything that needs to outlive the HTTP response: AI generation, exports, renders) →useJobsreferences/jobs.md - Payments (Stripe-backed subscriptions, paywalls, one-time products, tips, refunds, cancellation — never hand-roll Stripe; use /
useSubscription/useCheckout) →requireSubscriptionreferences/payments.md - Game rooms (turn/tick game loops, lobby, host-advanced phases, +
useGameRoomDO) →GameRoom§ Real-time collab + § Game roomsreferences/sdk-reference.md - Custom bindings & metering (Vectorize, AI, R2, KV, D1, Queues, Hyperdrive; autoprovisioning;
"auto"for D1;runMigrations/meterAiper-tenant rollup via the auto-attachedmeterVectorizeAE dataset) →USAGE_EVENTSreferences/bindings.md
Skip all of these for apps that only need client hooks and .
integration.post(...)七个独立的扩展方向,按需加载即可:
- 服务器动作(绕过调用者RBAC的特权写入)→
references/server-actions.md - AI聊天(支持多轮工具调用、持久化聊天历史、上下文窗口压缩的流式Claude / OpenAI / Cerebras聊天)→
references/ai-chat.md - 定时任务(通过+
AppCronRoom实现的定时任务)→useCronMonitorreferences/cron.md - 作业(通过+
AppJobRoom实现的持久化后台任务——任何需要独立于HTTP响应运行的任务:AI生成、导出、渲染)→useJobsreferences/jobs.md - 支付(Stripe支持的订阅、付费墙、一次性产品、打赏、退款、取消——请勿自行实现Stripe逻辑;使用/
useSubscription/useCheckout)→requireSubscriptionreferences/payments.md - 游戏房间(回合/ tick游戏循环、大厅、主机进阶阶段、+
useGameRoomDO)→GameRoom§ 实时协作 + § 游戏房间references/sdk-reference.md - 自定义绑定与计量(Vectorize、AI、R2、KV、D1、Queues、Hyperdrive;自动配置;D1的
"auto";通过自动附加的runMigrationsAE数据集实现的按租户USAGE_EVENTS/meterAi汇总)→meterVectorizereferences/bindings.md
如果应用仅需要客户端钩子和,可跳过所有上述扩展。
integration.post(...)Integrations
集成功能
Call external APIs through the api-worker proxy:
typescript
import { integration } from 'deepspace'
const result = await integration.post('openweathermap/geocoding', { q: city })
// Returns: { success: true, data: <endpoint-specific> } | { success: false, error: string }Endpoint names are two segments: . Don't guess — names like or aren't real and return 404 at runtime. Verify with / (the agent-friendly catalog + schema source — no auth, no app dir required).
<integration>/<endpoint>geocode-cityweather-forecastnpx deepspace integrations listinfo <ep>Default billing is owner-pays, so auth-gate any UI that calls to keep anonymous bots from billing the owner. → for billing modes, the discovery CLI, testing rules, and the response-envelope gotchas.
integration.post(...)references/integrations.md通过api-worker代理调用外部API:
typescript
import { integration } from 'deepspace'
const result = await integration.post('openweathermap/geocoding', { q: city })
// Returns: { success: true, data: <endpoint-specific> } | { success: false, error: string }端点名称由两部分组成:。请勿猜测——类似或的名称不存在,运行时会返回404。请使用 / 验证(这是适合代理的目录+Schema来源——无需认证、无需应用目录)。
<integration>/<endpoint>geocode-cityweather-forecastnpx deepspace integrations listinfo <ep>默认计费方式为所有者付费,因此请为所有调用的UI添加认证限制,防止匿名机器人产生费用。→ 了解计费模式、发现CLI、测试规则和响应信封注意事项。
integration.post(...)references/integrations.mdLogin, test, deploy
登录、测试、部署
Login (npx deepspace login
)
npx deepspace login登录(npx deepspace login
)
npx deepspace loginnpx deepspace whoami--jsondevtestdeploywhoamiNot logged indevtestdeploy~/.deepspace/sessionNot logged in- Pause and tell the user. Login opens a browser tab (GitHub/Google OAuth) on their machine and polls up to 10 minutes. They need to be at the keyboard. There is no agent-runnable bypass — never ask the user for their password.
- Run interactive login without an artificial time bound. Do not wrap in ,
timeout N, or any cutoff — those terminate OAuth before completion and leave no session. (sleep N && killisn't installed on macOS by default; don't reach for it.) Run in foreground or a true background process.timeout - After login completes, verify with before retrying
npx deepspace whoami/dev/test. Re-running them while login is still polling produces the same error — that's expected order, not a bug.deploy - Never copy from a sibling app.
.dev.varsis minted against that app's wrangler name; borrowing causes silent auth mismatches.APP_OWNER_JWT
****是检查登录状态的标准方式(代理可添加参数)。它会刷新JWT,与 / / 使用的调用路径相同——如果成功,那么这些操作也会成功。失败时:标准错误输出. Run `deepspace login`.,退出码1。
npx deepspace whoami--jsondevtestdeploywhoamiNot logged indevtestdeploy~/.deepspace/sessionNot logged in- 暂停操作并告知用户。登录会在用户的机器上打开一个浏览器标签页(GitHub/Google OAuth),并最多轮询10分钟。用户需要在键盘前完成操作。没有代理可绕过的方式——永远不要向用户索要密码。
- 运行交互式登录时不要设置人为时间限制。请勿使用、
timeout N或任何截断操作——这些会在OAuth完成前终止进程,导致无法生成会话。(macOS默认未安装sleep N && kill;请勿使用它。)请在前台或真正的后台进程中运行登录命令。timeout - 登录完成后,使用验证,然后再重试
npx deepspace whoami/dev/test。在登录仍在轮询时重新运行这些操作会产生相同的错误——这是正常的顺序,不是bug。deploy - 永远不要从其他应用复制文件。
.dev.vars是针对该应用的wrangler名称生成的;借用会导致静默的认证不匹配。APP_OWNER_JWT
Test (npx deepspace test
)
npx deepspace test测试(npx deepspace test
)
npx deepspace testTests are the primary way to verify code changes. The scaffolded specs ( / / ) are starting points — extend them per the Step 8 checklist in . The full extension table, debug-from-failures rule, route coverage, multi-user patterns, and the fixture all live in that file.
smoke.spec.tsapi.spec.tscollab.spec.tsreferences/testing.md'deepspace/testing'One rule stays here because it bites first-time runs: run tests only after a runtime-affecting code change (, , etc.). Skip them for conversation, planning, reading, or pure documentation edits — don't run as a ritual.
src/worker.ts测试是验证代码变更的主要方式。脚手架提供的测试用例( / / )是起点——请根据中的步骤8检查清单扩展它们。完整的扩展表、从失败中调试的规则、路由覆盖率、多用户模式以及夹具都在该文档中。
smoke.spec.tsapi.spec.tscollab.spec.tsreferences/testing.md'deepspace/testing'有一条规则需要在此强调,因为它会影响首次运行:仅在代码变更影响运行时(、等)后才运行测试。在讨论、规划、阅读或纯文档编辑时,请跳过测试——不要将其作为例行操作。
src/worker.tsDeploy (npx deepspace deploy
)
npx deepspace deploy部署(npx deepspace deploy
)
npx deepspace deployOn an initial build, run the pre-deploy checklist in §5 first. On follow-up deploys with those already verified, just run the command:
references/uiux.mdbash
npx deepspace deploy # → <wrangler.name>.app.spaceThe subdomain is the field in . Edit it there if you want a different deploy target — does not accept a name override. Re-run if the session has expired.
namewrangler.tomldeploynpx deepspace login首次构建时,请先执行 §5中的部署前检查清单。后续部署时,如果已完成这些检查,只需运行命令即可:
references/uiux.mdbash
npx deepspace deploy # → <wrangler.name>.app.space子域名由中的字段决定。如果需要不同的部署目标,请在此处编辑该字段——不接受名称覆盖。如果会话过期,请重新运行。
wrangler.tomlnamedeploynpx deepspace login.dev.vars
contract
.dev.vars.dev.vars
约定
.dev.varsdevtestAUTH_JWT_PUBLIC_KEYAUTH_JWT_ISSUERAUTH_WORKER_URLAPI_WORKER_URLPLATFORM_WORKER_URLOWNER_USER_IDAPP_OWNER_JWTAPP_IDENTITY_TOKENALLOW_DEBUG_ROUTES# --- not managed by the SDK; preserved across dev/test runs ---APP_IDENTITY_TOKENnpx deepspace deploycaptureScreenshotreferences/payments.mdreferences/sdk-reference.mdAnything you add below that divider — third-party API tokens, custom feature flags, your own service URLs — is preserved verbatim across / runs, and shipped to prod as bindings on (same access pattern in dev and prod; no step).
devtestsecret_textdeployenv.MY_KEYwrangler secret putLimits enforced server-side at deploy:
- Name must match .
^[A-Za-z_][A-Za-z0-9_]*$ - Per-value cap: 32 KB (32 × 1024 bytes).
- Total cap across all user secrets: 128 KB.
- Raw JSON payload cap: 1 MB → 413.
- Name must not collide with (11 SDK-owned), any declared custom binding, or any DO class in
RESERVED_BINDING_NAMES.__DO_MANIFEST__
Read if any of those collisions trip you.
references/bindings.mddevtestAUTH_JWT_PUBLIC_KEYAUTH_JWT_ISSUERAUTH_WORKER_URLAPI_WORKER_URLPLATFORM_WORKER_URLOWNER_USER_IDAPP_OWNER_JWTAPP_IDENTITY_TOKENALLOW_DEBUG_ROUTES# --- not managed by the SDK; preserved across dev/test runs ---APP_IDENTITY_TOKENnpx deepspace deploycaptureScreenshotreferences/payments.mdreferences/sdk-reference.md您在分隔符下方添加的任何内容——第三方API令牌、自定义功能标志、您自己的服务URL——都会在 / 运行过程中完整保留,并在时作为绑定部署到生产环境(开发和生产环境中均通过访问;无需执行步骤)。
devtestdeploysecret_textenv.MY_KEYwrangler secret put部署时服务器端会强制执行以下限制:
- 名称必须匹配。
^[A-Za-z_][A-Za-z0-9_]*$ - 单个值上限:32 KB(32 × 1024字节)。
- 所有用户密钥的总上限:128 KB。
- 原始JSON负载上限:1 MB → 返回413错误。
- 名称不得与(11个SDK自有名称)、任何已声明的自定义绑定或
RESERVED_BINDING_NAMES中的任何DO类冲突。__DO_MANIFEST__
如果遇到上述冲突,请阅读。
references/bindings.mdHandling rules — .dev.vars
holds live credentials
.dev.vars处理规则——.dev.vars
包含实时凭证
.dev.varsThe file holds a live (signed against the user's identity) plus whatever third-party tokens (Stripe, OpenAI, …) the user wrote below the divider. Treat its contents as secret throughout the session, not just at commit time:
APP_OWNER_JWT- Never read the file's values into your output. No , no
cat .dev.vars/head/grep-then-paste-into-chat, no inclusion in summaries, generated docs, READMEs, commit messages, PR bodies, or screenshots. If you need to confirm a key is present, check the key name (Read— files-only, not content) and report presence/absence — never the value.grep -l '^STRIPE_SECRET_KEY=' .dev.vars - Never pass secrets as CLI args. leaks into shell history,
MY_KEY=… npx deepspace dev, and child-process env dumps. Write the line intops auxbelow the divider and let the SDK pick it up via.dev.varsin worker code.env.MY_KEY - Never commit . The scaffold's
.dev.varscovers it; do not add a.gitignoreexception, do not!, do not paste its contents into a tracked file "for clarity." If agit add -f .dev.varsshows it untracked, that's the correct state — leave it.git status - Never assert on secret values in tests. Test that auth works (a request returns 200, a webhook fires) — never and never echo the value into a request body that goes to a third party you don't control.
expect(env.STRIPE_SECRET_KEY).toBe('sk_live_…') - Adding a new secret is one step: append below the divider in
KEY=value, then.dev.vars/npx deepspace dev. The CLI handles upload asdeployon deploy — nosecret_text, no out-of-band copy.wrangler secret put
该文件包含有效的(针对用户身份签名)以及用户在分隔符下方添加的任何第三方令牌(Stripe、OpenAI等)。在整个会话过程中,请将其内容视为机密,而不仅仅是在提交时:
APP_OWNER_JWT- 永远不要将文件内容读取到输出中。不要执行、
cat .dev.vars/head/grep后粘贴到聊天中,不要包含在摘要、生成的文档、README、提交消息、PR正文或截图中。如果需要确认某个密钥是否存在,请检查密钥名称(Read——仅检查文件是否包含该密钥,不显示内容)并报告存在/不存在——永远不要显示值。grep -l '^STRIPE_SECRET_KEY=' .dev.vars - 永远不要将机密作为CLI参数传递。会泄露到shell历史、
MY_KEY=… npx deepspace dev和子进程环境转储中。请将该行添加到ps aux的分隔符下方,让SDK在Worker代码中通过.dev.vars获取。env.MY_KEY - 永远不要提交。脚手架的
.dev.vars已包含该文件;请勿添加.gitignore例外,不要执行!,不要将其内容粘贴到跟踪文件中“以便清晰查看”。如果git add -f .dev.vars显示它未被跟踪,这是正确的状态——请保持不变。git status - 永远不要在测试中断言机密值。测试认证是否有效(请求返回200、webhook触发)——不要执行,永远不要将值回显到发送给不受您控制的第三方的请求体中。
expect(env.STRIPE_SECRET_KEY).toBe('sk_live_…') - 添加新机密只需一步:在的分隔符下方追加
.dev.vars,然后执行KEY=value/npx deepspace dev。CLI会在部署时将其作为deploy上传——无需执行secret_text,无需手动复制。wrangler secret put
References
参考文档
Required preflight before any code change. Before editing files or writing code:
- List the files you will touch.
- Scan the table below and list every row whose "Read before" trigger matches the work.
- each matching reference in this turn, before the first edit — not after, not "if needed later."
Read - If your list under (2) is empty, stop and re-scan the table; for any non-trivial DeepSpace work at least one row applies.
Each reference also declares its own "Load when …" trigger as its first line — that gate is authoritative; if it says load, load it before touching the matching surface.
| Reference | Read before |
|---|---|
| Reaching for any hook, type, or export beyond |
| Defining a collection, picking a permission rule, debugging "why can't this user see/edit X," wiring |
| Choosing the auth model (public / gated / mixed), adding |
| Editing |
| Adding privileged writes that bypass the caller's RBAC. |
| Adding a streamed chat UI with tool use over the app's records. |
| Adding scheduled tasks, building the admin cron monitor, testing cron via |
| Adding background-job handlers (AI generation, exports, renders), choosing client vs server enqueue, handling progress / cancellation / multi-tick checkpoints. |
| Declaring custom Cloudflare bindings (Vectorize / R2 / KV / D1 / Queues / AI / Browser / Hyperdrive / AE), |
| Calling external APIs (LLMs, search, media, social, finance, etc.). |
| Anything involving money, Stripe, billing, paywalls, subscriptions, pricing pages, "Upgrade" buttons, Pro / premium tiers, gating features behind a plan, one-time products, tips, donations, free trials, refunds, or cancellation. Never hand-roll Stripe in a DeepSpace app — declare in |
| Buying / attaching / managing a custom domain ( |
| Adding audio/video rooms — token mint, billing model, room lifecycle. |
| Calling Gmail / Calendar / Drive / Contacts — per-user billing, scope step-up, |
| Working on theme, home page, primitives, interaction polish, or "feels generic" feedback. Trigger especially when about to use |
| Writing or extending specs, applying the Step 8 checklist, building multi-user flows, route coverage, debugging flaky tests. |
| Building marketing / landing / splash pages, addressing "feels AI-generated" feedback, customizing the scaffolded |
任何代码变更前必须执行的预检步骤。在编辑文件或编写代码前:
- 列出您将修改的文件。
- 扫描下表,列出所有“阅读时机”与您的工作匹配的行。
- 在本次会话中阅读每个匹配的参考文档,在首次编辑前完成——不要在编辑后阅读,也不要“以后需要时再读”。
- 如果步骤2中的列表为空,请停止并重新扫描表格;任何非 trivial 的DeepSpace工作至少会匹配一行。
每个参考文档的第一行也声明了自己的“加载时机”触发条件——该条件是权威的;如果它说需要加载,请在接触对应的功能前加载该文档。
| 参考文档 | 阅读时机 |
|---|---|
| 当您需要使用 |
| 定义集合、选择权限规则、调试“为什么该用户无法查看/编辑X”、配置 |
| 选择认证模型(公开 / gated / 混合)、添加 |
| 编辑 |
| 添加绕过调用者RBAC的特权写入时。 |
| 添加支持工具调用的流式聊天UI以操作应用记录时。 |
| 添加定时任务、构建管理员定时任务监控、通过 |
| 添加后台任务处理器(AI生成、导出、渲染)、选择客户端 vs 服务器入队、处理进度/取消/多tick检查点时。 |
| 声明自定义Cloudflare绑定(Vectorize / R2 / KV / D1 / Queues / AI / Browser / Hyperdrive / AE)、 |
| 调用外部API(LLM、搜索、媒体、社交、金融等)时。 |
| 涉及资金、Stripe、计费、付费墙、订阅、定价页面、“升级”按钮、专业/高级套餐、功能按计划限制、一次性产品、打赏、捐赠、免费试用、退款或取消的任何场景。永远不要在DeepSpace应用中自行实现Stripe逻辑——在 |
| 购买/绑定/管理自定义域名( |
| 添加音视频房间——令牌生成、计费模型、房间生命周期时。 |
| 调用Gmail / Calendar / Drive / Contacts——按用户计费、范围提升、 |
| 处理主题、首页、组件、交互优化或“感觉通用”的反馈时。尤其是当您打算使用 |
| 编写或扩展测试用例、应用步骤8检查清单、构建多用户流程、路由覆盖率、调试不稳定测试时。 |
| 构建营销/着陆/启动页面、处理“感觉是AI生成的”反馈、自定义脚手架提供的 |
Gotchas
常见陷阱
Cross-cutting traps that don't have a natural reference home. Domain-specific gotchas live in their topical reference (auth, schemas, integrations, architecture, testing, bindings).
- Scaffold's local UI primitives shadow the SDK — wraps the tree in
_app.tsxfromToastProvider, not fromsrc/components/ui/. Importingdeepspace(or any locally-shadowed primitive) fromuseToastthrowsdeepspaceat runtime — the React contexts don't match. Import fromuseToast must be used within ToastProvider, not from../components/ui. Full explanation indeepspace§ "Critical import rule."references/uiux.md - Page files belong in — generouted scans only this directory. Putting pages in
src/pages/results in 404s even if nav links exist.src/features/<name>/ - Don't scaffold-then-move to pair a directory with a different subdomain. If you need directory with subdomain
foo-site, scaffold intofoo-mainand editfoo-site'swrangler.tomltoname. Scaffolding asfoo-mainthen moving the files lands in the same state with extra failure surface (brokenfoo-main, straygit initpaths). See.wrangler/§ App-name rules.references/architecture.md - Never put identity in WebSocket URLs or headers. The starter
/api/*stripswsRoute/userId/userName/userEmail/userImageUrlquery params on every upgrade and re-applies them only from a verified JWT. The platform worker does the same onrole(overwrites/api/*from JWT, stripsX-User-Id). Caller identity is always the JWT subject — there is no client-side override. Three valid WS states: no token → anonymous (DO assignsX-App-Action); invalid token → 401; valid token → JWT identity. (Cross-app scopesanon-<uuid>/workspace:*/dir:*have no anonymous path — auth is required.)conv:* - Port 5173 may be held by a parallel session — ships with
tests/playwright.config.ts, so a sibling session's Vite on 5173 is picked up and your tests run against its app. Do not kill a parallel session's processes. For your own leaked workerd/wrangler (crashed terminal, IDE close), usereuseExistingServer: true(addnpx deepspace killto sweep every workerd/wrangler/vite on the box). For genuine parallel work, use--all(or 5175, 5176, …) and edit--port 5174sotests/playwright.config.tsandwebServer.portboth match before running tests.use.baseURL
这些跨领域的陷阱没有合适的参考文档归属。特定领域的陷阱请查看对应的参考文档(认证、Schema、集成、架构、测试、绑定)。
- 脚手架的本地UI组件会覆盖SDK组件——使用
_app.tsx中的src/components/ui/包裹整个组件树,而非ToastProvider中的。从deepspace导入deepspace(或任何被本地覆盖的组件)会在运行时抛出useToast错误——React上下文不匹配。请从useToast must be used within ToastProvider导入,不要从../components/ui导入。完整说明请查看deepspace§ “关键导入规则”。references/uiux.md - 页面文件必须放在目录下——generouted仅扫描此目录。将页面放在
src/pages/目录下会导致404错误,即使存在导航链接。src/features/<name>/ - 不要先搭建脚手架再移动目录以匹配不同的子域名。如果需要目录对应子域名
foo-site,请直接在foo-main目录下搭建脚手架,然后编辑foo-site的wrangler.toml字段为name。先以foo-main搭建脚手架再移动文件会导致额外的失败风险(foo-main损坏、git init路径错误)。详见.wrangler/§ 应用名称规则。references/architecture.md - 永远不要在WebSocket URL或头中包含身份信息。初始的
/api/*会在每次升级时剥离wsRoute/userId/userName/userEmail/userImageUrl查询参数,仅从验证后的JWT重新应用这些信息。平台Worker在role请求上也会执行相同操作(从JWT覆盖/api/*,剥离X-User-Id)。调用者身份始终是JWT的主体——没有客户端覆盖的方式。WebSocket有三种有效状态:无令牌→匿名(DO分配X-App-Action);无效令牌→401;有效令牌→JWT身份。(跨应用范围anon-<uuid>/workspace:*/dir:*不支持匿名路径——必须认证。)conv:* - 端口5173可能被并行会话占用——默认配置
tests/playwright.config.ts,因此并行会话中运行在5173端口的Vite会被复用,您的测试会针对该应用运行。不要终止并行会话的进程。对于您自己的泄露进程(终端崩溃、IDE关闭),请使用reuseExistingServer: true(添加npx deepspace kill可清除机器上所有的workerd/wrangler/vite进程)。如果需要真正的并行工作,请使用--all(或5175、5176等),并在运行测试前编辑--port 5174,使tests/playwright.config.ts和webServer.port匹配该端口。use.baseURL