Skip to main content

working-on-worker

Cloudflare Worker development conventions for Savecraft. Use when working on files in worker/, including the push API, SourceHub/UserHub Durable Objects, WebSocket protocol, D1 schemas, route handling, or Worker tests. Triggers on TypeScript Worker code, Miniflare, Vitest, Durable Objects, wrangler, or Worker deployment.

설치로 이동

소스 정보

저장소
joshsymonds/savecraft.gg
최근 소스 활동
2026년 3월 26일 23:00
감지된 SKILL.md 언어
영어
스타
12
포크
0

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
working-on-worker
description
Cloudflare Worker development conventions for Savecraft. Use when working on files in worker/, including the push API, SourceHub/UserHub Durable Objects, WebSocket protocol, D1 schemas, route handling, or Worker tests. Triggers on TypeScript Worker code, Miniflare, Vitest, Durable Objects, wrangler, or Worker deployment.
# Working on the Worker Read `docs/worker.md` for the full architecture reference. ## Verification ```bash just test-worker # Vitest + Miniflare ``` ## TypeScript Rules **Type safety:** - Never use `any` — use `unknown` if type is truly unknown. - Never use `@ts-ignore` or `@ts-expect-error` — fix the type issue properly. - Strict mode enabled. Avoid type assertions except after type guards. - Never use `!` non-null assertion without a preceding check. **State & data:** - Discriminated unions for state machines and message types. Never use boolean flags for multiple states. - Exhaustive checking with `never` type in switch defaults. - Use `readonly` for properties unless mutation is needed. Never mutate parameters. **Null handling:** - Always handle null/undefined explicitly. - Use optional chaining (`?.`) and nullish coalescing (`??`). **Error handling:** - Custom error classes for different error types. Never throw strings — always `Error` objects. - Never ignore Promise rejections. **eslint-enforced (CI will fail):** - `T[]` not `Array<T>` — eslint `array-type` rule. - `toSorted((a, b) => a.localeCompare(b))` not `sort()` — eslint unicorn/sonarjs rules. - Max function complexity: 15. Split into helper functions to stay under. **Never do:** - Use `any`, `var`, `==`, `@ts-ignore`, bare `!` assertions. - Mutate function parameters. - Skip runtime validation for external data (API responses, user input). ## MCP Handler The MCP server is a **hand-rolled JSON-RPC 2.0 handler**. Do NOT use `@modelcontextprotocol/sdk` — it depends on ajv/express/hono which are CJS and incompatible with the workerd runtime. - Handler: `src/mcp/handler.ts` (protocol routing) - Tools: `src/mcp/tools.ts` (pure tool functions) - The `agents` npm package (v0.6.0) replaces the deprecated `@cloudflare/agents`. See `docs/mcp.md` for the full tool contracts and OAuth architecture. ## Test Infrastructure **Sharded parallelism:** `just test-worker` runs 4 vitest shards in parallel (`worker/scripts/test-sharded.mjs`), each with its own Miniflare instance. This sidesteps Miniflare's `isolatedStorage` WAL bug while giving true file-level parallelism. `npm test` still works for single-shard runs. **Within each shard** (`vitest.config.ts`): `singleWorker: true` + `isolatedStorage: false` + `fileParallelism: false` — files run serially sharing one Miniflare instance per shard. **Test lifecycle:** - `setup.ts`: Creates tables (migrations) + one-time cleanup at suite start. - `helpers.ts`: `cleanAll()` batch-deletes all D1 tables (FK-safe order) + R2 objects. - **Every `describe` block** must have `beforeEach(cleanAll)` — NOT at module level. Module-level `beforeEach` leaks to all test files in singleWorker mode. - **Always consume DO fetch responses** (call `.json()` or `.text()`) — unconsumed responses leave SQLite WAL files that break `isolatedStorage` if ever re-enabled. **DO gotcha:** `DurableObject.ctx.id.toString()` returns a hex hash, NOT the original `idFromName()` string. Pass the real `userUuid` via `X-User-UUID` header if you need it inside the DO. **Test tokens:** `getOAuthToken(userUuid)` in `test/helpers.ts` uses `getOAuthApi()` to mint real library tokens via KV without Clerk. No dev-mode code in production. **IDE noise:** `ProvidedEnv` TS errors in tests are IDE-only; runtime works fine via Miniflare. ## Key Paths ``` worker/src/index.ts # Routes, request handling, OAuthProvider wrapper worker/src/hub.ts # SourceHub Durable Object (per-source, daemon WebSocket + state) worker/src/user-hub.ts # UserHub Durable Object (per-user, UI WebSocket + aggregation) worker/src/auth.ts # Session/daemon auth (stub mode + Clerk mode) worker/src/oauth.ts # OAuth endpoint config, OAUTH_ENDPOINTS constant worker/src/mcp/handler.ts # JSON-RPC 2.0 protocol handler worker/src/mcp/tools.ts # Pure MCP tool functions worker/test/helpers.ts # cleanAll(), getOAuthToken(), test utilities worker/test/setup.ts # Table creation, one-time cleanup worker/vitest.config.ts # Per-shard config (singleWorker + isolatedStorage) worker/scripts/test-sharded.mjs # Parallel shard runner (4 vitest processes) worker/wrangler.toml # Bindings, D1, R2, KV, DO ```
GitHub에서 보기