Skip to content

Releases: dilitS/webox

v0.1.0-rc3 — Sprint 21 cPanel adapter foundation + public launch prep

Choose a tag to compare

@dilitS dilitS released this 25 May 10:04

Webox v0.1.0-rc3 — Release notes

Tag: v0.1.0-rc3 · published 2026-05-25 as a GitHub pre-release.
Type: Release candidate refresh — Sprint 21 (cPanel adapter foundation + public launch prep) layered onto the rc2 baseline.

RC3 is scope-additive over rc2. The MVP product surface is unchanged for smallhost-devil operators; this RC ships read-only diagnostic and infrastructure for cPanel. Promote to v0.1.0 GA by re-tagging the same SHA after .cursor/skills/release-check/SKILL.md is fully ticked. The next code-affecting work is the mutating cPanel adapter (Sprint 22 → v0.2.0-rc1).


What changed since v0.1.0-rc2

Sprint 21 (TASK-21.1 .. 21.6 + 21.8) lands in a single autonomous session: a full read-only cPanel client (HTTPS + SSH), a diagnostic CLI, live SSH probing for the preset registry, and the operator-facing artefacts the public launch needs (README EN, asciinema cast).

New transport layer — providers/cpanel/uapi/

A standalone, importable package the future providers/cpanel adapter will compose. No mutating endpoints are reachable from this client today — the MutatingClient interface returns ErrSprintScopeNotMutable so the type system enforces the "no destructive ops in v0.2-rc" guardrail.

  • HTTPS path (Client in client.go + transport.go):
    • Typed ListDomains / ListPassengerApps / ListMysqlDatabases / ListSSLKeys over https://host:2083/execute/<Module>/<Function>.
    • HTTPS-only (constructor refuses http://), Authorization: cpanel <user>:<token>, 4 MiB body cap, configurable *http.Client.
    • Exponential backoff on 429 / 5xx (500 ms × 2ⁿ, capped at 3 retries + injectable for fast tests).
    • 10 typed sentinels (ErrAuthenticationFailed, ErrRateLimited, ErrMalformedResponse, ErrModuleFunctionDenied, ErrTransportUnavailable, …) — operators can errors.Is without string-matching.
  • SSH fallback (SSHFallback in ssh.go + sshpool.go):
    • Shells out to uapi --user=<user> --output=jsonpretty <Module> <function> over the project's SSH pool.
    • Every shell argument routed through '\''-escaping shellQuote (defence in depth — the threat model is documented in the 10-case test table including $(rm -rf /) / `whoami` / O'Brien / ; ls; # injection attempts).
    • The SSHRunner seam keeps unit tests dependency-free; production SSHPoolRunner distinguishes non-zero exit (returned via exitCode) from transport failure (wrapped in ErrTransportUnavailable).
  • Composite layer (Composite in composite.go):
    • Closed Reader interface plus generics-driven dispatcher prefers HTTPS, fails over to SSH on errors.Is(err, ErrTransportUnavailable), surfaces auth / rate-limit / malformed / module-denied verbatim.
    • Generic tryComposite[T any] removes runtime type assertions — each List* method is a one-line forward.
  • Decoders (decoders.go):
    • Shape-tolerant decodeListResponse[T] accepts modern object-wrapper + top-level array + legacy map-keyed shapes (cPanel < 88 still in the wild).
    • Stable id-sort keeps test fixtures and TUI rows identical across cPanel versions.

Coverage: 77.9 % across 24 unit tests. 7 golden fixtures cover happy + edge paths; research-derived from public api.docs.cpanel.net until the live test account onboarding (Sprint 22 TASK-22.0) backfills them.

New CLI — webox doctor cpanel

webox doctor cpanel \
  --host=panel.example.com --user=operator \
  [--token=...] [--api-port=2083] [--ssh-port=22] \
  [--timeout=30s] [--no-ssh] [--no-uapi] [--json]

Exercises all four read-only modules in a single call. Routes through HTTPS when --token is supplied, falls over to SSH on transport failure. Section status taxonomy: OK / DISABLED (ErrModuleFunctionDenied — not a Webox failure, counts as OK in the rollup) / AUTH_FAILED / UNREACHABLE / FAILED. Rollup verdict: OK (all OK / DISABLED, exit 0), DEGRADED (mixed, exit 0), BLOCKED (everything failed, exit 1).

23 unit tests cover validation, rollup 7-case table, builder wiring (HTTPS-only / SSH-only / composite), happy / DEGRADED / BLOCKED outcomes, text + JSON output stability, and CLI flag parsing including the provider new cpanel <X> vs doctor cpanel ambiguity resolution.

Bug discovered + fixed in flight: transport.sleepWithCtx previously returned ctx.Err() unwrapped, so context-cancelled retries surfaced as FAILED instead of UNREACHABLE. The fix wraps ctx.Err() with ErrTransportUnavailable; smoke test against RFC 5737 unreachable IP (192.0.2.1) now correctly returns 4× UNREACHABLE + BLOCKED verdict.

webox doctor preset --probe over real SSH

The Sprint-19 stub became a live execution path. New invocation:

webox doctor preset --id=<preset> --probe \
  --host=<host> --user=<user> [--port=N] [--timeout=30s] [--json]

Pure summarization logic (11 unit tests across summarizeProbe / formatProbeText / formatProbeJSON) lives in cmd/webox/probe.go. Production runner shells out to the operator's native ssh binary with BatchMode=yes -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 — Webox owns no new auth surface (delegates to ~/.ssh/config + ssh-agent).

Output: per-probe block + summary line + confidence score (0-100, integer share of OK probes, rounded down so it's never inflated). JSON schema: preset_id, preset_name, host, user, confidence, ok_count, mismatch_count, failed_count, results[]. Exit codes: 0 (all OK), 1 (≥1 FAILED), 2 (≥1 MISMATCH).

Launch artefacts

  • README EN final at 58 lines (README.md) — single H1, value proposition, install snippet, "What works today" (5 bullets with Sprint 20 keybindings), provider-adapter invitation, 4-row roadmap, contributing/security/license. All 13 internal links verified. RC2 badge bumped to RC3 will follow this release.
  • asciinema 3.x cast + GIF — deterministic 45–60 s tour via scripts/record-demo.sh, pinned to 120×35 Bento Ultra framing. Embedded inline in README EN. Artefacts: docs/screenshots/sprint-21/demo.cast + demo.gif.

Documentation

  • Sprint 21 plan closed with full Outcome section: path-A selected (full parallel), 6/8 tasks done, TASK-21.7 (cPanel test account) carried over to Sprint 22.
  • Sprint 21 retro shipped at docs/retros/2026-05-25-sprint-21.md — what worked, friction, surprises, changes to apply going forward, open questions.
  • Sprint 22 plan (docs/sprints/sprint-22-cpanel-adapter-mutations.md) — mutating UAPI client + full providers.HostingProvider implementation + wizard integration + GHA template + E2E + v0.2.0-rc1 tag.
  • Sprint 23 plan (docs/sprints/sprint-23-second-provider-or-launch.md) — decision-doc: Path A (DirectAdmin) / Path B (CyberPanel) / Path C (Public Launch redux), matrix to be filled at Sprint 22 retro.

Quality bars met

Gate Status Threshold
Tests passing (make test -race) ✅ green All packages
Coverage (make cover-check) ✅ ≥ 79 % global; new providers/cpanel/uapi/ at 77.9 % ≥ 70 % global
Lint (golangci-lint v2) ✅ 0 issues 0 issues
Vulnerability scan (govulncheck) ✅ clean 0 known CVEs
Bento render perf (make bench-check) ✅ < 5 ms/op ≤ 5 000 000 ns/op
Manual smoke (make smoke-test) ✅ 5 scenarios × 34 assertions × ~83 s All scenarios green
CI bundle (make ci) ✅ green Full pipeline

Known gaps + carry-overs

  • TASK-21.7 — Live cPanel test account. Blocked on maintainer-side procurement (vendor purchase + H88 partnership outreach). Until it lands, the 7 fixtures in providers/cpanel/uapi/testdata/ stay research-derived; the cpanel-generic preset remains research (not verified). Sprint 22 starts with TASK-22.0 = account procurement as a P0 gate.
  • MVP product surface is unchanged for smallhost-devil operators. RC3 does not ship a cPanel provider adapter — the providers/cpanel/cpanel.go adapter implementing providers.HostingProvider.CreateProject / RemoveProject / ... lands in Sprint 22. RC3 only ships diagnostic + transport.
  • Mutating ops gated behind a future env-var. Sprint 22's MutatingClient.Call will require WEBOX_CPANEL_MUTATIONS=1 as defence in depth on top of the type-system enforcement — operator must opt in explicitly.

Upgrade path

  • From v0.1.0-rc2: drop in webox binary; no config migration needed. New CLI surfaces are additive.
  • Existing smallhost-devil users: nothing to do; no behaviour change.
  • Operators wanting to evaluate cPanel diagnostic: webox doctor cpanel --host=panel.example.com --user=operator --token=$TOKEN returns a verdict; mutating ops will arrive in v0.2.0-rc1.

Next milestone

Sprint 22 — cPanel adapter part 2 (mutating ops + adapter + wizard + GHA template + E2E + live-account fixtures) ships as v0.2.0-rc1.

Webox v0.1.0-rc2 — Sprint 20 (TUI polish + Provider Catalog)

Choose a tag to compare

@dilitS dilitS released this 25 May 08:49

Webox v0.1.0-rc2 — Release notes

Tag: v0.1.0-rc2 · published 2026-05-25 as a GitHub pre-release.
Type: Release candidate refresh — Sprint 20 (TUI polish + Provider Catalog) ships into the RC channel alongside the new manual-validation harness.

Promote this commit to v0.1.0 (GA) by re-tagging the same SHA after the manual checklist in .cursor/skills/release-check/SKILL.md is fully ticked. No code changes expected between RC2 and GA; the next code-affecting work is on the v0.2 track (Sprint 21 cPanel adapter).


What changed since v0.1.0-rc1

This RC bundles Sprint 20's TUI hardening, the Sprint 19 carry-over Provider Catalog screen, and a brand-new tuistory-driven PTY smoke harness that validates every user-facing change against the actual ./bin/webox binary on every push.

New cockpit surfaces

  • Provider Catalog screen (p from dashboard) — a read-only browser over the Sprint-19 embedded preset registry. Rows are grouped by region (🇵🇱 Poland, 🇪🇺 Europe, 🌍 Global, 🛠 Advanced) with status pills (VERIFIED / CANDIDATE / RESEARCH / DEPRECATED / COMMUNITY) and capability badges (SSH · API · Node · SSL · DB · Logs · Safe Restart · Fixtures). ↑/↓ walks the cursor, Enter/ toggles a deep-dive strip (markets, panel API, restart method, paths, probes, known risks, sources, verification audit trail). c copies a stable plain-text "Webox Provider Briefing" to the OS clipboard (pbcopy / xsel / xclip / wl-copy / clip.exe); on headless servers the failure surfaces an inline remediation hint instead of crashing.
  • Help overlay (? from any surface) — a centred fullscreen modal that lists keybindings sourced from the active surface's footer at render time. The list cannot drift from reality because it is parsed from the same string the chrome already advertises. While the overlay is up, every other key is silently swallowed except ?, Esc, q, Ctrl-C (strict block, matching the host-key modal pattern).

Project Detail tab unstubs

Both v0.2-flagged tabs are now first-class read-only views (no backend I/O, no wizard, no risk of writes):

  • Tab 2 — Environment Diff. A compact table of secrets/registry.json entries: alias, env-var key, last_rotated_at relative time, source backend, stale flag (older than 60 days). Onboarding hint when the project has no entries yet.
  • Tab 3 — Database. A stack-aware connection cheatsheet (mysql / postgres / redis / sqlite) with copy-friendly one-liners, host hint inferred from profile, and a per-stack documentation link.

Standard mode mini-bento

The 100×30 Standard mode now lays out a 4-tile mini-bento (projects + server detail above, CI/CD strip + log strip below) instead of the old dual-tile fallback. Density is now within 5 lines of Ultra at the same width, without compromising the safe-zone Tiny fallback at sub-80×24.

Mouse semantics

  • Layout-aware left-click. From the dashboard, a click anywhere inside the Projects tile drills into Project Detail; clicks on status bar / footer / empty space are silent no-ops (no more accidental focus loss).
  • From Project Detail, a body click returns to the dashboard. Tab is a new alias for the same back-navigation (matches the new help overlay's listed binding).

Footer / chrome hints

  • Per-surface footers (projectdetail, projectwizard, initwizard, resumewizard, importpreview, catalog) carry context-specific keybindings instead of the old global hint. The chrome no longer advertises the never-implemented [/] command palette.
  • Focus-mode footer (when a tile is locked via Tab) shows focus: <tile> · [PgUp/PgDn] scroll panel · [Esc] release.
  • Bento UltraPlus's deep-dive strip placeholder is gone — the mode now uses the same 4-band layout as Ultra at higher resolutions until a real deep-dive tile lands in v0.2.
  • Bento Tiny fallback's misleading [r] to redraw hint is replaced with Resize to ≥ 100×24 to unlock cockpit.

Manual smoke harness

  • make smoke-test. New scripts/manual-test/ Node 24+ project drives ./bin/webox --mock through every Sprint 20 user-facing change via tuistory (Playwright-for-terminals): 5 scenarios × 34 assertions × ~83 s wall-clock end-to-end. Scenarios cover bento mode flipping on resize, help overlay strict-block routing, Provider Catalog navigation + clipboard, Project Detail tab navigation including the Tab back-nav alias, and layout-aware mouse clicks (status bar no-op, Projects tile drill, body-click back). Artefacts: 17 text snapshots + REPORT.md under docs/screenshots/sprint-20/manual/.
  • CI integration. New advisory job smoke-tui in .github/workflows/ci.yml runs the harness on every push / PR (Ubuntu, Node 24, pinned actions/setup-node@48b55a0 SHA). The job is continue-on-error: true and excluded from ci-summary.needs until we accumulate a few weeks of green runs; on every run it uploads the manual snapshots + REPORT.md as the smoke-tui-<sha> artefact (14-day retention) so reviewers can diff the rendered terminal output without re-running the suite locally. Makefile::smoke-test pins VERSION=smoke-test via sub-make so snapshots stay deterministic between commits.

Tooling

  • cmd/screenshot/main.go — new development tool that programmatically renders tui.Model to a deterministic frame for documentation work. Replaces the ad-hoc probe.go scripts used during Sprint 20.

Quality bars met

Gate Status Threshold
Tests passing (make test -race) ✅ green All packages
Coverage (make cover-check) ✅ ≥ 80 % ≥ 70 % global
Lint (golangci-lint v2) ✅ 0 issues 0 issues
Vulnerability scan (govulncheck) ✅ clean 0 known CVEs
Bento render perf (make bench-check) ✅ < 5 ms/op ≤ 5 000 000 ns/op
CI bundle (make ci) ✅ green Full pipeline
Manual smoke (make smoke-test) ✅ 5/5 scenarios, 34/34 assertions n/a yet

Documentation

Known limitations (unchanged from rc1)

  • One verified provider only. Adapters for cPanel, DirectAdmin, CyberPanel are scaffolded but not implemented. Sprint 21 ships the cPanel adapter foundation (read-only UAPI client + SSH fallback + webox doctor cpanel); creation flows land in Sprint 22.
  • Asciinema demo + static dashboard.png not yet recorded (Sprint 21 TASK-21.6).
  • EN landing body still in PL — head/meta translated; body pass in Sprint 21 TASK-21.5.
  • No Homebrew tap / go install published yet — lands with the GA promotion.

Upgrade notes

If you tried v0.1.0-rc1:

  1. git pull && make build — that's it. No config migration, no schema change, no flag rename.
  2. From the dashboard, press ? to see the new help overlay. Press p to open the Provider Catalog. Press Enter on a project, then 2 and 3 to see the new Env Diff / Database tabs. Press Tab from any tab to return to the dashboard.

If you skipped rc1 entirely:

  1. git clone https://github.com/dilitS/webox.git && cd webox && make build
  2. ./bin/webox --mock to explore the cockpit with synthetic data.
  3. ./bin/webox (without --mock) launches the init wizard for your first profile.

Security

  • License: Apache License 2.0 (unchanged).
  • Disclosure: SECURITY.md — coordinated disclosure via private GitHub Security Advisories.
  • No new dependencies on the runtime side. The smoke harness is dev-only (scripts/manual-test/) and never imported by the production binary; it ships nothing into release artefacts.

Credits

In addition to the rc1 credits:

  • remorses / tuistory — Playwright-for-terminals. Made the manual smoke harness possible inside a normal CI minute budget.
  • Sprint 20 reviewers for catching the dashboard footer drift and the v0.2-flagged tab alert noise during pre-release walkthroughs.

Next: v0.1.0 GA promotion or v0.2.0 track

When the manual checklist in .cursor/skills/release-check/SKILL.md is ticked, promote this commit to GA:

git tag v0.1.0 v0.1.0-rc2
git push origin v0.1.0

The GA promotion adds: cosign signature, SLSA provenance, GoReleaser-built multi-arch binaries (darwin/arm64, darwin/amd64, linux/amd64, linux/arm64), Homebrew tap PR, and the v0.1.0 retrospective.

The next code-affecting work is on the v0.2.0 track — Sprint 21 starts the cPanel adapter foundation in parallel with public-launch prep (README EN final, asciinema demo, cPanel test account onboarding). See docs/sprints/sprint-21-cpanel-adapter-prep.md.

Webox v0.1.0-rc1 — release candidate

Pre-release

Choose a tag to compare

@dilitS dilitS released this 25 May 03:10

Webox v0.1.0-rc1 — Release notes

Tag: v0.1.0-rc1 · published 2026-05-25 as a GitHub pre-release.
Type: Release candidate — operator-only manual checklist still pending before GA.

Promote this commit to v0.1.0 (GA) by re-tagging the same SHA after the manual checklist in .cursor/skills/release-check/SKILL.md is fully ticked. No code changes expected between RC1 and GA.


Highlights

Webox v0.1 is the first publicly distributed cut of a terminal operator cockpit for developers running projects on shared hosting. After 14 sprints of docs-first design, hardening, and adapter-pattern work, plus a launch-readiness Sprint 15, the codebase is ready for community review.

  • One verified hosting provider — small.pl / Devil — implemented end-to-end behind the providers.HostingProvider interface. Adapters for cPanel, DirectAdmin, and CyberPanel are scaffolded by webox provider new <name> --preset=<…> and slated for v0.2 / v0.3.
  • Bento Ultra cockpit (120×35) with live tiles: project list + detail, CI/CD pipeline modal, server topology, live log stream, header server metrics. Standard Cockpit (100×30) auto-fallback for smaller terminals.
  • Transactional project wizard — subdomain → database → SSL → GitHub repo + workflow → first deploy, with LIFO rollback on any failure (no orphaned resources).
  • Secrets done right — system keyring (Keychain / Secret Service / Credential Manager) with AES-256-GCM + Argon2id fallback for headless boxes. Zero plaintext secrets in config.json. Ever. AES-GCM nonce sourced strictly from crypto/rand.Read(12 bytes) — no time.Now(), no counters.
  • Strict SSH posture — TOFU on first connect, strict block on host-key mismatch with an explicit out-of-band confirmation modal, never auto-accept.
  • Zero telemetry / phone-home. --debug-trace writes JSONL strictly to ~/.cache/webox/trace.jsonl (mode 0600, redactor-filtered). The file never leaves the operator's machine.
  • webox provider new <name> [--preset=PRESET] — adapter scaffolding generator with 4 presets (blank, cpanel-uapi, directadmin, cyberpanel). Generates a working go build-clean skeleton + TDD test stubs + fixture README in 30 seconds, and patches the production blank-import block idempotently.

Quality bars met

Gate Status Threshold
Tests passing (make test -race) ✅ green All packages
Coverage (make cover-check) ✅ 80.4 % ≥ 70 % global
Lint (golangci-lint v2) ✅ 0 issues 0 issues
Vulnerability scan (govulncheck) ✅ clean 0 known CVEs
Bento render perf (make bench-check) ✅ 195 666 ns/op (worst) ≤ 5 000 000 ns/op
CI bundle (make ci) ✅ green Full pipeline
Coverage of TUI surfaces ✅ 100 % (per package)
Generated package builds ✅ verified end-to-end (go build ./providers/<gen>/...) n/a
Generated package tests pass ✅ verified n/a

Documentation

  • README.md — 136-line conversion-optimised launch landing.
  • CONTRIBUTING.md — 143-line EN on-ramp (5-min setup → branching → PR checklist → 3 contribution paths → guardrails → maintainer SLA).
  • docs/contributing/PROVIDER.md — 4-hour walkthrough for adding a hosting-panel adapter.
  • docs/SECURITY.md — full threat model, secret-handling policy.
  • docs/DESIGN.md — architecture, contracts, state machine, caching, rollback.
  • docs/ROADMAP.md — v0.1 → v0.2 → v0.3 → v1.0 plan.

Known limitations

  • One verified provider only. Adapters for cPanel, DirectAdmin, CyberPanel are scaffolded (webox provider new …) but not implemented. v0.2 ships cPanel; v0.3 ships DirectAdmin. See .github/issue-drafts/ for community on-ramps.
  • Asciinema demo + static dashboard.png not yet recorded. Scripts are in scripts/record-demo.sh and scripts/capture-screenshot.sh. Operator records the canonical artefacts before flipping to GA.
  • EN landing body still in PL. Head/meta layer is translated; body needs a native-speaker review pass. Landing is gitignored (decoupled deploy via Cloudflare Pages / Vercel), so this does not block the binary release.
  • --preset=PRESET requires the equals form. Space-separated --preset PRESET is not supported in v0.1 (parser consistency with --debug-trace=PATH). Help text + error messages reflect this; space-form support is a v0.2 candidate.
  • No Homebrew tap / go install published yet. v0.1.0-rc1 ships as a tagged source release only. Homebrew formula + GoReleaser binary publishing land with the GA promotion.

Upgrade notes

This is the first public release — there is nothing to upgrade from.

If you are migrating from a hand-written shell script:

  1. git clone https://github.com/dilitS/webox.git && cd webox && make build
  2. ./bin/webox --mock to explore the cockpit with synthetic data.
  3. ./bin/webox (without --mock) launches the init wizard for your first profile.
  4. ./bin/webox doctor validates your local setup any time.

Security

  • License: Apache License 2.0 (changed from MIT on 2026-05-25 — explicit patent grant for commercial-panel adapters).
  • Disclosure: see SECURITY.md — coordinated disclosure via private GitHub Security Advisories. Never open a public issue for a security finding.
  • Threat model: docs/SECURITY.md (STRIDE-light, 6 attacker profiles, 9 mitigations).

Credits

  • Charmbracelet — Bubble Tea, Lipgloss, Bubbles, the entire Charm ecosystem.
  • The small.pl / Devil team — for shipping a hosting platform with a real CLI in 2026 and for being a generous launch partner.
  • Go SSH and keyring maintainersgolang.org/x/crypto/ssh, zalando/go-keyring, and the long tail of well-licensed Go libraries.
  • Pre-implementation reviewers of the 619-line PRD monolith for catching design drift before a single line of production code shipped.

Next: v0.1.0 GA promotion

When the manual checklist is ticked (see .cursor/skills/release-check/SKILL.md):

git tag v0.1.0 v0.1.0-rc1            # promote the same commit
git push origin v0.1.0               # triggers release.yml workflow

Or use the helper:

make release-promote FROM=v0.1.0-rc1 TO=v0.1.0   # (future Sprint 16 target)

The GA promotion adds: cosign signature, SLSA provenance, GoReleaser-built multi-arch binaries (darwin/arm64, darwin/amd64, linux/amd64, linux/arm64), Homebrew tap PR, and the v0.1.0 retrospective.