Package Exports
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@revota/wms-cli) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
wms-cli
Command-line client for the Revota WMS (Warehouse Management System). Thin HTTP wrapper over the wms-be NestJS API.
Install
Requires Node.js >= 20.
git clone git@github.com:avarevota/wms-cli.git
cd wms-cli
npm install
npm run build
npm link # exposes `wms` (and `revota`) globallyFor local development without linking:
npm run dev -- <command> # runs via tsx, no build step
# e.g.
npm run dev -- list inboundsConfigure
The CLI stores config (API URL, auth token, user) in ~/.config/revota-wms/config.json (chmod 600).
wms config set apiUrl https://wms.example.com # default: http://localhost:3030
wms config get apiUrlapi-url, apiurl, and apiUrl are all accepted as key names.
Authenticate
wms login # prompts for email + password
wms login -e me@example.com -p secret # non-interactive
wms whoami
wms logout # clears token; apiUrl is preservedCommands
wms list <resource>
Available resources: inbounds, outbounds, stock, skus, locations, customers, movements, adjustments, opnames, picklists, packs, ships. Singular and dashed aliases (inbound, sku, product, adjustment, stock-opname, picklist, pack, ship, shipment, …) also work.
wms list inbounds --status PENDING --limit 20
wms list outbounds --page 2
wms list stock # paginated; --json for full shape
wms list skus
wms list locations --zone A
wms list movements --from 2026-04-01 --to 2026-04-22
wms list adjustments --status 1 --warehouse-id <id> --from 2026-04-01Flags (each applies where the backend supports it):
| Flag | Notes |
|---|---|
--limit <n> |
Page size, max 50 |
--page <n> |
Page number |
--status <v> |
Filter by status. Accepts numeric codes or enum labels for: adjustments / opnames / movements (PENDING, WAITING_FOR_APPROVAL, DONE, CANCELED); outbounds (HOLD, PROCESS, READY_TO_SHIP, COMPLETE, ERROR, CANCELED); picklists (PENDING, READY_TO_PICK, PICK, READY_TO_PACK, PACK, READY_TO_SHIP, SHIP, CANCELED); packs (PENDING, INPROGRESS, DONE); ships (READY_TO_SHIP, SHIPPED). |
--type <v> |
Adjustment type (1 = product) |
--sku <v> |
Filter by SKU (where supported) |
--location <v> |
Filter by location (where supported) |
--zone <v> / --area <v> |
Locations |
--from <date> / --to <date> |
Date ranges (movements, adjustments) |
--customer-id <id> / --brand-id <id> / --warehouse-id <id> |
Adjustments / scoped resources |
--assigned <id> |
Adjustments — filter by assignee |
--json |
Raw JSON output (unwrapped data) |
wms get <resource> <id>
wms get inbound <id>
wms get outbound <id>
wms get sku <id>
wms get location <id>
wms get customer <id>
wms get movement <id>
wms get adjustment <id>wms get stock <id> is not supported — the backend has no stock detail endpoint. Use wms list stock instead.
wms update <resource> <id>
Updates products / variants via PUT /products/:id (the id is a product variant id). Pass any subset of flags, or hand it a full payload via --data '<json>'.
wms update sku <variantId> --name "New Name" --price 19900
wms update sku <variantId> --sku NEW-001 --sku-external EXT-001 --cogs 12000
wms update sku <variantId> --attributes '[{"name":"color","value":"red"}]'
wms update sku <variantId> --data '{"name":"…","sku":"…","skuExternal":"…","brandId":"…","categoryId":"…","method":1}'Available fields: --name, --sku, --sku-external, --msku, --brand-id, --category-id, --customer-id, --cogs, --price, --method, --note, --attributes (JSON array), --dimension (JSON object). The backend marks brandId/categoryId/name/sku/skuExternal as required — for partial edits, fetch the record first or use --data.
wms adjustment <action>
Stock-adjustment lifecycle. The flow is: create → save-products → (review/update-item/cancel-item) → finish → approve.
wms adjustment create \
--warehouse-id <id> --assigned-to <userId> --due-date 2026-05-01 \
[--customer-id <id>] [--brand-id <id>] [--note "monthly cycle count"]
wms adjustment save-products <adjustmentId> \
--warehouse-id <id> \
--items '[{"productVariantId":"…","originLocation":"BIN-A1","qty":12,"batchNumber":"…","expiredDate":"2026-12-31"}]'
# Convenience: add a single line without writing JSON
wms adjustment add-item <adjustmentId> \
--warehouse-id <id> --product-variant-id <id> --origin-location BIN-A1 --qty 12 \
[--batch-number B-001 --expired-date 2026-12-31 --inventory-status 1]
# Discover what's currently in stock for the adjustment's warehouse
wms adjustment products <adjustmentId>
wms adjustment items <adjustmentId> [--limit 50 --page 1]
wms adjustment update-item <itemId> --qty 10
wms adjustment cancel-item <itemId>
wms adjustment cancel <adjustmentId> # cancel the whole adjustment
wms adjustment finish <adjustmentId> # PENDING → WAITING_FOR_APPROVAL
wms adjustment approve <adjustmentId> --note "approved after spot check"finish and approve return { succeed, failed, errors[] } — the CLI prints both counts and any per-item errors. See docs/KNOWLEDGE.md for status codes.
wms inbound <action>
Manage inbound work orders beyond list/get.
wms inbound orders <inboundId> [--limit 50 --page 1]
wms inbound update-order <orderId> --expected-quantity 12 --batch-number B-001 --expired-date 2026-12-31
wms inbound finish <inboundId>
wms inbound cancel <inboundId>update-order is partial — pass any subset of --expected-quantity, --batch-number, --expired-date.
wms opname <action>
Stock-opname / cycle-counting workflow. Mirrors adjustment in shape (PENDING → WAITING_FOR_APPROVAL → DONE / CANCELED) but the count source is "physical inventory at location", not a discrepancy ticket.
wms opname create --name "Q2 cycle count, zone A" \
--warehouse-id <id> --assigned-to <userId> [--type 1] [--customer-id …] [--brand-id …] [--note …] [--due-date 2026-05-15]
# Discover product variants available to add (helper)
wms opname products <opnameId> --warehouse-id <id> [--zone-code Z1 --area-code A1 --search abc]
# Add counted items in batch (one storage list per group)
wms opname add-items \
--data '[{"stockOpnameId":"<id>","productVariantIds":["<v1>","<v2>"],"storages":[{"warehouseId":"<id>","zoneCode":"Z1","areaCode":"A1","storageCode":"BIN-A1"}]}]'
# Or batch-update counted quantities by barcode after the count is done
wms opname batch-update-items <opnameId> \
--items '[{"barcode":"123","storage":{"warehouseId":"<id>","zoneCode":"Z1","areaCode":"A1","storageCode":"BIN-A1"},"actualQuantity":12}]'
# Inspect & adjust per-item
wms opname items <opnameId> [--type 1 --group --limit 50 --page 1]
wms opname adjust-item <itemId> --quantity 11
wms opname cancel-item <itemId>
# Update header before finishing
wms opname update <opnameId> --name "…" --due-date 2026-05-30 --note "extended"
# Lifecycle
wms opname finish <opnameId> # PENDING → WAITING_FOR_APPROVAL
wms opname approve <opnameId> --note # → DONE (applies stock corrections)
wms opname cancel <opnameId> # PATCH /cancel
wms opname delete <opnameId> # soft deletewms logs <kind>
Read-only audit / activity surfaces. Bounded windows are enforced where the backend requires them.
wms logs activity --module INBOUND --user-id <id> --from 2026-04-01 --to 2026-04-26
wms logs modules # enum values for --module above
wms logs webhooks --from 2026-04-01 --to 2026-04-26 --event 1 --keyword forstok
wms logs sync-stocks --from 2026-04-01 --type 1 --keyword "out of stock"logs webhooks requires --from and --to (backend constraint). Use --json if you'd rather pipe the raw envelope into jq.
wms outbound <action>
Outbound order management beyond list/get. Status flags accept labels (PROCESS, READY_TO_SHIP, COMPLETE, …) or numeric codes.
wms outbound update-status <orderId> --status READY_TO_SHIP --awb JNE1234
wms outbound update-status <orderId> --status CANCELED --cancel-reason "Customer canceled"
wms outbound cancel <orderId>
wms outbound bulk-update-status --ids <id1>,<id2> --status COMPLETE
wms outbound bulk-set-picker --ids <id1>,<id2> --picker <userId> --status PROCESS
wms outbound logs --outbound-number <code>bulk-* commands accept --is-selected-all to apply to every record matching the supplied filters (--filter-status, --customer-id).
wms picklist <action>
Picklist lifecycle from generation through shipping. The flow is: generate → set picker → set mobile-storage → pick-away (per scan) → finish → set packing-area → update-to-shipped.
# Generate a picklist for selected outbound orders
wms picklist generate --outbound-ids <id1>,<id2> --picker-count 2
# List items + see a single item
wms list picklists --status READY_TO_PICK
wms picklist items <picklistId>
wms picklist item <itemId>
# Assign and route
wms picklist set-picker <picklistId> --picker <userId>
wms picklist set-mobile-storage <picklistId> --area-code CART-1
wms picklist set-packing-area <picklistId> --area-code PACK-A
# Floor scans
wms picklist product-scan --sku <barcode>
wms picklist location-scan --location BIN-A1
# Per-item pick — one call per scan
wms picklist pick-away \
--picklist-id <id> --pick-item-id <itemId> --item-barcode 12345 --qty 1 \
--warehouse-id <id> --zone-code Z1 --area-code A1 --storage-code BIN-A1 \
--mobile-storage-code CART-1
# Lifecycle
wms picklist finish <picklistId>
wms picklist update-to-shipped <picklistId> --awb JNE1234wms pack <action>
Pack workflow. Built from one or more finished picklists; each pack splits into pack orders (one per outbound), and each pack order has pack items (per SKU/box).
# Build the pack from finished picklists
wms pack create --picklist-ids <pl1>,<pl2>
# List + drill down
wms list packs --status INPROGRESS
wms pack orders <packId>
wms pack items <packOrderId>
wms pack pack-order <packId> <orderId>
# Per-scan packing
wms pack pack-away --pack-item-id <id> --qty 1 --item-barcode 12345
# Fix mistakes / close out
wms pack adjust-item <itemId> --quantity 2
wms pack finish --pack-id <packId> --pack-order-id <orderId>
# Diagnostic
wms pack mobile-storages [--mobile-storage-code CART-1]wms ship <action>
Ship workflow. Tracks the AWB lifecycle from "ready to ship" → "shipped" (delivered, with proof).
wms list ships --status READY_TO_SHIP
wms ship create --awb JNE1234
wms ship proof-of-delivery <shipId> --proof "https://files.example.com/pod-123.png"
wms ship completed <shipId>wms put-away <action>
Inbound partial put-away workflow on /inbound-puts. The flow is: create session → add items (per location) → finish (commits stock). Multiple sessions can run for one inbound.
# 1. Create a put-away session covering selected order line(s)
wms put-away create --inbound-id <inboundId> --order-ids <orderId1>,<orderId2>
# 2. Add a counted item, mapping it to a destination location
wms put-away add-item <putAwayId> \
--inbound-order-id <orderId> --warehouse-id <id> \
--zone-code Z1 --area-code A1 --storage-code BIN-A1 \
--accepted 10 --rejected 0
# 3. Inspect / fix items
wms put-away detail <putAwayId>
wms put-away update-item <putAwayId> <itemId> \
--warehouse-id <id> --zone-code Z1 --area-code A1 --storage-code BIN-A2 --accepted 8
wms put-away delete-item <putAwayId> <itemId>
# 4. List sessions for an inbound, finish or cancel
wms put-away list <inboundId>
wms put-away finish <putAwayId> # commits stock to locations
wms put-away cancel <putAwayId>Global flags
| Flag | Purpose |
|---|---|
--verbose |
Log request/response (password + token redacted) |
--json |
Raw JSON output (per-command) |
-h, --help |
Help on any command |
Output modes
- Default: formatted table for lists, key/value block for details.
--json: rawdatafrom the API envelope. Pipe tojq:wms list inbounds --json | jq '.items[].reference'
Error handling
The CLI exits with status 1 and a one-line error for:
- Network errors, non-JSON responses.
401— printsSession expired — run 'wms login'.429— printsRate limit exceeded — slow down and retry.- Backend
{ success: false }envelopes — printsmessageanderrors[].
Development
npm run typecheck
npm run lint
npm run build # tsup → dist/index.js
npm run dev -- list inboundsProject layout:
src/
index.ts # commander entry, global flags, help footer
commands/
auth.ts # login / logout / whoami
config.ts # config get/set
list.ts # `wms list <resource>` dispatcher
get.ts # `wms get <resource> <id>` dispatcher
update.ts # `wms update <resource> <id>` dispatcher
adjustment.ts # `wms adjustment <action>` workflow group
inbound.ts # `wms inbound <action>` (orders, update-order, finish, cancel)
put-away.ts # `wms put-away <action>` (partial put-away workflow)
opname.ts # `wms opname <action>` (cycle-count workflow)
logs.ts # `wms logs <kind>` (activity / webhooks / sync-stocks)
outbound.ts # `wms outbound <action>` (order status, picker, logs)
picklist.ts # `wms picklist <action>` (generate, pick, finish, ship)
pack.ts # `wms pack <action>` (create, pack-away, finish, items)
ship.ts # `wms ship <action>` (create, proof-of-delivery, completed)
lib/
client.ts # fetch wrapper, envelope unwrap, 401/429 handling
config.ts # ~/.config/revota-wms store (chmod 600)
resources.ts # resource registry (add new resources here)
output.ts # table / JSON / colored output
errors.ts # shared error printerAdding a new read-only resource: append a ResourceDef entry in src/lib/resources.ts — no new command files needed.
Adding update support to a resource: set the update block on its ResourceDef (method, fields, optional pathFor). The shared wms update dispatcher will pick up the flags automatically.
Adding a new workflow (multi-action lifecycle, e.g. adjustment / opname): create a dedicated command group in src/commands/<name>.ts and register it from src/index.ts. The resource registry handles list/get; the command file owns custom actions.
Operations Guide
For detailed status codes, workflows, and operational guidance, see docs/KNOWLEDGE.md.
This guide is especially useful for:
- Understanding status code meanings (e.g., what does status "2" mean for inbounds?)
- Common operational workflows
- Data relationships between entities
- CLI tips for daily operations
License
UNLICENSED — internal use only.