Unverified 提交 29028f65 authored 作者: Will Chen's avatar Will Chen 提交者: GitHub

Replace prettier with oxfmt for faster formatting (#2313)

## Summary - Swap prettier for oxfmt in devDependencies for faster formatting - Rename scripts: prettier -> fmt, prettier:check -> fmt:check - Update lint-staged to use oxfmt - Update CLAUDE.md and skill docs to reference npm run fmt ## Test plan - [x] Run npm run fmt to verify formatting works - [x] Run npm run fmt:check to verify check mode works - [x] Verify lint-staged runs oxfmt on commit #skip-bugbot <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Replaced Prettier with oxfmt for faster formatting. Updated to oxfmt 0.26.0, added a project config, renamed scripts to fmt and fmt:check, and refreshed docs; oxfmt’s new rules applied compact formatting across many files. - **Migration** - Use npm run fmt and npm run fmt:check in local workflows and CI. - lint-staged now formats with oxfmt on commit. - Requires Node 20.19+ or 22.12+. <sup>Written for commit a9e3812b02849f8d6357913113fca68ca8b4fcbc. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: 's avatarClaude Opus 4.5 <noreply@anthropic.com>
上级 909a00b0
...@@ -39,7 +39,6 @@ Identify and fix flaky E2E tests by running them repeatedly and investigating fa ...@@ -39,7 +39,6 @@ Identify and fix flaky E2E tests by running them repeatedly and investigating fa
``` ```
Notes: Notes:
- If `$ARGUMENTS` is provided without the `e2e-tests/` prefix, add it - If `$ARGUMENTS` is provided without the `e2e-tests/` prefix, add it
- If `$ARGUMENTS` is provided without the `.spec.ts` suffix, add it - If `$ARGUMENTS` is provided without the `.spec.ts` suffix, add it
- A test is considered **flaky** if it fails at least once out of 10 runs - A test is considered **flaky** if it fails at least once out of 10 runs
...@@ -53,7 +52,6 @@ Identify and fix flaky E2E tests by running them repeatedly and investigating fa ...@@ -53,7 +52,6 @@ Identify and fix flaky E2E tests by running them repeatedly and investigating fa
``` ```
Analyze the debug output to understand: Analyze the debug output to understand:
- Timing issues (race conditions, elements not ready) - Timing issues (race conditions, elements not ready)
- Animation/transition interference - Animation/transition interference
- Network timing variability - Network timing variability
...@@ -63,7 +61,6 @@ Identify and fix flaky E2E tests by running them repeatedly and investigating fa ...@@ -63,7 +61,6 @@ Identify and fix flaky E2E tests by running them repeatedly and investigating fa
6. **Fix the flaky test:** 6. **Fix the flaky test:**
Common fixes following Playwright best practices: Common fixes following Playwright best practices:
- Use `await expect(locator).toBeVisible()` before interacting with elements - Use `await expect(locator).toBeVisible()` before interacting with elements
- Use `await page.waitForLoadState('networkidle')` for network-dependent tests - Use `await page.waitForLoadState('networkidle')` for network-dependent tests
- Use stable selectors (data-testid, role, text) instead of fragile CSS selectors - Use stable selectors (data-testid, role, text) instead of fragile CSS selectors
...@@ -94,7 +91,6 @@ Identify and fix flaky E2E tests by running them repeatedly and investigating fa ...@@ -94,7 +91,6 @@ Identify and fix flaky E2E tests by running them repeatedly and investigating fa
9. **Summarize results:** 9. **Summarize results:**
Report to the user: Report to the user:
- Which tests were identified as flaky - Which tests were identified as flaky
- What was causing the flakiness - What was causing the flakiness
- What fixes were applied - What fixes were applied
......
...@@ -7,7 +7,6 @@ Rebase E2E test snapshots based on failed tests from the PR comments. ...@@ -7,7 +7,6 @@ Rebase E2E test snapshots based on failed tests from the PR comments.
1. Get the current PR number using `gh pr view --json number --jq '.number'` 1. Get the current PR number using `gh pr view --json number --jq '.number'`
2. Fetch PR comments and look for the Playwright test results comment. Parse out the failed test filenames from either: 2. Fetch PR comments and look for the Playwright test results comment. Parse out the failed test filenames from either:
- The "Failed Tests" section (lines starting with `- \`filename.spec.ts`) - The "Failed Tests" section (lines starting with `- \`filename.spec.ts`)
- The "Update Snapshot Commands" section (contains `npm run e2e e2e-tests/filename.spec.ts`) - The "Update Snapshot Commands" section (contains `npm run e2e e2e-tests/filename.spec.ts`)
...@@ -36,7 +35,6 @@ Rebase E2E test snapshots based on failed tests from the PR comments. ...@@ -36,7 +35,6 @@ Rebase E2E test snapshots based on failed tests from the PR comments.
7. Show the user which snapshots were updated using `git diff` on the snapshot files. 7. Show the user which snapshots were updated using `git diff` on the snapshot files.
8. Review the snapshot changes to ensure they look reasonable and are consistent with the PR's purpose. Consider: 8. Review the snapshot changes to ensure they look reasonable and are consistent with the PR's purpose. Consider:
- Do the changes align with what the PR is trying to accomplish? - Do the changes align with what the PR is trying to accomplish?
- Are there any unexpected or suspicious changes? - Are there any unexpected or suspicious changes?
......
...@@ -11,7 +11,6 @@ Create a plan to fix a GitHub issue, then send it to be worked on remotely after ...@@ -11,7 +11,6 @@ Create a plan to fix a GitHub issue, then send it to be worked on remotely after
1. **Fetch the GitHub issue:** 1. **Fetch the GitHub issue:**
First, extract the issue number from `$ARGUMENTS`: First, extract the issue number from `$ARGUMENTS`:
- If `$ARGUMENTS` is a number (e.g., `123`), use it directly - If `$ARGUMENTS` is a number (e.g., `123`), use it directly
- If `$ARGUMENTS` is a URL (e.g., `https://github.com/owner/repo/issues/123`), extract the issue number from the path - If `$ARGUMENTS` is a URL (e.g., `https://github.com/owner/repo/issues/123`), extract the issue number from the path
...@@ -22,13 +21,11 @@ Create a plan to fix a GitHub issue, then send it to be worked on remotely after ...@@ -22,13 +21,11 @@ Create a plan to fix a GitHub issue, then send it to be worked on remotely after
``` ```
2. **Analyze the issue:** 2. **Analyze the issue:**
- Understand what the issue is asking for - Understand what the issue is asking for
- Identify the type of work (bug fix, feature, refactor, etc.) - Identify the type of work (bug fix, feature, refactor, etc.)
- Note any specific requirements or constraints mentioned - Note any specific requirements or constraints mentioned
3. **Explore the codebase:** 3. **Explore the codebase:**
- Search for relevant files and code related to the issue - Search for relevant files and code related to the issue
- Understand the current implementation - Understand the current implementation
- Identify what needs to change - Identify what needs to change
...@@ -37,7 +34,6 @@ Create a plan to fix a GitHub issue, then send it to be worked on remotely after ...@@ -37,7 +34,6 @@ Create a plan to fix a GitHub issue, then send it to be worked on remotely after
4. **Determine testing approach:** 4. **Determine testing approach:**
Consider what kind of testing is appropriate for this change: Consider what kind of testing is appropriate for this change:
- **E2E test**: For user-facing features or complete user flows. Prefer this when the change involves UI interactions or would require mocking many dependencies to unit test. - **E2E test**: For user-facing features or complete user flows. Prefer this when the change involves UI interactions or would require mocking many dependencies to unit test.
- **Unit test**: For pure business logic, utility functions, or isolated components. - **Unit test**: For pure business logic, utility functions, or isolated components.
- **No new tests**: Only for trivial changes (typos, config tweaks, etc.) - **No new tests**: Only for trivial changes (typos, config tweaks, etc.)
...@@ -47,7 +43,6 @@ Create a plan to fix a GitHub issue, then send it to be worked on remotely after ...@@ -47,7 +43,6 @@ Create a plan to fix a GitHub issue, then send it to be worked on remotely after
5. **Create a detailed plan:** 5. **Create a detailed plan:**
Write a plan that includes: Write a plan that includes:
- **Summary**: Brief description of the issue and proposed solution - **Summary**: Brief description of the issue and proposed solution
- **Files to modify**: List of files that will need changes - **Files to modify**: List of files that will need changes
- **Implementation steps**: Ordered list of specific changes to make - **Implementation steps**: Ordered list of specific changes to make
...@@ -61,11 +56,9 @@ Create a plan to fix a GitHub issue, then send it to be worked on remotely after ...@@ -61,11 +56,9 @@ Create a plan to fix a GitHub issue, then send it to be worked on remotely after
7. **Ask how to proceed:** 7. **Ask how to proceed:**
After the plan is approved, ask the user whether they want to: After the plan is approved, ask the user whether they want to:
- **Continue locally**: Implement the plan in the current session - **Continue locally**: Implement the plan in the current session
- **Send to remote**: Push to a remote Claude session for implementation - **Send to remote**: Push to a remote Claude session for implementation
8. **Execute based on user choice:** 8. **Execute based on user choice:**
- If **local**: Proceed to implement the plan step by step, then run `/dyad:pr-push` when complete - If **local**: Proceed to implement the plan step by step, then run `/dyad:pr-push` when complete
- If **remote**: Use `ExitPlanMode` with `pushToRemote: true` and share the remote session URL with the user - If **remote**: Use `ExitPlanMode` with `pushToRemote: true` and share the remote session URL with the user
...@@ -7,7 +7,7 @@ Run pre-commit checks including formatting, linting, and type-checking, and fix ...@@ -7,7 +7,7 @@ Run pre-commit checks including formatting, linting, and type-checking, and fix
1. **Run formatting check and fix:** 1. **Run formatting check and fix:**
``` ```
npm run prettier npm run fmt
``` ```
This will automatically fix any formatting issues. This will automatically fix any formatting issues.
...@@ -23,7 +23,6 @@ Run pre-commit checks including formatting, linting, and type-checking, and fix ...@@ -23,7 +23,6 @@ Run pre-commit checks including formatting, linting, and type-checking, and fix
3. **Fix remaining lint errors manually:** 3. **Fix remaining lint errors manually:**
If there are lint errors that could not be auto-fixed, read the affected files and fix the errors manually. Common issues include: If there are lint errors that could not be auto-fixed, read the affected files and fix the errors manually. Common issues include:
- Unused variables or imports (remove them) - Unused variables or imports (remove them)
- Missing return types (add them) - Missing return types (add them)
- Any other ESLint rule violations - Any other ESLint rule violations
...@@ -37,7 +36,6 @@ Run pre-commit checks including formatting, linting, and type-checking, and fix ...@@ -37,7 +36,6 @@ Run pre-commit checks including formatting, linting, and type-checking, and fix
5. **Fix any type errors:** 5. **Fix any type errors:**
If there are type errors, read the affected files and fix them. Common issues include: If there are type errors, read the affected files and fix them. Common issues include:
- Type mismatches (correct the types) - Type mismatches (correct the types)
- Missing type annotations (add them) - Missing type annotations (add them)
- Null/undefined handling issues (add appropriate checks) - Null/undefined handling issues (add appropriate checks)
...@@ -47,11 +45,10 @@ Run pre-commit checks including formatting, linting, and type-checking, and fix ...@@ -47,11 +45,10 @@ Run pre-commit checks including formatting, linting, and type-checking, and fix
After making manual fixes, re-run the checks to ensure everything passes: After making manual fixes, re-run the checks to ensure everything passes:
``` ```
npm run prettier && npm run lint && npm run ts npm run fmt && npm run lint && npm run ts
``` ```
7. **Summarize the results:** 7. **Summarize the results:**
- Report which checks passed - Report which checks passed
- List any fixes that were made manually - List any fixes that were made manually
- If any errors could not be fixed, explain why and ask the user for guidance - If any errors could not be fixed, explain why and ask the user for guidance
......
...@@ -11,13 +11,11 @@ Address all outstanding issues on a GitHub Pull Request by handling both review ...@@ -11,13 +11,11 @@ Address all outstanding issues on a GitHub Pull Request by handling both review
This is a meta-skill that orchestrates two sub-skills to comprehensively fix PR issues. This is a meta-skill that orchestrates two sub-skills to comprehensively fix PR issues.
1. **Run `/dyad:pr-fix:comments`** to handle all unresolved review comments: 1. **Run `/dyad:pr-fix:comments`** to handle all unresolved review comments:
- Address valid code review concerns - Address valid code review concerns
- Resolve invalid concerns with explanations - Resolve invalid concerns with explanations
- Flag ambiguous issues for human attention - Flag ambiguous issues for human attention
2. **Run `/dyad:pr-fix:actions`** to handle failing CI checks: 2. **Run `/dyad:pr-fix:actions`** to handle failing CI checks:
- Fix failing tests (unit and E2E) - Fix failing tests (unit and E2E)
- Update snapshots if needed - Update snapshots if needed
- Ensure all checks pass - Ensure all checks pass
......
...@@ -9,7 +9,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request. ...@@ -9,7 +9,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
## Instructions ## Instructions
1. **Determine the PR to work on:** 1. **Determine the PR to work on:**
- If `$ARGUMENTS` contains a PR number or URL, use that - If `$ARGUMENTS` contains a PR number or URL, use that
- Otherwise, get the current branch's PR using `gh pr view --json number,url,title,body --jq '.'` - Otherwise, get the current branch's PR using `gh pr view --json number,url,title,body --jq '.'`
- If no PR is found, inform the user and stop - If no PR is found, inform the user and stop
...@@ -21,7 +20,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request. ...@@ -21,7 +20,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
``` ```
Identify which checks are failing: Identify which checks are failing:
- Lint/formatting checks - Lint/formatting checks
- Type checks - Type checks
- Unit tests - Unit tests
...@@ -29,19 +27,16 @@ Fix failing CI checks and GitHub Actions on a Pull Request. ...@@ -29,19 +27,16 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
- Build checks - Build checks
3. **For failing lint/formatting checks:** 3. **For failing lint/formatting checks:**
- Run `npm run lint:fix` to auto-fix lint issues - Run `npm run lint:fix` to auto-fix lint issues
- Run `npm run prettier` to fix formatting - Run `npm run fmt` to fix formatting
- Review the changes made - Review the changes made
4. **For failing type checks:** 4. **For failing type checks:**
- Run `npm run ts` to identify type errors - Run `npm run ts` to identify type errors
- Read the relevant files and fix the type issues - Read the relevant files and fix the type issues
- Re-run type checks to verify fixes - Re-run type checks to verify fixes
5. **For failing unit tests:** 5. **For failing unit tests:**
- Run the failing tests locally to reproduce: - Run the failing tests locally to reproduce:
``` ```
npm run test -- <test-file-pattern> npm run test -- <test-file-pattern>
...@@ -50,7 +45,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request. ...@@ -50,7 +45,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
- Fix the underlying code issues or update tests if the behavior change is intentional - Fix the underlying code issues or update tests if the behavior change is intentional
6. **For failing Playwright/E2E tests:** 6. **For failing Playwright/E2E tests:**
- Check if the failures are snapshot-related by examining the CI logs or PR comments - Check if the failures are snapshot-related by examining the CI logs or PR comments
- If snapshots need updating, run the `/dyad:e2e-rebase` skill to fix them - If snapshots need updating, run the `/dyad:e2e-rebase` skill to fix them
- If the failures are not snapshot-related: - If the failures are not snapshot-related:
...@@ -61,7 +55,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request. ...@@ -61,7 +55,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
- Investigate and fix the underlying issues - Investigate and fix the underlying issues
7. **For failing build checks:** 7. **For failing build checks:**
- Run the build locally: - Run the build locally:
``` ```
npm run build npm run build
...@@ -69,7 +62,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request. ...@@ -69,7 +62,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
- Fix any build errors that appear - Fix any build errors that appear
8. **After making all fixes, verify:** 8. **After making all fixes, verify:**
- Run the full lint check: `npm run lint` - Run the full lint check: `npm run lint`
- Run type checks: `npm run ts` - Run type checks: `npm run ts`
- Run relevant unit tests - Run relevant unit tests
...@@ -93,7 +85,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request. ...@@ -93,7 +85,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
Then run `/dyad:pr-push` to push the changes. Then run `/dyad:pr-push` to push the changes.
10. **Provide a summary to the user:** 10. **Provide a summary to the user:**
- List which checks were failing - List which checks were failing
- Describe what was fixed for each - Describe what was fixed for each
- Note any checks that could not be fixed and require human attention - Note any checks that could not be fixed and require human attention
...@@ -9,7 +9,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately ...@@ -9,7 +9,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately
## Instructions ## Instructions
1. **Determine the PR to work on:** 1. **Determine the PR to work on:**
- If `$ARGUMENTS` is provided: - If `$ARGUMENTS` is provided:
- If it's a number (e.g., `123`), use it as the PR number - If it's a number (e.g., `123`), use it as the PR number
- If it's a URL (e.g., `https://github.com/owner/repo/pull/123`), extract the PR number from the path - If it's a URL (e.g., `https://github.com/owner/repo/pull/123`), extract the PR number from the path
...@@ -54,7 +53,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately ...@@ -54,7 +53,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately
3. **For each unresolved review thread, categorize it:** 3. **For each unresolved review thread, categorize it:**
Read the comment(s) in the thread and determine which category it falls into: Read the comment(s) in the thread and determine which category it falls into:
- **Valid issue**: A legitimate code review concern that should be addressed (bug, improvement, style issue, etc.) - **Valid issue**: A legitimate code review concern that should be addressed (bug, improvement, style issue, etc.)
- **Not a valid issue**: The reviewer may have misunderstood something, the concern is already addressed elsewhere, or the suggestion conflicts with project requirements - **Not a valid issue**: The reviewer may have misunderstood something, the concern is already addressed elsewhere, or the suggestion conflicts with project requirements
- **Ambiguous**: The comment is unclear, requires significant discussion, or involves a judgment call that needs human input - **Ambiguous**: The comment is unclear, requires significant discussion, or involves a judgment call that needs human input
...@@ -62,14 +60,12 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately ...@@ -62,14 +60,12 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately
4. **Handle each category:** 4. **Handle each category:**
**For valid issues:** **For valid issues:**
- Read the relevant file(s) mentioned in the comment - Read the relevant file(s) mentioned in the comment
- Understand the context and the requested change - Understand the context and the requested change
- Make the necessary code changes to address the feedback - Make the necessary code changes to address the feedback
- The thread will be marked as resolved when the code is pushed (GitHub auto-resolves when the code changes) - The thread will be marked as resolved when the code is pushed (GitHub auto-resolves when the code changes)
**For not valid issues:** **For not valid issues:**
- Reply to the thread explaining why the concern doesn't apply: - Reply to the thread explaining why the concern doesn't apply:
``` ```
...@@ -92,7 +88,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately ...@@ -92,7 +88,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately
Note: Replace `<THREAD_ID>` with the thread's `id` field from the GraphQL response. Note: Replace `<THREAD_ID>` with the thread's `id` field from the GraphQL response.
**For ambiguous issues:** **For ambiguous issues:**
- Reply to the thread flagging it for human attention: - Reply to the thread flagging it for human attention:
``` ```
gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments/<COMMENT_ID>/replies \ gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments/<COMMENT_ID>/replies \
...@@ -104,7 +99,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately ...@@ -104,7 +99,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately
5. **After processing all comments, verify and commit changes:** 5. **After processing all comments, verify and commit changes:**
If any code changes were made: If any code changes were made:
- Run `/dyad:lint` to ensure code passes all checks - Run `/dyad:lint` to ensure code passes all checks
- Stage and commit the changes: - Stage and commit the changes:
...@@ -126,7 +120,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately ...@@ -126,7 +120,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately
7. **Provide a summary to the user:** 7. **Provide a summary to the user:**
Report: Report:
- **Addressed**: List of comments that were fixed with code changes - **Addressed**: List of comments that were fixed with code changes
- **Resolved (not valid)**: List of comments that were resolved with explanations - **Resolved (not valid)**: List of comments that were resolved with explanations
- **Flagged for human attention**: List of ambiguous comments left open - **Flagged for human attention**: List of ambiguous comments left open
......
...@@ -11,7 +11,6 @@ Commit any uncommitted changes, run lint checks, fix any issues, and push the cu ...@@ -11,7 +11,6 @@ Commit any uncommitted changes, run lint checks, fix any issues, and push the cu
Run `git status` to check for any uncommitted changes (staged, unstaged, or untracked files). Run `git status` to check for any uncommitted changes (staged, unstaged, or untracked files).
If there are uncommitted changes: If there are uncommitted changes:
- Identify files that should NOT be committed (e.g., `.env`, `.env.*`, `credentials.*`, `*.secret`, `*.key`, `*.pem`, `.DS_Store`, `node_modules/`, `*.log`, temporary files, or anything that looks like it contains secrets or personal configuration) - Identify files that should NOT be committed (e.g., `.env`, `.env.*`, `credentials.*`, `*.secret`, `*.key`, `*.pem`, `.DS_Store`, `node_modules/`, `*.log`, temporary files, or anything that looks like it contains secrets or personal configuration)
- Stage and commit all OTHER files with a descriptive commit message summarizing the changes - Stage and commit all OTHER files with a descriptive commit message summarizing the changes
- Keep track of any files you ignored so you can report them at the end - Keep track of any files you ignored so you can report them at the end
...@@ -23,7 +22,7 @@ Commit any uncommitted changes, run lint checks, fix any issues, and push the cu ...@@ -23,7 +22,7 @@ Commit any uncommitted changes, run lint checks, fix any issues, and push the cu
Run these commands to ensure the code passes all pre-commit checks: Run these commands to ensure the code passes all pre-commit checks:
``` ```
npm run prettier && npm run lint:fix && npm run ts npm run fmt && npm run lint:fix && npm run ts
``` ```
If there are errors that could not be auto-fixed, read the affected files and fix them manually, then re-run the checks until they pass. If there are errors that could not be auto-fixed, read the affected files and fix them manually, then re-run the checks until they pass.
...@@ -58,7 +57,6 @@ Commit any uncommitted changes, run lint checks, fix any issues, and push the cu ...@@ -58,7 +57,6 @@ Commit any uncommitted changes, run lint checks, fix any issues, and push the cu
Note: `--force-with-lease` is used because the commit may have been amended. It's safer than `--force` as it will fail if someone else has pushed to the branch. Note: `--force-with-lease` is used because the commit may have been amended. It's safer than `--force` as it will fail if someone else has pushed to the branch.
5. **Summarize the results:** 5. **Summarize the results:**
- Report any uncommitted changes that were committed in step 1 - Report any uncommitted changes that were committed in step 1
- Report any files that were IGNORED and not committed (if any), explaining why they were skipped - Report any files that were IGNORED and not committed (if any), explaining why they were skipped
- Report any lint fixes that were applied - Report any lint fixes that were applied
......
...@@ -28,7 +28,6 @@ Rebase the current branch on the latest upstream changes, resolve conflicts, and ...@@ -28,7 +28,6 @@ Rebase the current branch on the latest upstream changes, resolve conflicts, and
For example: `git rebase upstream/main` For example: `git rebase upstream/main`
4. **If there are merge conflicts:** 4. **If there are merge conflicts:**
- Identify the conflicting files from the rebase output - Identify the conflicting files from the rebase output
- Read each conflicting file and understand both versions of the changes - Read each conflicting file and understand both versions of the changes
- Resolve the conflicts by editing the files to combine changes appropriately - Resolve the conflicts by editing the files to combine changes appropriately
...@@ -51,7 +50,6 @@ Rebase the current branch on the latest upstream changes, resolve conflicts, and ...@@ -51,7 +50,6 @@ Rebase the current branch on the latest upstream changes, resolve conflicts, and
Run the `/dyad:pr-push` skill to run lint checks, fix any issues, and push the rebased branch. Run the `/dyad:pr-push` skill to run lint checks, fix any issues, and push the rebased branch.
6. **Summarize the results:** 6. **Summarize the results:**
- Report that the rebase was successful - Report that the rebase was successful
- List any conflicts that were resolved - List any conflicts that were resolved
- Note any lint fixes that were applied - Note any lint fixes that were applied
......
...@@ -13,7 +13,6 @@ Analyze session debugging data to identify errors and issues that may have cause ...@@ -13,7 +13,6 @@ Analyze session debugging data to identify errors and issues that may have cause
1. **Parse and validate the arguments:** 1. **Parse and validate the arguments:**
Split `$ARGUMENTS` on whitespace to get exactly two arguments: Split `$ARGUMENTS` on whitespace to get exactly two arguments:
- First argument: session data URL (must start with `http://` or `https://`) - First argument: session data URL (must start with `http://` or `https://`)
- Second argument: GitHub issue identifier (number like `123` or full URL like `https://github.com/owner/repo/issues/123`) - Second argument: GitHub issue identifier (number like `123` or full URL like `https://github.com/owner/repo/issues/123`)
...@@ -31,7 +30,6 @@ Analyze session debugging data to identify errors and issues that may have cause ...@@ -31,7 +30,6 @@ Analyze session debugging data to identify errors and issues that may have cause
``` ```
Understand: Understand:
- What problem the user is reporting - What problem the user is reporting
- Steps to reproduce (if provided) - Steps to reproduce (if provided)
- Expected vs actual behavior - Expected vs actual behavior
...@@ -44,7 +42,6 @@ Analyze session debugging data to identify errors and issues that may have cause ...@@ -44,7 +42,6 @@ Analyze session debugging data to identify errors and issues that may have cause
4. **Analyze the session data:** 4. **Analyze the session data:**
Look for suspicious entries including: Look for suspicious entries including:
- **Errors**: Any error messages, stack traces, or exception logs - **Errors**: Any error messages, stack traces, or exception logs
- **Warnings**: Warning-level log entries that may indicate problems - **Warnings**: Warning-level log entries that may indicate problems
- **Failed requests**: HTTP errors, timeout failures, connection issues - **Failed requests**: HTTP errors, timeout failures, connection issues
...@@ -55,7 +52,6 @@ Analyze session debugging data to identify errors and issues that may have cause ...@@ -55,7 +52,6 @@ Analyze session debugging data to identify errors and issues that may have cause
5. **Correlate with the reported issue:** 5. **Correlate with the reported issue:**
For each suspicious entry found, assess: For each suspicious entry found, assess:
- Does the timing match when the user reported the issue occurring? - Does the timing match when the user reported the issue occurring?
- Does the error message relate to the feature/area the user mentioned? - Does the error message relate to the feature/area the user mentioned?
- Could this error cause the symptoms the user described? - Could this error cause the symptoms the user described?
...@@ -80,13 +76,11 @@ Analyze session debugging data to identify errors and issues that may have cause ...@@ -80,13 +76,11 @@ Analyze session debugging data to identify errors and issues that may have cause
7. **Provide recommendations:** 7. **Provide recommendations:**
For each high-confidence finding, suggest: For each high-confidence finding, suggest:
- Where in the codebase to investigate - Where in the codebase to investigate
- Potential root causes - Potential root causes
- Suggested fixes if apparent - Suggested fixes if apparent
8. **Summarize:** 8. **Summarize:**
- Total errors/warnings found - Total errors/warnings found
- Top 3 most likely causes - Top 3 most likely causes
- Recommended next steps for investigation - Recommended next steps for investigation
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"printWidth": 80,
"experimentalSortPackageJson": false,
"ignorePatterns": [
"build",
"coverage",
"drizzle/",
"**/pnpm-lock.yaml",
"**/snapshots/**",
"e2e-tests/fixtures/**"
]
}
...@@ -17,7 +17,9 @@ testSkipIfWindows( ...@@ -17,7 +17,9 @@ testSkipIfWindows(
const iframe = po.getPreviewIframeElement(); const iframe = po.getPreviewIframeElement();
await expect( await expect(
iframe.contentFrame().getByText("Console Logs Test App"), iframe.contentFrame().getByText("Console Logs Test App"),
).toBeVisible({ timeout: Timeout.MEDIUM }); ).toBeVisible({
timeout: Timeout.MEDIUM,
});
// Open the system messages console // Open the system messages console
// Logs are generated in useEffect when component mounts, so they may already exist // Logs are generated in useEffect when component mounts, so they may already exist
...@@ -99,7 +101,9 @@ testSkipIfWindows( ...@@ -99,7 +101,9 @@ testSkipIfWindows(
const iframeFrame = iframe.contentFrame(); const iframeFrame = iframe.contentFrame();
await expect( await expect(
iframeFrame.getByText("Network Requests Test App"), iframeFrame.getByText("Network Requests Test App"),
).toBeVisible({ timeout: Timeout.MEDIUM }); ).toBeVisible({
timeout: Timeout.MEDIUM,
});
// Wait for service worker to be ready // Wait for service worker to be ready
// Service worker registration is async, so we wait for it to be active // Service worker registration is async, so we wait for it to be active
...@@ -261,7 +265,9 @@ testSkipIfWindows("clear logs button clears all logs", async ({ po }) => { ...@@ -261,7 +265,9 @@ testSkipIfWindows("clear logs button clears all logs", async ({ po }) => {
const iframe = po.getPreviewIframeElement(); const iframe = po.getPreviewIframeElement();
await expect( await expect(
iframe.contentFrame().getByText("Console Logs Test App"), iframe.contentFrame().getByText("Console Logs Test App"),
).toBeVisible({ timeout: Timeout.MEDIUM }); ).toBeVisible({
timeout: Timeout.MEDIUM,
});
// Open the system messages console // Open the system messages console
const consoleHeader = po.page.locator('text="System Messages"').first(); const consoleHeader = po.page.locator('text="System Messages"').first();
......
...@@ -11,7 +11,9 @@ test("file tree search finds content matches and surfaces line numbers", async ( ...@@ -11,7 +11,9 @@ test("file tree search finds content matches and surfaces line numbers", async (
// Wait for the code view to finish loading files // Wait for the code view to finish loading files
await expect( await expect(
po.page.getByText("Loading files...", { exact: false }), po.page.getByText("Loading files...", { exact: false }),
).toBeHidden({ timeout: Timeout.LONG }); ).toBeHidden({
timeout: Timeout.LONG,
});
const searchInput = po.page.getByTestId("file-tree-search"); const searchInput = po.page.getByTestId("file-tree-search");
await expect(searchInput).toBeVisible({ timeout: Timeout.MEDIUM }); await expect(searchInput).toBeVisible({ timeout: Timeout.MEDIUM });
......
...@@ -227,6 +227,8 @@ test.describe("Git Collaboration", () => { ...@@ -227,6 +227,8 @@ test.describe("Git Collaboration", () => {
await po.waitForToast("success"); await po.waitForToast("success");
await expect( await expect(
po.page.getByTestId(`collaborator-item-${fakeUser}`), po.page.getByTestId(`collaborator-item-${fakeUser}`),
).not.toBeVisible({ timeout: 5000 }); ).not.toBeVisible({
timeout: 5000,
});
}); });
}); });
...@@ -733,7 +733,9 @@ export class PageObject { ...@@ -733,7 +733,9 @@ export class PageObject {
async waitForAnnotatorMode() { async waitForAnnotatorMode() {
// Wait for the annotator toolbar to be visible // Wait for the annotator toolbar to be visible
await expect(this.page.getByRole("button", { name: "Select" })).toBeVisible( await expect(this.page.getByRole("button", { name: "Select" })).toBeVisible(
{ timeout: Timeout.MEDIUM }, {
timeout: Timeout.MEDIUM,
},
); );
} }
......
...@@ -24,7 +24,9 @@ testSkipIfWindows( ...@@ -24,7 +24,9 @@ testSkipIfWindows(
// The button may not exist if there are no problems, so we check for the "No problems found" text // The button may not exist if there are no problems, so we check for the "No problems found" text
await expect( await expect(
po.page.getByText(/No problems found|No Problems Report/), po.page.getByText(/No problems found|No Problems Report/),
).toBeVisible({ timeout: Timeout.MEDIUM }); ).toBeVisible({
timeout: Timeout.MEDIUM,
});
// Send prompt that triggers write_file with TS errors, then run_type_checks // Send prompt that triggers write_file with TS errors, then run_type_checks
await po.sendPrompt("tc=local-agent/run-type-checks"); await po.sendPrompt("tc=local-agent/run-type-checks");
......
...@@ -38,7 +38,9 @@ testWithConfig({ ...@@ -38,7 +38,9 @@ testWithConfig({
// Check if the force-close dialog is visible by looking for the heading // Check if the force-close dialog is visible by looking for the heading
await expect( await expect(
po.page.getByRole("heading", { name: "Force Close Detected" }), po.page.getByRole("heading", { name: "Force Close Detected" }),
).toBeVisible({ timeout: Timeout.MEDIUM }); ).toBeVisible({
timeout: Timeout.MEDIUM,
});
// Verify the warning message // Verify the warning message
await expect( await expect(
......
...@@ -205,7 +205,9 @@ testSkipIfWindows("discard changes", async ({ po }) => { ...@@ -205,7 +205,9 @@ testSkipIfWindows("discard changes", async ({ po }) => {
// Verify the visual changes dialog is gone // Verify the visual changes dialog is gone
await expect(po.page.getByText(/\d+ component[s]? modified/)).not.toBeVisible( await expect(po.page.getByText(/\d+ component[s]? modified/)).not.toBeVisible(
{ timeout: Timeout.MEDIUM }, {
timeout: Timeout.MEDIUM,
},
); );
// Verify that the changes are NOT applied to codebase // Verify that the changes are NOT applied to codebase
......
module.exports = { module.exports = {
"**/*.{ts,tsx}": () => "npm run ts", "**/*.{ts,tsx}": () => "npm run ts",
"**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx,vue,astro,svelte}": "oxlint", "**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx,vue,astro,svelte}": "oxlint",
"*.{js,css,md,ts,tsx,jsx,json,yml,yaml}": "prettier --write", "*.{js,css,md,ts,tsx,jsx,json,yml,yaml}": "oxfmt",
}; };
差异被折叠。
{ {
"name": "dyad", "name": "dyad",
"productName": "dyad",
"version": "0.34.0-beta.1", "version": "0.34.0-beta.1",
"description": "Free, local, open-source AI app builder", "description": "Free, local, open-source AI app builder",
"main": ".vite/build/main.js", "keywords": [],
"license": "MIT",
"author": {
"name": "Will Chen",
"email": "willchen90@gmail.com"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/dyad-sh/dyad.git" "url": "https://github.com/dyad-sh/dyad.git"
}, },
"engines": { "main": ".vite/build/main.js",
"node": ">=20"
},
"scripts": { "scripts": {
"clean": "rimraf out scaffold/node_modules", "clean": "rimraf out scaffold/node_modules",
"start": "electron-forge start", "start": "electron-forge start",
...@@ -28,9 +30,9 @@ ...@@ -28,9 +30,9 @@
"db:generate": "drizzle-kit generate", "db:generate": "drizzle-kit generate",
"db:push": "drizzle-kit push", "db:push": "drizzle-kit push",
"db:studio": "drizzle-kit studio", "db:studio": "drizzle-kit studio",
"prettier:check": "npx prettier --check .", "fmt:check": "npx oxfmt --check",
"prettier": "npx prettier --write .", "fmt": "npx oxfmt",
"presubmit": "npm run prettier:check && npm run lint", "presubmit": "npm run fmt:check && npm run lint",
"test": "vitest run", "test": "vitest run",
"test:watch": "vitest", "test:watch": "vitest",
"test:ui": "vitest --ui", "test:ui": "vitest --ui",
...@@ -40,52 +42,6 @@ ...@@ -40,52 +42,6 @@
"e2e": "playwright test", "e2e": "playwright test",
"e2e:shard": "playwright test --shard" "e2e:shard": "playwright test --shard"
}, },
"keywords": [],
"author": {
"name": "Will Chen",
"email": "willchen90@gmail.com"
},
"license": "MIT",
"devDependencies": {
"@electron-forge/cli": "^7.11.1",
"@electron-forge/maker-deb": "^7.11.1",
"@electron-forge/maker-rpm": "^7.11.1",
"@electron-forge/maker-squirrel": "^7.11.1",
"@electron-forge/maker-zip": "^7.11.1",
"@electron-forge/plugin-auto-unpack-natives": "^7.11.1",
"@electron-forge/plugin-fuses": "^7.11.1",
"@electron-forge/plugin-vite": "^7.11.1",
"@electron-forge/publisher-github": "^7.11.1",
"@electron/fuses": "^1.8.0",
"@playwright/test": "^1.52.0",
"@testing-library/react": "^16.3.0",
"@types/better-sqlite3": "^7.6.13",
"@types/fs-extra": "^11.0.4",
"@types/glob": "^8.1.0",
"@types/kill-port": "^2.0.3",
"@types/node": "^22.14.0",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@typescript/native-preview": "^7.0.0-dev.20260107.1",
"@vitest/ui": "^3.1.1",
"babel-plugin-react-compiler": "^1.0.0",
"cross-env": "^7.0.3",
"drizzle-kit": "^0.30.6",
"electron": "40.0.0",
"eslint": "^8.57.1",
"eslint-plugin-import": "^2.31.0",
"happy-dom": "^17.4.4",
"husky": "^9.1.7",
"lint-staged": "^15.5.2",
"oxlint": "^1.41.0",
"prettier": "3.5.3",
"rimraf": "^6.0.1",
"typescript": "^5.8.3",
"vite": "^5.4.17",
"vitest": "^3.1.1"
},
"dependencies": { "dependencies": {
"@ai-sdk/amazon-bedrock": "^4.0.9", "@ai-sdk/amazon-bedrock": "^4.0.9",
"@ai-sdk/anthropic": "^3.0.7", "@ai-sdk/anthropic": "^3.0.7",
...@@ -182,9 +138,53 @@ ...@@ -182,9 +138,53 @@
"uuid": "^11.1.0", "uuid": "^11.1.0",
"zod": "^3.25.76" "zod": "^3.25.76"
}, },
"devDependencies": {
"@electron-forge/cli": "^7.11.1",
"@electron-forge/maker-deb": "^7.11.1",
"@electron-forge/maker-rpm": "^7.11.1",
"@electron-forge/maker-squirrel": "^7.11.1",
"@electron-forge/maker-zip": "^7.11.1",
"@electron-forge/plugin-auto-unpack-natives": "^7.11.1",
"@electron-forge/plugin-fuses": "^7.11.1",
"@electron-forge/plugin-vite": "^7.11.1",
"@electron-forge/publisher-github": "^7.11.1",
"@electron/fuses": "^1.8.0",
"@playwright/test": "^1.52.0",
"@testing-library/react": "^16.3.0",
"@types/better-sqlite3": "^7.6.13",
"@types/fs-extra": "^11.0.4",
"@types/glob": "^8.1.0",
"@types/kill-port": "^2.0.3",
"@types/node": "^22.14.0",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"@typescript/native-preview": "^7.0.0-dev.20260107.1",
"@vitest/ui": "^3.1.1",
"babel-plugin-react-compiler": "^1.0.0",
"cross-env": "^7.0.3",
"drizzle-kit": "^0.30.6",
"electron": "40.0.0",
"eslint": "^8.57.1",
"eslint-plugin-import": "^2.31.0",
"happy-dom": "^17.4.4",
"husky": "^9.1.7",
"lint-staged": "^15.5.2",
"oxfmt": "^0.26.0",
"oxlint": "^1.41.0",
"rimraf": "^6.0.1",
"typescript": "^5.8.3",
"vite": "^5.4.17",
"vitest": "^3.1.1"
},
"overrides": { "overrides": {
"@vercel/sdk": { "@vercel/sdk": {
"@modelcontextprotocol/sdk": "$@modelcontextprotocol/sdk" "@modelcontextprotocol/sdk": "$@modelcontextprotocol/sdk"
} }
} },
"engines": {
"node": ">=20"
},
"productName": "dyad"
} }
...@@ -2,31 +2,31 @@ ...@@ -2,31 +2,31 @@
"name": "@dyad-sh/nextjs-webpack-component-tagger", "name": "@dyad-sh/nextjs-webpack-component-tagger",
"version": "0.8.0", "version": "0.8.0",
"description": "A webpack loader that automatically adds data attributes to your React components in Next.js.", "description": "A webpack loader that automatically adds data attributes to your React components in Next.js.",
"main": "dist/index.js", "keywords": [
"module": "dist/index.mjs", "dyad",
"types": "dist/index.d.ts", "nextjs",
"type": "module", "react",
"webpack",
"webpack-loader"
],
"license": "Apache-2.0",
"author": "Dyad",
"files": [ "files": [
"dist" "dist"
], ],
"type": "module",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"publishConfig": {
"access": "public"
},
"scripts": { "scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts", "build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "npm run build -- --watch", "dev": "npm run build -- --watch",
"lint": "eslint . --max-warnings 0", "lint": "eslint . --max-warnings 0",
"prepublishOnly": "npm run build" "prepublishOnly": "npm run build"
}, },
"keywords": [
"webpack",
"webpack-loader",
"nextjs",
"react",
"dyad"
],
"author": "Dyad",
"license": "Apache-2.0",
"peerDependencies": {
"webpack": "^5.0.0"
},
"dependencies": { "dependencies": {
"@babel/parser": "^7.23.0", "@babel/parser": "^7.23.0",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
"tsup": "^8.0.2", "tsup": "^8.0.2",
"typescript": "^5.2.2" "typescript": "^5.2.2"
}, },
"publishConfig": { "peerDependencies": {
"access": "public" "webpack": "^5.0.0"
} }
} }
...@@ -2,30 +2,30 @@ ...@@ -2,30 +2,30 @@
"name": "@dyad-sh/react-vite-component-tagger", "name": "@dyad-sh/react-vite-component-tagger",
"version": "0.8.0", "version": "0.8.0",
"description": "A Vite plugin that automatically adds data attributes to your React components.", "description": "A Vite plugin that automatically adds data attributes to your React components.",
"main": "dist/index.js", "keywords": [
"module": "dist/index.mjs", "dyad",
"types": "dist/index.d.ts", "react",
"type": "module", "vite",
"vite-plugin"
],
"license": "Apache-2.0",
"author": "Dyad",
"files": [ "files": [
"dist" "dist"
], ],
"type": "module",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"publishConfig": {
"access": "public"
},
"scripts": { "scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts", "build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "npm run build -- --watch", "dev": "npm run build -- --watch",
"lint": "eslint . --max-warnings 0", "lint": "eslint . --max-warnings 0",
"prepublishOnly": "npm run build" "prepublishOnly": "npm run build"
}, },
"keywords": [
"vite",
"vite-plugin",
"react",
"dyad"
],
"author": "Dyad",
"license": "Apache-2.0",
"peerDependencies": {
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
},
"dependencies": { "dependencies": {
"@babel/parser": "^7.23.0", "@babel/parser": "^7.23.0",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
"typescript": "^5.2.2", "typescript": "^5.2.2",
"vite": "^5.0.0" "vite": "^5.0.0"
}, },
"publishConfig": { "peerDependencies": {
"access": "public" "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
} }
} }
{ {
"name": "vite_react_shadcn_ts", "name": "vite_react_shadcn_ts",
"private": true,
"version": "0.0.0", "version": "0.0.0",
"private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
......
...@@ -24,7 +24,8 @@ const badgeVariants = cva( ...@@ -24,7 +24,8 @@ const badgeVariants = cva(
); );
export interface BadgeProps export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>, extends
React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {} VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) { function Badge({ className, variant, ...props }: BadgeProps) {
......
...@@ -34,7 +34,8 @@ const buttonVariants = cva( ...@@ -34,7 +34,8 @@ const buttonVariants = cva(
); );
export interface ButtonProps export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>, extends
React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> { VariantProps<typeof buttonVariants> {
asChild?: boolean; asChild?: boolean;
} }
......
...@@ -48,7 +48,8 @@ const sheetVariants = cva( ...@@ -48,7 +48,8 @@ const sheetVariants = cva(
); );
interface SheetContentProps interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, extends
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
VariantProps<typeof sheetVariants> {} VariantProps<typeof sheetVariants> {}
const SheetContent = React.forwardRef< const SheetContent = React.forwardRef<
......
...@@ -2,8 +2,7 @@ import * as React from "react"; ...@@ -2,8 +2,7 @@ import * as React from "react";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
export interface TextareaProps export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>( const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => { ({ className, ...props }, ref) => {
......
...@@ -702,7 +702,9 @@ describe("processFullResponse", () => { ...@@ -702,7 +702,9 @@ describe("processFullResponse", () => {
expect(fs.mkdirSync).toHaveBeenCalledWith( expect(fs.mkdirSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src", "/mock/user/data/path/mock-app-path/src",
{ recursive: true }, {
recursive: true,
},
); );
expect(fs.writeFileSync).toHaveBeenCalledWith( expect(fs.writeFileSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src/file1.js", "/mock/user/data/path/mock-app-path/src/file1.js",
...@@ -759,15 +761,21 @@ describe("processFullResponse", () => { ...@@ -759,15 +761,21 @@ describe("processFullResponse", () => {
// Check that directories were created for each file path // Check that directories were created for each file path
expect(fs.mkdirSync).toHaveBeenCalledWith( expect(fs.mkdirSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src", "/mock/user/data/path/mock-app-path/src",
{ recursive: true }, {
recursive: true,
},
); );
expect(fs.mkdirSync).toHaveBeenCalledWith( expect(fs.mkdirSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src/utils", "/mock/user/data/path/mock-app-path/src/utils",
{ recursive: true }, {
recursive: true,
},
); );
expect(fs.mkdirSync).toHaveBeenCalledWith( expect(fs.mkdirSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src/components", "/mock/user/data/path/mock-app-path/src/components",
{ recursive: true }, {
recursive: true,
},
); );
// Using toHaveBeenNthCalledWith to check each specific call // Using toHaveBeenNthCalledWith to check each specific call
...@@ -824,7 +832,9 @@ describe("processFullResponse", () => { ...@@ -824,7 +832,9 @@ describe("processFullResponse", () => {
expect(fs.mkdirSync).toHaveBeenCalledWith( expect(fs.mkdirSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src/components", "/mock/user/data/path/mock-app-path/src/components",
{ recursive: true }, {
recursive: true,
},
); );
expect(fs.renameSync).toHaveBeenCalledWith( expect(fs.renameSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src/components/OldComponent.jsx", "/mock/user/data/path/mock-app-path/src/components/OldComponent.jsx",
......
...@@ -978,9 +978,8 @@ src/file2.ts ...@@ -978,9 +978,8 @@ src/file2.ts
describe("hasExternalChanges", () => { describe("hasExternalChanges", () => {
it("should default to true when no assistant message has commitHash", async () => { it("should default to true when no assistant message has commitHash", async () => {
const { getCurrentCommitHash, isGitStatusClean } = await import( const { getCurrentCommitHash, isGitStatusClean } =
"@/ipc/utils/git_utils" await import("@/ipc/utils/git_utils");
);
const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash); const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash);
const mockIsGitStatusClean = vi.mocked(isGitStatusClean); const mockIsGitStatusClean = vi.mocked(isGitStatusClean);
...@@ -1011,9 +1010,8 @@ src/file2.ts ...@@ -1011,9 +1010,8 @@ src/file2.ts
}); });
it("should be false when latest assistant commit matches current and git status is clean", async () => { it("should be false when latest assistant commit matches current and git status is clean", async () => {
const { getCurrentCommitHash, isGitStatusClean } = await import( const { getCurrentCommitHash, isGitStatusClean } =
"@/ipc/utils/git_utils" await import("@/ipc/utils/git_utils");
);
const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash); const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash);
const mockIsGitStatusClean = vi.mocked(isGitStatusClean); const mockIsGitStatusClean = vi.mocked(isGitStatusClean);
...@@ -1047,9 +1045,8 @@ src/file2.ts ...@@ -1047,9 +1045,8 @@ src/file2.ts
}); });
it("should be true when latest assistant commit differs from current", async () => { it("should be true when latest assistant commit differs from current", async () => {
const { getCurrentCommitHash, isGitStatusClean } = await import( const { getCurrentCommitHash, isGitStatusClean } =
"@/ipc/utils/git_utils" await import("@/ipc/utils/git_utils");
);
const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash); const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash);
const mockIsGitStatusClean = vi.mocked(isGitStatusClean); const mockIsGitStatusClean = vi.mocked(isGitStatusClean);
...@@ -1083,9 +1080,8 @@ src/file2.ts ...@@ -1083,9 +1080,8 @@ src/file2.ts
}); });
it("should be true when git status is dirty even if commits match", async () => { it("should be true when git status is dirty even if commits match", async () => {
const { getCurrentCommitHash, isGitStatusClean } = await import( const { getCurrentCommitHash, isGitStatusClean } =
"@/ipc/utils/git_utils" await import("@/ipc/utils/git_utils");
);
const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash); const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash);
const mockIsGitStatusClean = vi.mocked(isGitStatusClean); const mockIsGitStatusClean = vi.mocked(isGitStatusClean);
......
...@@ -155,9 +155,7 @@ function ExternalLink({ ...@@ -155,9 +155,7 @@ function ExternalLink({
return ( return (
<a <a
className={`${baseClasses} ${ className={`${baseClasses} ${variant === "primary" ? primaryClasses : secondaryClasses}`}
variant === "primary" ? primaryClasses : secondaryClasses
}`}
onClick={() => IpcClient.getInstance().openExternalUrl(href)} onClick={() => IpcClient.getInstance().openExternalUrl(href)}
> >
<span>{children}</span> <span>{children}</span>
......
...@@ -985,25 +985,19 @@ function ProposalSummary({ ...@@ -985,25 +985,19 @@ function ProposalSummary({
if (sqlQueries.length) { if (sqlQueries.length) {
parts.push( parts.push(
`${sqlQueries.length} SQL ${ `${sqlQueries.length} SQL ${sqlQueries.length === 1 ? "query" : "queries"}`,
sqlQueries.length === 1 ? "query" : "queries"
}`,
); );
} }
if (serverFunctions.length) { if (serverFunctions.length) {
parts.push( parts.push(
`${serverFunctions.length} Server ${ `${serverFunctions.length} Server ${serverFunctions.length === 1 ? "Function" : "Functions"}`,
serverFunctions.length === 1 ? "Function" : "Functions"
}`,
); );
} }
if (packagesAdded.length) { if (packagesAdded.length) {
parts.push( parts.push(
`${packagesAdded.length} ${ `${packagesAdded.length} ${packagesAdded.length === 1 ? "package" : "packages"}`,
packagesAdded.length === 1 ? "package" : "packages"
}`,
); );
} }
......
...@@ -86,9 +86,7 @@ const ChatMessage = ({ message, isLastMessage }: ChatMessageProps) => { ...@@ -86,9 +86,7 @@ const ChatMessage = ({ message, isLastMessage }: ChatMessageProps) => {
return ( return (
<div <div
className={`flex ${ className={`flex ${message.role === "assistant" ? "justify-start" : "justify-end"}`}
message.role === "assistant" ? "justify-start" : "justify-end"
}`}
> >
<div className={`mt-2 w-full max-w-3xl mx-auto group`}> <div className={`mt-2 w-full max-w-3xl mx-auto group`}>
<div <div
......
...@@ -124,9 +124,7 @@ const ErrorBanner = ({ error, onDismiss, onAIFix }: ErrorBannerProps) => { ...@@ -124,9 +124,7 @@ const ErrorBanner = ({ error, onDismiss, onAIFix }: ErrorBannerProps) => {
> >
<ChevronRight <ChevronRight
size={14} size={14}
className={`mt-0.5 transform transition-transform ${ className={`mt-0.5 transform transition-transform ${isCollapsed ? "" : "rotate-90"}`}
isCollapsed ? "" : "rotate-90"
}`}
/> />
{isCollapsed ? getTruncatedError() : error.message} {isCollapsed ? getTruncatedError() : error.message}
...@@ -561,9 +559,7 @@ export const PreviewIframe = ({ loading }: { loading: boolean }) => { ...@@ -561,9 +559,7 @@ export const PreviewIframe = ({ loading }: { loading: boolean }) => {
type === "iframe-sourcemapped-error" type === "iframe-sourcemapped-error"
? payload?.stack?.split("\n").slice(0, 1).join("\n") ? payload?.stack?.split("\n").slice(0, 1).join("\n")
: payload?.stack; : payload?.stack;
const errorMessage = `Error ${ const errorMessage = `Error ${payload?.message || payload?.reason}\nStack trace: ${stack}`;
payload?.message || payload?.reason
}\nStack trace: ${stack}`;
console.error("Iframe error:", errorMessage); console.error("Iframe error:", errorMessage);
setErrorMessage({ message: errorMessage, source: "preview-app" }); setErrorMessage({ message: errorMessage, source: "preview-app" });
const logEntry = { const logEntry = {
...@@ -996,7 +992,7 @@ export const PreviewIframe = ({ loading }: { loading: boolean }) => { ...@@ -996,7 +992,7 @@ export const PreviewIframe = ({ loading }: { loading: boolean }) => {
}} }}
variant="outline" variant="outline"
> >
{/* Tooltips placed inside items instead of wrapping {/* Tooltips placed inside items instead of wrapping
to avoid asChild prop merging that breaks highlighting */} to avoid asChild prop merging that breaks highlighting */}
<ToggleGroupItem value="desktop" aria-label="Desktop view"> <ToggleGroupItem value="desktop" aria-label="Desktop view">
<Tooltip> <Tooltip>
......
...@@ -100,8 +100,8 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) { ...@@ -100,8 +100,8 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
| undefined; | undefined;
const isVertexConfigured = Boolean( const isVertexConfigured = Boolean(
vertexSettings?.projectId && vertexSettings?.projectId &&
vertexSettings?.location && vertexSettings?.location &&
vertexSettings?.serviceAccountKey?.value, vertexSettings?.serviceAccountKey?.value,
); );
const isAzureConfigured = const isAzureConfigured =
......
...@@ -66,9 +66,9 @@ export function VertexConfiguration() { ...@@ -66,9 +66,9 @@ export function VertexConfiguration() {
const isConfigured = Boolean( const isConfigured = Boolean(
(projectId.trim() && location && serviceAccountKey) || (projectId.trim() && location && serviceAccountKey) ||
(existing.projectId && (existing.projectId &&
existing.location && existing.location &&
existing.serviceAccountKey?.value), existing.serviceAccountKey?.value),
); );
return ( return (
......
...@@ -24,7 +24,8 @@ const badgeVariants = cva( ...@@ -24,7 +24,8 @@ const badgeVariants = cva(
); );
export interface BadgeProps export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>, extends
React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {} VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) { function Badge({ className, variant, ...props }: BadgeProps) {
......
...@@ -2,8 +2,7 @@ import * as React from "react"; ...@@ -2,8 +2,7 @@ import * as React from "react";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
export interface TextareaProps export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>( const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => { ({ className, ...props }, ref) => {
......
...@@ -168,7 +168,9 @@ export const language_models = sqliteTable("language_models", { ...@@ -168,7 +168,9 @@ export const language_models = sqliteTable("language_models", {
builtinProviderId: text("builtin_provider_id"), builtinProviderId: text("builtin_provider_id"),
customProviderId: text("custom_provider_id").references( customProviderId: text("custom_provider_id").references(
() => language_model_providers.id, () => language_model_providers.id,
{ onDelete: "cascade" }, {
onDelete: "cascade",
},
), ),
description: text("description"), description: text("description"),
max_output_tokens: integer("max_output_tokens"), max_output_tokens: integer("max_output_tokens"),
......
...@@ -41,7 +41,7 @@ export function useLanguageModelProviders() { ...@@ -41,7 +41,7 @@ export function useLanguageModelProviders() {
const azureSettings = providerSettings as AzureProviderSetting; const azureSettings = providerSettings as AzureProviderSetting;
const hasSavedSettings = Boolean( const hasSavedSettings = Boolean(
(azureSettings?.apiKey?.value ?? "").trim() && (azureSettings?.apiKey?.value ?? "").trim() &&
(azureSettings?.resourceName ?? "").trim(), (azureSettings?.resourceName ?? "").trim(),
); );
if (hasSavedSettings) { if (hasSavedSettings) {
return true; return true;
......
...@@ -8,10 +8,8 @@ export function useShortcut( ...@@ -8,10 +8,8 @@ export function useShortcut(
iframeRef?: React.RefObject<HTMLIFrameElement | null>, iframeRef?: React.RefObject<HTMLIFrameElement | null>,
): void { ): void {
useEffect(() => { useEffect(() => {
const isModifierActive = ( const isModifierActive = (modKey: boolean | undefined, eventKey: boolean) =>
modKey: boolean | undefined, modKey ? eventKey : true;
eventKey: boolean,
) => (modKey ? eventKey : true);
const validateShortcut = ( const validateShortcut = (
eventKey: string, eventKey: string,
......
...@@ -362,9 +362,7 @@ async function pollForAccessToken(event: IpcMainInvokeEvent) { ...@@ -362,9 +362,7 @@ async function pollForAccessToken(event: IpcMainInvokeEvent) {
`Unknown GitHub error: ${data.error_description || data.error}`, `Unknown GitHub error: ${data.error_description || data.error}`,
); );
event.sender.send("github:flow-error", { event.sender.send("github:flow-error", {
error: `GitHub authorization error: ${ error: `GitHub authorization error: ${data.error_description || data.error}`,
data.error_description || data.error
}`,
}); });
stopPolling(); stopPolling();
break; break;
......
...@@ -298,9 +298,7 @@ const getProposalHandler = async ( ...@@ -298,9 +298,7 @@ const getProposalHandler = async (
const totalTokens = messagesTokenCount + codebaseTokenCount; const totalTokens = messagesTokenCount + codebaseTokenCount;
const contextWindow = Math.min(await getContextWindow(), 100_000); const contextWindow = Math.min(await getContextWindow(), 100_000);
logger.log( logger.log(
`Token usage: ${totalTokens}/${contextWindow} (${ `Token usage: ${totalTokens}/${contextWindow} (${(totalTokens / contextWindow) * 100}%)`,
(totalTokens / contextWindow) * 100
}%)`,
); );
// If we're using more than 80% of the context window, suggest summarizing // If we're using more than 80% of the context window, suggest summarizing
......
...@@ -559,8 +559,10 @@ export interface McpServer { ...@@ -559,8 +559,10 @@ export interface McpServer {
updatedAt: number; updatedAt: number;
} }
export interface CreateMcpServer export interface CreateMcpServer extends Omit<
extends Omit<McpServer, "id" | "createdAt" | "updatedAt"> {} McpServer,
"id" | "createdAt" | "updatedAt"
> {}
export type McpServerUpdate = Partial<McpServer> & Pick<McpServer, "id">; export type McpServerUpdate = Partial<McpServer> & Pick<McpServer, "id">;
export type McpToolConsentType = "ask" | "always" | "denied"; export type McpToolConsentType = "ask" | "always" | "denied";
......
...@@ -29,14 +29,10 @@ export async function executeAddDependency({ ...@@ -29,14 +29,10 @@ export async function executeAddDependency({
// Update the message content with the installation results // Update the message content with the installation results
const updatedContent = message.content.replace( const updatedContent = message.content.replace(
new RegExp( new RegExp(
`<dyad-add-dependency packages="${packages.join( `<dyad-add-dependency packages="${packages.join(" ")}">[^<]*</dyad-add-dependency>`,
" ",
)}">[^<]*</dyad-add-dependency>`,
"g", "g",
), ),
`<dyad-add-dependency packages="${packages.join( `<dyad-add-dependency packages="${packages.join(" ")}">${installResults}</dyad-add-dependency>`,
" ",
)}">${installResults}</dyad-add-dependency>`,
); );
// Save the updated message back to the database // Save the updated message back to the database
......
...@@ -224,9 +224,7 @@ export async function processFullResponseActions( ...@@ -224,9 +224,7 @@ export async function processFullResponseActions(
}); });
} catch (error) { } catch (error) {
errors.push({ errors.push({
message: `Failed to add dependencies: ${dyadAddDependencyPackages.join( message: `Failed to add dependencies: ${dyadAddDependencyPackages.join(", ")}`,
", ",
)}`,
error: error, error: error,
}); });
} }
...@@ -573,9 +571,7 @@ export async function processFullResponseActions( ...@@ -573,9 +571,7 @@ export async function processFullResponseActions(
// Just log, but don't throw an error because the user can still // Just log, but don't throw an error because the user can still
// commit these changes outside of Dyad if needed. // commit these changes outside of Dyad if needed.
logger.error( logger.error(
`Failed to commit changes outside of dyad: ${uncommittedFiles.join( `Failed to commit changes outside of dyad: ${uncommittedFiles.join(", ")}`,
", ",
)}`,
); );
extraFilesError = (error as any).toString(); extraFilesError = (error as any).toString();
} }
......
...@@ -358,16 +358,16 @@ export function isSupabaseConnected(settings: UserSettings | null): boolean { ...@@ -358,16 +358,16 @@ export function isSupabaseConnected(settings: UserSettings | null): boolean {
} }
return Boolean( return Boolean(
settings.supabase?.accessToken || settings.supabase?.accessToken ||
(settings.supabase?.organizations && (settings.supabase?.organizations &&
Object.keys(settings.supabase.organizations).length > 0), Object.keys(settings.supabase.organizations).length > 0),
); );
} }
export function isTurboEditsV2Enabled(settings: UserSettings): boolean { export function isTurboEditsV2Enabled(settings: UserSettings): boolean {
return Boolean( return Boolean(
isDyadProEnabled(settings) && isDyadProEnabled(settings) &&
settings.enableProLazyEditsMode === true && settings.enableProLazyEditsMode === true &&
settings.proLazyEditsMode === "v2", settings.proLazyEditsMode === "v2",
); );
} }
......
{ {
"name": "fake-llm-server", "name": "fake-llm-server",
"version": "1.0.0", "version": "1.0.0",
"description": "Fake OpenAI API server for testing",
"keywords": [],
"license": "ISC",
"author": "",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
...@@ -8,10 +12,6 @@ ...@@ -8,10 +12,6 @@
"dev": "ts-node index.ts", "dev": "ts-node index.ts",
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"keywords": [],
"author": "",
"license": "ISC",
"description": "Fake OpenAI API server for testing",
"dependencies": { "dependencies": {
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.18.2", "express": "^4.18.2",
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论