listee-libs is the public monorepo that hosts the Listee SDK packages. Each module is published under the @listee/* scope so downstream applications (API, web, CLI, MCP) can consume them independently. The initial release focuses on @listee/db (database access layer) and @listee/auth (token verification utilities), with @listee/types and other packages (chat, ui, sdk) landing incrementally.
packages/<name>— Individual packages with their implementation insrc/and compiled output indist/.tsconfig.json— Shared TypeScript project references and strict compiler requirements.biome.json— Biome formatter and linter configuration.vitest.config.ts— Test runner configuration for the entire workspace..github/workflows/— CI pipelines based onlistee-dev/listee-ci@v1workflows.
- Install Bun
1.2.22(or later). We recommend pinning via"packageManager": "bun@1.2.22"in the root package.json for reproducibility. - Run
bun installat the repository root (catalog-aware installation for every workspace). - Use
bun run lint,bun run build, andbun run testto verify changes locally. - Initialize Changesets with
bun run changeset initif you are bootstrapping a fresh clone.
- Provides a thin Postgres + Drizzle ORM layer with connection caching for local development.
- Requires
POSTGRES_URLto be defined before callingcreatePostgresConnection. - Exposes helpers:
createPostgresConnection— returns a cachedpostgresclient (disabled in production); accepts optional overrides.db— shareddrizzle-ormdatabase instance backed by the cached connection.createRlsClient/createDrizzle— wrap transactions with Supabase-style RLS claims and role switching.
- Publishes generated types alongside compiled output (
sideEffects: falsefor optimal tree-shaking). - Ships with Bun-based unit tests (
packages/db/src/index.test.ts) that mockpostgres/drizzle-orm. Runbun testfrom the repo root to execute them.
- Exposes reusable authentication providers under
packages/auth/src/authentication/. createSupabaseAuthenticationvalidates Supabase-issued JWT access tokens against the project's JWKS (/auth/v1/.well-known/jwks.json), enforces issuer/audience/role constraints, and returns a typedSupabaseTokenpayload.- Shared utilities (
shared.ts,errors.ts) handle predictable error surfaces; tests live beside the implementation (supabase.test.ts) and exercise positive/negative paths. - The package emits declarations from
src/only; test files are excluded fromdist/viatsconfig.json.
- Follow the guidance in
AGENTS.mdfor agent automation workflows and repository conventions. - Keep documentation and code comments in English.
- Coordinate feature work through focused branches (
feature/...,chore/..., etc.) and submit PRs with clear descriptions, linked issues, and test evidence.
routesonly depend onqueries, translate the return values into HTTP responses, and decide status codes.queriesorchestrate the necessaryservicesandrepositoriesfor each use case and accept dependencies via factories so they remain easy to test.servicesmay depend onrepositories(never the other way around). When a service grows large, consider moving domain logic under a dedicateddomain/module and keeping application services thin.repositoriessit at the bottom layer and encapsulate external SDK calls, SQL, or KV access. They should return plain TypeScript/domain types (string,Date, structured objects) to upstream layers.
Keep a single direction: routes → queries → (services → repositories). With the stack arranged this way you can reuse everything below queries across different runtimes (e.g., Cloudflare Workers) and mock each layer in isolation during tests.
- Treat authentication (identifying who the caller is) and authorization (deciding what that caller may do) as separate concerns under the
authpackage. - Place authentication adapters in
packages/auth/src/authentication/and expose helpers such asgetAuthenticatedUser(request)so each runtime can plug in its own token/session verification. - Organize authorization policies under
packages/auth/src/authorization/with domain-specific modules (e.g.,policies/chat.tsprovidingcanAccessChat). Policies may declare repository interfaces that the application injects, keeping policy evaluation independent from data fetching details. - The recommended execution order for an authenticated endpoint is
Route Handler → Authentication → Queries → Authorization → Services/Repositories. Queries receive the authenticated actor (for example, via context) and call the relevant authorization policy before touching domain services.
Changesets drive versioning and publishing.
- Run
bun run changesetfor every meaningful change. Select the affected packages and bump type, then commit the generated.changeset/*.mdfile. - When the Changeset PR merges to
main, the CI pipeline creates a “Version Packages” PR. Merge it to stage versions. - A second merge to
maintriggers thereleasejob. Approve theproductionenvironment gate in Actions to publish to npm. - Verify the published versions with
npm view @listee/<package> versionand update release notes as needed.
- Each package
package.jsonmust declare:"publishConfig": { "access": "public", "provenance": true }, "repository": { "type": "git", "url": "https://github.com/listee-dev/listee-libs.git" }
- npm must grant Trusted Publisher access to
listee-dev/listee-libs(workflowci.yml, environmentproduction). No permanentNPM_TOKENis required. - The reusable
release.ymlfromlistee-ciusesnpx changeset version/publishwith npm@latest, so local releases can be simulated vianpx changeset version && npx changeset publish.