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

标签:#p

找到 12119 篇相关文章

AI 资讯

A 500-Line Flutter Login Test Became One Promt

Lets start with a bit of back story. I am a full stack developer. Developer being the keyword here, not a QA developer. But in my current role, I was recently asked to come up with a testing suite for the web application and the Flutter app I was managing and maintaining. At that time, I didn’t have anything better to do and thought this would be a fun little project to work on for a couple of weeks. Boy o boy, I was wrong. People in QA are so opinionated. Everyone has their preferred framework, structure, naming convention, abstraction, folder structure and a very strong opinion about why your approach is wrong. Starting with the industry best practices I started by trying to follow the trends and best practices used in the industry. Page Object Models, reusable helpers, proper assertions and all the usual bits and bobs. For the web application, which was built with React, I chose Playwright. For the Flutter app, I went with integration_test . Sounded simple enough. The login test that took three hours The first test I tried to write was a simple login flow. Open the application Enter the username and password Press the login button Wait for the dashboard Easy, right? It took me ages. And by ages, I mean roughly three hours just to get the web test to pass reliably. The actual Playwright test ended up being around 300 lines once I included the boilerplate, setup, selectors, assertions, waits, Page Object Model structure and everything else needed around the actual journey. Then came the Flutter app. That one was worse. The app has its own custom way of starting different flavors, and both the web application and Flutter app are white-labelled products. That means there are a lot of variations to cover. Different branding, configurations, screens and sometimes slightly different user journeys. Before I could even test the login flow, I needed a pile of setup code just to launch the correct version of the app. The Flutter test eventually went beyond 500 lines, includ

2026-08-06 原文 →
AI 资讯

A Privacy-First Browser Workflow for AI Photo Editing

AI photo editors look simple from the outside: upload an image, describe a change, and download the result. The hard part is everything around the model call. If you are building or evaluating a browser-based image editor, the workflow needs to protect the original file, reject bad inputs early, make retries safe, and help the user compare the result with the source. This article walks through a small implementation pattern that does that without turning the UI into a complex desktop editor. 1. Validate the image before upload Do not rely on the file extension. Check the MIME type, file size, and whether the browser can actually decode the image. const ACCEPTED_TYPES = new Set ([ " image/jpeg " , " image/png " , " image/webp " , ]); async function validateImage ( file ) { if ( ! ACCEPTED_TYPES . has ( file . type )) { throw new Error ( " Use a JPG, PNG, or WebP image. " ); } const maxBytes = 10 * 1024 * 1024 ; if ( file . size > maxBytes ) { throw new Error ( " The image must be smaller than 10 MB. " ); } const bitmap = await createImageBitmap ( file ); const dimensions = { width : bitmap . width , height : bitmap . height }; bitmap . close (); if ( dimensions . width < 64 || dimensions . height < 64 ) { throw new Error ( " The image is too small for a useful edit. " ); } return dimensions ; } This catches renamed files, broken images, and tiny inputs before they consume bandwidth or model credits. 2. Treat the prompt as a single edit contract Open-ended chat is useful, but it can make image editing unpredictable. A clearer UI asks for one concrete change at a time: remove the person on the right; replace the background with a plain white wall; repair the crease across the top-left corner; extend the image to a 16:9 frame. The request object should preserve that intent without mixing it with UI state: function buildEditRequest ( file , prompt , options = {}) { const normalizedPrompt = prompt . trim (). replace ( / \s +/g , " " ); if ( normalizedPrompt . length < 5 )

2026-08-06 原文 →
AI 资讯

The Check That Only Confirmed a Name

The owner had already asked for the alert emails to stop. A fix shipped. Then another email landed. Then another. "ong it just ssent me abother email," he said, voice-dictated, unedited. Fifteen minutes later: "go another one." The system was reporting an outage that did not exist. The Transport That Only Ever Failed A 14-PR merge train had just moved every cron producer's alerting off shared email and onto Buzz, a Nostr-relay team chat. One producer per PR, each with its own liveness contract and a bead receipt. It shipped cleanly. But the library backing those producers carried a default that had only one job: fail. AF_BUZZ_CMD = " ${ AF_BUZZ_CMD :- af_default_buzz_post } " af_default_buzz_post returned 1 with "no Buzz transport injected". Every caller that sourced the library (which is every cron producer) exhausted its Buzz retries and fell through to the email floor. The system reported a false Buzz outage while the relay was healthy. It did this 2 to 5 times per hour. Evidence arrived in the logs: 581 dedup markers, a steady stream of "[INTENT ALERT FLOOR: Buzz unreachable]" emails, and sweep.log showing buzz=ok only for the handful of callers invoked through the CLI entrypoint rather than by sourcing the library. That asymmetry was the bug. The CLI had a one-line fixup swapping in the real transport, annotated in a comment as "the library path is unchanged". The library path did not, and the cron producers all take the library path. The fix promoted the real transport to the default for both seams. af_buzz_transport already discovers the installed buzz-notify.sh and already fails closed when it is genuinely missing. The dead CLI fixup was deleted. Fail-closed behavior survives, but now it is conditional on genuine absence rather than on every caller remembering to opt in. Why not migrate callers one at a time? Because the per-caller route leaves the next new producer to rediscover this the same way. Flipping the default fixes the class, not the instance. The

2026-08-06 原文 →
AI 资讯

TypeScript Strict Null Checks in 2026: Real-World Patterns for Handling `undefined` Without the Noise

TypeScript Strict Null Checks in 2026: Real-World Patterns for Handling undefined Without the Noise This article was written with the assistance of AI, under human supervision and review. Most TypeScript null safety problems stem from teams treating strictNullChecks as a boolean toggle instead of a design constraint. The compiler flag eliminates an entire class of production bugs, but codebases that flip it on without adjusting their patterns end up drowning in type assertions and optional chaining operators. The result is worse than the original false confidence wrapped in noise. The fundamental issue is that JavaScript conflates absence and failure. A missing property, an API error, and an uninitialized variable all return undefined or null , but they represent completely different failure modes. When teams enable strictNullChecks without encoding these distinctions into their types, the compiler forces them to handle every potential undefined the same way. That leads to defensive checks that obscure intent and catch nothing of value. The correct approach treats null safety as a type design problem. Discriminated unions encode why a value is missing. Branded types prove non-nullability at the boundary. Type guards narrow only when the business logic demands it. The patterns are simple, but they require understanding what the compiler is actually checking and what guarantees your code actually needs. This post covers the essential patterns teams need to write null-safe TypeScript in 2026 without the noise. Apply these in production and the difference will be immediate. Key Takeaways strictNullChecks eliminates runtime null errors only if your types encode why values are missing, not just that they might be missing. Discriminated unions outperform null returns for API responses because they force exhaustive handling of failure cases at compile time. Non-null assertions ( ! ) are acceptable at proven boundaries where external systems guarantee non-null values, but ne

2026-08-06 原文 →
开发者

Building for the Next Wave: My Journey Crafting Next.js Templates for the Nigerian Market

Bridging Design and Code to Empower Local Businesses As a full-stack developer specializing in JavaScript and React, one of the most exciting ventures I'm currently on is building ready-made websites and Next.js templates through Softchic. This isn't just about coding; it's about deeply understanding the needs of businesses, particularly within the vibrant and rapidly evolving Nigerian market, and translating those into high-performance, beautiful web solutions. Why Next.js? Performance, SEO, and Developer Experience My choice of Next.js as the primary framework for these templates was deliberate: Performance: Server-side rendering (SSR) and static site generation (SSG) capabilities are crucial. In areas where internet speeds might vary, a fast-loading website isn't just a nice-to-have; it's essential for user retention and conversion. SEO: For businesses looking to establish a strong online presence, robust SEO capabilities out-of-the-box mean our templates provide a solid foundation for discoverability. Developer Experience: Building with Next.js allows for efficient development, leveraging the power of React while simplifying routing, data fetching, and API routes. This means faster iteration and higher quality templates. The Nigerian Market: Unique Challenges, Immense Opportunity Crafting templates specifically for the Nigerian market presents a fascinating set of considerations: Design Aesthetics: Understanding local preferences in terms of color palettes, layouts, and user flows is critical. It's not just about what looks good globally, but what resonates locally. This is where my dual role as creative director for promotional materials comes into play – applying that eye for design directly to the templates. Mobile-First Mentality: A significant portion of internet users in Nigeria access the web via mobile devices. Every template is meticulously designed with a mobile-first approach to ensure optimal responsiveness and user experience on smaller screens. Aff

2026-08-06 原文 →
AI 资讯

I tried using an AI agent to set up a fresh Windows PC and Reddit was right about Ninite

I tried the obvious nerd experiment on a fresh Windows machine: let an AI agent handle setup. It looked clever for about two minutes. Then I watched OpenClaw get stuck on installer checkboxes, pause on modal windows, and generally do the digital equivalent of forgetting why it walked into the room. While it was still fighting one installer, I switched tactics: Ninite for the common app bundle WinGet for package installs I wanted to keep and rerun PowerShell for the boring system-level stuff GPT-5 or Claude for planning, not clicking That combo finished 18 app installs before the agent recovered. And after reading through this r/openclaw thread , I think the real lesson is bigger than Windows setup: GUI-driving agents are the wrong abstraction for deterministic work. If the task is "figure out what this machine needs," use a model. If the task is "install these 18 things and stop being interesting," use scripts. The mistake: asking an agent to be a mouse I’m not anti-agent. I’m anti-fragile-automation. OpenClaw, GPT-5, and Claude are useful when the problem is ambiguous: "Set this machine up for Python, Docker, VS Code, Node, and a local Ollama stack" "Compare package managers and suggest the cleanest install path" "Draft a setup script and explain what might fail" They are much less useful when the problem is fully deterministic: Click Next Decline the bundled toolbar Choose default install path Wait Repeat 17 times That second category is where WinGet, Ninite, and PowerShell win by being boring. Boring is good. This is the same pattern you see in real automations in n8n, Make, Zapier, or custom agent workflows: let GPT-5 or Claude interpret messy input let deterministic steps execute the plan keep the model out of the loop unless judgment is required That architecture is faster, easier to debug, and usually cheaper. What actually worked on a fresh Windows setup Here’s the split I’d use again. Job Best tool Install common desktop apps fast Ninite Create a repeatable

2026-08-06 原文 →
开发者

The Automation Imperative: Building Efficient Workflows as a Full-Stack Developer & Entrepreneur

Why I'm Prioritizing Automation in My Stack and Business Strategy As a full-stack developer working with JavaScript, Python, and Supabase, and simultaneously building out Delight Softwares Inc. and Softchic, efficiency isn't a luxury – it's a core requirement. My journey involves balancing academic pursuits with real-world tech solutions, especially for the Nigerian market. This dual role has highlighted a critical need: intelligent automation . I'm currently in the strategic planning phase of deeply integrating automation across my development and business operations. This isn't just about saving time; it's about building scalable, resilient systems that allow me to focus on innovation rather than repetition. The Vision: Where Automation Fits In Development Workflow Optimization: CI/CD Pipelines: As I delve deeper into backend development and complex Next.js applications, automating testing, building, and deployment processes becomes non-negotiable. Imagine pushing code and having tests run, builds deployed to staging, and even production updates handled with minimal manual intervention. This frees up precious time for architecting robust database logic and crafting intricate APIs. Local Environment Setup: Scripting initial project setups, dependency installations, and database seeding can save hours per project. Tools like npm scripts or simple Python automation can standardize this. Code Quality & Linting: Automated pre-commit hooks or CI checks using tools like ESLint for JavaScript/TypeScript and Black/Flake8 for Python ensure consistent code quality without constant manual review. Business Operations & Growth: Market Intelligence Automation: For Softchic, understanding market trends for website templates is crucial. Automating data collection from various sources using Python scripts can provide invaluable insights for product development and pricing strategies. Content & Marketing Streamlining: While creativity is human-driven, the distribution of promotional

2026-08-06 原文 →
AI 资讯

I Built a Chinese Neighborhood Auntie to Review TypeScript Code typescript ai productivity tooling

I was writing TypeScript one day. any everywhere, functions nested five levels deep. AI code review tools exist, but their output is cold. "Critical: Type 'any' is not recommended." Zero personality. So I thought, what if code review was done by a Chinese neighborhood auntie? She doesn't know programming, but she's been mediating disputes for 20 years, and explains code problems using life wisdom that's accidentally accurate. ts-auntie-review was born. An Agent Skill that reviews TypeScript code across six dimensions. Real technical analysis, hilarious delivery. Repo What it looks like Paste TS code, say "review my code", auntie goes to work. Write function getUserData(id: string): any , auntie says: "This any makes auntie shake her head. any is like saying 'eat whatever, drink whatever' — when something goes wrong, nobody can explain." Change API_URL from https to http , auntie says: "You replaced your front door with cardboard. HTTPS encrypts, HTTP sends your login credentials naked on the street." Nest functions five levels deep, auntie says: "You're making Matryoshka dolls. Your mom would lecture you to death." Six audit dimensions Type safety: any abuse, as without validation, missing return types, ! assertions. Naming: camelCase/snake_case mixing, Boolean prefixes, constant style, I prefix. Complexity: nesting depth, function length, cyclomatic complexity. Boundary: unhandled null/undefined, silently swallowed exceptions, uncaught Promises. Dead code: unused functions, unused imports, unreachable code, commented blocks, unused variables. TS conventions: type vs interface consistency, enum pitfalls, readonly, generic constraints, satisfies operator, import type. Scoring 100-point "Community Harmony Score". Fatal costs 30, warning 15, suggestion 5. Four tiers. 90+ is Model Resident, "bring auntie a tangerine". 70-89 is Needs Improvement. 50-69 is Deadline for Cleanup. Below 50 is Eviction Notice, "this code is a condemned building, rebuild." Honesty Auntie label

2026-08-06 原文 →
开发者

El redondeo que hace que tu bot arriesgue 10 veces lo que crees

Casi todo bot de trading tiene una línea que decide cuánto comprar . Suele parecer trivial: si arriesgo el 1% de mi saldo y mi stop está a 1000 dólares de distancia, la cantidad sale de una división. El cálculo es de primaria. Lo que no es de primaria es hacer que ese número quepa en las restricciones del exchange . Ahí es donde se pierde dinero, y de formas que no aparecen en los logs. El patrón que multiplica tu riesgo Esto está en incontables bots, y estuvo en uno mío: cantidad = max ( 1 , int ( cantidad_teorica / contract_size )) La intención es defensiva: "que nunca salga cero". El efecto es el contrario. Si la cantidad teórica sale 0.1 contratos, int() la trunca a 0 , y entonces max(1, ...) la fuerza a uno . Acabas de abrir una posición diez veces más grande que la que autorizaste. Con números concretos: saldo de 500 USD, riesgo del 1% (5 USD), entrada en 50 000, stop en 45 000, contratos de 0.01. El riesgo real de ese contrato único es de 50 USD — diez veces el presupuesto. Y ocurre en silencio: la orden se acepta, el bot sigue, no hay excepción que capturar. Lo peor es que no es un caso raro. Pasa siempre que el saldo es pequeño o el stop es ancho, es decir, exactamente cuando menos margen tienes para equivocarte. Los otros dos que cuestan dinero Ignorar el nocional mínimo. El exchange rechaza la orden por valor mínimo, el bot lo registra como error de red, y nadie se entera de que esa señal nunca se operó. El backtest la contó; la cuenta no. No reservar para comisiones. Con un stop ajustado, las comisiones de ida y vuelta pueden ser la mitad del riesgo real . Si dimensionas contra la distancia al stop y nada más, arriesgas sistemáticamente más de lo que crees. Cómo lo resolví Saqué el cálculo del bot y lo publiqué como librería: position-sizing (Apache-2.0, sin dependencias). from decimal import Decimal from position_sizing import MarketSpec , size_for_risk spec = MarketSpec ( amount_step = Decimal ( " 0.001 " ), min_amount = Decimal ( " 0.001 " ), min_noti

2026-08-06 原文 →
AI 资讯

Reasonix - Deepseek: A Terminal Coding Agent Built Around the Thing Everyone Else Ignores

Most terminal coding agents are architecturally similar: a loop, a tool registry, some context management, a TUI. Reasonix picks a different thing to optimize for, and it is a thing that shows up on your bill rather than in a demo video. The tagline is "engineered around prefix-cache stability — leave it running." That phrase is doing a lot of work, so let's unpack it. Why prefix caching is the whole pitch DeepSeek's API, like several others, caches the prefix of your prompt. If the next request starts with the exact same token sequence as the previous one, the provider serves those tokens from cache and bills them at a small fraction of the normal input rate. Cache hits are dramatically cheaper than cache misses. Here is the catch: it is a prefix cache. The match has to start at token zero and run forward. Change one character near the top of your context and every token after it is a miss. Now think about what a typical agent harness does over a long session. It re-summarizes the conversation. It injects a fresh timestamp or a re-scanned directory tree at the top. It reorders tool definitions. It rewrites the system prompt when you switch modes. Every one of those is a mutation near the front of the context, and every one of them silently invalidates the entire cache. The result is an agent that feels fine and costs several times what it should. You do not notice, because nothing errors. You just watch the number go up. Reasonix's central design constraint is: don't do that. Keep the front of the context stable, append rather than mutate, and put churn where it costs least. What that looks like in practice A small, stable environment summary is injected at startup rather than regenerated each turn. Stale tool output gets snipped and pruned before summary compaction kicks in, so a giant cat result from twenty turns ago is not still sitting in your prefix. The built-in tool schema contract is documented and regression-reviewed, because a silent tool-definition reshu

2026-08-06 原文 →
AI 资讯

LoopX: A Control Plane for AI Agents That Have to Keep Working for Days

If you have ever pointed a coding agent at a multi-day goal, you know the failure mode. It is not that the model writes a bad function. It is that on turn 40, the agent no longer remembers what the objective was, which decision you already made, what is out of scope, or what the last run actually proved. The context window rolled over, and the plot went with it. LoopX is an attempt to fix that specific problem. It calls itself "loop engineering for long-running AI agents," and it is a local control plane that sits above your agent runtime rather than replacing it. The one-sentence version Your agent (Codex, Claude Code, Cursor, whatever) executes bounded loops. Something (a heartbeat, a cron job, you hitting enter) triggers the next loop. LoopX holds the state that has to survive between those loops. The project draws the separation like this: Layer Role Codex / Claude Code / Cursor Execute a bounded agent loop: read, write, run commands, respond Goal mode / automation / CLI / TUI Trigger or schedule the next loop LoopX Preserve goals, gates, todos, run history, quota, evidence, handoff state That third row is the whole product. LoopX is not an executor and not an autonomous production controller. It is a state kernel with a CLI. Why "just use a todo file" isn't enough A TODO.md plus a long system prompt gets you surprisingly far. It falls over once any of these become true: The goal changed halfway through, and nothing recorded why . A decision genuinely needs a human, and that request evaporated into a chat message nobody read. Two agents are touching the same repo and neither knows who owns what. The last run claimed success, and there is no artifact proving it. Some work is safe and read-only, some crosses into writes, production, or private data, and the distinction lives only in your head. LoopX makes those things explicit and machine-readable, which is what lets a loop run longer without becoming less accountable. The concepts, in plain English Lifetime goals

2026-08-06 原文 →
AI 资讯

Claude Code Authentication: Subscription, API Key, Amazon Bedrock, and Claude Platform on AWS

I'm a big fan of using Claude and Claude Code for development. Many organizations are currently using these tools to improve developer productivity and ultimately build better products. Our role and our tools have changed — we went from powerful autocomplete to autonomous agents that can refactor, review, and implement features, most of the time better than we can on our own. Authentication methods There are several authentication methods, each with different billing, cost tracking, and governance options. Depending on your organization, you will choose the one that fits best. Personal development — Anthropic API key I use this for experimenting with the Anthropic library for learning and prototyping. You set ANTHROPIC_API_KEY in your environment (or a .env file), and the SDK picks it up automatically. Pay-as-you-go per token, no infrastructure needed. from dotenv import load_dotenv load_dotenv () import json import anthropic client = anthropic . Anthropic () tools = [ { " name " : " get_weather " , " description " : ( " Returns current weather for a city. Use ONLY for weather queries. " " Input: city name (string). Output: temperature in Celsius and conditions. " ), " input_schema " : { " type " : " object " , " properties " : { " city " : { " type " : " string " }}, " required " : [ " city " ], }, }, { " name " : " get_time " , " description " : ( " Returns the current local time for a city. Use ONLY for time/timezone queries. " " Input: city name (string). Output: local time string. " ), " input_schema " : { " type " : " object " , " properties " : { " city " : { " type " : " string " }}, " required " : [ " city " ], }, }, ] def get_weather ( city : str ) -> dict : return { " city " : city , " temp_c " : 22 , " conditions " : " sunny " } def get_time ( city : str ) -> dict : return { " city " : city , " local_time " : " 14:35 " } TOOL_FUNCTIONS = { " get_weather " : get_weather , " get_time " : get_time , } def run_agent ( user_message : str ) -> str : messages =

2026-08-06 原文 →