diff --git a/.gemini/skills/regression-finder/SKILL.md b/.gemini/skills/regression-finder/SKILL.md new file mode 100644 index 0000000000..0f9e1b8946 --- /dev/null +++ b/.gemini/skills/regression-finder/SKILL.md @@ -0,0 +1,55 @@ +--- +name: regression-finder +description: Identify the root cause of a regression by scanning recent PRs and commits or using automated bisecting. Use when a user reports a bug that "used to work before", "broke", "stopped working", or asks "which PR caused this regression". +--- + +# Regression Finder + +## Overview + +This skill helps you find the exact change (PR or commit) that introduced a bug. It uses a combination of metadata analysis (searching PR titles and file changes) and behavioral analysis (automated `git bisect`). + +## Workflow + +### 1. Reproduction Assessment +First, determine if the bug is reliably reproducible. +- Ask the user for a reproduction command or script. +- Attempt to write a minimal unit test or shell script. +- **CRITICAL**: If you cannot create a **reliable** test (e.g., due to complexity, external deps, or flakiness), **DO NOT** create an unreliable one. Skip `git bisect` and proceed to Step 2 to rely solely on metadata and code analysis. + +### 2. Metadata Culprit Search (PR Focus) +Scan recent history to find the PR that likely caused the issue. +- **Prioritize finding the Pull Request (PR)**. PRs provide context (why a change was made) that commits lack. +- **Targeted File Search**: If you have high confidence in which files are involved (e.g., a UI bug in `packages/cli`), search for PRs touching those files first: + - Use `git log -n 30 --pretty=format:"%h %s" -- ` to see the most recent commits to those files. + - Look for commit messages that mention PR numbers (e.g., "Merge pull request #123" or "feat: ... (#456)"). +- **Broad Search**: If the location is unknown, use `gh pr list --limit 30 --state merged` to get a general list of recent PRs and filter by title/description. +- Always try to link a suspicious commit back to its originating PR for full context. + +### 3. Candidate Selection & Verification +Your goal is to identify the **PR** that caused the regression. + +**Scenario A: You HAVE a reliable test** +- **Verify**: Checkout the merge commit of a candidate PR and run the test. +- **Bisect**: If candidates are unclear, use `git bisect` with the test script (see `scripts/bisect_run.sh`). + +**Scenario B: You DO NOT have a reliable test** +- **Manual Analysis**: Read the code diffs of potential candidates. Look for logic changes that match the bug description. +- **Diff Check**: `git show ` or view the PR diff. +- **Selection**: + - If one PR is a **Strong Match** (obvious logic error matching the bug), select it as the result. + - If ambiguous, select the **Top 3 Candidates** based on file relevance and recency. +- **Constraint**: Do **NOT** run `git bisect` without a reliable test. + +### 4. Reporting +- Present your findings: + - **Single Strong Candidate**: If identified. + - **Top 3 Candidates**: If the exact cause is uncertain. +- **Do NOT** automatically attempt to fix, revert, or run further verification unless explicitly asked. The user will decide the next step (e.g., revert locally, investigate further). + +## Tips for Efficiency +- **Limit File Scope**: When scanning metadata, always provide file paths to `git log` to ignore unrelated changes. +- **Sanity Check**: Always verify the "Good" and "Bad" commits manually before starting a long `bisect run`. + +## Common Regression Patterns +See [references/patterns.md](references/regression-patterns.md) for a guide on interpreting "breaking" changes like state synchronization issues or dependency mismatches. diff --git a/.gemini/skills/regression-finder/references/regression-patterns.md b/.gemini/skills/regression-finder/references/regression-patterns.md new file mode 100644 index 0000000000..1c740986bc --- /dev/null +++ b/.gemini/skills/regression-finder/references/regression-patterns.md @@ -0,0 +1,41 @@ +# Common Regression Patterns + +When analyzing a "bad" commit, look for these common patterns that often cause +regressions in this codebase. + +## 1. State Synchronization Issues + +**Symptoms**: UI doesn't update, stale data, "disappearing" history. +**Pattern**: State is derived from multiple sources that are updated at +different times, or state is updated via side-effects (e.g., `useEffect` or +callbacks) instead of being purely derived. **Fix**: Use `useMemo` to derive +state or ensure atomic updates. + +## 2. Missing Hook Dependencies + +**Symptoms**: Logic runs with old state, variables seem stuck. **Pattern**: A +`useCallback`, `useMemo`, or `useEffect` has an incomplete dependency array. +**Check**: Look for ESLint suppression comments like +`// eslint-disable-next-line react-hooks/exhaustive-deps`. + +## 3. Bypassed Logic + +**Symptoms**: Feature works sometimes but fails in specific paths (e.g., after +cancellation). **Pattern**: A refactor introduced a new submission or update +path that bypasses existing validation or cleanup logic. **Check**: Search for +direct calls to `onSubmit` or `setState` that should have gone through a wrapper +function (like `handleSubmit`). + +## 4. Environment/Platform Specifics + +**Symptoms**: Works on MacOS but fails on Windows or Linux. **Pattern**: Usage +of path delimiters (`/` vs +``), terminal escape sequences, or platform-specific CLI flags. **Fix**: Use `node:path` +and verify terminal capability detection. + +## 5. Mock Mismatch in Tests + +**Symptoms**: Tests pass but application fails (or vice versa). **Pattern**: A +mock in a unit test was not updated to reflect a change in the real +implementation's interface or behavioral expectations. **Check**: Verify that +mock return values and implementations match the current code. diff --git a/.gemini/skills/regression-finder/scripts/bisect_run.sh b/.gemini/skills/regression-finder/scripts/bisect_run.sh new file mode 100755 index 0000000000..e055f6b0d7 --- /dev/null +++ b/.gemini/skills/regression-finder/scripts/bisect_run.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# bisect_run.sh +# Automated test script for git bisect run. +# Expects the test command as the first argument. + +TEST_COMMAND=$1 + +if [ -z "$TEST_COMMAND" ]; then + echo "Error: No test command provided." + exit 125 # Skip this commit +fi + +echo "Running test: $TEST_COMMAND" + +# Execute the test command +eval "$TEST_COMMAND" +EXIT_CODE=$? + +if [ $EXIT_CODE -eq 0 ]; then + echo ">>> COMMIT IS GOOD" + exit 0 +else + echo ">>> COMMIT IS BAD (Exit Code: $EXIT_CODE)" + exit 1 +fi diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index 6dfc62f322..84cb96a78f 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -56,6 +56,7 @@ import { DEFAULT_GEMINI_MODEL, DEFAULT_GEMINI_MODEL_AUTO, isAutoModel, + isGemini2Model, isPreviewModel, PREVIEW_GEMINI_FLASH_MODEL, PREVIEW_GEMINI_MODEL, @@ -809,9 +810,9 @@ export class Config { params.truncateToolOutputThreshold ?? DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD; // // TODO(joshualitt): Re-evaluate the todo tool for 3 family. - this.useWriteTodos = isPreviewModel(this.model) - ? false - : (params.useWriteTodos ?? true); + this.useWriteTodos = isGemini2Model(this.model) + ? (params.useWriteTodos ?? true) + : false; this.enableHooksUI = params.enableHooksUI ?? true; this.enableHooks = params.enableHooks ?? true; this.disabledHooks = params.disabledHooks ?? []; diff --git a/regression-finder.skill b/regression-finder.skill new file mode 100644 index 0000000000..5ac78500db Binary files /dev/null and b/regression-finder.skill differ