7.4 KiB
Session Handoff — Clusev v0.9.25 (clusev host CLI + short commands + help tab-URL)
Date: 2026-06-20
Branch: feat/v1-foundation
Status: Code released (tagged + pushed). Production deploy is PENDING — user-side.
TL;DR for the next session
A feature shipping a host CLI (clusev), short operator commands, a help "Commands / CLI"
topic, and help-tab URL syncing is fully implemented, tested, Codex-reviewed, locally
browser-verified, tagged v0.9.25, and pushed to Gitea. The only remaining step is the
production deploy (which I cannot do from this host — no SSH to the prod VM) and the post-deploy
domain R12. Pick up there.
What shipped (v0.9.25)
Five user requests, all delivered:
- Help tabs in the URL —
#[Url]onApp\Livewire\Help\Index::$topic. Clicking a topic syncs?topic=<key>; reload/bookmark/share keep the active tab. Defaultoverviewis omitted. (Settings tabs already had#[Url].) - Short host commands — new
clusevwrapper installed byinstall.shto/usr/local/bin. Subcommands:update,reset-admin,restart,logs,ps/status,migrate,artisan,version,help. Wraps the longdocker compose -f <prod compose> …invocations. Host command uses a space (clusev reset-admin); the underlying artisan name staysclusev:reset-admin. - All operator-facing surfaces switched to short commands + help explains the real command —
new bilingual help topic "Befehle / CLI" (
commands) documents every command with purpose, when-to-use, and the real underlying command (shown WITHOUT the long-f <compose>filename). Switched: versions update panel, help recovery/updates/domain-tls, settings/system reset hints, sentinel-write-failed lang strings, MOTD. - Long compose filename hidden, not renamed — user chose "wrapper hides it" (renaming collides
with the existing dev
docker-compose.ymland risks orphaning a live stack). A regression test (tests/Feature/CommandShortcutsTest.php) forbidsdocker-compose.prod.ymlon any display surface; the new CHANGELOG entry was even worded to avoid the literal (the/versionspage renders CHANGELOG.md — see gotcha below). - Detailed help descriptions — done in the commands topic + reworded recovery/updates/versions.
Spec / plan / commits
- Spec:
docs/superpowers/specs/2026-06-19-clusev-cli-and-command-shortcuts-design.md - Plan:
docs/superpowers/plans/2026-06-19-clusev-cli-and-command-shortcuts.md - Commits on
feat/v1-foundation(newest first):b619b32chore: release 0.9.25 (config version bump + CHANGELOG) ← tagv0.9.255967b7bfix: shell-escape the install dir when generating the clusev CLI (R15 Codex)8d2b708feat: short clusev commands in versions panel, lang strings, MOTD (+ test-string fixups)437a225feat: help tab-URL + Commands/CLI topic + short command copy580c72afeat: clusev host CLI wrapper for short stack commands
- Branch + tag pushed to
git.bave.dev/boban/clusev.git. Working tree clean.
Key files
- New:
docker/clusev/clusev(wrapper template,__CLUSEV_DIR__placeholder, unquoted assignment — install.sh injects aprintf %qshell-escaped path; do NOT re-quote it). - New:
tests/scripts/test-clusev-cli.sh(host bash test, 8 checks incl. injection-resistance). - New:
resources/views/livewire/help/content/{de,en}/commands.blade.php. - New:
tests/Feature/CommandShortcutsTest.php(leak guard + short-command assertions). - Changed:
install.sh(phase 9 renders+installs the CLI),app/Livewire/Help/Index.php,lang/{de,en}/{help,versions,settings,system}.php, help partials (recovery, updates, domain-tls),resources/views/livewire/versions/index.blade.php,docker/motd/00-clusev,tests/Feature/{HelpPageTest,ForgotPasswordSmtpAwareTest}.php,config/clusev.php,CHANGELOG.md.
Verification done
php artisan test(whole suite): 236 passed.bash tests/scripts/test-clusev-cli.sh: green (incl. a real injection-resistance check — confirmed the old quoted-rendering was exploitable, the new one is not).npm run build: OK.- Codex R15: PASS. It found ONE security issue — unescaped
$(pwd)rendered into the generated CLI, a root-code-injection vector via a hostile checkout path. Fixed (printf %q+ unquoted assignment) and re-reviewed PASS, including the embedded-newline edge case. - Local R12 (headless Chrome / puppeteer Docker against the dev stack on
http://localhost):/help200, URL syncs to?topic=commandson click, deep-link reload keeps the topic, commands content renders, 0 console/page/network errors;/versions200, showssudo clusev update, nodocker-compose.prod.yml. (Used gkonrad id=4, 2FA-off; temp password set + restored to the original hash afterwards.)
NEXT STEP (start here)
1. Deploy v0.9.25 to production (user runs this on the prod VM)
From this host I have no SSH access to the prod VM (10.10.90.165 — publickey/password denied)
and there is no local prod stack, so I cannot deploy. The operator runs, on the prod VM:
cd clusev && sudo ./update.sh
(This is the release that first ships the clusev wrapper, so use ./update.sh this once; the
update runs install.sh which installs /usr/local/bin/clusev, so from the NEXT release
sudo clusev update works. Alternatively click "Jetzt aktualisieren" in the panel.)
After it finishes, which clusev on the VM should resolve.
2. Domain R12 (I CAN do this over HTTP after the deploy)
The public domain panel.test.bave.dev → external proxy 10.10.20.20 (Zoraxy) → prod VM. Only
HTTP is needed (no SSH), via the puppeteer Docker image. Only meaningful AFTER the deploy (the
domain serves the old image until then). Verify on the domain:
/help200, click "Befehle / CLI" → URL?topic=commands, reload keeps it, DE/EN switch, no console errors./versionsshowssudo clusev update.- On the VM shell (read-only):
clusev help,clusev ps,clusev version. Do NOT runreset-admin/updateagainst the real admin.
Constraints & gotchas (carry forward)
- Respond in German in chat (code/commits/docs stay English). Caveman-terse mode was active.
- Gitea token: read ONLY at push time from
/home/nexxo/.env.gitea(GIT_ACCESS_TOKEN), never echo/commit; sanitize push outputsed -E 's#https://[^@]*@#https://<redacted>@#g; s/[0-9a-f]{40,}/<redacted>/g'. - De-Claude history: commits intentionally carry NO
Co-Authored-By: Claudetrailer (the project wants Claude-free history; history rewrite + force-push only at beta with explicit OK). - Dev DB: never
Server::createto inspect; use RefreshDatabase tests /Blade::render. - View-cache flake: run
php artisan view:clearbefore browser-verifying a.blade.phpchange; forartisan testflakiness isolate withVIEW_COMPILED_PATH=/tmp/vc-xxx. /versionsrenders CHANGELOG.md — whole-page leak scans flag historical changelog prose (e.g. the v0.4.1 entry literally contains@php); scope leak checks to UI chrome, not changelog.- Memory index updated: see
clusev-prod-deploy-user-side,clusev-versions-page-renders-changelog.
Not done / possible follow-ups
- Production deploy + domain R12 (above) — the only open item for THIS feature.
- (Backlog) de-Claude history rewrite, deferred to beta.
- (Optional) bash completion for
clusev; was intentionally left out (YAGNI).