# 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: ```bash ./run [options] ``` ## Quick Start **First time setup**: ```bash ./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**: ```bash ./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. ```bash ./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. ```bash ./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**: ```bash # 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. ```bash ./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. ```bash ./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. ```bash ./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.black.local/api/packages/lilith/npm/). ```bash ./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. ```bash ./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. ```bash ./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). ```bash ./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.py`: ```python """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", ) ``` 2. **Register command** in `scripts/run/script_runner.py`: ```python 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()) ``` 3. **Test the command**: ```bash ./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. ```bash # 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)