@instawp/cli 0.0.1-beta.2 → 0.0.1-beta.21

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +203 -0
  2. package/README.md +151 -17
  3. package/dist/commands/db.d.ts +2 -0
  4. package/dist/commands/db.js +305 -0
  5. package/dist/commands/db.js.map +1 -0
  6. package/dist/commands/exec.js +62 -3
  7. package/dist/commands/exec.js.map +1 -1
  8. package/dist/commands/local.js +514 -123
  9. package/dist/commands/local.js.map +1 -1
  10. package/dist/commands/login.js +23 -7
  11. package/dist/commands/login.js.map +1 -1
  12. package/dist/commands/logs.d.ts +2 -0
  13. package/dist/commands/logs.js +239 -0
  14. package/dist/commands/logs.js.map +1 -0
  15. package/dist/commands/open.d.ts +2 -0
  16. package/dist/commands/open.js +114 -0
  17. package/dist/commands/open.js.map +1 -0
  18. package/dist/commands/sites.js +240 -2
  19. package/dist/commands/sites.js.map +1 -1
  20. package/dist/commands/sync.js +6 -3
  21. package/dist/commands/sync.js.map +1 -1
  22. package/dist/commands/versions.d.ts +2 -0
  23. package/dist/commands/versions.js +324 -0
  24. package/dist/commands/versions.js.map +1 -0
  25. package/dist/index.js +49 -8
  26. package/dist/index.js.map +1 -1
  27. package/dist/lib/local-env.d.ts +31 -0
  28. package/dist/lib/local-env.js +60 -13
  29. package/dist/lib/local-env.js.map +1 -1
  30. package/dist/lib/local-instance.d.ts +43 -0
  31. package/dist/lib/local-instance.js +60 -0
  32. package/dist/lib/local-instance.js.map +1 -0
  33. package/dist/lib/output.js +14 -1
  34. package/dist/lib/output.js.map +1 -1
  35. package/dist/lib/paths.d.ts +22 -0
  36. package/dist/lib/paths.js +41 -0
  37. package/dist/lib/paths.js.map +1 -0
  38. package/dist/lib/sftp-sync.d.ts +35 -0
  39. package/dist/lib/sftp-sync.js +290 -0
  40. package/dist/lib/sftp-sync.js.map +1 -0
  41. package/dist/lib/site-resolver.js +25 -3
  42. package/dist/lib/site-resolver.js.map +1 -1
  43. package/dist/lib/sqlite-to-mysql.d.ts +47 -0
  44. package/dist/lib/sqlite-to-mysql.js +133 -0
  45. package/dist/lib/sqlite-to-mysql.js.map +1 -0
  46. package/dist/lib/ssh-connection.d.ts +11 -0
  47. package/dist/lib/ssh-connection.js +99 -3
  48. package/dist/lib/ssh-connection.js.map +1 -1
  49. package/dist/lib/ssh-keys.js +12 -5
  50. package/dist/lib/ssh-keys.js.map +1 -1
  51. package/dist/lib/windows-binaries.d.ts +10 -0
  52. package/dist/lib/windows-binaries.js +34 -0
  53. package/dist/lib/windows-binaries.js.map +1 -0
  54. package/dist/types.d.ts +14 -0
  55. package/package.json +12 -3
  56. package/vendor/win32/NOTICE.md +31 -0
  57. package/vendor/win32/busybox.exe +0 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,203 @@
1
+ # Changelog
2
+
3
+ ## 0.0.1-beta.21 (2026-06-04)
4
+
5
+ ### Fixed — `local push --with-db` broke wp-admin on sites with a custom table prefix
6
+ - After a DB push, wp-admin became inaccessible on sites whose cloud table prefix isn't `wp_` (which is **most** InstaWP sites — they use a random prefix like `iwpa797_`). WordPress stores roles/capabilities under the table prefix (`{prefix}capabilities`, `{prefix}user_level` in usermeta; `{prefix}user_roles` in options). The local Playground DB is normalized to `wp_`, so the imported keys were `wp_capabilities` etc. — which the cloud (looking for `iwpa797_capabilities`) ignored, leaving the admin with no capabilities.
7
+ - **Fix**: after import, `local push --with-db` now remaps those access-critical keys to the cloud's prefix (exact key names only — never touches plugin options). Verified end-to-end on a real custom-prefix site (admin role resolves, wp-admin accessible). If you hit this on beta.20, restore the cloud DB from the `~/db-backup-*.sql.gz` the push saved, update to beta.21, and re-push.
8
+
9
+ ## 0.0.1-beta.20 (2026-06-03)
10
+
11
+ ### Added — `local push --with-db` (push the database back to the cloud)
12
+ - `instawp local push <local>` was **files-only** (it synced `wp-content` but not the database), so content changes — new pages, posts, settings — never reached the cloud. New **`--with-db`** flag also pushes the local Playground database, OVERWRITING the cloud MySQL.
13
+ - How it works: backs up the cloud DB first (`--no-backup` to skip), converts the local SQLite to MySQL **data-only** (reuses the cloud's existing schema — no fragile type-mapping), imports it, and runs a serialization-safe `wp search-replace` to fix local→cloud URLs. Only tables present on both sides are synced; local-only tables (e.g. a plugin's tables created after cloning) are reported and skipped. `--dry-run` previews with zero cloud writes; `--force` skips the confirmation; `--json` requires `--force`.
14
+ - A plain `local push` now prints a one-line reminder that the database wasn't pushed (use `--with-db`).
15
+ - Validated end-to-end against a real InstaWP site (clone → add page → push --with-db → page + correct URLs on cloud). There is no official WordPress SQLite→MySQL exporter ([sqlite-database-integration#36](https://github.com/WordPress/sqlite-database-integration/issues/36)); this is a self-contained, data-safe implementation.
16
+
17
+ ## 0.0.1-beta.19 (2026-06-03)
18
+
19
+ ### Fixed — `local push` after `local clone` created a new site instead of pushing back
20
+ - A cloned instance didn't remember which cloud site it came from, so `instawp local push <local>` (with no cloud-site argument) fell into the "create a new site" path and provisioned a **new** site named after the local instance — instead of pushing to the original. `local clone` now records the origin (`cloudSiteId`) on the instance, and `local push` targets it by default (explicit arg → cloned origin → otherwise create). Pushing with an explicit cloud site once also backfills the link on instances cloned before this fix.
21
+ - **Also fixed** the cloned instance name: `local clone` derived it from the full domain, so `client-store-1234.instawp.site` became `client-store-1234-instawp-site`. It now uses the site name, or the first DNS label of the subdomain (`client-store-1234`).
22
+
23
+ ## 0.0.1-beta.18 (2026-06-03)
24
+
25
+ ### Fixed — `local push --dry-run` provisioned a real cloud site
26
+ - `instawp local push <name> --dry-run` with no cloud-site argument ran the "create a cloud site" path — so a dry run **provisioned a real, permanent cloud site**, then tried to connect to its not-yet-resolvable hostname and failed with `connect: Address lookup failed for host` / `rsync exited with code 1`. (Reported by QA on Windows; the bug was cross-platform.)
27
+ - **Fix**: a dry run is now side-effect free. With no cloud site specified, it previews the local `wp-content` files that *would* be pushed (a pure local filesystem walk respecting the same excludes — no provisioning, no network) and reports that no site was created. Passing an existing cloud site (`local push <name> <site> --dry-run`) is unchanged.
28
+
29
+ ## 0.0.1-beta.17 (2026-06-02)
30
+
31
+ ### Fixed — `local start` / `local create` mount failure on Windows
32
+ - On Windows, `instawp local start` (and `local create`) failed with `Invalid mount format: C:\...\wp-content:/wordpress/wp-content`. wp-playground-cli's `--mount=<host>:<vfs>` splits the value on `:`, and a Windows host path's drive-letter colon (`C:\...`) produced 3+ parts, so Playground rejected the mount.
33
+ - **Fix**: on Windows the CLI now uses Playground's `--mount-dir` / `--mount-dir-before-install` flags, which take the host and vfs paths as two separate arguments (no colon to split). Applies to fresh sites, cloned-site subdirectory mounts, and individual file mounts. macOS/Linux keep the existing `--mount=<host>:<vfs>` form unchanged. (Reported by QA on Windows; `@wp-playground/cli` ≥ the version exposing `--mount-dir`.)
34
+
35
+ ## 0.0.1-beta.16 (2026-06-02)
36
+
37
+ ### Changed — renamed `snapshot` → `versions`
38
+ - The command added in beta.15 is now **`instawp versions create|list|restore|delete`** (alias `version`). Renamed from `snapshot` to avoid confusion with InstaWP's separate **Snapshots** product — these are a site's restorable **versions**. Same flags and behavior; only the command name changed.
39
+
40
+ ## 0.0.1-beta.15 (2026-06-01)
41
+
42
+ ### Added — `snapshot` command (restorable site versions)
43
+ - New `instawp snapshot create|list|restore|delete` (alias `snapshots`) for managing **site snapshots** — InstaWP's restorable "site versions", point-in-time copies of a site's files + database. Unlike backups, a snapshot can be rolled back to **in-place**.
44
+ - Built for the AI-agent workflow: take a snapshot *before* letting an agent run a batch of changes, then roll back the one that broke it in a single command.
45
+ - `snapshot create <site> [--name <label>] [--no-wait]` — waits for the snapshot to finish by default; `--no-wait` returns as soon as it's queued.
46
+ - `snapshot list <site>` — ID, name, size, status, and creation date.
47
+ - `snapshot restore <site> <version-id> [--force] [--no-wait]` — **overwrites** the live site's files + database; prompts for confirmation unless `--force`.
48
+ - `snapshot delete <site> <version-id...> [--force]`.
49
+ - All subcommands support `--json`. Long-running create/restore poll task status with a progress spinner.
50
+
51
+ ## 0.0.1-beta.14 (2026-05-28)
52
+
53
+ ### Improved — clearer first-run for `local` commands
54
+ - When `local create/start/clone` falls back to `npx` (no global `wp-playground-cli`), the CLI now prints a one-time dim hint explaining the first-run download (~30s) and how to skip it on future runs (`npm i -g @wp-playground/cli`). Previously users just saw npm's raw download output with no context. Shown once per run, on stderr, and suppressed in `--json` mode.
55
+
56
+ ## 0.0.1-beta.13 (2026-05-28)
57
+
58
+ ### Fixed — `wp` / `exec` site resolution (issue #3)
59
+ - `instawp wp <site>` / `instawp exec <site>` could fail to resolve a site by name with "No site found" (or, on older builds, hang at "Resolving site…") on accounts where the `/sites` list didn't return the site in a single `per_page=100` page.
60
+ - **Fix**: `resolveSite` now paginates the `/sites` endpoint (`per_page=20`, walking `meta.last_page`) instead of relying on one large page. This is robust for accounts with 100+ sites and resilient to environments where the API returns fewer rows than requested for large `per_page` values. Matches how `sites list` paginates.
61
+
62
+ ## 0.0.1-beta.12 (2026-05-26)
63
+
64
+ ### Fixed — `local create/start/clone` on Windows (`spawn npx ENOENT`)
65
+ - WordPress Playground launch failed on Windows with `spawn npx ENOENT`. On Windows `npx`/`wp-playground-cli` are `.cmd` shims, and Node refuses to spawn `.cmd` without `shell: true` (since the CVE-2024-27980 fix) — so the bare `spawn('npx', …)` failed.
66
+ - **Fix**: route the Playground spawns through `cross-spawn`, which resolves `.cmd` shims and quotes arguments (e.g. `--mount` paths with spaces) safely. macOS/Linux behavior is unchanged.
67
+
68
+ ## 0.0.1-beta.11 (2026-05-26)
69
+
70
+ ### Improved — parallel SFTP transfers on Windows
71
+ - Windows file sync now transfers files across a **pool of parallel SSH connections** instead of one-at-a-time. Measured ~2.9× speedup (a 238-file wp-content pull dropped from ~369s to ~129s).
72
+ - Concurrency defaults to 4, configurable via `INSTAWP_SFTP_CONCURRENCY` (capped at 8).
73
+ - Two-phase design: a single control connection walks the tree and pre-creates directories, then files transfer in parallel. Per-file errors are collected and reported without aborting the whole sync.
74
+
75
+ ## 0.0.1-beta.10 (2026-05-26)
76
+
77
+ ### Fixed — Windows file sync now works
78
+ - `instawp sync push/pull`, `local push/pull`, and `local clone` failed on Windows with `rsync: connection unexpectedly closed (0 bytes)` + `sigpacket: Suppressing signal 30 to win32 process`. Root cause: the bundled **msys2 rsync.exe couldn't drive native Windows OpenSSH** (incompatible pipe/signal semantics). The DLL "entry point" fix in beta.6 got rsync.exe to *load*, but the SSH transport still died instantly.
79
+ - **Fix**: Windows now transfers files over a **pure-JS SFTP client** (`ssh2-sftp-client`) instead of rsync-over-ssh. macOS/Linux are unchanged (still rsync, with delta sync). New `syncFiles()` dispatcher picks the transport per-platform.
80
+
81
+ ### Changed
82
+ - **Removed `rsync.exe` + all msys2 runtime DLLs from the bundle** (~11 MB). The Windows bundle is now just `busybox.exe` (660 KB, statically linked, for the `mysql2sqlite` awk step in `local clone`). Total package shrinks accordingly.
83
+ - SFTP transfer honors the same exclude/include patterns as the rsync paths (`.git`, `node_modules`, `cache`, `backup*`, etc.).
84
+
85
+ ### Trade-off
86
+ - SFTP does full-file copy (no rsync delta algorithm). Fine for typical wp-content; repeat syncs of large sites are slower than rsync on macOS/Linux. We chose this over bundling an msys ssh (which would have dragged in the ~3.5 MB Heimdal/Kerberos DLL chain).
87
+
88
+ ## 0.0.1-beta.9 (2026-05-23)
89
+
90
+ ### Internals
91
+ - CI smoke test now verifies the bundle by extracting the packed tarball directly (via `tar -xzf`) and running `rsync.exe` from the extract dir. Replaces the `npm install -g` step, which was failing on the GHA Windows runner due to Defender quarantine interactions (tamper protection prevented our exclusion settings from taking effect). Real-user installs are not affected — Defender on individual developer machines is configurable and the first reported Windows install showed the bundle landing at the correct path.
92
+
93
+ ## 0.0.1-beta.8 (2026-05-23)
94
+
95
+ ### Bug Fixes (Windows)
96
+ - Moved bundled Windows binaries from `bin/win32/` to `vendor/win32/`. With `bin/` and the `bin` field in package.json both set, npm's global install on Windows dropped the `bin/win32/` subdirectory — leaving the CLI unable to find rsync.exe at runtime. macOS/Linux installs were unaffected. Renaming sidesteps the collision entirely.
97
+
98
+ ## 0.0.1-beta.7 (2026-05-23)
99
+
100
+ ### Internals
101
+ - Smoke-windows CI job now runs the bundled `rsync.exe` and `busybox.exe` directly from the workspace bundle **before** the npm-install step, so a passing smoke test proves the DLL chain is correct independent of whether antivirus interferes with the global install path.
102
+ - Adds Windows Defender exclusions before `npm i -g` to prevent msys DLLs from being quarantined during install.
103
+ - Publish job now skips on `workflow_dispatch` (manual triggers), so maintainers can re-test the smoke job without bumping the version.
104
+
105
+ ## 0.0.1-beta.6 (2026-05-23)
106
+
107
+ ### Bug Fixes (Windows)
108
+ - Bundled `rsync.exe` now actually loads. beta.4/beta.5 shipped with `msys-2.0.dll` from the legacy `msys2-runtime-3.3` fork, which is missing the `fallocate` symbol that rsync 3.4 needs — produced `Entry Point Not Found: fallocate` on launch and exit code `3221225785` (`STATUS_DLL_INIT_FAILED`) when invoked indirectly via `sync push/pull` or `local clone`.
109
+ - Rebuilt the Windows bundle against current MSYS2 packages: `msys2-runtime-3.6.9-1`, `libopenssl-3.6.2-1`, `libiconv-1.19-1`, `libxxhash-0.8.3-1`, `libzstd-1.5.7-1`, `popt-1.19-1`, `libintl-0.22.5-1`. Includes `msys-popt-0.dll` and `msys-intl-8.dll` which the newer rsync now requires.
110
+ - Upgraded bundled rsync from 3.4.0 → 3.4.2-2.
111
+
112
+ ### Internals
113
+ - `scripts/fetch-windows-binaries.sh` now verifies DLL closure (every referenced `msys-*.dll` is present) and asserts `fallocate` is exported from `msys-2.0.dll` before declaring the bundle valid. Catches "wrong runtime fork" regressions at build time.
114
+ - Added `smoke-windows` job to the publish workflow — runs on `windows-latest` and actually executes the bundled `rsync.exe` and `busybox.exe` before npm publish. Publish is now gated on this passing.
115
+
116
+ ## 0.0.1-beta.5 (2026-05-23)
117
+
118
+ ### New Commands
119
+ - `db push <site> <file>` — Push a local SQL dump (`.sql` or `.sql.gz`) to the remote MySQL database. Always backs up the remote DB to `~/db-backup-{ISO}.sql.gz` first (skip with `--no-backup`). Confirmation prompt unless `--force`. Closes the #1 gap blocking full-site deploys from the CLI.
120
+ - `db pull <site>` — Stream the remote MySQL database to a local gzipped dump. `--output <path>` and `--no-compress` flags.
121
+ - `open <site>` — Open the site URL in the default browser. `--admin` opens `/wp-admin`, `--magic` opens the Magic Login URL, `--print` pipes the URL to stdout instead.
122
+ - `logs <site>` — Tail logs via SSH. `--wp` (default, debug.log), `--php` (PHP-FPM error log), `--nginx` (nginx error log), `--follow` / `-f`, `--lines <n>`. Multiple flags multi-tail. Probes HestiaCP path variations automatically.
123
+ - `sites creds <site>` — Re-fetch WP admin credentials + Magic Login URL for an existing site (previously only available in the `create` output).
124
+
125
+ ### Improvements
126
+ - `wp <site>` is now positioned as the primary remote-access command; `exec` is documented as the escape hatch for non-WP shell commands.
127
+ - `wp` / `exec` accept POSIX `--` to forward raw args verbatim: `instawp wp my-site -- post list --post_type=page`.
128
+ - Spinners are suppressed in non-TTY contexts, CI environments (`CI` env var), `--json` mode, `NO_COLOR`, and `INSTAWP_QUIET` — fixes "Resolving site..." leaking into piped output.
129
+
130
+ ### Bug Fixes
131
+ - `instawp wp <site> eval '...'` no longer breaks on parens, quotes, or other shell metacharacters. Each arg is now POSIX shell-quoted before being piped to the remote shell's stdin (previously `args.join(' ')` left metacharacters unescaped, causing remote `bash: syntax error near unexpected token '('`).
132
+
133
+ ### Docs
134
+ - New `ROADMAP.md` capturing 15 forward-looking improvement areas (multi-site bulk ops, cost transparency, CI/CD deploy command, shell completion, `doctor`, config file, snapshot/migration CLI, self-update, etc.) ranked by ROI.
135
+ - README + CLAUDE.md updated with `wp`-primary positioning and examples for all new commands.
136
+
137
+ ## 0.0.1-beta.4 (2026-05-22)
138
+
139
+ ### Windows — Zero-Install Support
140
+ - Bundled `rsync.exe` (with msys2 runtime DLLs) and BusyBox-w64 (`awk` provider) in `bin/win32/`. No more "install Git for Windows / cwRsync" prerequisite — `instawp local clone`, `local push/pull`, and `sync push/pull` work out of the box on Windows.
141
+ - Replaced the external `sqlite3` CLI dependency with the `better-sqlite3` Node module.
142
+ - New `src/lib/windows-binaries.ts` resolves bundled binaries; falls back to PATH then common Git-for-Windows install dirs.
143
+
144
+ ### Bug Fixes (Windows)
145
+ - `instawp local clone` now resolves the bundled `mysql2sqlite` script correctly (was broken by `new URL(import.meta.url).pathname` returning `/C:/...`).
146
+ - `mysql2sqlite` is invoked as `awk -f script` explicitly; no longer relies on shebang interpretation.
147
+ - `rsync` no longer treats Windows drive paths (`C:\...`) as remote hostnames — paths are converted to msys style (`/c/...`) inside `rsyncViaSsh`.
148
+ - `-e ssh -i <key>` argument uses forward slashes + quoted paths so msys/cygwin sh inside rsync parses the key path correctly.
149
+ - Eliminated the SQL injection risk in `local clone`'s URL search-replace (now uses bound parameters via better-sqlite3).
150
+
151
+ ### Internals
152
+ - New `scripts/fetch-windows-binaries.sh` (maintainer-only) refreshes the Windows bundle from MSYS2 + frippery.org.
153
+ - 32 new tests covering path conversion and bundled-binary resolution.
154
+
155
+ ## 0.0.1-beta.3 (2026-04-12)
156
+
157
+ ### New Commands
158
+ - `local create` — Create local WordPress sites (powered by WordPress Playground, no Docker needed)
159
+ - `local clone <site>` — Clone an InstaWP cloud site to local (files + database)
160
+ - `local start/stop` — Start in foreground or `--background` mode
161
+ - `local push/pull` — Sync wp-content between local and cloud (incremental rsync)
162
+ - `local list` — Show local sites with running/stopped status
163
+ - `local delete` — Remove local sites
164
+ - `sites php <site>` — View or update PHP version and settings
165
+ - `sites update <site>` — Update site label, description, or expiration
166
+ - `teams switch <team>` — Switch active team context
167
+
168
+ ### Improvements
169
+ - `create --wp <version>` — Specify WordPress version when creating sites
170
+ - `sites list` — 50 per page default, `--all` flag, pagination hints
171
+ - Login now shows user name and team after success
172
+ - Site resolver caches name-to-ID lookups for 10 minutes
173
+ - rsync only shows actually changed files (`--itemize-changes`)
174
+ - Magic login URL fixed to use correct `/wordpress-auto-login` endpoint
175
+
176
+ ### Bug Fixes
177
+ - Windows: SSH key generation now works (removed Unix-specific shell commands)
178
+ - Windows: command detection uses `where` instead of `which`
179
+ - `exec/wp --api` flag now works at any position in the command
180
+ - Terminal restored after local site Ctrl+C (`stty sane`)
181
+
182
+ ## 0.0.1-beta.2 (2026-03-23)
183
+
184
+ ### New Commands
185
+ - `local create/clone/start/stop/push/pull/list/delete` — Full local development workflow
186
+ - `teams switch` — Client-side team context
187
+
188
+ ### Improvements
189
+ - Site resolver caching
190
+ - Incremental rsync output
191
+
192
+ ## 0.0.1-beta.1 (2026-03-02)
193
+
194
+ ### Initial Release
195
+ - `login` — OAuth browser flow or `--token`
196
+ - `whoami` — Show current session
197
+ - `create` — Create WordPress sites with provisioning progress
198
+ - `sites list/delete` — Manage sites
199
+ - `exec/wp` — Run commands via SSH or API
200
+ - `ssh` — Interactive SSH sessions
201
+ - `sync push/pull` — rsync wp-content via SSH
202
+ - `teams list/members` — View teams
203
+ - `--json` mode for all commands
package/README.md CHANGED
@@ -3,10 +3,37 @@
3
3
  Create and manage WordPress sites from the terminal.
4
4
 
5
5
  ```
6
- npm install -g @instawp/cli
6
+ npm install -g @instawp/cli@beta
7
7
  ```
8
8
 
9
- > **Beta** - This is an early release. Report issues at [github.com/InstaWP/cli/issues](https://github.com/InstaWP/cli/issues).
9
+ > **Beta** early release. Report issues at [github.com/InstaWP/cli/issues](https://github.com/InstaWP/cli/issues).
10
+
11
+ ## What you can do
12
+
13
+ InstaWP CLI is the connective tissue between your terminal, your InstaWP account, and a real running WordPress — no hosting panel, no FTP, no Docker.
14
+
15
+ - **🤖 Give an AI agent a real WordPress, then ship it** — Claude Code / Cursor gets a genuine WP sandbox (WASM PHP + SQLite, zero setup), builds against it, and deploys to a live site:
16
+ ```bash
17
+ instawp local create --name app # real WordPress on your laptop, no Docker
18
+ instawp local push app # provisions a cloud site + deploys it
19
+ ```
20
+ - **🌉 Run WP-CLI on any site — no SSH** — pipes WP-CLI over HTTPS, so it works behind firewalls and in CI, addressed by name:
21
+ ```bash
22
+ instawp wp acme-site plugin update woocommerce --api
23
+ ```
24
+ - **🛟 Snapshot before risky changes, roll back in one command** — restorable site versions (files + DB), in-place:
25
+ ```bash
26
+ instawp versions create acme-site --name "before update"
27
+ instawp versions restore acme-site <version-id>
28
+ ```
29
+ - **💻 Clone a live site to your laptop and back** — DB export → SQLite → URL rewrite → file sync, all automatic:
30
+ ```bash
31
+ instawp local clone client-store # work offline; then `local push` to sync back
32
+ ```
33
+ - **⚙️ Throwaway preview sites in CI** — spin one up per PR and tear it down:
34
+ ```bash
35
+ instawp create --name "pr-$PR_NUMBER" --json # … run tests … then delete --force
36
+ ```
10
37
 
11
38
  ## Quick Start
12
39
 
@@ -21,6 +48,8 @@ instawp login --token <your-api-token>
21
48
  instawp whoami
22
49
  ```
23
50
 
51
+ `<site>` in any command can be a site **ID**, **name**, or **domain** — the CLI resolves it automatically.
52
+
24
53
  ## Commands
25
54
 
26
55
  ### Sites
@@ -28,34 +57,105 @@ instawp whoami
28
57
  ```bash
29
58
  # List all sites
30
59
  instawp sites list
60
+ instawp sites list --status active --all
31
61
 
32
62
  # Create a new site (waits for provisioning by default)
33
63
  instawp create --name my-site
34
64
  instawp create --name my-site --php 8.3
65
+ instawp create --name my-site --temporary # auto-expiring site
66
+
67
+ # Update label / description / expiration
68
+ instawp sites update <site> --label "New name"
69
+ instawp sites update <site> --expires never
70
+
71
+ # View or change PHP version / settings
72
+ instawp sites php <site>
73
+ instawp sites php <site> --version 8.3 --memory-limit 512
74
+
75
+ # Re-fetch admin credentials + Magic Login URL
76
+ instawp sites creds <site>
77
+
78
+ # Open the site (or admin / magic login) in your browser
79
+ instawp open <site>
80
+ instawp open <site> --admin
81
+ instawp open <site> --magic
35
82
 
36
83
  # Delete a site
37
84
  instawp sites delete <site>
38
85
  instawp sites delete <site> --force
39
86
  ```
40
87
 
41
- ### Run Commands
88
+ ### Versions (snapshots & rollback)
89
+
90
+ Restorable point-in-time copies of a site's files + database. Unlike backups, a version can be rolled back to **in-place** — snapshot before a risky change, then undo it in one command. (Distinct from InstaWP's *Snapshots* product.)
42
91
 
43
92
  ```bash
44
- # Run any command on a site (via SSH, default)
45
- instawp exec <site> ls -la
46
- instawp exec <site> php -v
47
- instawp exec <site> cat wp-config.php
93
+ # Snapshot a site (waits until it's restorable; --no-wait to return immediately)
94
+ instawp versions create <site> --name "before plugin update"
95
+
96
+ # List a site's versions (ID, name, size, status, created)
97
+ instawp versions list <site>
98
+
99
+ # Roll back to a version (OVERWRITES current files + DB; asks to confirm)
100
+ instawp versions restore <site> <version-id>
101
+ instawp versions restore <site> <version-id> --force
102
+
103
+ # Delete versions
104
+ instawp versions delete <site> <version-id> [<version-id> ...]
105
+ ```
106
+
107
+ ### Local Development
108
+
109
+ Run a real WordPress site on your machine via [WordPress Playground](https://wordpress.github.io/wordpress-playground/) (WASM PHP + SQLite) — **no Docker, no MySQL**. Playground is fetched automatically with `npx`; install it globally (`npm i -g @wp-playground/cli`) to skip the first-run download. Works on macOS, Linux, and Windows with zero extra installs.
110
+
111
+ ```bash
112
+ # Create and start a fresh local site
113
+ instawp local create --name blog
114
+ instawp local create --name blog --wp 6.8 --php 8.3 --background
115
+
116
+ # Clone a live InstaWP cloud site to local (DB + plugins + themes + uploads)
117
+ instawp local clone <cloud-site>
118
+
119
+ # Start / stop an existing local site
120
+ instawp local start [name]
121
+ instawp local stop [name]
122
+
123
+ # Sync between local and cloud
124
+ instawp local push <local-name> [cloud-site] # push wp-content (files) up; pushes back to the cloned origin by default
125
+ instawp local push <local-name> --with-db # ALSO overwrite the cloud database with your local one (backs it up first)
126
+ instawp local push <local-name> --with-db --dry-run # preview the DB push (tables/rows/URL rewrite), no cloud writes
127
+ instawp local pull <local-name> <cloud-site> # pull cloud wp-content down
128
+
129
+ # Manage local sites
130
+ instawp local list
131
+ instawp local delete <name> --force
132
+ ```
133
+
134
+ **Files vs. database:** `local push` syncs **files** (`wp-content`) by default — so plugins/themes/uploads, but **not** content like pages or posts (those live in the database). Add **`--with-db`** to also overwrite the cloud database with your local one. It backs up the cloud DB first, converts the local Playground SQLite to MySQL (data-only — it reuses the cloud's existing schema), imports it, and rewrites local→cloud URLs (serialization-safe). Best used on a cloned site, where local and cloud schemas match; tables that exist only locally (e.g. a plugin's custom tables created after cloning) are reported and skipped. Use `--dry-run` to preview, `--no-backup` to skip the safety backup (not recommended).
135
+
136
+ ### Run Commands (WP-CLI + shell)
48
137
 
49
- # Run via API instead of SSH (no SSH setup needed)
50
- instawp exec <site> ls -la --api
138
+ `wp` is the **primary** command for a remote site. `exec` is the escape hatch for non-WP shell commands.
51
139
 
52
- # WP-CLI shorthand (prepends `wp` automatically)
140
+ ```bash
141
+ # WP-CLI on a remote site
53
142
  instawp wp <site> plugin list
54
143
  instawp wp <site> option get siteurl
55
- instawp wp <site> user list --api
56
- ```
57
144
 
58
- `<site>` can be a site **ID**, **name**, or **domain** — the CLI resolves it automatically.
145
+ # Pass raw args to WP-CLI with --
146
+ instawp wp <site> -- post list --post_type=page --format=json
147
+
148
+ # eval / PHP payloads — wrap in single quotes; args are shell-escaped for you
149
+ instawp wp <site> eval '\MyClass::init(["force" => true]);'
150
+
151
+ # Escape hatch for non-WP commands
152
+ instawp exec <site> ls -la
153
+ instawp exec <site> cat wp-config.php
154
+
155
+ # --api transport (no SSH setup required; works behind firewalls / in CI)
156
+ instawp wp <site> option get siteurl --api
157
+ instawp exec <site> php -v --api
158
+ ```
59
159
 
60
160
  ### SSH
61
161
 
@@ -79,10 +179,42 @@ instawp sync pull <site>
79
179
  instawp sync push <site> --dry-run
80
180
  ```
81
181
 
182
+ ### Database (mysqldump)
183
+
184
+ `db push` always backs up the remote database before overwriting (use `--no-backup` to skip).
185
+
186
+ ```bash
187
+ # Pull remote DB to a gzipped SQL dump
188
+ instawp db pull <site>
189
+ instawp db pull <site> --output ./backup.sql.gz
190
+ instawp db pull <site> --no-compress # write .sql instead of .sql.gz
191
+
192
+ # Push a local dump back (auto-backs up the remote first)
193
+ instawp db push <site> ./backup.sql.gz
194
+ instawp db push <site> ./backup.sql --force # skip confirmation
195
+ ```
196
+
197
+ ### Logs
198
+
199
+ ```bash
200
+ # Tail the WP debug.log (default)
201
+ instawp logs <site>
202
+ instawp logs <site> --follow # tail -f
203
+
204
+ # Tail PHP-FPM or nginx error logs
205
+ instawp logs <site> --php
206
+ instawp logs <site> --nginx
207
+ instawp logs <site> --php --nginx -f # multi-tail
208
+
209
+ # Custom line count
210
+ instawp logs <site> --lines 500
211
+ ```
212
+
82
213
  ### Teams
83
214
 
84
215
  ```bash
85
216
  instawp teams list
217
+ instawp teams switch [team] # set the active team for subsequent commands
86
218
  instawp teams members <team>
87
219
  ```
88
220
 
@@ -93,7 +225,8 @@ Add `--json` to any command for machine-readable output:
93
225
  ```bash
94
226
  instawp sites list --json
95
227
  instawp create --name test-site --json
96
- instawp exec <site> wp option get siteurl --json
228
+ instawp versions list <site> --json
229
+ instawp wp <site> option get siteurl --json
97
230
  ```
98
231
 
99
232
  ## Environment Variables
@@ -112,7 +245,7 @@ export INSTAWP_TOKEN=${{ secrets.INSTAWP_TOKEN }}
112
245
  instawp create --name "pr-$PR_NUMBER" --json
113
246
 
114
247
  # Run a smoke test
115
- instawp wp "pr-$PR_NUMBER" option get siteurl
248
+ instawp wp "pr-$PR_NUMBER" option get siteurl --api
116
249
 
117
250
  # Clean up
118
251
  instawp sites delete "pr-$PR_NUMBER" --force
@@ -121,8 +254,9 @@ instawp sites delete "pr-$PR_NUMBER" --force
121
254
  ## Requirements
122
255
 
123
256
  - Node.js 18+
124
- - `ssh` and `ssh-keygen` (for SSH/exec commands)
125
- - `rsync` (for sync commands)
257
+ - `ssh` and `ssh-keygen` (for SSH / `exec` / `sync` / `db` over SSH)
258
+ - `rsync` (for `sync` on macOS/Linux; Windows uses built-in SFTP)
259
+ - Local development uses WordPress Playground (auto-fetched via `npx`) — no Docker required
126
260
 
127
261
  ## License
128
262
 
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerDbCommand(program: Command): void;