learning_ai_common_plat/AGENTS.md

38 KiB
Raw Blame History

AGENTS.md — AI Coding Agent Instructions

For: Claude Code, OpenAI Codex, Cursor, GitHub Copilot, Windsurf Cascade, and any AI coding agent. Repo: learning_ai_common_plat — Shared platform packages + microservices for the ByteLyst ecosystem. See also: README.md for quick start, docs/ECOSYSTEM_ARCHITECTURE.md for full architecture.


1. Project Identity

Key Value
Root package @bytelyst/root
Library scope @bytelyst/* (packages/)
Service scope @lysnrai/* (services/)
Product consumers LysnrAI, MindLyst, ChronoMind, JarvisJr, NomGap, PeakPulse
Product-agnostic Yes — every Cosmos doc includes productId
Runtime Node.js (ESM), TypeScript 5.7+
Package manager pnpm (workspace)
Test runner Vitest
Prototype stack Docker Compose with Cosmos emulator, Azurite, Mailpit, Traefik, Loki, and Grafana

2. Monorepo Layout

learning_ai_common_plat/
├── packages/                       # @bytelyst/* shared libraries
│   ├── errors/                     # Typed HTTP service errors (400429)
│   ├── cosmos/                     # Azure Cosmos DB client singleton + container registry
│   ├── config/                     # Zod-based env loader + product identity + AKV resolver
│   ├── auth/                       # JWT utilities, auth middleware, password hashing
│   ├── api-client/                 # Configurable fetch wrapper with auth token injection
│   ├── fastify-core/               # createServiceApp() factory + startService() helper
│   ├── react-auth/                 # React auth context factory (typed provider + hook)
│   ├── logger/                     # Structured logging wrapper (pino-based)
│   ├── testing/                    # Shared test mocks, fixtures, Fastify inject helpers
│   ├── blob/                       # Azure Blob Storage client + SAS token helpers
│   ├── extraction/                 # createExtractionClient(), shared types for extraction consumers
│   ├── monitoring/                 # Health-check utilities, Loki/Grafana helpers
│   ├── llm-router/                 # Deterministic LLM router: provider/model selection, fallback, health
│   └── design-tokens/              # Cross-platform tokens (JSON → CSS/TS/Kotlin/Swift)
│       ├── tokens/bytelyst.tokens.json   # ← CANONICAL SOURCE
│       ├── scripts/generate.ts           # Token generator
│       └── generated/                    # Output: tokens.css, tokens.ts, MindLystTokens.kt, MindLystTheme.swift
├── dashboards/                     # Product-agnostic web dashboards (Next.js)
│   ├── admin-web/                  # Platform admin console (port 3001)
│   └── tracker-web/                # Issue tracker + public roadmap (port 3003)
├── services/                       # @lysnrai/* product-agnostic microservices
│   ├── platform-service/           # Product-agnostic platform: auth, audit, flags, notifications, blob,
│   │                               #   invitations, referrals, promos, subscriptions, usage, plans,
│   │                               #   licenses, stripe, items, comments, votes, public (port 4003)
│   │                               #   NOTE: Product-specific modules migrated to product repos' backend/
│   ├── extraction-service/         # LangExtract text extraction + Python sidecar (port 4005)
│   └── monitoring/                 # Loki + Grafana config, health-check script
├── docs/                           # Architecture docs, roadmap, analysis
├── package.json                    # Root scripts: build, test, typecheck, clean, prototype:self-test
├── pnpm-workspace.yaml             # Workspace: packages/* + services/* + dashboards/*
├── tsconfig.base.json              # Shared TS config (ES2022, NodeNext, strict)
├── vitest.config.ts                # Root vitest config (passWithNoTests)
├── docker-compose.yml              # Prototype stack: services + Cosmos emulator + Azurite + Mailpit + monitoring
├── .env.example                    # Required env vars template
└── .editorconfig                   # Editor settings

2A. Prototype Runtime Conventions

  • The current single-host prototype is defined by docker-compose.yml.
  • Prototype state currently lives in:
    • Cosmos DB Emulator
    • Azurite blob storage
    • Mailpit SMTP sandbox
  • Reuse the existing prototype diagnostics instead of adding parallel health endpoints:
    • GET /health
    • GET /api/health/dependencies
    • GET /api/self-test
    • GET /api/self-test.json
  • The canonical host-side smoke test command is pnpm prototype:self-test.
  • The underlying implementation is scripts/prototype-self-test.sh. Extend it instead of creating duplicate one-off prototype scripts.
  • If you change prototype infra, also update:

Current local prototype endpoints

  • platform-service: http://localhost:4003
  • extraction-service: http://localhost:4005
  • mcp-server: http://localhost:4007
  • Cosmos Data Explorer: http://localhost:1234
  • Azurite blob endpoint: http://localhost:10000
  • Mailpit SMTP: localhost:1025
  • Mailpit inbox UI: http://localhost:8025

3. Tech Stack Rules

TypeScript (all packages + services)

  • Module system: ESM ("type": "module" everywhere)
  • TS target: ES2022, moduleResolution: NodeNext
  • Base config: All packages/services extend ../../tsconfig.base.json
  • Builds: tsc — outputs to dist/
  • Tests: Vitest with passWithNoTests: true at root

Service framework (Fastify)

  • Framework: Fastify 5 with Zod validation
  • Module pattern: types.tsrepository.tsroutes.ts per module
  • Auth: JWT via jose — platform-service issues, all others validate
  • Database: Azure Cosmos DB via @azure/cosmos
  • Logging: Fastify built-in req.log / app.log (never console.log)
  • Health: Every service exposes GET /health{ status: "ok", service, requestId }
  • Request tracing: x-request-id header propagated across all services
  • Dev mode: tsx watch src/server.ts

Package conventions

  • All packages export from src/index.tsdist/index.js
  • Use exports field in package.json (not just main)
  • Peer dependencies for heavy/shared deps (@azure/cosmos, jose, bcryptjs, react, zod)
  • Workspace deps: "@bytelyst/errors": "workspace:*"
  • If a dashboard or app consumes a local package outside the pnpm workspace, build the package first and import from dist/, not raw src/

4. Coding Conventions

MUST follow

  • Every Cosmos document MUST include a productId field
  • Every REST endpoint MUST validate input with Zod schemas
  • Every service MUST propagate x-request-id headers
  • Prototype infra changes MUST preserve pnpm prototype:self-test
  • Prototype dependency checks belong in the shared status/self-test surfaces, not ad hoc endpoints
  • Use PRODUCT_ID from @bytelyst/config (loadProductIdentity()) — never hardcode
  • Services use self-contained Zod config schemas in src/lib/config.ts (avoids zod version mismatch with shared packages)
  • Services re-export from @bytelyst/* in their src/lib/ files (errors.ts, cosmos.ts, product-config.ts)
  • For LLM routing, prefer @bytelyst/llm-router as the source of truth; do not introduce parallel routing logic unless explicitly required
  • __LOCAL_LLMs/dashboard uses server-side routing in src/app/api/ollama/chat/route.ts; preserve that pattern and keep the UI as a thin client
  • Commit messages: type(scope): description — types: feat, fix, docs, refactor, test, chore

MUST NOT do

  • Never use console.log in production code — use req.log or app.log in Fastify
  • Never use any type — use Zod inference or explicit types
  • Never hardcode secrets or API keys
  • Secret guardrails: Husky runs scripts/secret-scan-staged.sh (pre-commit) and scripts/secret-scan-repo.sh (pre-push). See docs/WINDSURF/CODEX_SESSION_SUMMARY_AND_PLAYBOOK.md.
  • Never commit real emulator keys or blob account keys in tracked files; keep placeholders in .env.example
  • Never modify tests to make them pass — fix the actual code
  • Never delete existing comments or documentation unless explicitly asked
  • Never add emojis to code unless explicitly asked

5. Design System (Critical)

NEVER hardcode colors

All colors MUST come from @bytelyst/design-tokens. Hardcoded hex values create inconsistency and maintenance debt.

Platform DON'T DO
Web color: '#5A8CFF' color: var(--ml-accent-primary)
Web (Tailwind) bg-[#5A8CFF] bg-[var(--ml-accent-primary)]
iOS Color(hex: 0x5A8CFF) MindLystColors.darkAccentPrimary
Android/KMP Color(0xFF5A8CFF) Color(MindLystTokens.Dark.ACCENT_PRIMARY)
React Native backgroundColor: '#5A8CFF' tokens.colors.accentPrimary

Token file locations

packages/design-tokens/
├── tokens/bytelyst.tokens.json          # ← CANONICAL SOURCE (edit this)
├── generated/
│   ├── tokens.css                       # Web: CSS custom properties
│   ├── tokens.ts                        # TypeScript constants
│   ├── MindLystTokens.kt                # Kotlin/KMP/Android
│   ├── MindLystTheme.swift              # Swift/iOS
│   └── react-native/tokens.ts           # React Native
└── scripts/
    ├── generate.ts                      # Main generator
    ├── generate-react-native.ts         # RN generator
    ├── validate-tokens.cjs              # Validation script
    └── token-coverage.cjs               # Coverage report

How to update tokens

  1. Edit packages/design-tokens/tokens/bytelyst.tokens.json
  2. Run pnpm --filter @bytelyst/design-tokens generate
  3. Copy generated files to consumer repos (see per-repo AGENTS.md)
  4. Commit both the JSON source AND generated files

Product-specific token sections

Each product has a dedicated section in bytelyst.tokens.json:

Product Token Section Example
MindLyst color.brain BRAIN_WORK, BRAIN_HOME
JarvisJr color.jarvisjr AGENT_COACH, AGENT_LINGUA
PeakPulse color.peakpulse ACTIVITY_HIKE, SPEED_ZONE_FAST
ChronoMind color.chronomind URGENCY_CRITICAL, FOCUS_MODE
NomGap color.nomgap STAGE_KETOSIS, AUTOPHAGY_METER
LysnrAI color.lysnrai RECORDING_ACTIVE, DICTATION_MODE

Validation

Check for hardcoded colors before committing:

# In any product repo
node ../learning_ai_common_plat/packages/design-tokens/scripts/validate-tokens.cjs src/

# Get coverage report
node ../learning_ai_common_plat/packages/design-tokens/scripts/token-coverage.cjs src/

CI Integration: All PRs should run the validation script and fail if new hardcoded colors are introduced.

Current adoption status (2026-03-03)

Product Token Adoption Status
MindLyst iOS 100% Good
MindLyst Android 100% Good
ChronoMind Web 0% Critical
ChronoMind iOS 0% Critical
PeakPulse iOS 0% Needs tokens
NomGap 0% Critical (466 hardcoded)
LysnrAI iOS 0% Critical
JarvisJr iOS 0% Critical

See full audit: docs/design-system/DESIGN_SYSTEM_AUDIT_2026-03-03.md

6. File Ownership Map

Domain Location Key Files
Errors packages/errors/ src/index.tsBadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, ConflictError, RateLimitError
Cosmos client packages/cosmos/ src/index.tsgetCosmosClient(), getContainer(), container registry
Config / Product ID packages/config/ src/index.tsloadEnvConfig(), loadProductIdentity(), getProductId()
JWT / Auth packages/auth/ src/index.tssignJwt(), verifyJwt(), hashPassword(), verifyPassword(), auth middleware
API client packages/api-client/ src/index.tscreateApiClient() with token injection
React auth packages/react-auth/ src/index.tscreateAuthContext() factory (provider + hook)
LLM router packages/llm-router/ src/router.ts — route/plan/fallback, src/registry.ts — providers incl. local Ollama
Design tokens packages/design-tokens/ tokens/bytelyst.tokens.json (source), scripts/generate.ts (generator), generated/ (output)
Auth / JWT issue services/platform-service/ src/modules/auth/
Feature flags services/platform-service/ src/modules/flags/ — FNV-1a hash for deterministic rollout
Blob storage services/platform-service/ src/modules/blob/, src/lib/blob.ts — SAS tokens, CRUD
Prototype status services/platform-service/ src/modules/status/ — dependency health JSON, self-test JSON, self-test HTML
Delivery / SMTP services/platform-service/ src/modules/delivery/ — SMTP delivery, Mailpit-backed prototype email flows
Audit log services/platform-service/ src/modules/audit/
Notifications services/platform-service/ src/modules/notifications/
Rate limiting services/platform-service/ src/modules/rate-limit/
Subscriptions services/platform-service/ src/modules/subscriptions/
Stripe webhooks services/platform-service/ src/modules/stripe/
Usage tracking services/platform-service/ src/modules/usage/
Plans services/platform-service/ src/modules/plans/
Licenses services/platform-service/ src/modules/licenses/
Invitations services/platform-service/ src/modules/invitations/
Referrals services/platform-service/ src/modules/referrals/
Promos services/platform-service/ src/modules/promos/
Tracker items services/platform-service/ src/modules/items/
Public roadmap services/platform-service/ src/modules/public/
Tracker comments services/platform-service/ src/modules/comments/
Tracker votes services/platform-service/ src/modules/votes/
Extraction routes services/extraction-service/ src/modules/extract/ — POST /extract, /extract/batch, /extract/jobs, /extract/models
Extraction tasks services/extraction-service/ src/modules/tasks/ — predefined task library (triage, transcript, memory-insight, etc.)
Extraction Python services/extraction-service/ python/src/ — LangExtract sidecar (FastAPI :4006), extractor, task registry, language detection
Extraction package packages/extraction/ src/index.tscreateExtractionClient(), shared types for consumers
Monitoring services/monitoring/ health-check.ts, loki/, grafana/
Local LLM dashboard __LOCAL_LLMs/dashboard/ src/app/api/ollama/chat/route.ts — shared router + Ollama bridge, src/app/lib/llm-router.ts — built package re-export

Dashboard Consumers (via file: refs)

The following dashboards consume @bytelyst/* packages:

Dashboard Location Packages Used
admin-web dashboards/admin-web/ (this repo) api-client, auth, config, cosmos, errors, logger, react-auth
user-dashboard-web ../learning_voice_ai_agent/ api-client, auth, config, cosmos, errors, logger, react-auth
tracker-web dashboards/tracker-web/ (this repo) api-client, config, cosmos, errors

Prerequisite: Run pnpm build in this repo before running npm install in any dashboard.

Local Mission Control Dashboard

__LOCAL_LLMs/dashboard/ is a standalone Next.js app for local Ollama usage. It is not part of the pnpm workspace, but it consumes @bytelyst/llm-router.

  • Build source of truth: packages/llm-router/
  • Dashboard bridge: __LOCAL_LLMs/dashboard/src/app/lib/llm-router.ts
  • Chat routing path: __LOCAL_LLMs/dashboard/src/app/api/ollama/chat/route.ts
  • The dashboard must consume the built package output from packages/llm-router/dist/
  • __LOCAL_LLMs/dashboard/package.json runs predev and prebuild hooks to build @bytelyst/llm-router automatically
  • Auto model selection should happen on the server route, not in the React client

6. How to Run Things

# ── Install ────────────────────────────────────────
pnpm install

# ── Build all packages + services ──────────────────
pnpm build

# ── Run all tests ────────────────────────────────
pnpm test

# ── Type-check everything ──────────────────────────
pnpm typecheck

# ── Clean dist/ in all packages ────────────────────
pnpm clean

# ── Run a specific service in dev mode ─────────────
pnpm --filter @lysnrai/platform-service dev    # port 4003
pnpm --filter @lysnrai/extraction-service dev  # port 4005

# ── Run tests for one workspace ────────────────────
pnpm --filter @lysnrai/platform-service test
pnpm --filter @bytelyst/errors test
pnpm --filter @bytelyst/llm-router test

# ── Generate design tokens ─────────────────────────
pnpm --filter @bytelyst/design-tokens generate

# ── Local LLM dashboard ────────────────────────────
cd __LOCAL_LLMs/dashboard && npm run dev      # predev builds @bytelyst/llm-router first
cd __LOCAL_LLMs/dashboard && npm run build    # prebuild builds @bytelyst/llm-router first

# ── Docker Compose (all services + monitoring) ─────
docker compose up -d
docker compose down
pnpm prototype:self-test

# ── Portable builds for consumer repos ────────────
# Pack @bytelyst/* tarballs so Docker/CI builds don't need this sibling repo
./scripts/prep-consumer.sh /path/to/consumer-dir           # pack + rewrite
./scripts/prep-consumer.sh /path/to/consumer-dir --restore # undo

# ── Health check all services ──────────────────────
pnpm --filter @lysnrai/monitoring check

7. Common Patterns

Adding a new Fastify module

  1. Create services/<service>/src/modules/<name>/types.ts — Zod schemas + TS interfaces
  2. Create services/<service>/src/modules/<name>/repository.ts — Cosmos CRUD
  3. Create services/<service>/src/modules/<name>/routes.ts — REST endpoints
  4. Register in services/<service>/src/server.ts: await app.register(routes, { prefix: "/api" })
  5. Add tests: services/<service>/src/modules/<name>/<name>.test.ts

Adding a new shared package

  1. Create packages/<name>/ with package.json (name: "@bytelyst/<name>")
  2. Add src/index.ts with exports
  3. Add tsconfig.json extending ../../tsconfig.base.json
  4. Heavy deps go in peerDependencies, not dependencies
  5. Consumer services add "@bytelyst/<name>": "workspace:*" to their dependencies

Using shared packages in services

Services re-export from @bytelyst/* in src/lib/ for clean internal imports:

// src/lib/errors.ts
export { BadRequestError, NotFoundError, ConflictError } from '@bytelyst/errors';

// src/lib/cosmos.ts
export { getCosmosClient, getContainer } from '@bytelyst/cosmos';

// src/lib/product-config.ts
import { loadProductIdentity } from '@bytelyst/config';
const identity = loadProductIdentity();
export const PRODUCT_ID = identity.productId;

Design token workflow

  1. Edit packages/design-tokens/tokens/bytelyst.tokens.json
  2. Run pnpm --filter @bytelyst/design-tokens generate
  3. Copy generated files to consumer repos:
    • MindLystTokens.ktmindlyst-native/shared/.../theme/
    • MindLystTheme.swiftmindlyst-native/iosApp/
    • Token CSS → design-system/web/mindlyst.css (token section only)

8. Environment Variables

Required by all services (see .env.example):

COSMOS_ENDPOINT=https://<account>.documents.azure.com:443/
COSMOS_KEY=<primary-key>
COSMOS_DATABASE=lysnrai
JWT_SECRET=<shared-secret>

Prototype Docker defaults differ from production:

  • COSMOS_ENDPOINT=http://cosmos-emulator:8081
  • STORAGE_PROVIDER=azure with Azurite-backed blob config
  • EMAIL_PROVIDER=smtp with SMTP_HOST=mailpit
  • Use placeholders in tracked files; keep real local values in .env

Additional per-service:

# platform-service
STRIPE_SECRET_KEY=<stripe-key>
STRIPE_WEBHOOK_SECRET=<webhook-secret>

# platform-service (blob storage)
AZURE_BLOB_CONNECTION_STRING=<connection-string>
AZURE_BLOB_ACCOUNT_NAME=bytelystblobs
AZURE_BLOB_ACCOUNT_KEY=<account-key>

# All services
DEFAULT_PRODUCT_ID=lysnrai

9. Corporate Network / Proxy Setup

Development happens on a corporate network with a TLS-intercepting proxy. The NETWORK env var controls all proxy behavior — no manual toggling needed.

Quick Reference

Tool Corporate proxy mechanism Config location
npm / pnpm NPM_CONFIG_REGISTRY → JFrog proxy, NPM_CONFIG_STRICT_SSL=false switch-network.sh
Node.js NODE_TLS_REJECT_UNAUTHORIZED=0 switch-network.sh
Python (pip) PIP_TRUSTED_HOST, http_proxy/https_proxy switch-network.sh
Gradle / Android / KMP Custom JVM truststore with corporate CA cert ~/.gradle/gradle.properties + GRADLE_OPTS
curl / general HTTP http_proxy/https_proxycso.proxy.att.com:8080 switch-network.sh

How it works

  1. ~/.zshrc sets export NETWORK=corp (or home)
  2. ~/.zshrc sources scripts/switch-network.sh from this repo
  3. The script conditionally sets/unsets all proxy env vars based on NETWORK
  4. On new shell: 🏢 NETWORK=corp — proxy active or 🏠 NETWORK=home — direct internet

Key files

File Purpose
scripts/switch-network.sh Central network switch — sets all proxy vars
~/.gradle/gradle.properties Gradle daemon JVM args (truststore) + HTTP proxy host/port
~/.gradle/ssl/gradle-cacerts.jks Java truststore = default cacerts + ATT CSO proxy CA cert

Gradle SSL (TLS interception)

The corporate proxy (cso.proxy.att.com) does TLS interception — it replaces upstream TLS certificates with its own, signed by the ATTINTERNALROOTv2 CA. Gradle's JVM doesn't trust this CA by default.

Solution: A custom Java truststore (~/.gradle/ssl/gradle-cacerts.jks) that includes:

  • All default Java CA certificates (from $JAVA_HOME/lib/security/cacerts)
  • The AT&T CSO proxy CA certificate

The truststore is passed to Gradle via:

  • GRADLE_OPTS env var (set by switch-network.sh when NETWORK=corp) — for the wrapper bootstrap JVM
  • org.gradle.jvmargs in ~/.gradle/gradle.properties — for the daemon JVM

Recreate truststore (needed after Java updates):

mkdir -p ~/.gradle/ssl
JAVA_HOME=$(/usr/libexec/java_home)
cp "$JAVA_HOME/lib/security/cacerts" ~/.gradle/ssl/gradle-cacerts.jks
echo | openssl s_client -connect services.gradle.org:443 \
  -proxy cso.proxy.att.com:8080 -showcerts 2>/dev/null \
  | awk 'BEGIN{c=0} /BEGIN CERT/{c++} c==2{print} /END CERT/&&c==2{exit}' \
  > /tmp/corp-ca.pem
keytool -importcert -noprompt -trustcacerts -alias att-cso-proxy \
  -file /tmp/corp-ca.pem \
  -keystore ~/.gradle/ssl/gradle-cacerts.jks -storepass changeit
  • Always use NETWORK env var — never hardcode proxy URLs in app code
  • Gradle builds require GRADLE_OPTS with truststore when on corp network (handled automatically by switch-network.sh)
  • If a Gradle build fails with SSL errors, verify echo $GRADLE_OPTS shows the truststore path
  • If adding a new tool that fetches from the internet, add its proxy config to switch-network.sh
  • ~/.gradle/gradle.properties is a local-only file — never commit it to any repo

Kotlin Platform SDK (packages/kotlin-platform-sdk/)

The shared Kotlin SDK is consumed by Android apps as a composite build via includeBuild() in each product's settings.gradle.kts. Key details:

  • settings.gradle.kts declares pluginManagement and dependencyResolutionManagement repos (required for composite builds to resolve their own deps)
  • build.gradle.kts uses the Compose compiler plugin for UI components (SurveyUI, InAppMessageUI)
  • Uses kotlinOptions { jvmTarget = "17" } (not compilerOptions {}) for compatibility

10. Dependency Graph

@bytelyst/errors          ← no deps (foundation)
@bytelyst/cosmos          ← peers: @azure/cosmos
@bytelyst/config          ← peers: zod; includes AKV resolver (resolveKeyVaultSecrets)
@bytelyst/auth            ← peers: jose, bcryptjs
@bytelyst/api-client      ← no deps
@bytelyst/react-auth      ← deps: @bytelyst/api-client; peers: react
@bytelyst/blob            ← peers: @azure/storage-blob
@bytelyst/extraction      ← no deps (types + client factory)
@bytelyst/monitoring      ← no deps (health-check utilities)
@bytelyst/llm-router      ← no deps (deterministic provider/model router + local Ollama plan support)
@bytelyst/fastify-core    ← deps: fastify; createServiceApp() + startService()
@bytelyst/logger          ← deps: pino
@bytelyst/testing         ← deps: vitest; shared mocks + Fastify inject helpers
@bytelyst/design-tokens   ← no deps (standalone generator)

@lysnrai/platform-service    ← @bytelyst/{fastify-core, config, cosmos, errors, auth, blob}
@lysnrai/extraction-service  ← @bytelyst/{fastify-core, config, cosmos, errors, auth}

Build order: packages first (they have no inter-deps), then services. pnpm build handles this automatically via workspace topology.

11. Key Documents

When you need to... Read this
Understand the full architecture docs/ECOSYSTEM_ARCHITECTURE.md
See the extraction roadmap docs/ROADMAP.md
Understand why this repo exists docs/COMMON_PLATFORM_ANALYSIS.md
Quick start / consuming packages README.md
LysnrAI product repo conventions ../learning_voice_ai_agent/AGENTS.md
MindLyst native repo conventions ../learning_multimodal_memory_agents/AGENTS.md

12. Service Test Counts

Service / Package Tests Runner
platform-service 800 vitest
extraction-service 46 vitest
packages (various) ~30 vitest
Total 876+

Note: billing-service, growth-service, and tracker-service were consolidated into platform-service (Feb 2026). Product-specific modules migrated to product repo backends (see below).

13. Product-Specific Backends

Product-specific API modules have been migrated from platform-service into each product repo's backend/ directory:

Product Repo Port Modules Tests
PeakPulse ../learning_ai_peakpulse/backend/ 4010 peak-sessions, peak-routes 32
ChronoMind ../learning_ai_clock/backend/ 4011 timers, routines, households, shared-timers 130
JarvisJr ../learning_ai_jarvis_jr/backend/ 4012 jarvis-agents, jarvis-sessions, jarvis-memory, jarvis-teams, marketplace 198
NomGap ../learning_ai_fastgap/backend/ 4013 fasting-sessions, fasting-protocols, body-stages, social-fasting, meal-log, push-triggers 152
MindLyst ../learning_multimodal_memory_agents/backend/ 4014 brains, memory, reflections, daily-briefs, streaks 59

Each product backend uses @bytelyst/* packages via file: refs and follows the same Fastify module pattern.

14. Common Pitfalls

  1. Don't import zod from @bytelyst/config in services — services bundle their own zod version. Use self-contained Zod schemas in src/lib/config.ts.
  2. Don't forget productId — every Cosmos document must include it.
  3. Don't use dependencies for heavy libs in packages — use peerDependencies so consumers control the version.
  4. Don't mix up package scopes — libraries are @bytelyst/*, services are @lysnrai/*.
  5. Don't run npm commands — this is a pnpm workspace. Always use pnpm. Exception: __LOCAL_LLMs/dashboard/ is intentionally npm-managed and may use npm run dev/build/start.
  6. Don't modify generated files directly — edit bytelyst.tokens.json and re-run the generator.
  7. Build packages before testing services or non-workspace dashboards — service tests and __LOCAL_LLMs/dashboard may import from @bytelyst/* dist/. Run pnpm build first if you get import errors.
  8. Don't duplicate LLM routing logic — update @bytelyst/llm-router first, then have consumers call it.

Cross-Repo Automation

For periodic maintenance tasks that span all ByteLyst repos (test audits, coverage gaps, dependency checks, secret scans, typecheck sweeps), see the Coding Agent Automation Playbook:

docs/devops/CODING_AGENT_AUTOMATION_PLAYBOOK.md

Key tasks: workspace hygiene sweep, cross-repo test suite, backend/web coverage gap analysis, TypeScript typecheck sweep, dependency health check, secret scan, code quality audit, AGENTS.md consistency check.