Atlas / Skills / wavetermdev / Electron Api

Electron ApiSAFE

skills/wavetermdev/electron-api

An open-source, AI-integrated, cross-platform terminal for seamless workflows

Verdict
SAFE
Grade
B
Trust score
89 /100
Version
—
Hosts
—
License
Apache-2.0
Stars
22,418
01

Overview

An open-source, AI-integrated, cross-platform terminal for seamless workflows

Read from source at commit 63907843412fOBSERVED · 2026-10-05
02

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: electron-api
description: Guide for adding new Electron APIs to Wave Terminal. Use when implementing new frontend-to-electron communications via preload/IPC.
---

# Adding Electron APIs

Electron APIs allow the frontend to call Electron main process functionality directly via IPC.

## Four Files to Edit

1. [`frontend/types/custom.d.ts`](frontend/types/custom.d.ts) - TypeScript [`ElectronApi`](frontend/types/custom.d.ts:82) type
2. [`emain/preload.ts`](emain/preload.ts) - Expose method via `contextBridge`
3. [`emain/emain-ipc.ts`](emain/emain-ipc.ts) - Implement IPC handler
4. [`frontend/preview/preview-electron-api.ts`](frontend/preview/preview-electron-api.ts) - Add a no-op stub to keep the `previewElectronApi` object in sync with the `ElectronApi` type

## Three Communication Patterns

1. **Sync** - `ipcRenderer.sendSync()` + `ipcMain.on()` + `event.returnValue = ...`
2. **Async** - `ipcRenderer.invoke()` + `ipcMain.handle()`
3. **Fire-and-forget** - `ipcRenderer.send()` + `ipcMain.on()`

## Example: Async Method

### 1. Define TypeScript Interface

In [`frontend/types/custom.d.ts`](frontend/types/custom.d.ts):

```typescript
type ElectronApi = {
    captureScreenshot: (rect: Electron.Rectangle) => Promise<string>; // capture-screenshot
};
```

### 2. Expose in Preload

In [`emain/preload.ts`](emain/preload.ts):

```typescript
contextBridge.exposeInMainWorld("api", {
    captureScreenshot: (rect: Rectangle) => ipcRenderer.invoke("capture-screenshot", rect),
});
```

### 3. Implement Handler

In [`emain/emain-ipc.ts`](emain/emain-ipc.ts):

```typescript
electron.ipcMain.handle("capture-screenshot", async (event, rect) => {
    const tabView = getWaveTabViewByWebContentsId(event.sender.id);
    if (!tabView) throw new Error("No tab view found");
    const image = await tabView.webContents.capturePage(rect);
    return `data:image/png;base64,${image.toPNG().toString("base64")}`;
});
```

### 4. Add Preview Stub

In [`frontend/preview/preview-electron-api.ts`](frontend/preview/preview-electron-api.ts):

```typescript
captureScreenshot: (_rect: Electron.Rectangle) => Promise.resolve(""),
```

### 5. Call from Frontend

```typescript
import { getApi } from "@/store/global";

const dataUrl = await getApi().captureScreenshot({ x: 0, y: 0, width: 800, height: 600 });
```

## Example: Sync Method

### 1. Define

```typescript
type ElectronApi = {
    getUserName: () => string; // get-user-name
};
```

### 2. Preload

```typescript
getUserName: () => ipcRenderer.sendSync("get-user-name"),
```

### 3. Handler (⚠️ MUST set event.returnValue or browser hangs)

```typescript
electron.ipcMain.on("get-user-name", (event) => {
    event.returnValue = process.env.USER || "unknown";
});
```

### 4. Call

```typescript
import { getApi } from "@/store/global";

const userName = getApi().getUserName(); // blocks until returns
```

## Example: Fire-and-Forget

### 1. Define

```typescript
type ElectronApi = {
    openExternal: (url: string) => void; // open-external
};
```

### 2. Preload

```typescript
openExternal: (url) => ipcRenderer.send("open-external", url),
```

### 3. Handler

```typescript
electron.ipcMain.on("open-external", (event, url) => {
    electron.shell.openExternal(url);
});
```

## Example: Event Listener

### 1. Define

```typescript
type ElectronApi = {
    onZoomFactorChange: (callback: (zoomFactor: number) => void) => void; // zoom-factor-change
};
```

### 2. Preload

```typescript
onZoomFactorChange: (callback) => 
    ipcRenderer.on("zoom-factor-change", (_event, zoomFactor) => callback(zoomFactor)),
```

### 3. Send from Main

```typescript
webContents.send("zoom-factor-change", newZoomFactor);
```

## Quick Reference

**Use Sync when:**
- Getting config/env vars
- Quick lookups, no I/O
- ⚠️ **CRITICAL**: Always set `event.returnValue` or browser hangs

**Use Async when:**
- File operations
- Network requests
- Can fail or take time

**Use Fire-and-forget when:**
- No return value needed
- Triggering actions

**Electron API vs RPC:**
- Electron API: Native OS features, window management, Electron APIs
- RPC: Database, backend logic, remote servers

## Checklist

- [ ] Add to [`ElectronApi`](frontend/types/custom.d.ts:82) in [`custom.d.ts`](frontend/types/custom.d.ts)
- [ ] Include IPC channel name in comment
- [ ] Expose in [`preload.ts`](emain/preload.ts)
- [ ] Implement in [`emain-ipc.ts`](emain/emain-ipc.ts)
- [ ] Add no-op stub to [`preview-electron-api.ts`](frontend/preview/preview-electron-api.ts)
- [ ] IPC channel names match exactly
- [ ] **For sync**: Set `event.returnValue` (or browser hangs!)
- [ ] Test end-to-end
03

Trust audit

SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeNA
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
none-observed
Shell
none-observed
Dependencies
pinned
Secrets in source
none-found

Findings (0)

No findings outside the package's declared scope.

Gates applied: no_behavioural_pass.

Audited 2026-10-05 · audit v0.4.1 · source sha 63907843412ffull audit observations/trust-audit/skill/wavetermdev__electron-api.json · Report an issue / request a re-scan
04

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-0563907843412fSAFEB89first audit
05

Questions

What does the Electron Api skill do?

An open-source, AI-integrated, cross-platform terminal for seamless workflows

Is Electron Api safe to install?

The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.

What can Electron Api access on my machine?

The audit observed no filesystem, network or shell use at all in its source.

How current is this page?

The grade is for one exact copy of the source (63907843412f), read on 2026-10-05. The repository is watched, and a new audit runs when it changes — this is the first audit.

Advertisement