AI 资讯
How I Built an Adversarial AI Council in React (and Why It Argues With You)
A local-first, single-file SPA where multiple agents debate your decision and hand you a verdict. The problem: every AI I asked just agreed with me I almost named this project wrong. I'd picked a name that sounded powerful. I asked ChatGPT, and it loved it. I asked Claude, and it nodded along. Nobody warned me about the trademark conflict, the wrong search intent, or the SEO fight I'd pick with the BBC. That was the moment I realized the problem wasn't the name. It was the feedback loop. Most AI assistants are tuned to please, so they hide your blind spots instead of showing them. When you need to make a consequential decision, "sounds great" is the most expensive answer you can get. So I built the opposite: a council of AI agents that disagree on purpose. What NoFlattery does NoFlattery puts 2–4 agents in a room, gives them different reasoning biases, and makes them debate your decision. The output isn't another chat transcript. It's a Decision Record: a clear verdict, the reasoning behind it, the main risk, what would change the call, and a next step. Use it for product decisions, pricing, tech stack, hiring, or any call where one perspective isn't enough. Key product choices: Local-first: your chats and API keys stay in your browser. BYOK: bring your own OpenAI, Anthropic, OpenRouter, or Ollama key. One-time price: no subscription, no account, no data harvesting. The stack The whole app is a single-file SPA built with: React 19 + TypeScript Zustand for state Dexie over IndexedDB for local-first storage Vite + vite-plugin-singlefile for a single index.html deploy An OpenAI-compatible provider runtime so users can plug in their own keys Why single-file? Because the deploy becomes dead simple. One HTML file. No server for the data. No build orchestration. I can ship the app to Cloudflare Pages and forget about it. The turn engine: deterministic, not magical The heart of NoFlattery is a turn-based multi-agent engine. One user message triggers one round. Each agent sp
AI 资讯
Structuring TypeScript: Interfaces, Type Aliases, Enums, and Object Types
Structuring TypeScript: Interfaces, Type Aliases, Enums, and Object Types You've learned TypeScript's primitive types and the basics of type inference here . Now it's time to model real-world data — users, orders, API responses, configuration objects. That's where interfaces, type aliases, and enums come in. These three features are what make TypeScript genuinely powerful for building applications. Let's dig in. Object Types: Describing the Shape of Data Before we get to interfaces, let's understand object types. When you want to describe the structure of an object, you define what properties it has and what types those properties are: // Inline object type annotation function displayUser ( user : { name : string ; age : number ; email : string }): void { console . log ( ` ${ user . name } ( ${ user . age } ) — ${ user . email } ` ); } This works, but it's messy to repeat everywhere. That's why we use type aliases and interfaces to name and reuse these shapes. Type Aliases: Naming a Type A type alias gives a name to any type — primitives, unions, objects, or combinations: // Alias for a primitive union type ID = string | number ; // Alias for an object shape type User = { id : ID ; name : string ; age : number ; email : string ; }; // Now use it anywhere const user : User = { id : 1 , name : " Ramesh " , age : 31 , email : " ramesh@example.com " , }; function getUser ( id : ID ): User { // ... fetch user logic } Type aliases are flexible — they can represent almost anything. Interfaces: Defining Object Contracts An interface is specifically designed to describe the shape of an object. Syntax is slightly different: interface User { id : number ; name : string ; age : number ; email : string ; } const user : User = { id : 1 , name : " Ramesh " , age : 31 , email : " ramesh@example.com " , }; Optional and Readonly Properties Properties can be marked as optional ( ? ) or read-only ( readonly ): interface UserProfile { readonly id : number ; // Can't be changed after cre
AI 资讯
What is HiveTalk?
HiveTalk.space is a privacy focused chat app. HiveTalk.space should not be confused with hivetalk.org. While both platforms focus on communication, they are separate projects with different goals and feature sets. HiveTalk is closed source and cloud hosted, making it easy to start chatting without setting up your own server. Despite not being self-hosted, privacy remains a core focus. Private conversations are designed with privacy in mind, allowing users to communicate without unnecessary tracking or intrusive data collection. Every account includes generous free limits. Users can upload files and videos up to 1 GB each, send unlimited messages , and sign in using supported social login providers or a traditional account. Creating communities is simple, with the ability to make your own chat rooms for friends, gaming groups, project teams, schools, or fanbases in just a few clicks. HiveTalk also aims to provide a modern messaging experience with features such as polls, rich text formatting, media sharing, and room management tools, while keeping the interface simple and easy to use. Whether you want a private conversation, a small group chat, or a larger community, HiveTalk is designed to scale without placing artificial limits on everyday usage. Unlike many messaging platforms that reserve key features for paid subscriptions, HiveTalk offers its core functionality for free. The goal is to make private, feature-rich communication accessible without requiring users to pay just to unlock basic messaging features. As the platform continues to develop, new features and improvements are regularly added, with a focus on privacy, usability, and giving communities more control over how they communicate.
AI 资讯
Cosmic as Agent Memory: Structured, Versioned, and Queryable
AI agents get better the more they run. Every conversation turn, every task completed, every prompt refined adds to a growing body of context that shapes the next output. The compounding effect is real: an agent with 100 turns of memory and a versioned prompt history behaves meaningfully differently from one starting cold. This post walks through using a structured, versioned, API-accessible store as the memory layer for AI agents, with TypeScript examples. Agent messages, system prompts, findings, and instructions are all stored as structured, versioned, API-accessible Objects. Each new turn adds to the record. Each prompt edit is tracked. What Agent Memory Actually Needs The compounding loop only works if the memory layer has the right properties. Most agent frameworks handle working memory well. The gap is episodic and semantic memory: what the agent learned, did, and produced across sessions. Researchers at Elastic recently published a breakdown of agent memory tiers : working memory (in-context), episodic memory (past interactions), semantic memory (knowledge), and procedural memory (learned behaviors). Good persistent agent memory needs four properties: Structured : queryable by type, status, date, or custom field, not just full-text search Versioned : you need to know what the agent wrote at each point in time, not just the latest state API-accessible : any model, any framework, any language should be able to read and write it Human-reviewable : agents make mistakes; a human needs to inspect and correct outputs without touching a database Objects as Agent Outputs When an agent produces output, storing it as a structured Object gives you a queryable record with typed fields, a draft/published workflow so a human can review before promoting to production, a full audit trail of every change, REST API access from any runtime, and a dashboard UI where non-technical team members can inspect, edit, or approve agent outputs. Here's a simple research agent that stores
AI 资讯
The stock-analysis API you don't have to build
I was building a feature that needed to say something useful about a stock — not just print its P/E, but actually read the situation: is this cheap or expensive, what's the bull case, is the insider buying real or routine. I went looking for an API. Every finance API I found sold me raw data . Alpha Vantage, Twelve Data, Yahoo Finance, FMP — they'll hand you fundamentals, prices, filings, all of it. Great. Now I get to write the part that turns 40 metrics into "this looks expensive but the moat is widening." That's the part that's actually hard, and the part I didn't want to own forever. So I'd be wiring three data providers, normalizing their conflicting field names, writing and tuning the LLM prompts, handling the rate limits and the caching, and then maintaining all of it as the upstreams change. For a feature, not a product. What I wanted instead A single endpoint. Ticker in, analysis out — already synthesized, already structured. That's what I ended up building for myself and then put on RapidAPI: Agent Toolbelt — AI Stock Research API . It pulls live fundamentals from Polygon, Finnhub, and Financial Modeling Prep, then returns a Motley-Fool-style read as typed JSON. The numbers are in there too, but the point is the verdict and the reasoning. Here's a real stock-thesis response: { "verdict" : "bullish" , "oneLiner" : "Nvidia owns the essential infrastructure for the AI revolution with a defensible software moat." , "keyStrengths" : [ "~80%+ data center GPU market share" , "CUDA moat creates switching costs" , "42 buy / 5 hold / 1 sell analyst consensus" ], "keyRisks" : [ "36.9x P/E leaves no margin for error" , "Competition from AMD and custom silicon" ], "insiderRead" : "Two executives bought ~47k shares each — meaningful open-market purchases, not routine grants." , "dataSnapshot" : { "currentPrice" : 180.4 , "peRatio" : 36.9 , "marketCapBillions" : 4452.2 } } That's one HTTP call. No data-provider accounts, no prompt engineering, no normalization layer. The
AI 资讯
7 Alternatives to Building SaaS Backlogs That Never Get Finished
Most SaaS ideas don’t fail because of bad ideas. They fail because the execution gets stuck in an endless setup loop. You start with energy, then slowly get buried in: auth systems, billing, dashboards, SEO, analytics, and infrastructure decisions. By the time the “real product” should begin, momentum is already gone. Here are 7 practical alternatives to building SaaS in a way that never gets finished. 1. Nexora (start with a working SaaS foundation) Instead of rebuilding everything, Nexora gives you a production-ready base so you can focus on actual features. Includes: Authentication system Stripe billing User dashboards SEO pages Blog + docs structure Clean Next.js architecture 🔗 https://nexora.collabtower.com/ 👉 Best for founders who want to ship instead of setup. 2. Build-from-scratch Next.js projects The most common approach. You get: Full control Flexible architecture But you also get: Weeks of setup Repeated boilerplate work High chance of burnout before launch 3. SaaS boilerplates (minimal versions) Lightweight starter kits with: Auth Basic UI Simple Stripe setup But usually missing: Real dashboards SEO systems Production-level structure 4. Supabase-first builds Backend-focused setups. You get: Database Auth APIs But still need to build: Billing UI system Marketing pages SaaS structure 5. Low-code SaaS tools Fast visual builders. Pros: Quick UI creation No heavy coding Cons: Limited flexibility Hard to scale complex SaaS logic Platform dependency 6. AI-generated starter apps AI tools can scaffold SaaS apps instantly. Pros: Fast starting point Cons: Inconsistent structure Requires cleanup Not production-ready out of the box 7. Tutorial-based SaaS builds Many developers still learn SaaS by following tutorials step-by-step. Pros: Educational Cons: Slow Fragmented Hard to turn into real production apps Final takeaway Most SaaS workflows fail before launch because they repeat the same mistake: They start from zero every single time. That creates unnecessary setup
AI 资讯
Perl PAGI Project Updates
Quick update to anyone interested in upcoming changes to the PAGI project (spiritual successor to Plack/PSGI). 1) Distribution split up: when we released PAGI, we initially released everything as one distribution. PAGI ( https://metacpan.org/pod/PAGI ) currently has a) the PAGI specification; b) the reference server and c) a bunch of ease of use tools, similar to the role that the Plack distribution played for PSGI. Putting everything into one place was just to make my life easier as in the early bunch of releases there was a lot of fixes and updates, most of which cut across all three parts of PAGI. Also I wanted to make it easy for people getting into PAGI to be able to explore the ecosystem. However now that code seems to be settling down having these in independent repos and releases makes more sense. Going forward the PAGI repo will only update if the spec itself changes; PAGI::Server and PAGI::Tools (where all the utilities and helpers now go) likewise. I think this will start to bring some stability to the ecosystem, especially now that PAGI::Server is functionally complete based on the goal chart I had for it initially. So I will only update it to fix bugs and security issues. PAGI::Tools will probably continue to see evolution over the summer as I start to nail down more common use cases and identify patterns worth encapsulating. 2) Specification clarifications and updates: The PAGI specification itself will move to v0.3 in the next release and it contains mostly clarifications and fixes. Biggest change will be a more detailed mechanism for controlling streaming output, especially around handling back pressure as well as new callbacks to notice when the output buffer is getting full and when it clears. Hopefully these changes will make it easier and more reliable to do streaming in PAGI. PAGI::Server has been updated to match, and the response helper in PAGI::Tools has some updates around that as well. Currently all this sits on Github: https://github.com/j
AI 资讯
Building a browser diagram editor: which import/export formats actually matter?
Disclosure up front: I'm affiliated with diagram.now — I'm connected to the product. I'm posting this to get developer feedback on diagram import/export interoperability, not to pitch an install. Most teams I've worked with don't have one source of truth for their diagrams. They have: a few Mermaid blocks living in READMEs and Markdown docs, an old Visio ( .vsdx ) or Lucidchart file someone made two reorgs ago, a SQL schema that is secretly the "real" ERD, and a pile of screenshots pasted into docs and tickets. The diagram is rarely the hard part. The hard part is that the same diagram lives in five formats and none of them stay in sync with the docs they're supposed to explain. I've been working on diagram.now , a browser-based editor for technical diagrams — flowcharts, UML, ERD, BPMN, cloud/network architecture, mind maps, wireframes. It's a free browser editor with no signup to start. There's an optional Confluence app for teams that want diagrams editable inside Confluence pages, but that's intentionally not what I want to talk about here. I want feedback on the editor itself, and specifically on the interoperability story. What it does today Import/insert from Mermaid and SQL — paste a Mermaid graph or a CREATE TABLE block to start an editable diagram instead of a static render. Import Lucidchart and Visio .vsdx files — this is migration-oriented, and honestly the part I most want real-world files to stress-test. Export to PNG, SVG, PDF, or a URL. Templates/shapes for the diagram categories above. I'm deliberately keeping the Confluence side secondary. The thing I actually want to learn is whether the browser editor plus import/export is useful on its own. Where I'd love feedback Imports: Which format matters most to you — Mermaid, SQL→ERD, .vsdx , Lucidchart, or something else (PlantUML, draw.io XML, Graphviz)? If you've ever tried to migrate diagrams between tools, where did it break? URL export: Is a shareable diagram URL genuinely useful in your workflow (
AI 资讯
Collection of Claude Skills for Indie Developers - Here's What I Learned
A few months ago I started building small tools as single HTML files - no npm, no React, no backend. Just one file that opens in a browser and works offline. I built 4 real products this way: DarkenAmber IT Tools - 17+ developer tools in 194KB ZeroOffice - PDF, image, AI tools in one file PrivacyKit - Photo privacy tools, no upload required ElectroKit - Electrical calculator + cost estimates for CIS market Every single one: one .html file. Works offline. Opens instantly. No server. The problem with AI coding assistants Every time I asked Claude or Copilot to build something simple, I got: A React project with src/ folder package.json with 12 dependencies webpack config TypeScript setup ...before writing a single line of actual logic. I kept manually correcting it. "No, one file. No npm. Vanilla JS." Then I realized - I should just teach it once and reuse that knowledge. What is a Claude Skill? A skill is a Markdown file with YAML frontmatter that changes how Claude thinks for a specific context. It is not a prompt. It is not a system message. It is a reusable set of rules that shapes how Claude reasons, what it prioritizes, and what it avoids. yaml--- name: single-file-app description: "Build complete web tools as a single HTML file - vanilla JS, inline CSS, localStorage, offline-first." tags: html vanilla-js offline version: 1.2 --- The two skills I built single-file-app Teaches Claude to build complete web tools in one HTML file. What changes: No React, no npm, no build tools unless truly justified Vanilla JS first, always localStorage for data persistence Dark/light theme with system preference detection Accessibility built in (labels, aria, keyboard nav) XSS prevention for user input Export/import for user data Anti-patterns it prevents: ❌ "Let me set up a React project" ❌ Creating src/ folder for a simple tool ❌ Suggesting npm install for a calculator ✅ "Here is your complete HTML file" ship-it Teaches Claude to bias toward shipping over planning for early-stag
AI 资讯
I’m excited to announce that I’ve officially taken my latest project, 𝗟𝘂𝗺𝗼𝗿𝗮, 𝗽𝘂𝗯𝗹𝗶𝗰 𝗼𝗻 𝗚𝗶𝘁𝗛𝘂𝗯! 🚀🫵
𝗦𝗮𝘆 𝗵𝗲𝗹𝗹𝗼 𝘁𝗼 𝗟𝘂𝗺𝗼𝗿𝗮 — 𝗧𝗵𝗲 𝗨𝗹𝘁𝗶𝗺𝗮𝘁𝗲 𝗕𝗼𝗼𝘁𝘀𝘁𝗿𝗮𝗽 𝟱 𝗔𝗱𝗺𝗶𝗻 𝗗𝗮𝘀𝗵𝗯𝗼𝗮𝗿𝗱 𝗨𝗜 𝗞𝗶𝘁. 💎 🔗 𝗚𝗶𝘁𝗛𝘂𝗯 𝗥𝗲𝗽𝗼: https://github.com/Chetankumar-Akarte/lumora 🔗 Demo: https://renukatechnologies.in/demo/lumora/ Don't forgot to 🤩 Star and 👉 Fork the Repo 𝗟𝘂𝗺𝗼𝗿𝗮 is a modern, responsive 𝗕𝗼𝗼𝘁𝘀𝘁𝗿𝗮𝗽 𝟱 𝗔𝗱𝗺𝗶𝗻 𝗗𝗮𝘀𝗵𝗯𝗼𝗮𝗿𝗱 𝗨𝗜 𝗞𝗶𝘁 designed for teams that need a polished, enterprise-ready control center without the bloat. Whether you are building for SaaS, CRM, E-commerce, or internal analytics, Lumora provides a scalable, token-driven foundation to speed up your workflow. 𝗟𝘂𝗺𝗼𝗿𝗮 is the result: a complete admin ecosystem featuring everything from KPI blocks and ApexCharts to full E-commerce management flows and authentication screens. 𝗪𝗵𝗮𝘁’𝘀 𝗶𝗻𝘀𝗶𝗱𝗲? • Full UI Kit with basic and advanced components. • Enterprise pages (Users, Roles, Permissions, Invoices). • Interactive apps like Calendar and Contacts. • Clean, token-driven styling for consistent design. 𝗧𝗲𝗰𝗵 𝗵𝗶𝗴𝗵𝗹𝗶𝗴𝗵𝘁𝘀: • Bootstrap 5.3 • ApexCharts & Chart.js • Vanilla JavaScript • Mobile-first design 𝗞𝗲𝘆 𝗛𝗶𝗴𝗵𝗹𝗶𝗴𝗵𝘁𝘀: • 𝗠𝗼𝗱𝗲𝗿𝗻 𝗧𝗲𝗰𝗵 𝗦𝘁𝗮𝗰𝗸: Built with Bootstrap 5.3, Vanilla JS, and CSS3 using a module-first architecture. • 𝗖𝗼𝗺𝗽𝗿𝗲𝗵𝗲𝗻𝘀𝗶𝘃𝗲 𝗗𝗮𝘀𝗵𝗯𝗼𝗮𝗿𝗱𝘀: Includes layouts for Analytics, CRM, Project Management, HRM, and more. • 𝗙𝗲𝗮𝘁𝘂𝗿𝗲-𝗣𝗮𝗰𝗸𝗲𝗱 𝗔𝗽𝗽𝘀: Ready-to-use interfaces for Advanced Chat, Kanban boards, Email, and File Management. • 𝗗𝗮𝗿𝗸 & 𝗟𝗶𝗴𝗵𝘁 𝗠𝗼𝗱𝗲𝘀: Clean, professional visuals with seamless theme switching. • 𝗗𝗲𝘃𝗲𝗹𝗼𝗽𝗲𝗿 𝗙𝗿𝗶𝗲𝗻𝗱𝗹𝘆: Modular CSS, reusable partials, and organized project structure. I built this to bridge the gap between "pretty" templates and "functional" enterprise tools. Check it out, star the repo, and let me know what you think! I'd love for you to take a look at the code and perhaps even use it for your next project. Feedback and contributions are always welcome! WebDevelopment, Bootstrap5, AdminDashboard, OpenSource, UIUX, JavaScript, GitHub, Bootstrap, CodingCommunity, OpenSourceProject, FrontendDev, LumoraUI
AI 资讯
I built a Chrome extension that shows which tab is eating your RAM (and frees it in one click)
The problem I kept running into I'm a chronic tab hoarder. At any given time I've got 40–80 tabs open across two windows. Chrome's built-in Memory Saver is aggressive in the wrong ways — it hibernates tabs I'm actively referencing. And the built-in task manager is a two-step detour that still doesn't tell me which tabs I should actually close. So I built Tab Memory Manager. What it does Per-tab memory estimates — A live MB count next to every open tab. Sorted by memory usage by default. There's a live total on the toolbar icon so you always know what Chrome is consuming right now. Smart suggestions — The extension flags your biggest, stalest tabs: ones that are idle the longest and consuming the most. It never suggests your active tab, pinned tabs, tabs playing audio, or domains you've whitelisted. Hibernate, don't close — This was the core design decision. Hibernating frees the memory but keeps the tab alive in your strip — it reloads when you click it. Much safer than closing, especially mid-research. Bulk cleanup — Select multiple tabs or hit Apply on the suggestions panel. See the total memory you'll reclaim before you commit. Undo list — Closed something by mistake? There's a "Recently cleaned" panel. One click to restore. Tab grouping — Groups all your open tabs by domain into color-coded Chrome tab groups, instantly. The interesting technical bit: memory estimates Chrome's stable extension API doesn't expose exact per-tab memory. The chrome.processes API that does exists only on Dev and Canary builds — not the Chrome that 99% of people use. So Tab Memory Manager uses calibrated estimates based on tab state, domain patterns, and known Chrome process overhead. These are clearly labeled "est." in the UI. If you're on Dev or Canary, you can switch on real per-tab memory in settings. The warning Chrome shows about "processes requires dev channel" is a Chrome-generated note about that optional API — the extension works completely normally without it. It's not a bug
AI 资讯
Building GitHub-Inspired Version Control and Forking Without Duplicating Project Files
One of the challenges I faced while building my LaTeX Writer project was implementing version control and project forking in a storage-efficient way. A typical LaTeX project contains multiple files. Even a simple project usually has a "main.tex" file, bibliography files, images, style files, and other supporting documents. If I stored a complete copy of every file for every version or fork, storage requirements would grow rapidly. Imagine a project with four files and ten versions. Storing the entire project for every version would mean storing the same files repeatedly, even when only one line changed. Forking would create an even bigger problem because every fork would require another complete copy of the project. Instead of accepting this inefficiency, I started researching how large platforms solve the same problem. GitHub was the obvious inspiration. Learning from GitHub GitHub does not store a complete copy of a repository every time a change is made. Instead, it stores content separately and uses references to connect files, commits, and repositories. This idea became the foundation for my own implementation. Project Structure Whenever a new project is created, a default file called "main.tex" is generated automatically. The project itself does not directly contain file contents. Instead, it stores metadata such as: Project ID Owner ID Root Folder ID File References Each file also has its own metadata record containing: File ID File Name Blob ID Project ID Owner ID Folder ID The actual content is not stored inside the file metadata. Instead, the content lives inside a separate entity called a Blob. Loading a Project When the editor loads a project, it reconstructs the directory structure using metadata. The process works like this: Retrieve the project's Root Folder ID. Find all folders belonging to that folder hierarchy. Find all files belonging to each folder. Build the directory tree for the frontend. Because files and folders are stored independently, the
AI 资讯
From Pixels to Proteins: Building a Precise Dietary Analysis System with GPT-4o and SAM
Have you ever tried to track your calories by manually searching for "half-eaten avocado toast" in a database? It’s a nightmare. While basic AI Computer Vision can identify an "apple," traditional models often fail at the granular level—distinguishing between 100g and 250g of pasta or identifying hidden toppings in a complex salad. In this tutorial, we are building a high-precision food nutrition AI engine. By combining the Segment Anything Model (SAM) for pixel-perfect object isolation and GPT-4o Vision for multi-modal reasoning and volume estimation, we can transform a simple smartphone photo into a detailed nutritional report. If you’re looking to dive deeper into production-grade AI patterns, I highly recommend checking out the advanced engineering guides at WellAlly Blog , which served as a major inspiration for this architecture. 🏗️ The Architecture: A Hybrid Vision Pipeline To achieve high accuracy, we don't just throw an image at an LLM. We use a "Segment-then-Analyze" pipeline. This ensures the LLM focuses on specific regions of interest (ROIs) rather than getting distracted by the background. graph TD A[User Uploads Food Image] --> B[Pre-processing with OpenCV] B --> C[SAM: Segment Anything Model] C --> D{Multi-Object Masking} D -->|Mask 1: Protein| E[GPT-4o Vision Reasoning] D -->|Mask 2: Carbs| E D -->|Mask 3: Veggies| E E --> F[Nutrient Mapping & Volume Estimation] F --> G[FastAPI Response: JSON Schema] G --> H[Final Dashboard] 🛠️ Prerequisites Before we start, ensure you have your environment ready: Python 3.10+ GPT-4o API Key (OpenAI) SAM Weights ( sam_vit_h_4b8939.pth ) Tech Stack : FastAPI , OpenCV , PyTorch , segment-anything 🚀 Step-by-Step Implementation 1. Object Segmentation with SAM First, we use Meta’s SAM to generate masks. This allows us to "cut out" each individual food item. import numpy as np import cv2 from segment_anything import sam_model_registry , SamPredictor # Initialize SAM sam_checkpoint = " sam_vit_h_4b8939.pth " model_type = "
开发者
Limn Engine — Complete API Reference
📚 Limn Engine — Complete API Reference Quick Navigation Class Purpose Level Display Canvas, game loop, input, camera, scenes 🟢 L1 Component Every visible game object 🟢 L1 Camera Viewport control (follow, shake, zoom) 🟡 L2 move Movement, physics, particles, helpers 🟢 L1 state Read-only query helpers 🟢 L1 TileMap Grid-based levels 🟡 L2 Tctxt Rich text with backgrounds 🟢 L1 Sound Single audio file 🟢 L1 SoundManager Multiple sounds, volume control 🔴 L4 ParticleSystem Emit, burst, continuous emitters 🟠 L3 Sprite Spritesheet animation 🟡 L2 Display The heart of every Limn Engine game. Creates the canvas, runs the game loop, captures input, manages the camera, and controls scenes. Constructor const display = new Display (); Properties Property Type Description .canvas HTMLCanvasElement The game canvas .context CanvasRenderingContext2D 2D drawing context .keys Array Boolean array indexed by keyCode .scene Number Current active scene (default 0) .camera Camera Attached camera instance .deltaTime Number Time since last frame (seconds) .fps Number Current frames per second .frameNo Number Total frames elapsed .x / .y Number false Methods Method Parameters Description .start(w, h, node) width, height, parentNode Initialise canvas and start game loop .perform() — Activate dual-canvas pipeline (call before .start() ) .add(comp, scene) Component, scene number Register a Component for rendering .stop() — Pause the game loop .scale(w, h) width, height Resize canvas after start .backgroundColor(color) CSS color Set background colour .lgradient(dir, c1, c2) direction, color, color Linear gradient background .rgradient(c1, c2) color, color Radial gradient background .fullScreen() — Enter fullscreen .exitScreen() — Exit fullscreen .tileMap() — Build TileMap from display.map and display.tile Usage const display = new Display (); display . perform (); display . start ( 800 , 600 ); display . backgroundColor ( " #0a0a2a " ); const player = new Component ( 40 , 40 , " blue " , 100 , 100 ); d
AI 资讯
Pinion: Resumable File Uploads for PHP
(Without Fighting upload_max_filesize ) You deploy your app. A user picks a 400 MB video. They hit upload. The progress bar freezes. Then — nothing. You check the logs. POST Content-Length exceeded post_max_size . Again. We've all been there. The fix is usually "raise PHP limits" or "use S3." Both work — until you're on shared hosting, a legacy VPS, or a client who won't touch php.ini . That's the problem Pinion solves. What is Pinion? Pinion is an open-source resumable chunked upload protocol for PHP. Instead of one giant multipart/form-data request, the browser sends the file in small parts (default: 5 MB). The server stores each part, then assembles the final file on disk. Three steps. That's the whole contract: init → upload parts → complete Package Registry Role pinoox/pinion Packagist PHP server engine @pinooxhq/pinion-client npm Browser client Protocol id: pinion · version: 2 Why not just use S3? Object storage is great. But sometimes you need files on your server : A CMS media library on local disk A Laravel app without cloud budget Shared hosting with no S3 SDK An admin panel behind a simple PHP API Pinion isn't a CDN or a storage service. It's a protocol — a stable HTTP contract that works in plain PHP, Laravel, or Pinoox. How it works (30-second version) sequenceDiagram participant Browser participant API participant Disk Browser->>API: POST /init (filename, size, fingerprint) API-->>Browser: upload_id, chunk_size, missing_indexes loop Each part Browser->>API: POST /upload (chunk + SHA-256 hash) API->>Disk: store part end Browser->>API: POST /complete API->>Disk: assemble file API-->>Browser: done ✓ Resume is built in. The client sends a fingerprint ( name:size:lastModified:type ). If the connection drops, the same file picks up where it left off — only missing parts are re-uploaded. Integrity too. Each part gets a SHA-256 chunk_hash . The server can reject corrupted chunks before they pollute your disk. Server side: 10 lines of PHP composer require pinoo
AI 资讯
Who Here Has Worked with Legacy? The Longer You Wait, the Worse It Gets
I promised myself that starting this week I'd switch to lighter topics. But on Monday, my JSNation...
AI 资讯
Event Loop - Entendendo uma das bases do Node
O Event Loop é o mecanismo responsável por decidir quando callbacks e continuidades de operações assíncronas devem ser executados. Ele não executa operações de I/O diretamente, mas organiza a ordem em que elas retornam para o JavaScript. Essa arquitetura permite que o Node.js mantenha uma única thread de execução para JavaScript, enquanto delega operações de rede, disco e sistema operacional para componentes especializados do runtime e do próprio sistema operacional. Início Quando iniciamos um processo Node.js, o runtime carrega o arquivo de entrada da aplicação e executa todo o código síncrono disponível na Call Stack. Somente após essa etapa o Event Loop passa a assumir o controle do fluxo da aplicação, verificando continuamente quais callbacks estão prontos para execução. │ timers │ └─────────────┬─────────────┘ │ v ┌───────────────────────────┐ ┌─>│ pending callbacks │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ idle, prepare │ │ └─────────────┬─────────────┘ ┌───────────────┐ │ ┌─────────────┴─────────────┐ │ incoming: │ │ │ poll │<─────┤ connections, │ │ └─────────────┬─────────────┘ │ data, etc. │ │ ┌─────────────┴─────────────┐ └───────────────┘ │ │ check │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ close callbacks │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ └──┤ timers │ └───────────────────────────┘ Trecho retirado da documentação principal. Sobre o Event Loop Durante muito tempo tratei o Event Loop como um dos conceitos mais complexos do Node.js. Depois de estudar a documentação oficial com mais calma, percebi que a dificuldade não está no Event Loop em si, mas na quantidade de conceitos diferentes que normalmente são apresentados ao mesmo tempo: libuv, Call Stack, Promises, Microtasks, Sistema Operacional e I/O. Quando isolamos o papel do Event Loop, ele se torna surpreendentemente simples. Definindo os passos e apresentando o iceberg 🧊 O Event Loop não executa trabalho. Ele agenda tr
AI 资讯
Stop Picking Dashboard Icons by Keyword
Most dashboard icon problems do not come from bad icons. They come from good icons used with the wrong meaning. You search for users , pick a clean SVG icon, place it in the sidebar, and move on. Then later you need another icon for: Customers Team members Account owners Permissions Audiences Invited users Admins Suddenly, the same “user” metaphor has to carry too many meanings. That is where SaaS dashboards often start to feel noisy. Not because the icons are ugly. Not because the SVGs are technically wrong. Not because the design system is broken. Because the icon choices were made by keyword instead of meaning. Keyword search is only the first step Most developers choose icons like this: Need an icon for billing? Search billing . Need an icon for users? Search users . Need an icon for analytics? Search chart . Need an icon for settings? Search settings . That works for finding candidates. But it does not solve the real UI problem. A keyword tells you what the icon is related to. It does not tell you what the icon means in your product. For example, search for settings . You might find: A gear Sliders A wrench Control knobs A preferences panel A tune icon They all match the keyword. But they do not say the same thing. A gear usually means global settings. Sliders suggest adjustable preferences or filters. A wrench feels technical or maintenance-oriented. Control knobs suggest fine tuning. A panel icon may suggest a configuration screen. The same keyword can point to different mental models. And in a dashboard, mental models matter more than decorative accuracy. SaaS dashboards are meaning-dense interfaces A marketing website can sometimes get away with decorative icons. A SaaS dashboard cannot. Dashboards are dense. They contain navigation, actions, status indicators, tables, filters, empty states, permissions, billing screens, integrations, reports, and settings. Users do not look at each icon in isolation. They scan. They compare. They move quickly. They expect
AI 资讯
Why setTimeout is Lying to Your Retry Logic
You've written retry logic. It probably looks something like this: async function withRetry ( fn , retries = 3 ) { for ( let i = 0 ; i < retries ; i ++ ) { try { return await fn (); } catch ( err ) { if ( i === retries - 1 ) throw err ; await new Promise ( r => setTimeout ( r , 200 * ( i + 1 ))); } } } You test it locally. You simulate a slow dependency like this: const fakeDB = async () => { await new Promise ( r => setTimeout ( r , 200 )); // simulate DB return { id : 1 , name : ' test ' }; }; Your retry logic works. Tests pass. You ship it. Then in production, your app starts dropping requests under load. The problem isn't your retry logic. It's your fake. Real dependencies don't have flat latency Here's what your Postgres instance actually looks like in production: p50: 5ms — half of all queries finish in under 5ms p95: 50ms — 95% finish under 50ms p99: 200ms — 99% finish under 200ms p99.9: 2000ms — that one unlucky query during a GC pause Your setTimeout(fn, 200) simulates the worst case, every single time. That's not how production works. And because it's not how production works, your retry logic has never actually been tested against reality. The bugs hide in the variance — not in the slow case, but in the unpredictability. What the real distribution looks like Latency in distributed systems follows a lognormal distribution . It's right-skewed: most requests are fast, a meaningful minority are slow, and a small tail is very slow. This shape comes from how real systems work: GC pauses — Java, Go, and even Node's garbage collector occasionally stops the world Cold caches — first query after a cache miss is always slower Network jitter — packet routing isn't deterministic Noisy neighbors — other workloads on the same hardware compete for resources Connection pool exhaustion — when all connections are busy, new queries wait None of these are constant. They're random, rare, and multiplicative — which is exactly what produces a lognormal shape. Why this matters fo
AI 资讯
(Alert!)5 Things Even AI Can't Do, GraphQL
GraphQL: A Complete Guide for Developers in 2026 NEWS: MY GAME JUST LAUNCHED Flip Duel Card Battle - Apps on Google Play Outsmart rivals in 1v1 card duels. Joker, bluff, ranked PvP. 5 rounds. play.google.com If you have built more than a couple of APIs, you have probably felt the friction of REST at scale. You ship an endpoint, the frontend team asks for one more field, you version the route, the mobile team needs a different shape of the same data, and six months later you are maintaining /v3/users/:id/full next to /v2/users/:id/summary and nobody remembers which one the Android app actually calls. GraphQL was built to kill that exact pain. It is a query language and runtime that lets clients ask for precisely the data they need — no more, no less — from a single endpoint, against a strongly typed schema that doubles as living documentation. This guide walks through GraphQL from first principles to production concerns. It is aimed at working developers, so expect schema definitions, resolvers, real queries, the N+1 problem, federation, security, and the parts of the ecosystem that actually matter in 2026. By the end you should be able to decide whether GraphQL belongs in your stack and how to build it without shooting yourself in the foot. What GraphQL Actually Is GraphQL is a specification, not a library or a framework. It was created at Facebook in 2012 to power their mobile apps, open-sourced in 2015, and is now governed by the GraphQL Foundation under the Linux Foundation. The spec defines a query language, a type system, and an execution model — but it deliberately says nothing about which database you use, which programming language you implement it in, or how you transport requests over the wire. That last point trips people up, so let it sink in: GraphQL is transport-agnostic and storage-agnostic. Most implementations run over HTTP with JSON, but that is a convention, not a requirement. Your resolvers can pull data from PostgreSQL, a REST microservice, a gR