## Building and running

Before submitting any changes, it is crucial to validate them by running the
full preflight check. This command will build the repository, run all tests,
check for type errors, and lint the code.

To run the full suite of checks, execute the following command:

```bash
npm run preflight
```

This single command ensures that your changes meet all the quality gates of the
project. While you can run the individual steps (`build`, `test`, `typecheck`,
`lint`) separately, it is highly recommended to use `npm run preflight` to
ensure a comprehensive validation.

## Writing Tests

This project uses **Vitest** as its primary testing framework. When writing
tests, aim to follow existing patterns. Key conventions include:

### Test Structure and Framework

- **Framework**: All tests are written using Vitest (`describe`, `it`, `expect`,
  `vi`).
- **File Location**: Test files (`*.test.ts` for logic, `*.test.tsx` for React
  components) are co-located with the source files they test.
- **Configuration**: Test environments are defined in `vitest.config.ts` files.
- **Setup/Teardown**: Use `beforeEach` and `afterEach`. Commonly,
  `vi.resetAllMocks()` is called in `beforeEach` and `vi.restoreAllMocks()` in
  `afterEach`.

### Mocking (`vi` from Vitest)

- **ES Modules**: Mock with
  `vi.mock('module-name', async (importOriginal) => { ... })`. Use
  `importOriginal` for selective mocking.
  - _Example_:
    `vi.mock('os', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, homedir: vi.fn() }; });`
- **Mocking Order**: For critical dependencies (e.g., `os`, `fs`) that affect
  module-level constants, place `vi.mock` at the _very top_ of the test file,
  before other imports.
- **Hoisting**: Use `const myMock = vi.hoisted(() => vi.fn());` if a mock
  function needs to be defined before its use in a `vi.mock` factory.
- **Mock Functions**: Create with `vi.fn()`. Define behavior with
  `mockImplementation()`, `mockResolvedValue()`, or `mockRejectedValue()`.
- **Spying**: Use `vi.spyOn(object, 'methodName')`. Restore spies with
  `mockRestore()` in `afterEach`.

### Commonly Mocked Modules

- **Node.js built-ins**: `fs`, `fs/promises`, `os` (especially `os.homedir()`),
  `path`, `child_process` (`execSync`, `spawn`).
- **External SDKs**: `@google/genai`, `@modelcontextprotocol/sdk`.
- **Internal Project Modules**: Dependencies from other project packages are
  often mocked.

### React Component Testing (CLI UI - Ink)

- Use `render()` from `ink-testing-library`.
- Assert output with `lastFrame()`.
- Wrap components in necessary `Context.Provider`s.
- Mock custom React hooks and complex child components using `vi.mock()`.

### Asynchronous Testing

- Use `async/await`.
- For timers, use `vi.useFakeTimers()`, `vi.advanceTimersByTimeAsync()`,
  `vi.runAllTimersAsync()`.
- Test promise rejections with `await expect(promise).rejects.toThrow(...)`.

### General Guidance

- When adding tests, first examine existing tests to understand and conform to
  established conventions.
- Pay close attention to the mocks at the top of existing test files; they
  reveal critical dependencies and how they are managed in a test environment.

## Git Repo

The main branch for this project is called "main"

## JavaScript/TypeScript

When contributing to this React, Node, and TypeScript codebase, please
prioritize the use of plain JavaScript objects with accompanying TypeScript
interface or type declarations over JavaScript class syntax. This approach
offers significant advantages, especially concerning interoperability with React
and overall code maintainability.

### Preferring Plain Objects over Classes

JavaScript classes, by their nature, are designed to encapsulate internal state
and behavior. While this can be useful in some object-oriented paradigms, it
often introduces unnecessary complexity and friction when working with React's
component-based architecture. Here's why plain objects are preferred:

- Seamless React Integration: React components thrive on explicit props and
  state management. Classes' tendency to store internal state directly within
  instances can make prop and state propagation harder to reason about and
  maintain. Plain objects, on the other hand, are inherently immutable (when
  used thoughtfully) and can be easily passed as props, simplifying data flow
  and reducing unexpected side effects.

- Reduced Boilerplate and Increased Conciseness: Classes often promote the use
  of constructors, this binding, getters, setters, and other boilerplate that
  can unnecessarily bloat code. TypeScript interface and type declarations
  provide powerful static type checking without the runtime overhead or
  verbosity of class definitions. This allows for more succinct and readable
  code, aligning with JavaScript's strengths in functional programming.

- Enhanced Readability and Predictability: Plain objects, especially when their
  structure is clearly defined by TypeScript interfaces, are often easier to
  read and understand. Their properties are directly accessible, and there's no
  hidden internal state or complex inheritance chains to navigate. This
  predictability leads to fewer bugs and a more maintainable codebase.

- Simplified Immutability: While not strictly enforced, plain objects encourage
  an immutable approach to data. When you need to modify an object, you
  typically create a new one with the desired changes, rather than mutating the
  original. This pattern aligns perfectly with React's reconciliation process
  and helps prevent subtle bugs related to shared mutable state.

- Better Serialization and Deserialization: Plain JavaScript objects are
  naturally easy to serialize to JSON and deserialize back, which is a common
  requirement in web development (e.g., for API communication or local storage).
  Classes, with their methods and prototypes, can complicate this process.

### Embracing ES Module Syntax for Encapsulation

Rather than relying on Java-esque private or public class members, which can be
verbose and sometimes limit flexibility, we strongly prefer leveraging ES module
syntax (`import`/`export`) for encapsulating private and public APIs.

- Clearer Public API Definition: With ES modules, anything that is exported is
  part of the public API of that module, while anything not exported is
  inherently private to that module. This provides a very clear and explicit way
  to define what parts of your code are meant to be consumed by other modules.

- Enhanced Testability (Without Exposing Internals): By default, unexported
  functions or variables are not accessible from outside the module. This
  encourages you to test the public API of your modules, rather than their
  internal implementation details. If you find yourself needing to spy on or
  stub an unexported function for testing purposes, it's often a "code smell"
  indicating that the function might be a good candidate for extraction into its
  own separate, testable module with a well-defined public API. This promotes a
  more robust and maintainable testing strategy.

- Reduced Coupling: Explicitly defined module boundaries through import/export
  help reduce coupling between different parts of your codebase. This makes it
  easier to refactor, debug, and understand individual components in isolation.

### Avoiding `any` Types and Type Assertions; Preferring `unknown`

TypeScript's power lies in its ability to provide static type checking, catching
potential errors before your code runs. To fully leverage this, it's crucial to
avoid the `any` type and be judicious with type assertions.

- **The Dangers of `any`**: Using any effectively opts out of TypeScript's type
  checking for that particular variable or expression. While it might seem
  convenient in the short term, it introduces significant risks:
  - **Loss of Type Safety**: You lose all the benefits of type checking, making
    it easy to introduce runtime errors that TypeScript would otherwise have
    caught.
  - **Reduced Readability and Maintainability**: Code with `any` types is harder
    to understand and maintain, as the expected type of data is no longer
    explicitly defined.
  - **Masking Underlying Issues**: Often, the need for any indicates a deeper
    problem in the design of your code or the way you're interacting with
    external libraries. It's a sign that you might need to refine your types or
    refactor your code.

- **Preferring `unknown` over `any`**: When you absolutely cannot determine the
  type of a value at compile time, and you're tempted to reach for any, consider
  using unknown instead. unknown is a type-safe counterpart to any. While a
  variable of type unknown can hold any value, you must perform type narrowing
  (e.g., using typeof or instanceof checks, or a type assertion) before you can
  perform any operations on it. This forces you to handle the unknown type
  explicitly, preventing accidental runtime errors.

  ```ts
  function processValue(value: unknown) {
    if (typeof value === 'string') {
      // value is now safely a string
      console.log(value.toUpperCase());
    } else if (typeof value === 'number') {
      // value is now safely a number
      console.log(value * 2);
    }
    // Without narrowing, you cannot access properties or methods on 'value'
    // console.log(value.someProperty); // Error: Object is of type 'unknown'.
  }
  ```

- **Type Assertions (`as Type`) - Use with Caution**: Type assertions tell the
  TypeScript compiler, "Trust me, I know what I'm doing; this is definitely of
  this type." While there are legitimate use cases (e.g., when dealing with
  external libraries that don't have perfect type definitions, or when you have
  more information than the compiler), they should be used sparingly and with
  extreme caution.
  - **Bypassing Type Checking**: Like `any`, type assertions bypass TypeScript's
    safety checks. If your assertion is incorrect, you introduce a runtime error
    that TypeScript would not have warned you about.
  - **Code Smell in Testing**: A common scenario where `any` or type assertions
    might be tempting is when trying to test "private" implementation details
    (e.g., spying on or stubbing an unexported function within a module). This
    is a strong indication of a "code smell" in your testing strategy and
    potentially your code structure. Instead of trying to force access to
    private internals, consider whether those internal details should be
    refactored into a separate module with a well-defined public API. This makes
    them inherently testable without compromising encapsulation.

### Type narrowing `switch` clauses

Use the `checkExhaustive` helper in the default clause of a switch statement.
This will ensure that all of the possible options within the value or
enumeration are used.

This helper method can be found in `packages/cli/src/utils/checks.ts`

### Embracing JavaScript's Array Operators

To further enhance code cleanliness and promote safe functional programming
practices, leverage JavaScript's rich set of array operators as much as
possible. Methods like `.map()`, `.filter()`, `.reduce()`, `.slice()`,
`.sort()`, and others are incredibly powerful for transforming and manipulating
data collections in an immutable and declarative way.

Using these operators:

- Promotes Immutability: Most array operators return new arrays, leaving the
  original array untouched. This functional approach helps prevent unintended
  side effects and makes your code more predictable.
- Improves Readability: Chaining array operators often lead to more concise and
  expressive code than traditional for loops or imperative logic. The intent of
  the operation is clear at a glance.
- Facilitates Functional Programming: These operators are cornerstones of
  functional programming, encouraging the creation of pure functions that take
  inputs and produce outputs without causing side effects. This paradigm is
  highly beneficial for writing robust and testable code that pairs well with
  React.

By consistently applying these principles, we can maintain a codebase that is
not only efficient and performant but also a joy to work with, both now and in
the future.

## React (mirrored and adjusted from [react-mcp-server](https://github.com/facebook/react/blob/4448b18760d867f9e009e810571e7a3b8930bb19/compiler/packages/react-mcp-server/src/index.ts#L376C1-L441C94))

### Role

You are a React assistant that helps users write more efficient and optimizable
React code. You specialize in identifying patterns that enable React Compiler to
automatically apply optimizations, reducing unnecessary re-renders and improving
application performance.

### Follow these guidelines in all code you produce and suggest

Use functional components with Hooks: Do not generate class components or use
old lifecycle methods. Manage state with useState or useReducer, and side
effects with useEffect (or related Hooks). Always prefer functions and Hooks for
any new component logic.

Keep components pure and side-effect-free during rendering: Do not produce code
that performs side effects (like subscriptions, network requests, or modifying
external variables) directly inside the component's function body. Such actions
should be wrapped in useEffect or performed in event handlers. Ensure your
render logic is a pure function of props and state.

Respect one-way data flow: Pass data down through props and avoid any global
mutations. If two components need to share data, lift that state up to a common
parent or use React Context, rather than trying to sync local state or use
external variables.

Never mutate state directly: Always generate code that updates state immutably.
For example, use spread syntax or other methods to create new objects/arrays
when updating state. Do not use assignments like state.someValue = ... or array
mutations like array.push() on state variables. Use the state setter (setState
from useState, etc.) to update state.

Accurately use useEffect and other effect Hooks: whenever you think you could
useEffect, think and reason harder to avoid it. useEffect is primarily only used
for synchronization, for example synchronizing React with some external state.
IMPORTANT - Don't setState (the 2nd value returned by useState) within a
useEffect as that will degrade performance. When writing effects, include all
necessary dependencies in the dependency array. Do not suppress ESLint rules or
omit dependencies that the effect's code uses. Structure the effect callbacks to
handle changing values properly (e.g., update subscriptions on prop changes,
clean up on unmount or dependency change). If a piece of logic should only run
in response to a user action (like a form submission or button click), put that
logic in an event handler, not in a useEffect. Where possible, useEffects should
return a cleanup function.

Follow the Rules of Hooks: Ensure that any Hooks (useState, useEffect,
useContext, custom Hooks, etc.) are called unconditionally at the top level of
React function components or other Hooks. Do not generate code that calls Hooks
inside loops, conditional statements, or nested helper functions. Do not call
Hooks in non-component functions or outside the React component rendering
context.

Use refs only when necessary: Avoid using useRef unless the task genuinely
requires it (such as focusing a control, managing an animation, or integrating
with a non-React library). Do not use refs to store application state that
should be reactive. If you do use refs, never write to or read from ref.current
during the rendering of a component (except for initial setup like lazy
initialization). Any ref usage should not affect the rendered output directly.

Prefer composition and small components: Break down UI into small, reusable
components rather than writing large monolithic components. The code you
generate should promote clarity and reusability by composing components
together. Similarly, abstract repetitive logic into custom Hooks when
appropriate to avoid duplicating code.

Optimize for concurrency: Assume React may render your components multiple times
for scheduling purposes (especially in development with Strict Mode). Write code
that remains correct even if the component function runs more than once. For
instance, avoid side effects in the component body and use functional state
updates (e.g., setCount(c => c + 1)) when updating state based on previous state
to prevent race conditions. Always include cleanup functions in effects that
subscribe to external resources. Don't write useEffects for "do this when this
changes" side effects. This ensures your generated code will work with React's
concurrent rendering features without issues.

Optimize to reduce network waterfalls - Use parallel data fetching wherever
possible (e.g., start multiple requests at once rather than one after another).
Leverage Suspense for data loading and keep requests co-located with the
component that needs the data. In a server-centric approach, fetch related data
together in a single request on the server side (using Server Components, for
example) to reduce round trips. Also, consider using caching layers or global
fetch management to avoid repeating identical requests.

Rely on React Compiler - useMemo, useCallback, and React.memo can be omitted if
React Compiler is enabled. Avoid premature optimization with manual memoization.
Instead, focus on writing clear, simple components with direct data flow and
side-effect-free render functions. Let the React Compiler handle tree-shaking,
inlining, and other performance enhancements to keep your code base simpler and
more maintainable.

Design for a good user experience - Provide clear, minimal, and non-blocking UI
states. When data is loading, show lightweight placeholders (e.g., skeleton
screens) rather than intrusive spinners everywhere. Handle errors gracefully
with a dedicated error boundary or a friendly inline message. Where possible,
render partial data as it becomes available rather than making the user wait for
everything. Suspense allows you to declare the loading states in your component
tree in a natural way, preventing “flash” states and improving perceived
performance.

### Process

1. Analyze the user's code for optimization opportunities:
   - Check for React anti-patterns that prevent compiler optimization
   - Look for component structure issues that limit compiler effectiveness
   - Think about each suggestion you are making and consult React docs for best
     practices

2. Provide actionable guidance:
   - Explain specific code changes with clear reasoning
   - Show before/after examples when suggesting changes
   - Only suggest changes that meaningfully improve optimization potential

### Optimization Guidelines

- State updates should be structured to enable granular updates
- Side effects should be isolated and dependencies clearly defined

## Comments policy

Only write high-value comments if at all. Avoid talking to the user through
comments.

## General style requirements

Use hyphens instead of underscores in flag names (e.g. `my-flag` instead of
`my_flag`).
