Skip to content

klim browser

klim browser launches a small local HTTP server and opens the klim UI in your default browser. The web view is a thin frontend over the same service layer the TUI and other CLI commands use; every page renders from a real PATH scan and version resolution, no separate data store.

klim browser local web view showing the For You page with tool cards and match scores

Terminal window
klim browser [flags]

By default the server picks a free port, binds to 127.0.0.1, and opens the resulting URL in your default browser. The URL is also printed to stderr so you can copy-paste it manually if auto-open fails.

$ klim browser
klim browser listening on http://127.0.0.1:54321
press Ctrl-C to stop
FlagDescription
--portListen port (0 lets the kernel pick a free one). Default 0.
--bindBind address. Default 127.0.0.1.
--no-openDo not auto-open the browser.
--keep-aliveKeep the server running after the last browser tab closes (default: shut down 10 seconds after last tab disconnects).
--insecure-bindAllow non-loopback bind addresses. Auto-generates a 32-byte bearer token and prints a ?token=… URL; the lone purpose of this flag is to be an explicit acknowledgement that the server will be reachable from the network.

--bind defaults to 127.0.0.1 and refuses any non-loopback address unless --insecure-bind is also passed, so you can’t accidentally expose an unauthenticated server on a LAN. When --insecure-bind is on, every request other than /healthz requires the token (cookie, ?token= query param, or Authorization: Bearer). See the Security section below for details.

PathRenders
/Installed tools, with category and source filters.
/tools/<name>Per-tool detail with Install / Upgrade / Remove buttons.
/updatesOutdated tools with current → latest version comparison.
/discoverFull marketplace catalog with category, tag, and free-text filters.
/favoritesYour favorited tools, with toggle action on each row.
/dashboardAggregate stats: counts, top categories, sample of pending updates.
/trailTrail entry list.
/trail/<ref>Snapshot at the given trail ref.
/backupExport YAML download, share token, and manifest preview.
/backup/export.yamlDirect YAML download (used by the Export button).
/configRead-only YAML dump of the running configuration.
/jobs/<id>Live progress for an Install / Upgrade / Remove job (SSE-streamed).
/healthzLiveness probe (200 ok). Always unauthenticated.

The Tool detail page exposes the same Install / Upgrade / Remove actions as the TUI. Submitting a button creates a job and redirects to /jobs/<id>, which streams the package manager’s combined stdout / stderr line-by-line via Server-Sent Events. The page also falls back to the snapshot endpoint if the browser doesn’t support SSE.

The action chooses a package manager automatically:

  • Install uses the best available source for your OS (the same rule klim list uses for its install commands).
  • Upgrade and Remove prefer the source the tool is already installed from.

A JSON counterpart to every page is exposed under /api/*. The shapes mirror the existing CLI --output json payloads so existing scripts read both indistinguishably.

PathMethodReturns
/api/toolsGETAll resolved tools + catalog summary.
/api/tools/<name>GETOne resolved tool, including GitHub metadata.
/api/dashboardGETStats payload used by /dashboard.
/api/trailGETTrail entries (newest first).
/api/trail/<ref>GET{ "entry": ..., "snapshot": ... }.
/api/favoritesGETYour current favorite tool names (sorted).
/api/favorites/<name>/togglePOSTFlip the favorite state; returns { "name", "favorite" }.
/api/jobsPOSTBody: { "action": "install"|"upgrade"|"remove", "tool": "<name>" }. Returns 202 Accepted + the job snapshot.
/api/jobs/<id>GETJSON snapshot of the job.
/api/jobs/<id>/streamGETServer-Sent Events stream of the job’s output (replays history on connect).

State-changing endpoints (POST) require an Origin or Referer header that matches the host serving the request. This blocks CSRF and DNS rebinding even on loopback. Browsers send the right header automatically; scripts must set -H "Origin: http://127.0.0.1:<port>" explicitly.

Terminal window
# Run on a fixed port without opening the browser (CI / headless).
klim browser --port 7777 --no-open
# Probe the API while the server is running.
curl -s http://127.0.0.1:7777/api/dashboard | jq .updates_available
  • Loopback-only by default. --insecure-bind is required for any other interface.
  • --insecure-bind automatically enables bearer-token authentication. klim generates a 32-byte token at startup and prints a ?token=<token> URL to stderr. Visiting that URL once sets a session cookie; the token is also accepted via Authorization: Bearer <token> for scripts. /healthz stays open for liveness probes.
  • Only one Install / Upgrade / Remove job runs per tool at a time. Submitting a second action for a tool that already has a running job redirects to the existing job’s progress page (HTTP 303 for the HTML form path, HTTP 409 with redirect_to for the JSON API).
  • All HTML is rendered through Go’s html/template, which escapes values by default.
  • State-changing endpoints (favorite toggle, install / upgrade / remove jobs) require an Origin or Referer header matching the request’s Host. This blocks CSRF and DNS-rebinding attacks even when the server is reachable over loopback. Browsers send the header automatically for in-page navigation.
  • Action jobs (install / upgrade / remove) shell out to the user’s package managers using the same templates klim list uses. klim itself does not run anything as root; sudo prompts behave the same way they do from the terminal.