From 038412bb0f57d97fdab133b79ba87dd62b4b645b Mon Sep 17 00:00:00 2001 From: Dave Sargent Date: Fri, 29 May 2026 09:33:03 -0700 Subject: [PATCH 1/8] refactor(gearbox): adopt webcore/core/errors Repoint the 9 apperrors import sites to github.com/sarg3nt/webcore/core/errors and delete the now-duplicated internal/framework/errors. Adds webcore require + local replace directive. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/webcore-extraction-plan.md | 523 ++++++++++++++++++ gearbox/go.mod | 18 +- gearbox/go.sum | 62 +-- gearbox/internal/framework/errors/errors.go | 241 -------- .../framework/errors/errors_writehttp_test.go | 64 --- gearbox/internal/framework/handler/alerts.go | 2 +- .../framework/handler/api_certificates.go | 2 +- .../internal/framework/handler/api_logs.go | 2 +- .../framework/handler/api_services.go | 2 +- .../internal/framework/handler/api_traffic.go | 2 +- gearbox/internal/framework/handler/backup.go | 2 +- gearbox/internal/framework/handler/config.go | 2 +- .../internal/framework/handler/security.go | 2 +- gearbox/internal/framework/handler/users.go | 2 +- 14 files changed, 572 insertions(+), 354 deletions(-) create mode 100644 docs/webcore-extraction-plan.md delete mode 100644 gearbox/internal/framework/errors/errors.go delete mode 100644 gearbox/internal/framework/errors/errors_writehttp_test.go diff --git a/docs/webcore-extraction-plan.md b/docs/webcore-extraction-plan.md new file mode 100644 index 0000000..f98c778 --- /dev/null +++ b/docs/webcore-extraction-plan.md @@ -0,0 +1,523 @@ +# Web-core extraction plan + +Status: **Planned, not started.** +Owner: Dave + Claude (Opus 4.7 → upgrading) +Last updated: 2026-05-28 +Working directories involved: `/Users/dave/src/gearbox`, `/Users/dave/src/libation`, future `/Users/dave/src/webcore` + +This document is the single source of truth for extracting shared web framework code out of `gearbox` and `libation` into a new module so all current and future sarg3nt web apps consume the same UI primitives, auth flow, session/CSRF handling, SSE transport, and form/validation helpers. It is written to be self-contained — a fresh Claude session must be able to pick up from here without re-running the audit. + +--- + +## 1. Decisions (locked) + +| # | Decision | Value | +|---|----------|-------| +| 1 | Module path | `github.com/sarg3nt/webcore` | +| 2 | Repo layout | Single repo, two top-level Go packages: `ui/` and `core/` | +| 3 | Cutover order | Gearbox first (source of truth), then libation | +| 4 | Pre-extraction cleanup | Part of extraction, not separate gearbox PRs | +| 5 | Login UI scope | Include password reset, change-password, forgot-password flows in MVP | +| 6 | SSE transport | Extract `core/transport/sse.go` + `ui/static/js/sse.js` | +| 7 | `dev_bypass` build tags | Lift gearbox's `--tags dev` loopback bypass into shared `core/auth` | + +User instruction verbatim: "Write the plan in a detailed .md file in either rep, I don't care which. I need to restart VS code / Claude as there is a new version of Claude out that we need to upgrade to. But write the plan first, make sure you have all the context to get back to work on this once the restart and new Opus model are online." + +--- + +## 2. Conversation context — what just happened + +Earlier in the same session before this plan was written: + +### Libation UI fixes already shipped (working in browser, not committed) + +Goal was to bring libation's layout closer to gearbox. User reported three specific issues: + +1. Left-hand nav scrolled with the page — wanted fixed. +2. Toasts appeared in the wrong place (bottom-right vs gearbox's top-right). +3. Sidebar collapse was visually broken. + +Changes applied in libation: + +- `internal/framework/ui/toast.templ` — moved container `fixed bottom-4 right-4 z-50` → `fixed top-4 right-4 z-[9999]` with `pointer-events-none`. +- `assets/static/css/sidebar.css` — full rewrite. Fixed-position rail (15rem expanded, 3.5rem collapsed), `transition: width 0.25s ease-in-out` on sidebar + `margin-left` on `#main-content`, label fade-out via opacity+width, collapsed nav-link centers icon, mobile (` carries only positioning, inner `flex flex-col w-full h-full` wrapper splits non-scrolling header from `