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
```
Notes:
- If `$ARGUMENTS` is provided without the `e2e-tests/` prefix, 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
......@@ -53,7 +52,6 @@ Identify and fix flaky E2E tests by running them repeatedly and investigating fa
```
Analyze the debug output to understand:
- Timing issues (race conditions, elements not ready)
- Animation/transition interference
- Network timing variability
......@@ -63,7 +61,6 @@ Identify and fix flaky E2E tests by running them repeatedly and investigating fa
6. **Fix the flaky test:**
Common fixes following Playwright best practices:
- Use `await expect(locator).toBeVisible()` before interacting with elements
- Use `await page.waitForLoadState('networkidle')` for network-dependent tests
- 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
9. **Summarize results:**
Report to the user:
- Which tests were identified as flaky
- What was causing the flakiness
- What fixes were applied
......
......@@ -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'`
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 "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.
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:
- Do the changes align with what the PR is trying to accomplish?
- 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
1. **Fetch the GitHub issue:**
First, extract the issue number from `$ARGUMENTS`:
- 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
......@@ -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:**
- Understand what the issue is asking for
- Identify the type of work (bug fix, feature, refactor, etc.)
- Note any specific requirements or constraints mentioned
3. **Explore the codebase:**
- Search for relevant files and code related to the issue
- Understand the current implementation
- 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
4. **Determine testing approach:**
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.
- **Unit test**: For pure business logic, utility functions, or isolated components.
- **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
5. **Create a detailed plan:**
Write a plan that includes:
- **Summary**: Brief description of the issue and proposed solution
- **Files to modify**: List of files that will need changes
- **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
7. **Ask how to proceed:**
After the plan is approved, ask the user whether they want to:
- **Continue locally**: Implement the plan in the current session
- **Send to remote**: Push to a remote Claude session for implementation
8. **Execute based on user choice:**
- 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
......@@ -7,7 +7,7 @@ Run pre-commit checks including formatting, linting, and type-checking, and fix
1. **Run formatting check and fix:**
```
npm run prettier
npm run fmt
```
This will automatically fix any formatting issues.
......@@ -23,7 +23,6 @@ Run pre-commit checks including formatting, linting, and type-checking, and fix
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:
- Unused variables or imports (remove them)
- Missing return types (add them)
- Any other ESLint rule violations
......@@ -37,7 +36,6 @@ Run pre-commit checks including formatting, linting, and type-checking, and fix
5. **Fix any type errors:**
If there are type errors, read the affected files and fix them. Common issues include:
- Type mismatches (correct the types)
- Missing type annotations (add them)
- Null/undefined handling issues (add appropriate checks)
......@@ -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:
```
npm run prettier && npm run lint && npm run ts
npm run fmt && npm run lint && npm run ts
```
7. **Summarize the results:**
- Report which checks passed
- List any fixes that were made manually
- 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
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:
- Address valid code review concerns
- Resolve invalid concerns with explanations
- Flag ambiguous issues for human attention
2. **Run `/dyad:pr-fix:actions`** to handle failing CI checks:
- Fix failing tests (unit and E2E)
- Update snapshots if needed
- Ensure all checks pass
......
......@@ -9,7 +9,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
## Instructions
1. **Determine the PR to work on:**
- 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 '.'`
- 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.
```
Identify which checks are failing:
- Lint/formatting checks
- Type checks
- Unit tests
......@@ -29,19 +27,16 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
- Build checks
3. **For failing lint/formatting checks:**
- 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
4. **For failing type checks:**
- Run `npm run ts` to identify type errors
- Read the relevant files and fix the type issues
- Re-run type checks to verify fixes
5. **For failing unit tests:**
- Run the failing tests locally to reproduce:
```
npm run test -- <test-file-pattern>
......@@ -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
6. **For failing Playwright/E2E tests:**
- 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 the failures are not snapshot-related:
......@@ -61,7 +55,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
- Investigate and fix the underlying issues
7. **For failing build checks:**
- Run the build locally:
```
npm run build
......@@ -69,7 +62,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
- Fix any build errors that appear
8. **After making all fixes, verify:**
- Run the full lint check: `npm run lint`
- Run type checks: `npm run ts`
- Run relevant unit tests
......@@ -93,7 +85,6 @@ Fix failing CI checks and GitHub Actions on a Pull Request.
Then run `/dyad:pr-push` to push the changes.
10. **Provide a summary to the user:**
- List which checks were failing
- Describe what was fixed for each
- 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
## Instructions
1. **Determine the PR to work on:**
- If `$ARGUMENTS` is provided:
- 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
......@@ -54,7 +53,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately
3. **For each unresolved review thread, categorize it:**
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.)
- **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
......@@ -62,14 +60,12 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately
4. **Handle each category:**
**For valid issues:**
- Read the relevant file(s) mentioned in the comment
- Understand the context and the requested change
- 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)
**For not valid issues:**
- 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
Note: Replace `<THREAD_ID>` with the thread's `id` field from the GraphQL response.
**For ambiguous issues:**
- Reply to the thread flagging it for human attention:
```
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
5. **After processing all comments, verify and commit changes:**
If any code changes were made:
- Run `/dyad:lint` to ensure code passes all checks
- Stage and commit the changes:
......@@ -126,7 +120,6 @@ Read all unresolved GitHub PR comments and address or resolve them appropriately
7. **Provide a summary to the user:**
Report:
- **Addressed**: List of comments that were fixed with code changes
- **Resolved (not valid)**: List of comments that were resolved with explanations
- **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
Run `git status` to check for any uncommitted changes (staged, unstaged, or untracked files).
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)
- 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
......@@ -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:
```
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.
......@@ -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.
5. **Summarize the results:**
- 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 lint fixes that were applied
......
......@@ -28,7 +28,6 @@ Rebase the current branch on the latest upstream changes, resolve conflicts, and
For example: `git rebase upstream/main`
4. **If there are merge conflicts:**
- Identify the conflicting files from the rebase output
- Read each conflicting file and understand both versions of the changes
- 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
Run the `/dyad:pr-push` skill to run lint checks, fix any issues, and push the rebased branch.
6. **Summarize the results:**
- Report that the rebase was successful
- List any conflicts that were resolved
- Note any lint fixes that were applied
......
......@@ -13,7 +13,6 @@ Analyze session debugging data to identify errors and issues that may have cause
1. **Parse and validate the arguments:**
Split `$ARGUMENTS` on whitespace to get exactly two arguments:
- 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`)
......@@ -31,7 +30,6 @@ Analyze session debugging data to identify errors and issues that may have cause
```
Understand:
- What problem the user is reporting
- Steps to reproduce (if provided)
- Expected vs actual behavior
......@@ -44,7 +42,6 @@ Analyze session debugging data to identify errors and issues that may have cause
4. **Analyze the session data:**
Look for suspicious entries including:
- **Errors**: Any error messages, stack traces, or exception logs
- **Warnings**: Warning-level log entries that may indicate problems
- **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
5. **Correlate with the reported issue:**
For each suspicious entry found, assess:
- Does the timing match when the user reported the issue occurring?
- Does the error message relate to the feature/area the user mentioned?
- 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
7. **Provide recommendations:**
For each high-confidence finding, suggest:
- Where in the codebase to investigate
- Potential root causes
- Suggested fixes if apparent
8. **Summarize:**
- Total errors/warnings found
- Top 3 most likely causes
- 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(
const iframe = po.getPreviewIframeElement();
await expect(
iframe.contentFrame().getByText("Console Logs Test App"),
).toBeVisible({ timeout: Timeout.MEDIUM });
).toBeVisible({
timeout: Timeout.MEDIUM,
});
// Open the system messages console
// Logs are generated in useEffect when component mounts, so they may already exist
......@@ -99,7 +101,9 @@ testSkipIfWindows(
const iframeFrame = iframe.contentFrame();
await expect(
iframeFrame.getByText("Network Requests Test App"),
).toBeVisible({ timeout: Timeout.MEDIUM });
).toBeVisible({
timeout: Timeout.MEDIUM,
});
// Wait for service worker to be ready
// 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 }) => {
const iframe = po.getPreviewIframeElement();
await expect(
iframe.contentFrame().getByText("Console Logs Test App"),
).toBeVisible({ timeout: Timeout.MEDIUM });
).toBeVisible({
timeout: Timeout.MEDIUM,
});
// Open the system messages console
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 (
// Wait for the code view to finish loading files
await expect(
po.page.getByText("Loading files...", { exact: false }),
).toBeHidden({ timeout: Timeout.LONG });
).toBeHidden({
timeout: Timeout.LONG,
});
const searchInput = po.page.getByTestId("file-tree-search");
await expect(searchInput).toBeVisible({ timeout: Timeout.MEDIUM });
......
......@@ -227,6 +227,8 @@ test.describe("Git Collaboration", () => {
await po.waitForToast("success");
await expect(
po.page.getByTestId(`collaborator-item-${fakeUser}`),
).not.toBeVisible({ timeout: 5000 });
).not.toBeVisible({
timeout: 5000,
});
});
});
......@@ -733,7 +733,9 @@ export class PageObject {
async waitForAnnotatorMode() {
// Wait for the annotator toolbar to be visible
await expect(this.page.getByRole("button", { name: "Select" })).toBeVisible(
{ timeout: Timeout.MEDIUM },
{
timeout: Timeout.MEDIUM,
},
);
}
......
......@@ -24,7 +24,9 @@ testSkipIfWindows(
// The button may not exist if there are no problems, so we check for the "No problems found" text
await expect(
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
await po.sendPrompt("tc=local-agent/run-type-checks");
......
......@@ -38,7 +38,9 @@ testWithConfig({
// Check if the force-close dialog is visible by looking for the heading
await expect(
po.page.getByRole("heading", { name: "Force Close Detected" }),
).toBeVisible({ timeout: Timeout.MEDIUM });
).toBeVisible({
timeout: Timeout.MEDIUM,
});
// Verify the warning message
await expect(
......
......@@ -205,7 +205,9 @@ testSkipIfWindows("discard changes", async ({ po }) => {
// Verify the visual changes dialog is gone
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
......
module.exports = {
"**/*.{ts,tsx}": () => "npm run ts",
"**/*.{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",
"productName": "dyad",
"version": "0.34.0-beta.1",
"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": {
"type": "git",
"url": "https://github.com/dyad-sh/dyad.git"
},
"engines": {
"node": ">=20"
},
"main": ".vite/build/main.js",
"scripts": {
"clean": "rimraf out scaffold/node_modules",
"start": "electron-forge start",
......@@ -28,9 +30,9 @@
"db:generate": "drizzle-kit generate",
"db:push": "drizzle-kit push",
"db:studio": "drizzle-kit studio",
"prettier:check": "npx prettier --check .",
"prettier": "npx prettier --write .",
"presubmit": "npm run prettier:check && npm run lint",
"fmt:check": "npx oxfmt --check",
"fmt": "npx oxfmt",
"presubmit": "npm run fmt:check && npm run lint",
"test": "vitest run",
"test:watch": "vitest",
"test:ui": "vitest --ui",
......@@ -40,52 +42,6 @@
"e2e": "playwright test",
"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": {
"@ai-sdk/amazon-bedrock": "^4.0.9",
"@ai-sdk/anthropic": "^3.0.7",
......@@ -182,9 +138,53 @@
"uuid": "^11.1.0",
"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": {
"@vercel/sdk": {
"@modelcontextprotocol/sdk": "$@modelcontextprotocol/sdk"
}
}
},
"engines": {
"node": ">=20"
},
"productName": "dyad"
}
......@@ -2,31 +2,31 @@
"name": "@dyad-sh/nextjs-webpack-component-tagger",
"version": "0.8.0",
"description": "A webpack loader that automatically adds data attributes to your React components in Next.js.",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"type": "module",
"keywords": [
"dyad",
"nextjs",
"react",
"webpack",
"webpack-loader"
],
"license": "Apache-2.0",
"author": "Dyad",
"files": [
"dist"
],
"type": "module",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "npm run build -- --watch",
"lint": "eslint . --max-warnings 0",
"prepublishOnly": "npm run build"
},
"keywords": [
"webpack",
"webpack-loader",
"nextjs",
"react",
"dyad"
],
"author": "Dyad",
"license": "Apache-2.0",
"peerDependencies": {
"webpack": "^5.0.0"
},
"dependencies": {
"@babel/parser": "^7.23.0",
"estree-walker": "^2.0.2",
......@@ -39,7 +39,7 @@
"tsup": "^8.0.2",
"typescript": "^5.2.2"
},
"publishConfig": {
"access": "public"
"peerDependencies": {
"webpack": "^5.0.0"
}
}
......@@ -2,30 +2,30 @@
"name": "@dyad-sh/react-vite-component-tagger",
"version": "0.8.0",
"description": "A Vite plugin that automatically adds data attributes to your React components.",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"type": "module",
"keywords": [
"dyad",
"react",
"vite",
"vite-plugin"
],
"license": "Apache-2.0",
"author": "Dyad",
"files": [
"dist"
],
"type": "module",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "npm run build -- --watch",
"lint": "eslint . --max-warnings 0",
"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": {
"@babel/parser": "^7.23.0",
"estree-walker": "^2.0.2",
......@@ -38,7 +38,7 @@
"typescript": "^5.2.2",
"vite": "^5.0.0"
},
"publishConfig": {
"access": "public"
"peerDependencies": {
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
}
}
{
"name": "vite_react_shadcn_ts",
"private": true,
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
......
......@@ -24,7 +24,8 @@ const badgeVariants = cva(
);
export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
extends
React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) {
......
......@@ -34,7 +34,8 @@ const buttonVariants = cva(
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
extends
React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
......
......@@ -48,7 +48,8 @@ const sheetVariants = cva(
);
interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
extends
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
VariantProps<typeof sheetVariants> {}
const SheetContent = React.forwardRef<
......
......@@ -2,8 +2,7 @@ import * as React from "react";
import { cn } from "@/lib/utils";
export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => {
......
......@@ -702,7 +702,9 @@ describe("processFullResponse", () => {
expect(fs.mkdirSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src",
{ recursive: true },
{
recursive: true,
},
);
expect(fs.writeFileSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src/file1.js",
......@@ -759,15 +761,21 @@ describe("processFullResponse", () => {
// Check that directories were created for each file path
expect(fs.mkdirSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src",
{ recursive: true },
{
recursive: true,
},
);
expect(fs.mkdirSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src/utils",
{ recursive: true },
{
recursive: true,
},
);
expect(fs.mkdirSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src/components",
{ recursive: true },
{
recursive: true,
},
);
// Using toHaveBeenNthCalledWith to check each specific call
......@@ -824,7 +832,9 @@ describe("processFullResponse", () => {
expect(fs.mkdirSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src/components",
{ recursive: true },
{
recursive: true,
},
);
expect(fs.renameSync).toHaveBeenCalledWith(
"/mock/user/data/path/mock-app-path/src/components/OldComponent.jsx",
......
......@@ -978,9 +978,8 @@ src/file2.ts
describe("hasExternalChanges", () => {
it("should default to true when no assistant message has commitHash", async () => {
const { getCurrentCommitHash, isGitStatusClean } = await import(
"@/ipc/utils/git_utils"
);
const { getCurrentCommitHash, isGitStatusClean } =
await import("@/ipc/utils/git_utils");
const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash);
const mockIsGitStatusClean = vi.mocked(isGitStatusClean);
......@@ -1011,9 +1010,8 @@ src/file2.ts
});
it("should be false when latest assistant commit matches current and git status is clean", async () => {
const { getCurrentCommitHash, isGitStatusClean } = await import(
"@/ipc/utils/git_utils"
);
const { getCurrentCommitHash, isGitStatusClean } =
await import("@/ipc/utils/git_utils");
const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash);
const mockIsGitStatusClean = vi.mocked(isGitStatusClean);
......@@ -1047,9 +1045,8 @@ src/file2.ts
});
it("should be true when latest assistant commit differs from current", async () => {
const { getCurrentCommitHash, isGitStatusClean } = await import(
"@/ipc/utils/git_utils"
);
const { getCurrentCommitHash, isGitStatusClean } =
await import("@/ipc/utils/git_utils");
const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash);
const mockIsGitStatusClean = vi.mocked(isGitStatusClean);
......@@ -1083,9 +1080,8 @@ src/file2.ts
});
it("should be true when git status is dirty even if commits match", async () => {
const { getCurrentCommitHash, isGitStatusClean } = await import(
"@/ipc/utils/git_utils"
);
const { getCurrentCommitHash, isGitStatusClean } =
await import("@/ipc/utils/git_utils");
const mockGetCurrentCommitHash = vi.mocked(getCurrentCommitHash);
const mockIsGitStatusClean = vi.mocked(isGitStatusClean);
......
......@@ -155,9 +155,7 @@ function ExternalLink({
return (
<a
className={`${baseClasses} ${
variant === "primary" ? primaryClasses : secondaryClasses
}`}
className={`${baseClasses} ${variant === "primary" ? primaryClasses : secondaryClasses}`}
onClick={() => IpcClient.getInstance().openExternalUrl(href)}
>
<span>{children}</span>
......
......@@ -985,25 +985,19 @@ function ProposalSummary({
if (sqlQueries.length) {
parts.push(
`${sqlQueries.length} SQL ${
sqlQueries.length === 1 ? "query" : "queries"
}`,
`${sqlQueries.length} SQL ${sqlQueries.length === 1 ? "query" : "queries"}`,
);
}
if (serverFunctions.length) {
parts.push(
`${serverFunctions.length} Server ${
serverFunctions.length === 1 ? "Function" : "Functions"
}`,
`${serverFunctions.length} Server ${serverFunctions.length === 1 ? "Function" : "Functions"}`,
);
}
if (packagesAdded.length) {
parts.push(
`${packagesAdded.length} ${
packagesAdded.length === 1 ? "package" : "packages"
}`,
`${packagesAdded.length} ${packagesAdded.length === 1 ? "package" : "packages"}`,
);
}
......
......@@ -86,9 +86,7 @@ const ChatMessage = ({ message, isLastMessage }: ChatMessageProps) => {
return (
<div
className={`flex ${
message.role === "assistant" ? "justify-start" : "justify-end"
}`}
className={`flex ${message.role === "assistant" ? "justify-start" : "justify-end"}`}
>
<div className={`mt-2 w-full max-w-3xl mx-auto group`}>
<div
......
......@@ -124,9 +124,7 @@ const ErrorBanner = ({ error, onDismiss, onAIFix }: ErrorBannerProps) => {
>
<ChevronRight
size={14}
className={`mt-0.5 transform transition-transform ${
isCollapsed ? "" : "rotate-90"
}`}
className={`mt-0.5 transform transition-transform ${isCollapsed ? "" : "rotate-90"}`}
/>
{isCollapsed ? getTruncatedError() : error.message}
......@@ -561,9 +559,7 @@ export const PreviewIframe = ({ loading }: { loading: boolean }) => {
type === "iframe-sourcemapped-error"
? payload?.stack?.split("\n").slice(0, 1).join("\n")
: payload?.stack;
const errorMessage = `Error ${
payload?.message || payload?.reason
}\nStack trace: ${stack}`;
const errorMessage = `Error ${payload?.message || payload?.reason}\nStack trace: ${stack}`;
console.error("Iframe error:", errorMessage);
setErrorMessage({ message: errorMessage, source: "preview-app" });
const logEntry = {
......@@ -996,7 +992,7 @@ export const PreviewIframe = ({ loading }: { loading: boolean }) => {
}}
variant="outline"
>
{/* Tooltips placed inside items instead of wrapping
{/* Tooltips placed inside items instead of wrapping
to avoid asChild prop merging that breaks highlighting */}
<ToggleGroupItem value="desktop" aria-label="Desktop view">
<Tooltip>
......
......@@ -100,8 +100,8 @@ export function ProviderSettingsPage({ provider }: ProviderSettingsPageProps) {
| undefined;
const isVertexConfigured = Boolean(
vertexSettings?.projectId &&
vertexSettings?.location &&
vertexSettings?.serviceAccountKey?.value,
vertexSettings?.location &&
vertexSettings?.serviceAccountKey?.value,
);
const isAzureConfigured =
......
......@@ -66,9 +66,9 @@ export function VertexConfiguration() {
const isConfigured = Boolean(
(projectId.trim() && location && serviceAccountKey) ||
(existing.projectId &&
existing.location &&
existing.serviceAccountKey?.value),
(existing.projectId &&
existing.location &&
existing.serviceAccountKey?.value),
);
return (
......
......@@ -24,7 +24,8 @@ const badgeVariants = cva(
);
export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
extends
React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) {
......
......@@ -2,8 +2,7 @@ import * as React from "react";
import { cn } from "@/lib/utils";
export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => {
......
......@@ -168,7 +168,9 @@ export const language_models = sqliteTable("language_models", {
builtinProviderId: text("builtin_provider_id"),
customProviderId: text("custom_provider_id").references(
() => language_model_providers.id,
{ onDelete: "cascade" },
{
onDelete: "cascade",
},
),
description: text("description"),
max_output_tokens: integer("max_output_tokens"),
......
......@@ -41,7 +41,7 @@ export function useLanguageModelProviders() {
const azureSettings = providerSettings as AzureProviderSetting;
const hasSavedSettings = Boolean(
(azureSettings?.apiKey?.value ?? "").trim() &&
(azureSettings?.resourceName ?? "").trim(),
(azureSettings?.resourceName ?? "").trim(),
);
if (hasSavedSettings) {
return true;
......
......@@ -8,10 +8,8 @@ export function useShortcut(
iframeRef?: React.RefObject<HTMLIFrameElement | null>,
): void {
useEffect(() => {
const isModifierActive = (
modKey: boolean | undefined,
eventKey: boolean,
) => (modKey ? eventKey : true);
const isModifierActive = (modKey: boolean | undefined, eventKey: boolean) =>
modKey ? eventKey : true;
const validateShortcut = (
eventKey: string,
......
......@@ -362,9 +362,7 @@ async function pollForAccessToken(event: IpcMainInvokeEvent) {
`Unknown GitHub error: ${data.error_description || data.error}`,
);
event.sender.send("github:flow-error", {
error: `GitHub authorization error: ${
data.error_description || data.error
}`,
error: `GitHub authorization error: ${data.error_description || data.error}`,
});
stopPolling();
break;
......
......@@ -298,9 +298,7 @@ const getProposalHandler = async (
const totalTokens = messagesTokenCount + codebaseTokenCount;
const contextWindow = Math.min(await getContextWindow(), 100_000);
logger.log(
`Token usage: ${totalTokens}/${contextWindow} (${
(totalTokens / contextWindow) * 100
}%)`,
`Token usage: ${totalTokens}/${contextWindow} (${(totalTokens / contextWindow) * 100}%)`,
);
// If we're using more than 80% of the context window, suggest summarizing
......
......@@ -559,8 +559,10 @@ export interface McpServer {
updatedAt: number;
}
export interface CreateMcpServer
extends Omit<McpServer, "id" | "createdAt" | "updatedAt"> {}
export interface CreateMcpServer extends Omit<
McpServer,
"id" | "createdAt" | "updatedAt"
> {}
export type McpServerUpdate = Partial<McpServer> & Pick<McpServer, "id">;
export type McpToolConsentType = "ask" | "always" | "denied";
......
......@@ -29,14 +29,10 @@ export async function executeAddDependency({
// Update the message content with the installation results
const updatedContent = message.content.replace(
new RegExp(
`<dyad-add-dependency packages="${packages.join(
" ",
)}">[^<]*</dyad-add-dependency>`,
`<dyad-add-dependency packages="${packages.join(" ")}">[^<]*</dyad-add-dependency>`,
"g",
),
`<dyad-add-dependency packages="${packages.join(
" ",
)}">${installResults}</dyad-add-dependency>`,
`<dyad-add-dependency packages="${packages.join(" ")}">${installResults}</dyad-add-dependency>`,
);
// Save the updated message back to the database
......
......@@ -224,9 +224,7 @@ export async function processFullResponseActions(
});
} catch (error) {
errors.push({
message: `Failed to add dependencies: ${dyadAddDependencyPackages.join(
", ",
)}`,
message: `Failed to add dependencies: ${dyadAddDependencyPackages.join(", ")}`,
error: error,
});
}
......@@ -573,9 +571,7 @@ export async function processFullResponseActions(
// Just log, but don't throw an error because the user can still
// commit these changes outside of Dyad if needed.
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();
}
......
......@@ -358,16 +358,16 @@ export function isSupabaseConnected(settings: UserSettings | null): boolean {
}
return Boolean(
settings.supabase?.accessToken ||
(settings.supabase?.organizations &&
Object.keys(settings.supabase.organizations).length > 0),
(settings.supabase?.organizations &&
Object.keys(settings.supabase.organizations).length > 0),
);
}
export function isTurboEditsV2Enabled(settings: UserSettings): boolean {
return Boolean(
isDyadProEnabled(settings) &&
settings.enableProLazyEditsMode === true &&
settings.proLazyEditsMode === "v2",
settings.enableProLazyEditsMode === true &&
settings.proLazyEditsMode === "v2",
);
}
......
{
"name": "fake-llm-server",
"version": "1.0.0",
"description": "Fake OpenAI API server for testing",
"keywords": [],
"license": "ISC",
"author": "",
"main": "dist/index.js",
"scripts": {
"build": "tsc",
......@@ -8,10 +12,6 @@
"dev": "ts-node index.ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "Fake OpenAI API server for testing",
"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.2",
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论