Skip to main content

Shared packages

Reusable infrastructure lives under packages/. Apps depend on these; apps never depend on each other.

PackagePurpose
@constellation-platform/auth-coreJWT types, clearance levels, permission checking
@constellation-platform/auth-nextNext.js auth middleware (withAuth, withTenantAuth, locale primitives)
@constellation-platform/dbTenant-scoped Prisma client, RLS helpers, auditAction() for routine audit, correlation-id propagation
@constellation-platform/design-tokensThe 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/errorsStandard error hierarchy and API envelope (AppError, toErrorResponse)
@constellation-platform/auditTransactional audit via outbox (auditCritical() — writes audit row + publishes audit.entry.created event in the same txn)
@constellation-platform/eventsOutbox-based event publishing (publish), polling dispatcher, subscribe
@constellation-platform/jobsJob queue abstraction (createJobQueue({ type: 'postgres' | 'memory', ... })). Two implementations today: PostgresJobQueue (durable) and InMemoryJobQueue (tests)
@constellation-platform/storageObject-storage adapter. S3-compatible (MinIO in dev, S3 in cloud, MinIO on-prem) plus a Supabase Storage backend for Supabase-hosted tenants
@constellation-platform/i18nBCP-47 Locale type, resolveLocale(), Intl format helpers
@constellation-platform/translationAI-backed translation; wraps ai-core
@constellation-platform/ai-coreProvider-agnostic LLM abstraction (Claude / mock); audit + budget
@constellation-platform/ai-embeddingsEmbedding-API provider abstraction (OpenAI / mock); pgvector-friendly output
@constellation-platform/ai-ragRetrieval-augmented generation primitives — combines ai-core and ai-embeddings for grounded responses
@constellation-platform/coordinatorHosted 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/testingTest tenant/user factories, test transaction wrapper
@constellation/contractsShared Zod schemas and derived types (cross-module event payloads, common shapes)
@constellation-platform/uiShared 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-chatShared 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/configShared 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. Locale union, SUPPORTED_LOCALES, resolveLocale(), negotiateAcceptLanguage(), formatDate/DateTime/Number/Currency, message-loader with regional → base-language → default fallback, and a localized() JSONB overlay reader.
  • @constellation-platform/auth-next/locale — Next.js wiring. Cookie helpers (readLocaleCookie, serializeLocaleCookie, clearLocaleCookieValue), edge-middleware integration via the localeResolver option on createConstellationAuthMiddleware, withVaryCookie() response decorator, and AuthContext.locale populated by withAuth.
  • @constellation-platform/translation — AI translation. TranslationProvider interface and createTranslationProvider({ ai, model }) that wraps ai-core so tenant budget + audit are inherited.
  • @constellation-platform/ui — shared LocaleSwitcher client 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)].

UtilityRungTypical surface
shadow / shadow-2xs / shadow-xs / shadow-sm--e-1inputs, switches, cards, active chips
shadow-md--e-2popover, dropdown menu, select content
shadow-lg--e-3dialog, sheet, submenus, drag lifts
shadow-xl / shadow-2xl--e-popdrawers, 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, since shadow-md already 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 a var(). The separate drop-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-core for provider-agnostic completion calls (with budget + audit). Add @constellation-platform/ai-embeddings when you need vector embeddings (semantic search, RAG retrieval). Add @constellation-platform/ai-rag when you want grounded answers — it composes ai-core + ai-embeddings and 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's consultCoordinator() — it wraps ai-core and writes an append-only coordinator.consults row plus a coordinator.consult.created audit 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's synthesizeCycleRetrospective() 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/db for any tenant-scoped DB access. Use withTenantContext() to open a transaction with app.tenant_id set. Use auditAction() for routine audit; reach for @constellation-platform/audit's auditCritical() only when the mutation must publish an audit.entry.created outbox event for downstream SIEM.
  • Async work. @constellation-platform/jobs for one-off background work. @constellation-platform/events for cross-module domain events (always wrap in the originating transaction).
  • Files. @constellation-platform/storage (S3 / MinIO).
  • Auth. Apps wire @constellation-platform/auth-next and call into @constellation-platform/auth-core for permission helpers.
  • UI. Always import from @constellation-platform/ui, never from app-local components/ui/. Overlays (Dialog, Sheet, Popover, DropdownMenu, Select, Tooltip, AlertDialog) all portal into document.body, so they stack by z-index alone — never set a z-* class on one; pass layer and let nested overlays derive from it. See overlay-layering.