算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
backend-building-swarm【设计与创意】Swarm-aware backend building that grafts tRPC + Drizzle ORM + Hono onto an existing webapp-building-swarm frontend. Grafts in place on a worktree of the shared repo (created via swarm-workspace) and commits on a backend branch the main agent merges. Supports incremental features (db, auth) and fullstack-template provisioning (--template). Use when th…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Stack: tRPC + Drizzle ORM + Hono + MySQL + OAuth 2.0
A swarm-aware backend skill that grafts onto an existing webapp-building-swarm project. Adds api/, contracts/, and optionally db/ directories — but never replaces or modifies existing frontend files.
Prerequisite: An existing shared repo created by webapp-building-swarm at /mnt/agents/output/app.
This skill builds on the swarm-workspace two-tier filesystem — a shared
coordination repo (branch hub) plus per-subagent worktrees. See
swarm-workspace/SKILL.md for the full contract; it is not restated here.
init.sh grafts in place on $PROJECT_PATH and commits on whatever
branch is checked out there — it does NOT manage worktrees or merge. In the
swarm flow the main agent creates the backend worktree via
swarm-workspace's setup-local.sh, runs init.sh in it with PROJECT_PATH
pointed at the worktree, commits on the backend branch, and merges that
branch into the integration line before page branches fork — so all page
agents inherit the tRPC client and contracts. The main agent runs the graft
itself rather than dispatching a subagent because init.sh writes a
gitignored .env that never travels through the merge: it survives only in
the sandbox where it ran, which must be the main agent's own — the one that
later builds and stages .env into the other worktrees. Webapp commit history
is preserved because the backend branch descends from the scaffolded frontend.
Features can be installed incrementally. Base infrastructure (Hono server, tRPC, contracts) is always installed automatically on first run.
| Feature | What it provides | Dependencies |
|---|---|---|
db | Drizzle ORM + MySQL — adds db/, api/queries/connection.ts, drizzle.config.ts | — |
auth | Kimi OAuth + user management — adds api/kimi/, Login page, useAuth, AuthLayout | requires db (auto-included) |
Default: init.sh "App" with no --features → defaults to auth (= db + auth).
All scripts use absolute paths from /app/.agents/skills/backend-building-swarm/scripts/.
init.sh — Backend graft (run inside the backend worktree)# Point PROJECT_PATH at the backend worktree (created by setup-local.sh first):
PROJECT_PATH=$HOME/app-backend \
bash /app/.agents/skills/backend-building-swarm/scripts/init.sh "<app-title>" [--features db,auth | --template]
$PROJECT_PATH and commits on the currently checked-out branch. In the swarm flow $PROJECT_PATH is the main-agent-owned backend worktree (the graft is the main agent's own job, not a subagent's — see the gitignored-.env reason above); the script's bare default (/mnt/agents/output/app) exists only for the deterministic structure test. It does NOT create worktrees or merge..backend-features.json gates re-runs (adding --features auth later only installs the delta). Graft-owned auth UI (Login.tsx, useAuth.ts, AuthLayout*) is planted authoritatively each run, while user-extensible files (schema.ts, seed.ts, connection.ts, drizzle.config.ts) yield to any version already present.Two execution paths depending on which webapp template was used:
| Mode | Webapp template | Backend work |
|---|---|---|
--features db,auth (default) | frontend-only (e.g. 0-origin, airlens-style) | full graft: copy api/contracts/db, patch vite/tsconfig, auto-wire main.tsx/App.tsx, portal call, commit |
--template | fullstack (ships .backend-features.json + pre-laid api/, db/, contracts/) | provision-only: read manifest, portal call, write .env, npm install, commit |
--features and --template are mutually exclusive. --template is selected automatically by the presence of .backend-features.json in the project — it reads the feature list from that manifest and skips all file copy/patch/wiring (the fullstack template already laid them out), doing portal provisioning + .env only.
Use swarm-workspace's setup-local.sh, passing this skill's prebuilt backend
node_modules (Hono/tRPC/Drizzle) as NODE_MODULES_SRC:
NODE_MODULES_SRC=/app/.agents/skills/backend-building-swarm/scripts/template/node_modules \
bash /app/.agents/skills/swarm-workspace/scripts/setup-local.sh <branch> $HOME/app-<branch>
/mnt/agents/output/app$HOME/app-<branch>) to avoid worktree metadata collisionsnode_modules so npm install is fast, then npm installgit worktree prune — it destroys other agents' worktree entriesSee swarm-workspace/SKILL.md for the full two-tier filesystem contract.
.prepare-template.sh — Image build-time onlyBuilds scripts/template/node_modules/ by npm install-ing the template package.json. Runs once at image build time, not at runtime.
The end-to-end sequencing is owned by vibecoding-webapp-swarm (the backend
graft is its Phase 4.5: run once on a backend branch forked from scaffold,
merged before page branches fork). This skill provides the graft itself. The
shape of a graft step:
webapp-building-swarm init + scaffold land a frontend on the shared reposetup-local.sh (with NODE_MODULES_SRC = this skill's template/node_modules)PROJECT_PATH=$HOME/app-backend init.sh "<title>" [--features … | --template] — graft, provision, commit on backendbackend into the integration line; page agents then inherit the tRPC client + contractsIncremental features (add capabilities over time): re-run init.sh
in a worktree with --features auth — the .backend-features.json manifest
gates it to install only the delta, landing a new commit on that branch.
PROJECT_PATH=$HOME/init REMOTE_PATH=/mnt/agents/output/app \
bash /app/.agents/skills/webapp-building-swarm/scripts/init-webapp.sh "My App"
# Create the backend worktree (swarm-workspace's setup-local.sh + this skill's node_modules), then graft into it:
NODE_MODULES_SRC=/app/.agents/skills/backend-building-swarm/scripts/template/node_modules \
bash /app/.agents/skills/swarm-workspace/scripts/setup-local.sh backend $HOME/app-backend
# Full stack with auth (default):
PROJECT_PATH=$HOME/app-backend \
bash /app/.agents/skills/backend-building-swarm/scripts/init.sh "My App"
# Database only (no auth):
PROJECT_PATH=$HOME/app-backend \
bash /app/.agents/skills/backend-building-swarm/scripts/init.sh "My App" --features db
# Fullstack template (skip scaffolding; provision-only — auto-detected via .backend-features.json):
PROJECT_PATH=$HOME/app-backend \
bash /app/.agents/skills/backend-building-swarm/scripts/init.sh "My App" --template
Then the main agent merges the backend branch:
cd /mnt/agents/output/app && git merge backend --no-edit. Because .env is
gitignored, copy it to the shared repo so later worktrees can pick it up:
cp $HOME/app-backend/.env /mnt/agents/output/app/.env.
What this does (base, always on first run with --features):
api/, contracts/ into the worktreevite.config.ts in-place (adds @contracts alias, envDir, build.outDir)tsconfig.server.json and merges @contracts/* path into existing tsconfigspackage.json (adds backend deps and scripts).env with portal credentialsnpm installAdditional per feature:
db/ directory, drizzle.config.ts, database connection, DATABASE_URL env var, and db/seed.ts (scaffold for seeding — run with npx tsx db/seed.ts). Do not overwrite the generated api/queries/connection.ts, drizzle.config.ts, or .env. Only add your tables to db/schema.ts.api/kimi/, auth router, client patches (Login, useAuth, AuthLayout, TRPCProvider), auto-wires Login/NotFound routes into App.tsx.On first run, init.sh auto-wires TRPCProvider into src/main.tsx. When auth feature is installed, it also adds Login/NotFound routes to src/App.tsx. Check the init output:
If manual wiring is needed, do it in a worktree (created via swarm-workspace's setup-local.sh, which auto-copies the staged .env so npm run db:* has DATABASE_URL), edit, commit on the branch — the main agent merges it into the shared repo. (No push: worktrees share the shared repo's .git object store.)
Run from a worktree, not OSS. npm run db:* needs DATABASE_URL, which lives in
.env — setup-local.sh auto-copies the graft's staged .env ($REPO_PATH/.env)
into every worktree, so this works without extra flags. ENV_SRC is shown explicitly
below for clarity (and to override the source if ever needed); omitting it falls back
to the same staged .env:
ENV_SRC=/mnt/agents/output/app/.env \
NODE_MODULES_SRC=/app/.agents/skills/backend-building-swarm/scripts/template/node_modules \
bash /app/.agents/skills/swarm-workspace/scripts/setup-local.sh main $HOME/app-main
cd $HOME/app-main && npm run db:push
# Build on a final-build worktree (correctness gate — catch type/build errors)
ENV_SRC=/mnt/agents/output/app/.env \
NODE_MODULES_SRC=/app/.agents/skills/backend-building-swarm/scripts/template/node_modules \
bash /app/.agents/skills/swarm-workspace/scripts/setup-local.sh final-build $HOME/app-final-build
cd $HOME/app-final-build && npm run build
Do not copy dist/ anywhere. The model records a version of the committed
source via mshtools-website_version_manager (action: "build_version",
type: "dynamic" — static serves the frontend only, without the server), and the
platform builds the dynamic app server-side from that version's committed
source in the worktree (project_dir) — which is why node_modules and .env
must be present there (ENV_SRC above copies .env into the worktree). The
tool is invoked per the system prompt, not by this skill.
| Command | Description | Requires |
|---|---|---|
npm run dev | Start development server with HMR at http://localhost:3000 | base |
npm run build | Build for production (outputs to dist/) | base |
npm start | Start production server | base |
npm run check | Type-check all TypeScript files | base |
npm run format | Format code with Prettier | base |
npm run test | Run tests with Vitest | base |
npm run db:push | Sync schema to DB during development (recommended) | db |
npm run db:generate | Generate migration SQL for production deployment | db |
npm run db:migrate | Apply pending migration files to the database | db |
Run npm run * commands inside a worktree ($HOME/app-<branch>), not on the shared coordination repo. Heavy steps (install, build, dev) would thrash its slow FUSE mount; and even the light db:* commands need the worktree's node_modules + .env, which are gitignored and therefore present only in worktrees — never in the coordination repo.
getDb() connectioninit.sh against /mnt/agents/output/app in a swarm setup — set PROJECT_PATH to the backend worktree created by setup-local.sh. Grafting directly in the shared repo edits/builds in the coordination hub.backend branch — init.sh commits the graft on the branch but does not merge. The main agent must git merge backend before page branches fork, or page agents won't inherit the tRPC client.npm install / npm run build on /mnt/agents/output/app — it's coordination only. Use a worktree.git worktree prune in any worktree — it destroys other agents' worktree metadata in the shared .git/worktrees/ directory.typeof table.$inferSelect from db/schema.ts. Hand-written createdAt: string will conflict with the actual Date objects delivered by superjson.getDb().query.*, getDb().select(), getDb().insert()).api/lib/ or api/kimi/ — framework internals. Build on top of them.src/pages/Login.tsx, src/hooks/useAuth.ts, src/const.ts, src/components/AuthLayout*.tsx are installed by the auth graft and consumed as-is. The template Login.tsx is the only OAuth entry point; sign-in CTAs navigate to LOGIN_PATH from @/const rather than constructing OAuth URLs.LOGIN_PATH.api/ from frontend code — use @contracts/ for types/constants that cross the boundary. The only exception is the type import in src/providers/trpc.tsx.api as the tRPC client name — it's trpc (imported from @/providers/trpc)..input(z.object({...})) for mutations and parameterized queries.serial() for foreign key columns — serial() is bigint unsigned auto_increment, MySQL only allows one auto-increment column per table. FK columns must use bigint("col", { mode: "number", unsigned: true }).int() for foreign keys referencing serial() PKs — type mismatch.schema.ts and run npm run db:push to sync. See Troubleshooting.db:push --force — auto-accepts destructive changes..env values — generated by init.sh with valid credentials. Do not overwrite or placeholder-ify.api/queries/connection.ts, api/middleware.ts, api/lib/, drizzle.config.ts, src/providers/trpc.tsx, .env. Build on top.Required reading before implementing features — read these docs (under docs/):
When building features on this stack:
src/ to understand the app structure (from a worktree)db/schema.ts, then run npm run db:push from the worktreeapi/ and register them in api/router.tssrc/ using the existing @/ aliasWhen to use which features:
--features db--features auth (includes db automatically)auth--template (features come from the template's .backend-features.json)| Path | What to do |
|---|---|
src/main.tsx | TRPCProvider auto-wired here (verify after init) |
src/App.tsx | Login/NotFound routes auto-wired here (auth feature only) |
src/pages/ | Route-level page components |
src/sections/ | Visual sections within a page (from webapp-building templates) |
src/components/ | New UI components |
api/router.ts | Register new tRPC routers |
api/queries/ | Add query functions for new tables (db feature) |
db/schema.ts | Add new database tables (db feature) |
contracts/ | Shared types/constants (frontend + backend) |
api/lib/ | Framework internals — don't modify |
api/kimi/ | Kimi SDK modules — don't modify (auth feature) |
Full directory tree: Project Structure
This template uses react-router v7.
import { useNavigate, useLocation, useParams, Link, Routes, Route, BrowserRouter } from "react-router";
See tRPC Best Practices and the frontend's App.tsx for current route definitions.
Port 3000 already in use — lsof -ti:3000 | xargs kill.
Database connection refused — Check DATABASE_URL in .env. Run npm run db:push before npm run dev.
User reports login failing — Verify VITE_KIMI_AUTH_URL and VITE_APP_ID in .env match the portal app config, and that src/pages/Login.tsx still matches the template (the only OAuth entry point).
npm run db:migrate fails — NEVER drop tables. Fix schema.ts, run npm run db:push, delete the broken migration file and its entry in db/migrations/meta/_journal.json, then npm run db:generate for a clean baseline.
init.sh errors that $PROJECT_PATH/src is missing — the worktree wasn't created or points at the wrong place. Create it first with swarm-workspace's setup-local.sh (NODE_MODULES_SRC=…/backend-building-swarm/scripts/template/node_modules … setup-local.sh backend $HOME/app-backend), and pass PROJECT_PATH=$HOME/app-backend.
git merge backend conflicts — the backend branch must fork from the merged scaffold; merge it before page branches fork (Phase 4.5, before Phase 5). If it diverged, re-graft on a fresh backend worktree off the current integration head.
Type errors after adding a new router — Make sure you registered it in api/router.ts inside appRouter.