- 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>
|
||
|---|---|---|
| .. | ||
| deploy | ||
| .env.example | ||
| docker-compose.yml | ||
| Dockerfile | ||
| inspect-bundle.sh | ||
| package.json | ||
| package.sh | ||
| README.md | ||
| remoteAgent.js | ||
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:
- Dedicated
docker-containerbuilder. The default buildx builder on Docker Desktop uses thedockerdriver, 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) awbxprov-remote-agent-builderusing thedocker-containerdriver, which spins up an isolated BuildKit instance that actually honors--platform. binfmthandlers. When cross-building, the script best-effort registers QEMU handlers for the target arch viatonistiigi/binfmt. Docker Desktop usually has these; Colima / plain Docker Engine often don't.docker image inspectcheck after build. Reads the image out of the local daemon and refuses to proceed ifArchitecturedoesn't match the requested--platform.inspect-bundle.shon 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 eithersha256sumorshasum.
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:
- Verify the SHA-256 checksum against
SHA256SUMS. docker loadthe image tarball.- Sanity-check the image architecture matches the host.
- On first run: copy
.env.example→.envand stop, asking you to fill inWS_URL(the bot's public WebSocket endpoint) andWS_TOKEN(matching the value in the bot's.env). - On the second run:
docker compose up -dto 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.