今日已更新 143 条资讯 | 累计 40588 条内容
关于我们

标签:#showdev

找到 487 篇相关文章

AI 资讯

I pulled Roblox's public API every day for a week to watch one game go vertical

Late August I kept seeing the name Dungeon Lootr in places it hadn't been before. I wanted to know whether the game was actually growing or whether I was just noticing it more. Turns out Roblox exposes enough public data to answer that without an API key, so I started pulling it every day. The endpoint is boring in the best way: curl "https://games.roblox.com/v1/games?universeIds=9656201728" You get back visits , playing , favoritedCount , updated and a few other fields. A second call to /v1/games/votes?universeIds=... gives you up and down votes. No auth, no rate-limit drama at once-a-day volume. Here is what a week of that looks like for this one game: Date Total visits Playing right now Favorites Approval Sep 2 4.83M — 25.5k 96% Sep 3 5.39M 10.8k 29.8k 96.1% Sep 4 6.85M 11.4k 38.6k 96.1% That is about 1.4 million more visits than when I checked yesterday, and favorites jumped by almost nine thousand. The updated timestamp moved twice in two days (Sep 2 23:06 UTC and Sep 4 00:56 UTC), so the developers are shipping while the curve is climbing rather than sitting on it. The part that surprised me: the game was created on January 31, 2026. It sat there for seven months doing nothing visible, then flipped in the last week of August. I do not have a clean explanation. No single creator video I can point to, no front-page placement I noticed. It just started compounding. I wrapped the two calls into a tiny CLI so I would stop retyping the universe ID: https://github.com/jackzhouqd/roblox-game-stats — plain Python, no dependencies. Point it at any universe ID and it prints the same table. A few caveats before anyone reads too much into this: visits is cumulative and not deduplicated. It counts sessions, not people. playing is a snapshot at the moment you call it. Hit it at 3am and you will get a different number than at 8pm. One day of movement means nothing on its own. A week of movement in the same direction is when I start paying attention. What I am doing with it: I

2026-09-04 原文 →
AI 资讯

fetch-sentinel v0.1-alpha: guardian en tiempo de fetch para agentes, con KI abiertos declarados

🛡️ fetch-sentinel: El cortafuegos local (CPU-Only) para blindar la ventana de contexto de tus agentes de IA frente a inyecciones indirectas de prompts. Internet es hostil por defecto. Tu agente ya no tiene por qué estar expuesto. fetch-sentinel es un guardia estructural en el punto de entrada cuando un agente autonomo hace fetch de contenido web arbitrario. Su trabajo es decidir, antes de que el contenido externo entre al contexto del LLM, que partes son dato y que partes son instruccion. Este post NO presenta fetch-sentinel como un producto listo para produccion. Lo presenta como un repositorio alfa con cuatro capas obligatorias implementadas y verificadas localmente con 161 tests, y con dos KI conocidos abiertos (KI-10, KI-11) que una auditoria independiente identifico en la segunda ronda de revision y que requieren un refactor mayor para cerrarse. El problema: inyeccion indirecta de prompts via contenido fetched Cuando un agente LLM navega la web por su cuenta, el contenido fetched es input no confiable. Un atacante puede inyectar instrucciones en paginas que el agente va a leer como si fueran parte del prompt del sistema: Texto invisible en comentarios HTML, atributos alt, metadata. Codepoints Unicode ofuscados (TAG block, ZWSP, BIDI override) que sobreviven a la mayoria de los pipelines de sanitizacion. Manipulacion semantica sin instruccion explicita: propaganda o "hechos" seleccionados empaquetados como resumen. Exfiltracion en cadena: si el agente tiene acceso a shell, email o API keys, una inyeccion exitosa escala a accion real no autorizada. Los firewalls semanticos no resuelven esto (intentar defenderse contra manipulacion semantica convierte el componente en algo que no funciona). Lo que resuelve el problema es defender el punto de entrada. Que hace fetch-sentinel Cuatro capas obligatorias: Capa Modulo Que hace 1 - Fetch aislado core/fetcher.py Extraccion readability sobre html.parser (stdlib), descarta <script> , <style> , <iframe> , <noscript> , <objec

2026-09-04 原文 →
AI 资讯

I made a habit tracker where you can filter and sort by anything

OpenHabitTracker is a free, open source habit tracker that also holds your notes and tasks. It runs on Windows, Linux, macOS, iOS, Android and in a browser, with no ads and no account. Filtering and sorting habits A habit here is not measured by a streak. It is measured by how much of its interval has gone by. A habit you want to do every ten days, two days late, is at 120%. A habit you want to do every four days, also two days late, is at 150%. Because that is a number, you can filter on a range of it: only habits above 50%, only habits below 150%, or only the ones in between. That last one is everything neither freshly done nor badly overdue. You can sort by it as well, and the sort takes the repeat count into account, so a habit done three times a day and one done weekly are compared against each other rather than the daily ones always sitting on top. There are other ways to sort habits by time: how long you want between repeats, how long it has actually been averaging, how long since the last one, and how much time you have spent on it in total or per completion. Notes and tasks sort by the plain things, category, priority and title, and tasks also by their planned date and duration. Each of the three keeps its own sort order. Filtering by date Tasks have a planned date. Tasks and habits have the dates they were completed on. Both are filtered separately, each before, on, after or not on a date you pick. A filter can also take a number of days from today instead of a date. Minus seven to plus seven is the week either side of now, and it still means that in a month, because the days are counted at the moment you look rather than the moment you set it. Showing what was not done The completed-date filter has a switch next to it. Turned on, the range shows what you finished in those days. Turned off, the same range shows what you did not. Searching notes, tasks and habits Searching a note searches the whole note, not just its title. Searching tasks and habits search

2026-09-04 原文 →
AI 资讯

Why I gave Claude Code a computer instead of building another IDE

Most "AI coding" products still put a chat window next to your editor and call it a day. I wanted something closer to what Claude Code already does well on a server: give it a real computer and let it drive. Superagent is a Mac app that gives Claude Code (or any agent you point it at) an actual environment to work in, not just a text box. Concretely: A real browser it can navigate, click, type into, and read the DOM of, not screenshots and guesses. An iOS Simulator window it can install apps into, tap through, and screenshot to verify UI changes. A relay that pairs your Mac with your phone, so the agent can keep working (and you can keep watching) from your pocket. The core idea is boring on purpose: don't build a smarter chat window, build a better place for the agent to act. Most of the interesting failures I hit while building this weren't in the model, they were in the environment: synthetic file inputs that don't persist through a web form's upload component, elements that exist in the DOM but aren't in the accessibility tree, simulator state that drifts from what a screenshot shows. Fixing those is what actually makes an agent reliable to hand a task to. It's built as three pieces: an Electron desktop app, a SwiftUI iOS companion, and a small Cloudflare Worker relay that pairs the two with per-address rate limits so a lost phone can't be used to spam a stranger's Mac. If you want to see it: https://peerlist.io/pungme/project/superagent-for-mac Happy to answer questions about the browser automation approach, the simulator driving, or the relay's pairing/security model in the comments.

2026-09-03 原文 →
AI 资讯

I Built the World's Most Customizable Scientific Calculator (30+ Themes, Python + PyQt6)

The idea Every OS ships a calculator. Every one of them looks the same, feels the same, and disappears from memory the moment you close it. So I built ACALCU v3 — an Akhouri Systems product — a scientific calculator that's absurdly, unnecessarily customizable. Not because a calculator needs 30+ themes and per-button styling, but because it was a fun constraint to design around: how far can you push a "boring" utility app before it becomes something people actually enjoy using? What it does At its core, ACALCU is a standard scientific calculator: basic arithmetic, sin, cos, tan, log, √, π, percentages, and a running expression engine built on Python's math module. On top of that core, it layers: 30+ built-in themes — Royal, Liquid Glass, Wild, Cyberpunk, Dracula, Nord, Solarized, Monokai, Windows 7 / Vista / 10, OneUI 8.0, Matrix, Rose Gold, Galaxy, Fire, Ice, Neon, Vintage, Sakura, Midnight, Forest, Candy, Terminal, Gold Dark, and more. Per-button customization — right-click any button to change its color, font, or set a custom image/video as its background. Every button on the grid is independently styleable. A live "Wild" theme — a small animated plant widget that visibly grows every time you run a calculation. Calculation history — a scrollable dialog of your last 50 calculations. Persistent config — every customization is saved to a local JSON file and reloaded on next launch. Full keyboard support — number keys, operators, Enter/Escape, all mapped to the same input pipeline the buttons use. Architecture The whole thing is a single-file PyQt6 desktop app, structured around a few core pieces: python THEMES = { "DEFAULT": { "app_bg": "#0a0a0a", "display_bg": "#111111", ... }, "ROYAL": { "app_bg": "#0a0800", "display_fg": "#ffd700", ... }, "LIQUID_GLASS": { "app_bg": "transparent", ... , "transparent": True }, # ...30+ more } Each theme is just a dict of colors, font, corner radius, and optional flags (transparent, wild). The Config class resolves the active theme

2026-09-03 原文 →
AI 资讯

Why I Built ToolVerse: A Solo Developer’s Journey to Making Financial Clarity Private and Free

Can I Afford This? 1. The Story Behind the Code ​Every developer knows the late nights, the stubborn bugs, and the quiet satisfaction of seeing a project finally come to life. For the past few weeks, my world has revolved around a single mission: building ToolVerse. ​ 2. Like many of you, I looked at the current landscape of financial tools—cluttered with intrusive trackers, forced sign-ups, and paywalls—and asked a simple question: What if we could do better? ​ 3. What if people could calculate their debt consolidation, check their ACA health insurance premiums, or map out their tax withholding scenarios instantly, securely, and completely privately right inside their browser? ​ 4. What is ToolVerse? ​ToolVerse is a collection of high-intent, lightning-fast financial decision tools designed for the US audience. It runs on a lean, efficient stack: ​ 5. Frontend & Hosting: Hosted seamlessly on GitHub Pages for blazing-fast load times and global reach. ​ ** Backend Intelligence:** Powered by Vercel server-side API execution to handle complex lookups (like ACA subsidy calculations) securely without storing user data. ​Privacy-First Architecture: No mandatory accounts, no email walls, and zero data selling. Calculations happen right where they belong—on the user's device. **​ The Reality of Solo Building** ​Building this as a solo creator hasn't been a straight line. From battling server-side routing issues to optimizing sitemaps for Google Search Console indexing, every single line of code taught me resilience. There were days when things broke, but seeing those first users land on the platform and find actual value in these tools made every sleepless night worth it. ​ 8. Let's Build Together! ​ToolVerse is growing, and its infrastructure is ready for scale. 9. I am currently looking for: ​Collaborators & Open-Source Contributors who are passionate about building useful, privacy-first web utilities. ​10. Sponsors & API Partners in the US financial and health tech space

2026-09-03 原文 →
AI 资讯

Qisutu: An Open-Source, Self-Hosted Service Desk for ITSM and Automation

Many organizations still need a service desk that runs on their own infrastructure. They may have strict data-protection requirements, existing directory services, internal workflows, or simply want to remain in control of their system and data. That is why we created Qisutu : a fully open-source, self-hosted service desk for ticketing, IT service management, and process automation. Qisutu 1.0.3 is the current stable release and is ready for production use. What Qisutu provides Qisutu combines the core components needed to operate a professional service desk: Agent and customer portals Ticket creation through the web interface and email Queue-based ticket processing Automation and configurable workflows Knowledge base and multilingual FAQ articles Configurable CMDB Reports and statistics REST API Custom customer and public web forms Time tracking with billable and non-billable entries CSV imports for customers, contacts, and agents Two-factor authentication using TOTP LDAP and Active Directory integration Microsoft 365 and Google Workspace email integration using OAuth2 A module manager and a versioned API for add-ons The system currently includes eleven complete interface languages: German English French Italian Brazilian Portuguese European Portuguese Spanish Dutch Polish Czech Turkish Built for self-hosting Qisutu runs entirely on infrastructure controlled by the organization using it. Ticket data, customer information, attachments, credentials, and configuration remain on the operator's own server. The software is based on: Perl and CGI MariaDB or MySQL Template Toolkit Apache A browser-based user interface The installation script prepares the required packages, Perl modules, Apache configuration, systemd services, database configuration, and web installer. Multiple Qisutu instances can run independently on the same server. This makes it possible to maintain separate production and test environments without mixing their databases, services, or configuration. Ema

2026-09-03 原文 →
AI 资讯

ADAM-PS5

🎮 ADAM-PS5 — A PS5 Emulator in Development I’m working on an ambitious project called ADAM-PS5 , with the ultimate goal of developing a PlayStation 5 emulator for PC capable of running PS5 games . The project is still in the early stages of development , and I do not consider it a complete emulator at this point. I’m building the foundation step by step: system architecture, low-level emulation, memory and resource management, graphics, input handling, execution, debugging, and development tools. 🚧 Early Development There is still a huge amount of work ahead before reaching the point where commercial PS5 games can actually run. That’s why I’m sharing the project from its early stages rather than presenting it as a finished product. 🤖 One of the project’s goals is also to integrate Artificial Intelligence to help analyze errors, monitor performance, understand system logs, and assist with the development process. The long-term goal is: PC → ADAM-PS5 → PS5 Software Environment → Games Reaching that stage requires implementing and accurately simulating many different components of the console’s hardware and software architecture. I’m sharing the project now because I want to document the entire development journey from the beginning — including what gets built, what fails, what gets improved, and how the project evolves with each release. 🔥 ADAM-PS5 is not finished. It is being built. And the ultimate goal is simple: Run PlayStation 5 games on PC through our own emulator. ADAM-PS5 is an independent development project and is not affiliated with Sony Interactive Entertainment.

2026-09-03 原文 →
AI 资讯

You don't need a remote desktop for the room you're standing in

Someone plugs in the HDMI cable. The room's display shows nothing, or shows 1024×768, or shows the desktop of whoever presented last week. After a minute of this, somebody says "just share your screen", and out comes AnyDesk or TeamViewer. It works. It is also the wrong shape for the problem, and noticing why turns out to be more interesting than it sounds. What remote desktop tools are actually for AnyDesk, TeamViewer and RustDesk exist to solve one problem well: reach a machine you are not near. Your parent's laptop. A server in a rack. A colleague's desktop three time zones away. Everything about their design follows from that. One person connects to one machine. That person takes the mouse. The remote screen is mirrored to them, and the whole session is framed as control — because when you are not in the room, control is the only way to do anything. Being fair about the privacy question, because it is the claim people reach for first and it is wrong: AnyDesk has a LAN mode , and in it a session goes directly between the two machines without the internet. RustDesk can be self-hosted entirely on your own infrastructure. Neither of these tools forces your screen through somebody's cloud if you configure them not to. If you have read that they do, that is not accurate. The mismatch is not privacy. It is shape. The relay, the account and the NAT traversal are not overhead — they are the product, and they are what makes reaching a machine in another country possible at all. Standing beside the machine, you pay for all three and use none of them. Where the shape stops fitting Stand in a room with four people and a Mac, and three things go wrong at once. It is one-to-one. Remote desktop is a session between two endpoints. Four people looking at one screen is not what it models, so three of them read over a shoulder. It mirrors, and mirroring is sometimes the wrong answer. Every tool in this category shows a screen that already exists. But the meeting-room problem is oft

2026-09-02 原文 →
开发者

Small update since this post was published: added dark theme, improved tooltips, more optimization for phones, "Share" button, puzzle intro on first visit, and PWA support, so the app installs like a regular app. Still open to feedback! I'd really apprecia

I created an interactive version of the Zebra puzzle (Einstein's riddle) - I would appreciate your feedback! Andrii Andrii Andrii Follow Aug 24 I created an interactive version of the Zebra puzzle (Einstein's riddle) - I would appreciate your feedback! # showdev # frontend # webdev 3 comments 2 min read

2026-09-02 原文 →
AI 资讯

I Built Hydration Buddy: A Floating Hydration Companion for Windows

I spend long hours working on a computer, and one simple thing I regularly forget is drinking enough water. Most hydration apps rely on notifications. The problem? Notifications are very easy to dismiss. So I started building Hydration Buddy : a lightweight Windows app designed to stay visible without constantly interrupting your workflow. What it does Tracks daily water intake Shows your daily hydration progress Gives gentle reminders Lets you quickly log water Includes a small floating companion that stays on screen Keeps the experience lightweight and simple Why I built it The idea wasn't to build another notification app. I wanted something that could quietly stay present while I'm coding or working and make the habit harder to forget. Hydration Buddy is currently in beta, so I'm still testing the experience and improving it based on real user feedback. 🎁 The first 25 beta users get free lifetime access. You can try it here: https://hydrationbuddy.patelmahek.in/ If you test it, I'd especially love feedback on: The floating companion Reminder experience Ease of logging water Features you'd like to see next I'm building this in public, so I'll also share some of the technical decisions, mistakes, and improvements as the product evolves.

2026-09-02 原文 →
开发者

You dismiss reminders. You don't ignore a pet.

Mushroom is a tiny pixel creature that lives on your Mac . It can tell when you are actually at the desk, so it nudges you to drink, move and rest your eyes at the moments that help, and stays quiet when they would not. Made for people who sit at a Mac for hours. Developers, designers, writers, students, anyone whose focus is the problem and the job at the same time. Mushroom can do lots of things: https://www.getmushroom.app/features Pricing: https://www.getmushroom.app/pricing If you've seen Mushroom elsewhere, please let me know where. If you miss a feature, please tell me. I'm open for feedback and suggestions. Personal comment: I have created Mushroom because I wanted a very simple way to set up a quick reminder. You just type what and when in one sentence, and your reminder is set. Over the course of weeks, it evolved into a whole set of features. I'd like to thank Michael K. Graves for helping with ideas and suggestions, and I'd like to thank Caz-Bee for providing the graphics. Thank you for giving my post attention.

2026-09-02 原文 →
AI 资讯

I Built a Link-in-Bio Platform… Then I Asked: “Why Would Anyone Come Back?”

On July 11, 2026, I started building a project inspired by link-in-bio platforms. The idea was pretty straightforward: Create a profile → customize it → add your links → share it. So I built Rizzzler. And right now, it has 11 users. Yep. 11 😂 Not exactly the kind of number you'd put on a startup pitch deck. But those 11 users actually made me think about the project in a completely different way. The problem I noticed 🤔 I started looking at how people were using Rizzzler. And I noticed something: People would create their profile... Then disappear. Some wouldn't come back for a week. Some wouldn't even check the app for weeks. And eventually I realized something obvious. Why would they? Rizzzler was primarily a profile website. Once you've created your profile and shared your link, what reason do you have to open it again? You don't. That got me thinking: What else can we actually do with a profile? I didn't want Rizzzler to become something people set up once and completely forget about. I wanted the profile to actually do something. And that's where I got a pretty crazy idea. What if Rizzzler became more than a profile? I've used services that let you log into other applications using their account. For example: Sign in with GitHub. That got me thinking: What if Rizzzler could do something similar? Instead of Rizzzler only being a place where you create a profile... What if developers could use Rizzzler as an identity provider? And suddenly I had a new idea: Sign in with Rizzzler That was probably the craziest idea I've had for this project so far. And I decided to build it. I built my own OAuth 2.0 system 🔐 I started building the OAuth 2.0 mechanism, the developer-side integration, and the documentation. I also created a developer docs page so developers can understand how to integrate Sign in with Rizzzler into their applications. I've tested the mechanism locally, but there's an important distinction: It hasn't been properly tested by a real third-party applica

2026-09-02 原文 →
AI 资讯

Split PDF Pages in the Browser with pdf-lib — No Uploads, No Server

A few weeks ago I built a free online Merge PDF tool that runs 100% in the browser. Today I'm sharing its sibling: a Split PDF tool using the same library — pdf-lib — with zero file uploads, zero watermark, and zero server code. You can try it live here: https://yourutilityhub.com/pdf/split-pdf Why split PDFs in the browser? Most online PDF tools upload your file to a server — which means your document is never truly private. Splitting pages locally means: No uploads — nothing leaves your device No watermark or signup Free — no per-page charges Works offline, fast, for files of any size (limited by your browser's memory) The plan We'll load the PDF, pick a page range (or specific pages), copy those pages into a fresh PDFDocument , and save the result — all with pdf-lib . Let's walk through the full working component . 1. Install and import npm install pdf-lib import { PDFDocument } from " pdf-lib " ; 2. Load the uploaded file const arrayBuffer = await file . arrayBuffer (); const pdf = await PDFDocument . load ( arrayBuffer ); const totalPages = pdf . getPageCount (); PDFDocument.load() accepts an ArrayBuffer . We read it straight from the File object — no server involved. 3. Split by page range (e.g. 1-5 or 3- ) const parts = pageRange . split ( " - " ); const startRaw = parseInt ( parts [ 0 ]. trim (), 10 ); const endRaw = parts [ 1 ]. trim () === "" ? totalPages : parseInt ( parts [ 1 ]. trim (), 10 ); // validate 1..totalPages const startPage = Math . min ( startRaw , endRaw ) - 1 ; // 0-based const endPage = Math . max ( startRaw , endRaw ) - 1 ; const newPdf = await PDFDocument . create (); const pageIndices = []; for ( let i = startPage ; i <= endPage ; i ++ ) { pageIndices . push ( i ); } const copiedPages = await newPdf . copyPages ( pdf , pageIndices ); copiedPages . forEach ( page => newPdf . addPage ( page )); The trick: copyPages() wants 0-based indices , but users type 1-based page numbers, so we subtract 1. "3-" with an empty end means "to the last pa

2026-09-02 原文 →
开发者

How an Abandoned Client Project Became My Proudest Showcase

In the first part of this series , I walked through the technical grit of rebuilding a musician's web platform from scratch—spending over 320 hours fixing legacy WordPress code, writing custom CLI tools with Node.js and FFmpeg, and crafting a lightweight Vanilla JS SPA router. If Part 1 was about the engineering side , Part 2 is about the human side : scope creep, irrational client expectations, and why finishing an "abandoned" project is sometimes the ultimate test of a developer’s character. "Appetite Comes With Eating": How a Volunteer Portfolio Case Turned Into Scope Creep They say the road to hell is paved with good intentions. We stepped into this project on pure enthusiasm. The agreement was simple: we help an independent artist build a sleek web presence for free, and in return, we get a real-world production case for our engineering portfolios. Win-win, right? At the beginning, everything was smooth. The client was absolutely thrilled with the initial UI/UX prototypes. But as soon as the application was actually hosted and brought to life, the "appetite" started growing exponentially: Phase 1 (Initial tweaks): "Can we change the album cover art?" — Sure thing. It's your music, your Bandcamp embed—done. Phase 2 (The Breaking Point): "The fonts don't feel right... can we rewrite the copy?" This was the final straw. Keep in mind: we had repeatedly confirmed typography and styling choices with the client earlier, and everything had been approved. When my teammate David politely informed the client that fundamental UI changes were outside the scope of our volunteer agreement, the client responded with: "Just show me where the files are, and I'll change the fonts myself." For anyone who works in web development, this was the ultimate ironic punchline. Changing fluid typography, responsive SCSS breakpoints, and layout variables isn't like picking a font in Microsoft Word. Knowing that the client had previously struggled to set up a basic Bandcamp profile, we wishe

2026-09-01 原文 →
AI 资讯

I built a location-to-station finder for China’s high-speed rail

China’s high-speed rail network is easy to admire and surprisingly easy to use once you know the correct station. The difficult part for many first-time visitors happens earlier: a single city can have several major stations, and a traveler often starts with a hotel, airport, attraction, or street address—not a station name. I initially wanted to build a practical transport tool for foreign visitors in China. After reading travel questions, the recurring problem was not simply “how do I buy a train ticket?” It was: Which station should I depart from? Is Shanghai Hongqiao the same place as Shanghai Station? Which English station name matches the Chinese name shown in the booking app? Is the nearest station actually useful for my destination? So I built a small station-finding workflow instead of another static railway map. The workflow The user enters two real places: where they are starting from, such as a hotel or airport; where they are going, such as another hotel, city center, or attraction. The page then shows candidate departure and arrival stations side by side, with both English and Chinese station names. After the user selects a pair, the tool prepares the exact station names for an official Railway 12306 check. You can try the current version here: China high-speed rail station finder Why I did not turn it into a ticket seller Railway schedules, ticket availability, fares, and passenger rules are official-service data. I do not want a travel helper to imply that a route exists merely because two stations are geographically close. The boundary is therefore deliberate: Ask-China helps turn real places into candidate stations. It shows bilingual names so travelers can recognize the correct station. Railway 12306 remains the final place to verify the journey and book. This also keeps failure states honest. If place search or route estimation is unavailable, the page should say that instead of inventing a confident answer. The implementation decisions that matt

2026-09-01 原文 →
AI 资讯

I raced six models against each other on DigitalOcean Inference. The cheapest one won.

Every time I put a model behind an endpoint I make the same lazy decision. I pick whatever I used last time, or whatever I read about most recently, and I tell myself I'll benchmark it properly later, and later never arrives because there is always something with an actual deadline on it and comparing model latencies feels like procrastination even when it isn't. I never do it. Not once. So I built the thing that would make me do it. One prompt, fired at six models at once, streaming side by side in columns, with time to first token and cost per run underneath each one. About 390 lines of Python. Code's here , MIT, take it. Then I ran it, and three things happened that I didn't plan for. The integration is two lines, and that's the least interesting part DigitalOcean's inference endpoint speaks OpenAI, so this is the whole thing: client = OpenAI ( base_url = " https://inference.do-ai.run/v1/ " , api_key = os . environ [ " DIGITAL_OCEAN_MODEL_ACCESS_KEY " ], ) Every model below goes through that one client. Llama, DeepSeek, Mistral, Qwen, OpenAI's open-weight gpt-oss line. Only the model string changes. That is the pitch, and it's real, and I'll move past it quickly because you already knew an OpenAI-compatible endpoint would work like an OpenAI- compatible endpoint. What I didn't know is everything that follows. One footnote before you paste that snippet. The credential is a model access key , created under the Gradient AI Platform. It is not the API token from Settings, API. Different thing, different page. (Although, as I found out later, the endpoint doesn't care nearly as much about that distinction as the docs do.) Six streams, no event loop I wanted the columns to fill simultaneously. Real racing, not six sequential progress bars pretending. The tidy way to do that is one endpoint that fans out server side and multiplexes everything back down a single connection. I didn't do the tidy way. The browser opens one EventSource per model instead: GET /stream?model=<

2026-09-01 原文 →
AI 资讯

The standard library is not a validator: 72 hours of zero-dependency JSON in Rust

I spent last weekend building a JSON toolkit in Rust under one rule: no third-party dependencies . Not "few". None. The [dependencies] table in Cargo.toml is present and empty, and Cargo.lock holds exactly one package — the project itself. No serde , No serde_json , No clap , No itoa , No ryu . That constraint is the premise of the Zero Dependency hackathon , and it is a good premise, because it forces you to find out what the standard library actually promises. Here is the thing I did not expect to find: About 10% of the JSON documents that RFC 8259 says a parser must reject are accepted by Rust's own number parser. Not a subtle 10%. NaN , Infinity , .5 , 5. , +1 and 012 are all invalid JSON, and f64::from_str and i64::from_str take every one of them. If you write a JSON parser the obvious way — scan to the end of the number token, hand the slice to from_str — you ship a parser that is silently non-conformant, with no warning anywhere. I have the number because I counted it against a real corpus before writing the parser. The rest of this post is what that measurement did to the design, and what generalizes to languages that are not Rust. What I built jaq-lite is a hand-rolled RFC 8259 parser, a serializer, and a jq-style query CLI with rustc -style caret diagnostics — 4,670 lines under src/ and 4,432 lines of tests, standard library only. $ echo '{"users":[{"name":"ada","age":36},{"name":"linus","age":54}]}' | jaq-lite '.users[] | .name' "ada" "linus" It supports identity, field access, quoted fields, indexes, iteration, pipes, commas, parentheses, the optional operator ? , and eleven builtins ( length , keys , keys_unsorted , type , to_entries , from_entries , flatten , first , last , reverse , not ). Exit codes follow jq: 2 for a bad flag, 3 for a filter that does not compile, 5 for input that is not JSON, 0 otherwise. The measurement JSONTestSuite is the standard conformance corpus: 318 files in test_parsing/ , named by what a parser is supposed to do with them

2026-09-01 原文 →
AI 资讯

The wait queue is just a channel: building a small distributed lock server in Go

Sooner or later you hit the same small problem: two services, on two machines, want to touch the same thing at the same moment — append to a shared file, update a row nobody is fencing, call an API that tolerates one caller at a time. One of them has to wait. The usual answers feel heavier than the problem. Put a service in front and serialize everything through it — now you are building a queue, and then a second queue to hand results back, because you no longer know the outcome at the moment you asked. Cache the resource in Redis and lock there — fine until the resource does not fit in memory, and you have inherited Redlock's ordering guarantees (there are none) and its debates. I wanted the lock as its own primitive: lock a key, do the work, unlock the key. Nothing else. That is Locking-Center — a single binary, one dependency, no config file, no consensus layer to operate. This post is about the three ideas that made it small enough to be worth trusting. 1. One channel per key — and the queue comes for free Every key gets a Go channel with a buffer of exactly one: type Channel struct { key string mutexChan chan bool // buffered, capacity 1 } func NewChannel ( key string ) * Channel { return & Channel { key : key , mutexChan : make ( chan bool , 1 )} } Sending into it acquires the lock. Receiving from it releases : c . mutexChan <- true // acquire — blocks if someone already holds the key // ... critical section ... <- c . mutexChan // release The buffer of one is the whole trick. The first send fills the buffer and returns immediately: that caller holds the key. The second send has nowhere to go, so it blocks — and so does the third, and the fourth. The blocked senders are the wait queue. When the holder releases (a receive frees the slot), the runtime wakes the next blocked sender. And it wakes them in order. The Go runtime keeps a FIFO wait queue behind every channel, so callers are served roughly in arrival order rather than whoever happens to reschedule firs

2026-09-01 原文 →