# HyperDesk

`HyperDesk` is an Electron desktop harness for running Pi agent sessions alongside a visible browser workspace.

The UI is written in Gleam/Lustre and runs in an Electron overlay. The main Electron process hosts:

- a persistent embedded browser view
- a Gleam/Lustre chat/session UI
- Pi SDK agent sessions
- approval-gated local and browser tools
- optional Chrome DevTools integration for controlling a visible Chrome window
- project Pi package extensions, including ZenBin publishing workflows

## Current capabilities

- Manage multiple Pi chat sessions from the left rail.
- Stream assistant responses into the Gleam/Lustre UI.
- Show Pi tool activity and pending approvals.
- Approve or reject browser, Chrome, shell, and file-write actions.
- Launch or connect to Chrome with remote debugging enabled.
- Navigate, inspect, click, fill, scroll, and submit forms in the embedded browser or Chrome through Pi tools.
- Render assistant Markdown safely through `marked` + `DOMPurify`.
- Open Pi login/model setup from the bundled home page.

## Project layout

```text
src/hyper_desk.gleam          Gleam/Lustre app state, update loop, and views
src/hyper_desk/*.gleam        Gleam wrappers for browser, Pi, Markdown, and URL FFI
src/hyper_desk/*.ffi.mjs      JavaScript FFI called by compiled Gleam
electron/main.cjs          Electron window, embedded browser, IPC, browser tools
electron/pi-adapter.cjs    Pi SDK session management and custom tools
electron/chrome-adapter.cjs Chrome DevTools Protocol integration
electron/preload.cjs       Safe IPC bridge exposed to the UI renderer
renderer/main.js           Renderer bootstrap and DOM helpers
renderer/*.css             UI styling
browser-home/hyper-desk.html  Trusted bundled browser home/setup page
test/hyper_desk_test.gleam    Gleam tests
```


## Install from npm

Run without installing globally:

```sh
npx hyperdesk
```

Or install the command globally:

```sh
npm install -g hyperdesk
hyperdesk
```

When launched from npm, HyperDesk uses the directory where you ran `hyperdesk` as the default workspace. New sessions start in `.` unless you choose another folder.

## Development

Install dependencies:

```sh
npm install
```

Run the app in development:

```sh
npm run dev
```

This command:

1. compiles Gleam to JavaScript,
2. starts Vite on `127.0.0.1:5173`,
3. opens the Electron shell.

## Build and checks

Build Gleam only:

```sh
npm run gleam:build
```

Build the production renderer bundle:

```sh
npm run build
```

Run Gleam tests:

```sh
gleam test
```

Start Electron after building:

```sh
npm start
```

## Pi setup

`HyperDesk` uses the installed `@earendil-works/pi-coding-agent` SDK and reads Pi auth/model configuration from the normal Pi agent directory.

By default, HyperDesk runs in standalone mode: global/project Pi package, extension, prompt, theme, and skill settings are not loaded into the desktop session. This keeps basic chat and browser work from requiring a system `npm` install. If you want external Pi packages such as `pi-subagents` or `pi-zenbin`, enable **Session → Enable External Pi Packages**. In that mode HyperDesk uses Pi's package manager and `npm` must be available on PATH.

If no model is available, run Pi login from a terminal:

```sh
pi /login
```

Then return to `HyperDesk` and refresh/configure models.


### Restoring the app HTML shell

The HyperDesk app shell lives at `index.html`. A known-good backup is kept at `backups/index.html.backup`. If the app window unexpectedly shows another page, or `index.html` appears to have been overwritten, restore it with:

```sh
cp backups/index.html.backup index.html
npm run build
```

Normal production/local launches should load `dist/index.html`; dev launches use Vite only through `npm run dev`.

## Tool and approval model

Pi sessions are created with read-only project tools plus custom tools for browser, Chrome, local shell, and file writing.

Read-only tools include:

- `read`
- `grep`
- `find`
- `ls`
- browser/Chrome snapshot tools
- `zenbin_identity` from the `pi-zenbin` extension

Actions that can affect local state or visible browser state request approval, including:

- file writes
- shell commands
- browser clicks/fills/scrolls/key presses/form submits
- Chrome navigation/clicks/fills/scrolls/key presses
- ZenBin identity creation/regeneration

The UI also has “approve all” buttons for browser actions and local write/bash actions. Treat these as powerful trust decisions.

## Security notes

This project intentionally gives a Pi agent access to local project files and browser automation. Be careful when using it with untrusted prompts or websites.

Important areas to keep tight:

- Do not allow arbitrary `file://` navigation except the trusted bundled home page.
- Keep browser and local-effect approvals scoped as narrowly as possible.
- Consider blocking `web_fetch_text` access to localhost, private IP ranges, and metadata endpoints.
- Be aware that file writes should guard against symlink escapes as well as `../` path escapes.
- Keep Electron renderer settings locked down: `contextIsolation: true`, `nodeIntegration: false`, and `sandbox: true`.

## Known gaps / TODO

- The README was updated to describe the current architecture, but tests are still minimal.
- Add tests for URL normalization, approval scoping, and project-path safety.
- Review whether the browser address bar/navigation UI should be restored or dead navigation state removed.
- Scope “approve all” behavior per session/thread rather than globally.
- Harden browser navigation and web fetching against local/private resource access.
