AI 资讯
Automating Multi‑Platform Content Publishing with a Node.js Scheduler
Automating Multi‑Platform Content Publishing with a Node.js Scheduler TL;DR: I extended the content-automation repo to generate weekly newsletters, Dev.to articles, and platform‑specific markdown in a single CI run. The key was a tiny Node.js scheduler that reads a JSON manifest, writes files, and flips “generated” flags in metadata.json so downstream pipelines know what to publish. The Problem Our content pipeline had three independent manual steps: Write a weekly newsletter markdown file. Draft a Medium article. Publish a Dev.to post. Each step required copying the same body copy into a different folder ( weekly/ , content-automation/medium_* , content-automation/substack_* ) and then manually toggling flags in metadata.json . During a production run on 2026‑08‑08 the CI job failed with a cryptic log line: Error: Conn The truncated message was coming from the Prisma client that our automation script uses to fetch the latest draft from the CMS. Because the script never updated the metadata.json flags after a successful write, the next run tried to re‑process the same draft, hit a stale DB connection, and blew up. In short: the automation was not idempotent , and the state tracking was brittle. What I Tried First My first attempt was to wrap the whole generation flow in a try / catch and, on any error, abort the job without touching the manifest. I added a quick if (fs.existsSync(filePath)) return; guard to each write operation. // naive guard if ( fs . existsSync ( targetPath )) { console . log ( ` ${ targetPath } already exists – skipping` ); return ; } That prevented duplicate files, but it also silently skipped a legitimate update when we intentionally rewrote a newsletter (e.g., after a typo fix). Moreover, the guard didn’t address the stale Prisma connection, so the same Error: Conn kept surfacing in later runs. The Implementation 1. Central Manifest ( metadata.json ) The manifest now lives at content/2026/08/08/content-automation/metadata.json . I added expli
科技前沿
2026 Subaru Outback review: Great interior, refined drive, divisive looks
The newest Outback sticks to the script; that's no bad thing if you like Outbacks.
AI 资讯
Orange Crush: TAG Heuer Drops a Bright Revamp of the Original Metal F1 Watch
The solar-powered limited edition may be here to mark the final Dutch Grand Prix taking place in Zandvoort, but it's the juicy iconic colorway WIRED's been waiting for.
AI 资讯
How to Split PDF by File Size in the Browser with Vue 3 and pdf-lib
Splitting a PDF by file size is one of the most practical but technically tricky operations. Unlike splitting by page count (simple math) or bookmarks (tree traversal), size-based splitting requires estimating and controlling the output size of each chunk — and PDFs don't have a simple "size per page" property. Here's how to build a browser-based PDF splitter that respects file size constraints. The challenge PDFs are notoriously unpredictable in terms of size. Two PDFs with the same number of pages can differ by 10x in file size depending on: Image resolution and compression Font embedding Color space (RGB vs. CMYK) Content complexity (vector graphics vs. scanned images) This means you can't calculate split points with simple arithmetic. You need to estimate, test, and adjust . The stack Vue 3 with Composition API pdf-lib for PDF manipulation Vite for bundling The core implementation The approach is greedy accumulation with size estimation : < script setup lang= "ts" > import { ref } from ' vue ' import { PDFDocument } from ' pdf-lib ' const file = ref < File | null > ( null ) const targetSizeMB = ref < number > ( 10 ) const compression = ref < ' none ' | ' low ' | ' high ' > ( ' low ' ) const splitting = ref ( false ) const progress = ref ( 0 ) const progressTotal = ref ( 0 ) const results = ref < Record < string , Uint8Array >> ({}) async function splitBySize () { if ( ! file . value ) return splitting . value = true const arrayBuffer = await file . value . arrayBuffer () const pdf = await PDFDocument . load ( arrayBuffer ) const totalPages = pdf . getPageCount () const targetBytes = targetSizeMB . value * 1024 * 1024 const outputFiles : Array < { name : string ; data : Uint8Array } > = [] let currentPdf = await PDFDocument . create () let currentSize = 0 let pageNum = 0 for ( let i = 0 ; i < totalPages ; i ++ ) { progressTotal . value = totalPages progress . value = i + 1 // Try adding this page try { const [ copiedPage ] = await currentPdf . copyPages ( pdf , [
开发者
NETO: Chat P2P local para equipos dev sin depender de la nube
¿Tu equipo comparte tokens, contraseñas de staging o discute arquitectura sensible por Slack? Cada mensaje viaja a servidores de terceros. NETO es una alternativa radical: un chat peer-to-peer que funciona exclusivamente en tu red local, sin cuentas, sin nube, con cifrado de extremo a extremo. ¿Qué es NETO? NETO es una herramienta de mensajería diseñada para equipos de desarrollo que comparten la misma red. No hay servidor central, no hay registro, no hay datos que salgan de tu oficina o VPN. Abres la app y empiezas a hablar. ¿Cómo funciona por debajo? Descubrimiento con mDNS : NETO utiliza multicast DNS para encontrar automáticamente a otros peers en la red local. Sin configurar IPs ni puertos manualmente: si estás en la misma red, apareces. Cifrado con X25519 : Cada par de usuarios negocia claves efímeras mediante el
AI 资讯
The half of California's AB 723 that nobody implements
`California's AB 723 has been in force since January 1, 2026. It amends Business & Professions Code § 10140.8 and it applies to any real estate listing image that has been digitally altered. Virtual staging is the obvious case, but the definition is wider than that. The rule has two parts: A statement that the image has been altered, "reasonably conspicuous" and placed on or adjacent to the image. A link to a publicly accessible URL, or a QR code, that includes and clearly identifies the original, unaltered image. Everyone builds the first part. It is a text label on a photo, an afternoon of work. The second part is a small piece of infrastructure: a permanent public URL, per image, that outlives the tab the agent had open when they exported. I build a virtual staging product, so I had to ship both. This is how the second part is put together, and the one thing I got wrong. What counts as altered Worth getting right before writing any code, because it decides which of your features need the label and which do not. Subsection (b)(2) carves out ordinary photo editing. Covered: Adding furniture, rugs, art or decor Removing furniture, clutter or personal items Changing paint, flooring or wall finishes Sky replacement and day to dusk Greening or reshaping lawns and landscaping Anything that changes the facade or the property itself Not covered: Exposure, lighting, white balance, color correction Sharpening Straightening, cropping, angle In the codebase that line is a set, and the two omissions are deliberate: ts export const TOOLS_ALTERING_LISTING_IMAGES = new Set([ "virtual-staging", "sky-replacement", "day-to-dusk", "grass-greener", "declutter", "object-remover", ]); image-enhancer is out because exposure and white balance are precisely what the statute excludes. A floor plan generator is out because a diagram is not an altered photograph. Attaching a legal claim to a feature the law does not cover is not a harmless extra: it is the fastest way to make the rest of your
AI 资讯
Idempotent File Anchoring: SHA-256 Dedup Before You Call the API
Building any intake pipeline, you'll hit the same problem eventually. Files arrive from multiple sources. Some you've already processed: re-uploads of the same document, copies from two different intake paths, items your worker errored on last run and re-queued. Call the anchoring API blindly and you end up with multiple proof records for identical bytes. The ProofLedger v1 API returns a duplicate_of field in its 201 response when it detects a hash it's already seen. But that's only half the solution. A network round-trip costs time and quota even when it comes back as a duplicate. Hash-based local deduplication is the other half. Here's how to build a worker that handles both layers. Hash Locally First The core pattern: compute the SHA-256 digest before making any API call. If you've seen this digest before, skip it. If you haven't, submit it. Two things you need: a persistent record of digests you've already anchored, and chunked hashing so large files don't blow memory. import hashlib import json from pathlib import Path SEEN_DB = Path ( " anchored_hashes.json " ) def load_seen (): if SEEN_DB . exists (): with open ( SEEN_DB ) as f : return json . load ( f ) return {} def save_seen ( db ): with open ( SEEN_DB , " w " ) as f : json . dump ( db , f , indent = 2 ) def hash_file ( path : str ) -> str : h = hashlib . sha256 () with open ( path , " rb " ) as f : for chunk in iter ( lambda : f . read ( 65536 ), b "" ): h . update ( chunk ) return h . hexdigest () 65536-byte chunks keep memory flat regardless of file size. The load_seen / save_seen pair gives you a persistent record that survives worker restarts. Submitting and Reading duplicate_of When duplicate_of appears in the API response, its value is the proof ID of the earliest anchor for that hash. That's the canonical ID. The new proof ID from this call is irrelevant. import requests API_URL = " https://proofledger.io/api/v1/proof " API_KEY = " sk_YOUR_KEY_HERE " def anchor_file ( file_path : str , seen : dict
AI 资讯
Running a Private LLM Game Master Entirely in the Browser
I recently discovered that you can run a fully interactive, narrative-driven RPG in your browser without uploading a single byte of user data to a cloud server. For a developer who is tired of the "send prompt to API, wait for response, render text" latency loop, this felt like a breakthrough. The result is Starwright , an endless space adventure where the plot is generated dynamically by a private on-device AI model. The Wedge: Latency and Privacy as Features Most browser-based AI games rely on a constant handshake with a remote inference engine. This introduces two friction points: network latency, which breaks immersion during dialogue, and privacy concerns, where your creative inputs are processed by third-party servers. By shifting the compute burden to the client using WebGPU, we can run a small model that runs in your browser entirely offline. This isn't just about cost savings on inference tokens; it’s about the feel of the interaction. When there is no network round-trip, the "typing" feel of the AI game master disappears. The narrative flow becomes immediate, similar to a traditional text adventure but with the generative flexibility of large language models. For developers building AI-native applications, this architecture suggests a shift in how we think about "always-on" AI. Instead of treating AI as a service, we treat it as a local capability. Implementation: WebGPU and Quantization The technical challenge in bringing this experience to the browser was fitting a capable narrative model into the memory constraints of a client device while maintaining responsive performance. We utilized WebGPU to accelerate the matrix multiplications required for inference, allowing the model to run smoothly on both modern desktops and capable laptops. The model is quantized to reduce its footprint, ensuring it can load within seconds. Here is a simplified view of how the inference loop is structured in the application: // Simplified inference loop for the on-device mod
AI 资讯
This great retro-inspired keyboard now comes preassembled
You probably know just by looking at it if the Classic-TKL Underscore Edition is for you. Do you want a retro-looking wired keyboard without a number pad? Great. Do you care that it doesn't have wireless? Perfect. Do you want it preassembled? Buddy, you're in the right place. But Nathan, you might say, preassembled is […]
AI 资讯
Peer review is overwhelmed—can it survive in the AI era?
As research and AI-assisted papers surge, volunteer reviewers struggle to keep up.
AI 资讯
Article: Comprehension as an Architectural Characteristic: A System That Is Not Understood Cannot Evolve Safely
As AI commoditizes code output, system comprehension silently decays, creating cognitive debt that threatens safe architectural evolution. This article explores why human understanding must be treated as an essential architectural characteristic, offering actionable strategies, socio-technical metrics, and design checkpoints to preserve intent across modern engineering teams. By Jacobus Meintjes, Narayana Rengaswamy, Paul Katsande, Sureshbabu Bikki
AI 资讯
The Laravel 13 Features That Matter in Real Projects
The Laravel 13 Features That Matter in Real Projects Laravel 13 shipped on March 17, 2026, and the upgrade story is unusually simple: zero application-level breaking changes from Laravel 12, one hard requirement (PHP 8.3), and several features that are genuinely useful in production rather than just impressive in release notes. This post focuses on the features you will actually reach for on real client projects — not an exhaustive tour. For the full release overview, upgrade checklist, and breaking changes reference, see Laravel 13: Features, Upgrade Guide, and Breaking Changes . Prerequisites: PHP 8.3+, Laravel 13.x (latest stable: 13.14.0 as of June 2026), Composer 2.x. 1. PHP Attributes on Models and Controllers Laravel 13 adds PHP 8-style #[Attribute] support across 15+ framework locations. The old property-based syntax still works — this is purely additive. On Eloquent Models: use Illuminate\Database\Eloquent\Attributes\Table ; use Illuminate\Database\Eloquent\Attributes\Fillable ; use Illuminate\Database\Eloquent\Attributes\Hidden ; #[Table('posts', primaryKey: 'id', incrementing: true, timestamps: true)] #[Fillable('title', 'body', 'user_id')] #[Hidden('deleted_at')] class Post extends Model {} On Controllers: use Illuminate\Routing\Attributes\Controllers\Authorize ; use Illuminate\Routing\Attributes\Controllers\Middleware ; #[Middleware('auth')] class CommentController extends Controller { #[Middleware('subscribed')] #[Authorize('create', [Comment::class, 'post'])] public function store ( Post $post ) { } } When to actually use this: Attributes shine on large domain models where $fillable , $hidden , $casts , and relationship declarations are scattered across the class. Collocating table definition and mass assignment rules at the top of the file improves readability at a glance. On small CRUD models, the tradeoff is extra import lines for minimal gain. Common mistake: Mass-converting every existing model to attribute syntax in a single PR. It creates a lar
AI 资讯
PDF Generator Fingerprints: What Software Made This File (And Where It Lies)
Originally published at htpbe.tech . The version on htpbe.tech stays in sync with the latest detection algorithm — refer to it for the canonical text. Two bank statements land in your underwriting queue. Both look like they came from the same bank. Both open cleanly. Both show the account holder you expect. One was generated by the bank’s statement engine. The other was rebuilt in a desktop editor, with the closing balance quietly raised by a few thousand. From the outside, they are indistinguishable. From the inside, they were made by entirely different software — and that software left its name behind. Every PDF carries a fingerprint of the tool that produced it. Not a watermark you can see, but a set of structural habits: how the file lays out its objects, how it embeds fonts, what it writes into its own metadata, how it joins pages together. A risk team that learns to read these fingerprints gains a powerful, content-independent question to ask of any document: does the software that claims to have made this file actually behave like that software? This article walks through the major server-side PDF generation libraries, explains what the Producer and Creator fields really tell you (and where they lie), and shows how a structural analysis reads all of it automatically. The two fields everyone looks at first Open any PDF’s properties and you will find two metadata fields that name software: Creator — the application a human used to author the document. Microsoft Word, Adobe InDesign, LaTeX, a bank’s internal reporting tool. Producer — the library that wrote the final PDF bytes. Adobe PDF Library, iText, ReportLab, the print-to-PDF subsystem of an operating system. In a clean pipeline these tell a coherent story. A document authored in Word and saved to PDF reports Creator: Microsoft Word and Producer: Microsoft® Word . A LaTeX paper reports Creator: TeX and Producer: pdfTeX-1.40.26 . The two fields together describe a real, plausible toolchain. The problem: both
AI 资讯
How Pinterest Secures AWS Infrastructure at Scale with a Centralized Terraform Pipeline
Pinterest has revealed the Resource Provisioner Pipeline (RPP), its own Terraform execution engine. It ensures least-privilege access and needs dual-control reviews. This is important for the company’s AWS infrastructure, as it adds strict guardrails to the GitHub Actions workflows. By Claudio Masolo
AI 资讯
Your AI Agent Needs a Maintenance Window Protocol
Long-running agents are usually tested at startup and during normal operation. The awkward middle is ignored: what happens when you need to deploy a new image, rotate a credential, migrate a database, or restart the host while the agent is halfway through a tool call? A process supervisor can restart a crashed agent. It cannot decide whether a browser checkout was committed, whether a webhook was acknowledged, or whether a tool call is safe to replay. That decision belongs in the agent runtime. This post presents a small maintenance-window protocol for agents that run for hours or days. It has four goals: stop accepting new work; let safe work finish or reach a checkpoint; make ambiguous work visible instead of guessing; resume with an explicit recovery decision. 1. Model maintenance as a state transition Do not treat maintenance as kill -TERM followed by hope. Give the runtime a durable state machine: RUNNING -> DRAINING -> QUIESCED -> STOPPED | +-> NEEDS_REVIEW DRAINING rejects new jobs but allows an active job to continue until its next checkpoint or deadline. QUIESCED means there are no unclassified side effects in flight. NEEDS_REVIEW is the safe outcome when the process died after sending a request but before recording the response. Persist the transition, not just an in-memory flag. A minimal record can look like this: { "runtime" : "agent-7" , "maintenance_id" : "mw-2026-08-10-001" , "state" : "DRAINING" , "started_at" : "2026-08-10T08:00:00Z" , "accepting_work" : false , "active_runs" : 2 } If the host disappears, the replacement process can see that the previous shutdown never reached QUIESCED . That is much more useful than inferring health from a missing PID. 2. Put checkpoints around side effects An LLM step is usually replayable. A payment, email, browser click, deployment, or Git push may not be. Record a checkpoint immediately before and after every non-idempotent boundary: PLANNED -> DISPATCHED -> ACKNOWLEDGED -> OBSERVED On restart: PLANNED can be
开发者
How to Secure Your WordPress Dashboard and Prevent Clients from Breaking Their Sites
A guide on using Admin Extension Access Control to lock down WordPress plugins and prevent unauthorized changes. How to Secure Your WordPress Dashboard and Prevent Clients from Breaking Their Sites If you are a freelance web developer or run an agency, you have probably experienced the dread of a client accidentally bringing down their WordPress site. You spend weeks building a robust, performant website, only for an unauthorized user to log into the dashboard, start deactivating essential plugins, or install poorly coded extensions that break everything. WordPress is fantastic because of its flexibility, but out of the box, any Administrator can touch everything . To solve this problem, I want to introduce a lightweight solution: Admin Extension Access Control . What is Admin Extension Access Control? Admin Extension Access Control is a WordPress plugin designed to give you granular control over who can see, modify, install, or delete plugins on your site. Built for modern environments (PHP 8.1+ and WordPress 6.0+), it allows you to configure strict role-based access rules without writing custom PHP functions in your functions.php file every time. Key Features Global Lockdown : Completely remove the plugins page for specific user roles. Granular Permissions : Restrict the ability to add, delete, activate, deactivate, or install plugins on a per-role basis. Exempt Users Whitelist : Designate trusted administrators (like yourself) who bypass all lockdown rules. Only exempt users can configure the access control settings. Dashboard Cleanup : Hide the plugins menu item from unauthorized users to keep the dashboard less confusing for clients. How It Works Once installed and activated, the user who activates the plugin is automatically added to the Exempt Users list. This prevents you from accidentally locking yourself out. From the settings panel, you can select which roles should be restricted from managing plugins. For example, you can give your client an "Administrat
AI 资讯
Presentation: Leveraging Adversary Emulation for GenAI Red Teaming
Kennedy Torkura discusses practical GenAI red teaming techniques to safeguard LLMs and knowledge bases against security threats like data poisoning and LLMjacking on AWS. He explains how engineering leaders and architects can bridge traditional cloud security with MITRE ATLAS frameworks to proactively identify vulnerabilities, implement guardrails, and secure production AI applications. By Kennedy Torkura
AI 资讯
GitHub Code Quality Targets Maintainability as AI-Generated Code Increases
GitHub Code Quality is now generally available on GitHub Enterprise Cloud and GitHub Team. The service combines CodeQL analysis with AI-assisted detection of maintainability and reliability problems, then uses Copilot Autofix to suggest changes for review in pull requests, according to an announcement from GitHub. By Matt Saunders
AI 资讯
Buildpacks Move the Container Hardening Control Point Away From the Dockerfile
Cloud Native Buildpacks, which graduated within the CNCF in July 2026, move base image choice out of per-service Dockerfiles into a single builder owned by platform engineering, enabling fleet-wide patching. BellSoft's hardened Paketo builder is the latest sign that vendors now treat the builder, not the Dockerfile, as the container security control point. By Mark Silvester
AI 资讯
I Built a ₹15 Landing Page About Mumbai's Soul Food
A scroll-driven cinematic page about vada pav. No framework, no build step. Just HTML, CSS, and a story worth telling. Dev.to Frontend Challenge submission.