131 lines
4.7 KiB
Markdown
131 lines
4.7 KiB
Markdown
# AGENTS.md - Desktop App Guidelines
|
|
|
|
Thin Electrobun shell hosting the fullstack server app.
|
|
|
|
## Tech Stack
|
|
|
|
> **⚠️ This project uses Bun — NOT Node.js / npm. All commands use `bun`. Never use `npm`, `npx`, or `node`.**
|
|
|
|
- **Type**: Electrobun desktop application
|
|
- **Design**: Server-driven desktop (thin native shell hosting web app)
|
|
- **Runtime**: Bun (Main process) + CEF (Chromium Embedded Framework)
|
|
- **Framework**: Electrobun
|
|
- **Build**: Electrobun CLI + Turborepo
|
|
|
|
## Architecture
|
|
|
|
- **Server-driven design**: The desktop app is a "thin" native shell. It does not contain UI or business logic; it merely hosts the `apps/server` TanStack Start application in a native window.
|
|
- **Dev mode**: Connects to an external Vite dev server at `localhost:3000`. Requires `apps/server` to be running separately.
|
|
- **Prod mode**: Spawns an embedded TanStack Start server (Nitro) as a child process and loads the dynamically assigned local URL.
|
|
- **Config**: `electrobun.config.ts` manages app metadata (identifier, name), build entries, and asset bundling.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
# Development
|
|
bun dev # Start Electrobun dev mode (requires server dev running)
|
|
|
|
# Build
|
|
bun build # Build stable release (all platforms)
|
|
|
|
# Code Quality
|
|
bun fix # Biome auto-fix
|
|
bun typecheck # TypeScript check
|
|
```
|
|
|
|
## Directory Structure
|
|
|
|
```
|
|
.
|
|
├── src/
|
|
│ └── bun/
|
|
│ └── index.ts # Main process entry (Window management + server lifecycle)
|
|
├── electrobun.config.ts # App metadata and build/copy configuration
|
|
├── package.json # Scripts and dependencies
|
|
├── turbo.json # Build pipeline dependencies (depends on server build)
|
|
└── AGENTS.md # Desktop guidelines (this file)
|
|
```
|
|
|
|
## Development Workflow
|
|
|
|
1. **Start server**: In `apps/server`, run `bun dev`.
|
|
2. **Start desktop**: In `apps/desktop`, run `bun dev`.
|
|
3. **Connection**: The desktop app polls `localhost:3000` until responsive, then opens the native window.
|
|
|
|
## Production Architecture
|
|
|
|
### Build Pipeline
|
|
The desktop build is orchestrated by Turbo. It depends on the server's production build:
|
|
- `turbo.json`: `@furtherverse/desktop#build` depends on `@furtherverse/server#build`.
|
|
- `electrobun.config.ts`: Copies `../server/.output` to `server-output` folder within the app bundle.
|
|
|
|
### Server Lifecycle
|
|
In production, the main process manages the embedded server:
|
|
- **Spawn**: Spawns server from `server-output/server/index.mjs` using `Bun.spawn`.
|
|
- **Port Allocation**: Server is started with `PORT=0` and `HOST=127.0.0.1`.
|
|
- **Port Detection**: The main process parses the server's `stdout` using a regex to find the dynamically assigned port.
|
|
- **Lifecycle**: The server process is tied to the app; it is killed on `SIGTERM`, `SIGINT`, or app exit. If the server process crashes, the app exits with an error.
|
|
|
|
## Environment Detection
|
|
|
|
The application determines its environment via the `ELECTROBUN_BUILD_ENV` variable, automatically set by the Electrobun CLI:
|
|
|
|
```typescript
|
|
const isDev = () => {
|
|
const env = process.env.ELECTROBUN_BUILD_ENV
|
|
return !env || env === 'dev'
|
|
}
|
|
```
|
|
|
|
- **dev**: Development mode (connects to external host).
|
|
- **canary / stable**: Production mode (starts embedded server).
|
|
|
|
## Environment Variables
|
|
|
|
- `ELECTROBUN_BUILD_ENV`: Auto-set by CLI. Determines whether to use local dev server or embedded server.
|
|
- `DATABASE_URL`: Required by the server process. Must be passed through from the parent environment to the spawned child process.
|
|
|
|
## Electrobun Patterns
|
|
|
|
### BrowserWindow Configuration
|
|
The main window uses the CEF renderer for consistency across platforms.
|
|
|
|
```typescript
|
|
new BrowserWindow({
|
|
title: 'Furtherverse',
|
|
url: serverUrl,
|
|
frame: {
|
|
x: 100,
|
|
y: 100,
|
|
width: 1200,
|
|
height: 800,
|
|
},
|
|
renderer: 'cef',
|
|
})
|
|
```
|
|
|
|
### Path Aliases
|
|
The main process uses `electrobun/bun` for native APIs and `PATHS` for locating bundled assets.
|
|
|
|
```typescript
|
|
import { BrowserWindow, PATHS } from 'electrobun/bun'
|
|
|
|
// Locate the embedded server bundle
|
|
const serverEntryPath = join(PATHS.VIEWS_FOLDER, '..', 'server-output', 'server', 'index.mjs')
|
|
```
|
|
|
|
## Critical Rules
|
|
|
|
**DO:**
|
|
- Use arrow functions for all components and utility functions.
|
|
- Ensure `apps/server` is built before building `apps/desktop` (handled by Turbo).
|
|
- Parse the server's stdout for the port instead of hardcoding ports in production.
|
|
- Handle server process termination to avoid orphan processes.
|
|
- Use `catalog:` for all dependency versions in `package.json`.
|
|
|
|
**DON'T:**
|
|
- Use `npm`, `npx`, `node`, `yarn`, or `pnpm`. Always use `bun`.
|
|
- Hardcode `localhost:3000` for production builds.
|
|
- Include UI components or business logic in the desktop app (keep it thin).
|
|
- Use `as any` or `@ts-ignore`.
|