Native Pebble C watch app for monitoring Codex app-server jobs over WebSocket JSON-RPC.
- The watch UI is native Pebble C.
- PKJS handles hosted settings, Codex JSON-RPC, and the compact AppMessage bridge to C.
- Browser-like Pebble WebSocket clients connect to a local sidecar because Codex app-server rejects WebSocket handshakes with an
Originheader. - There are no
/watch/*endpoints and no OpenAI credential flow on the watch. The sidecar forwards Codex JSON-RPC messages without translating them.
-
Build the hosted config page into
docs/config:npm run build:config:docs
-
Host
docs/with GitHub Pages. Published builds default to:https://nick1udwig.github.io/codex-pebble/config/ -
Start the sidecar locally:
npm run dev:sidecar
By default this listens on all interfaces at
0.0.0.0:4501. On launch it probes Codex app-server in this order, without starting Codex:- Existing Unix-socket app-server at
~/.codex/app-server-control/app-server-control.sock. - Existing stdio transport attached to the sidecar process's stdin/stdout.
If neither transport is available, the sidecar exits with an error before accepting watch connections.
Configure the watch to use the sidecar URL. For the emulator, use:
ws://127.0.0.1:4501For a real phone, configure the watch with a Tailnet-reachable or LAN URL for the machine running the sidecar. Default non-loopback binds generate a token; pass your own token if you want it stable:
npm run dev:sidecar -- --token <shared-token>
Configure the watch with:
ws://<tailnet-ip-or-host>:4501/?token=<shared-token>To pass a custom Unix socket:
npm run dev:sidecar -- --unix-socket /path/to/app-server.sock
The stdio fallback is only useful when another launcher has already connected the sidecar process's stdin/stdout to
codex app-server --listen stdio://. The sidecar does not start Codex app-server. - Existing Unix-socket app-server at
-
Build and install:
npm run build:watch pebble install --emulator emery
The local gates mirror the tg-pebble layout:
npm run test:js
npm run test:config
npm run test:sidecar
npm run test:build
npm run test:pre-releaseUse npm run dev:config to serve the config page at http://127.0.0.1:4173.
If a local sidecar is already running, npm run smoke:app-server -- --ws-url ws://127.0.0.1:4501 performs a read-only JSON-RPC smoke test over the same WebSocket path PKJS uses.
For an emulator smoke test:
pebble install --emulator emery --logsFor a real paired phone dev install:
npm run deploy:phone.github/workflows/pages.ymlbuildsdocs/configfromsrc/configand deploys GitHub Pages..github/workflows/public-build.ymlbuilds a release.pbwand uploads it as a workflow artifact..github/workflows/pre-release.ymlruns JS tests, config-page tests, sidecar tests, and a watch build..github/workflows/release.ymlmanually bumps the version, tagsvX.Y.Z, and publishes the release.pbwplus Linux, macOS, and Windows sidecar binaries.
Set GitHub Pages to GitHub Actions under repository settings before relying on the Pages workflow.
Generate schemas from the Codex version you run:
npm run schemas:ts
npm run schemas:jsonThe checked-in schemas/ directory was generated from the local Codex install and is used by unit tests to catch protocol drift. PKJS currently reads thread/list, distills each thread into a compact row, and sends those rows to the native C watch UI with AppMessage.