Buổi Sáng Mở IDE Lên Thì Thấy Chatbot
Có một loại kinh nghiệm mà lập trình viên nào cũng biết: mở máy lên, click vào shortcut quen thuộc, và cảm giác gì đó không ổn ập đến trước khi não kịp xử lý. Màn hình hiện lên thứ gì đó không quen, không đúng chỗ. Một giây im lặng. Rồi mới bắt đầu hoảng.
Sid có buổi sáng như vậy vào ngày 21 tháng 5.
Anh mở Antigravity - IDE AI của Google anh dùng hàng ngày trong nhiều tháng qua - và thấy nó biến mất. Cây thư mục, editor, toàn bộ giao diện IDE không còn nữa. Thay vào đó là một ô chat trống rỗng, chờ anh gõ câu hỏi vào.
Đêm hôm trước, Google vừa ra mắt Antigravity 2.0 tại I/O 2026. Một trải nghiệm kiểu Codex mới, được giới thiệu như sản phẩm agentic độc lập. Trước khi Sid kịp đọc thông báo, bản cập nhật tự động đã tự quyết định mọi thứ thay anh.
Chuyện gì đã xảy ra
Tóm gọn trong một câu: Google đẩy một bản cập nhật thay thế toàn bộ IDE bằng chatbot, và con đường duy nhất để lấy lại IDE cũ là xóa sạch tất cả rồi cài lại từ đầu.
--> // making it invisible to querySelectorAll. // // `data-cfasync="false"` keeps this rescue script executable even when // Rocket Loader is active. It rescues module scripts via two strategies: // 1. Query the DOM for type$="-module" + src (covers case A) // 2. Regex-parse the raw HTML for commented-out script tags (covers case B) // Dynamically-created scripts bypass Rocket Loader entirely. (function () { if (window.__markdyRescue) return; window.__markdyRescue = true; var rescued = false; function rescueModuleScripts() { if (rescued) return; rescued = true; var srcs = []; // Strategy 1: Rocket Loader kept the tag in DOM but changed the type. // type="module" → type="{uuid}-module" (still has src attribute) document.querySelectorAll('script[type$="-module"][src]').forEach(function (s) { srcs.push(s.src); }); // Strategy 2: Rocket Loader COMMENTED OUT the script tag entirely: // // These are invisible to querySelectorAll, so we parse the raw HTML. // We handle both attribute orderings (type-first or src-first). var html = document.documentElement.innerHTML; var reSrcFirst = //g; var reTypeFirst = //g; var m; while ((m = reSrcFirst.exec(html)) !== null) { srcs.push(m[1]); } while ((m = reTypeFirst.exec(html)) !== null) { srcs.push(m[1]); } // Re-inject each found src as a real module script. // Deduplicate first, then inject. Dynamically-created scripts bypass // Rocket Loader entirely. Modules with the same URL are only executed // once by the browser (cached), so re-injecting already-running scripts // is safe. var seen = {}; srcs.forEach(function (src) { if (seen[src]) return; seen[src] = true; var fix = document.createElement('script'); fix.type = 'module'; fix.src = src; fix.setAttribute('data-cfasync', 'false'); document.head.appendChild(fix); }); } // Rescue when user clicks the placeholder (fallback if autoplay failed). document.addEventListener('click', function (e) { var t = e.target; if (t && typeof t.closest === 'function' && t.closest('.markdy-placeholder')) { rescueModuleScripts(); } }); // Rescue automatically after a short delay for autoplay. // Only fires if initAll() never ran (no data-markdy-init on any root). setTimeout(function () { if (document.querySelector('.markdy-root:not([data-markdy-init])')) { rescueModuleScripts(); } }, 1500); }());Antigravity 2.0 không phải bản nâng cấp thông thường - đây là một sản phẩm khác đội cái tên cũ. Bản cập nhật này ghi đè aggressively toàn bộ application path trên máy. Nghĩa là không thể chạy song song cả hai phiên bản. Thậm chí cài lại IDE cũ cũng không được, vì chatbot 2.0 vẫn chiếm quyền khởi động mỗi lần anh click shortcut.
Cách khắc phục duy nhất được ghi nhận ở bất kỳ đâu: xóa sạch mọi thứ liên quan đến Antigravity. Không phải rollback. Không phải toggle cài đặt. Mà là xóa sạch - rồi mới cài lại gói IDE cũ mà Google đặt ở… tận cùng trang tải xuống, hy vọng không ai tình cờ thấy.
Và lịch sử chat cùng toàn bộ cài đặt cũ? Gần như mất hết. Có một thư mục antigravity-backup được tạo ra trong quá trình này, có thể chứa dữ liệu cũ. Chữ “có thể” đang làm hết sức mình ở đây.
Tại sao 600 người upvote bài này
Đây không phải một buổi sáng tệ tình cờ. Đây là chiến lược pivot sản phẩm được ngụy trang thành bản cập nhật tự động, và thread HN biết điều đó.
Một bình luận từ ctippett nói thẳng: “Google đang nhấn nút reset lại sản phẩm họ gọi là Antigravity, bất chấp người dùng hiện tại. Ổn thôi nếu bạn chưa từng cài trước đây… nhưng với người dùng cũ thì đây là sự đánh tráo cực kỳ mất phương hướng.”
Lý thuyết lan truyền trong thread: Google thấy thị trường cho một tool agentic tổng quát lớn hơn thị trường IDE chuyên biệt. Vậy là họ chuyển hướng. Bản cập nhật nền là thông báo proxy: workflow của bạn giờ phục vụ chiến lược sản phẩm của chúng tôi.
postalcoder nói thẳng hơn: “Google thiếu tập trung một cách đáng kinh ngạc. Họ rải sản phẩm lung tung, rồi chọn cái đang ít tệ nhất và thiếu nhiệt tình tập trung vào đó. So với mọi AI lab khác - lớn hay nhỏ - đều biết mình là ai.”
Bình luận đó được đồng ý rất nhiều.
Câu hỏi về lock-in
Một bình luận từ riskassessment chọc vào vấn đề cốt lõi hơn:
“Tôi ngạc nhiên khi người ta sẵn sàng dùng IDE closed-source chỉ để có coding agent. Cái giá bạn trả cho sự tích hợp chặt chẽ giữa IDE và agent là lock-in… Môi trường coding của bạn ít bị ảnh hưởng hơn khi dùng IDE open-source cộng thêm CLI agent.”
Đó là câu trả lời đúng về mặt triết học. Cũng là câu trả lời đòi hỏi sự cẩn thận mà bạn thường không có khi đang muốn ship feature gấp. IDE closed-source có sync và context storage độc quyền tiện lợi chính vì sự tích hợp đó. Và chính sự tích hợp đó khiến bạn mắc kẹt khi Google quyết định tái định nghĩa sản phẩm là gì.
| IDE AI tích hợp | Editor mở + CLI Agent |
|---|---|
| Cài đặt một click | Cần cấu hình thủ công |
| Context lưu xuyên session | Context quản lý theo từng tool |
| Autocomplete + agent loop mượt | Thêm một chút friction |
| Vendor kiểm soát floor | Bạn kiểm soát floor |
Hàng cuối, cột phải, là cược mà riskassessment đang đặt.
--> // making it invisible to querySelectorAll. // // `data-cfasync="false"` keeps this rescue script executable even when // Rocket Loader is active. It rescues module scripts via two strategies: // 1. Query the DOM for type$="-module" + src (covers case A) // 2. Regex-parse the raw HTML for commented-out script tags (covers case B) // Dynamically-created scripts bypass Rocket Loader entirely. (function () { if (window.__markdyRescue) return; window.__markdyRescue = true; var rescued = false; function rescueModuleScripts() { if (rescued) return; rescued = true; var srcs = []; // Strategy 1: Rocket Loader kept the tag in DOM but changed the type. // type="module" → type="{uuid}-module" (still has src attribute) document.querySelectorAll('script[type$="-module"][src]').forEach(function (s) { srcs.push(s.src); }); // Strategy 2: Rocket Loader COMMENTED OUT the script tag entirely: // // These are invisible to querySelectorAll, so we parse the raw HTML. // We handle both attribute orderings (type-first or src-first). var html = document.documentElement.innerHTML; var reSrcFirst = //g; var reTypeFirst = //g; var m; while ((m = reSrcFirst.exec(html)) !== null) { srcs.push(m[1]); } while ((m = reTypeFirst.exec(html)) !== null) { srcs.push(m[1]); } // Re-inject each found src as a real module script. // Deduplicate first, then inject. Dynamically-created scripts bypass // Rocket Loader entirely. Modules with the same URL are only executed // once by the browser (cached), so re-injecting already-running scripts // is safe. var seen = {}; srcs.forEach(function (src) { if (seen[src]) return; seen[src] = true; var fix = document.createElement('script'); fix.type = 'module'; fix.src = src; fix.setAttribute('data-cfasync', 'false'); document.head.appendChild(fix); }); } // Rescue when user clicks the placeholder (fallback if autoplay failed). document.addEventListener('click', function (e) { var t = e.target; if (t && typeof t.closest === 'function' && t.closest('.markdy-placeholder')) { rescueModuleScripts(); } }); // Rescue automatically after a short delay for autoplay. // Only fires if initAll() never ran (no data-markdy-init on any root). setTimeout(function () { if (document.querySelector('.markdy-root:not([data-markdy-init])')) { rescueModuleScripts(); } }, 1500); }());Có vá được không?
Phần nào được. Bình luận đứng đầu thread - từ antimirov - là một Python script tự động toàn bộ quá trình khôi phục: tắt background processes, merge VS Code settings, cập nhật extension pathways, và nối các SQLite database toàn cục bằng raw base64 protobuf concatenation để khôi phục lịch sử chat.
Chạy được. Hàng trăm người dùng Mac cảm ơn antimirov trong phần trả lời.
Và đây là footnote sẽ theo mãi câu chuyện này: antimirov viết cái script đó bằng Antigravity. Tool làm hỏng workflow của bạn đã tạo ra tool để sửa nó. Điều đó impressive hay cursed tùy thuộc hoàn toàn vào tâm trạng hiện tại của bạn và số giờ bạn đã mất vì bản cập nhật đó.
Đọc bài gốc nếu
- Bạn đang tự hỏi liệu AI IDE mình đang dùng có thể biến thành sản phẩm khác qua một bản cập nhật nền không
- Bạn cần các bước khôi phục thủ công mà không cần chạy script của người lạ
- Bạn dùng Antigravity trên Google AI Ultra và chưa mở nó sáng nay
Bỏ qua nếu
- Bạn đã dùng CLI agent (Gemini CLI, Claude Code, Codex) cộng với VS Code hay editor mã nguồn mở. Bạn đã đặt cược đúng từ trước rồi.
- Sự khác biệt giữa “cập nhật IDE” và “thay thế sản phẩm” không ảnh hưởng đến công việc hàng ngày của bạn
Bài học thật sự không phải về Antigravity. Đó là về cơ sở hạ tầng xung quanh công việc của bạn - và ai được quyền quyết định cơ sở hạ tầng đó trông như thế nào vào sáng hôm sau, trong lúc bạn đang ngủ.
Thảo luận trên Hacker News · Nguồn: 0xsid.com · Đăng bởi ssiddharth
Hoang Yell
Một nhà phát triển phần mềm và là người kể chuyện kỹ thuật. Tôi đọc Hacker News mỗi ngày và kể lại những câu chuyện hay nhất ở đây — bằng tiếng Việt và tiếng Anh, cho người tò mò nhưng không có thời gian.