@wat-toolbox/wat
v0.6.0
Published
wat — book WAT meeting rooms from the terminal. Email-OTP login, API-key auth, dev/prod targeting.
Downloads
1,188
Maintainers
Readme
wat — WAT Rooms CLI
Book WAT meeting rooms from the terminal. The CLI drives the same public API the web app uses (/api/rooms, /api/availability, /api/bookings), authenticated with a minted API key sent as a Bearer token. Package @wat-toolbox/wat, command wat.
Install
npm install -g @wat-toolbox/watQuick start
wat login # email-OTP → mints + stores an API key
wat rooms list # --all: admins also see archived rooms
wat availability --room "Room A" --from 2026-06-09 --to 2026-06-10
wat bookings list --mine # --limit <n> caps the output (default 50)
wat bookings create --room "Room A" --start "2026-06-09T10:00" --end "2026-06-09T11:00" --title "Sync" \
--guests "[email protected],[email protected]" # optional invitees (max 10, any address)
wat bookings edit <id> --start "2026-06-09T14:00" --end "2026-06-09T15:00"
wat bookings cancel <id>
wat keys list # your API keys (metadata only)
wat keys revoke <id> # confirms; --yes to skip
wat whoamiwat bookings edit PATCHes only the flags you pass (--room, --start, --end, --title, --guests; --tz sets the zone bare times are read in) — anything omitted keeps its current value. --guests is the one full-replacement flag: it overwrites the whole guest list (--guests "" removes everyone); newly added guests get an invitation email, removed guests a cancellation of their invite. Editing is allowed to the booking's owner (or an admin), only before the booking starts, and the server re-validates overlap, the daily budget, and opening hours.
Environment targeting
--env selects the deployment. Precedence (highest first): --api-url flag › WAT_CLI_API_BASE_URL › profile baseUrl › --env / WAT_CLI_ENV › prod default.
wat --env dev rooms list # → https://wat-app-git-stag-codika.vercel.app (development data)
wat --env prod rooms list # → https://app.wat.com (default)Time interpretation
A bare --start "2026-06-09T10:00" is read as Europe/Brussels wall-clock (matching the web UI) and converted to UTC for the API. Override the zone with --tz <IANA>. A value carrying an explicit offset (2026-06-09T10:00+02:00) or Z is honored as-is. Times are printed back in the same zone the CLI accepted, so what you type and what you see never disagree.
Booking rules
The server enforces these on create and edit; the CLI just relays the error:
- Minimum length 15 minutes; bookings must be in the future and at most 30 days ahead.
- Each member has a 2 h/day budget (per Brussels calendar day, across all rooms).
- Opening hours: 06:00–22:00 Europe/Brussels — the whole booking must fit inside one Brussels day (error code
outside_hours). - Overlaps are rejected atomically (
overlap, HTTP 409); a budget breach returnsbudget(409). - Guests: up to 10 invitee emails per booking (any address — guests need no WAT account). They receive the invitation (with calendar invite), the pre-start reminder, updates, and cancellations. Errors:
invalid_guests/too_many_guests(422).
Auth & config
wat login runs an email-OTP flow. First-time enrollment is automatic when your email is on the WAT enrollment allowlist (your company's domain, or your address added by a WAT admin); otherwise login fails with NOT_AUTHORIZED — ask a WAT admin to add your email or company domain, then retry. Agents and scripts use the two-step form: wat login --email <you> --request-code --json sends the code and exits, then wat login --email <you> --code <code> --json completes without prompting (passing --code skips the send — the code comes from the prior request). A missing required flag in --json mode fails fast with MISSING_FLAG. The minted API key is stored in ~/.config/wat/config.json (mode 0600) and sent as Authorization: Bearer <key>. The key carries your member role, and the server applies the same role gates as in the browser. Members get the booking surface; admins also get the wat admin … commands (see below).
When you log in against a non-default deployment (--env dev, --api-url, or WAT_CLI_API_BASE_URL), the profile is pinned to that base URL, so later commands keep talking to the deployment that minted the key.
wat config show— profiles + resolved targeting.wat keys list/wat keys revoke <id>— inspect + revoke your API keys (a revoked key is dead immediately, everywhere).wat logout— remove the local key (active profile, or--all); pair withwat keys revoketo kill it server-side too.
Override the key per-call with --api-key <key> or WAT_CLI_API_KEY.
Admin commands
Available to members with the admin or developer role (the server returns 403 otherwise; with a saved profile the CLI also pre-checks and prints a friendly message). Broadcasts stay web-only.
# Rooms
wat rooms create --name "Focus" --capacity 4 --tv
wat rooms edit "Focus" --capacity 6 --archive # --archive / --unarchive; <room> = name or id
wat rooms delete "Focus" # refused if it has future bookings (archive instead)
# Members
wat admin members list
wat admin members update <id> --role admin # or --activate / --deactivate
# Residents & allowed domains (the self-enrollment allowlist)
wat admin residents list
wat admin residents add [email protected] --name "Alice"
wat admin residents remove <id>
wat admin residents import people.csv --domains company.com,partner.com # CSV: "email,name" per line
wat admin domains list
wat admin domains add company.com --note "HQ"
wat admin domains remove <id>
# Room blocks (cancel + email any overlapping member bookings)
wat admin maintenance --room "Focus" --start "2026-06-20T09:00" --end "2026-06-20T12:00" --title "Deep clean"
wat admin blocks list
wat admin blocks create --room "Focus" --weekday 1 --start 09:00 --end 12:00 --label "Cleaning" # 0=Sun … 6=Sat
wat admin blocks delete <id>
# Access requests (people who asked for access)
wat admin requests list
wat admin requests accept <id> --add-domain # --add-domain allows the whole domain + sweeps siblings
wat admin requests decline <id>Accepting a request, adding a resident/domain, and the block commands send emails (acceptance notices, or reschedule notices to displaced bookers) — confirm before running them in scripts.
Output
Every command supports --json for machine consumption (the format the wat-plugin skills parse):
{ "success": true, "data": { ... } }
{ "success": false, "error": { "code": "...", "message": "...", "nextAction": "..." } }Develop
npm install
npm run build # tsc → dist/
npm test # vitest (config precedence + Brussels time conversion)Release (publish to npm)
Published as @wat-toolbox/wat (npm org wat-toolbox) by a tag-triggered GitHub Action (.github/workflows/publish.yml): it verifies the tag equals package.json#version, runs tests + build, then npm publish --access public.
One-time setup: add an npm Automation token as the NPM_TOKEN repo secret.
gh secret set NPM_TOKEN --repo WATbeta/wat-cliTo cut a release: bump version in package.json, commit, then push a matching v*.*.* tag.
git tag vX.Y.Z
git push origin vX.Y.ZThe repo is private, so the workflow publishes without --provenance; make the repo public to enable provenance attestation.
Scaffolded from codika-cli-template, mirroring the codika-meet CLI's --env + profile model.
