diff --git a/.gemini/commands/frontend.toml b/.gemini/commands/frontend.toml index 02242043b8..b039106444 100644 --- a/.gemini/commands/frontend.toml +++ b/.gemini/commands/frontend.toml @@ -14,41 +14,7 @@ core architecture, component patterns, and testing standards. In addition to the code context, you MUST strictly adhere to the following frontend-specific development guidelines while adding code to packages/cli. -## Testing Standards -* **Async Testing**: ALWAYS use `waitFor` from `packages/cli/src/test-utils/async.ts` instead of `vi.waitFor` to prevent flakiness and `act` warnings. NEVER use fixed waits (e.g., `await delay(100)`). -* **State Changes**: Wrap all blocks that change component state in `act`. -* **Snapshots**: Use `toMatchSnapshot` to verify rendering. -* **Rendering**: Use `render` or `renderWithProviders` from `packages/cli/src/test-utils/render.tsx` instead of `ink-testing-library` directly. -* **Mocking**: - * Reuse existing mocks/fakes where possible. - * **Parameterized Tests**: Use parameterized tests with explicit types to reduce duplication and ensure type safety. - * Avoid mocking the file system, os, or child_process if at all possible; if you have to mock the Mock critical dependencies (`fs`, `os`, `child_process`) do so ONLY at the top of the file. - -## React & Ink Architecture -* **Keyboard Handling**: You MUST use `useKeyPress.ts` from Gemini CLI for keyboard handling, NOT the standard ink library. This is critical for supporting slow terminals and multiple events per frame. - * Handle multiple events gracefully (often requires a reducer pattern, see `text-buffer.ts`). -* **State Management**: - * NEVER trigger side effects from within the body of a `setState` callback. Use a reducer or `useRef` if necessary. - * Initialize state explicitly (e.g., use `undefined` rather than `true` if unknown). -* **Performance**: - * Avoid synchronous file I/O in components. - * Do not introduce excessive property drilling; leverage or extend existing providers. - -## Configuration & Settings -* **Settings vs Args**: Use settings for user-configurable options; do not add new CLI arguments. -* **Schema**: Add new settings to `packages/cli/src/config/settingsSchema.ts`. -* **Documentation**: - * If `showInDialog: true`, document in `docs/get-started/configuration.md`. - * Ensure `requiresRestart` is correctly set. - -## Keyboard Shortcuts -* **Registration**: Define new shortcuts in `packages/cli/src/config/keyBindings.ts`. -* **Documentation**: Document all new shortcuts in `docs/cli/keyboard-shortcuts.md`. -* **Compatibility**: Avoid function keys and common VSCode shortcuts. Be cautious with `Meta` key (Mac-limited support). - -## General -* **Logging**: Use `debugLogger` for errors. NEVER leave `console.log/warn/error` in the code. -* **TypeScript**: Avoid the non-null assertion operator (`!`). +!{cat .gemini/commands/strict-development-rules.md} {{args}}. """ \ No newline at end of file diff --git a/.gemini/commands/full-context.toml b/.gemini/commands/full-context.toml index 1ab351ad2e..9d08af9ccc 100644 --- a/.gemini/commands/full-context.toml +++ b/.gemini/commands/full-context.toml @@ -17,41 +17,7 @@ prompts. In addition to the code context, you MUST strictly adhere to the following frontend-specific development guidelines when writing code in packages/cli. -## Testing Standards -* **Async Testing**: ALWAYS use `waitFor` from `packages/cli/src/test-utils/async.ts` instead of `vi.waitFor` to prevent flakiness and `act` warnings. NEVER use fixed waits (e.g., `await delay(100)`). -* **State Changes**: Wrap all blocks that change component state in `act`. -* **Snapshots**: Use `toMatchSnapshot` to verify rendering. -* **Rendering**: Use `render` or `renderWithProviders` from `packages/cli/src/test-utils/render.tsx` instead of `ink-testing-library` directly. -* **Mocking**: - * Reuse existing mocks/fakes where possible. - * **Parameterized Tests**: Use parameterized tests with explicit types to reduce duplication and ensure type safety. - * Avoid mocking the file system, os, or child_process if at all possible; if you have to mock the Mock critical dependencies (`fs`, `os`, `child_process`) do so ONLY at the top of the file. - -## React & Ink Architecture -* **Keyboard Handling**: You MUST use `useKeyPress.ts` from Gemini CLI for keyboard handling, NOT the standard ink library. This is critical for supporting slow terminals and multiple events per frame. - * Handle multiple events gracefully (often requires a reducer pattern, see `text-buffer.ts`). -* **State Management**: - * NEVER trigger side effects from within the body of a `setState` callback. Use a reducer or `useRef` if necessary. - * Initialize state explicitly (e.g., use `undefined` rather than `true` if unknown). -* **Performance**: - * Avoid synchronous file I/O in components. - * Do not introduce excessive property drilling; leverage or extend existing providers. - -## Configuration & Settings -* **Settings vs Args**: Use settings for user-configurable options; do not add new CLI arguments. -* **Schema**: Add new settings to `packages/cli/src/config/settingsSchema.ts`. -* **Documentation**: - * If `showInDialog: true`, document in `docs/get-started/configuration.md`. - * Ensure `requiresRestart` is correctly set. - -## Keyboard Shortcuts -* **Registration**: Define new shortcuts in `packages/cli/src/config/keyBindings.ts`. -* **Documentation**: Document all new shortcuts in `docs/cli/keyboard-shortcuts.md`. -* **Compatibility**: Avoid function keys and common VSCode shortcuts. Be cautious with `Meta` key (Mac-limited support). - -## General -* **Logging**: Use `debugLogger` for errors. NEVER leave `console.log/warn/error` in the code. -* **TypeScript**: Avoid the non-null assertion operator (`!`). +!{cat .gemini/commands/strict-development-rules.md} {{args}}. """ \ No newline at end of file diff --git a/.gemini/commands/review-and-fix.toml b/.gemini/commands/review-and-fix.toml index 5fb547455a..adc41ebd59 100644 --- a/.gemini/commands/review-and-fix.toml +++ b/.gemini/commands/review-and-fix.toml @@ -22,132 +22,9 @@ Follow these steps to conduct a thorough review: 4. Search the codebase if required. 5. Write a concise review of the changes, keeping in mind to encourage strong code quality and best practices. Pay particular attention to the Gemini MD file in the repo. 6. Consider ways the code may not be consistent with existing code in the repo. In particular it is critical that the react code uses patterns consistent with existing code in the repo. -7. Evaluate all tests on the changes and make sure that they are doing the following: - * Using `waitFor` from @{packages/cli/src/test-utils/async.ts} rather than - using `vi.waitFor` for all `waitFor` calls within `packages/cli`. Even if - tests pass, using the wrong `waitFor` could result in flaky tests as `act` - warnings could show up if timing is slightly different. - * Using `act` to wrap all blocks in tests that change component state. - * Using `toMatchSnapshot` to verify that rendering works as expected rather - than matching against the raw content of the output. - * If snapshots were changed as part of the changes, review the snapshots - changes to ensure they are intentional and comment if any look at all - suspicious. Too many snapshot changes that indicate bugs have been approved - in the past. - * Use `render` or `renderWithProviders` from - @{packages/cli/src/test-utils/render.tsx} rather than using `render` from - `ink-testing-library` directly. This is needed to ensure that we do not get - warnings about spurious `act` calls. If test cases specify providers - directly, consider whether the existing `renderWithProviders` should be - modified to support that use case. - * Ensure the test cases are using parameterized tests where that might reduce - the number of duplicated lines significantly. - * NEVER use fixed waits (e.g. 'await delay(100)'). Always use 'waitFor' with - a predicate to ensure tests are stable and fast. - * Ensure mocks are properly managed: - * Critical dependencies (fs, os, child_process) should only be mocked at - the top of the file. Ideally avoid mocking these dependencies altogether. - * Check to see if there are existing mocks or fakes that can be used rather - than creating new ones for the new tests added. - * Try to avoid mocking the file system whenever possible. If using the real - file system is difficult consider whether the test should be an - integration test rather than a unit test. - * `vi.restoreAllMocks()` should be called in `afterEach` to prevent test - pollution. - * Use `vi.useFakeTimers()` for tests involving time-based logic to avoid - flakiness. - * When creating parameterized tests, give the parameters types to ensure - that the tests are type-safe. -8. Evaluate all react logic carefully keeping in mind that the author of the - changes is not likely an expert on React. Key areas to audit carefully are: - * Whether `setState` calls trigger side effects from within the body of the - `setState` callback. If so, you *must* propose an alternate design using - reducers or other ways the code might be modified to not have to modify - state from within a `setState`. Make sure to comment about absolutely - every case like this as these cases have introduced multiple bugs in the - past. Typically these cases should be resolved using a reducer although - occassionally other techniques such as useRef are appropriate. Consider - suggesting that jacob314@ be tagged on the code review if the solution is - not 100% obvious. - * Whether code might introduce an infinite rendering loop in React. - * Whether keyboard handling is robust. Keyboard handling must go through - `useKeyPress.ts` from the Gemini CLI package rather than using the - standard ink library used by most keyboard handling. Unlike the standard - ink library, the keyboard handling library in Gemini CLI may report - multiple keyboard events one after another in the same React frame. This - is needed to support slow terminals but introduces complexity in all our - code that handles keyboard events. Handling this correctly often means - that reducers must be used or other mechanisms to ensure that multiple - state updates one after another are handled gracefully rather than - overriding values from the first update with the second update. Refer to - text-buffer.ts as a canonical example of using a reducer for this sort of - case. - * Ensure code does not use `console.log`, `console.warn`, or `console.error` - as these indicate debug logging that was accidentally left in the code. - * Avoid synchronous file I/O in React components as it will hang the UI. - * Ensure state initialization is explicit (e.g., use 'undefined' rather than - 'true' as a default if the state is truly unknown initially). - * Carefully manage 'useEffect' dependencies. Prefer to use a reducer - whenever practical to resolve the issues. If that is not practical it is - ok to use 'useRef' to access the latest value of a prop or state inside an - effect without adding it to the dependency array if re-running the effect - is undesirable (common in event listeners). - * NEVER disable 'react-hooks/exhaustive-deps'. Fix the code to correctly - declare dependencies. Disabling this lint rule will almost always lead to - hard to detect bugs. - * Avoid making types nullable unless strictly necessary, as it hurts - readability. - * Do not introduce excessive property drilling. There are multiple providers - that can be leveraged to avoid property drilling. Make sure one of them - cannot be used. Do suggest a provider that might make sense to be extended - to include the new property or propose a new provider to add if the - property drilling is excessive. Only use providers for properties that are - consistent for the entire application. -9. Evaluate `packages/core` (Services, Tools, Utilities): - * Ensure services are implemented as classes with clear lifecycle management (e.g., `initialize()` methods). - * Verify that `debugLogger` from `packages/core/src/utils/debugLogger.ts` is used for internal logging instead of `console`. - * Ensure all shell operations use `spawnAsync` from `packages/core/src/utils/shell-utils.ts` for consistent error handling and promise management. - * Check that filesystem errors are handled gracefully using `isNodeError` from `packages/core/src/utils/errors.ts`. - * Verify that new tools are added to `packages/core/src/tools/` and registered in `packages/core/src/tools/tool-registry.ts`. - * Ensure all new public services, utilities, and types are exported from `packages/core/src/index.ts`. - * Check that services are stateless where possible, or use the centralized `Storage` service for persistence. - * **Cross-Service Communication**: Prefer using the `coreEvents` bus (from `packages/core/src/utils/events.ts`) for asynchronous communication between services or to notify the UI of state changes. Avoid tight coupling between services. -10. Architectural Audit (Package Boundaries): - * **Logic Placement**: Non-UI logic (e.g., model orchestration, tool implementation, git/filesystem operations) MUST reside in `packages/core`. `packages/cli` should only contain UI/Ink components, command-line argument parsing, and user interaction logic. - * **Environment Isolation**: Core logic should not assume a TUI environment. Use the `ConfirmationBus` or `Output` abstractions for communicating with the user from Core. - * **Decoupling**: Actively look for opportunities to decouple services by using `coreEvents`. If a service is importing another service just to notify it of a change, it should probably be using an event instead. -11. General Gemini CLI design principles: - * Make sure that settings are only used for options that a user might - consider changing. - * Do not add new command line arguments and suggest settings instead. - * New settings must be added to packages/cli/src/config/settingsSchema.ts. - * If a setting has 'showInDialog: true', it MUST be documented in - docs/get-started/configuration.md. - * Ensure 'requiresRestart' is correctly set for new settings. - * Use 'debugLogger' for rethrown errors to avoid duplicate logging. - * All new keyboard shortcuts MUST be documented in - docs/cli/keyboard-shortcuts.md. - * Ensure new keyboard shortcuts are defined in - packages/cli/src/config/keyBindings.ts. - * If new keyboard shortcuts are added, remind the user to test them in - VSCode, iTerm2, Ghostty, and Windows to ensure they work for all - users. - * Be careful of keybindings that require the meta key as only certain - meta key shortcuts are supported on Mac. - * Be skeptical of function keys and keyboard shortcuts that are commonly - bound in VSCode as they may conflict. -12. TypeScript Best Practices: - * Use 'checkExhaustive' in the 'default' clause of 'switch' statements to - ensure all cases are handled. - * Avoid using the non-null assertion operator ('!') unless absolutely - necessary and you are confident the value is not null. - * **STRICT TYPING**: Strictly forbid 'any' and 'unknown' in both CLI and Core - packages. 'unknown' is only allowed if it is immediately narrowed using - type guards or Zod validation. Reject any code that uses 'any' or - 'unknown' without narrowing. -13. **Ruthless Cleanup**: - * If you identify significant code duplication, technical debt, or "AI Slop" (boilerplate, redundant comments), explicitly suggest initiating a `ruthless-refactorer` loop to clean it up. -14. Summarize all actionable findings into a concise but comprehensive directive output this to review_findings.md and advance to phase 2. +7. Follow these detailed review rules: +!{cat .gemini/commands/strict-development-rules.md} +8. Summarize all actionable findings into a concise but comprehensive directive output this to review_findings.md and advance to phase 2. Remember to use the GitHub CLI (`gh`) for all GitHub-related tasks, and local `git` commands if the target is 'staged'. diff --git a/.gemini/commands/review-frontend.toml b/.gemini/commands/review-frontend.toml index 39d723bdc4..e520e724f5 100644 --- a/.gemini/commands/review-frontend.toml +++ b/.gemini/commands/review-frontend.toml @@ -18,121 +18,12 @@ Follow these steps: 8. Consider ways the code may not be consistent with existing code in the repo. In particular it is critical that the react code uses patterns consistent with existing code in the repo. -9. Evaluate all tests on the PR and make sure that they are doing the following: - * Using `waitFor` from @{packages/cli/src/test-utils/async.ts} rather than - using `vi.waitFor` for all `waitFor` calls within `packages/cli`. Even if - tests pass, using the wrong `waitFor` could result in flaky tests as `act` - warnings could show up if timing is slightly different. - * Using `act` to wrap all blocks in tests that change component state. - * Using `toMatchSnapshot` to verify that rendering works as expected rather - than matching against the raw content of the output. - * If snapshots were changed as part of the pull request, review the snapshots - changes to ensure they are intentional and comment if any look at all - suspicious. Too many snapshot changes that indicate bugs have been approved - in the past. - * Use `render` or `renderWithProviders` from - @{packages/cli/src/test-utils/render.tsx} rather than using `render` from - `ink-testing-library` directly. This is needed to ensure that we do not get - warnings about spurious `act` calls. If test cases specify providers - directly, consider whether the existing `renderWithProviders` should be - modified to support that use case. - * Ensure the test cases are using parameterized tests where that might reduce - the number of duplicated lines significantly. - * NEVER use fixed waits (e.g. 'await delay(100)'). Always use 'waitFor' with - a predicate to ensure tests are stable and fast. - * Ensure mocks are properly managed: - * Critical dependencies (fs, os, child_process) should only be mocked at - the top of the file. Ideally avoid mocking these dependencies altogether. - * Check to see if there are existing mocks or fakes that can be used rather - than creating new ones for the new tests added. - * Try to avoid mocking the file system whenever possible. If using the real - file system is difficult consider whether the test should be an - integration test rather than a unit test. - * `vi.restoreAllMocks()` should be called in `afterEach` to prevent test - pollution. - * Use `vi.useFakeTimers()` for tests involving time-based logic to avoid - flakiness. - * Avoid using `any` in tests; prefer proper types or `unknown` with - narrowing. - * When creating parameterized tests, give the parameters types to ensure - that the tests are type-safe. -10. Evaluate all react logic carefully keeping in mind that the author of the PR - is not likely an expert on React. Key areas to audit carefully are: - * Whether `setState` calls trigger side effects from within the body of the - `setState` callback. If so, you *must* propose an alternate design using - reducers or other ways the code might be modified to not have to modify - state from within a `setState`. Make sure to comment about absolutely - every case like this as these cases have introduced multiple bugs in the - past. Typically these cases should be resolved using a reducer although - occassionally other techniques such as useRef are appropriate. Consider - suggesting that jacob314@ be tagged on the code review if the solution is - not 100% obvious. - * Whether code might introduce an infinite rendering loop in React. - * Whether keyboard handling is robust. Keyboard handling must go through - `useKeyPress.ts` from the Gemini CLI package rather than using the - standard ink library used by most keyboard handling. Unlike the standard - ink library, the keyboard handling library in Gemini CLI may report - multiple keyboard events one after another in the same React frame. This - is needed to support slow terminals but introduces complexity in all our - code that handles keyboard events. Handling this correctly often means - that reducers must be used or other mechanisms to ensure that multiple - state updates one after another are handled gracefully rather than - overriding values from the first update with the second update. Refer to - text-buffer.ts as a canonical example of using a reducer for this sort of - case. - * Ensure code does not use `console.log`, `console.warn`, or `console.error` - as these indicate debug logging that was accidentally left in the code. - * Avoid synchronous file I/O in React components as it will hang the UI. - * Ensure state initialization is explicit (e.g., use 'undefined' rather than - 'true' as a default if the state is truly unknown initially). - * Carefully manage 'useEffect' dependencies. Prefer to use a reducer - whenever practical to resolve the issues. If that is not practical it is - ok to use 'useRef' to access the latest value of a prop or state inside an - effect without adding it to the dependency array if re-running the effect - is undesirable (common in event listeners). - * NEVER disable 'react-hooks/exhaustive-deps'. Fix the code to correctly - declare dependencies. Disabling this lint rule will almost always lead to - hard to detect bugs. - * Avoid making types nullable unless strictly necessary, as it hurts - readability. - * Do not introduce excessive property drilling. There are multiple providers - that can be leveraged to avoid property drilling. Make sure one of them - cannot be used. Do suggest a provider that might make sense to be extended - to include the new property or propose a new provider to add if the - property drilling is excessive. Only use providers for properties that are - consistent for the entire application. -11. General Gemini CLI design principles: - * Make sure that settings are only used for options that a user might - consider changing. - * Do not add new command line arguments and suggest settings instead. - * New settings must be added to packages/cli/src/config/settingsSchema.ts. - * If a setting has 'showInDialog: true', it MUST be documented in - docs/get-started/configuration.md. - * Ensure 'requiresRestart' is correctly set for new settings. - * Use 'debugLogger' for rethrown errors to avoid duplicate logging. - * All new keyboard shortcuts MUST be documented in - docs/cli/keyboard-shortcuts.md. - * Ensure new keyboard shortcuts are defined in - packages/cli/src/config/keyBindings.ts. - * If new keyboard shortcuts are added, remind the user to test them in - VSCode, iTerm2, Ghostty, and Windows to ensure they work for all - users. - * Be careful of keybindings that require the meta key as only certain - meta key shortcuts are supported on Mac. - * Be skeptical of function keys and keyboard shortcuts that are commonly - bound in VSCode as they may conflict. -12. TypeScript Best Practices: - * Use 'checkExhaustive' in the 'default' clause of 'switch' statements to - ensure all cases are handled. - * Avoid using the non-null assertion operator ('!') unless absolutely - necessary and you are confident the value is not null. -13. If the change might at all impact the prompts sent to Gemini CLI, flagged - that the change could impact Gemini CLI quality and make sure anj-s has been - tagged on the code review. -14. Discuss with me before making any comments on the issue. I will clarify +9. Follow these detailed review rules: +!{cat .gemini/commands/strict-development-rules.md} +10. Discuss with me before making any comments on the issue. I will clarify which possible issues you identified are problems, which ones you need to investigate further, and which ones I do not care about. -15. If I request you to add comments to the issue, use +11. If I request you to add comments to the issue, use `gh pr comment {{args}} --body {{review}}` to post the review to the PR. Remember to use the GitHub CLI (`gh`) with the Shell tool for all diff --git a/.gemini/commands/strict-development-rules.md b/.gemini/commands/strict-development-rules.md new file mode 100644 index 0000000000..54c8ff80af --- /dev/null +++ b/.gemini/commands/strict-development-rules.md @@ -0,0 +1,64 @@ +# Gemini CLI Strict Development Rules + +These rules apply strictly to all code modifications and additions within the Gemini CLI project. + +## Testing Guidelines + +* **Async/Await**: Always use `waitFor` from `packages/cli/src/test-utils/async.ts` instead of `vi.waitFor` for all `waitFor` calls within `packages/cli`. NEVER use fixed waits (e.g., `await delay(100)`). Always use `waitFor` with a predicate to ensure tests are stable and fast. Using the wrong `waitFor` can result in flaky tests and `act` warnings. +* **React Testing**: Use `act` to wrap all blocks in tests that change component state. Use `render` or `renderWithProviders` from `packages/cli/src/test-utils/render.tsx` instead of `render` from `ink-testing-library` directly. This prevents spurious `act` warnings. If test cases specify providers directly, consider whether the existing `renderWithProviders` should be modified. +* **Snapshots**: Use `toMatchSnapshot` to verify that rendering works as expected rather than matching against the raw content of the output. When modifying snapshots, verify the changes are intentional and do not hide underlying bugs. +* **Parameterized Tests**: Use parameterized tests where it reduces duplicated lines. Give the parameters explicit types to ensure the tests are type-safe. +* **Mocks Management**: + * Mock critical dependencies (`fs`, `os`, `child_process`) ONLY at the top of the file. Ideally, avoid mocking these dependencies altogether. + * Reuse existing mocks and fakes rather than creating new ones. + * Avoid mocking the file system whenever possible. If using the real file system is too difficult, consider writing an integration test instead. + * Always call `vi.restoreAllMocks()` in `afterEach` to prevent test pollution. + * Use `vi.useFakeTimers()` for tests involving time-based logic to avoid flakiness. +* **Typing in Tests**: Avoid using `any` in tests; prefer proper types or `unknown` with narrowing. + +## React Guidelines (`packages/cli`) + +* **`setState` and Side Effects**: NEVER trigger side effects from within the body of a `setState` callback. Use a reducer or `useRef` if necessary. These cases have historically introduced multiple bugs; typically, they should be resolved using a reducer. +* **Rendering**: Do not introduce infinite rendering loops. Avoid synchronous file I/O in React components as it will hang the UI. Do not implement new logic for custom string measurement or string truncation. Use Ink layout instead, leveraging `ResizeObserver` as needed. +* **Keyboard Handling**: Keyboard handling MUST go through `useKeyPress.ts` from the Gemini CLI package rather than the standard ink library. This library supports reporting multiple keyboard events sequentially in the same React frame (critical for slow terminals). Handling this correctly often requires reducers to ensure multiple state updates are handled gracefully without overriding values. Refer to `text-buffer.ts` for a canonical example. +* **Logging**: Do not leave `console.log`, `console.warn`, or `console.error` in the code. +* **State & Effects**: Ensure state initialization is explicit (e.g., use `undefined` rather than `true` as a default if the state is truly unknown). Carefully manage `useEffect` dependencies. Prefer a reducer whenever practical. NEVER disable `react-hooks/exhaustive-deps`; fix the code to correctly declare dependencies instead. +* **Context & Props**: Avoid excessive property drilling. Leverage existing providers, extend them, or propose a new one if necessary. Only use providers for properties that are consistent across the entire application. +* **Code Structure**: Avoid complex `if` statements where `switch` statements could be used. Keep `AppContainer` minimal; refactor complex logic into React hooks. Evaluate whether business logic should be added to `hookSystem.ts` or integrated into `packages/core` rather than `packages/cli`. + +## Core Guidelines (`packages/core`) + +* **Services**: Implement services as classes with clear lifecycle management (e.g., `initialize()` methods). Services should be stateless where possible, or use the centralized `Storage` service for persistence. +* **Cross-Service Communication**: Prefer using the `coreEvents` bus (from `packages/core/src/utils/events.ts`) for asynchronous communication between services or to notify the UI of state changes. Avoid tight coupling between services. +* **Utilities**: Use `debugLogger` from `packages/core/src/utils/debugLogger.ts` for internal logging instead of `console`. Ensure all shell operations use `spawnAsync` from `packages/core/src/utils/shell-utils.ts` for consistent error handling and promise management. Handle filesystem errors gracefully using `isNodeError` from `packages/core/src/utils/errors.ts`. +* **Exports & Tooling**: Add new tools to `packages/core/src/tools/` and register them in `packages/core/src/tools/tool-registry.ts`. Export all new public services, utilities, and types from `packages/core/src/index.ts`. + +## Architectural Audit (Package Boundaries) + +* **Logic Placement**: Non-UI logic (e.g., model orchestration, tool implementation, git/filesystem operations) MUST reside in `packages/core`. `packages/cli` should ONLY contain UI/Ink components, command-line argument parsing, and user interaction logic. +* **Environment Isolation**: Core logic must not assume a TUI environment. Use the `ConfirmationBus` or `Output` abstractions for communicating with the user from Core. +* **Decoupling**: Actively look for opportunities to decouple services using `coreEvents`. If a service imports another just to notify it of a change, use an event instead. + +## General Gemini CLI Design Principles + +* **Settings**: Use settings for user-configurable options rather than adding new command line arguments. Add new settings to `packages/cli/src/config/settingsSchema.ts`. If a setting has `showInDialog: true`, it MUST be documented in `docs/get-started/configuration.md`. Ensure `requiresRestart` is correctly set. +* **Logging**: Use `debugLogger` for rethrown errors to avoid duplicate logging. +* **Keyboard Shortcuts**: Define all new keyboard shortcuts in `packages/cli/src/config/keyBindings.ts` and document them in `docs/cli/keyboard-shortcuts.md`. Be careful of keybindings that require the `Meta` key, as only certain meta key shortcuts are supported on Mac. Avoid function keys and shortcuts commonly bound in VSCode. + +## TypeScript Best Practices + +* Use `checkExhaustive` in the `default` clause of `switch` statements to ensure all cases are handled. +* Avoid using the non-null assertion operator (`!`) unless absolutely necessary. +* **STRICT TYPING**: Strictly forbid `any` and `unknown` in both CLI and Core packages. `unknown` is only allowed if it is immediately narrowed using type guards or Zod validation. +* NEVER disable `@typescript-eslint/no-floating-promises`. +* Avoid making types nullable unless strictly necessary, as it hurts readability. + +## TUI Best Practices + +* **Terminal Compatibility**: Consider how changes might behave differently across terminals (e.g., VSCode terminal, SSH, Kitty, default Mac terminal, iTerm2, Windows terminal). If modifying keyboard handling, integrate deeply with existing files like `KeypressContext.tsx` and `terminalCapabilityManager.ts`. +* **iTerm**: Be aware that `ITERM_SESSION_ID` may be present when users run VSCode from within iTerm, even if the terminal is not iTerm. + +## Code Cleanup + +* **Refactoring**: Actively clean up code duplication, technical debt, and boilerplate ("AI Slop") when working in the codebase. +* **Prompts**: Be aware that changes can impact the prompts sent to Gemini CLI and affect overall quality. diff --git a/packages/cli/GEMINI.md b/packages/cli/GEMINI.md index 50bc038b42..8ab50f6b57 100644 --- a/packages/cli/GEMINI.md +++ b/packages/cli/GEMINI.md @@ -5,11 +5,14 @@ - Always fix react-hooks/exhaustive-deps lint errors by adding the missing dependencies. - **Shortcuts**: only define keyboard shortcuts in - `packages/cli/src/config/keyBindings.ts + `packages/cli/src/config/keyBindings.ts` +- Do not implement any logic performing custom string measurement or string + truncation. Use Ink layout instead leveraging ResizeObserver as needed. +- Avoid prop drilling when at all possible. ## Testing - **Utilities**: Use `renderWithProviders` and `waitFor` from `packages/cli/src/test-utils/`. - **Snapshots**: Use `toMatchSnapshot()` to verify Ink output. -- **Mocks**: Use mocks as sparingly as possilble. +- **Mocks**: Use mocks as sparingly as possible.