@mainwp/control 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +583 -0
- package/bin/_exit.js +12 -0
- package/bin/dev.js +7 -0
- package/bin/run.js +7 -0
- package/dist/chat/chat-engine.d.ts +213 -0
- package/dist/chat/chat-engine.d.ts.map +1 -0
- package/dist/chat/chat-engine.js +636 -0
- package/dist/chat/chat-engine.js.map +1 -0
- package/dist/chat/index.d.ts +10 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +14 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/providers/anthropic.d.ts +52 -0
- package/dist/chat/providers/anthropic.d.ts.map +1 -0
- package/dist/chat/providers/anthropic.js +292 -0
- package/dist/chat/providers/anthropic.js.map +1 -0
- package/dist/chat/providers/gemini.d.ts +52 -0
- package/dist/chat/providers/gemini.d.ts.map +1 -0
- package/dist/chat/providers/gemini.js +284 -0
- package/dist/chat/providers/gemini.js.map +1 -0
- package/dist/chat/providers/index.d.ts +19 -0
- package/dist/chat/providers/index.d.ts.map +1 -0
- package/dist/chat/providers/index.js +23 -0
- package/dist/chat/providers/index.js.map +1 -0
- package/dist/chat/providers/local.d.ts +37 -0
- package/dist/chat/providers/local.d.ts.map +1 -0
- package/dist/chat/providers/local.js +130 -0
- package/dist/chat/providers/local.js.map +1 -0
- package/dist/chat/providers/openai-compatible.d.ts +155 -0
- package/dist/chat/providers/openai-compatible.d.ts.map +1 -0
- package/dist/chat/providers/openai-compatible.js +264 -0
- package/dist/chat/providers/openai-compatible.js.map +1 -0
- package/dist/chat/providers/openai.d.ts +24 -0
- package/dist/chat/providers/openai.d.ts.map +1 -0
- package/dist/chat/providers/openai.js +62 -0
- package/dist/chat/providers/openai.js.map +1 -0
- package/dist/chat/providers/openrouter.d.ts +26 -0
- package/dist/chat/providers/openrouter.d.ts.map +1 -0
- package/dist/chat/providers/openrouter.js +65 -0
- package/dist/chat/providers/openrouter.js.map +1 -0
- package/dist/chat/providers/provider-fetch.d.ts +15 -0
- package/dist/chat/providers/provider-fetch.d.ts.map +1 -0
- package/dist/chat/providers/provider-fetch.js +35 -0
- package/dist/chat/providers/provider-fetch.js.map +1 -0
- package/dist/chat/providers/provider.d.ts +214 -0
- package/dist/chat/providers/provider.d.ts.map +1 -0
- package/dist/chat/providers/provider.js +166 -0
- package/dist/chat/providers/provider.js.map +1 -0
- package/dist/chat/providers/sse-reader.d.ts +21 -0
- package/dist/chat/providers/sse-reader.d.ts.map +1 -0
- package/dist/chat/providers/sse-reader.js +48 -0
- package/dist/chat/providers/sse-reader.js.map +1 -0
- package/dist/chat/system-prompt.d.ts +33 -0
- package/dist/chat/system-prompt.d.ts.map +1 -0
- package/dist/chat/system-prompt.js +166 -0
- package/dist/chat/system-prompt.js.map +1 -0
- package/dist/chat/tool-envelope.d.ts +72 -0
- package/dist/chat/tool-envelope.d.ts.map +1 -0
- package/dist/chat/tool-envelope.js +263 -0
- package/dist/chat/tool-envelope.js.map +1 -0
- package/dist/commands/abilities/info.d.ts +21 -0
- package/dist/commands/abilities/info.d.ts.map +1 -0
- package/dist/commands/abilities/info.js +80 -0
- package/dist/commands/abilities/info.js.map +1 -0
- package/dist/commands/abilities/list.d.ts +19 -0
- package/dist/commands/abilities/list.d.ts.map +1 -0
- package/dist/commands/abilities/list.js +98 -0
- package/dist/commands/abilities/list.js.map +1 -0
- package/dist/commands/abilities/run.d.ts +75 -0
- package/dist/commands/abilities/run.d.ts.map +1 -0
- package/dist/commands/abilities/run.js +468 -0
- package/dist/commands/abilities/run.js.map +1 -0
- package/dist/commands/chat.d.ts +54 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +384 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/config/show.d.ts +54 -0
- package/dist/commands/config/show.d.ts.map +1 -0
- package/dist/commands/config/show.js +324 -0
- package/dist/commands/config/show.js.map +1 -0
- package/dist/commands/doctor.d.ts +77 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +412 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/jobs/watch.d.ts +50 -0
- package/dist/commands/jobs/watch.d.ts.map +1 -0
- package/dist/commands/jobs/watch.js +269 -0
- package/dist/commands/jobs/watch.js.map +1 -0
- package/dist/commands/login.d.ts +25 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +165 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/profile/delete.d.ts +22 -0
- package/dist/commands/profile/delete.d.ts.map +1 -0
- package/dist/commands/profile/delete.js +57 -0
- package/dist/commands/profile/delete.js.map +1 -0
- package/dist/commands/profile/list.d.ts +19 -0
- package/dist/commands/profile/list.d.ts.map +1 -0
- package/dist/commands/profile/list.js +53 -0
- package/dist/commands/profile/list.js.map +1 -0
- package/dist/commands/profile/use.d.ts +22 -0
- package/dist/commands/profile/use.d.ts.map +1 -0
- package/dist/commands/profile/use.js +46 -0
- package/dist/commands/profile/use.js.map +1 -0
- package/dist/config/fs-utils.d.ts +14 -0
- package/dist/config/fs-utils.d.ts.map +1 -0
- package/dist/config/fs-utils.js +31 -0
- package/dist/config/fs-utils.js.map +1 -0
- package/dist/config/keychain.d.ts +53 -0
- package/dist/config/keychain.d.ts.map +1 -0
- package/dist/config/keychain.js +175 -0
- package/dist/config/keychain.js.map +1 -0
- package/dist/config/profile-store.d.ts +85 -0
- package/dist/config/profile-store.d.ts.map +1 -0
- package/dist/config/profile-store.js +228 -0
- package/dist/config/profile-store.js.map +1 -0
- package/dist/config/settings.d.ts +71 -0
- package/dist/config/settings.d.ts.map +1 -0
- package/dist/config/settings.js +151 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/core/abilities-executor.d.ts +126 -0
- package/dist/core/abilities-executor.d.ts.map +1 -0
- package/dist/core/abilities-executor.js +264 -0
- package/dist/core/abilities-executor.js.map +1 -0
- package/dist/core/batch-manager.d.ts +113 -0
- package/dist/core/batch-manager.d.ts.map +1 -0
- package/dist/core/batch-manager.js +244 -0
- package/dist/core/batch-manager.js.map +1 -0
- package/dist/core/http-client.d.ts +111 -0
- package/dist/core/http-client.d.ts.map +1 -0
- package/dist/core/http-client.js +329 -0
- package/dist/core/http-client.js.map +1 -0
- package/dist/core/safety-controller.d.ts +114 -0
- package/dist/core/safety-controller.d.ts.map +1 -0
- package/dist/core/safety-controller.js +229 -0
- package/dist/core/safety-controller.js.map +1 -0
- package/dist/hooks/command-not-found.d.ts +12 -0
- package/dist/hooks/command-not-found.d.ts.map +1 -0
- package/dist/hooks/command-not-found.js +58 -0
- package/dist/hooks/command-not-found.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/base-command.d.ts +123 -0
- package/dist/lib/base-command.d.ts.map +1 -0
- package/dist/lib/base-command.js +285 -0
- package/dist/lib/base-command.js.map +1 -0
- package/dist/output/formatter.d.ts +48 -0
- package/dist/output/formatter.d.ts.map +1 -0
- package/dist/output/formatter.js +138 -0
- package/dist/output/formatter.js.map +1 -0
- package/dist/output/json-envelope.d.ts +43 -0
- package/dist/output/json-envelope.d.ts.map +1 -0
- package/dist/output/json-envelope.js +73 -0
- package/dist/output/json-envelope.js.map +1 -0
- package/dist/utils/audit-logger.d.ts +97 -0
- package/dist/utils/audit-logger.d.ts.map +1 -0
- package/dist/utils/audit-logger.js +169 -0
- package/dist/utils/audit-logger.js.map +1 -0
- package/dist/utils/colors.d.ts +29 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/colors.js +36 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/errors.d.ts +107 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +149 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/exit-codes.d.ts +21 -0
- package/dist/utils/exit-codes.d.ts.map +1 -0
- package/dist/utils/exit-codes.js +20 -0
- package/dist/utils/exit-codes.js.map +1 -0
- package/dist/utils/format.d.ts +64 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +69 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/prompt.d.ts +34 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +132 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/retry.d.ts +59 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +96 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/terminal-sanitizer.d.ts +60 -0
- package/dist/utils/terminal-sanitizer.d.ts.map +1 -0
- package/dist/utils/terminal-sanitizer.js +166 -0
- package/dist/utils/terminal-sanitizer.js.map +1 -0
- package/dist/validation/input-sanitizer.d.ts +76 -0
- package/dist/validation/input-sanitizer.d.ts.map +1 -0
- package/dist/validation/input-sanitizer.js +199 -0
- package/dist/validation/input-sanitizer.js.map +1 -0
- package/dist/validation/schema-validator.d.ts +75 -0
- package/dist/validation/schema-validator.d.ts.map +1 -0
- package/dist/validation/schema-validator.js +147 -0
- package/dist/validation/schema-validator.js.map +1 -0
- package/oclif.manifest.json +857 -0
- package/package.json +101 -0
- package/scripts/completions/README.md +221 -0
- package/scripts/completions/mainwpcontrol.bash +193 -0
- package/scripts/completions/mainwpcontrol.zsh +267 -0
- package/scripts/completions/profile-completer.sh +35 -0
- package/scripts/completions/regenerate.sh +78 -0
package/README.md
ADDED
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
# MainWP Control
|
|
2
|
+
|
|
3
|
+
A CLI for managing your MainWP Dashboard from the terminal. List sites, push updates, sync data, run batch operations across dozens of sites. The command is `mainwpcontrol`.
|
|
4
|
+
|
|
5
|
+
**Looking for the MCP Server instead?** [MainWP MCP Server](https://github.com/mainwp/mainwp-mcp) is for conversational AI management inside Claude, Cursor, or any MCP-compatible client. MainWP Control is for automation: cron jobs, CI/CD pipelines, monitoring scripts, and batch operations. Both talk to the same Abilities API with the same safety model.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
You need Node.js 20+ and a MainWP Dashboard (v6+) with an [Application Password](https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/).
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g @mainwp/control
|
|
15
|
+
|
|
16
|
+
mainwpcontrol login
|
|
17
|
+
|
|
18
|
+
mainwpcontrol abilities list
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
You should see something like this:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
Abilities (87 total)
|
|
25
|
+
|
|
26
|
+
Sites
|
|
27
|
+
Name Description Type
|
|
28
|
+
---------------- -------------------- --------------
|
|
29
|
+
list-sites-v1 List MainWP sites 📖 read
|
|
30
|
+
mainwpcontrol abilities run list-sites-v1
|
|
31
|
+
get-site-v1 Get site details 📖 read
|
|
32
|
+
mainwpcontrol abilities run get-site-v1
|
|
33
|
+
sync-sites-v1 Sync all sites ✏️ write
|
|
34
|
+
mainwpcontrol abilities run sync-sites-v1
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
That's it. You're connected and you can see every operation your Dashboard supports.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## What Just Happened
|
|
42
|
+
|
|
43
|
+
`abilities list` shows every operation available on your Dashboard. These are called "abilities" and they cover sites, plugins, themes, updates, clients, tags, and more.
|
|
44
|
+
|
|
45
|
+
Each ability has a name (like `list-sites-v1`) that you pass to `abilities run` to execute it. The list tells you whether each one is read-only, a write operation, or destructive.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Common Use Cases
|
|
50
|
+
|
|
51
|
+
**List all your sites:**
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
mainwpcontrol abilities run list-sites-v1 --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Check for pending updates across sites:**
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
mainwpcontrol abilities run list-updates-v1 --json
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Get details for a specific site:**
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
mainwpcontrol abilities run get-site-v1 --input '{"site_id": 1}' --json
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Preview a destructive action before running it:**
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
mainwpcontrol abilities run delete-site-v1 \
|
|
73
|
+
--input '{"site_id_or_domain": "mysite.com"}' \
|
|
74
|
+
--dry-run --json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Nothing changes until you explicitly pass `--confirm`.
|
|
78
|
+
|
|
79
|
+
**Update plugins and wait for completion:**
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
mainwpcontrol abilities run update-site-plugins-v1 \
|
|
83
|
+
--input '{"site_id": 1}' \
|
|
84
|
+
--wait --json
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`--wait` blocks until the operation finishes. Useful in CI pipelines.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Installation
|
|
92
|
+
|
|
93
|
+
### Standard install (recommended)
|
|
94
|
+
|
|
95
|
+
Pre-built keychain binaries are included for macOS, Windows, and Linux (x64 and arm64). On other platforms you may need C++ build tools during installation.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npm install -g @mainwp/control
|
|
99
|
+
|
|
100
|
+
# Interactive login (stores credentials in your OS keychain)
|
|
101
|
+
mainwpcontrol login
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Environment variable auth (CI, Docker, headless)
|
|
105
|
+
|
|
106
|
+
Use this when no OS keychain is available, or if keytar fails to build.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npm install -g @mainwp/control
|
|
110
|
+
|
|
111
|
+
export MAINWP_APP_PASSWORD='xxxx xxxx xxxx xxxx xxxx xxxx'
|
|
112
|
+
|
|
113
|
+
mainwpcontrol login --url https://dashboard.example.com --username admin
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
When the OS keychain is unavailable, credentials are not stored on disk. Keep `MAINWP_APP_PASSWORD` set for each run.
|
|
117
|
+
|
|
118
|
+
If keytar is installed but broken, set `MAINWPCONTROL_NO_KEYTAR=1` to skip loading it.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
<details>
|
|
123
|
+
<summary><strong>New to the Command Line?</strong></summary>
|
|
124
|
+
|
|
125
|
+
If you haven't used a terminal before, here's what you need to know.
|
|
126
|
+
|
|
127
|
+
### What is a terminal?
|
|
128
|
+
|
|
129
|
+
A terminal is where you type commands instead of clicking buttons. You'll see it called "command line" or "shell" in different places.
|
|
130
|
+
|
|
131
|
+
**How to open it:**
|
|
132
|
+
- **macOS**: Open **Terminal** (search in Spotlight, or look in Applications > Utilities)
|
|
133
|
+
- **Windows**: Open **PowerShell** (search in the Start menu)
|
|
134
|
+
- **Linux**: Open your distribution's **Terminal** app (usually in the applications menu)
|
|
135
|
+
|
|
136
|
+
### What does `npm install -g` do?
|
|
137
|
+
|
|
138
|
+
`npm` is the Node.js package manager. It downloads and installs JavaScript packages. The `-g` flag installs globally, which makes `mainwpcontrol` available as a command anywhere on your system, not only in one project folder.
|
|
139
|
+
|
|
140
|
+
### What is an environment variable?
|
|
141
|
+
|
|
142
|
+
An environment variable is a named value that programs can read. They're commonly used for passwords and API keys.
|
|
143
|
+
|
|
144
|
+
**Setting one:**
|
|
145
|
+
```bash
|
|
146
|
+
# macOS / Linux (lasts until you close the terminal)
|
|
147
|
+
export MAINWP_APP_PASSWORD='xxxx xxxx xxxx xxxx xxxx xxxx'
|
|
148
|
+
|
|
149
|
+
# Windows PowerShell (lasts until you close the window)
|
|
150
|
+
$env:MAINWP_APP_PASSWORD = 'xxxx xxxx xxxx xxxx xxxx xxxx'
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
For long-term storage, use the OS keychain (the default when you run `mainwpcontrol login`) or a restricted-permission `.env` file rather than pasting credentials into shell profile files.
|
|
154
|
+
|
|
155
|
+
### What is an Application Password?
|
|
156
|
+
|
|
157
|
+
WordPress Application Passwords let external tools like `mainwpcontrol` access your site without using your main login password. They look like groups of four characters separated by spaces (e.g., `abcd efgh ijkl mnop qrst uvwx`).
|
|
158
|
+
|
|
159
|
+
**To create one:** Log into WordPress admin > Users > Your Profile > scroll to **Application Passwords** > enter a name like "mainwpcontrol" > click **Add New Application Password** > copy the generated password.
|
|
160
|
+
|
|
161
|
+
### Reading command output
|
|
162
|
+
|
|
163
|
+
When you run a command, the output appears in your terminal. A few things to know:
|
|
164
|
+
|
|
165
|
+
- **`--json`** tells `mainwpcontrol` to output structured JSON (useful for scripting and piping to other tools)
|
|
166
|
+
- **Exit codes** indicate success (`0`) or failure (`1` through `5`). You won't see them directly, but scripts and CI use them to decide what happens next. Run `echo $?` (macOS/Linux) or `echo $LASTEXITCODE` (PowerShell) after a command to check.
|
|
167
|
+
|
|
168
|
+
</details>
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Basic Usage
|
|
173
|
+
|
|
174
|
+
### Abilities
|
|
175
|
+
|
|
176
|
+
Your Dashboard exposes its operations as "abilities." You browse them, pick one, and run it. Every ability has a versioned name like `list-sites-v1` that you pass to `abilities run`.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# List all abilities
|
|
180
|
+
mainwpcontrol abilities list
|
|
181
|
+
|
|
182
|
+
# Filter by category
|
|
183
|
+
mainwpcontrol abilities list --category sites
|
|
184
|
+
|
|
185
|
+
# Get full details and input schema for an ability
|
|
186
|
+
mainwpcontrol abilities info list-sites-v1
|
|
187
|
+
|
|
188
|
+
# Run an ability
|
|
189
|
+
mainwpcontrol abilities run list-sites-v1 --json
|
|
190
|
+
|
|
191
|
+
# Run with input parameters
|
|
192
|
+
mainwpcontrol abilities run get-site-v1 --input '{"site_id": 1}' --json
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Profiles
|
|
196
|
+
|
|
197
|
+
Each `mainwpcontrol login` creates a profile, a named connection to a Dashboard, identified by hostname. If you manage multiple Dashboards, run `login` once per Dashboard to create a profile for each.
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# List all profiles
|
|
201
|
+
mainwpcontrol profile list
|
|
202
|
+
|
|
203
|
+
# Switch active profile
|
|
204
|
+
mainwpcontrol profile use production.example.com
|
|
205
|
+
|
|
206
|
+
# Use a profile for one command without switching
|
|
207
|
+
mainwpcontrol abilities list --profile staging.example.com
|
|
208
|
+
|
|
209
|
+
# Delete a profile and its keychain credentials
|
|
210
|
+
mainwpcontrol profile delete staging.example.com
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Diagnostics
|
|
214
|
+
|
|
215
|
+
`doctor` checks your configuration, credentials, and Dashboard connectivity. Run it first if something isn't working.
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
# Check configuration and connectivity
|
|
219
|
+
mainwpcontrol doctor
|
|
220
|
+
|
|
221
|
+
# Verbose output
|
|
222
|
+
mainwpcontrol doctor -v
|
|
223
|
+
|
|
224
|
+
# JSON output
|
|
225
|
+
mainwpcontrol doctor --json
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Chat Mode
|
|
229
|
+
|
|
230
|
+
If you have an LLM API key, you can talk to your Dashboard in plain English instead of constructing commands. Good for exploration, not required for anything.
|
|
231
|
+
|
|
232
|
+
Set one of these environment variables to enable it:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# Pick one (Anthropic, OpenAI, Google, or OpenRouter)
|
|
236
|
+
export ANTHROPIC_API_KEY='sk-ant-...'
|
|
237
|
+
|
|
238
|
+
mainwpcontrol chat
|
|
239
|
+
mainwpcontrol chat "list all sites with pending updates"
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
See [Chat Mode Configuration](#chat-mode-configuration) for all supported providers and flags.
|
|
243
|
+
|
|
244
|
+
### Global Flags
|
|
245
|
+
|
|
246
|
+
These flags work on every command.
|
|
247
|
+
|
|
248
|
+
| Flag | Description |
|
|
249
|
+
|------|-------------|
|
|
250
|
+
| `--json` | Structured JSON output |
|
|
251
|
+
| `--quiet` / `-q` | Suppress output (exit code only) |
|
|
252
|
+
| `--profile <name>` | Use a specific profile |
|
|
253
|
+
| `--debug` | Show redacted debug diagnostics on stderr |
|
|
254
|
+
| `--help` | Show help |
|
|
255
|
+
|
|
256
|
+
### Abilities Run Flags
|
|
257
|
+
|
|
258
|
+
Extra flags for `abilities run`. These control input, safety checks, and batch job behavior.
|
|
259
|
+
|
|
260
|
+
| Flag | Description |
|
|
261
|
+
|------|-------------|
|
|
262
|
+
| `--input` / `-i` | Input parameters as JSON (use `-` for stdin) |
|
|
263
|
+
| `--input-file` | Read input from a JSON file |
|
|
264
|
+
| `--dry-run` | Preview changes without executing |
|
|
265
|
+
| `--confirm` | Execute a destructive ability |
|
|
266
|
+
| `--force` | Skip interactive confirmation (CI mode) |
|
|
267
|
+
| `--wait` | Block until batch job completes |
|
|
268
|
+
| `--wait-timeout` | Max seconds to wait (default: 300) |
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Concepts
|
|
273
|
+
|
|
274
|
+
### Abilities
|
|
275
|
+
|
|
276
|
+
Abilities are the operations your MainWP Dashboard exposes through its REST API. Each one has:
|
|
277
|
+
|
|
278
|
+
- A versioned name (e.g., `list-sites-v1`, `delete-site-v1`)
|
|
279
|
+
- An input schema (what parameters it accepts)
|
|
280
|
+
- Annotations that tell you what kind of operation it is
|
|
281
|
+
|
|
282
|
+
The annotations matter:
|
|
283
|
+
- **Readonly**: Safe to run anytime. Cannot modify data.
|
|
284
|
+
- **Destructive**: Permanently changes or deletes data. Requires `--dry-run` preview, then `--confirm` to execute.
|
|
285
|
+
- **Idempotent**: Safe to re-run. Same result on repeated calls.
|
|
286
|
+
|
|
287
|
+
Run `mainwpcontrol abilities info <name>` to see the full schema and annotations for any ability.
|
|
288
|
+
|
|
289
|
+
### Profiles
|
|
290
|
+
|
|
291
|
+
A profile is a named connection to a MainWP Dashboard. It stores the Dashboard URL and username. Your password stays in the OS keychain (or in the `MAINWP_APP_PASSWORD` environment variable when no keychain is available).
|
|
292
|
+
|
|
293
|
+
Running `mainwpcontrol login` creates a profile automatically, named after the Dashboard hostname:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
# Creates profile "staging.example.com"
|
|
297
|
+
mainwpcontrol login --url https://staging.example.com --username admin
|
|
298
|
+
|
|
299
|
+
# Creates profile "production.example.com"
|
|
300
|
+
mainwpcontrol login --url https://production.example.com --username admin
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
The profile file at `~/.config/mainwpcontrol/profiles.json` never contains passwords.
|
|
304
|
+
|
|
305
|
+
### Safety Model
|
|
306
|
+
|
|
307
|
+
Destructive operations follow a two-step pattern: preview first, then execute.
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
# Step 1: Preview (nothing changes)
|
|
311
|
+
mainwpcontrol abilities run delete-site-v1 \
|
|
312
|
+
--input '{"site_id_or_domain": "mysite.com"}' \
|
|
313
|
+
--dry-run --json
|
|
314
|
+
|
|
315
|
+
# Step 2: Execute after reviewing the preview
|
|
316
|
+
mainwpcontrol abilities run delete-site-v1 \
|
|
317
|
+
--input '{"site_id_or_domain": "mysite.com"}' \
|
|
318
|
+
--confirm --force --json
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
`--dry-run` and `--confirm` are mutually exclusive. You cannot pass both.
|
|
322
|
+
|
|
323
|
+
In CI/scripted workflows where you've already validated the operation, pass `--confirm --force` directly to skip the interactive prompt.
|
|
324
|
+
|
|
325
|
+
### Batch Jobs
|
|
326
|
+
|
|
327
|
+
Operations that affect many items (200+) are automatically queued as batch jobs. The command returns a `job_id` immediately, and you can watch progress:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
mainwpcontrol jobs watch <job-id>
|
|
331
|
+
|
|
332
|
+
# With a timeout
|
|
333
|
+
mainwpcontrol jobs watch <job-id> --timeout 120
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
Or use `--wait` on the original command to block until completion:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
mainwpcontrol abilities run sync-sites-v1 --wait --wait-timeout 300 --json
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Advanced Usage
|
|
345
|
+
|
|
346
|
+
### CI/CD Patterns
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
# Non-interactive login
|
|
350
|
+
export MAINWP_APP_PASSWORD='xxxx xxxx xxxx xxxx xxxx xxxx'
|
|
351
|
+
mainwpcontrol login --url https://dashboard.example.com --username admin
|
|
352
|
+
|
|
353
|
+
# Silent execution with exit codes
|
|
354
|
+
mainwpcontrol abilities run list-sites-v1 --json --quiet
|
|
355
|
+
echo "Exit code: $?"
|
|
356
|
+
|
|
357
|
+
# Pipeline branching on exit codes
|
|
358
|
+
if mainwpcontrol abilities run check-sites-v1 --json --quiet; then
|
|
359
|
+
echo "All sites healthy"
|
|
360
|
+
else
|
|
361
|
+
echo "Issues detected"
|
|
362
|
+
fi
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Input from Files and Stdin
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
# From a JSON file
|
|
369
|
+
mainwpcontrol abilities run update-site-plugins-v1 --input-file params.json --json
|
|
370
|
+
|
|
371
|
+
# From stdin
|
|
372
|
+
echo '{"site_id": 1}' | mainwpcontrol abilities run get-site-v1 --input - --json
|
|
373
|
+
|
|
374
|
+
# Heredoc
|
|
375
|
+
mainwpcontrol abilities run get-site-v1 --input - --json <<EOF
|
|
376
|
+
{"site_id": 1}
|
|
377
|
+
EOF
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Chat Mode Configuration
|
|
381
|
+
|
|
382
|
+
Chat requires one of these environment variables:
|
|
383
|
+
|
|
384
|
+
| Variable | Provider |
|
|
385
|
+
|----------|----------|
|
|
386
|
+
| `ANTHROPIC_API_KEY` | Anthropic Claude |
|
|
387
|
+
| `OPENAI_API_KEY` | OpenAI GPT |
|
|
388
|
+
| `GOOGLE_API_KEY` | Google Gemini |
|
|
389
|
+
| `OPENROUTER_API_KEY` | OpenRouter |
|
|
390
|
+
| `LOCAL_LLM_API_KEY` | Local LLM (with optional `LOCAL_LLM_URL`) |
|
|
391
|
+
|
|
392
|
+
Additional chat flags: `--provider`, `--model`, `--max-turns`, `--max-context-messages`, `--no-stream`.
|
|
393
|
+
|
|
394
|
+
In non-TTY environments (pipes, CI), `mainwpcontrol chat` without a message argument exits with guidance instead of hanging.
|
|
395
|
+
|
|
396
|
+
### Shell Completion
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
# Bash
|
|
400
|
+
source /path/to/mainwp-control/scripts/completions/mainwpcontrol.bash
|
|
401
|
+
|
|
402
|
+
# Zsh
|
|
403
|
+
source /path/to/mainwp-control/scripts/completions/mainwpcontrol.zsh
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Configuration File
|
|
407
|
+
|
|
408
|
+
Settings live at `~/.config/mainwpcontrol/settings.json`:
|
|
409
|
+
|
|
410
|
+
```json
|
|
411
|
+
{
|
|
412
|
+
"defaultJsonOutput": true,
|
|
413
|
+
"timeout": 30000,
|
|
414
|
+
"debug": false,
|
|
415
|
+
"llmProvider": "openai",
|
|
416
|
+
"chatContextMessages": 20
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Workflow Guides
|
|
421
|
+
|
|
422
|
+
Step-by-step guides for common automation patterns:
|
|
423
|
+
|
|
424
|
+
| Workflow | Description |
|
|
425
|
+
|----------|-------------|
|
|
426
|
+
| [Daily Health Check](docs/workflows/daily-health-check.md) | Cron job that checks site connectivity and alerts via Slack |
|
|
427
|
+
| [Plugin Deployment Verification](docs/workflows/plugin-deployment-verification.md) | GitHub Actions workflow to verify a plugin exists across all sites |
|
|
428
|
+
| [Monthly Batch Updates](docs/workflows/monthly-batch-updates.md) | Preview and apply updates safely, scripted and GitHub Actions variants |
|
|
429
|
+
| [Input from File](docs/workflows/input-from-file.md) | Pass complex parameters via JSON files, stdin pipes, or heredocs |
|
|
430
|
+
| [Monitoring Integration](docs/workflows/monitoring-integration.md) | Send site metrics to Datadog, StatsD, or other monitoring tools |
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## Reference
|
|
435
|
+
|
|
436
|
+
### Exit Codes
|
|
437
|
+
|
|
438
|
+
| Code | Meaning | CI Usage |
|
|
439
|
+
|------|---------|----------|
|
|
440
|
+
| 0 | Success | Continue pipeline |
|
|
441
|
+
| 1 | User/input error | Fix command syntax |
|
|
442
|
+
| 2 | Auth/config error | Check credentials |
|
|
443
|
+
| 3 | Network error | Retry or check connectivity |
|
|
444
|
+
| 4 | API error | Check ability parameters |
|
|
445
|
+
| 5 | Internal error | Report bug |
|
|
446
|
+
|
|
447
|
+
### Environment Variables
|
|
448
|
+
|
|
449
|
+
#### MainWP Configuration
|
|
450
|
+
|
|
451
|
+
| Variable | Description |
|
|
452
|
+
|----------|-------------|
|
|
453
|
+
| `MAINWP_APP_PASSWORD` | Application password for non-interactive login and commands when keychain is unavailable |
|
|
454
|
+
| `MAINWPCONTROL_NO_KEYTAR` | Set to `1` to skip keytar (keychain) loading entirely |
|
|
455
|
+
| `MAINWP_ALLOW_HTTP` | Set to `1` to allow insecure HTTP Dashboard URLs |
|
|
456
|
+
|
|
457
|
+
#### Chat/LLM Configuration
|
|
458
|
+
|
|
459
|
+
| Variable | Description |
|
|
460
|
+
|----------|-------------|
|
|
461
|
+
| `ANTHROPIC_API_KEY` | Anthropic Claude |
|
|
462
|
+
| `OPENAI_API_KEY` | OpenAI GPT |
|
|
463
|
+
| `GOOGLE_API_KEY` | Google Gemini |
|
|
464
|
+
| `OPENROUTER_API_KEY` | OpenRouter |
|
|
465
|
+
| `LOCAL_LLM_API_KEY` | Local LLM provider (required to enable local provider) |
|
|
466
|
+
| `LOCAL_LLM_URL` | Local endpoint URL (optional, defaults to localhost) |
|
|
467
|
+
| `MAINWP_LLM_PROVIDER` | Override auto-detected provider |
|
|
468
|
+
| `MAINWP_LLM_MODEL` | Specify model to use |
|
|
469
|
+
|
|
470
|
+
### Configuration Settings
|
|
471
|
+
|
|
472
|
+
All settings in `~/.config/mainwpcontrol/settings.json`:
|
|
473
|
+
|
|
474
|
+
| Setting | Type | Description |
|
|
475
|
+
|---------|------|-------------|
|
|
476
|
+
| `defaultJsonOutput` | boolean | Default to JSON output |
|
|
477
|
+
| `timeout` | number | HTTP request timeout in milliseconds |
|
|
478
|
+
| `debug` | boolean | Enable debug output |
|
|
479
|
+
| `llmProvider` | string | Default LLM provider for chat |
|
|
480
|
+
| `chatContextMessages` | number | Max messages in chat context |
|
|
481
|
+
| `skipSSLVerification` | boolean | Disable TLS verification (insecure, prefer per-profile setting via `login --skip-ssl-verify`) |
|
|
482
|
+
| `allowInsecureHttp` | boolean | Allow `http://` Dashboard URLs without `MAINWP_ALLOW_HTTP=1` |
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## Troubleshooting
|
|
487
|
+
|
|
488
|
+
<details>
|
|
489
|
+
<summary><strong>"keytar failed to build" or native module errors during install</strong></summary>
|
|
490
|
+
|
|
491
|
+
Keytar requires native C++ compilation on some platforms. If it fails:
|
|
492
|
+
|
|
493
|
+
1. **Use environment variable auth instead** (bypasses keytar entirely):
|
|
494
|
+
```bash
|
|
495
|
+
export MAINWP_APP_PASSWORD='your-application-password'
|
|
496
|
+
mainwpcontrol login --url https://dashboard.example.com --username admin
|
|
497
|
+
```
|
|
498
|
+
2. **Or skip keytar explicitly** by setting `MAINWPCONTROL_NO_KEYTAR=1` before running commands.
|
|
499
|
+
|
|
500
|
+
The pre-built binaries cover macOS, Windows, and Linux (x64/arm64). If you're on a different platform or architecture, you'll need C++ build tools (`gcc`, `g++`, `make`) or the env var approach.
|
|
501
|
+
|
|
502
|
+
</details>
|
|
503
|
+
|
|
504
|
+
<details>
|
|
505
|
+
<summary><strong>"command not found" after install</strong></summary>
|
|
506
|
+
|
|
507
|
+
This usually means your npm global bin directory isn't in your system PATH.
|
|
508
|
+
|
|
509
|
+
1. **Find where npm installs global packages:**
|
|
510
|
+
```bash
|
|
511
|
+
npm config get prefix
|
|
512
|
+
```
|
|
513
|
+
2. **Add the `bin` subdirectory to your PATH.** For example, if the prefix is `/usr/local`:
|
|
514
|
+
```bash
|
|
515
|
+
# Add to ~/.bashrc, ~/.zshrc, or your shell profile:
|
|
516
|
+
export PATH="/usr/local/bin:$PATH"
|
|
517
|
+
```
|
|
518
|
+
3. **Restart your terminal** (or run `source ~/.zshrc` / `source ~/.bashrc`) and try again.
|
|
519
|
+
|
|
520
|
+
On Windows, the npm global directory is usually already in PATH after installing Node.js.
|
|
521
|
+
|
|
522
|
+
</details>
|
|
523
|
+
|
|
524
|
+
<details>
|
|
525
|
+
<summary><strong>"connection refused" or network errors</strong></summary>
|
|
526
|
+
|
|
527
|
+
If `mainwpcontrol login` or commands fail with connection errors:
|
|
528
|
+
|
|
529
|
+
1. **Check the Dashboard URL.** Make sure it's the full URL with `https://` (e.g., `https://dashboard.example.com`). Don't include a trailing slash.
|
|
530
|
+
2. **Verify HTTPS.** `mainwpcontrol` requires HTTPS by default. If your Dashboard uses HTTP (not recommended), set `MAINWP_ALLOW_HTTP=1`.
|
|
531
|
+
3. **Check firewall/network.** Make sure your machine can reach the Dashboard:
|
|
532
|
+
```bash
|
|
533
|
+
curl -I https://dashboard.example.com
|
|
534
|
+
```
|
|
535
|
+
4. **SSL certificate issues.** If using a self-signed certificate, you can use `mainwpcontrol login --skip-ssl-verify` (not recommended for production).
|
|
536
|
+
|
|
537
|
+
</details>
|
|
538
|
+
|
|
539
|
+
---
|
|
540
|
+
|
|
541
|
+
## Contributing
|
|
542
|
+
|
|
543
|
+
```bash
|
|
544
|
+
npm run build # Build the project
|
|
545
|
+
npm test # Run tests (unit + e2e, no network needed)
|
|
546
|
+
npm run lint # Check code style
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### Live Integration Tests
|
|
550
|
+
|
|
551
|
+
`npm run test:live` runs tests against a real MainWP Dashboard, including workflow documentation validation. These require a running Dashboard and credentials:
|
|
552
|
+
|
|
553
|
+
```bash
|
|
554
|
+
export MAINWP_API_URL=https://your-dashboard.example.com
|
|
555
|
+
export MAINWP_USER=your-admin-username
|
|
556
|
+
export MAINWP_APP_PASSWORD=your-application-password
|
|
557
|
+
|
|
558
|
+
npm run test:live
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
The live suite includes API tests (login, abilities discovery, read-only execution, safety model, exit codes) and workflow doc tests (validates that every jq expression, field name, and data pipeline documented in `docs/workflows/` works against the real API).
|
|
562
|
+
|
|
563
|
+
Live tests are safe: they only run read-only operations and `--dry-run` previews, never mutations.
|
|
564
|
+
|
|
565
|
+
---
|
|
566
|
+
|
|
567
|
+
## License
|
|
568
|
+
|
|
569
|
+
GPL-3.0-or-later
|
|
570
|
+
|
|
571
|
+
---
|
|
572
|
+
|
|
573
|
+
## Requirements
|
|
574
|
+
|
|
575
|
+
- Node.js 20 LTS or later
|
|
576
|
+
- MainWP Dashboard 6+ with Abilities API
|
|
577
|
+
- WordPress Application Password
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
- [MainWP](https://mainwp.com/)
|
|
582
|
+
- [MainWP MCP Server](https://github.com/mainwp/mainwp-mcp)
|
|
583
|
+
- [Issue Tracker](https://github.com/mainwp/mainwp-control/issues)
|
package/bin/_exit.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Shared entrypoint setup: SIGPIPE handling and clean exit for native addons.
|
|
2
|
+
|
|
3
|
+
// SIGPIPE: exit cleanly when piped to `head`, `grep -q`, etc.
|
|
4
|
+
process.on('SIGPIPE', () => process.exit(0));
|
|
5
|
+
|
|
6
|
+
// Force exit to prevent native addon handles (e.g. keytar) from keeping
|
|
7
|
+
// the process alive. Drain stdout/stderr first to avoid truncating piped output.
|
|
8
|
+
const drain = (s) => new Promise((resolve) => s.write('', resolve));
|
|
9
|
+
export async function drainAndExit() {
|
|
10
|
+
await Promise.all([drain(process.stdout), drain(process.stderr)]);
|
|
11
|
+
process.exit(process.exitCode ?? 0);
|
|
12
|
+
}
|
package/bin/dev.js
ADDED