Skip to content

Commit fb78845

Browse files
committed
Initial commit without large files
0 parents  commit fb78845

File tree

1,843 files changed

+307055
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,843 files changed

+307055
-0
lines changed

.cursor/rules/ipc.mdc

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
description:
3+
globs:
4+
alwaysApply: true
5+
---
6+
You're building an Electron app following good security practices
7+
8+
# IPC
9+
Structure:
10+
- [ipc_client.ts](mdc:src/ipc/ipc_client.ts) - lives in the renderer process and is used to send IPCs to the main process.
11+
- to use it just do `IpcClient.getInstance()`
12+
- [preload.ts](mdc:src/preload.ts) - allowlist
13+
- [ipc_host.ts](mdc:src/ipc/ipc_host.ts) - contains the various IPC handlers attached which are: [app_handlers.ts](mdc:src/ipc/handlers/app_handlers.ts), [chat_stream_handlers.ts](mdc:src/ipc/handlers/chat_stream_handlers.ts), [settings_handlers.ts](mdc:src/ipc/handlers/settings_handlers.ts) etc.
14+
15+
# React
16+
- This is a React app
17+
- Using TanStack router, NOT next.js, NOT react Router.
18+
19+
20+
# IPC & React query patterns
21+
22+
23+
Okay, I can help you summarize this pattern for creating a new Cursor rule, focusing on the TanStack Query integration and the preferred error handling strategy.
24+
25+
Here's a summary of the pattern:
26+
27+
The pattern involves a client-side React hook interacting with main process IPC handlers via an `IpcClient` layer, leveraging TanStack Query for managing asynchronous operations, state, and caching.
28+
29+
**1. React Hook (e.g., `useSomething.ts`):**
30+
31+
* **Data Fetching (`useQuery`):**
32+
* Define a `queryKey` (e.g., `["entity", entityId]`) for caching and invalidation.
33+
* The `queryFn` is an asynchronous function that:
34+
* Retrieves an `IpcClient` instance.
35+
* Calls the appropriate method on `IpcClient` (e.g., `ipcClient.listEntities({ parentId })`). This method corresponds to an IPC channel.
36+
* Use the `enabled` option if the query depends on certain conditions (e.g., `entityId !== null`).
37+
* Optionally provide `initialData` and `meta` (e.g., for global error display like `showErrorToast: true`).
38+
* The hook returns `data`, `isLoading`, `error`, and a `refetch` function from `useQuery`.
39+
40+
* **Data Mutations (`useMutation`):**
41+
* The `mutationFn` is an asynchronous function that:
42+
* Performs any necessary input validation, potentially throwing an error directly if client-side checks fail (e.g., `if (!entityId) throw new Error("Entity ID is required");`).
43+
* Retrieves an `IpcClient` instance.
44+
* Calls the appropriate method on `IpcClient` (e.g., `ipcClient.createEntity({ data })`).
45+
* `onSuccess`:
46+
* Invalidate relevant queries using `queryClient.invalidateQueries({ queryKey: ["entity"] })` to ensure data consistency and trigger refetches.
47+
* Optionally, update local state directly or refetch specific related data.
48+
* `onError`:
49+
* Handle errors, often by displaying a notification to the user (e.g., using a `showError(error)` utility).
50+
* The hook exposes an asynchronous function (e.g., `createEntity`) that internally calls `mutation.mutateAsync(params)`.
51+
52+
* **Local State Management (Optional, e.g., Jotai):**
53+
* `useEffect` can synchronize data fetched by TanStack Query with global state atoms if needed.
54+
* Atoms can also store UI-related state or parameters for hooks.
55+
56+
**2. IPC Client (`ipc_client.ts`):**
57+
58+
* Acts as an intermediary between the renderer process (React hooks) and the main process (IPC handlers).
59+
* For each IPC channel, it has a corresponding asynchronous method (e.g., `async listEntities(params) { return this.ipcRenderer.invoke("list-entities", params); }`).
60+
* It uses `ipcRenderer.invoke` to send messages and receive `Promise`s. If the main process handler throws an error, the `Promise` will be rejected, and this rejection will be handled by TanStack Query in the hook.
61+
62+
**3. IPC Handlers (e.g., `entity_handlers.ts` in the main process):**
63+
64+
* **Registration:**
65+
* Handlers are registered using `ipcMain.handle("channel-name", async (event, args) => { /* ... */ })`. The `channel-name` must match what `IpcClient` calls.
66+
* **Logic:**
67+
* Contains the core business logic, interacting with databases (e.g., `db`), file system (`fs`), or other main-process services (e.g., `git`).
68+
* **Error Handling (Crucial):**
69+
* **Handlers MUST `throw new Error("Descriptive error message")` when an operation fails or an invalid state is encountered.** This is the preferred pattern over returning objects like `{ success: false, errorMessage: "..." }`.
70+
71+
* **Concurrency (If Applicable):**
72+
* For operations that modify shared resources related to a specific entity (like an `appId`), use a locking mechanism (e.g., `withLock(appId, async () => { ... })`) to prevent race conditions.
73+
74+
**Flow Summary:**
75+
76+
1. React component calls a function from the custom hook.
77+
2. The hook's `queryFn` (for reads) or `mutationFn` (for writes) calls a method on `IpcClient`.
78+
3. `IpcClient` uses `ipcRenderer.invoke` to send a message to the main process.
79+
4. The corresponding `ipcMain.handle` in the main process executes.
80+
* If successful, it returns data.
81+
* **If an error occurs, it `throw`s an `Error`.**
82+
5. The `Promise` from `ipcRenderer.invoke` resolves or rejects.
83+
6. TanStack Query handles the resolved data or the rejection:
84+
* `useQuery`: Populates `data` or `error`.
85+
* `useMutation`: Calls `onSuccess` or `onError`.
86+
87+
This pattern ensures that errors are propagated correctly from the main process back to the React application, where TanStack Query can manage the error state and allow for robust error handling and UI feedback.

.cursorignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)
2+
scaffold/

.devcontainer/devcontainer.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"image": "mcr.microsoft.com/devcontainers/universal:2",
3+
"features": {}
4+
}

.env.example

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Environment variables needed for dyad local development.
2+
# To use, copy this file to a new file named ".env" and fill in your private keys and settings.
3+
# Your actual .env file should NOT be committed.
4+
5+
# AI Provider API Keys(Optional)
6+
OPENAI_API_KEY=
7+
ANTHROPIC_API_KEY=
8+
GOOGLE_API_KEY=
9+
10+
11+
# Local AI Model Configuration (Optional)
12+
# Set these if you are running local AI models like Ollama or LM Studio.
13+
# Default for Ollama is http://127.0.0.1:11434
14+
OLLAMA_HOST=
15+
16+
# GitHub Integration (Optional)
17+
# Needed for features that interact with GitHub repositories.
18+
GITHUB_CLIENT_ID=
19+
GITHUB_CLIENT_SECRET=
20+
GITHUB_TOKEN=
21+
22+
23+
# Apple Notarization (macOS Build Only)
24+
# Only required if you are building and signing a release version for macOS.
25+
APPLE_ID=
26+
APPLE_PASSWORD=
27+
APPLE_TEAM_ID=
28+
SM_CODE_SIGNING_CERT_SHA1=
29+
30+
31+
# Development & Testing Variables (Advanced)
32+
# These are typically not needed for standard contribution.
33+
# NODE_ENV=development
34+
# E2E_TEST_BUILD=
35+
# CI=
36+
# DYAD_ENGINE_URL=
37+
# DYAD_GATEWAY_URL=

.eslintrc.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"env": {
3+
"browser": true,
4+
"es6": true,
5+
"node": true
6+
},
7+
"extends": [
8+
"eslint:recommended",
9+
"plugin:@typescript-eslint/eslint-recommended",
10+
"plugin:@typescript-eslint/recommended",
11+
"plugin:import/recommended",
12+
"plugin:import/electron",
13+
"plugin:import/typescript"
14+
],
15+
"parser": "@typescript-eslint/parser"
16+
}

.gitattributes

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Set the default behavior, in case people don't have core.autocrlf set.
2+
* text=auto
3+
4+
# Make everything in the e2e-tests/snapshots directory use LF line endings.
5+
# Otherwise we'll get diffs in the snapshots when running on Windows.
6+
e2e-tests/snapshots/** text eol=lf
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
name: Add Template
3+
about: Request to add a template to Dyad Hub
4+
title: "Add Template: [Template Name]"
5+
labels: "add-template"
6+
assignees: ""
7+
---
8+
9+
If you'd like to add a template to Dyad Hub, follow the [Add Template guide](https://alifullstack.com/docs/templates/add-template).
10+
11+
**Template name:**
12+
13+
**Template description (1-2 sentences):**
14+
15+
**GitHub repo:**
16+
17+
**Screenshot**
18+
19+
<!-- Please attach a screenshot of your template in action -->
20+
21+
**Open Source License**
22+
23+
- [ ] This template is open-source (e.g. MIT, Apache 2.0)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
name: Bug report
3+
about: Create a report to help us improve
4+
title: ""
5+
labels: "bug"
6+
assignees: ""
7+
---
8+
9+
<!--
10+
⚠️ IMPORTANT: All sections marked as required must be completed in English.
11+
Issues that do not meet these requirements will be closed and may need to be resubmitted.
12+
-->
13+
14+
**Describe the bug**
15+
A clear and concise description of what the bug is.
16+
17+
**To Reproduce**
18+
Steps to reproduce the behavior:
19+
20+
1. Go to '...'
21+
2. Click on '....'
22+
3. Scroll down to '....'
23+
4. See error
24+
25+
**Expected behavior**
26+
A clear and concise description of what you expected to happen.
27+
28+
**Screenshots**
29+
If applicable, add screenshots to help explain your problem.
30+
31+
**Desktop (please complete the following information):**
32+
33+
- OS: [e.g. iOS]
34+
- Browser [e.g. chrome, safari]
35+
- Version [e.g. 22]
36+
37+
**Additional context**
38+
Add any other context about the problem here.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea for this project
4+
title: ""
5+
labels: "feature request"
6+
assignees: ""
7+
---
8+
9+
**Is your feature request related to a problem? Please describe.**
10+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
11+
12+
**Describe the solution you'd like**
13+
A clear and concise description of what you want to happen.
14+
15+
**Describe alternatives you've considered**
16+
A clear and concise description of any alternative solutions or features you've considered.
17+
18+
**Additional context**
19+
Add any other context or screenshots about the feature request here.

.github/workflows/ci.yml

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
types: [opened, synchronize, reopened]
9+
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
defaults:
15+
run:
16+
shell: bash
17+
18+
jobs:
19+
test:
20+
# Why Mac and Windows?
21+
# I can't run electron playwright on ubuntu-latest and
22+
# Linux support for Dyad is experimental so not as important
23+
# as Mac + Windows
24+
strategy:
25+
fail-fast: false
26+
matrix:
27+
os: [
28+
# npm install is very slow
29+
# { name: "windows-arm", image: "windows-11-arm" },
30+
{ name: "windows", image: "windows-latest" },
31+
{ name: "macos", image: "macos-latest" },
32+
]
33+
shard: [1, 2, 3, 4]
34+
shardTotal: [4]
35+
runs-on: ${{ matrix.os.image }}
36+
steps:
37+
- name: Checkout code
38+
uses: actions/checkout@v4
39+
- name: Initialize environment
40+
uses: actions/setup-node@v4
41+
with:
42+
node-version-file: package.json
43+
cache: npm
44+
cache-dependency-path: package-lock.json
45+
- name: Install node modules
46+
run: npm ci --no-audit --no-fund --progress=false
47+
- name: Presubmit check (e.g. lint, format)
48+
# do not run this on Windows (it fails and not necessary)
49+
# Only run on shard 1 to avoid redundant execution
50+
if: contains(matrix.os.name, 'macos') && matrix.shard == 1
51+
run: npm run presubmit
52+
- name: Type-checking
53+
# do not run this on windows (it's redunant)
54+
# Only run on shard 1 to avoid redundant execution
55+
if: contains(matrix.os.name, 'macos') && matrix.shard == 1
56+
run: npm run ts
57+
- name: Unit tests
58+
# do not run this on windows (it's redunant)
59+
# Only run on shard 1 to avoid redundant execution
60+
if: contains(matrix.os.name, 'macos') && matrix.shard == 1
61+
run: npm run test
62+
- name: Setup pnpm
63+
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
64+
with:
65+
version: latest
66+
- name: Clone nextjs-template
67+
run: git clone --depth 1 https://github.com/SFARPak/nextjs-template.git nextjs-template
68+
- name: Get pnpm store directory
69+
id: pnpm-cache
70+
shell: bash
71+
run: |
72+
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
73+
- name: Setup pnpm cache
74+
uses: actions/cache@v4
75+
with:
76+
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
77+
key: ${{ matrix.os.name }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
78+
restore-keys: |
79+
${{ matrix.os.name }}-pnpm-store-
80+
# Not strictly needed but makes the e2e tests faster (and less flaky)
81+
- name: Install scaffold dependencies
82+
run: cd scaffold && pnpm install
83+
- name: Install nextjs-template dependencies
84+
run: cd nextjs-template && pnpm install
85+
- name: Install Chromium browser for Playwright
86+
run: npx playwright install chromium --with-deps
87+
- name: Build
88+
env:
89+
NODE_OPTIONS: "--max-old-space-size=4096"
90+
run: npm run pre:e2e
91+
- name: Prep test server
92+
run: cd testing/fake-llm-server && npm install && npm run build && cd -
93+
- name: E2E tests (Shard ${{ matrix.shard }}/4)
94+
# You can add debug logging to make it easier to see what's failing
95+
# by adding "DEBUG=pw:browser" in front.
96+
# Use blob reporter for sharding and merge capabilities
97+
run: DEBUG=pw:browser npx playwright test --shard=${{ matrix.shard }}/${{ matrix.shardTotal }}
98+
- name: Upload shard results
99+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
100+
if: ${{ !cancelled() }}
101+
with:
102+
name: blob-report-${{ matrix.os.name }}-shard-${{ matrix.shard }}
103+
path: blob-report
104+
retention-days: 1
105+
106+
merge-reports:
107+
# Merge reports after playwright-tests, even if some shards have failed
108+
if: ${{ !cancelled() }}
109+
needs: [test]
110+
111+
runs-on: ubuntu-latest
112+
steps:
113+
- uses: actions/checkout@v4
114+
- uses: actions/setup-node@v4
115+
with:
116+
node-version: lts/*
117+
- name: Install dependencies
118+
run: npm ci --no-audit --no-fund --progress=false
119+
120+
- name: Download blob reports from GitHub Actions Artifacts
121+
uses: actions/download-artifact@v4
122+
with:
123+
path: all-blob-reports
124+
pattern: blob-report-*
125+
merge-multiple: true
126+
127+
- name: Debug - List downloaded blob reports
128+
run: |
129+
echo "Contents of all-blob-reports directory:"
130+
ls -la all-blob-reports/
131+
echo "File sizes and details:"
132+
find all-blob-reports/ -type f -exec ls -lh {} \; || echo "No files found"
133+
134+
- name: Merge into HTML Report
135+
run: PLAYWRIGHT_HTML_OUTPUT_DIR=playwright-report npx playwright merge-reports --config=merge.config.ts ./all-blob-reports
136+
137+
- name: Debug - List playwright-report contents
138+
run: |
139+
echo "Contents of playwright-report directory:"
140+
ls -la playwright-report/ || echo "playwright-report directory does not exist"
141+
echo "Current directory contents:"
142+
ls -la
143+
144+
- name: Upload HTML report
145+
uses: actions/upload-artifact@v4
146+
with:
147+
name: html-report--attempt-${{ github.run_attempt }}
148+
path: playwright-report
149+
retention-days: 3

0 commit comments

Comments
 (0)