AI 资讯
Unpacking Manifest V3: Chrome’s Big Extension Shakeup! 🛠️
Hey tech family! 👋 If you’ve noticed your favorite Chrome extensions acting a bit differently lately or if you're a developer currently sweating over a massive codebase rewrite you are experiencing the era of Manifest V3 (MV3) . 🤖 Google has officially pushed the web ecosystem forward by deprecating Manifest V2, making MV3 the absolute standard for how browser extensions behave. But why is this happening, what actually changed, and why is the internet so divided over it? Let’s break it all down in plain English! 👇 🧐 What Exactly is Manifest V3? Think of a "Manifest" as the blueprint file ( manifest.json ) that tells the browser exactly what an extension is, what files it uses, and what permissions it needs to run. Manifest V3 is Google's major architectural overhaul of this system. Its core mission sounds great on paper: improve user privacy, beef up security, and boost browser performance . However, achieving those goals meant rewriting the core rules of how extensions interact with your browser. 🛠️ The Biggest Changes & New Features MV3 isn't just a small patch; it fundamentally alters the underlying extension engine. Here are the headline shifts: Goodbye Background Pages, Hello Service Workers! 💤 In MV2, extensions used hidden, persistent background pages that ran 24/7, hogging your computer's RAM even when you weren't using them. MV3 replaces these with Service Workers. They are event-driven meaning they wake up, execute a task (like clicking an extension icon), and go right back to sleep. Hello, free RAM! 🐏 The Ad-Blocker Shakeup: webRequest vs. declarativeNetRequest 🛑 This is the most controversial change. In MV2, powerful extensions like uBlock Origin used the webRequest API to intercept, read, and block network requests in real-time using complex code. MV3 replaces the blocking version of this with declarativeNetRequest . Instead of letting the extension intercept the data, the extension must now hand Chrome a pre-defined list of rules, and Chrome does the b
AI 资讯
SpaceX is now a public company valued for its AI potential, so what comes next?
As of today, SpaceX is owned by investors who will want to see it make money.
AI 资讯
SpaceX IPO closes up 19% and delivers the world’s first trillionaire
The company made its heavily anticipated debut on Friday, trading higher than its initial $135 IPO price.
AI 资讯
Understanding XML Structure: A Practical Guide for Developers
JSON and GraphQL dominate modern web development, but XML (eXtensible Markup Language) is far from obsolete. Enterprise integrations, legacy systems, healthcare standards, and financial protocols still rely heavily on XML. If you work across diverse stacks, understanding XML is a skill that pays dividends. This guide covers the core syntax, validation techniques, parsing approaches, and best practices - with code you can put to work right away. Why XML Still Matters in 2026 XML has been around since 1996 and continues to thrive in specific domains. It handles deeply nested hierarchical data well, supports robust native schema validation, and manages mixed document-oriented content better than most alternatives. If you're dealing with SOAP APIs, Android layouts, SVG, DOCX/XLSX files, HL7 healthcare records, or FIX financial protocols, you're already in XML territory. The Core Building Blocks of an XML Document At its core, XML is a tree of nodes serialized as text. Every well-formed document starts with a declaration that tells the parser the version and character encoding - UTF-8 is the standard choice. From there, the document is composed of nested elements, attributes, and optionally text content. Elements - The Tree Nodes Elements are the primary structural unit in XML. They wrap your data in opening and closing tags. XML is case-sensitive, so a tag and a tag are treated as two completely different elements. Every opened element must have a corresponding closing tag to keep the document well-formed. Attributes - Metadata on Elements Attributes sit inside an opening tag and carry metadata about the element rather than the primary data itself. A good rule of thumb: use attributes for identifiers, types, or units (like currency), and use child elements for the actual payload data. This separation keeps your parsers predictable and your document structure clean. Self-Closing Elements When an element has no content or child nodes, you can collapse the open and close t
AI 资讯
Rebuilding the Hull at Sea
The box that ran everything started dying in April. Not dramatically. Machines almost never die dramatically. It started with instability... the kind you explain away once, side-eye twice, and start losing sleep over the third time production goes down while you're in the middle of something else. The host under my entire stack... public site, analytics, security tooling, the AI crew's memory layer... was getting flaky. And flaky hardware only trends one direction. Here's the thing about a homelab that lives in a 40ft fifth wheel: there is no second team. No vendor escalation. No change advisory board. No maintenance window negotiated three weeks out. There's me, a crew of governed AI instances, and a reclaimed Dell T3600 about to get the biggest promotion of its second life. So we didn't try to heal the sick box. We built a new hull alongside it and started moving the ship... plank by plank... while it was still sailing. One ground rule, set day one: the old host stays untouched and keeps serving production until the new hull is proven. Not "mostly proven." Proven. Hold that thought, it matters at the end. Moving containers is the easy part. Docker made that boring years ago, and boring is a compliment in infrastructure. What's never boring is the inventory of everything you assumed and never wrote down. A migration doesn't test your stack. It tests your assumptions. Here's what mine were hiding. 01: The umbilical nobody documented Security stack went first. Suricata, Zeek, Wazuh, CrowdSec, Falco, the whole alphabet, up clean on the new hull. Then the MCP server, the piece that gives the AI crew its hands, refused to come up right. It was hard-wired over HTTP to the crew's memory backend. A live dependency, in production for months, documented exactly nowhere. The crew that documents every f*cking thing had never documented its own umbilical cord. Fix was trivial once we could see it: deploy the brain before the hands. Reorder, redeploy, done. But the lesson isn't
科技前沿
SpaceX shares soar 30% midday, vaulting it to top six most valuable U.S. companies
The company made its heavily anticipated debut on Friday, trading higher than its initial $135 IPO price.
AI 资讯
Elon Musk Is the World’s First Trillionaire
SpaceX’s stock market debut has thrust the richest man in the universe into an unexplored frontier of wealth.
科技前沿
Robinhood sees ‘record-breaking’ traffic after SpaceX stock debuts
The trading platform says some customers experienced intermittent disruptions, but those issues have resolved.
AI 资讯
A trillion dollars is a stupid amount of money
Elon Musk is now officially the world's first trillionaire. That is a colossal amount of wealth (and by proxy, power) for one individual to have. Its scale - a thousand times more than a billion - is difficult to fathom for those of us who aren't among the 3,363 billionaires that currently exist in our […]
AI 资讯
Elon Musk becomes the world’s first trillionaire after SpaceX’s historic IPO
The SpaceX IPO has boosted Musk's paper wealth to more than $1,000,000,000,000 at a time when he is more hated -- and powerful -- than ever.
科技前沿
SpaceX opens at $150, an 11% pop for the most anticipated debut in history
The company made its heavily-anticipated debut on Friday, trading higher than its initial $135 IPO price.
AI 资讯
Ditch Electron: Spawning a Rust-Powered Python Sidecar from Bun
Part 1 of the ERTH Architecture Series: Launching local backends on Port 0, dynamic port negotiation, and establishing the dual-core desktop backbone. If you are building a modern desktop application, you are probably tired of the same old options. On one hand, you have Electron . It’s the industry standard, but it forces you to bundle a full Chromium browser and a Node.js runtime with every app. Even a simple "Hello World" takes up 200MB+ of disk space and eats hundreds of megabytes of RAM. For background utility utilities or AI assistants that need to be nimble, this is a massive tax. On the other hand, you have Tauri . It solves the bundle size issue by binding to OS-native WebViews and using Rust for the backend. But unless you are already a Rust expert, you will find yourself fighting the compiler's borrow checker and async lifecycles, slowing down your development velocity. But what if you want to use Python for its rich AI ecosystem (Ollama, SQLModel, PyTorch), but still keep the UI lightweight, fast-loading, and responsive? Welcome to the ERTH Stack ( E lectroBun + R obyn + T urso + H TMX). In this first post of our 5-part series, we will break down how to launch a high-performance Python sidecar backend directly from a Bun-based desktop shell, bypassing the bloated Electron environment entirely. The Concept: Heterogeneous Dual-Core In the ERTH architecture, the desktop app is split into two physical processes: The Main Process (Bun) : Responsible for native OS window management, IPC (Inter-Process Communication), and hosting the HTML/CSS view. We use ElectroBun —a next-generation, ultra-lightweight wrapper that binds directly to the OS-native WebKit engine (no Chromium bloat!). The Sidecar Process (Python/Robyn) : Responsible for heavy computations, database access, and local LLM orchestration. We use Robyn , an incredibly fast, Rust-based async Python web framework. Here is how the lifecycle and process boundaries interact: Step 1: Spawning the Robyn Sidec
AI 资讯
Why I Abandoned Electron & SPAs to Build a 128MB Local-First Desktop AI Agent
How the ERTH Architecture (ElectroBun + Robyn + Turso + HTMX) breaks the obesity of modern desktop app development. If you’ve tried to build a cross-platform desktop application recently, you’ve likely faced the classic developer’s dilemma: Electron makes developer velocity fast, but at the cost of dragging a bloated Chromium kernel and Node.js runtime into every build. A simple "Hello World" easily eats up 200MB+ of disk space and hundreds of megabytes of RAM. Tauri solves the footprint issue by using OS-native WebViews and Rust, but forces you onto Rust’s steep learning curve, sacrificing the agility of rapid prototyping. The Python Distribution Hell : With the rise of local LLMs and Edge AI, Python is the de facto language for AI orchestration. Yet, packaging Python, its heavy dependencies, and databases into a double-click-to-run package for non-technical users remains a nightmare. Faced with these shackles, I decided to take a step back and rewrite the physical laws of desktop development. Today, I’m introducing the ERTH Stack ( E lectroBun + R obyn + T urso + H TMX)—a heterogeneous, local-first, zero-JS desktop application architecture designed for independent full-stack creators. And yes, the entire bundle—including a browser shell, a high-performance Python sidecar, a local database, and local AI agent execution—packages into a single 128MB standalone binary. Our open-source implementation is live on GitHub: 👉 GitHub Repository: bnpysse/erth_assistant The Core Pillars of the ERTH Architecture To achieve a minimalist footprint without sacrificing developer velocity, we structured the architecture into four core layers: ERTH ARCHITECTURE [E]lectroBun (UI Shell) ───[HTMX]───► [H]TMX (Zero-JS Frontend) │ ▲ (IPC) (HTTP) ▼ │ [R]obyn (Python Sidecar) ───────────► [T]urso / libSQL (Local-First DB) 1. [E]lectroBun: The Lightweight Shell Instead of Electron’s heavy Chromium, ElectroBun binds directly to the OS-native WebKit engine (Cocoa WebKit on macOS, WebView2 on W
AI 资讯
Model Context Protocol (MCP): Giao Thức Tương Lai Cho AI
Model Context Protocol (MCP): Giao Thức Kết Nối Thế Giới Cho Trí Tuệ Nhân Tạo Trong thế giới AI đang phát triển với tốc độ chóng mặt, việc xây dựng các ứng dụng thông minh, có khả năng tương tác linh hoạt với dữ liệu và công cụ bên ngoài là một thách thức lớn. Các mô hình ngôn ngữ lớn (LLM) như GPT, Claude, hay Gemini dù mạnh mẽ nhưng thường hoạt động trong "vùng cô lập", thiếu khả năng truy cập trực tiếp vào các hệ thống bên ngoài theo thời gian thực. Đây chính là lúc Model Context Protocol (MCP) xuất hiện như một giải pháp cách mạng. MCP là một giao thức mở, được thiết kế để tiêu chuẩn hóa cách thức các ứng dụng cung cấp ngữ cảnh (context) cho LLM, giúp phá vỡ rào cản giữa trí tuệ nhân tạo và thế giới thực. Bài viết này sẽ đi sâu vào phân tích Model Context Protocol , từ định nghĩa, kiến trúc, đến các lợi ích và ứng dụng thực tế, giúp bạn hiểu tại sao nó được coi là "ngôn ngữ chung" của tương lai AI. Model Context Protocol (MCP) Là Gì? Model Context Protocol (MCP) là một giao thức mở, được phát triển để tạo ra một chuẩn giao tiếp thống nhất giữa các LLM và các nguồn dữ liệu, công cụ bên ngoài. Hãy tưởng tượng MCP như một "cổng USB" dành cho AI. Thay vì mỗi ứng dụng AI phải viết mã tích hợp riêng lẻ với từng loại cơ sở dữ liệu, API, hay hệ thống tệp tin (mỗi loại một kiểu "phích cắm" khác nhau), MCP cung cấp một giao diện chuẩn. Bất kỳ ứng dụng nào hỗ trợ MCP đều có thể kết nối với bất kỳ nguồn tài nguyên nào cũng hỗ trợ MCP một cách liền mạch. Mục Đích Cốt Lõi Của MCP Mục tiêu chính của Model Context Protocol là giải quyết vấn đề "fragmentation" (phân mảnh) trong hệ sinh thái AI. Trước MCP, việc tích hợp thường diễn ra rời rạc: Mỗi nhà phát triển ứng dụng phải tự xây dựng các "kết nối" tùy chỉnh. Mỗi lần cập nhật mô hình hoặc công cụ có thể làm hỏng các tích hợp cũ. Khó khăn trong việc chia sẻ và tái sử dụng các công cụ AI giữa các dự án. MCP giải quyết những vấn đề này bằng cách cung cấp một lớp trừu tượng chuẩn hóa. Kiến Trúc Và Cách Thức Hoạt Động Của MCP Kiến
开发者
There’s no need to include ‘navigation’ in your navigation labels
One of those nuances to keep in your back pocket when writing for screen readers. There’s no need to include ‘navigation’ in your navigation labels originally handwritten and published with love on CSS-Tricks . You should really get the newsletter as well.
产品设计
A White Supremacist Youth Group Helped Orchestrate the Belfast Riots
After Elon Musk and Tommy Robinson stoked anger over a horrific knife attack in Belfast, a youth group linked to a global neo-Nazi movement quietly orchestrated anti-immigrant riots.
AI 资讯
Stop Hand-Editing Fragile APT Lines: Practical deb822 `.sources` Files for Debian and Ubuntu
If you still manage APT repositories as long one-line deb ... entries, you are working with a format APT now explicitly marks as deprecated. It still works, but it is harder to read, harder to automate safely, and easier to get wrong when you add options like arch= or signed-by= . The better option is deb822 style .sources files. This post shows how to: read the structure of a .sources file migrate a legacy .list entry safely use Signed-By without falling back to apt-key disable a repository cleanly without deleting it verify that APT accepts the new configuration I am focusing on practical host administration, not packaging theory. Why move to deb822 now? The sources.list(5) man page now says the traditional one-line .list format is deprecated and may eventually be removed, though not before 2029. More importantly, deb822 solves real operational annoyances: fields are explicit instead of positional one stanza can describe multiple suites or types Enabled: no is cleaner than commenting lines in and out machine parsing is much easier Signed-By is clearer and safer in structured form On a current Debian host, you may already be using it without noticing: find /etc/apt/sources.list.d -maxdepth 1 -type f -name '*.sources' On my test system, the default Debian repository is already stored as /etc/apt/sources.list.d/debian.sources . The old format vs the new format A traditional one-line entry looks like this: deb [arch=amd64 signed-by=/etc/apt/keyrings/example.gpg] https://packages.example.com/apt stable main The same source in deb822 format becomes: Types: deb URIs: https://packages.example.com/apt Suites: stable Components: main Architectures: amd64 Signed-By: /etc/apt/keyrings/example.gpg That is the core win. Instead of cramming everything into one line and hoping spacing stays correct, each field says exactly what it means. Example 1, a clean Debian .sources file Here is a practical example for Debian using separate stanzas for the main archive and the security arch
AI 资讯
I Cut My Next.js + Supabase App Load Time by 73% - Here Are the 5 Techniques That Actually Worked
I Cut My Next.js + Supabase App Load Time by 73% - Here Are the 5 Techniques That Actually Worked Last month, our SaaS dashboard was embarrassingly slow . 4.2 seconds to load the main page. Users were complaining. Conversion rates were tanking. Today? 1.1 seconds . 73% faster. Here's exactly what worked (and what didn't). The Problem: Death by a Thousand Database Calls Our dashboard showed user projects, team members, recent activity, and notifications. Sounds simple, right? Wrong. Each component was making its own database calls. The projects list fetched projects, then made separate calls for each project's stats. The activity feed loaded events, then fetched user details for each event. Classic N+1 query problem, but worse. Technique #1: Strategic Data Fetching Consolidation Before: 47 database calls to load the dashboard After: 3 database calls The fix wasn't fancy. We consolidated related data into single queries using Supabase's nested select syntax: // ❌ Before: Multiple separate calls const projects = await supabase . from ( ' projects ' ). select ( ' * ' ) const stats = await Promise . all ( projects . map ( p => supabase . from ( ' project_stats ' ). select ( ' * ' ). eq ( ' project_id ' , p . id )) ) // ✅ After: Single consolidated call const projects = await supabase . from ( ' projects ' ) . select ( ` *, project_stats(*), team_members(count), recent_activity:activities(*, user:users(name, avatar_url)) ` ) . limit ( 10 ) Result: Dashboard load time dropped from 4.2s to 2.8s (33% improvement) Technique #2: Aggressive Caching with Smart Invalidation Most dashboard data doesn't change every second. We implemented a three-tier caching strategy: // Static data: Cache indefinitely const categories = await supabase . from ( ' categories ' ) . select ( ' * ' ) . cache ({ revalidate : false }) // Semi-static data: Cache with revalidation const userProjects = await supabase . from ( ' projects ' ) . select ( ' * ' ) . eq ( ' user_id ' , userId ) . cache ({ revali
AI 资讯
Next.js + Supabase Performance Optimization: From Slow to Lightning Fast
Next.js + Supabase Performance Optimization: From Slow to Lightning Fast Last month, I optimized a Next.js + Supabase application that was frustratingly slow. Initial page load took 4.2 seconds, Lighthouse performance score was 62, and users were complaining. After applying these optimization techniques, we achieved: 70% faster load times (4.2s → 1.3s) Lighthouse score of 96 (up from 62) LCP improved by 65% (3.8s → 1.3s) 50% reduction in database queries Here's exactly how we did it. The Starting Point: Measuring Performance Before optimizing anything, we measured current performance using: Lighthouse (Chrome DevTools): Performance: 62 First Contentful Paint (FCP): 2.1s Largest Contentful Paint (LCP): 3.8s Total Blocking Time (TBT): 420ms Cumulative Layout Shift (CLS): 0.18 Real User Monitoring: Average page load: 4.2s Time to Interactive: 5.1s Database query time: 850ms average The Problems: Unoptimized database queries No caching strategy Large JavaScript bundles Unoptimized images Blocking render paths Too many client-side fetches Let's fix each one. 1. Database Query Optimization Problem: N+1 Queries The biggest performance killer was N+1 queries. We were fetching posts, then fetching the author for each post individually. // ❌ Bad: N+1 queries (1 + N database calls) async function getPosts () { const { data : posts } = await supabase . from ( ' posts ' ) . select ( ' id, title, author_id ' ) // Fetching author for each post = N queries const postsWithAuthors = await Promise . all ( posts . map ( async ( post ) => { const { data : author } = await supabase . from ( ' users ' ) . select ( ' name, avatar ' ) . eq ( ' id ' , post . author_id ) . single () return { ... post , author } }) ) return postsWithAuthors } Impact: 50 posts = 51 database queries (850ms total) Solution: Use Joins // ✅ Good: Single query with join (1 database call) async function getPosts () { const { data : posts } = await supabase . from ( ' posts ' ) . select ( ` id, title, author:users(nam
AI 资讯
Matchmakers Are Being Paid $25K to Find Trad Wives for Rich Men
Even in blue states, nonreligious tech entrepreneurs and CEOs are increasingly asking for “traditional” and “conservative” women, matchmakers tell WIRED.