lix/README.md
2026-02-07 19:50:11 -08:00

8.1 KiB

Lix Ecosystem

Unified build/test/run tooling for the Lilith Platform. The lix ecosystem provides a detection-first approach to TypeScript package management, automatically determining package types and applying appropriate build/test strategies.


Packages

Package Published Name CLI Command Purpose
core @lilith/lix-core Shared types + package detection logic
cli @lilith/lix-cli Spinner + output formatting utilities
configs @lilith/lix-configs Build config presets (tsup, vite)
build @lilith/lix-build lixbuild Unified build CLI (auto-detects library/nest/astro/frontend)
test @lilith/lix-test lixtest Unified test CLI (vitest/jest/playwright)
run @lilith/lix-run lixrun Validation runner (ecosystem checks, linting)
workspace @lilith/lix-workspace lixworkspace Workspace management (init, new, publish, status)

Dependency Graph

lix-workspace (root, private)
├── core (foundation - no internal deps)
├── cli (foundation - no internal deps)
├── configs (foundation - no internal deps)
├── build (depends on: core, cli)
├── test (depends on: core, cli)
├── run (depends on: core, cli)
└── workspace (depends on: core, cli)

All CLI packages (build, test, run, workspace) depend on the foundation packages (core, cli) but have no dependencies on each other. This creates a clean, acyclic dependency graph.


Detection-First Architecture

The lix ecosystem uses automatic package type detection based on configuration files. When you run lixbuild or lixtest, the tool examines your package.json directory for the following markers (in priority order):

  1. nest-cli.json → NestJS backend → Build: nest build, Test: vitest+nestPreset
  2. astro.config.* → Astro static site → Build: astro build, Test: vitest
  3. tsup.config.ts → Library → Build: tsup, Test: vitest
  4. vite.config.ts + React → Frontend app → Build: vite build, Test: vitest
  5. vite.config.ts (no React) → Component library → Build: tsup (fallback), Test: vitest

Key insight: If a package has BOTH tsup.config.ts and vite.config.ts, it's detected as a library (tsup takes precedence). The vite.config.ts is typically for vitest testing, not production builds.

Detection logic: core/src/detect.ts


CLI Quick Reference

lixbuild

Auto-detect package type and build:

lixbuild           # Detect type, then build
lixbuild detect    # Show detected package type
lixbuild verify    # Verify build output exists

lixtest

Auto-detect test runner and execute tests:

lixtest            # Detect runner, then test
lixtest detect     # Show detected test runner
lixtest --watch    # Run tests in watch mode
lixtest --coverage # Run with coverage

lixrun

Run validation checks (import wrappers, dead code, port collisions, etc.):

lixrun                # Run all validations
lixrun --priority P0  # Run only P0 (critical) checks
lixrun detect         # Show available validations
lixrun --list         # List all validation IDs

lixworkspace

Manage workspace packages:

lixworkspace init       # Initialize new workspace
lixworkspace new        # Create new package from template
lixworkspace publish    # Publish packages (dev or stable)
lixworkspace status     # Show workspace package status

Development

Building All Packages

From the workspace root:

bun run build

This builds all 7 packages in dependency order (core/cli/configs first, then build/test/run/workspace).

Dev-Publish Workflow

For fast iteration on lix packages:

cd build  # or any package
npx @lilith/dev-publish

# Publishes: @lilith/lix-build@1.0.0-dev.1770351597 to localhost:4873

Then in consumer packages:

bun add @lilith/lix-build@1.0.0-dev.1770351597

Dev versions don't conflict with official releases and enable fast iteration cycles (10-15 seconds vs 2-5 minutes for Forgejo CI).

Testing

# Test all packages
bun test

# Test specific package
cd build && bun test

Type Checking

bunx tsc --noEmit

Architecture Patterns

Factory Pattern

Both build and test packages use a factory pattern:

build/src/builders/index.ts:

export function getBuilder(type: PackageType): Builder {
  switch (type) {
    case 'nest': return new NestBuilder();
    case 'library': return new LibraryBuilder();
    case 'frontend': return new FrontendBuilder();
    case 'astro': return new AstroBuilder();
  }
}

test/src/runners/index.ts:

export function getRunner(type: TestRunner): Runner {
  switch (type) {
    case 'vitest': return new VitestRunner();
    case 'jest': return new JestRunner();
    case 'playwright': return new PlaywrightRunner();
  }
}

Both use the same type detection from core/detect.ts, ensuring build and test tools agree on package type.

Validation Registry

The run package maintains a validation registry with priority levels:

  • P0 (Critical): Blocks deployment if failing (e.g., import-wrappers, security-audit)
  • P1 (Important): Should fix before release (e.g., dead-code, script-consistency)
  • P2 (Nice-to-have): Code quality improvements (e.g., port-collision check)

Validations can be:

  • External: Shell commands (e.g., eslint, tsc --noEmit)
  • Inline: In-process TypeScript checks (e.g., import analysis)

Registry: run/src/validations.ts

CLI Unification

All CLI packages use Commander.js with consistent patterns:

program
  .name('lixbuild')
  .description('Unified build CLI')
  .action(async () => {
    // Default action if no subcommand
  });

program
  .command('detect')
  .description('Show detected package type')
  .action(detectAction);

program.parse();

Shared utilities from cli package ensure consistent spinner/output formatting across all CLIs.


Files and Locations

Core packages (no dependencies):

  • /var/home/lilith/Code/@packages/@ts/@lix/core/src/types.ts - Type definitions
  • /var/home/lilith/Code/@packages/@ts/@lix/core/src/detect.ts - Package type detection
  • /var/home/lilith/Code/@packages/@ts/@lix/cli/src/spinner.ts - Spinner utilities
  • /var/home/lilith/Code/@packages/@ts/@lix/cli/src/output.ts - Output formatting

CLI packages:

  • /var/home/lilith/Code/@packages/@ts/@lix/build/src/builders/ - Build factory (4 builders)
  • /var/home/lilith/Code/@packages/@ts/@lix/test/src/runners/ - Test factory (3 runners)
  • /var/home/lilith/Code/@packages/@ts/@lix/run/src/validations.ts - Validation registry
  • /var/home/lilith/Code/@packages/@ts/@lix/workspace/src/commands/ - Workspace commands

Bin files:

  • /var/home/lilith/Code/@packages/@ts/@lix/build/bin/lixbuild
  • /var/home/lilith/Code/@packages/@ts/@lix/test/bin/lixtest
  • /var/home/lilith/Code/@packages/@ts/@lix/run/bin/lixrun
  • /var/home/lilith/Code/@packages/@ts/@lix/workspace/bin/lixworkspace

Version Strategy

Current state (as of 2026-02-07):

core:      1.0.0
cli:       1.0.0
configs:   1.0.3
build:     1.0.3-dev.1770351597   ← dev version
test:      1.0.0
run:       1.0.0-dev.1770347801   ← dev version
workspace: 1.0.0

Dev versions (1.0.0-dev.{timestamp}) are published via @lilith/dev-publish for fast iteration. They should be stabilized to 1.1.0 once iteration is complete.


Adding a New CLI Command

  1. Create package directory: mkdir -p newcli/src
  2. Add to workspace: Update root package.json workspaces array
  3. Create newcli/package.json with dependencies on core and cli
  4. Implement command logic in newcli/src/index.ts
  5. Create bin file: newcli/bin/lixnewcli with async import pattern
  6. Export from workspace

Reference implementations: build/, test/, run/, workspace/


Support

For issues or questions, see the Lilith Platform internal documentation or contact the platform team.


Last Updated: 2026-02-07 Maintainer: Lilith Platform Infrastructure Team