learning_ai_common_plat/AGENTS.md
saravanakumardb1 fde10be75b chore: add extraction-service to AGENTS.md, CI matrix, token pre-commit hook (7.9)
- AGENTS.md: extraction-service in layout, file ownership, deps, test table (211+ tests)
- ci.yml.disabled: extraction package + extraction-service added to matrix
- package.json: lint-staged rule to auto-generate tokens on bytelyst.tokens.json change
- ROADMAP.md: 252/278 (~91%), 7.9 done
2026-02-14 20:48:07 -08:00

20 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
Product-agnostic Yes — every Cosmos doc includes productId
Runtime Node.js (ESM), TypeScript 5.7+
Package manager pnpm (workspace)
Test runner Vitest

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 (loadProductIdentity)
│   ├── 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
│   ├── testing/                    # Shared test mocks, fixtures, Fastify inject helpers
│   └── 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
├── services/                       # @lysnrai/* product-agnostic microservices
│   ├── platform-service/           # Auth, audit, flags, notifications, blob (port 4003)
│   ├── billing-service/            # Subscriptions, Stripe, usage, licenses (port 4002)
│   ├── growth-service/             # Invitations, referrals, promos (port 4001)
│   ├── tracker-service/            # Items, comments, votes, public roadmap (port 4004)
│   ├── 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
├── pnpm-workspace.yaml             # Workspace: packages/* + services/*
├── tsconfig.base.json              # Shared TS config (ES2022, NodeNext, strict)
├── vitest.config.ts                # Root vitest config (passWithNoTests)
├── docker-compose.yml              # Full service stack + Loki + Grafana + Traefik
├── .env.example                    # Required env vars template
└── .editorconfig                   # Editor settings

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:*"

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
  • 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)
  • 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 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. 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)
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
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/billing-service/ src/modules/subscriptions/
Stripe webhooks services/billing-service/ src/modules/stripe/
Usage tracking services/billing-service/ src/modules/usage/
Plans services/billing-service/ src/modules/plans/
Licenses services/billing-service/ src/modules/licenses/
Invitations services/growth-service/ src/modules/invitations/
Referrals services/growth-service/ src/modules/referrals/
Promos services/growth-service/ src/modules/promos/
Tracker items services/tracker-service/ src/modules/items/
Public roadmap services/tracker-service/ src/modules/public/
Tracker comments services/tracker-service/ src/modules/comments/
Tracker votes services/tracker-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/

Dashboard Consumers (via file: refs)

The following dashboards in ../learning_voice_ai_agent/ consume @bytelyst/* packages:

Dashboard Packages Used
admin-dashboard-web api-client, auth, config, cosmos, errors, logger, react-auth
user-dashboard-web api-client, auth, config, cosmos, errors, logger, react-auth
tracker-dashboard-web api-client, config, cosmos, errors

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

6. How to Run Things

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

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

# ── Run all tests (277 tests across all workspaces) ─
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
pnpm --filter @lysnrai/billing-service dev
pnpm --filter @lysnrai/growth-service dev
pnpm --filter @lysnrai/tracker-service dev

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

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

# ── Docker Compose (all services + monitoring) ─────
docker compose up -d
docker compose down

# ── 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>

Additional per-service:

# billing-service + growth-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. Dependency Graph

@bytelyst/errors          ← no deps (foundation)
@bytelyst/cosmos          ← peers: @azure/cosmos
@bytelyst/config          ← peers: zod
@bytelyst/auth            ← peers: jose, bcryptjs
@bytelyst/api-client      ← no deps
@bytelyst/react-auth      ← deps: @bytelyst/api-client; peers: react
@bytelyst/design-tokens   ← no deps (standalone generator)

@lysnrai/platform-service ← @bytelyst/{config, cosmos, errors}
@lysnrai/billing-service  ← @bytelyst/{config, cosmos, errors}
@lysnrai/growth-service   ← @bytelyst/{config, cosmos, errors}
@lysnrai/tracker-service     ← @bytelyst/{config, cosmos, errors}
@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.

10. 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

11. Service Test Counts

Service / Package Tests Runner
platform-service 55 vitest
tracker-service 45 vitest
extraction-service 46 vitest
growth-service 33 vitest
billing-service 32 vitest
Total 211+

12. 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.
  6. Don't modify generated files directly — edit bytelyst.tokens.json and re-run the generator.
  7. Build packages before testing services — service tests may import from @bytelyst/* dist. Run pnpm build first if you get import errors.