Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
27ca45f
Add GitHub Pages deployment workflow and set base path
Feb 22, 2026
9dc994a
Switch Pages deploy to gh-pages branch strategy
Feb 22, 2026
0af4a26
Fix base path for enterprise GitHub Pages deployment
Feb 22, 2026
0359278
Fix deploy script to use npm install instead of npm ci
Feb 22, 2026
8aeff16
Fix deploy script: use --legacy-peer-deps for npm compatibility
Feb 22, 2026
4112ce2
Enable axis by default, move x-axis to top, and add simulation error …
Feb 23, 2026
5fe9aae
Update package-lock.json dependencies
Feb 23, 2026
5fab1b1
Update default Python example with rotation and ngspice
Feb 23, 2026
cf67aa9
Update analogpy to 0.2.2 and sync SVG visualization style
Feb 23, 2026
c22490a
Deploy 0.2.2 with optimized loading and SVG alignment
Feb 23, 2026
b82ff2f
Fix deploy.py to protect node_modules and optimize Pyodide loading
Feb 23, 2026
44e98ff
Enhance UI: reduce plot height, add CSV preview, and improve error lo…
Feb 23, 2026
1030928
Implement waveform cursors A/B with intersection markers and delta di…
Feb 23, 2026
1768bf1
Fix CSP image errors, improve plot stability, and patch deploy script
Feb 23, 2026
913e56b
Switch to local Pyodide hosting to bypass enterprise CSP
Feb 23, 2026
5526e05
Fix Vite build by using dynamic path for local Pyodide import
Feb 23, 2026
4667978
Optimize deploy script: remove redundant npm install and protect loca…
Feb 23, 2026
ec6726a
Fix Pyodide path: use hardcoded base URL to bypass redirection errors
Feb 23, 2026
435c3f5
Completely secure deploy script using git worktrees to protect local …
Feb 23, 2026
722caaa
Revert Pyodide to stable CDN loading for reliable local development
Feb 23, 2026
eb3f8b4
Switch deployment script to use enterprise remote exclusively
Feb 23, 2026
420a9d9
Final synchronization across all remotes
Feb 23, 2026
9368c9e
Fix plot marker scaling and simplify remote switch script
Feb 24, 2026
b02a290
Add fullscreen support for plot and analysis tabs
Feb 24, 2026
5da9cf8
Handle canvas resize in fullscreen to prevent stretching
Feb 24, 2026
860f305
Add AI chat tab with OpenAI/Anthropic/Google support
Feb 24, 2026
feebe16
Redesign layout: flex height, legend overlay, 60:40 split, minimize b…
Feb 25, 2026
05f1bdf
Fix plot height, in-page expand mode, remove schematic tab, fix schem…
Feb 25, 2026
69fa1a7
Disable minimize button, clean up minimize logic
Feb 25, 2026
46300cb
Fix plot height (40vh), expand mode, schematic zoom panel
Feb 25, 2026
e1d87f8
50/50 editor/schematic split, reduce AI chat height
Feb 25, 2026
43235c0
55/45 editor/schematic split, 45vh plot height
Feb 25, 2026
f6faf01
Fix plot height: canvas uses 100% inside heightProp box, axis gets he…
Feb 25, 2026
2108661
Expand plot box by axis row height to prevent waveform clipping
Feb 25, 2026
836a824
Fix white gap: body flex column 100vh, #root flex:1, remove body margin
Feb 25, 2026
8e356b2
Revert plotArray to original canvas height approach (canvasStyle = he…
Feb 25, 2026
c8b3ee2
Fix Select All/None: use dedicated callbacks for single state update
Feb 25, 2026
f3c198c
Fix AI example answer: i(l) is saved by default, no .save needed
Feb 25, 2026
d3e05ae
Fix inductor current example with actual simulation data (231mA peak)
Feb 25, 2026
c41dec5
Fix inductor current answer with real CMOS90 simulation data (195mA p…
Feb 25, 2026
de15793
Fix maximize mode: keep plot at 40vh always
Feb 25, 2026
94bbaf3
Plot height: 80vh in maximize mode, 40vh normal
Feb 25, 2026
dfb2de1
Plot height: 70vh in maximize mode
Feb 25, 2026
f44505e
Add Y-axis zoom with Shift+scroll, X-axis zoom with normal scroll
Feb 25, 2026
482ab10
Fix Y-axis zoom: handle macOS Shift+scroll deltaX/deltaY swap
Feb 25, 2026
26f466e
Cap AI chat height to 40vh to match plot, show send button
Feb 25, 2026
6859747
AI chat height: 95% of parent, revert chat history limits
Feb 25, 2026
a68db26
Clamp schematic zoom minimum to 100%
Feb 25, 2026
dd98bce
Revert zoom- clamp, keep full zoom range for future
Feb 25, 2026
45034ca
Update pythonDefault with schematic positioning and draw_wires
Feb 25, 2026
bb74fce
AI chat height 90%
Feb 25, 2026
3f46168
AI chat: use 40vh fixed height matching plot, 25vh chat history max
Feb 25, 2026
49954be
AI chat: 45vh normal, 70vh maximized; history 30vh/55vh
Feb 25, 2026
bddc5df
Rewrite all example Q&A with simulation-verified data
Feb 25, 2026
c66642a
Add API key privacy reminder in AI chat settings bar
Feb 25, 2026
03d33c9
Rebrand website to analogpy and update GitHub link
Feb 25, 2026
8972be8
Update download filename and test expectations to analogpy
Feb 25, 2026
6fbbaae
Update branding text with AI integration and PDK security details
Feb 25, 2026
223b4b7
Update branding to 'leveraging the foundations of EEcircuit'
Feb 25, 2026
866bc0c
Merge branding and controls into a single top header row to save vert…
Feb 25, 2026
e71410d
Shift Clear button left to avoid GitHub corner overlap
Feb 25, 2026
e76016d
Update AI models and add logo assets
Feb 25, 2026
78bfecb
Increase editor height to 40vh and shift fullscreen button left
Feb 25, 2026
bf661cc
Add manual Day/Night mode toggle button to header
Feb 25, 2026
d1c846d
Change logo from jpg to png
Feb 25, 2026
72de55f
Simplify analogpy header tagline
Feb 25, 2026
269a8d0
Improve branding header with monospaced pip install and hierarchical …
Feb 25, 2026
6f19c83
change .gitignore
circuitmuggle Feb 27, 2026
aa225a0
switch_git_remote.py to .gitignore
circuitmuggle Feb 27, 2026
aca5d8e
Fix Vite base path for Vercel deployment
circuitmuggle Feb 27, 2026
900ae1c
fix: improve fullscreen plot layout and button UX
circuitmuggle Feb 27, 2026
01f38a2
feat: grid overlay, fullscreen remount fix, legend close button, UX i…
circuitmuggle Feb 27, 2026
2e9091c
feat: plot UX improvements — shortcuts popup, cursor labels, legend m…
circuitmuggle Feb 27, 2026
17d6748
feat: cursor persistence across fullscreen, 3rd cursor M, UX improvem…
circuitmuggle Feb 27, 2026
d01cc1e
feat: click-to-select curves/cursors, color-matched status, UX polish
circuitmuggle Feb 27, 2026
c026626
fix: bump analogpy to 0.2.3 (adds relative_via support)
circuitmuggle Feb 27, 2026
ec96ea6
fix: remove hardcoded analogpy version, always install latest from PyPI
circuitmuggle Feb 27, 2026
8736638
feat: rework mouse controls — left drag pan, right drag zoom, better …
circuitmuggle Feb 28, 2026
a131c87
fix: use --legacy-peer-deps in CI to resolve eslint peer conflict
circuitmuggle Mar 1, 2026
4847cc1
fix: apply --legacy-peer-deps to remaining CI workflow files
circuitmuggle Mar 1, 2026
ff59c32
fix: increase Node.js heap to 4GB in CI to fix OOM during build
circuitmuggle Mar 1, 2026
03eed30
fix: pass --max-old-space-size=4096 directly to node in build script
circuitmuggle Mar 1, 2026
596a063
chore: remove deploy-pages workflow (using Vercel instead of GitHub P…
circuitmuggle Mar 1, 2026
66326b9
chore: remove build-push-main workflow (was testing upstream eelab-de…
circuitmuggle Mar 1, 2026
2052cb4
chore: remove build-push-next workflow (upstream eelab-dev artifact, …
circuitmuggle Mar 1, 2026
f54da9a
fix: curve selection — skip isPoints and unnamed lines, use screen-pi…
circuitmuggle Mar 1, 2026
3ac3c08
feat: evenly-spaced HSL hues for curve colors, replace random RGB
circuitmuggle Mar 1, 2026
9bb1c6d
feat: per-curve color picker — replace rainbow button with palette ed…
circuitmuggle Mar 1, 2026
5bccc86
feat: wider legend, visible editor/schematic expand buttons in toolbar
circuitmuggle Mar 1, 2026
2faa231
fix: revert legend width, add editor wide button, color editor expand…
circuitmuggle Mar 1, 2026
7aed5c2
feat: restore Max/Collapse buttons for editor and schematic
circuitmuggle Mar 1, 2026
5f82f50
feat: color swatch in legend is now clickable color picker, swap edit…
circuitmuggle Mar 1, 2026
b4aba9e
fix: always use fresh HSL colors on simulation run, preserve visibili…
circuitmuggle Mar 1, 2026
b8d66cc
Explicit generate_ngspice/spectre calls; stdout in Info tab
circuitmuggle Mar 2, 2026
4d9998a
Fix RecursionError: drop function patching, keep stdout capture
circuitmuggle Mar 2, 2026
2999a12
Show representative ngspice command in Info tab
circuitmuggle Mar 2, 2026
40bc57c
Update default Python example to use add_net/add_gnd/inst vars
circuitmuggle Mar 2, 2026
55f8459
Fix Info tab ngspice command: remove -b flag
circuitmuggle Mar 2, 2026
df18438
Improve run feedback: success toast, auto-switch tabs, clear error di…
circuitmuggle Mar 2, 2026
60c3c20
update: new default Python example with relative_via schematic positions
circuitmuggle Mar 2, 2026
1335c42
update: add DC() to default Python example, import DC from analogpy
circuitmuggle Mar 2, 2026
426f6fd
Update default Python example to user's RLC circuit with DC+Transient
circuitmuggle Mar 3, 2026
9f9976a
update webiste logo
circuitmuggle Mar 3, 2026
3cd824c
Include EEcircuit branding in the new consolidated top toolbar for le…
Feb 25, 2026
e815c2f
Restore EEcircuit branding in README, add new features description
circuitmuggle Mar 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 0 additions & 43 deletions .github/workflows/build-push-main.yml

This file was deleted.

76 changes: 0 additions & 76 deletions .github/workflows/build-push-next.yml

This file was deleted.

4 changes: 3 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ jobs:
node-version: "20"

- name: Install npm packages
run: npm install
run: npm install --legacy-peer-deps

- name: Build
run: npm run build
env:
NODE_OPTIONS: "--max-old-space-size=4096"
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,8 @@ tests/repos
test-results
playwright-report
.DS_Store
deploy_github_npm.py
switch_git_remote.py
TODO_filesystem.md
TODO_AI.md
TODO_spectre_PDK.md
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

# EEcircuit

EEcircuit is a circuit simulator based on [ngspice](https://sourceforge.net/p/ngspice/ngspice/) that operates directly in your browser using [WebAssembly](https://webassembly.org/) technology. It takes a spice-based netlist as input and produces analysis results from your simulations as output. You can visualize and plot the results in the browser using the high-performance WebGL plotting library, [webgl-plot](https://github.com/danchitnis/webgl-plot), or download the data in CSV format for further analysis. Importantly, your netlist and results are processed locally, meaning they always remain within your browser and are never uploaded to a server. This project focuses on facilitating rapid analysis and sharing of circuit ideas and results within the [VLSI](https://en.wikipedia.org/wiki/Very_Large_Scale_Integration) and chip-design communities. Additionally, since EEcircuit uses a text-based netlist as input, you can utilize [Git](https://git-scm.com/) for version control to track your changes effectively.
EEcircuit is a circuit simulator based on ngspice that operates directly in your browser using WebAssembly technology. It takes a spice-based netlist as input and produces analysis results from your simulations as output. You can visualize and plot the results in the browser using the high-performance WebGL plotting library, **webgl-plot**, or download the data in CSV format for further analysis. Importantly, your netlist and results are processed locally, meaning they always remain within your browser and are never uploaded to a server. This project focuses on facilitating rapid analysis and sharing of circuit ideas and results within the VLSI and chip-design communities. Additionally, since EEcircuit uses a text-based netlist as input, you can utilize Git for version control to track your changes effectively.

### What's new

The plot viewer has been significantly enhanced with an advanced interactive experience: three independent measurement cursors (**A**, **B**, **M**) can be placed on any curve via keyboard shortcuts, with delta readouts in the legend. Each curve now has a **per-curve color picker** accessible directly from the legend. Zoom and pan have been reworked — scroll to zoom the X axis, Shift+Scroll for the Y axis, right-click drag for rectangle zoom, and middle-click drag to pan. A full keyboard shortcut system covers cursor placement, view fit, zoom steps, and item deletion. The platform also demonstrates AI-assisted circuit design and debugging through integration with **Anthropic Claude**, **Google Gemini**, and **OpenAI GPT**.

## Getting started

Expand Down Expand Up @@ -34,7 +38,26 @@ vin 1 0 0 pulse (0 1.8 0 0.1 0.1 15 30)

## Usage

Use your mouse to pan & zoom on the plot. left click for area **zoom** and right click hold and drag for **pan**. To reset the view **double click**.
### Plot controls

| Action | Result |
|--------|--------|
| **Scroll** | Zoom X axis |
| **Shift + Scroll** | Zoom Y axis |
| **Right-click drag** | Zoom in on X axis (rectangle select) |
| **Middle-click drag** | Pan X + Y |
| **Left-click** | Select curve or cursor marker |

### Keyboard shortcuts

| Key | Action |
|-----|--------|
| `a` / `b` / `m` | Place cursor A / B / M on nearest curve |
| `c` | Clear all cursors |
| `f` | Fit view (reset zoom) |
| `[` / `]` | Zoom out / zoom in (X axis) |
| `Delete` | Remove selected curve or cursor |
| `Esc` | Deselect |

## Documentation

Expand Down
194 changes: 194 additions & 0 deletions TODO_AI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# TODO: AI Chat Backend Proxy

## Goal

Allow public EEcircuit users to ask 3 AI-powered circuit questions per 24 hours
without needing their own API key. Rate limiting is enforced server-side.

## Architecture

```
EEcircuit website (GitHub Pages, static)
↓ POST /api/chat (no user key required)
Vercel Edge Function (eecircuit-api.vercel.app)
↓ check rate limit → Vercel KV (Redis)
↓ forward to OpenAI with secret key
← AI response
EEcircuit website
```

## Rate Limiting

- **3 requests per user per 24 hours** (rolling window)
- Identity: IP address + browser fingerprint (localStorage UUID + user agent hash)
- MAC address is NOT accessible from a browser (network layer only)
- Storage: Vercel KV (free tier: 30MB, sufficient for millions of rate limit entries)
- After 3 requests: show message "Free quota used. Provide your own API key to continue,
or try again in 24 hours."

## Why Not Expose the Key in the Frontend?

Any API key embedded in browser JS is visible in DevTools / network tab / page source.
Anyone can extract it and make unlimited calls. The proxy keeps the key server-side
as a Vercel environment variable, never sent to the browser.

## Selected Models (OpenAI only for the free tier)

| Model | Use case |
|---|---|
| `gpt-5.2` | Default — latest, best reasoning |
| `gpt-5.2-pro` | Premium option for users with own key |
| `gpt-4o` | Fallback — reliable, lower cost |

## Implementation Steps

### 1. New Vercel project: `eecircuit-api`

Small project (~20 lines), separate from EEcircuit website repo.

**File: `api/chat.ts`** (Vercel Edge Function)
```typescript
import { kv } from "@vercel/kv";

export const config = { runtime: "edge" };

const FREE_QUOTA = 3;
const WINDOW_MS = 24 * 60 * 60 * 1000; // 24 hours

export default async function handler(req: Request) {
// CORS headers
if (req.method === "OPTIONS") {
return new Response(null, {
headers: {
"Access-Control-Allow-Origin": "https://gaofeng-fan.github.io",
"Access-Control-Allow-Methods": "POST",
"Access-Control-Allow-Headers": "Content-Type",
},
});
}

// Rate limit check
const ip = req.headers.get("x-forwarded-for") ?? "unknown";
const body = await req.json();
const fingerprint = body.fingerprint ?? "";
const key = `rl:${ip}:${fingerprint}`;

// User providing their own key bypasses rate limit
const userKey = body.userApiKey;
const apiKey = userKey || process.env.OPENAI_API_KEY!;

if (!userKey) {
const count = (await kv.get<number>(key)) ?? 0;
if (count >= FREE_QUOTA) {
return Response.json(
{ error: "Free quota (3/day) exceeded. Provide your own OpenAI API key to continue." },
{ status: 429 }
);
}
await kv.set(key, count + 1, { px: WINDOW_MS });
}

// Forward to OpenAI
const openaiRes = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
body: JSON.stringify({
model: body.model ?? "gpt-5.2",
messages: body.messages,
max_tokens: 1024,
}),
});

const data = await openaiRes.json();
return Response.json(data, {
headers: { "Access-Control-Allow-Origin": "https://gaofeng-fan.github.io" },
});
}
```

### 2. Vercel setup

1. Create new repo `eecircuit-api`, push to GitHub
2. Import into Vercel dashboard
3. Add env var: `OPENAI_API_KEY=sk-...`
4. Add Vercel KV store (Storage tab → KV → Create)
5. Deploy → get URL: `https://eecircuit-api.vercel.app`

### 3. EEcircuit frontend changes

In `src/ai/aiClient.ts`:
- Default endpoint: `https://eecircuit-api.vercel.app/api/chat`
- If user provides own key: call OpenAI directly (bypass proxy)
- Send `fingerprint` field: `localStorage.getItem("userId") || crypto.randomUUID()`
(generate once, persist in localStorage)

In `src/ai/AiChat.tsx`:
- Show remaining free quota: "2 free questions remaining today"
- Show input for own API key (optional, for power users)
- After quota exhausted: show "Provide your own key or wait 24h" message

## Cost Estimate

- gpt-5.2: ~$5/MTok input, ~$20/MTok output
- Per question: ~2000 tokens context + ~500 output ≈ $0.015
- 3 questions/user/day @ 100 users/day = 300 questions = $4.50/day
- Scale to 1000 users/day = $45/day — monitor and add stricter limits if needed

## Notes

- Keep "bring your own key" option in the UI — useful for power users and testing
- The proxy only supports OpenAI for the free tier (simpler, single key to manage)
- Anthropic and Google remain available for users with their own keys
- Add CORS restriction to only allow requests from the EEcircuit GitHub Pages domain

---

## Monetization

The AI feature has two natural revenue angles:

### 1. AI question credits (pay-per-use)

Beyond the 3 free questions/day, sell credit packs:

| Tier | Price | Credits |
|---|---|---|
| Free | $0 | 3/day |
| Starter | $5 | 100 credits |
| Pro | $20 | 500 credits |
| Unlimited | $15/month | Unlimited |

Each "credit" = one AI question. Implementation: Stripe one-time payment or
subscription → store credit balance in Vercel KV keyed by user ID.

### 2. Domain-specific analog AI (premium model)

Fine-tune or prompt-engineer a model specifically for analog circuit design:
- Trained on SPICE netlists, analog design textbooks, application notes
- Understands analogpy syntax natively
- Can suggest component values, explain simulation results, debug convergence

Charge a premium for this specialized model vs. the generic GPT/Claude free tier.
Users who pay get routed to the fine-tuned model; free tier uses the standard model.

### 3. AI-assisted PDK-aware design (long-term)

Combine with the Spectre/PDK cloud compute (see TODO_spectre_PDK.md):
- AI suggests sizing for a specific process node (e.g. TSMC N28)
- Automatically generates a simulation-ready netlist
- Runs the simulation on cloud backend
- Returns results with AI interpretation

This closes the loop: design → simulate → explain, all in one session.
Bundle pricing: AI credits + simulation credits in one subscription.

### Implementation path

1. Add user accounts (Auth0 or Clerk) — prerequisite for all paid tiers
2. Integrate Stripe for credit purchases
3. Store credit balance in Vercel KV
4. Route free vs. paid users to different model endpoints
5. Dashboard: show remaining credits, purchase history
Loading