Development Guide

Prerequisites

Tool Version Notes
Node.js v20+ (v22 recommended)  
Go v1.22+ CGO must be enabled
C compiler any Required by CGO — gcc on Linux, Xcode CLT on macOS, MinGW on Windows
Trivy CLI optional For image vulnerability scanning in Security Hub

Install Trivy (macOS):

brew install trivy

Setup

# Install Node dependencies (also runs postinstall which rebuilds node-pty)
npm install

# Build the Go sidecar — required before first dev run
cd go-core && go build ./cmd/podscape-core/ && cd ..

Development

npm run dev          # Start Electron + Vite dev server with hot reload

Note: If window.kubectl.* methods appear as undefined at runtime, the preload build is stale. Restart npm run dev.


Running Tests

# Frontend (Vitest)
npm run test
npm run test:watch   # watch mode

# Go sidecar (handlers, rbac, helm, portforward, prometheus, ownerchain)
cd go-core && go test ./...

Building

The full build compiles the Go sidecar first, then runs electron-vite:

npm run build        # Go sidecar + renderer + main + preload

Individual steps:

cd go-core && go build ./cmd/podscape-core/   # sidecar binary only
cd go-core && go build ./cmd/podscape-mcp/    # MCP server binary only
npx electron-vite build                        # Electron assets only

Distribution

Packages are produced by electron-builder. Artifacts land in dist/.

npm run build:mac    # macOS — .dmg + .zip (arm64 and x64 separately)
npm run build:win    # Windows — NSIS installer (.exe)
npm run build:linux  # Linux — AppImage + .deb

Icon generation

Icons must be generated before packaging if they don’t already exist:

npm run icon:icns    # macOS .icns from resources/icon.png
npm run icon:ico     # Windows .ico from resources/icon.png

Requirements: imagemagick (Linux/macOS) or the scripts handle it via sips on macOS.


CI / Release

Releases are triggered by pushing a v* git tag. The workflow (.github/workflows/release.yml) runs three parallel jobs:

Job Runner Output
release-mac (arm64) macos-latest .dmg + .zip for Apple Silicon
release-mac (x64) macos-13 .dmg + .zip for Intel
release-win windows-latest .exe NSIS installer
release-linux ubuntu-latest .AppImage + .deb

Each job also uploads a checksums-<platform>.txt file to the GitHub release so users can verify downloads with SHA256.

# Create and push a release tag
git tag v2.3.0
git push origin v2.3.0

Required GitHub secret: GH_TOKEN with contents: write permission on the repository.


Settings Schema

App settings are stored in ~/.podscape/settings.json. The file is created automatically on first write. All fields are optional — missing keys fall back to the defaults shown below.

{
  "kubeconfigPath": "",
  "shellPath": "",
  "theme": "dark",
  "prodContexts": [],
  "prometheusUrls": {}
}
Field Type Default Description
kubeconfigPath string "" Absolute path to a kubeconfig file. Empty string means use $KUBECONFIG env var, then ~/.kube/config.
shellPath string "" Absolute path to the shell binary used for PTY terminals (e.g. /bin/zsh). Empty string means auto-detect from the user’s environment.
theme "dark" \| "light" \| "" "dark" UI colour theme. Empty string defers to the last-used or OS preference.
prodContexts string[] [] List of kubeconfig context names to treat as production. Any matching context activates the red border + banner in the UI.
prometheusUrls Record<string, string> {} Per-context manual Prometheus base URLs (e.g. { "my-ctx": "https://prometheus.example.com" }). Empty string for a context means auto-discover via Kubernetes service proxy.

The settings file is read and written by src/main/settings/settings_storage.ts (getSettings / saveSettings). IPC handlers in src/main/ipc/settings.ts expose settings:get and settings:set channels to the renderer via window.settings.


Auto-Updater

Podscape uses electron-updater to deliver in-app updates. The updater is configured in src/main/system/updater.ts and only activates in production builds (is.dev guard — no update checks during npm run dev).

Update source: electron-updater reads the publish configuration from package.json (GitHub releases). It fetches latest.yml / latest-mac.yml from the GitHub release assets to compare the current version against the latest published release.

Behaviour:

  • autoDownload is set to false — updates are downloaded only when the user explicitly confirms.
  • autoInstallOnAppQuit is true — a downloaded update is installed automatically the next time the app quits.
  • An initial check fires 5 seconds after launch (delayed to avoid racing with sidecar startup). The timer is cancelled on before-quit to prevent a network request into a partially torn-down process.
  • Events fired before the renderer window is ready are queued (up to 20) and flushed once did-finish-load fires, so no update notification is lost on a fast machine.

IPC channels:

Channel Direction Description
updater:check Renderer → Main (handle) Trigger an immediate update check
updater:download Renderer → Main (handle) Start downloading the available update
updater:install Renderer → Main (handle) Quit and install the downloaded update
updater:checking Main → Renderer (send) Update check started
updater:available Main → Renderer (send) New version found; payload is the UpdateInfo object
updater:not-available Main → Renderer (send) Already on the latest version
updater:progress Main → Renderer (send) Download progress; payload is a ProgressInfo object
updater:downloaded Main → Renderer (send) Download complete; payload is the UpdateDownloadedEvent object
updater:error Main → Renderer (send) Error during check or download; payload is the error message string

The UpdateBanner component in src/renderer/components/core/UpdateBanner.tsx listens for these events and renders an in-app notification bar when an update is available or has been downloaded.

Testing updates locally: electron-updater skips the update check entirely when is.dev is true, so local testing requires a production build. Point autoUpdater.updateConfigPath to a local dev-app-update.yml file or use autoUpdater.forceDevUpdateConfig = true with a matching release on a local file server.


Known Build Notes

  • node-pty native rebuild: npm install runs electron-builder install-app-deps via postinstall, which rebuilds node-pty for the target Electron version. On macOS the prebuilt spawn-helper binaries may lack execute permission — the postinstall script applies chmod +x automatically.
  • CGO on Windows: MinGW must be on PATH before building the Go sidecar. The CI workflow adds it via $env:PATH.
  • Sidecar location: In dev, the binary is expected at go-core/podscape-core. In production, electron-builder copies it to resources/bin/podscape-core via extraResources.

Copyright © 2026 Coding Protocols Private Limited. Distributed under the MIT license.