[PR #99] [MERGED] fix: prevent stale SPA shell from resurrecting fixed frontend bugs #99

Closed
opened 2026-08-15 07:30:12 +02:00 by zaph0d · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/niels-emmer/myace/pull/99
Author: @niels-emmer
Created: 8/14/2026
Status: Merged
Merged: 8/14/2026
Merged by: @niels-emmer

Base: mainHead: fix/stale-spa-shell-and-safari-blob-download


📝 Commits (2)

  • 681afac docs: rewrite adapters research as current-state adapter reference
  • c0bf340 fix: prevent stale SPA shell from resurrecting fixed bugs; defer blob revoke for Safari downloads

📊 Changes

9 files changed (+356 additions, -330 deletions)

View changed files

📝 README.md (+7 -9)
docs/ADAPTERS_RESEARCH.md (+0 -313)
📝 docs/README.md (+4 -3)
docs/adapters-research.md (+313 -0)
📝 docs/extending.md (+2 -2)
📝 frontend/nginx.conf (+18 -0)
📝 frontend/src/pages/TargetExporter.test.tsx (+5 -1)
📝 frontend/src/pages/TargetExporter.tsx (+6 -1)
📝 scripts/sync_wiki.py (+1 -1)

📄 Description

Summary

  • Root-caused a live report that the compile-zip download bug (fixed in #95) still reproduced on the deployed VPS with an already-existing profile ("IAC expert") + claude-code target. Direct testing against the live production HTTPS endpoint and against the exact real profile row (via compile_profile() called directly in the backend container) both confirmed the server-side fix is correct and complete — the discrepancy is a stale browser tab/cache serving the pre-#95 frontend bundle, which nothing was forcing to refresh.
  • nginx.conf served index.html with no Cache-Control header, so a browser that already loaded the app could keep running an old cached shell (pointing at a JS bundle hash that no longer exists after the next deploy) indefinitely — a normal reload doesn't guarantee a refetch, and users have no way to know their tab is stale. Now index.html is Cache-Control: no-cache (always revalidate) and hashed /assets/* files get long-lived immutable caching, so every deploy is picked up on next load.
  • Also fixed a related Safari-specific bug in TargetExporter.tsx: URL.revokeObjectURL() was called synchronously right after a.click(), which races Safari's native "Save As" dialog — WebKit needs the blob to stay alive until the user responds, so an immediate revoke can make that save fail or truncate. Revocation is now deferred by one tick.

Test plan

  • npm run lint and npx vitest run pass (updated the download test to await the now-deferred revokeObjectURL call)
  • Rebuilt local myace-frontend container; confirmed index.html sends Cache-Control: no-cache and /assets/*.js sends public, max-age=31536000, immutable
  • Verified via direct backend compile_profile() call against the real "IAC expert" profile (base Software Engineer + 4 additional collections) with target=claude-code: correctly produces 35 files (proper CLAUDE.md, individual .claude/skills/*/SKILL.md, .claude/agents/*.md, .claude/commands/*.md), not a single AGENTS.md
  • Real (non-scripted) browser click on "Download as .zip" against the rebuilt local container downloads a correct 23-file zip

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/niels-emmer/myace/pull/99 **Author:** [@niels-emmer](https://github.com/niels-emmer) **Created:** 8/14/2026 **Status:** ✅ Merged **Merged:** 8/14/2026 **Merged by:** [@niels-emmer](https://github.com/niels-emmer) **Base:** `main` ← **Head:** `fix/stale-spa-shell-and-safari-blob-download` --- ### 📝 Commits (2) - [`681afac`](https://github.com/niels-emmer/myace/commit/681afacb4717c3a4062dcc9d5fd514fda422fadb) docs: rewrite adapters research as current-state adapter reference - [`c0bf340`](https://github.com/niels-emmer/myace/commit/c0bf340bd83658dd580ba867b695b3e610b74cbf) fix: prevent stale SPA shell from resurrecting fixed bugs; defer blob revoke for Safari downloads ### 📊 Changes **9 files changed** (+356 additions, -330 deletions) <details> <summary>View changed files</summary> 📝 `README.md` (+7 -9) ➖ `docs/ADAPTERS_RESEARCH.md` (+0 -313) 📝 `docs/README.md` (+4 -3) ➕ `docs/adapters-research.md` (+313 -0) 📝 `docs/extending.md` (+2 -2) 📝 `frontend/nginx.conf` (+18 -0) 📝 `frontend/src/pages/TargetExporter.test.tsx` (+5 -1) 📝 `frontend/src/pages/TargetExporter.tsx` (+6 -1) 📝 `scripts/sync_wiki.py` (+1 -1) </details> ### 📄 Description ## Summary - Root-caused a live report that the compile-zip download bug (fixed in #95) still reproduced on the deployed VPS with an already-existing profile ("IAC expert") + claude-code target. Direct testing against the live production HTTPS endpoint and against the exact real profile row (via `compile_profile()` called directly in the backend container) both confirmed the server-side fix is correct and complete — the discrepancy is a stale browser tab/cache serving the pre-#95 frontend bundle, which nothing was forcing to refresh. - `nginx.conf` served `index.html` with no `Cache-Control` header, so a browser that already loaded the app could keep running an old cached shell (pointing at a JS bundle hash that no longer exists after the next deploy) indefinitely — a normal reload doesn't guarantee a refetch, and users have no way to know their tab is stale. Now `index.html` is `Cache-Control: no-cache` (always revalidate) and hashed `/assets/*` files get long-lived immutable caching, so every deploy is picked up on next load. - Also fixed a related Safari-specific bug in `TargetExporter.tsx`: `URL.revokeObjectURL()` was called synchronously right after `a.click()`, which races Safari's native "Save As" dialog — WebKit needs the blob to stay alive until the user responds, so an immediate revoke can make that save fail or truncate. Revocation is now deferred by one tick. ## Test plan - [x] `npm run lint` and `npx vitest run` pass (updated the download test to await the now-deferred `revokeObjectURL` call) - [x] Rebuilt local `myace-frontend` container; confirmed `index.html` sends `Cache-Control: no-cache` and `/assets/*.js` sends `public, max-age=31536000, immutable` - [x] Verified via direct backend `compile_profile()` call against the real "IAC expert" profile (base Software Engineer + 4 additional collections) with `target=claude-code`: correctly produces 35 files (proper CLAUDE.md, individual `.claude/skills/*/SKILL.md`, `.claude/agents/*.md`, `.claude/commands/*.md`), not a single AGENTS.md - [x] Real (non-scripted) browser click on "Download as .zip" against the rebuilt local container downloads a correct 23-file zip 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
zaph0d 2026-08-15 07:30:12 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
github-mirrors/myace#99
No description provided.