WPS365 CLI is a Go-based command-line tool that provides structured access to the WPS 365 Open Platform APIs. It follows a spec-driven architecture — the OpenAPI specification files define the API surface, and curated YAML files define the human-friendly command mapping. The Go binary reads these specs at runtime to build its command tree, perform request validation, and manage authentication.
┌─────────────────────────────────────────────────────────┐
│ User / Script │
└──────────────────────┬──────────────────────────────────┘
│
┌────────────┴────────────┐
│ CLI Flag Parsing │ cobra + pflag
│ (cobra command tree) │
└────────────┬────────────┘
│
┌───────────────┴───────────────┐
│ Command Router │
│ ┌──────────┐ ┌──────────┐ │
│ │ Curated │ │ Raw API │ │
│ │ Commands │ │ (api get │ │
│ │ │ │ /path) │ │
│ └─────┬─────┘ └────┬─────┘ │
└─────────┼────────────┼─────────┘
│ │
┌──────┴────────────┴──────┐
│ Request Builder │
│ - Resolve path params │
│ - Bind flags → body/que │
│ - Apply transforms │
│ - Validate via schema │
└──────────┬───────────────┘
│
┌──────────┴───────────────┐
│ Auth Middleware │
│ - Select token type │
│ - Auto-refresh (10s) │
│ - 401 → retry once │
└──────────┬───────────────┘
│
┌──────────┴───────────────┐
│ HTTP Client │
│ - Send request │
│ - Dry-run support │
└──────────┬───────────────┘
│
┌──────────┴───────────────┐
│ Output Formatter │
│ json | yaml | table | tsv│
└──────────────────────────┘
Since the Go source code is not published in this repository, the layout shown here reflects the runtime data directory and the published repo contents.
.
├── README.md # Chinese documentation
├── README.en.md # English documentation
├── install.sh # macOS/Linux installer
├── install.ps1 # Windows PowerShell installer
└── docs/
├── prerequisites.md # OAuth app setup guide
└── assets/ # Screenshot images for docs
macOS: ~/Library/Application Support/wps365-cli/
Linux: ~/.local/share/wps365-cli/ (or $XDG_DATA_HOME/wps365-cli/)
Windows: %APPDATA%\wps365-cli\
wps365-cli/
├── spec/
│ ├── api/
│ │ ├── 365.yaml # Official OpenAPI 3.0 spec (~74k lines, 801 endpoints)
│ │ └── customs/ # User-provided custom API specs
│ └── curated/
│ ├── 365.yaml # Curated command definitions (152 commands)
│ └── customs/ # User-provided custom curated specs
└── config.json # Non-secret configuration (client_id, redirect_uri, etc.)
Credential storage (never in the data directory):
- macOS: Keychain (via
keyringGo package) - Windows: Credential Manager
- Linux: Encrypted file (
AES-256-GCM), key auto-generated and stored separately
Curated commands map complex API interactions to semantic CLI verbs. They are defined in curated/365.yaml.
Example definition:
- id: calendar.events.create
command: calendar events create
summary: 创建日程
method: POST
path: /v7/calendars/{calendar_id}/events/create
args:
- name: calendar-id
required: true
to: path.calendar_id
flags:
- name: from
type: string
required: true
to: body.start_time
- name: name
type: string
to: body.summary
body:
bindings:
- from_flag: from
to: start_time
transform: passthroughKey design principles:
- Semantic naming:
calendar events createoverapi post /v7/calendars/{id}/events/create - Smart defaults: Pagination defaults, required-scope auto-validation
- Type transforms:
split_csv,to_bool,to_intconvert CLI strings to API types - Auth constraint checking: Each command declares its security requirement; incompatible token types produce errors
api get|post|put|patch|delete|head <path> accesses any endpoint in the OpenAPI spec directly.
wps365-cli api get "/v7/users/current"
wps365-cli api post "/v7/calendars/create" --data '{"summary": "New Calendar"}'This ensures 100% API coverage even before a curated command exists.
- On startup, the CLI reads the spec directory path (default or
WPS365_CONFIG_DIR) - It loads
api/365.yamlto build the full API map - It loads
curated/365.yamlto register curated commands - Custom specs in
customs/are merged, allowing users to extend both raw API and curated commands spec updatefetches the latest official specs from the remote repositoryspec add --custom-api/--custom-curatedinstalls user-provided spec files
┌────────────────────────────────────────────────┐
│ Auth Provider │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Delegated │ │ App │ │
│ │ (User OAuth) │ │ (Client │ │
│ │ │ │ Credentials)│ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ ┌──────┴──────────────────┴───────┐ │
│ │ Token Store │ │
│ │ Keychain / Credential Manager │ │
│ │ / Encrypted File │ │
│ └──────────────────────────────────┘ │
│ │
│ Auto-refresh: │
│ - 10s before expiry → proactive refresh │
│ - 401 response → transparent retry │
│ - Delegated: use refresh_token │
│ - App: re-acquire via client_credentials │
└────────────────────────────────────────────────┘
Three auth modes:
- Delegated: User authorizes via browser OAuth, token includes
refresh_token - App: Client credentials grant, no user context,
client_id+client_secret - OSH: Enterprise gateway credentials for internal environments
The CLI reads the OpenAPI security field for each endpoint to determine which token type is required. If the current token is incompatible, it errors rather than silently switching.
All commands route through a shared output pipeline:
- API response (JSON) →
- JMESPath/jsonpath filtering (if
--querysupported) → - Format transformer:
json(default),yaml,table,tsv
| Flag | Purpose |
|---|---|
--api-base |
Override API base URL |
--dry-run |
Print request without sending |
-o, --output |
Output format: json/yaml/table/tsv |
--quiet |
Suppress stderr informational output |
See README.md for the full list. Key categories:
- Credentials:
WPS365_CLIENT_ID,WPS365_CLIENT_SECRET,WPS365_ACCESS_TOKEN - Endpoints:
WPS365_API_BASE,WPS365_AUTH_URL,WPS365_TOKEN_URL - Config:
WPS365_CONFIG_DIR,WPS365_AUTH(default mode),WPS365_OUTPUT - Security:
WPS365_KEYRING_BACKEND,WPS365_KEYRING_PASSWORD
Users can extend the CLI without code changes:
# Add a custom API endpoint definition
wps365-cli spec add --custom-api ./my-api.yaml
# Add a custom curated command
wps365-cli spec add --custom-curated ./my-commands.yamlThis is the primary extension mechanism for organizations with private or internal APIs that follow the WPS 365 Open Platform conventions.
Non-interactive auth via environment variables:
export WPS365_CLIENT_ID="<client-id>"
export WPS365_CLIENT_SECRET="<client-secret>"
wps365-cli auth login --appCombined with --dry-run for safe scripting and -o tsv for piping to other tools.