wbxcallprov/docker/remote-agent
jmcqueen 93b060bc8b Modernize bot to Node.js 22 with modular architecture and remote SIW agent
- Refactor monolithic index.js (2646 lines) into src/{webex,integrations,
  cards,flows,commands,services} modules; replace node-fetch/form-data
  with native fetch/FormData; move all secrets to .env via dotenv
- Add dockerized remote SIW agent (docker/remote-agent/) with cross-arch
  buildx packaging (arm64 Mac -> linux/amd64), idempotent install.sh
  deploy bundle, and docker-free ZIP inspector for arch verification
- Bot hosts a WebSocket server; agent proxies SIW requests with a
  per-request insecure:true flag, replacing the process-wide
  NODE_TLS_REJECT_UNAUTHORIZED bypass
- Add ESLint flat config + Prettier, rewrite Dockerfile as non-root
  multi-stage node:22-alpine build, README covering setup / deploy /
  remote agent workflow
- Fix parseStoreArg to read trigger.prompt correctly (was indexing past
  the framework's post-match slice); register /help as regex (string
  matcher only compares the first token); switch catch-all to /.+/
  (previous /.*/gim was stateful due to the g flag); remove
  /fixDisplayNames command and its flow/card

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 14:48:51 -04:00
..
deploy Modernize bot to Node.js 22 with modular architecture and remote SIW agent 2026-07-06 14:48:51 -04:00
.env.example Modernize bot to Node.js 22 with modular architecture and remote SIW agent 2026-07-06 14:48:51 -04:00
docker-compose.yml Modernize bot to Node.js 22 with modular architecture and remote SIW agent 2026-07-06 14:48:51 -04:00
Dockerfile Modernize bot to Node.js 22 with modular architecture and remote SIW agent 2026-07-06 14:48:51 -04:00
inspect-bundle.sh Modernize bot to Node.js 22 with modular architecture and remote SIW agent 2026-07-06 14:48:51 -04:00
package.json Modernize bot to Node.js 22 with modular architecture and remote SIW agent 2026-07-06 14:48:51 -04:00
package.sh Modernize bot to Node.js 22 with modular architecture and remote SIW agent 2026-07-06 14:48:51 -04:00
README.md Modernize bot to Node.js 22 with modular architecture and remote SIW agent 2026-07-06 14:48:51 -04:00
remoteAgent.js Modernize bot to Node.js 22 with modular architecture and remote SIW agent 2026-07-06 14:48:51 -04:00

wbxStoreProvision Remote Agent — Build & Package

This directory produces a self-contained, offline-installable Docker bundle for the wbxStoreProvision remote agent. The agent is a tiny WebSocket client that runs inside a segmented (store / on-prem) network and proxies HTTP requests from the main bot back to Store Info Web.

The layout mirrors the equivalent bundle in the netanalyzer repo so the same operator playbook applies. Both bundles use distinct image tags and container names (wbxprov-remote-agent vs sha-remote-agent), so a single on-prem host can run both agents side by side without conflict.

Layout

docker/remote-agent/
├── Dockerfile             build definition (node:22-alpine + tini, non-root)
├── docker-compose.yml     build-from-source compose (dev / rebuild use only)
├── package.json           the agent's own package manifest (ws + axios + dotenv)
├── package.sh             produces the shippable ZIP under dist/
├── inspect-bundle.sh      docker-free arch/OS check on any built ZIP
├── remoteAgent.js         the agent itself — proxies WS → HTTP
├── .env.example           template consumed at deploy time
├── deploy/
│   ├── docker-compose.yml runtime-only compose (used inside the ZIP)
│   ├── install.sh         idempotent installer bundled into the ZIP
│   └── README.md          operator-facing README bundled into the ZIP
└── dist/                  produced by package.sh (git-ignored)

Build & package a bundle

From the repo root, or the docker/remote-agent/ directory:

# Default: build for linux/amd64 (typical Rocky/RHEL/Ubuntu servers)
npm run agent:package
# or explicitly: ./docker/remote-agent/package.sh

# ARM Linux target (e.g. Raspberry Pi, ARM-based server)
./docker/remote-agent/package.sh --platform linux/arm64

# Override the version tag
./docker/remote-agent/package.sh --tag 1.0.1

# Preflight only — verify the build environment without actually building.
# Useful the first time you set up a new machine.
npm run agent:check

Output: docker/remote-agent/dist/wbxprov-remote-agent-<version>.zip.

How cross-arch builds (arm64 Mac → linux/amd64) are guaranteed

Building an x86_64 Linux image from an Apple Silicon Mac is the single easiest way to silently ship a broken bundle, so the script defends against that in four independent layers:

  1. Dedicated docker-container builder. The default buildx builder on Docker Desktop uses the docker driver, which is pinned to the daemon's native architecture and will happily ignore --platform. The script creates (and, if it finds a mis-driver builder with the same name, re-creates) a wbxprov-remote-agent-builder using the docker-container driver, which spins up an isolated BuildKit instance that actually honors --platform.
  2. binfmt handlers. When cross-building, the script best-effort registers QEMU handlers for the target arch via tonistiigi/binfmt. Docker Desktop usually has these; Colima / plain Docker Engine often don't.
  3. docker image inspect check after build. Reads the image out of the local daemon and refuses to proceed if Architecture doesn't match the requested --platform.
  4. inspect-bundle.sh on the final ZIP. Independent, docker-free check that reads the image config JSON directly out of the tarball inside the ZIP. If this passes, the ZIP is provably correct regardless of anything the local daemon may have said.

If any layer detects a mismatch, package.sh exits non-zero and prints the exact rebuild command. You cannot accidentally ship an arm64 bundle to an amd64 host.

Verify a ZIP after the fact (no docker required)

# Auto-detects the newest ZIP in dist/:
npm run agent:inspect

# Or point it at a specific bundle:
./docker/remote-agent/inspect-bundle.sh path/to/wbxprov-remote-agent-1.0.0.zip

# Enforce expectations (exits non-zero if wrong):
EXPECTED_ARCH=amd64 EXPECTED_OS=linux npm run agent:inspect

This works on any machine with python3 + unzip — no Docker daemon required — so you can verify a bundle on the Linux target host itself before running ./install.sh.

Requirements on the build host

  • Docker with the buildx plugin (Docker Desktop includes it out of the box).
  • zip, node, python3, and either sha256sum or shasum.

Deploy the bundle on the remote host

Transfer the ZIP produced above to the target host, then:

unzip wbxprov-remote-agent-<version>.zip
cd wbxprov-remote-agent-<version>
./install.sh

install.sh will:

  1. Verify the SHA-256 checksum against SHA256SUMS.
  2. docker load the image tarball.
  3. Sanity-check the image architecture matches the host.
  4. On first run: copy .env.example.env and stop, asking you to fill in WS_URL (the bot's public WebSocket endpoint) and WS_TOKEN (matching the value in the bot's .env).
  5. On the second run: docker compose up -d to start the container.

See deploy/README.md for the full operator-facing guide (upgrades, troubleshooting, logs).

Configuring the bot side

The bot's .env needs matching values:

WS_PORT=8080         # what the bot's WebSocket server listens on
WS_TOKEN=<same secret the agent sends as Authorization: Bearer>

Make sure whatever public URL fronts the bot (reverse proxy, ingress, etc.) maps /ws (or wherever WS_URL in the agent's .env points) through to WS_PORT on the bot container.

Coexisting with the netanalyzer agent

The two bundles are cleanly separated:

wbxStoreProvision netanalyzer
Image tag wbxprov-remote-agent:<version> sha-remote-agent:<version>
Container name wbxprov-remote-agent sha-remote-agent
Deploy folder wbxprov-remote-agent-<version>/ sha-remote-agent-<version>/
.env variables WS_URL, WS_TOKEN WS_URL, WS_TOKEN

Each has its own .env inside its own folder pointing at its own server, so there's no shared state between them.