Install
$ agentstack add skill-lukedj78-dev-flow-monorepo-sync-types ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
monorepo-sync-types — regenerate + propagate backend types across the monorepo
Contract
See references/contracts.md (vendored from dev-flow). Key facts:
- Reads
/.workflow/meta.json#stack.framework— must be"monorepo". - Reads
meta.json#stack.dbandstack.authto determine the source of truth: "supabase"→ runsupabase gen types typescriptagainst the linked project."neon-drizzle"→ introspect/pull viadrizzle-kitand re-exportInferSelectModel/InferInsertModelfrom the Drizzle schema (this is the default DB for most projects — seemodule-add/references/module-db.md)."trpc"→ re-import the server router type and re-export it."firebase"→ no auto-gen, but normalize fixed types from Firestore rules (limited)."custom-rest"→ ask the user where the schema lives (Zod / OpenAPI / TS source).- Writes generated types into
packages/shared/src/types/(NOT intopackages/api/, becausepackages/sharedis consumed by BOTH apps including for non-backend code). - Idempotent: regenerating overwrites; no-diff prints "already in sync".
- Does NOT modify
phase.
When this skill applies
- User says: "rigenera i tipi", "sync DB schema", "supabase types update", "the backend changed, update types".
- Orchestrator does NOT route here automatically — invoked on demand (e.g., after a backend migration).
Knowledge dependencies
monorepo-bootstrap/references/structure.md— forpackages/shared/src/types/location.rn-backend/references/.md— for provider-specific gen commands.module-add/references/module-db.md— for the web side conventions.
Workflow
Step 1 — Verify preconditions
Read .workflow/meta.json. Abort if:
stack.framework != "monorepo".stack.db == nullANDstack.auth == null→ "No backend configured yet. Runmodule-add dborrn-module-add dbfirst."
Read meta.json#stack_config.supabase_project_ref (or equivalent) for the gen command target.
Step 2 — Branch by provider
Supabase
Run the canonical gen command:
npx supabase gen types typescript --project-id > packages/shared/src/types/database.ts
(or --linked if supabase login + supabase link already done.)
Add to packages/shared/src/index.ts:
export type { Database } from './types/database';
Add a typed Supabase client wrapper in packages/api/src/client.ts:
import { createClient } from '@supabase/supabase-js';
import type { Database } from '@/shared/types/database';
export const supabase = createClient(
process.env.EXPO_PUBLIC_SUPABASE_URL!, // or NEXT_PUBLIC_ on web side — see decision-tree
process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY!,
);
Both web and mobile apps now import supabase from @/api/client and get full type safety: supabase.from('posts').select(...) is fully typed.
neon-drizzle
This is the default DB stack for most projects (see module-add/references/module-db.md). Drizzle's schema file is already the source of truth for types — there's no separate "gen types" command — so syncing means two things: (1) make sure the schema file matches the live DB, and (2) re-export row types to packages/shared/.
- If drift with the live database is suspected (someone ran DDL outside Drizzle, or this is the first sync), refresh the schema from the database:
``bash npx drizzle-kit pull ` This introspects the Neon database and (re)writes the schema file. Confirm the target path against module-add/references/module-db.md — by default apps/web/lib/db/schema.ts`.
- Re-export typed rows via
InferSelectModel/InferInsertModel(fromdrizzle-orm) intopackages/shared/src/types/db.ts:
```ts import type { InferSelectModel, InferInsertModel } from 'drizzle-orm'; import { users, posts } from '../../../../apps/web/lib/db/schema'; // adjust relative path to the real schema location
export type User = InferSelectModel; export type NewUser = InferInsertModel; export type Post = InferSelectModel; export type NewPost = InferInsertModel; ```
- Add to
packages/shared/src/index.ts:
``ts export * from './types/db'; ``
If the schema file was hand-edited to add tables/columns that haven't reached the database yet, don't pull (it would overwrite the new columns) — instead run the migration first (drizzle-kit generate + drizzle-kit migrate; drizzle-kit push is dev-only and destructive on column drops, per module-add/references/module-db.md), then re-export types from the now-current schema.
tRPC
The types flow automatically via TS inference — no gen step. The skill verifies the wiring is correct:
packages/api/src/client.tsimports the server'sAppRoutertype:
``ts import type { AppRouter } from '../../../server/src/router'; export const trpc = createTRPCReact(); ``
- (Optional) Re-export Zod-derived input/output types from
packages/shared/src/types/:
``ts import type { inferRouterOutputs } from '@trpc/server'; import type { AppRouter } from '../../api/src/router-type'; // a re-export export type RouterOutputs = inferRouterOutputs; ``
If the server lives outside the monorepo: import via a published @/types package OR copy the router types file into packages/shared/src/types/router.d.ts and tell the user to keep it in sync.
Firebase
No auto-gen. The skill creates skeleton types from Firestore rules + user input:
- Ask the user for the collections in use (or parse
firestore.rules). - For each collection, ask the user for the document shape OR generate a placeholder.
- Write
packages/shared/src/types/firestore.tswith the shapes.
This is a manual-maintenance scenario — Firebase doesn't ship a type-gen tool the way Supabase does.
Custom REST
Ask the user where the schema lives:
- Zod schemas in the server: ask for the path, generate
packages/shared/src/types/api.tsviaz.inferfor each. - OpenAPI spec: ask for the YAML/JSON path, run
npx openapi-typescript -o packages/shared/src/types/api.d.ts. - TS source in a separate repo: copy the relevant types into
packages/shared/src/types/api.tsand instruct the user to keep in sync.
Step 3 — Verify
Run pnpm tsc --noEmit from apps/web, apps/mobile, and packages/shared. Must pass.
If types changed in ways that broke existing code, report each error — the user fixes the consumers (the skill doesn't auto-fix arbitrary call sites).
Step 4 — Update meta.json + commit
{
"stack_config": {
"types_last_synced_at": "",
"types_source": "supabase" // or "neon-drizzle" / "trpc" / "firebase" / "custom-rest"
},
"history": [
...,
{ "skill": "monorepo-sync-types", "ran_at": "", "outputs": [...] }
]
}
If git repo: commit with chore(types): sync from .
Common anti-patterns (NEVER do)
- ❌ Generate types into
packages/api/— types are general-purpose, both apps consume them; they live inpackages/shared/. - ❌ Hand-edit generated type files — they will be overwritten next sync.
- ❌ Skip the
packages/shared/src/index.tsre-export — apps would need deep import paths. - ❌ Forget the
--project-idflag onsupabase gen types— it will fail or generate the wrong schema. - ❌ Run gen without verifying the user is logged into the right project (
supabase status). - ❌ For tRPC: import the server router via a brittle relative path (
../../../../server/src/router). Instead use a workspace import if the server is in the monorepo, or a.d.tsshim file if not.
Updating meta.json (recommended pattern)
python3 .../dev-flow/scripts/update_meta.py record-artifact \
--path packages/shared/src/types/database.ts --produced-by 'monorepo-sync-types'
python3 .../dev-flow/scripts/update_meta.py append-history \
--skill 'monorepo-sync-types' --inputs '{"source": "supabase"}' --outputs '{"types": "packages/shared/src/types/database.ts"}'
Sources
- Spec:
docs/superpowers/specs/2026-05-29-monorepo-set-design.md - Official: https://supabase.com/docs/guides/api/rest/generating-types
- Official: https://trpc.io/docs/quickstart#using-trpcs-types-on-the-client
monorepo-bootstrap/references/structure.md
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: lukedj78
- Source: lukedj78/dev-flow
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.