M0 Phase 0: upstream bump to livetemplate v0.19.1 + client 0.18.2 - #296
Conversation
Tinkerdown was pinned to livetemplate v0.10.0 while upstream shipped nine minor releases. Adopt the current latest across the stack: livetemplate v0.10.0 -> v0.19.1 lvt/components pseudo -> v0.2.0 @livetemplate/client 0.14.3 -> 0.18.2 No source changes were required. Tinkerdown's livetemplate API surface is 10 symbols, all stable across the range, and the one API removed upstream (WithStore, v0.19.0) was never used here. The client version is a wire contract, not a preference: livetemplate v0.18.0 added the ClientVersion constant precisely because there is no runtime server<->client version handshake, and v0.19.0 declares 0.18.2 as the compatible pair for this server release. Also fix `make build` to run `npm ci` before `npm run build` (#295). It previously bundled whatever happened to be in client/node_modules rather than what the lockfile pins -- on this checkout node_modules had drifted to 0.11.9, so any rebuild silently reverted shipped fixes including the data-lvt-force-update handling the checkbox e2e tests depend on. Without this fix the next `make build` would revert the bundle committed here. Verification (all under GOWORK=off, since a go.work one directory up redirects to local upstream checkouts that are ahead of the published tags -- so without it the pinned dependency is not what gets tested): - go build ./... clean - full `go test ./...` green, including the root package that holds all 32 //go:build !ci e2e files (827s) - the discriminating e2e set 14/14: TestAutoTables_*, TestAutoTasks_* (checkbox toggle), TestExecToolbar*, TestLvtSourceMarkdownToggle* - bundle provenance confirmed directionally: ctrlKey occurrences 1 -> 5, matching the v0.18.2 client fix for bare-key lvt-on:keydown firing while Ctrl/Meta/Alt is held Plan tracker updated in the same commit (convention 4), recording four findings: WithEphemeralSweepTTL has no call site in tinkerdown (it is a HandleOption; tinkerdown never calls Handle()); `go test -tags=browser` was fiction (no such tag -- e2e is opt-out via !ci, not opt-in); the go.work redirect; and that websocket.go still writes each inline block to /tmp, contradicting the reframe's disk-free claim now that v0.17.0 ships WithParseFS -- deferred to M1 Phase 3 rather than refactored here. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018M9pJSPmG6i1D8s6rpEV4h
ReviewThis is a clean, well-scoped dependency bump. Verified several of the PR's claims directly against the merged tree:
Code quality: No notes — there's no hand-written logic in this diff to critique beyond the one-line Makefile fix, which is correct and minimal. Bugs/correctness: None found. The one item worth flagging for awareness rather than action: the bundle provenance check ( Performance: N/A — no runtime logic changed. Security: No concerns. Test coverage: The verification story here is unusually thorough for a dependency bump (14/14 discriminating e2e set, directional bundle check, manual browser pass, CSS parity check). One gap acknowledged in the plan tracker itself: CI structurally cannot catch an e2e regression on this bundle going forward, since the tests that would are Also confirmed per CLAUDE.md guidance: this PR doesn't introduce or reimplement any Nice work tying the dependency bump, the #295 build fix, and the plan-tracker update into one coherent, well-documented change. |
Addresses the review-bot suggestion on #296: this asset is generated yet tracked, so it can silently disagree with the lockfile that supposedly produced it -- the exact failure class recorded in #295. Documents the three things that are non-obvious about it: regenerate via `make build-client` (never a bare `npm run build`, which bundles whatever is in node_modules); CI cannot catch a regression here because the e2e tests that would are !ci-only, so a local run is the only gate; and check direction rather than mere difference, since a downgrade also differs from HEAD. Also notes that the client version is a wire contract pinned by livetemplate's ClientVersion constant, not whatever npm calls latest. Lands beside the files rather than in CONTRIBUTING so it is visible to whoever is about to touch them. Never served over HTTP -- client assets go out through the named GetClientJS/GetClientCSS accessors, not the embedded FS wholesale -- so this only adds ~2KB to the binary. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018M9pJSPmG6i1D8s6rpEV4h
|
Thanks — took the bundle-provenance suggestion. Added It documents the three non-obvious things: regenerate via You're right that No behavior change; Leaving the |
Review: M0 Phase 0 upstream bumpReviewed the diff (CHANGELOG, Makefile, go.mod/go.sum, client package files, plan tracker, generated client bundle). Overall this is a clean, well-documented dependency bump with no hand-written source changes — solid work. A few notes: Strengths
Minor observations (non-blocking)
SecurityNo security concerns — this only bumps first-party ( Nice, thorough verification writeup in the PR description — the directional bundle check and the |
|
Second-pass notes addressed:
CI e2e smoke subset — agreed, and it's the sharpest observation in the review. You're right that this PR's own root cause was 'a bad bundle slipped through because nothing caught it,' and the mitigation still bottoms out in a human remembering to run Plan-tracker size — noted and accepted. Convention 4 requires the drift land in the same commit as the code, so the ratio is by design, but it does make the diff stat misleading to a skimmer. No new test coverage — correct and expected; zero source changes to cover. |
First phase of the ephemeral-UI reframe plan (M0 Phase 0).
Tinkerdown was pinned to
livetemplate v0.10.0while upstream shipped nine minor releases. This adopts the current latest across the stack.github.com/livetemplate/livetemplategithub.com/livetemplate/lvt/components2026-02-28@livetemplate/clientnode_moduleshad drifted to 0.11.9No source changes were required. Tinkerdown's livetemplate API surface is 10 symbols, all stable across the range, and the one API removed upstream (
WithStore, v0.19.0) was never used here.The client version is a wire contract, not a preference: livetemplate v0.18.0 added the
ClientVersionconstant precisely because there is no runtime server↔client version handshake, and v0.19.0 declares0.18.2as the compatible pair for this server release.Also fixes #295
make buildrannpm run buildwith no install step, so it bundled whatever happened to be inclient/node_modulesrather than what the lockfile pins. On a drifted checkout this silently regenerated the committed bundle from a stale dependency and reverted shipped fixes — including thedata-lvt-force-updatehandling the checkbox e2e tests depend on. Now runsnpm cifirst.This is folded in here deliberately: without it, the next
make buildwould silently revert the bundle this PR commits.Verification
All under
GOWORK=off— ago.workone directory up redirectslivetemplate/lvtto local checkouts that sit ahead of the published tags, so without it the pinned dependency is not what gets tested.go build ./...clean; fullgo test ./...green, including the root package holding all 32//go:build !cie2e files (827s)TestAutoTables_*,TestAutoTasks_*(checkbox toggle),TestExecToolbar*,TestLvtSourceMarkdownToggle*ctrlKeyoccurrences 1 → 5, matching v0.18.2's client fix for bare-keylvt-on:keydownfiring while Ctrl/Meta/Alt is held. A size delta alone would not distinguish an upgrade from a downgrade —make buildregenerates the committed client bundle from stale node_modules, breaking checkbox e2e tests #295's bad bundle also differed from HEAD.browser.cssis byte-identical for a good reason (the bump doesn't touch tinkerdown's own CSS sources); the client'slivetemplate.cssis deliberately not bundled, as it only configureslvt-fx:*, unused here.examples/action-buttons, full-page screenshot — styling, auto-table, form controls, button variants and syntax highlighting all correct; console clean, no JS exceptions.Plan tracker updated in the same commit (convention 4)
Four findings recorded, three of which outlive this phase:
WithEphemeralSweepTTLhas no call site — it's aHandleOptionand tinkerdown never callsHandle(). The plan's Implementation item assumed otherwise; struck through with the reason so M1 doesn't re-propose it.go test -tags=browser ./...was fiction — no such tag exists. E2E is opt-out (!ci), and CI excludes it twice over (-tags=ciand-skip='E2E|e2e'), so CI structurally cannot catch an e2e regression; the local run is the only gate.go.workredirect — local builds were never testing the published dependency.GOWORK=offis now written into § Verification as the operational form of session-guide convention 11.websocket.go:467still writes each inline block to/tmp, contradicting the reframe's "disk-free ephemeral path" claim now that v0.17.0 shipsWithParseFS. Deferred to M1 Phase 3 rather than refactored here — a WS hot-path rewrite inside a version-bump phase would destroy the phase's isolability.The plan's "multi-minor upstream bump may ripple" risk is retired: it was aimed at the Go boundary, and the actual hazard was committed-artifact provenance, now recorded as a standing risk.
🤖 Generated with Claude Code
https://claude.ai/code/session_018M9pJSPmG6i1D8s6rpEV4h