Lessons and gotchas#
These cost time on the first site and will come up again. The API-level facts are on HubSpot facts; these are the ones that shaped the workflow itself.
Safety#
- Account fall-through. An unknown
--accountname silently uses the default account. Every tool that writes checkshs account listand a sentinel page first. - Fetch before you restore. The portal was a round ahead of git once. Restoring a module from git would have
reverted someone's work.
hs cms fetchfirst, every time. - Module uploads have no undo button. They're live within a minute. Additive variants plus the regression gate are the only protection, and the fetched backup is the rollback.
- Keys pasted into chat get rotated. Keep them in
~/.hscli/config.ymland.env.
Audit and rules#
- The crawler reads what the CSS says, not what the screen shows. The first crawl took mobile padding for desktop, and the rules built on it were wrong. Check one value in a browser.
- Numbered, append-only rules. Review rounds add rules, they don't rewrite them, so every draft decision can be traced back.
- Don't reuse another site's rules. Two sites built with this process came out with different chassis. Derive from each site's crawl.
Modules#
- Presets hide nothing. Hiding controls behind a preset failed the editor check within a day. Every control a preset owns offers Default and can be overridden.
- Retiring a preset value breaks saved pages. Keep the old values renderable and re-save the affected pages through the API.
- Parallel modules beat restyles. A prefixed rebuild leaves every legacy instance alone, and it lets you consolidate (three heroes into one).
- Generated module files are not for hand edits. Give the generator a
--check.
Pages#
- Iterate on the draft. Every round in HubSpot is a round you can't diff. Drafts are HTML in git.
- Splice, don't regenerate, once a page is approved. A full generator rerun can pick different assets on a machine with a different crawl cache. After approval, edit the approved sections of the draft in place and republish.
- Repo-local assets go up first. The publisher rewrites
../assets/…to File Manager URLs. If the file isn't there yet, the page ships a broken image, and the CDN caches the 404.
Browser checks#
- Headless Chrome gets its own profile. Screenshots taken through the user's profile were flaky, so the shooter always creates a temporary one and never touches the user's browser.
- Background windows don't animate. Chrome pauses
requestAnimationFramein a background window, so automated checks can't judge motion. Drive the animation's clock by hand for order checks, and judge the feel by eye in a visible window. - Long recordings against a live page drop the CDP socket. Record from a local harness.
Process#
- Write the log the day it happens. The first site's
CLAUDE.mdholds a dated line for every upload and publish, with ids. That is what made "what is on which portal" answerable weeks later. - Name the next manual step. Things only the UI can do (global content settings, publishing from staging) go in the log as pending, with the name of the person whose click it is.