今日精选
HOT最新资讯
共 31925 篇Sometimes the most resilient thing a system can do isn’t retry
submitted by /u/madflojo [link] [留言]
France doubles down on restricting access to Polymarket
The country's gambling authority ordered ISPs to block access to the prediction market's website.
Waymo says San Francisco service has resumed after one-hour pause
This isn’t the first time power outages have caused issues for Waymo.
Why I Stopped Copy-Pasting Repositories and Started Building My Own Starter CLI
Every developer has a "starter project." Some keep a GitHub template. Some duplicate their previous SaaS project. Some run create-next-app and spend the next two hours installing the same dependencies, configuring the same tools, and recreating the same folder structure. I was in the second group. Every new project started the same way. bun create next-app Then came the checklist. Install Tailwind CSS. Configure Biome. Add shadcn/ui. Organize folders. Set up a UI library. Configure TypeScript. Add environment files. Set up a monorepo. Copy utility functions. Configure path aliases. Install development tools. None of these tasks were difficult. They were just repetitive. After starting enough projects, I realized something: I wasn't building products. I was rebuilding the same foundation over and over again. The Starter Kit Trap Like many developers, I created a "starter repository." Whenever I wanted to build something new, I'd clone it. It worked... until it didn't. Eventually I had multiple starter repositories. One for a monorepo. One for a standalone project. One with authentication. One without authentication. One for experiments. One that was already outdated. Keeping them synchronized became its own maintenance project. Fix a bug in one. Forget to fix it in another. Upgrade Next.js in one repository. Forget the rest. The more starters I created, the less useful they became. Why Existing Starters Didn't Quite Fit There are already fantastic starter kits in the ecosystem. Some focus on minimalism. Others include every feature imaginable. The problem wasn't that they were bad. The problem was that they optimized for someone else's workflow. Every project I build starts with almost the same stack. Next.js TypeScript Bun/pnpm Tailwind CSS v4 shadcn/ui Biome Production-ready project structure I didn't want to answer twenty configuration questions every time I scaffolded a project. I wanted one command. npx create-notils my-app …and be ready to start building. Opini
Kimi: Threat or menace?
Chinese company Moonshot AI released a new version of its Kimi model this week, prompting concern about "full AI communism."
The evolution of how we use CSS
CSS has been around for about 30 years. It is the only styling language built specifically for the web platform, and it is one of the three core technologies that make the web what it is. Without it, every page would be a block of black text on a white background, laid out from top to bottom with no control whatsoever. That is not an exaggeration. That is what the web looks like without CSS. The original design goal of CSS has never changed. It is a declarative language that describes how documents should be presented. It does one thing and it does it in a standardized way that works across browsers. That restraint is not a weakness. It is the reason CSS has survived for two decades without being replaced. It never tried to be more than a styling language. Looking back at frontend development in the late 2000s, the frustration is hard to overstate. The gap between what CSS could do and what designs required was so wide that the platform itself felt like the obstacle. The vendor prefix era is the clearest example. You wrote -webkit- , -moz- , -ms- , -o- before every experimental property, often all four, because no browser could agree on when a feature was stable. Autoprefixer became a standard dependency not because developers were lazy, but because manual prefix management was genuinely unsustainable. It was not that CSS was badly designed. It was that the pace of the platform could not keep up with what developers were building. This created a pattern. Every time the platform fell short, the community built a workaround. Those workarounds became tools. Those tools became dependencies. And those dependencies reshaped how we thought about CSS entirely. Each new abstraction solved a real problem, but it also moved us further from writing actual CSS. Eventually, it became natural to assume that any serious project needed a layer on top of CSS to be viable. However, if CSS is so good at its job, why have we spent so long building alternative ecosystems on top of it? Pr
A tiny engine for generating file trees
I just tagged 1.0.0 of ts-treegen, a small TypeScript library for describing file structures as data and writing them to disk. If you've ever built a CLI, a scaffolding tool, or anything that needs to generate a bunch of files and folders, you know the usual approach: a pile of fs.writeFileSync calls, manual path joins, and conditional logic scattered everywhere. ts-treegen is my attempt at making that feel less like plumbing and more like just describing what you want. What it looks like import { file , dir , emit , plan } from " ts-treegen/node " ; const files = await emit ( file ( " README.md " , " # My New App " ), dir ( " src " , file ( " index.ts " , " console.log('hello'); " )), ); const p = await plan ( files , { targetDir : " ./output " }); await p . run (); file() and dir() build a tree. emit() resolves it. plan() figures out what needs to be written and gives you a chance to inspect it before anything touches disk. That's the whole API. Conditional files don't need any special syntax either. It's just JavaScript: isProd && file ( " .env.production " , " NODE_ENV=production " ); No template tags, no wrapper nodes to learn. If a value is falsy, it's filtered out. Why I built it this way The goal from the start was to keep the surface area small enough that you could hold the whole API in your head after reading the README once. I went through a few iterations before landing here, and each one was mostly about removing things rather than adding them. Conflict resolution collapsed down to a single overwrite flag. Copy helpers got cut because fs.cp already does the job. Custom error types got replaced with things you'd actually reach for in normal code. Every feature I kept had to earn its place by solving something real, not just being possible to build. Along the way the library also became runtime-agnostic. The core has zero dependencies and works against a small FileSystem interface, so I/O is fully pluggable. ts-treegen/node wires up Node's fs/promises fo
$20/Month: The Price Ceiling Every AI Company Copied
In this blog post, we will see why almost every major AI subscription, ChatGPT, Claude, Perplexity, and Gemini, somehow landed on the exact same $20 a month price tag. We will trace it back to where it started, look at the actual reasoning behind the number, and figure out whether this price ceiling will hold or eventually crack the way streaming subscriptions did. The $20 monthly price point shared by ChatGPT Plus, Claude Pro, Perplexity Pro, and Google AI Pro traces back to OpenAI's February 2023 launch, which was designed to subsidize free-tier costs rather than reflect the actual value of the product. Competitors adopted the number through price anchoring, not independent cost analysis. The same pattern has extended to smaller AI tools and is now repeating at higher tiers, with $200 and $100 monthly plans emerging for power users. Despite identical pricing, what each $20 subscription delivers varies significantly across providers in terms of usage limits, features, and model access. The Coincidence That Isn't a Coincidence As of mid-2026, ChatGPT Plus, Claude Pro, and Perplexity Pro all cost exactly $20 a month. Google AI Pro (formerly Gemini Advanced) sits one cent below at $19.99. Four completely different companies, four completely different models, and yet the sticker price converges on almost the same number. That's not four companies independently landing on the same cost math. It's one company setting a price, and everyone else deciding not to compete on it. Where It Actually Started: OpenAI, February 2023 ChatGPT launched free in November 2022 and crossed a million users within about a month, which was an enormous number for a research preview. On February 1, 2023, OpenAI introduced ChatGPT Plus at $20 a month, expanding it internationally on February 10. The pitch at the time was simple: general access even during peak load, faster responses, and priority access to new features. Worth remembering: this was the GPT-3.5 era. GPT-4 hadn't shipped yet. Subs
Customizable workout app
If you are like me, then you have also tried to change a specific thing in your workout plan that your app of choice didn't support. Well I'm trying to fix that issue with a workout app in which you'll be able to customize pretty much everything (WIP). Building the thing in Flutter to have mobile (starting with Android) and web. The web app is live! If you work out and have tried similar apps before, your feedback would be gold. But really any feedback is appreciated. I also found that finding the required 12 people with an Android phone for closed testing on Google Play Console was more difficult than anticipated. So if you'd be interested in that, hit me up at dev@notes.fitness ! Gym Notes — A Customizable Workout Logbook for Strength Training A free, customizable workout logbook that tracks exercises, sets, reps, and weights. Built-in training plans with automatic progression. gym.notes.fitness
Stop Rebasing Every Time: A Safer Way to Keep Your Git Branch Updated with `master`
If you work on long-lived feature branches, you've probably experienced this: master (or main ) keeps moving. Your branch falls behind. Pull requests become harder to review. Merge conflicts get bigger every day. Many teams solve this by rebasing their feature branches. Others—including many enterprise teams—prefer merging the latest master into the feature branch to preserve commit history and avoid rewriting commits that may already be shared. If your workflow uses merge instead of rebase, this article shows how to make the process much faster with a custom Git alias. The Problem Imagine your repository looks like this. master A──B──C──D feature/login \ E──F While you're developing, your teammates merge several pull requests. master A──B──C──D──G──H──I feature/login \ E──F Now your feature branch is missing the latest changes. If you don't sync it: merge conflicts accumulate CI may fail unexpectedly testing becomes less reliable your eventual pull request becomes much harder to review Keeping your branch up-to-date regularly makes integration much smoother. Updating Your Branch Manually Suppose you're working on: feature/login and want to sync it with master . First, fetch the latest changes: git fetch origin Switch to your feature branch: git checkout feature/login Reset your local branch to match the remote version: git reset --hard origin/feature/login Why reset? This ensures your local branch exactly matches the remote branch before merging. It's useful if your local branch is only a working copy of the remote branch. Warning: Any unpushed commits will be permanently deleted. Merge the latest master : git merge --no-ff origin/master Finally, push the updated branch: git push Your history now becomes: master A──B──C──D──G──H──I \ feature/login M \ / E──────F where M is the merge commit. That's a Lot of Typing... Every time you want to synchronize a branch, you're repeating the same commands: git fetch git checkout feature/login git reset --hard origin/feature/l
Apple has banned home service content on upcoming Maps ads
The company may be trying to save ad space for local businesses.
Google might not kneecap the Pixel 11a with an old processor
Mystic Leaks suggests that the Pixel 11a will return to featuring a flagship-grade processor with the Tensor G6. Rather than the Tensor G5 found in the Pixel 10 and 10 Pro, the Pixel 10a shipped with the previous generation Tensor G4. That was a huge disappointment since, typically, the Pixel a lineup kept the modern […]
Your HTML is fine. The CDN still blocks the bot.
This started as a comment @wrencalloway left on my last post. It was sharp enough that it deserved more than a reply — so here's the full version. You did the work. The page is server-rendered. The JSON-LD is in the raw response. curl returns the whole article, headline and all. A crawler that fetches your URL gets everything it needs. Except the crawler never fetches your URL. It asks the CDN, and the CDN says 403. Your content is perfect and unreachable. This is the layer underneath the one everyone talks about — and it's invisible in every tool you'd normally reach for. Two different kinds of "no" robots.txt is a note taped to the door. It says "please don't come in." A polite crawler reads it and turns around. A rude one ignores it and walks straight past. Either way, the note never touches your bytes — it's a request, enforced entirely by the visitor's own manners. A WAF or CDN rule is the door. It answers the request itself, at the edge, before anything reaches your origin: 403 Forbidden , 429 Too Many Requests , or a JavaScript challenge the bot can't solve. The HTML behind that door could be a masterpiece or a blank page. The bot sees neither. It sees the status code. People spend weeks perfecting the note and never check whether the door is locked. This isn't hypothetical — here's the data Cloudflare Radar publishes what actually happens to AI-crawler traffic across its network. From the AI Insights dashboard (7-day view, as of 18 July 2026): Of all HTTP responses served to AI bots and crawlers: 200 OK — 73.6% 403 Forbidden — 5.2% 429 Too Many Requests — 1.3% 503 — 1.1% AI-crawler response codes. Source: Cloudflare Radar, AI Insights, 7-day view, 18 Jul 2026. Read that again. More than one in fifteen requests from AI crawlers is being actively refused at the edge — 403 or 429 — before it ever touches the content. Not deprioritised. Refused. And most of that isn't a decision. It's a default — a managed WAF ruleset, a "block AI bots" toggle flipped in 2024, a
I Built a Crew of AI Agents That Review Code Like a Real Team — Then Watched Them Argue With SigNoz
I Built a Crew of AI Agents That Review Code Like a Real Team — Then Watched Them Argue With SigNoz My submission for the Agents of SigNoz Hackathon (Track: AI & Agent Observability) The idea Most "AI code review" demos are one LLM call with a clever prompt. That's fine, but it doesn't reflect how review actually works on a real team — different people care about different things. Someone obsesses over edge cases. Someone else nitpicks naming. Someone else only cares if it's going to be slow in production. And then someone has to actually make the call on whether the PR merges. So I built that as a crew: a Logic Reviewer , a Style Reviewer , and a Performance Reviewer — three independent agents, each with a narrow system prompt that tells them to only look at their lane — followed by a Moderator agent that reads all three opinions and produces one final verdict, calling out disagreement when it happens. The interesting engineering problem wasn't the prompting. It was: once you have four chained LLM calls, how do you actually know what's happening inside your own system? Why observability, not just another agent demo Once I had the crew working, I had zero visibility into it. Four sequential API calls, each with its own latency and token cost, and all I had was print() statements. If the moderator gave a weird verdict, I had no fast way to tell whether the logic reviewer hallucinated an issue, or the moderator just summarized badly. If a run felt slow, I couldn't tell which of the four agents was the bottleneck. This is exactly the gap SigNoz is built for, so I instrumented every agent call with OpenTelemetry: Each specialist agent and the moderator run inside their own span ( agent.logic_reviewer , agent.style_reviewer , agent.performance_reviewer , agent.moderator ) All four are nested under one parent span, code_review_session , so a single review run shows up as one trace with four child spans Every span carries the attributes that actually matter for debugging a
Project Log #17: My Agent Misreads Bank Balances. Here's How I'm Fixing It.
Day 17. OCR on banking apps is unreliable. I built a verification layer that double-checks every number. Day 16 was a milestone: multi-app workflows. The agent copied my bank balance and sent it to Mom on WhatsApp. Three apps. One task. But behind that success was an uncomfortable truth: the agent misreads numbers about 20% of the time. For a message to Mom, that's a typo. For a financial transaction, that's a disaster. Today, I built the fix. The Problem Banking apps scored F on my accessibility audit. No UI labels. No content descriptions. The agent has to rely entirely on OCR to read anything on screen. And banking apps have terrible OCR conditions: Small, condensed fonts for account numbers and balances Low contrast (grey text on slightly darker grey backgrounds) Currency symbols (₦, $, £) that OCR often confuses with numbers Commas in large numbers that OCR sometimes reads as decimals The result? A balance of "₦15,000" sometimes gets read as "₦15.000" or "₦15,00" or "₦15000." One missing digit. One wrong decimal. And the entire task is compromised. The Fix: Numeric Verification Layer I built a verification step specifically for financial data. Before any number gets stored in task memory, it goes through three checks. Check 1: Format Validation The extracted text must match a valid currency format. It must contain a currency symbol (₦, $, £, €) followed by digits, optionally with commas and a decimal point. Anything that doesn't match this pattern is rejected immediately. Check 2: Double-Read Confirmation The agent reads the same number twice—two separate screenshots, two separate OCR passes. If both readings match exactly, the number is accepted. If they differ, the agent reads a third time. If two out of three match, that value wins. If all three differ, the task is aborted with an error message. Check 3: Range Validation The extracted number must fall within a reasonable range. A bank balance of "₦0" or "₦999,999,999,999" is probably an OCR error. The agent