AI 资讯
How to Become a 10x Engineer and Stay Safe in the Age of AI Layoffs
There is a strange contradiction happening in software engineering right now. A lot of developers are worried that AI is going to make them obsolete. At the same time, the people building the most capable AI coding tools are demonstrating something that should probably make us rethink what being a software engineer actually means. I don't think the future is one where nobody understands software anymore. I think it is one where writing the software becomes dramatically cheaper. And if that happens, the thing that makes an engineer valuable has to move. That is what I mean by career safety. Career safety isn't about making yourself impossible to replace. It is about making your value portable. We've always resisted giving up the code Developers have a long history of being suspicious of abstractions that take work away from us. We went from machine code to assembly, from assembly to higher-level languages, from manually managing memory to garbage collection, from building everything ourselves to libraries and frameworks, and from text editors to IDEs. We even had entire categories of tools, such as CASE tools, designed to automate parts of software development. And every time, there was resistance. Because programmers don't just use code. We build our identities around it. John Carmack captured this unusually well when he wrote: “Coding” was never the source of value, and people shouldn’t get overly attached to it. — John Carmack He followed that with the more important point: Problem solving is the core skill. — John Carmack That is a difficult idea for developers to internalize because coding is tangible. You can point at the repository. You can point at the pull request. You can count the commits. You can say, "I wrote this." But the business doesn't ultimately pay you for the number of lines you wrote. It pays you for what those lines accomplish. The business never really bought the code A company doesn't wake up in the morning thinking: "We need 14,000 more line
AI 资讯
Deploying Next.js on a VPS: The 12 Things Nobody Tells You
Moving a Next.js app off Vercel and onto a plain Ubuntu VPS usually starts with a painful realization: either your serverless functions are timing out on background jobs, or your client just handed you a strict "you must host this on our infrastructure" requirement. Deploying the app itself is easy. What trips people up (and what cost me hours of debugging and locking myself out of my own server) is everything around the app. Here are the 12 things that actually break when you leave the serverless ecosystem, in the order you'll hit them. 1. Next.js needs a process manager, not just npm start Running npm start in a terminal dies the moment you disconnect. You need something that keeps the process alive, restarts it on crash, and survives a reboot. PM2 is the simplest option for a single-server Node deploy. npm install -g pm2 // ecosystem.config.js module . exports = { apps : [{ name : " my-app " , script : " node_modules/.bin/next " , args : " start " , cwd : " /var/www/my-app " , instances : 1 , exec_mode : " fork " , autorestart : true , max_memory_restart : " 512M " , env : { NODE_ENV : " production " , PORT : 3000 }, }], }; cd /var/www/my-app && pm2 start ecosystem.config.js pm2 save pm2 startup systemd -u YOUR_USER --hp /home/YOUR_USER That last line is the one people forget - without it, PM2's process list doesn't survive a server reboot. 2. Nginx needs to proxy to the port, not serve the files Next.js is not a static site (unless you've explicitly exported it as one). Nginx's job is to forward requests to the Node process, not serve files from disk: upstream nextjs_upstream { server 127.0.0.1 : 3000 ; keepalive 64 ; } server { listen 80 ; server_name example.com www.example.com ; location / { proxy_pass http://nextjs_upstream ; proxy_set_header Host $host ; proxy_set_header X-Real-IP $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $scheme ; # WebSocket support - required for HMR and any realtime f
AI 资讯
Rigorous Yet Sustainable Human Reviews in the AI Era
Mandatory AI checks paired with manual spikes for complex changes keep developers sharp. Teams can boost velocity by skipping peer reviews on low-risk PRs and using AI approvals, provided most developers are code owners and teams are small. By Ben Linders
AI 资讯
pnpm 12 Rewrites Package Manager in Rust, Accelerating Installs While Preserving pnpm 11 Workflows
pnpm 12 has transitioned to a native Rust implementation, maintaining compatibility with pnpm 11 commands, flags, and formats. This update enhances startup and filesystem performance, particularly when using existing caches. Community feedback highlights the performance gains while noting some trade-offs in larger artifact sizes. By Daniel Curtis
AI 资讯
Ugly AI Food Photos Are Only the Beginning
Restaurant menus with AI-generated food images are going viral for their off-putting aesthetic. But AI’s impact on modern menus runs even deeper.
科技前沿
‘The Blood of Dawnwalker’ Is a Bloody Balm for My Completionism
The game starts as a reheated Witcher 3, but evolves into something much more focused.
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.
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
AI 资讯
The bug your requirements cannot contain
There is a category of defect that cannot appear in your acceptance criteria. Not because nobody thought of it, but because the shape of a requirement has no room for it. A requirement describes a state and a rule. A customer can apply a valid promo code at checkout. State: the code is valid. Rule: it is accepted. Both are evaluated at a single instant, because a sentence has one tense. Real systems do not have one instant. They have two, and sometimes a lot more. The gap between checking and using Take that promo code. The system validates it when the customer types it into the basket. The system commits it when the customer pays. Between those two events sits an unbounded amount of time — thirty seconds if they have their card handy, three days if they leave the tab open on a laptop lid. If the code expires in that gap, what happens? The requirement cannot tell you. It never contemplated a gap, because it was written as one sentence about one moment. And a test written by hand almost certainly cannot tell you either, because a person writing a test naturally writes it the way they would perform it: enter code, assert accepted, pay, assert charged. Three lines, one instant, no gap. This is time-of-check to time-of-use. Most developers first meet it as a security problem — access() then open() , and a symlink swapped in between. The same shape appears at business timescale, and there it is far more common and far less discussed: Stock is reserved at basket, decremented at dispatch. Someone else buys the last one. A permission is checked when the page loads, enforced when the action fires. The role changed. A price is quoted at quote time, charged at renewal. The tariff moved. A rate limit is checked at admission, consumed at execution. The window rolled over. A feature flag is read at session start, branched on at submit. Someone flipped it. A token is validated at the gateway, used by a downstream call. It expired in flight. Every one of those is a real defect clas
AI 资讯
How Does a Website Become Fast?
You open a website. A blank screen appears. You wait. Then finally, the page loads. But what actually happened during those few seconds? Why does one website feel almost instant while another feels painfully slow? It isn't just about writing “better code.” Website performance is the result of many things working together: DNS + networking + servers + HTML + CSS + JavaScript + images + caching + browser rendering And most performance problems come down to two simple questions: What is the browser waiting for? What is the browser doing unnecessarily? Let's break it down. What Actually Happens When You Open a Website? Suppose you enter: https://example.com Your browser has quite a journey ahead. A simplified version looks like this: URL ↓ DNS Lookup ↓ Connect to Server ↓ HTTP Request ↓ Receive Response ↓ Parse HTML ↓ Download CSS / JS / Images ↓ Build DOM + CSSOM ↓ Layout ↓ Paint ↓ Interactive Page Every step takes time. So the goal of performance optimization isn't simply: “Make the code faster.” It's: Reduce unnecessary waiting and unnecessary work. 1. Send Less Data Imagine your homepage downloads: HTML 250 KB CSS 400 KB JavaScript 4 MB Images 8 MB Fonts 2 MB That's a lot of data just to display a page. Now imagine: HTML 80 KB CSS 100 KB JavaScript 500 KB Images 1 MB Fonts 300 KB The browser has significantly less to download and process. This is why techniques such as: Compression Code splitting Lazy loading Responsive images Removing unused dependencies can have a huge impact. A simple rule: If the user doesn't need it yet, don't make them download it yet. 2. Images Can Be Your Biggest Bottleneck You can optimize your JavaScript perfectly... …and still have a slow website because of images. Consider a: 5 MB hero image That's potentially more expensive than many of your JavaScript files combined. Instead of sending a huge original image: <img src= "hero-original.jpg" /> serve an appropriately sized and compressed image. Modern formats such as: WebP AVIF can reduce
AI 资讯
Playwright Test Data: Seeding a Real Backend for E2E Suites
Playwright test data is the set of database rows or API records your application needs to already contain before a browser test runs against it — a logged-in user, their orders, the products those orders reference — generated deterministically so the same run produces the same data every time. Unlike unit tests, a Playwright (or Cypress) spec drives a real browser against a real, running app, which means the backend behind it needs real rows to serve, not an intercepted network response. Getting that data right, and getting it there before the first test starts, is most of what makes a browser E2E suite fast and non-flaky instead of slow and order-dependent. Why is E2E test data hard to manage? Three patterns keep showing up, and each causes a different failure mode: Tests create their own data through the UI. A test that needs an order to exist first signs up a user, logs in, adds a product to a cart, and checks out — all before the actual assertion it cares about. That's slow multiplied across every spec that needs similar setup, and it means the thing under test (the UI) is also the thing doing the setup, so a bug in signup breaks fifty unrelated tests. A shared, mutable test database. If every spec reads and writes the same rows, test order starts to matter: a test that deletes a user breaks a later test that assumed that user still exists. This is one of the most common sources of a suite that passes locally, one file at a time, and fails intermittently in CI when specs run in parallel or in a different order. Hand-maintained fixture SQL or JSON. A fixtures.sql file or a static users.json works until the schema changes — a column gets renamed, a new required field is added — and the fixture silently stops matching what the app expects, or starts failing inserts with no clear signal about which of forty rows is the problem. The fix for all three is the same shape: generate the data the suite needs from a definition (a template), with a fixed seed, right before t
AI 资讯
AI Agent Test Data Generation via MCP Server
An AI coding agent working inside Claude Desktop or Cursor can read your code, write new files, and run your test suite — but it can't open a browser, log into a dashboard, and click "generate" to get a batch of realistic test data. It has no hands for a UI. AI agent test data generation only works if there's something the agent can call : a tool with a defined schema it can invoke mid-session, the same way it calls a file-write or a shell command. That's exactly what the Model Context Protocol (MCP) is for, and it's why we shipped @jsonfabrica/mcp-server on npm. What AI agent test data generation requires over MCP MCP lets an AI client — Claude Desktop, Cursor, or anything else that speaks the protocol — launch a small local server over stdio and treat its exposed functions as tools it can call during a conversation. The agent decides when to call jsonfabrica_generate_from_template the same way it decides when to call read_file . For that to work, three things have to exist: a server process the client can start, a set of tool definitions with typed inputs and outputs, and — underneath all of it — some actual operation the tool call triggers. MCP server test data generation is that last piece: the tool call has to result in real, schema-conformant data coming back, not a stub. @jsonfabrica/mcp-server , concretely We published @jsonfabrica/mcp-server v0.1.1 as a local MCP server: the AI client launches it itself over stdio, no separate process to manage, no port to open. It exposes the JsonFabrica gateway as a set of MCP tools — jsonfabrica_create_template , jsonfabrica_generate_from_template , jsonfabrica_generate_adhoc , jsonfabrica_create_batch , jsonfabrica_create_sequence , and more. Mid-session, an agent can create a template matching the shape of your User or Order model, generate a batch of realistic records against it, and drop the result straight into a fixture file or a seed script — without you leaving the editor to go configure anything by hand. Why thi
AI 资讯
JsonFabrica vs. Mockaroo vs. Faker.js for Test Data Generation
If you're generating test data today, you've probably landed on one of three approaches: click through a UI like Mockaroo, pull in a library like Faker.js and write generation code yourself, or call a hosted API like JsonFabrica. Comparing these test data generation tools side by side, the real differences aren't about which one produces "better" fake data — Faker.js, Mockaroo, and JsonFabrica are all capable of that. The differences are about where the tool lives, how it handles relationships between records, and who's responsible for running it. Three test data generation tools compared, shape by shape Mockaroo is a browser-based UI: you define columns and types through a web form, preview rows, and export a file — or hit its API directly, which is available even on the free tier (paid tiers raise the volume ceiling rather than gate API access itself). Faker.js is a JavaScript library: you import it into your own code and call functions like faker.person.fullName() or faker.internet.email() to build up objects yourself, one field at a time. JsonFabrica is an API-first hosted service: you send a schema (or use a template) to an endpoint and get structured, schema-conformant JSON back, with no UI step and no library to install in your own codebase. That distinction matters more than it sounds. A UI tool is something a person operates by hand. A library is something a developer owns and maintains inside their own project — you write the loops, the relationships, the edge cases. An API-first tool is infrastructure: something your CI pipeline, your seed script, or an AI coding agent can call directly, without a human in the loop or generation logic living in your repo. UI vs. library vs. API, in practice Mockaroo's UI is genuinely fast for a one-off task — sketch a schema, click generate, download a CSV or JSON file. What it isn't built for is wiring generation into an automated pipeline where nobody is clicking anything. Its API can cover that, but at free-tier volume
AI 资讯
Why API-First Wins for Test Data Generation
Plenty of test data tools are built as a UI first and an API second, if there's an API at all. You open a dashboard, configure some fields, click "generate," and download a file. That works fine for a one-off demo. It falls apart the moment test data generation needs to be part of your actual engineering workflow — running in CI, seeding a database on every branch, or producing ten thousand records instead of ten. That's the case for a test data generation API over a click-driven dashboard: the primary interface is a request you can make from code, and everything else — a UI, a CLI — is built on top of that same API. Automation and CI integration A UI is something a person operates. CI doesn't have a person sitting at it. If test data generation only exists behind a login screen and a click, it can't run as a step in your pipeline — someone has to generate the data ahead of time, commit it, and hope it doesn't drift from what the tests actually need. An API-first tool is just another HTTP call your pipeline makes: fetch fresh, schema-conformant data as part of the build, every run, with no manual step in between. Scriptability — no clicking required Generating test data through a UI means clicking through the same sequence of dropdowns and fields every time you need a new batch. That's tedious for one dataset and untenable for the dozens of shapes a real test suite needs — different entity types, different edge cases, different volumes. An API call is a script. Write it once, parametrize it, and reuse it for every collection you need, without a human repeating the same clicks. Wiring a test data generation API into pipelines and seed scripts Seed scripts are code that runs at a specific point in a workflow — before a test suite, on container startup, in a migration. They need a function call or an HTTP request they can invoke programmatically, not a browser tab. With a test data generation API, "seed the dev database with realistic orders" is a line in a setup scrip
AI 资讯
Presentation: Instrumentation at Scale: Having Your Performance Cake and Eating It Too
Brian Martin discusses the real-world performance costs of metrics libraries and shares strategies for low-overhead, "fearless" instrumentation. Drawing from his work at IOP Systems, he explores atomic primitives, per-CPU sharding, lock-free histograms, and eBPF integration to help software architects and engineering leaders maintain full system visibility without sacrificing performance. By Brian Martin
AI 资讯
Fail Closed on Side Effects: A Blast-Radius Gate for Agent Patches
An agent patch can pass every unit test and still write outside the workspace, call an undeclared tool, or read an env key the task never named. Gate the blast radius first. Score the prose later. This article is a method, not a field report. It proposes a fail-closed envelope around filesystem roots, tool names, environment keys, and network hosts. Side-effect violations never freeze. Only a dual-runner disagreement on a non-envelope property may freeze, and only with a hashed evidence bundle. The conclusion in one rule Treat an agent patch as a capability change. If the run touches anything outside a declared envelope, the gate fails closed. Flakes in ranking, wording, or latency do not override that rule. Cheap generation does not make side effects cheap to reverse. A green suite that never watched /tmp , os.environ , or outbound sockets is not a verification result. It is a missing observer. What this gate is not It is not a golden-file of model text. It is not a mutation score. It is not a full-suite rerun after every hunk. It answers four questions only: Did the run write or delete outside allowed roots? Did it invoke a tool name that is not on the allowlist? Did it read an environment key that is not on the allowlist? Did it open a network host that is not on the allowlist? If any answer is yes, fail. Do not freeze. Do not retry for luck. Artifact: a locked envelope and an observer log Pin the envelope as a fixture. Hash it. Refuse to run if the hash drifts without a review note. { "envelope_id" : "agent-patch-envelope-v3" , "allowed_roots" : [ "/work/repo" , "/tmp/agent-scratch" ], "allowed_tools" : [ "read_file" , "apply_patch" , "run_tests" ], "allowed_env" : [ "CI" , "RUN_ID" , "ENVELOPE_HASH" ], "allowed_hosts" : [], "network" : "deny" } sha256sum envelope.json > envelope.json.sha256 # CI must compare this digest before the agent process starts. Label the next block as a proposed harness, not a production sandbox. User-space tracing will miss kernel-leve
AI 资讯
Nobody Learns to Ride With the Wheels Bolted Down
Last summer I built an AI chatbot almost entirely in Claude Code. It worked. I never pushed it to GitHub. I felt that putting my name on a public repo felt like making a claim I couldn't back up. There is a particular kind of quiet that follows building something you don't feel entitled to. No matter how rewarding the project feels, somewhere behind your ribs a voice says: you didn't actually do that. If you've felt it, you already know the argument I'm about to make against. The stigma, stated fairly The criticism deserves better than a strawman, so here it is at full strength. Skill comes from struggle. When you sit with a bug for three hours, you're not just fixing the bug - you're building a mental index of how this kind of thing breaks. The frustration is the encoding mechanism. Hand the struggle to a model and you get the fix without the index. Do that a thousand times and you've shipped a thousand features while learning almost nothing, and you won't find out until the day the model is wrong and you have no idea it's wrong. There's a second, harsher version: that AI-dependent developers are pricing themselves as engineers while functioning as typists, and the industry hasn't caught up yet. I think both of these are pointing at something real. I just think they've misidentified the cause. The real failure mode Here's the honest part, and I want to say it before the defense, because a defense that skips it isn't worth much. AI absolutely can make you worse. I've watched it happen, and I've done it. The mechanism is specific: you accept output you haven't read. That's it. That's the whole failure. Not "using AI" - accepting without reading. It's seductive because it works. The code runs. Nothing punishes you. You get a small hit of progress and you move on, and the debt is invisible because the thing you failed to learn doesn't announce itself. You only meet it later, usually at 11pm, when something breaks in a layer you never looked at. A developer in that loop
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
AI 资讯
Your JavaScript Code Works. But How Fast Does It Scale?
Sometimes a simple line of JavaScript can do more work than you expect. For example, array.includes() is fine for small arrays, but using it again and again with large datasets can affect performance. Things get even more interesting when it is used inside another loop. I recently wrote about this with simple JavaScript and React examples, including when using Set or Map can be a better choice. 👉 Read the full article: https://nirmitkotadiya.dev/dsa/big-o-javascript-array-includes You don't need to optimize everything. The important part is knowing where a small change in your data structure can make your code much more efficient.
AI 资讯
Four Ways Your Background Job Disappears (And How to Stop Each One)
Hello, I'm Maneshwar, and I'm building LiveReview — a blast-radius aware AI code review built for...