caffeinated-whale-cli 3.1.2__tar.gz → 3.2.0__tar.gz
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.
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/PKG-INFO +69 -36
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/README.md +68 -35
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/pyproject.toml +1 -1
- caffeinated_whale_cli-3.2.0/src/caffeinated_whale_cli/__init__.py +1 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/apps.py +90 -15
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/axi.py +53 -8
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/backup.py +12 -24
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/config.py +109 -8
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/init.py +73 -8
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/inspect.py +16 -1
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/label.py +6 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/list.py +39 -30
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/restart.py +2 -1
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/restore.py +4 -7
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/rm.py +156 -37
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/start.py +3 -1
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/status.py +84 -12
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/unlock.py +3 -4
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/update.py +47 -3
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/utils.py +21 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/apps.py +100 -1
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/auto_inspect.py +25 -4
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/backup.py +5 -3
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/bench_ops.py +204 -7
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/config.py +153 -3
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/cred_bridge.py +45 -10
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/credbridge.py +33 -5
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/docker.py +110 -16
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/doctor.py +67 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/init.py +131 -13
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/inspect.py +44 -1
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/resolvers.py +223 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/restart.py +1 -1
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/restore.py +7 -6
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/rm.py +113 -5
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/rm_bench.py +21 -1
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/start.py +11 -1
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/status.py +31 -2
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/supervision.py +33 -1
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/unlock.py +5 -3
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/update.py +171 -6
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/main.py +18 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/cred_daemon.py +74 -17
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/shared_home.py +27 -0
- caffeinated_whale_cli-3.2.0/src/caffeinated_whale_cli/utils/signals.py +61 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/startup.py +47 -34
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli.egg-info/SOURCES.txt +1 -0
- caffeinated_whale_cli-3.1.2/src/caffeinated_whale_cli/__init__.py +0 -1
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/LICENSE +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/setup.cfg +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/__main__.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/__init__.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/console.html +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/doctor.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/logs.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/open.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/rm_bench.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/rm_site.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/run.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/scale.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/self_update.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/serve.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/setup.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/stop.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/commands/where.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/__init__.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/envelope.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/errors.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/exec_stream.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/fleet.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/label.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/list.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/logs.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/open.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/rm_site.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/run.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/scale.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/setup.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/stop.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/url.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/version.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/core/where.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/update_notice.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/__init__.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/agent_hooks.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/auto_inspect.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/bench_labels.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/bench_sites.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/cache.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/completion_utils.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/config_utils.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/console.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/daemon_identity.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/db_utils.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/docker_utils.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/port_utils.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/sendme_utils.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/tips.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/toon.py +0 -0
- {caffeinated_whale_cli-3.1.2 → caffeinated_whale_cli-3.2.0}/src/caffeinated_whale_cli/utils/vscode_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: caffeinated-whale-cli
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: A CLI tool to help manage Frappe Docker instances.
|
|
5
5
|
Author-email: Christopher McKay <mckay.christopher73@outlook.com>
|
|
6
6
|
License: MIT
|
|
@@ -254,6 +254,7 @@ cwcli init [OPTIONS] [PROJECT_NAME]
|
|
|
254
254
|
| `-b`, `--bench TEXT` | Bench directory name inside the container (default: frappe-bench) |
|
|
255
255
|
| `-s`, `--site TEXT` | Primary site name: any hostname/FQDN or IPv4 address (default: development.localhost). `.localhost` names are recommended for local development - they resolve to the machine without DNS. A real domain or IP is accepted too; init prints a one-line note reminding you it must resolve to this machine for browser access |
|
|
256
256
|
| `--bench-parent TEXT` | Directory inside container where bench is created (default: /workspace); also the container mount point for the persisted host `data/` directory, fixed for the life of the instance - changing it on a re-init errors, naming the mounted directory |
|
|
257
|
+
| `--bench-image-tag TEXT` | Pin the `frappe/bench` Docker image to this exact tag (e.g. `v5.29.1`), skipping the Docker Hub latest-tag lookup entirely. Omit to use the short-lived cached tag or a fresh lookup |
|
|
257
258
|
| `--frappe-branch TEXT` | Frappe branch or tag for bench init, e.g. `version-16` or `v16.26.3` (default: version-16). Mutually exclusive with `--version` |
|
|
258
259
|
| `--version TEXT` | Frappe version for bench init, resolved by shape: a bare major (`16` → `version-16` branch) or a full semantic version (`16.26.3` → `v16.26.3` tag). Malformed values are rejected with a non-zero exit. Mutually exclusive with `--frappe-branch` |
|
|
259
260
|
| `--frappe-url TEXT` | Custom Frappe repository URL to build from (a fork), passed to `bench init --frappe-path`. Omit to use the default `frappe/frappe` repo. Pair with `--frappe-branch` to check out the fork's branch. A private fork authenticates through the same credential bridge as `apps install`/`apps update` (host `gh`/`glab`, no token in the container); sign in on the host first |
|
|
@@ -264,6 +265,7 @@ cwcli init [OPTIONS] [PROJECT_NAME]
|
|
|
264
265
|
| `--auto-start` | Automatically start containers if not running |
|
|
265
266
|
| `--start` / `--no-start` | After creating the bench+site, start its dev services (supervisord over `bench start`) so init leaves a running dev environment (default: `--start`). `--no-start` creates without starting, for automation/CI. Distinct from `--auto-start`, which only controls Docker container startup |
|
|
266
267
|
| `--reuse-bench` / `--no-reuse-bench` | Pre-answer the existing-bench question non-interactively: `--reuse-bench` reuses the bench and skips `bench init`; `--no-reuse-bench` requires a fresh `--bench` name and errors if it already exists. Default: ask interactively (a non-TTY without either flag refuses). Distinct from `--auto-start`, which controls container startup |
|
|
268
|
+
| `--uid INTEGER` | Override the uid/gid the container's `frappe` user is aligned to, instead of the host's own uid/gid. Mainly for a root-uid host (e.g. a CI runner running as uid 0), where a root host already falls back to a safe default automatically (see step 7 below); pass `--uid` to choose a specific uid instead. Must be a positive, non-root integer (`--uid 0`, negatives, and non-numeric values are rejected with a usage error before any container or file work). Applies only to this init invocation, including its end-of-init auto-start; it is never persisted, so later `cwcli start`/`restart` do not take it |
|
|
267
269
|
| `-v`, `--verbose` | Show verbose output with streaming command execution |
|
|
268
270
|
|
|
269
271
|
**What It Does:**
|
|
@@ -272,9 +274,9 @@ cwcli init [OPTIONS] [PROJECT_NAME]
|
|
|
272
274
|
2. Downloads `docker-compose.yml` from frappe_docker GitHub repository
|
|
273
275
|
3. Customizes port mappings based on `--port` flag
|
|
274
276
|
4. Binds the bench workspace to a host `~/.cwcli/projects/{project_name}/data/` directory at `--bench-parent` inside the container (default `/workspace`), so bench files stay directly accessible on the host and survive container recreation
|
|
275
|
-
5. Resolves the
|
|
277
|
+
5. Resolves the `frappe/bench` image tag to pin (never uses `:latest`): `--bench-image-tag` is used verbatim and skips the lookup; otherwise a short-lived on-disk cache serves repeated inits and only a cache miss queries Docker Hub for the latest stable tag
|
|
276
278
|
6. Pulls Docker images and starts containers
|
|
277
|
-
7. On hosts that expose uid/gid information, aligns the container's `frappe` user to the host user so bench files written to the mounted workspace stay host-owned and removable by `cwcli rm` (no-op when the ids already match; platforms without `os.getuid`, such as Windows, cleanly skip alignment because Docker Desktop handles bind-mount ownership; a failed attempted remap degrades to a warning and bench creation still proceeds)
|
|
279
|
+
7. On hosts that expose uid/gid information, aligns the container's `frappe` user to the host user so bench files written to the mounted workspace stay host-owned and removable by `cwcli rm` (no-op when the ids already match; platforms without `os.getuid`, such as Windows, cleanly skip alignment because Docker Desktop handles bind-mount ownership; a failed attempted remap degrades to a warning and bench creation still proceeds). On a **root host** (uid 0, a common CI-runner shape) the container `frappe` user is **not** remapped to 0 - that would collide with the container's own root user and break bench's `PATH` (`bench init` fails with exit 127) - so it falls back to the image's default uid (1000) and says so once in a warning; root can still remove those files, so `cwcli rm` keeps working. Pass `--uid <n>` to align to a specific uid instead
|
|
278
280
|
8. Pins the correct Python version via `PYENV_VERSION` for the branch (installs via pyenv if missing)
|
|
279
281
|
9. Pins the correct Node.js version via nvm for older branches (installs via nvm if missing)
|
|
280
282
|
10. Installs `yarn` globally for the activated Node.js version (older branches only)
|
|
@@ -778,6 +780,7 @@ The same fail-closed refusal applies when Docker cannot verify whether named vol
|
|
|
778
780
|
If Docker confirms that no named volumes remain, no backup is needed: `cwcli rm` cleans up the orphan's network and local directory under the default settings.
|
|
779
781
|
The volume state is checked again before cleanup, and any change or verification failure aborts instead of risking unbacked data.
|
|
780
782
|
Under `--no-volumes` no volume data is destroyed, so a stopped project is cleaned up without a backup as before.
|
|
783
|
+
A half-provisioned instance that holds no site on any bench has nothing to back up, so - like a confirmed volume-free orphan - the removal proceeds instead of refusing and sending you back for a second `--no-backup` run; this relaxes only on a *live* proof that every bench is site-less, and any ambiguity keeps the fail-closed refusal.
|
|
781
784
|
|
|
782
785
|
```bash
|
|
783
786
|
cwcli rm [OPTIONS] [PROJECT_NAME]...
|
|
@@ -808,7 +811,7 @@ If a project has no containers but still has a network, named volumes, or a loca
|
|
|
808
811
|
Confirmed volume-free orphans are cleaned under the defaults.
|
|
809
812
|
Orphans with named volumes, or an unknown volume state, remain protected by the backup gate.
|
|
810
813
|
|
|
811
|
-
An invalid project name (empty, `.`, `..`, an absolute path, or one containing a path separator) is rejected before anything is removed, since such a name could otherwise escape the projects directory.
|
|
814
|
+
An invalid project name (empty, blank/whitespace-only, `.`, `..`, an absolute path, or one containing a path separator) is rejected before anything is removed, since such a name could otherwise escape the projects directory or resolve to a phantom project; a blank name is reported as `(empty)` rather than an empty quote.
|
|
812
815
|
`cwcli rm` exits non-zero whenever any removal step fails, including a blocked backup, a rejected name, or a container, volume, network, or directory that could not be removed.
|
|
813
816
|
It does not print the success summary for a project that was not fully removed; the project stays in the cache (and `cwcli ls`) so the leftover state remains visible and can be retried.
|
|
814
817
|
|
|
@@ -1013,6 +1016,9 @@ This means an app you just installed is picked up automatically, without a manua
|
|
|
1013
1016
|
If nothing changed, the cached data is served unchanged; if that pass detects a change, it transparently falls back to a full re-inspect so the per-site installed-app lists are refreshed too.
|
|
1014
1017
|
Use `--no-refresh` to skip the pass and return the cached data as-is (fastest, but possibly stale), or `--update` to force a full re-inspect.
|
|
1015
1018
|
|
|
1019
|
+
**App-copy flags:** on a full inspect (not a cache-served read) `inspect` flags an app whose `apps/<app>` is a symlink (showing the real directory) and, more seriously, an app whose imported copy differs from `apps/<app>` (the bench imports a different copy, so the site runs code that changes to `apps/<app>` never reach).
|
|
1020
|
+
These are live-observed and not persisted to the cache.
|
|
1021
|
+
|
|
1016
1022
|
**Security Note:** The cache never stores Frappe secrets. Site and common configurations are whitelist-filtered before they are written, so database passwords, per-site encryption keys, admin/root passwords, and Redis URLs are stripped and never persisted (nothing reads them back from the cache - every credential consumer reads live from the container or from CLI flags/prompts). Any cache written before this behavior shipped is cleaned in place on the next run. As defense-in-depth, the cache is also stored with restricted filesystem permissions (directory: `0700`, database: `0600`) so only the current user can read it; still, do not share the cache directory (`~/.cwcli/cache/`) with untrusted users.
|
|
1017
1023
|
|
|
1018
1024
|
```bash
|
|
@@ -1230,17 +1236,18 @@ After a successful mutation the bench's cached app lists are refreshed so `where
|
|
|
1230
1236
|
|
|
1231
1237
|
```bash
|
|
1232
1238
|
cwcli apps list [OPTIONS] PROJECT_NAME
|
|
1233
|
-
cwcli apps install [OPTIONS] PROJECT_NAME
|
|
1239
|
+
cwcli apps install [OPTIONS] PROJECT_NAME [APP ...] # or -a/--app APP
|
|
1234
1240
|
cwcli apps uninstall [OPTIONS] PROJECT_NAME --app APP [--app APP ...]
|
|
1235
1241
|
cwcli apps update [OPTIONS] PROJECT_NAME APPS...
|
|
1236
1242
|
cwcli apps checkout [OPTIONS] PROJECT_NAME APP REF
|
|
1237
1243
|
```
|
|
1238
1244
|
|
|
1239
1245
|
**`apps list`** - lists apps available in the bench (live `ls apps/`); with `--installed`/`--site` it also lists the apps installed per site (all sites by default, grouped by site).
|
|
1246
|
+
It flags an app whose `apps/<app>` is a symlink (naming the real directory it points at) and, more seriously, an app whose imported copy differs from `apps/<app>` (the bench's Python actually imports a different copy, so operating on `apps/<app>` leaves the site running stale code); in `--json` an `app_copies` array carries the same detail for any flagged app.
|
|
1240
1247
|
|
|
1241
1248
|
**`apps install`** - ensures each app is present on the bench, then installs it on the target site(s).
|
|
1242
|
-
An app absent from `apps/` is fetched with `bench get-app` (honoring `--branch`); an app already present is not fetched again, so pre-warmed benches install it without failing on the existing directory.
|
|
1243
|
-
Each
|
|
1249
|
+
An app absent from `apps/` is fetched with `bench get-app` (honoring `--branch`); an app already present **and registered** (in `sites/apps.txt`) is not fetched again, so pre-warmed benches install it without failing on the existing directory. A present directory that is *not* a valid install - the leftover of an earlier fetch that cloned but failed at its `pip install` step - is refused with an actionable message telling you to remove it and re-run, rather than reporting a false "get-app ok" and then dumping a raw install traceback on every retry. When a fresh fetch itself fails, the partial `apps/<app>` directory it created is removed so a retry genuinely re-fetches (a pre-existing app directory is never touched).
|
|
1250
|
+
Each app is a known app name **or** a git URL (passed straight to `bench get-app` when a fetch is needed, so custom apps not in bench's registry work). Apps may be given positionally (matching `apps update`/`apps checkout` and `axi apps install`) or with `-a`/`--app`; both forms combine, and repeat either to install more than one.
|
|
1244
1251
|
`--fetch-only` ensures the app is present without installing it on any site.
|
|
1245
1252
|
`--if-not-present` makes install idempotent: an app already installed on a target site is skipped (reported, not reinstalled, with its install hooks never rerun) and the command still exits 0, so "ensure this app is installed" is a single call whose exit code a script can trust; an app the site does not have is still installed normally, and a genuine install failure still exits non-zero.
|
|
1246
1253
|
A bench that is already running may still serve code it loaded before the install and fail to see the new app: install therefore **resynchronises** that bench - it restarts every cwcli-supervised program that runs the bench's Python (`web`, `schedule`, and every worker) and requires every changed site to answer Frappe before it reports success.
|
|
@@ -1254,6 +1261,8 @@ A bench that was not running is left alone.
|
|
|
1254
1261
|
|
|
1255
1262
|
**`apps update`** - the canonical app-update path (what the deprecated `cwcli update` now delegates to). Updating the `frappe` framework app runs `bench update --reset`; other apps use the normal git-pull + migrate flow. After the migrations finish and maintenance mode is lifted, it runs the same **resynchronise** step as `apps install`, so a `git pull` cannot leave the bench's web, scheduler, and workers on the code that was there before it; every migrated site must answer Frappe before the run reports success. `--site` narrows which affected sites are migrated; if none of the named site(s) actually have the app installed, the command refuses and exits non-zero rather than silently migrating nothing (a genuine typo/mismatch guard - a bench with no affected sites at all still exits zero). It accepts the same migration flags as the [deprecated `update` command](#update---update-apps-and-migrate) (`--clear-cache`, `--clear-website-cache`, `--build`, `--skip-maintenance`, `--no-recache`). When updating the `frappe` framework app the flow runs the bench-wide `bench update --reset`, so `--site` and those per-app migration flags do not apply and are reported as ignored.
|
|
1256
1263
|
`--force` is an opt-in, **destructive** recovery for a conflicting update: if an app's `git pull` hits a **conflict** (local changes that would be overwritten, or a conflicted merge), it hard-resets that app to its remote tracking branch (`git fetch` then `git reset --hard @{u}`), discarding the local changes, so the update completes instead of failing. It fires **only on a conflict** - a clean update is untouched, and a pull that failed for another reason (network, auth) is left as the failure it is rather than having work discarded. Without `--force`, a conflict fails safely and discards nothing. Every force-reset app is reported (`force_reset_apps`) and a warning is printed at the reset. `--force` does not delete untracked files (it never runs `git clean`), matching `apps checkout --reset`. `--force` also clears a git **"dubious ownership"** refusal before pulling: when an app's repository is owned by a different user than the container runs as - common on a shared-mode or migrated instance whose app sources are owned by a pre-migration uid - it re-owns the repository to the container user so the pull proceeds, rather than surfacing a raw git ownership error. A `cwcli start`/`cwcli restart` self-heals the same ownership so a plain `apps update` works too; `--force` fixes it inline without a restart.
|
|
1264
|
+
When `apps/<app>` is a symlink, the update writes through it and the run names the real directory it operated on.
|
|
1265
|
+
After the pull, update verifies that the copy the bench actually imports is the copy it just updated; when they differ it does **not** report plain success - it warns, names both paths, and exits non-zero so a script notices the site is still running the other copy.
|
|
1257
1266
|
|
|
1258
1267
|
**`apps checkout`** - fetches and checks out an arbitrary branch, tag, or commit (`REF`) into an app that is **already present** in the bench (`apps/<app>`), so a specific feature branch can be put under test in the instance the app lives in.
|
|
1259
1268
|
Unlike `apps install` (bench acquisition when needed, then site installation) and `apps update` (the tracked upstream on every app), this targets one existing checkout: it runs `git fetch <remote> <ref>` then `git checkout -B <ref> FETCH_HEAD` in the app directory (the remote is auto-detected - `upstream` for a bench-installed app, `origin` for a hand-cloned one).
|
|
@@ -1267,8 +1276,9 @@ Dirty means precisely **anything `git status --porcelain` reports: staged change
|
|
|
1267
1276
|
Files matched by `.gitignore` are not reported by git and so never count, which is why ordinary build residue (`__pycache__`, `node_modules`, `*.egg-info`) does not block a checkout.
|
|
1268
1277
|
`--reset` is the explicit opt-in through that refusal: it hard-resets the working tree to the fetched ref, discarding tracked local edits, which guarantees the clean tree a subsequent `build`/`migrate` needs.
|
|
1269
1278
|
Note one honest limit: `--reset` does **not** delete untracked files, because cwcli never runs `git clean` - it lets the checkout proceed and leaves them where they are.
|
|
1279
|
+
Like `apps update`, checkout names the real directory when `apps/<app>` is a symlink, and after moving the tree it verifies the bench imports the copy it just changed; if the bench imports a different copy it warns, names both paths, and exits non-zero rather than reporting a checkout the site will not actually run.
|
|
1270
1280
|
|
|
1271
|
-
**Private repos:** `apps install`/`apps update`/`apps checkout` (and the deprecated `update`), plus any bench subcommand run through [`cwcli run`](#run---execute-bench-commands) (`cwcli run <project> get-app <private-url>`, `cwcli run <project> update --pull`), transparently authenticate git fetches against private GitHub/GitLab app repos through your host's already-signed-in `gh`/`glab` - nothing to configure, no token ever stored in the container, and public repos are unaffected. Sign in on the host first (`gh auth login` / `glab auth login`).
|
|
1281
|
+
**Private repos:** `apps install`/`apps update`/`apps checkout` (and the deprecated `update`), plus any bench subcommand run through [`cwcli run`](#run---execute-bench-commands) (`cwcli run <project> get-app <private-url>`, `cwcli run <project> update --pull`), transparently authenticate git fetches against private GitHub/GitLab app repos through your host's already-signed-in `gh`/`glab` - nothing to configure, no token ever stored in the container, and public repos are unaffected. Sign in on the host first (`gh auth login` / `glab auth login`). This credential bridge only serves operations run **through cwcli**; a raw `git` you run yourself inside the container (in a `docker exec` shell, or `cwcli open`) is not bridged and will prompt or fail auth. Run the fetch through `cwcli run <project> <bench-args>` instead, or - to bridge **interactive** git inside `cwcli open` or a `docker exec` shell (not just cwcli's own operations) - opt into the persistent [`config cred-bridge`](#config-cred-bridge---persistent-credential-bridge).
|
|
1272
1282
|
|
|
1273
1283
|
**Common Options:**
|
|
1274
1284
|
|
|
@@ -1276,7 +1286,7 @@ Note one honest limit: `--reset` does **not** delete untracked files, because cw
|
|
|
1276
1286
|
|--------|-------------|
|
|
1277
1287
|
| `--bench TEXT` | Which bench to target: its numeric index or label (see [Working with Multiple Benches](#working-with-multiple-benches)) |
|
|
1278
1288
|
| `-p`, `--path TEXT` | Explicit bench directory inside the container (lower-level alternative to `--bench`) |
|
|
1279
|
-
| `-a`, `--app TEXT` | App name (`install` also accepts a git URL); repeatable
|
|
1289
|
+
| `-a`, `--app TEXT` | App name (`install` also accepts a git URL); repeatable. Required for `uninstall`; for `install` the app may instead be given positionally |
|
|
1280
1290
|
| `--site TEXT` | Target site(s); repeatable. Omit for all sites (list/install/uninstall) or all affected sites (update) |
|
|
1281
1291
|
| `--json` | Machine-readable JSON output (for `install`/`uninstall`, includes the per-`(app, site)` results; for `update`, the full per-phase report). Stdout carries only the document - bench output never corrupts it |
|
|
1282
1292
|
| `-y`, `--yes` | Auto-start stopped containers without prompting; for `uninstall`, also skip the destructive confirmation |
|
|
@@ -1291,8 +1301,8 @@ cwcli apps list frappe-one
|
|
|
1291
1301
|
# List apps installed across every site, as JSON
|
|
1292
1302
|
cwcli apps list frappe-one --installed --json
|
|
1293
1303
|
|
|
1294
|
-
# Install ERPNext on every site of the bench
|
|
1295
|
-
cwcli apps install frappe-one
|
|
1304
|
+
# Install ERPNext on every site of the bench (positional app, or -a/--app)
|
|
1305
|
+
cwcli apps install frappe-one erpnext
|
|
1296
1306
|
|
|
1297
1307
|
# Install more than one app in the same call
|
|
1298
1308
|
cwcli apps install frappe-one --app erpnext --app hrms
|
|
@@ -1423,7 +1433,7 @@ cwcli unlock [OPTIONS] PROJECT_NAME
|
|
|
1423
1433
|
|
|
1424
1434
|
| Option | Description |
|
|
1425
1435
|
|--------|-------------|
|
|
1426
|
-
| `-s`, `--site TEXT` | Site name to unlock. If not provided, uses the default site (from `common_site_config.json`'s `default_site` or `sites/currentsite.txt`) |
|
|
1436
|
+
| `-s`, `--site TEXT` | Site name to unlock. If not provided, uses the default site (from `common_site_config.json`'s `default_site` or `sites/currentsite.txt`), falling back to the sole site of a single-site bench |
|
|
1427
1437
|
| `--bench TEXT` | Which bench to target: its numeric index or label (see [Working with Multiple Benches](#working-with-multiple-benches)) |
|
|
1428
1438
|
| `-p`, `--path TEXT` | Explicit bench directory inside the container (lower-level alternative to `--bench`; cannot be combined with it) |
|
|
1429
1439
|
| `-y`, `--yes` | Auto-start stopped containers without prompting |
|
|
@@ -1435,9 +1445,9 @@ Removes the `{bench_path}/sites/{site_name}/locks` directory, which can help res
|
|
|
1435
1445
|
A site with no locks folder is reported as an honest "already unlocked" success rather than a generic "unlocked" message.
|
|
1436
1446
|
|
|
1437
1447
|
**Smart Defaults:**
|
|
1438
|
-
- If `--site` is not specified,
|
|
1439
|
-
-
|
|
1440
|
-
-
|
|
1448
|
+
- If `--site` is not specified, uses your bench's configured default site (from `common_site_config.json`'s `default_site`, or `sites/currentsite.txt` when that key is absent); when no default is configured it falls back to the sole site of a single-site bench (the shape a fresh `cwcli init` leaves)
|
|
1449
|
+
- A multi-site bench with no configured default still requires `--site`, and the error lists the available sites
|
|
1450
|
+
- Shows "Using site '{site}'" when the site was resolved for you
|
|
1441
1451
|
|
|
1442
1452
|
**Examples:**
|
|
1443
1453
|
|
|
@@ -1445,9 +1455,9 @@ A site with no locks folder is reported as an honest "already unlocked" success
|
|
|
1445
1455
|
# Unlock a specific site
|
|
1446
1456
|
cwcli unlock my-project --site development.localhost
|
|
1447
1457
|
|
|
1448
|
-
# Use
|
|
1458
|
+
# Use the resolved site (no --site flag needed)
|
|
1449
1459
|
cwcli unlock my-project
|
|
1450
|
-
# Output: Using
|
|
1460
|
+
# Output: Using site 'development.localhost'
|
|
1451
1461
|
|
|
1452
1462
|
# Verbose mode with default site
|
|
1453
1463
|
cwcli unlock my-project -v
|
|
@@ -1498,7 +1508,7 @@ cwcli backup [OPTIONS] PROJECT_NAME
|
|
|
1498
1508
|
|
|
1499
1509
|
| Option | Description |
|
|
1500
1510
|
|--------|-------------|
|
|
1501
|
-
| `-s`, `--site TEXT` | Site name to back up. If not provided, uses the default site (from `common_site_config.json`'s `default_site` or `sites/currentsite.txt`) |
|
|
1511
|
+
| `-s`, `--site TEXT` | Site name to back up. If not provided, uses the default site (from `common_site_config.json`'s `default_site` or `sites/currentsite.txt`), falling back to the sole site of a single-site bench; a multi-site bench with no default requires `--site` and the error lists the sites |
|
|
1502
1512
|
| `--bench TEXT` | Which bench to target: its numeric index or label (see [Working with Multiple Benches](#working-with-multiple-benches)) |
|
|
1503
1513
|
| `-p`, `--path TEXT` | Explicit bench directory inside the container (lower-level alternative to `--bench`; cannot be combined with it) |
|
|
1504
1514
|
| `--with-files` | Include public and private files in the backup |
|
|
@@ -1541,7 +1551,7 @@ cwcli restore [OPTIONS] PROJECT_NAME
|
|
|
1541
1551
|
|
|
1542
1552
|
| Option | Description |
|
|
1543
1553
|
|--------|-------------|
|
|
1544
|
-
| `-s`, `--site TEXT` | Site name to restore. If not provided, uses the default site (from `common_site_config.json`'s `default_site` or `sites/currentsite.txt`) |
|
|
1554
|
+
| `-s`, `--site TEXT` | Site name to restore. If not provided, uses the default site (from `common_site_config.json`'s `default_site` or `sites/currentsite.txt`), falling back to the sole site of a single-site bench; a multi-site bench with no default requires `--site` and the error lists the sites |
|
|
1545
1555
|
| `--latest` | Non-interactive: select the most recent backup set for the target site (bypasses the backup menu). A non-TTY without any selector exits non-zero instead of hanging |
|
|
1546
1556
|
| `--backup-file TEXT` | Non-interactive: select the backup set whose database file matches this filename (or full container path). Bypasses the backup menu |
|
|
1547
1557
|
| `--bench TEXT` | Which bench to target: its numeric index or label (see [Working with Multiple Benches](#working-with-multiple-benches)) |
|
|
@@ -1618,7 +1628,7 @@ cwcli restore my-project --site production.localhost --latest --yes \
|
|
|
1618
1628
|
**Example Session:**
|
|
1619
1629
|
|
|
1620
1630
|
```
|
|
1621
|
-
Using
|
|
1631
|
+
Using site 'development.localhost'
|
|
1622
1632
|
|
|
1623
1633
|
? Select a backup to restore: (Use arrow keys)
|
|
1624
1634
|
|
|
@@ -1831,14 +1841,14 @@ read from that bench's `sites/common_site_config.json`, which is what bench's ow
|
|
|
1831
1841
|
`make_ports` writes - so a bench's HTTP code always describes that bench.
|
|
1832
1842
|
|
|
1833
1843
|
```bash
|
|
1834
|
-
cwcli status [OPTIONS] PROJECT_NAME
|
|
1844
|
+
cwcli status [OPTIONS] [PROJECT_NAME]
|
|
1835
1845
|
```
|
|
1836
1846
|
|
|
1837
1847
|
**Arguments:**
|
|
1838
1848
|
|
|
1839
1849
|
| Argument | Description |
|
|
1840
1850
|
|----------|-------------|
|
|
1841
|
-
| `PROJECT_NAME` | The Docker Compose project name to check (
|
|
1851
|
+
| `PROJECT_NAME` | The Docker Compose project name to check. Omit it for the all-instances summary (the same table `cwcli ls` gives) - a bare `cwcli status` reads like "how is everything", not a missing-argument error |
|
|
1842
1852
|
|
|
1843
1853
|
**Options:**
|
|
1844
1854
|
|
|
@@ -1879,15 +1889,20 @@ is a gap in cwcli's knowledge, not a fault in the bench.
|
|
|
1879
1889
|
`Host` header, so a request naming no site is correctly answered `404` by a
|
|
1880
1890
|
perfectly healthy bench - which is what `status` used to report on every read. The
|
|
1881
1891
|
probe now sends the bench's site as its `Host`, so a healthy bench reads `200`, and
|
|
1882
|
-
the report says which site it asked for (`web_site
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1892
|
+
the report says which site it asked for (`web_site`). That keeps the code
|
|
1893
|
+
attributable the same way the port does: it is that site's code, not a claim about
|
|
1894
|
+
the bench as a whole. A bench with no site recorded probes without a `Host` header,
|
|
1895
|
+
as before, and reports `web_site: null`. The human `cwcli status` web line shows the
|
|
1896
|
+
**host-reachable** address (`web <site>:<host-port> -> <code>`) - the same one the
|
|
1897
|
+
init banner and `cwcli axi url` print, so it is copy-pasteable - resolved by mapping
|
|
1898
|
+
the bench's container web port through the container's live host bindings; when that
|
|
1899
|
+
host binding cannot be resolved it falls back to the container port labelled
|
|
1900
|
+
`(in-container)` so nobody tries to open an unreachable address.
|
|
1886
1901
|
|
|
1887
1902
|
A truly-nonexistent project name (a typo, or one never created - no containers
|
|
1888
|
-
with the label at all) is NOT `offline`: it exits non-zero with a "
|
|
1889
|
-
|
|
1890
|
-
name that does not exist.
|
|
1903
|
+
with the label at all) is NOT `offline`: it exits non-zero with a "Project
|
|
1904
|
+
'<name>' not found." error on stderr, so a script can tell a stopped instance apart
|
|
1905
|
+
from a name that does not exist.
|
|
1891
1906
|
|
|
1892
1907
|
**Not under cwcli supervision:** if a bench is running but was NOT started by
|
|
1893
1908
|
cwcli's supervisord - a plain `bench start`, or an instance already running before
|
|
@@ -1900,9 +1915,20 @@ hint to run `cwcli start` to bring it under cwcli's supervisor. In this mode the
|
|
|
1900
1915
|
per-process supervisord `state` is unavailable (there is no supervisord to ask);
|
|
1901
1916
|
`up` comes straight from `ps`. `status` only reads - it never launches supervisord.
|
|
1902
1917
|
|
|
1918
|
+
**Maintenance mode is called out plainly.** A site stuck in maintenance mode answers
|
|
1919
|
+
HTTP 503 to every user with no other signal - the state a `migrate` / `apps update`
|
|
1920
|
+
killed mid-run (a closed terminal, a `kill`, a service stop) leaves behind. When a
|
|
1921
|
+
bench's site is in maintenance mode, `status` prints `MAINTENANCE MODE ON` for that
|
|
1922
|
+
site (even without `-v`, since it is a fault, not detail) and names the way out
|
|
1923
|
+
(`cwcli run <project> --site <site> set-maintenance-mode off`); `cwcli axi status`
|
|
1924
|
+
carries it as `maintenance_mode` plus a `status.maintenance_mode` warning. It is read
|
|
1925
|
+
live from the site's `site_config.json`, not inferred from the 503, and is skipped in
|
|
1926
|
+
the `--watch` loop (which makes no web probe).
|
|
1927
|
+
|
|
1903
1928
|
**Per-bench, per-process detail (stderr):** one sub-block per bench, headed by its
|
|
1904
|
-
index, path, label, and own aggregate, with a web line naming the
|
|
1905
|
-
|
|
1929
|
+
index, path, label, and own aggregate, with a web line naming the host-reachable
|
|
1930
|
+
address that was probed (`web dev.localhost:17001 -> 200`, or the container port
|
|
1931
|
+
labelled `(in-container)` when the host binding cannot be resolved). Beneath each, every Procfile process (`web`, `socketio`,
|
|
1906
1932
|
`worker`, `schedule`, `watch`, `redis_cache`, `redis_queue`) with up/down plus
|
|
1907
1933
|
its PID, uptime, CPU%, RSS, and supervisord's authoritative `state`
|
|
1908
1934
|
(`RUNNING`/`STARTING`/`BACKOFF`/`EXITED`/`FATAL`/`STOPPED`) - so a crash-looping or
|
|
@@ -2034,11 +2060,17 @@ cwcli config paths # list, one path per line
|
|
|
2034
2060
|
cwcli config paths --json # the same list as JSON
|
|
2035
2061
|
cwcli config paths add /home/user/benches # absolute paths only
|
|
2036
2062
|
cwcli config paths remove /home/user/benches
|
|
2063
|
+
cwcli config paths prune # dry-run: list dead paths
|
|
2064
|
+
cwcli config paths prune --yes # actually drop them
|
|
2037
2065
|
```
|
|
2038
2066
|
|
|
2039
2067
|
`add` refuses a non-absolute path with a usage error (exit 2) after `~` expansion, and normalizes before duplicate detection, so `/a/b` and `/a/b/` are one entry, not two.
|
|
2040
2068
|
Adding an already-present path and removing an absent one are both no-op successes (exit 0, saying which no-op occurred).
|
|
2041
2069
|
|
|
2070
|
+
`prune` removes custom search paths that no live instance references (they accumulate a graveyard: a path added for an instance later removed lingers forever and is re-scanned on every `inspect`).
|
|
2071
|
+
It checks each path live against every instance's frappe container and, with `--yes`, drops the ones absent from all of them; without `--yes` it is a dry-run that only lists what it would drop (`--json` for machine output).
|
|
2072
|
+
It is fail-closed: a path present in any instance is never dropped, and if any instance cannot be checked (stopped or unreachable) nothing is pruned, so a path a stopped instance still needs is never lost.
|
|
2073
|
+
|
|
2042
2074
|
##### `config cache` - Manage Cache
|
|
2043
2075
|
|
|
2044
2076
|
Manages the cache for project inspection data.
|
|
@@ -2137,11 +2169,12 @@ Honestly stated: the allowlist keeps the long-lived channel from silently wideni
|
|
|
2137
2169
|
|
|
2138
2170
|
**Cred-Bridge Subcommands:**
|
|
2139
2171
|
|
|
2140
|
-
- **`enable [--startup/--no-startup]`** - Enable the bridge AND start its background daemon, in one verb
|
|
2172
|
+
- **`enable [--project <name>] [--startup/--no-startup]`** - Enable the bridge AND start its background daemon, in one verb
|
|
2141
2173
|
- Idempotent; missing `gh`/`glab` is a warning, not a refusal (the bridge simply answers nothing until a tool is installed and authenticated).
|
|
2142
|
-
- Takes effect on
|
|
2143
|
-
- `--
|
|
2144
|
-
-
|
|
2174
|
+
- Takes effect immediately on every currently-running instance cwcli manages (a Frappe container cwcli did not create is never touched), and self-heals onto each instance on the next `cwcli open`/`cwcli start`/`cwcli run`. When the default sweep wires more than one instance it names them, so an operator on a multi-instance machine is never surprised.
|
|
2175
|
+
- `--project <name>` scopes the sweep to the named instance(s) (repeatable; an unknown name is the usual `not found` error, and a running container cwcli does not manage is refused rather than wired). Omit it to wire every running managed instance.
|
|
2176
|
+
- `--startup` also installs an automatic start at system boot/login (LaunchAgent on macOS, systemd user service on Linux, Task Scheduler on Windows) - this covers reopening VS Code straight after a reboot, before any cwcli verb has run. `--no-startup` removes the boot unit; omit both to leave it untouched. If the boot unit cannot be installed (for example a host with no systemd user session), the bridge still enables and runs - the message says so and names `cwcli config cred-bridge start` for a manual start.
|
|
2177
|
+
- Example: `cwcli config cred-bridge enable --project my-instance --startup`
|
|
2145
2178
|
|
|
2146
2179
|
- **`disable`** - Stop the daemon, set enabled = false, make every wired shim inert, and remove the boot unit (non-destructive; an `enable` recreates everything)
|
|
2147
2180
|
- Example: `cwcli config cred-bridge disable`
|
|
@@ -2521,7 +2554,7 @@ It exits non-zero if a restart fails or the named site does not answer Frappe's
|
|
|
2521
2554
|
|
|
2522
2555
|
These are agent-only for now: there is no human `cwcli migrate`, `cwcli run-tests`, or `cwcli build` yet. Use `cwcli run <project> --site <site> migrate` for the human equivalent.
|
|
2523
2556
|
|
|
2524
|
-
`cwcli axi init` provisions a new instance, bench, and site the way `cwcli init` does, but non-interactively and as ONE terminal TOON document. It **blocks** for the full 10-20 minute run - the same block-and-emit-one-document shape as `cwcli axi apps update`, because a progress stream would break the one-TOON-document contract - narrating coarse phase labels to stderr; run `cwcli logs <project>` / `cwcli status <project>` from a second shell for live progress. Running several `axi init` calls in parallel can OOM-kill the host on a memory-constrained machine - serialize them instead. Adding a bench to an already-running instance never disturbs it or its other benches: the frappe container is never pulled, recreated, or restarted, so every already-serving bench keeps running throughout. After the bench+site is created, it starts the bench's dev services by default (the same `core.start` behind `cwcli start`/`cwcli axi start`), leaving a running bench rather than a created-but-idle one; `--no-start` creates without starting, for automation/CI, distinct from Docker container startup (stage 1 always brings the containers up regardless of this flag). A dev-services start failure degrades to a stderr warning rather than a non-zero exit, since the bench was already created. The site administrator password comes from the **`CWCLI_ADMIN_PASSWORD` environment variable (recommended)** or `--admin-password`; the flag wins if both are set, and with neither set the verb refuses with a usage error (exit 2) naming both - it never generates a password and never prompts. The env var keeps the secret off the process argv (visible in `ps`/shell history) that the flag exposes; the container-side `bench new-site` still receives it, so treat the value as one-time. The MariaDB root password takes the same shape via `CWCLI_DB_ROOT_PASSWORD` / `--db-root-password` (default `123`). The interactive decisions the human `cwcli init` prompts for become non-prompting errors: an existing bench with neither `--reuse-bench` nor `--no-reuse-bench` is a usage error (exit 2) naming both; a port conflict names `--port` (exit 1); containers that do not come up point at `cwcli status`/`cwcli logs` (exit 1). There is no `--auto-start` (compose `cwcli axi start` then re-run) and no `--verbose` (stdout is always TOON). `--bench` here is the NAME of the bench to create, distinct from the `--bench <index|label>` selector the other verbs use.
|
|
2557
|
+
`cwcli axi init` provisions a new instance, bench, and site the way `cwcli init` does, but non-interactively and as ONE terminal TOON document. It **blocks** for the full 10-20 minute run - the same block-and-emit-one-document shape as `cwcli axi apps update`, because a progress stream would break the one-TOON-document contract - narrating coarse phase labels to stderr; run `cwcli logs <project>` / `cwcli status <project>` from a second shell for live progress. Running several `axi init` calls in parallel can OOM-kill the host on a memory-constrained machine - serialize them instead. Adding a bench to an already-running instance never disturbs it or its other benches: the frappe container is never pulled, recreated, or restarted, so every already-serving bench keeps running throughout. After the bench+site is created, it starts the bench's dev services by default (the same `core.start` behind `cwcli start`/`cwcli axi start`), leaving a running bench rather than a created-but-idle one; `--no-start` creates without starting, for automation/CI, distinct from Docker container startup (stage 1 always brings the containers up regardless of this flag). A dev-services start failure degrades to a stderr warning rather than a non-zero exit, since the bench was already created. The site administrator password comes from the **`CWCLI_ADMIN_PASSWORD` environment variable (recommended)** or `--admin-password`; the flag wins if both are set, and with neither set the verb refuses with a usage error (exit 2) naming both - it never generates a password and never prompts. The env var keeps the secret off the process argv (visible in `ps`/shell history) that the flag exposes; the container-side `bench new-site` still receives it, so treat the value as one-time. The MariaDB root password takes the same shape via `CWCLI_DB_ROOT_PASSWORD` / `--db-root-password` (default `123`). The interactive decisions the human `cwcli init` prompts for become non-prompting errors: an existing bench with neither `--reuse-bench` nor `--no-reuse-bench` is a usage error (exit 2) naming both; a port conflict names `--port` (exit 1); containers that do not come up point at `cwcli status`/`cwcli logs` (exit 1); an invalid `--uid` (0, negative, or non-numeric) is rejected before any container work. `--uid` behaves as it does on `cwcli init` (including the root-host fallback, whose one-time warning is folded into the report's `warnings`). There is no `--auto-start` (compose `cwcli axi start` then re-run) and no `--verbose` (stdout is always TOON). `--bench` here is the NAME of the bench to create, distinct from the `--bench <index|label>` selector the other verbs use.
|
|
2525
2558
|
|
|
2526
2559
|
`cwcli axi rm <project> --yes` permanently removes an instance: its containers, named volumes (databases, sites, and files), own Docker Compose network, and local project directory.
|
|
2527
2560
|
It is the agent form of `cwcli rm`, and it runs the same code.
|