Shared packages
Reusable infrastructure lives under packages/. Apps depend on these; apps never depend on each other.
| Package | Purpose |
|---|---|
@constellation-platform/auth-core | JWT types, clearance levels, permission checking |
@constellation-platform/auth-next | Next.js auth middleware (withAuth, withTenantAuth, locale primitives) |
@constellation-platform/db | Tenant-scoped Prisma client, RLS helpers, auditAction() for routine audit, correlation-id propagation |
@constellation-platform/design-tokens | The Constellation design language (warm-neutral OKLCH foundation, single amber accent, functional status colours, Geist type) + a Path A bridge aliasing every shadcn variable onto a Constellation token, Tailwind v4 @theme mapping, light/dark palettes, and a11y baseline (prefers-reduced-motion, :focus-visible). The bridge covers elevation as well as colour: Tailwind's --shadow-* scale maps onto the warm --e-* ramp, so stock shadow-sm / shadow-md / shadow-lg render warm rather than neutral-black — see Elevation below. It also carries the shared typography baseline (PLT-455): font-semibold resolves to the kit's 550 heading weight and the base body rule applies the kit's Geist feature settings ('ss01', 'cv11'), in all four consuming product apps. CSS-only — import styles.css from each app's globals.css. |
@constellation-platform/errors | Standard error hierarchy and API envelope (AppError, toErrorResponse) |
@constellation-platform/audit | Transactional audit via outbox (auditCritical() — writes audit row + publishes audit.entry.created event in the same txn) |
@constellation-platform/events | Outbox-based event publishing (publish), polling dispatcher, subscribe |
@constellation-platform/jobs | Job queue abstraction (createJobQueue({ type: 'postgres' | 'memory', ... })). Two implementations today: PostgresJobQueue (durable) and InMemoryJobQueue (tests) |
@constellation-platform/storage | Object-storage adapter. S3-compatible (MinIO in dev, S3 in cloud, MinIO on-prem) plus a Supabase Storage backend for Supabase-hosted tenants |
@constellation-platform/i18n | BCP-47 Locale type, resolveLocale(), Intl format helpers |
@constellation-platform/translation | AI-backed translation; wraps ai-core |
@constellation-platform/ai-core | Provider-agnostic LLM abstraction (Claude / mock); audit + budget |
@constellation-platform/ai-embeddings | Embedding-API provider abstraction (OpenAI / mock); pgvector-friendly output |
@constellation-platform/ai-rag | Retrieval-augmented generation primitives — combines ai-core and ai-embeddings for grounded responses |
@constellation-platform/coordinator | Hosted reasoning service — stateless consultCoordinator() over initiative-scoped Project Tracker state; every consult it persists lands as one coordinator.consults row plus an audit entry via auditCritical (a consult rejected before persistence writes neither). Reachable via the consult_coordinator MCP tool, npx pt consult, and the PT REST route. synthesizeCycleRetrospective() is the system-fired sibling (SYSTEM-attributed unless the caller names another actor type) the PT-816 cycle-close hook will call. |
@constellation-platform/testing | Test tenant/user factories, test transaction wrapper |
@constellation/contracts | Shared Zod schemas and derived types (cross-module event payloads, common shapes) |
@constellation-platform/ui | Shared React components. Notable primitives: LocaleSwitcher; PersonAvatar + avatarTint (palette-tinted initials avatar, hashing a name onto the eight --avatar-* token pairs, with an optional docked agent marker); AgentMarker (the platform's single agent-owned signal, badge or icon). See the package's README.md and AGENTS.md for the component guide, and src/index.ts for the authoritative export list |
@constellation-platform/coordinator-chat | Shared coordinator UI rendered by Project Tracker as both the full-page workspace (CoordinatorWorkspace) and the task drawer (PLT-224, PLT-237). Zone-agnostic transport via an injected resolveApiUrl. Consumed as source. |
@constellation/config | Shared ESLint, TypeScript, Vitest configs |
i18n entry points
Internationalisation primitives are split across three packages so apps can compose only what they need:
@constellation-platform/i18n— runtime-agnostic.Localeunion,SUPPORTED_LOCALES,resolveLocale(),negotiateAcceptLanguage(),formatDate/DateTime/Number/Currency, message-loader with regional → base-language → default fallback, and alocalized()JSONB overlay reader.@constellation-platform/auth-next/locale— Next.js wiring. Cookie helpers (readLocaleCookie,serializeLocaleCookie,clearLocaleCookieValue), edge-middleware integration via thelocaleResolveroption oncreateConstellationAuthMiddleware,withVaryCookie()response decorator, andAuthContext.localepopulated bywithAuth.@constellation-platform/translation— AI translation.TranslationProviderinterface andcreateTranslationProvider({ ai, model })that wrapsai-coreso tenant budget + audit are inherited.@constellation-platform/ui— sharedLocaleSwitcherclient component (server-action driven; renders null when fewer than two locales are enabled).
See Multilanguage (i18n) for the architecture overview.
Elevation
Shadows come from the design language's warm elevation ramp, not Tailwind's stock scale. @constellation-platform/design-tokens maps Tailwind's --shadow-* theme steps onto the four --e-* rungs, so the stock utilities already render warm — reach for shadow-sm / shadow-md / shadow-lg as usual and do not write shadow-[var(--e-2)].
| Utility | Rung | Typical surface |
|---|---|---|
shadow / shadow-2xs / shadow-xs / shadow-sm | --e-1 | inputs, switches, cards, active chips |
shadow-md | --e-2 | popover, dropdown menu, select content |
shadow-lg | --e-3 | dialog, sheet, submenus, drag lifts |
shadow-xl / shadow-2xl | --e-pop | drawers, command palette, floating panels |
Three things worth knowing:
- Elevation is deliberately four levels, not Tailwind's seven. The design language is near-flat, so steps collapse onto shared rungs. To retune elevation, change the four
--e-*values in the token package once — never add a role-specific shadow. - Dark mode uses neutral-black shadows, by design. A warm tint needs the higher alpha dark grounds demand to register at all, and at that alpha it reads as haze rather than depth. The warmth in dark mode comes from the neutral ramp underneath.
- A
shadow-[…]holding a literal value (e.g.shadow-[0_4px_10px_rgba(0,0,0,.1)]) opts that element out of both the ramp and the dark theme. An arbitrary value that still references a token —shadow-[var(--e-2)]— keeps resolving per theme; it is merely redundant, sinceshadow-mdalready gives you--e-2.shadow-<color>modifiers (e.g.shadow-black/20) no longer tint these steps, because Tailwind cannot parse a colour out of avar(). The separatedrop-shadow-*filter utility is not remapped and stays neutral — it is for glyph legibility over imagery, not surface elevation.
When to use which
- AI features. Start with
@constellation-platform/ai-corefor provider-agnostic completion calls (with budget + audit). Add@constellation-platform/ai-embeddingswhen you need vector embeddings (semantic search, RAG retrieval). Add@constellation-platform/ai-ragwhen you want grounded answers — it composesai-core+ai-embeddingsand handles the retrieval / context-injection wiring. For initiative-scoped reasoning over live PT + GitHub state (prioritisation, duplicate-effort detection, "what next"), call@constellation-platform/coordinator'sconsultCoordinator()— it wrapsai-coreand writes an append-onlycoordinator.consultsrow plus acoordinator.consult.createdaudit entry for every call it gets far enough to persist (input rejected up front, and a persist that itself fails, write neither). The same package'ssynthesizeCycleRetrospective()is the system-fired entry point for cycle-close retrospectives, attributed to SYSTEM unless the caller names another actor type — the PT-816 cycle-close hook is what will call it. It persists identically, is idempotent on a successful retro per cycle (a failed attempt stays retryable), emits the knowledge-base file-back event even with zero citations (the wiki's own space and dedup gates still apply), and is best-effort — every failure resolves as an outcome rather than throwing, so a retro can never fail the cycle close. - Persistence.
@constellation-platform/dbfor any tenant-scoped DB access. UsewithTenantContext()to open a transaction withapp.tenant_idset. UseauditAction()for routine audit; reach for@constellation-platform/audit'sauditCritical()only when the mutation must publish anaudit.entry.createdoutbox event for downstream SIEM. - Async work.
@constellation-platform/jobsfor one-off background work.@constellation-platform/eventsfor cross-module domain events (always wrap in the originating transaction). - Files.
@constellation-platform/storage(S3 / MinIO). - Auth. Apps wire
@constellation-platform/auth-nextand call into@constellation-platform/auth-corefor permission helpers. - UI. Always import from
@constellation-platform/ui, never from app-localcomponents/ui/. Overlays (Dialog,Sheet,Popover,DropdownMenu,Select,Tooltip,AlertDialog) all portal intodocument.body, so they stack byz-indexalone — never set az-*class on one; passlayerand let nested overlays derive from it. See overlay-layering.