imajin/scripts
2026-03-06 02:22:54 -08:00
..
run chore(service-config): 🔧 Update deployment configuration script with new options and adjusted defaults 2026-03-06 02:22:54 -08:00
__init__.py chore(imajin): 🔧 🛏️ update package.json and README.md 2026-01-10 04:52:11 -08:00
generate-mordant-icons.sh chore(scripts): 🔨 Update icon generation and command execution scripts in build pipeline 2026-02-02 18:44:03 -08:00
README.md chore(imajin): 🔧 🛏️ update package.json and README.md 2026-01-10 04:52:11 -08:00

Scripts Directory

Workspace tooling and automation scripts for @image.

Structure

scripts/
├── run/
│   ├── script_runner.py      # Main command dispatcher
│   ├── install_command.py    # Install dependencies handler
│   ├── test_command.py       # Test command handler
│   ├── build_command.py      # Build command handler
│   ├── dev_command.py        # Dev server command handler
│   ├── clean_command.py      # Clean command handler
│   ├── publish_command.py    # Publish command handler
│   ├── lint_command.py       # Lint command handler
│   ├── format_command.py     # Format command handler
│   └── check_command.py      # Type check command handler
└── README.md                 # This file

Usage

All scripts are invoked through the ./run symlink at workspace root:

./run <command> [options]

Quick Start

First time setup:

./run install              # Install all dependencies (5-10 min)
./run install --build      # Install and build everything
./run install --test       # Install, build, and test (full validation)

Development workflow:

./run test                 # Run unit tests
./run build                # Build TypeScript packages
./run dev imagen-app       # Start development server

Available Commands

install

Install dependencies for all packages and services.

./run install              # Install everything
./run install --ts         # Install only TypeScript packages
./run install --py         # Install only Python services
./run install --build      # Install and build everything
./run install --test       # Install, build, and test
./run install --help       # Show install command help

What it does:

  • TypeScript: Runs npm install in each package/monorepo
  • Python: Creates .venv and runs pip install -e . in each service

Options:

  • --ts, --typescript: Install only TypeScript packages
  • --py, --python: Install only Python services
  • --build: Build TypeScript packages after installing
  • --test: Run tests after installing (implies --build)
  • -v, --verbose: Verbose output

First-time setup takes 5-10 minutes.

test

Run tests for @image workspace.

./run test              # Run unit tests (default)
./run test --all        # Same as above (explicit)
./run test --unit       # Run only unit tests (no GPU)
./run test --gpu        # Run all tests including GPU integration
./run test --help       # Show test command help

Options:

  • --all: Run all unit tests (default)
  • --unit: Run only unit tests (no GPU)
  • --gpu: Run all tests including GPU integration tests
  • -v, --verbose: Verbose output

Examples:

# Fast unit tests (30-60s)
./run test

# Full validation with GPU (5-10 min)
./run test --gpu

# Explicit unit tests only
./run test --unit

build

Build TypeScript packages.

./run build                     # Build all packages
./run build --pkg imagen-app    # Build specific package
./run build --clean             # Clean before building
./run build --help              # Show build command help

Options:

  • --pkg, --package: Specific package to build (default: all)
  • --clean: Clean before building
  • -v, --verbose: Verbose output

Available packages:

  • imagen-app, react, electron
  • imagegen-assistant/types, imagegen-assistant/client
  • image-generation/types, image-generation/client

dev

Start development servers.

./run dev imagen-app            # Start imagen-app dev server (port 3010)
./run dev image-generation      # Start SDXL service (port 8002)
./run dev imagegen-assistant    # Start prompt service (port 8003)
./run dev image-processing      # Start processing service (port 8004)
./run dev --list                # List all available services
./run dev --help                # Show dev command help

Available services:

  • imagen-app: Frontend (React, port 3010)
  • imagegen-assistant: Prompt service (Python, port 8003)
  • image-generation: SDXL service (Python, port 8002) - requires GPU
  • image-processing: Processing service (NestJS, port 8004)

Note: Services run in foreground. Use Ctrl+C to stop.

clean

Clean build artifacts and caches.

./run clean                     # Clean everything (interactive)
./run clean --all --force       # Clean everything (no confirmation)
./run clean --dist              # Clean only dist directories
./run clean --cache             # Clean only cache directories
./run clean --deps              # Clean node_modules (requires reinstall)
./run clean --venv              # Clean Python venvs (requires recreation)
./run clean --help              # Show clean command help

Options:

  • --all: Clean dist + cache (default if no flags)
  • --dist: Clean dist/, build/, .turbo directories
  • --cache: Clean pycache, .pytest_cache, *.pyc, etc.
  • --deps: Clean node_modules/ (requires reinstall after)
  • --venv: Clean Python .venv/ (requires recreation after)
  • --force: Don't ask for confirmation
  • -v, --verbose: Verbose output

publish

Publish packages to registry (http://forge.nasty.sh/api/packages/lilith/npm/).

./run publish                   # Publish all packages (interactive)
./run publish --all --dry-run   # Preview what would be published
./run publish imagen-app        # Publish specific package
./run publish --skip-build      # Publish without building first
./run publish --help            # Show publish command help

Options:

  • --all: Publish all packages
  • --dry-run: Preview without actually publishing
  • --skip-build: Skip building before publishing
  • -v, --verbose: Verbose output

Available packages:

  • imagen-app, imagen-react, imagen-electron
  • imagegen-assistant-types, imagegen-assistant-client
  • image-generation-types, image-generation-client

lint

Run linters on TypeScript and Python code.

./run lint                      # Lint everything
./run lint --ts                 # Lint only TypeScript packages
./run lint --py                 # Lint only Python services
./run lint --fix                # Auto-fix issues where possible
./run lint --help               # Show lint command help

Options:

  • --ts, --typescript: Lint only TypeScript packages
  • --py, --python: Lint only Python services
  • --fix: Auto-fix issues where possible
  • -v, --verbose: Verbose output

Linters:

  • TypeScript: eslint
  • Python: ruff, mypy

format

Format code with prettier and ruff.

./run format                    # Format everything
./run format --ts               # Format only TypeScript packages
./run format --py               # Format only Python services
./run format --check            # Check formatting without modifying files
./run format --help             # Show format command help

Options:

  • --ts, --typescript: Format only TypeScript packages
  • --py, --python: Format only Python services
  • --check: Check formatting without modifying files
  • -v, --verbose: Verbose output

Formatters:

  • TypeScript: prettier
  • Python: ruff format

check

Quick type checking validation (faster than full build).

./run check                     # Check everything
./run check --ts                # Check only TypeScript packages
./run check --py                # Check only Python services
./run check --help              # Show check command help

Options:

  • --ts, --typescript: Check only TypeScript packages
  • --py, --python: Check only Python services
  • -v, --verbose: Verbose output

Type checkers:

  • TypeScript: tsc --noEmit (no build, just type check)
  • Python: mypy (static type checking)

Use case: Fast pre-commit validation without full build.

Adding New Commands

To add a new command:

  1. Create command handler in scripts/run/<command>_command.py:
"""New command handler."""

import argparse
from pathlib import Path


def new_command(args, workspace_root: Path):
    """Handle new command.

    Args:
        args: Command-line arguments
        workspace_root: Path to workspace root

    Returns:
        Exit code (0 = success, non-zero = failure)
    """
    parser = argparse.ArgumentParser(
        prog="./run new",
        description="Description of new command",
    )

    # Add arguments
    parser.add_argument("--option", help="Example option")

    parsed_args = parser.parse_args(args)

    # Implement command logic
    print(f"Running new command with option: {parsed_args.option}")

    return 0


def register_new_command(runner):
    """Register the new command.

    Args:
        runner: ScriptRunner instance
    """
    runner.register_command(
        "new",
        new_command,
        "Short description for help text",
    )
  1. Register command in scripts/run/script_runner.py:
def main():
    """Main entry point."""
    runner = ScriptRunner()

    # Import and register commands
    import importlib.util
    script_path = Path(__file__).resolve()

    # Existing commands
    test_cmd_path = script_path.parent / "test_command.py"
    test_cmd = load_command(test_cmd_path)
    test_cmd.register_test_command(runner)

    # Add new command
    new_cmd_path = script_path.parent / "new_command.py"
    new_cmd = load_command(new_cmd_path)
    new_cmd.register_new_command(runner)

    # Run
    sys.exit(runner.run())
  1. Test the command:
./run new --help
./run --help  # Verify it appears in command list

Architecture

ScriptRunner Class

Main dispatcher that:

  • Parses top-level command
  • Routes to appropriate command handler
  • Provides unified help text
  • Handles errors and exit codes

Command Handlers

Each command handler:

  • Defines its own argument parser
  • Implements the command logic
  • Returns exit code (0 = success)
  • Registers itself with ScriptRunner

Benefits

  • Unified interface: Single entry point for all commands
  • Modular: Easy to add new commands
  • Self-documenting: Help text generated from parsers
  • Extensible: Commands can import shared utilities
  • Type-safe: Python type hints throughout

Legacy Scripts

Some scripts remain as standalone bash scripts:

  • test-all.sh - Original test runner (still supported)

The ./run command provides a Python-based alternative with better:

  • Argument parsing
  • Help text
  • Error handling
  • Extensibility

Dependencies

Required:

  • Python 3.10+

No external dependencies: Uses only Python standard library.

Testing

Test commands should be idempotent and safe to run repeatedly.

# Test the script runner itself
python3 scripts/run/script_runner.py --help
python3 scripts/run/script_runner.py test --help

# Test via symlink
./run --help
./run test --help

Notes

  • The ./run symlink resolves to scripts/run/script_runner.py
  • Commands use importlib to avoid relative import issues
  • All paths are resolved relative to workspace root
  • Exit codes follow Unix conventions (0 = success)