AI 资讯
How MV3 Service Workers Made Me Use an Offscreen Document Just to Play a Goat Sound
So I built a Chrome extension that does one very stupid thing: it waits a random amount of time, then screams at you like a goat if you don't dismiss the notification fast enough. Simple idea. Should've been a simple build. It was not, because Manifest V3 said no. The plan was easy, in my head Here's what I thought I needed: chrome.alarms to fire at a random interval chrome.notifications to show a "you good?" popup If the user ignores it for 60 seconds, play a goat sound Step 3 is where things fell apart. Because in Manifest V3, your background script isn't a persistent background page anymore — it's a service worker. And service workers have the audio capabilities of a rock. No Audio() object. No Web Audio API. Nothing. You can't just do new Audio('goat.mp3').play() and call it a day, because there's no DOM for it to live in. I found this out the way everyone finds out things in MV3: by writing the obvious code, watching it silently fail, and then spending 20 minutes wondering if I'd misspelled "goat." Enter: the offscreen document Chrome's answer to "service workers can't do X" for a bunch of X's (audio playback included) is the offscreen document API . It's exactly what it sounds like — a hidden HTML page that exists purely so your extension has something with a DOM, so it can do DOM things. In my case, playing an mp3 of a goat losing its mind. The flow ends up looking like this: service worker (background.js) → creates an offscreen document if one doesn't exist → sends it a message: "play the sound" offscreen.html/offscreen.js → has an <audio> tag → actually plays the sound → closes itself when done It's a little bit like hiring a stunt double because the main actor (your service worker) isn't allowed near water. The offscreen document does the wet work, then goes home. Rough version of what that looks like in code: // background.js async function playGoatSound () { if ( ! ( await chrome . offscreen . hasDocument ())) { await chrome . offscreen . createDocument
AI 资讯
From text-JSON parsing to Claude tool use in JobSearch
My job-search tool had five functions whose only purpose was fixing JSON that Claude had just written. _clean_json_text , _fix_unescaped_newlines , _fix_single_quotes , _strip_markdown_wrapper , _extract_and_parse_json . There was also a sixth, _retry_json_fix , which took the broken JSON and sent it back to the model with a polite request to fix its own mess. I wrote every one of them, one bug at a time, over weeks. I was a little proud of them. That was the problem. How you end up with five parsers JobSearch is my personal tool, in production, single user: me. It ingests job offers from nine boards, and when I press "Analyze", Claude reads the offer against my CV and returns a structured verdict: score, recommendation, career track, the English level the ad actually requires. That verdict has to be JSON, because everything downstream is a database row, not prose. The first version did what every tutorial does. Ask the model for JSON in the prompt, take response.content[0].text , run json.loads on it. It worked in the demo and then production started teaching me things. The model wrapped the JSON in markdown fences, so I wrote a function to strip them. Sometimes it used single quotes, so I wrote a function to fix those. Then a description with a line break inside a string, so I wrote _fix_unescaped_newlines . Then a NaN where a number should be. Every fix was five lines, obviously correct, and came with its own tests. I still have the test names in the git history and they read like a confession: test_removes_trailing_commas , test_replaces_nan_with_null , test_replaces_infinity , test_unclosed_fence_still_strips_opening . By April the parsing layer was around 250 lines with seven strategies, chained, each catching what the previous one let through. The last resort was the AI self-repair call: if nothing parsed, send the broken output back and ask the model to repair it. A second API call, with real latency and real cost, to fix a formatting problem the first call
科技前沿
The 35 Best Board Games for Family Game Night
From monsters to kittens to strategy games, these sets will liven things up on nights when everyone is tired of screens.
开发者
I built a free Unicode font generator for social bios and nicknames
I'm excited to share a project I've been building: Letras Personalizadas — a free Unicode text styling tool that helps you create creative copy-and-paste text for social media, gaming, and messaging apps. Here's how it works: • Type your text • Instantly preview dozens of Unicode text styles • Copy your favorite with one click • Use it on Instagram, WhatsApp, TikTok, Discord, Free Fire, and more Although the website is designed primarily for Spanish-speaking users targetting Brazil, it works with any standard Latin text. One thing I've learned while building this project is that these tools are about much more than "fancy fonts." The real challenge is creating a smooth user experience—fast previews, mobile-friendly design, reliable copy buttons, platform compatibility, useful categories, favorites, and making the styled text effortless to use across different apps. I'm continuously improving the interface, expanding the style categories, and refining the mobile experience. If you have a few minutes to try it out, I'd love to hear your feedback and suggestions. Every comment helps make the tool better.
科技前沿
Best Power Banks (2026): My Picks After Testing Over 100
Keep your phone, laptop, handheld gaming console, and other electronics running with these travel-friendly power banks.
科技前沿
The 10 Best Electrolyte Powders (We Tested Over 20)
Get those lost minerals back with the help of our top electrolyte powders, tablets, drops, and chews for athletes, partiers, and everyone in between.
AI 资讯
I Built an AI App. Eight Months Later, It Became a Skill
When I first wrote about NutriAgent in November 2025, it was a full application. It had a Python backend, a web interface, a Telegram bot, user accounts, Google OAuth, Supabase, and a Google Sheets integration. Recently, I reproduced its core workflow as a skill for my personal AI agent. It took around 15 minutes and two prompts. I didn't build another backend, deploy a service, or implement OAuth again. I explained how I wanted the workflow to behave, tested it, and watched a new row appear in my nutrition spreadsheet. The original application wasn't a mistake. It was how I could deliver that experience with the tools available at the time. Eight months later, the starting point had changed. Eight Months Ago, This Was an App I built NutriAgent because I wanted to track calories and protein without trapping my data inside a nutrition app. I wanted the raw records in a spreadsheet I controlled, where I could create my own reports and eventually connect nutrition with my training data. The first version was a personal n8n workflow. It worked for me, but when a friend wanted to try it, I realized that everything was tied to my accounts. To make it reusable, I rebuilt it in Python and added the parts a real multi-user product needed: authentication, storage, a web interface, Telegram, Google OAuth, conversation history, and account linking. I've already told that story in I Ditched MyFitnessPal and Built an AI Agent to Track My Food , and later wrote about what broke after I used it every day for a month . This article starts after that version. My Gaming PC Became an Agent Box I had a modest gaming PC at home with 16 GB of RAM and a 1 TB drive. Using it through Windows, WSL, and remote desktop from my Mac felt awkward, so I installed Linux and turned it into a remote box for running agents. I'll write about that setup separately. I moved Hermes there from a VPS. Hermes is the personal agent I now run on that machine. It can load reusable skills and use tools connected
AI 资讯
How I make ffmpeg hit an exact file size (the bitrate math nobody explains)
Every few weeks I hit the same wall: I have a 300 MB screen recording, and something on the other end wants it under 8 MB . Discord, an email attachment, a bug tracker, a form that silently rejects anything bigger. The usual advice is "just use HandBrake" or "run ffmpeg with a lower CRF." But CRF doesn't take a target size — it takes a quality knob . So you export, check the size, it's 11 MB, nudge the knob, export again, now it's 5 MB and looks like a potato, nudge back… It's a binary search you run by hand, one full encode per guess. The thing is, hitting an exact size isn't a guessing game at all. It's arithmetic you can do before you encode. I ended up wrapping that arithmetic into a little Rust CLI ( DeepShrink ), but the math is the interesting part, and almost nobody writes it down. So here it is. The one insight everything rests on File size is (roughly) bitrate × duration . A bitrate is bits per second. A duration is seconds. Multiply them and the seconds cancel, leaving bits — the size of the file. That's it. That's the whole trick. Normally you treat bitrate as the input and size as whatever falls out. Flip it around: fix the size, measure the duration, and solve for the bitrate. You know the duration (ffprobe will tell you), and you know the size you want (the platform's limit). The only unknown is the bitrate — and now it's a single division away. bitrate = size_in_bits / duration_in_seconds Everything below is just this equation with the real-world messiness added back in. Building the budget, step by step Say I want a 60-second clip to fit Discord's 8 MB limit. 1. Turn the target size into bits. Sizes are in bytes, bitrate is in bits, so multiply by 8. (I'll use 1 MB = 1,000,000 bytes here to keep the mental math clean; if your platform means mebibytes, same method, different constant.) target_bits = 8_000_000 bytes × 8 = 64_000_000 bits (64 Mbit) 2. Reserve a little for container overhead. An .mp4 isn't pure video and audio — there's a container, a m
科技前沿
4 Best Walking Pads for Small Spaces and Standing Desks (2026)
Our remote team clocked serious hours walking, working, and sometimes jogging to find the best under-desk treadmills for home offices and small spaces.
安全
The Best Motion Sensors and Home Security Gadgets Without Cameras
If you prefer not to have cameras in and around your home, try one of these more private, WIRED-tested security devices.
科技前沿
The Best Tech for Back to School
Get ready to crush your coursework or scoot to class in style with these back-to-school gear picks.
AI 资讯
Fine, electric mountain bikes don’t suck
Cheater, I'd grumble between huffs as yet another e-bike rider casually skittered past me on a steep ascent. It's this purist attitude that, for years, has left me blind to one simple fact: electric mountain bikes are fun! My attitude adjustment came a few weeks ago, the very first time I rode an Amflow PX […]
AI 资讯
I Got Tired of AI Quiz Tools Making Up Facts That Weren't In My Notes, So I Built One That Can't
Two nights before a chemistry final, I pasted my notes into an AI quiz generator to test myself. One question asked about a reaction I never studied. I got it wrong, looked it up afterward, and it wasn't in my notes at all. The tool had just made it up. I went looking for a better one and hit the same wall three more times with three different tools. Paste your notes, get a quiz, and somewhere in the output is a question built on a fact your source material never mentioned. Nobody flags it. You just find out when you're wrong about something you were sure you'd studied. The failure mode makes sense once you think about how these tools are built. Most of them prompt an LLM with something like "generate 10 quiz questions from this text" and print whatever comes back. The model is good at sounding right. It is not naturally good at staying inside the boundary of what you actually gave it, and a prompt that says "don't hallucinate" is a request, not a constraint. The model can ignore it and you'd never know from the output alone. So I built QuizPaste around a different idea: don't ask the model to be honest, check it. When it generates a question, it has to also point at the sentence in your source text the question came from. Before that question ever gets shown to you, the code tries to actually locate that sentence in your original text. If it can't find it (wrong wording, a made-up detail, or the line just isn't there), the question gets thrown out silently and never reaches you. You only ever see questions the tool can prove came from your own material. Open any question and you can see the exact line highlighted. Using it is the boring part, on purpose. Paste lecture notes or a block of text, or grab a YouTube video's transcript (open the video, three dots, "Show transcript," copy the panel text, paste it in). There's no scraping involved, so it doesn't break when YouTube changes something on their end. You get a practice quiz plus flashcards in about five seconds
科技前沿
The Best New Camping Gear at REI (2026): Tents, Coolers, Bikes, More
I tested REI’s best new and revamped outdoor gear of 2026. Here’s what’s worth buying, from tents and sleeping bags to coolers and bikes.
开发者
Essential Gear for an Emergency Kit—for Cars or Go-Bags
We consulted preparedness experts and WIRED’s team of testers for the essential gear to keep on hand in case of wildfires, earthquakes, and lord knows what else.
AI 资讯
23 Best Gifts for Cooks (2026): Vitamix, Frying Pans, Air Fryers
From the best air fryer to frying pans to knife sharpeners anyone can use, these ideas will keep the curious home chef in your life tinkering away.
AI 资讯
Trump teleprompter aide made $100,000 betting on what Trump would say, reports say
If only someone could have predicted it.
AI 资讯
Google Vids now lets you star in your own AI videos
Google is adding personalized AI avatars to Vids that let users create videos starring a digital version of themselves, alongside Gemini Omni-powered tools for generating and editing videos from prompts and reference images.
AI 资讯
How a former DeepMind researcher raised at a $300M pre-seed valuation before launching a product
Drawing on more than a decade spent helping build some of the world's most influential AI systems, including research that later informed the development of ChatGPT, Andrew Dai explains why he believes visual AI is one of the next major frontiers in artificial intelligence.
科技前沿
11 Best Sleeping Bags (2026): Ultralight, Warm Weather, for Kids
Whether you’re climbing peaks or taking the family to the local park, we’ve found the best sleeping bags for every temperature, budget, and camping expedition.