A monorepo containing the in-agent UI application and shared packages for the Migration Planner project.
This project is organized as a monorepo using Yarn workspaces, which allows us to manage multiple related packages and applications in a single repository. The structure is divided into two main directories:
apps/- Contains standalone applications (e.g.,agent-ui)packages/- Contains reusable packages that can be shared across applications
This monorepo structure provides several benefits:
- Code sharing: Common functionality can be extracted into packages and reused across multiple apps
- Consistent tooling: Shared development tools and configurations ensure consistency across the codebase
- Atomic changes: Related changes across packages and apps can be made in a single commit
- Simplified dependency management: Dependencies are hoisted and shared where possible, reducing duplication
The root package.json provides workspace-wide scripts and dev dependencies that standardize development across all packages and apps:
Available Scripts:
yarn build:all- Build all packages and appsyarn bundle:all- Bundle all packages for publishingyarn clean:all- Clean all build artifactsyarn check:all- Run linting checks across all workspacesyarn check:fix:all- Auto-fix linting issuesyarn format:all- Format code across all workspacesyarn api-client:update- Regenerate the API client from OpenAPI specyarn agent-client:update- Regenerate the Agent client from OpenAPI spec
Shared Dev Dependencies:
@biomejs/biome- Linting and formatting (configured inbiome.json)@openapitools/openapi-generator-cli- OpenAPI code generationtypescript- TypeScript compiler (version ~5.5.0)vite- Build tool for applications- Various type definitions (
@types/*)
Each package and app can define its own scripts and dependencies, but they inherit the shared tooling from the root. This separation is intentional and serves to:
- Standardize packages: All packages follow similar patterns (build, bundle, clean scripts)
- Align dependency versions: Shared dev dependencies ensure consistent TypeScript versions, build tools, and linting rules across the entire monorepo
- Reduce duplication: Common tools are defined once at the root level rather than in each package
Common Package Scripts:
build- Compile TypeScript to JavaScriptbundle- Build and package for distributionclean- Remove build artifactscheck- Run linting checks using Biomecheck:fix- Auto-fix linting issues using Biomeformat- Format code using Biome
App-Specific Scripts:
Apps may include additional scripts like start and preview for development workflows.
Key Features:
- Generated from OpenAPI spec using
typescript-fetchgenerator - Type-safe API calls and models
- ES6 module support
- Isomorphic code: Works in both Node.js and browser environments
TypeScript client for the Migration Planner API, auto-generated from the OpenAPI specification. Provides type-safe API methods and models for interacting with the main Migration Planner backend.
TypeScript client for the Migration Planner Agent API. Similar to api-client, but specifically for agent-related operations. Auto-generated from the Agent API OpenAPI specification.
A lightweight dependency injection (IoC) container solution for React applications, inspired by InversifyJS. Provides a simple way to manage dependencies and inject them into React components.
Key Features:
- Singleton-scoped dependency injection container
- React Context-based provider pattern
useInjectionhook for accessing dependencies in components- Minimal API surface for easy adoption
A React-based user interface application for the Migration Planner Agent. Built with Vite, React Router, and PatternFly components.
Key Technologies:
- React 18
- Vite
- React Router
- PatternFly React components
- Emotion CSS
The best approach for adding a new package or app is to copy an existing similar one and adapt it to your needs. This ensures consistency with existing patterns and configurations.
Steps:
-
Choose a similar package/app as a template (e.g., copy
packages/api-clientfor a new client package, orapps/agent-uifor a new app) -
Copy the directory to your desired location (
packages/for packages,apps/for apps) -
Update the following:
package.json: Updatename,description, and any package-specific dependenciestsconfig.json: Adjust TypeScript configuration if needed- Source code: Replace with your implementation
- README.md: Update documentation
-
Add TypeScript project reference in the root
tsconfig.json:{ "references": [ { "path": "./your-new-package/tsconfig.json" } ] } -
Ensure scripts follow conventions:
build– Compile TypeScriptbundle– Build and package (for packages)clean– Remove build artifactscheck– Run static analysis/linting (e.g., type checks, code lint)format– Format code automatically
-
Run from root to verify:
yarn install yarn build:all
This project uses the OpenAPI Generator CLI to automatically generate TypeScript clients from OpenAPI specifications. This ensures that our API clients stay in sync with the backend API definitions.
- Type Safety: Generated clients provide full TypeScript type definitions based on the OpenAPI spec
- Consistency: Ensures API clients match the backend API exactly
- Maintainability: When the API changes, we regenerate clients rather than manually updating code
- Speed: Reduces boilerplate and potential errors from manual client implementation
The OpenAPI Generator CLI is configured via openapitools.json at the root of the project. Each client package has its own generator configuration:
api-client: Generates from the main Migration Planner API specagent-client: Generates from the Agent API spec
Via Yarn Scripts (Recommended):
# Update a specific client
yarn update:api-client
yarn update:agent-clientVia Makefile (isolated container execution, no extra dependencies needed): The Makefile provides a way to run the OpenAPI Generator CLI in isolation using Docker/Podman, ensuring consistent execution across different environments:
# Update a specific client
make api-client
make agent-client
# Or use the generic generate target
make generate ARGS="--generator-key api-client"
# Interact directly with the tool
make openapi-generator-cli ARGS="list"Why you should use the Makefile?
The Makefile runs the OpenAPI Generator CLI in a containerized environment, which:
- Ensures consistency: Same tool version across all developers and CI/CD
- Avoids local installation: No need to install the CLI tool locally
- Isolates dependencies: The generator runs in its own container, avoiding conflicts
- Uses pinned versions: The container image tag is pinned to a specific version (v7.18.0) for reproducibility
The container automatically mounts the project directory, so generated files are written directly to the appropriate package directories as configured in openapitools.json.
-
Install dependencies:
yarn install
-
Build all packages:
yarn build:all
-
Start an application:
cd apps/agent-ui yarn start -
Run linting:
yarn check:all
- Making changes: Work in the appropriate package or app directory
- Testing: Run package-specific scripts or use workspace scripts from root
- Linting/Formatting: Use
yarn check:allandyarn format:allfrom root - Updating API clients: Use
yarn update:*-clientscripts or Makefile targets when backend APIs change
When making changes to the generated client packages (api-client or agent-client), you may want to test them locally in a consuming application before publishing. The following procedure uses the api-client package for demonstration, but the same steps apply to agent-client.
Steps:
-
Generate the updated client files:
make api-client
-
Bundle the package from the top-level directory:
yarn workspace @migration-planner-ui/api-client bundle
-
Locate the generated archive. The output of the bundle command will display the path to the generated
.tgzfile:➤ YN0000: Package archive generated in <path>/out/@migration-planner-ui-api-client-1.0.0-alpha.tgz -
Install the package in your consuming application using the path from the previous step:
npm i <path-to-tgz>
⚠️ Warning: Runningnpm i <path-to-tgz>will modify the consuming application'spackage.jsonand lock file. These changes must NOT be committed to version control. Make sure to revert these files before committing any other changes.