- 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>
152 lines
6.2 KiB
Markdown
152 lines
6.2 KiB
Markdown
# 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:
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```bash
|
|
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.
|