Skip to content

Repository files navigation

Pesk

Pesk

Pesk is an Electron and TypeScript application for working with Codex through a dedicated chat workspace, remote-machine investigation, configurable Windows workflows, and remote Codex session access.

Pesk Codex workspace reviewing a Windows release candidate Pesk thread-wide file change review Pesk human approval gate for a remote diagnostic command Pesk generated-image activity and project manager

Features

  • Animated desktop companion with customizable visual themes
  • Integrated Codex workspace for interactive development assistance
  • Remote-machine investigation through one or more embedded terminals, with human approval
  • Extensible configuration and external content support after installation
  • Productivity automation through configurable Windows application presets
  • Native Windows integration through the system tray, keyboard shortcuts, and login startup

Architecture

The architecture separates renderer windows from main-process services: a secure IPC bridge carries UI actions and state, while focused services own Codex communication, remote-machine terminal access, browser connectivity, and persisted user data.

Runtime topology

flowchart LR
  Desktop((Desktop))
  Browser((Browser))

  subgraph Windows[Desktop windows]
    Pet[[Pet]]
    Chat[[Codex chat]]
    Menu[[Pesk menu]]
  end

  subgraph Electron[Electron main process]
    direction TB
    Bridge{{Secure IPC bridge}}
    Services{{Application services}}
    Codex([Codex client])
    Web([Chat web server])
    Bridge <--> Services
    Services <--> Codex
    Services <--> Web
  end

  Storage[(User data)]
  AppServer[/Codex app-server/]
  Push[/Browser push service/]

  Desktop --> Pet
  Desktop --> Chat
  Desktop --> Menu
  Pet <-->|IPC| Bridge
  Chat <-->|IPC| Bridge
  Menu <-->|IPC| Bridge
  Codex <-->|JSON-RPC over WebSocket| AppServer
  Browser <-->|Chat WebSocket| Web
  Web -->|Push notification| Push
  Push -->|Browser delivery| Browser
  Services --> Storage

  classDef user fill:#ede9fe,stroke:#7c3aed,color:#2e1065
  classDef window fill:#dbeafe,stroke:#2563eb,color:#172554
  classDef process fill:#ffedd5,stroke:#ea580c,color:#431407
  classDef service fill:#dcfce7,stroke:#16a34a,color:#14532d
  classDef external fill:#f3f4f6,stroke:#6b7280,color:#111827
  classDef storage fill:#fef3c7,stroke:#d97706,color:#451a03
  class Desktop,Browser user
  class Pet,Chat,Menu window
  class Bridge,Services process
  class Codex,Web service
  class AppServer,Push external
  class Storage storage
Loading

Remote Machine Investigation Flow

sequenceDiagram
  actor User
  participant Pesk as Pesk main process
  participant Codex
  participant HostA as Remote host A
  participant HostB as Remote host B

  User->>Pesk: Diagnose why one production host missed a release while peer hosts completed deployment successfully
  Pesk->>Codex: Forward investigation request
  loop Repeat until the issue is understood
    Codex->>Pesk: Request next diagnostic step
    Pesk->>User: Ask for human command approval
    alt Approved
      User->>Pesk: Approve command
      Pesk->>HostA: Execute approved command
      Pesk->>HostB: Execute approved command
      HostA-->>Pesk: Return state and command output
      HostB-->>Pesk: Return state and command output
      Pesk->>Codex: Provide terminal output
    else Rejected
      User-->>Pesk: Reject command
      Pesk-->>Codex: Tool request rejected
    end
  end
  Codex->>Pesk: Explain result
  Pesk-->>User: Display result
Loading

Component ownership

Diagram component Ownership and responsibility
Desktop windows Electron-owned pet, Codex chat, and Pesk menu surfaces for desktop interaction.
Secure IPC bridge The preload boundary that safely carries window requests and main-process state updates.
Application services Main-process coordination for configuration, settings, animations, presets, window lifecycle, and cross-component behavior.
Codex client Main-process connection and state owner for JSON-RPC requests, threads, turns, streaming, approvals, and user-input requests.
Remote Terminal Per-thread bridge to one or more remote machines, with session-aware terminal access and approval-gated Codex tools.
Chat web server Main-process LAN server for pairing, authenticated browser chat, state broadcasts, and push notification requests.
User data Local persisted configuration, settings, device credentials, VAPID keys, subscriptions, and external content.
Codex app-server External service that receives and streams Codex JSON-RPC traffic.
Browser push service External browser-vendor delivery service used for Web Push notifications.

Requirements

  • Windows for the packaged application and monitor-placement presets
  • Node.js and npm for development and packaging

Development

npm install
npm start

Useful commands:

npm run build     # Compile main and renderer TypeScript
npm test          # Build and run Jest tests
npm run dist      # Build the Windows NSIS installer

Compiled runtime files are written to build/. The installer is written to dist/Pesk-Setup-<version>.exe.

To open detached DevTools for the pet, chat, and menu windows:

DESKTOP_PET_DEVTOOLS=1 npm start

Configuration

Pesk uses JSON configuration for application behavior and keeps user preferences in a separate settings file.

  • During development, the repository root config.json provides the default configuration.
  • Installed builds use %APPDATA%\pesk\config.json as the user override. The file is created or edited manually; it is intentionally not included in the installer.
  • User preferences such as the selected animation, visibility, pause state, and lock state are stored in %APPDATA%\pesk\settings.json.

When both configuration files exist, values in the user configuration override the bundled or development defaults. Restart Pesk after changing configuration.

Application configuration

Example application configuration:

{
  "fps": 24,
  "petSize": 180,
  "animationsDir": "animations",
  "codexAppServerProfiles": [{ "id": "default", "name": "Default", "url": "ws://127.0.0.1:4500" }],
  "activeCodexAppServerProfileId": "default",
  "features": {
    "remoteTerminal": {
      "enabled": true,
      "url": "http://127.0.0.1:5000/provider/ssh"
    }
  },
  "codexStatusSound": "audio.mp3",
  "webAccessEnabled": false,
  "webPort": 4587,
  "webTlsKey": "",
  "webTlsCert": ""
}

Configuration fields:

  • fps and petSize control default animation playback and rendering.
  • animationsDir selects the external animation directory. Relative paths are resolved beside the active configuration file.
  • codexAppServerProfiles defines named app-server profiles. activeCodexAppServerProfileId selects the startup profile. Both can also be managed from the Pesk Menu.
  • features.remoteTerminal.enabled enables remote-machine investigation through an embedded terminal and approval-gated Codex terminal tools.
  • features.remoteTerminal.url points to an rterm provider page such as http://127.0.0.1:5000/provider/ssh. rterm owns provider, target, user, terminal-session creation, credentials, and provider operations.
  • codexStatusSound specifies an optional sound file. Relative paths are resolved beside the active configuration file.
  • webAccessEnabled enables the browser-based chat endpoint. It is disabled by default.
  • webPort specifies the HTTP/WebSocket listening port. The default is 4587.
  • webTlsKey and webTlsCert optionally enable HTTPS/WSS for the web chat. Relative paths resolve beside the active configuration file; configure both together.
  • presets defines named Windows commands or URLs available from the Pesk menu. Each action may specify a command, args, and an optional one-based monitor.
  • animations provides per-animation overrides such as fps. Animation folders contain numbered PNG frames, for example:
<active-config-directory>\animations\dance\001.png

Remote-machine troubleshooting

Remote-terminal access from web chat is brokered by Pesk. Web clients do not connect to the rterm service directly; authenticated paired clients receive only a short-lived, device-scoped capability.

When remote-terminal support is enabled, Codex can use these approval-gated tools:

  • remote_terminal.sessions — list available terminal sessions.
  • remote_terminal.read — read recent terminal output.
  • remote_terminal.execute — run an approved command.
  • remote_terminal.upload — upload a workspace file after approval.
  • remote_terminal.download — download a remote file after approval.

Codex app-server

Start an authenticated app-server separately:

codex app-server --listen ws://127.0.0.1:4500

Configure one or more profiles in config.json or from the Pesk Menu:

{
  "codexAppServerProfiles": [
    { "id": "local", "name": "Local", "url": "ws://127.0.0.1:4500" },
    { "id": "remote", "name": "Remote", "url": "wss://codex.example.test/ws" }
  ],
  "activeCodexAppServerProfileId": "local"
}

URLs must use ws:// or wss://. The active profile can be switched from the Pesk Menu without restarting; Pesk reloads threads and projects from the selected server.

To confirm that a local server is listening before opening Pesk, request its readiness endpoint:

curl http://127.0.0.1:4500/readyz

Keep the app-server on loopback (127.0.0.1) unless you have separately secured the transport and understand the exposure. The WebSocket listener is documented by Codex as experimental.

Keyboard shortcuts

All shortcut definitions are centralized in src/renderer/shared/shortcuts.ts. Global shortcuts are fixed application behavior; they are not configuration options.

Global and window controls

Shortcut Action
Ctrl+Down Open the Pesk menu
Ctrl+Up Focus the pet, chat input, or pending question
Ctrl+Shift+L Lock or unlock chat auto-hide on blur
Escape Hide chat and unfocus the pet

Chat history and navigation

Shortcut Action
Ctrl+Left / Ctrl+Right Switch between Codex sessions
Ctrl+C / Cmd+C Copy the selected message
Alt+Home / Alt+End Scroll to the top or bottom
Alt+Up / Alt+Down Select the previous or next message
Alt+Shift+Up / Alt+Shift+Down Select the previous or next user message
Shift+Up / Shift+Down Scroll history by one step
Alt+Right Copy the selected message into the composer
Shift+Enter Expand or collapse the selected message

Chat composer

Shortcut Context Action
Enter Desktop composer Submit the prompt
Enter Web composer Insert a newline
Ctrl+Enter Composer Insert a newline
Alt+Enter Composer Steer the active Codex turn, or submit when idle
Ctrl+C Working composer Interrupt the active Codex turn
Up / Down Composer Recall the previous or next submitted prompt at a line boundary

Suggestions and question forms

Shortcut Context Action
Up / Down Suggestions Select the previous or next suggestion
Enter Suggestions Accept the selected suggestion
Escape Suggestions/review Dismiss suggestions or cancel the review form
Up / Down Question options Select the previous or next radio option
Tab Question options Move from an option to its note field
Tab Question note Return to the selected option
Enter Question/review fields Submit the current form

Pesk menu and pairing

Shortcut Context Action
Tab / Shift+Tab Pesk menu Move to the next or previous section
Up / Down Pesk menu Move between actions
Left / Right Pesk menu device row Move between row actions
Escape Pesk menu Close the menu
Enter Pairing field Generate a pairing QR code
Enter / Space Web connection status Reload and reconnect

In the menu’s Presets section, typing unmodified printable characters filters presets and Backspace removes the last filter character.

Presets

Presets define named actions available from the Pesk menu. An action runs a Windows command with optional arguments. URL arguments can be used with browser commands, and monitor specifies a one-based monitor number.

{
  "presets": [
    {
      "name": "Open documentation",
      "actions": [
        {
          "command": "msedge",
          "args": ["--new-window", "https://example.com/docs"]
        }
      ]
    },
    {
      "name": "Open dashboard on monitor 2",
      "actions": [
        {
          "command": "brave",
          "args": ["--new-window", "http://localhost:3000"],
          "monitor": 2
        }
      ]
    }
  ]
}

Packaged builds enable Windows login startup after the installed application is launched once.

Browser chat access

Expose only the Codex chat to a browser on the same trusted LAN.

Enable access

  1. Set webAccessEnabled to true.
  2. Restart Pesk.
  3. Open the Pesk Menu and choose Pair a device.
  4. Enter a unique device name and press Enter.
  5. Scan the displayed QR code with the other device’s camera.

The QR code is single-use and expires after five minutes. Each paired device receives its own credential; credentials are not stored in config.json.

HTTPS and network safety

The endpoint uses HTTP/WebSocket by default and has no internet relay. HTTPS/WSS is required for PWA installation and browser notifications on LAN devices. Configure both webTlsKey and webTlsCert to enable it.

Do not expose the endpoint through router port forwarding. Use a trusted LAN or a VPN for remote access.

Browser notifications

After pairing:

  1. Install the chat as a PWA from the browser’s install command, if desired.
  2. If the browser asks for permission, choose Allow.
  3. If the prompt does not appear, click Enable notifications in the chat.
  4. If notifications are blocked, allow them in the browser’s site settings and refresh the chat.

Web Push ready means that the browser subscription was successfully saved. The indicator is hidden when setup is valid. It does not guarantee that the phone’s operating-system notification settings will display the notification.

Pesk stores:

  • %APPDATA%\pesk\web-devices.json — paired devices and hashed credentials.
  • %APPDATA%\pesk\web-push-vapid.json — server VAPID keys.
  • %APPDATA%\pesk\web-push-subscriptions.json — browser subscriptions, one active subscription per paired device.

In the Pairing menu, Web Push setup status is separate from delivery control. Enable push/Disable push controls whether Pesk sends updates; it does not grant browser permission or remove the subscription. The web chat is network-only and does not cache the application shell for offline use.

Web Push uses the browser vendor’s delivery service (for example, FCM or APNs) as an outbound dependency. Pesk does not need a public inbound endpoint or a separate notification server. The browser must be able to reach its push service, and Pesk must be able to make outbound HTTPS requests.

To generate a self-signed certificate for local/LAN HTTPS, run the helper from a shell and include the computer’s LAN IP:

./scripts/generate-tls-cert.sh "$APPDATA/pesk/tls" 192.168.1.23

Replace 192.168.1.23 with the computer’s actual LAN IP. The script prints the webTlsKey and webTlsCert entries to add to the active configuration.

Repository Layout

  • src/ — Electron main process, controllers, preload bridge, and renderer modules
  • src/renderer/ — separate pet, chat, and menu pages
  • assets/ — application icon and tray artwork
  • tests/ — Jest tests
  • scripts/ — build cleanup, renderer asset-copy, and TLS certificate helpers

About

A floating Windows desktop pet that helps with Codex, productivity, and other activities that may or may not need improving.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages