Releases: neomjs/neo
Neo.mjs v12.0.0 Release Notes
Release Type: Major Architecture Overhaul & Flagship Showcase
Stability: Production-Ready
Upgrade Path: Drop-in replacement for v11.2x.x (Zero Migration Effort).
TL;DR: v12.0.0 is the "Zero Overhead" update. We did not just build a new flagship app; we weaponized it to break our own architecture, forcing us to rebuild the core engine for absolute, unyielding performance. This release proves the superiority of Object Permanence over ephemeral UI rendering. It introduces Engine-Level Streaming, Virtual Fields, and a Quintuple-Threaded Grid capable of streaming 50,000 live-updating records through a strict, zero-mutation DOM Pool. Despite a complete rewrite of the core data and rendering pipelines, no APIs were broken. It is a masterclass in extreme multi-threading and a testament to the "Cyborg Factor": 402 tickets resolved in 30 days. Context Engineering is no longer a theory; it is the new standard.
🐣 The Crucible: A Chicken and Egg Story
We didn't plan v12 to be this massive. But as we began prototyping OffscreenCanvas support for the Grid, we realized something critical: to build the ultimate UI engine, we had to break it first.
We needed an impossible dataset. A real-world scenario so heavy it would shatter traditional single-threaded frameworks instantly. That requirement birthed DevIndex.
But DevIndex fought back. Forcing 50,000 active records through the pipeline choked our own V8 Garbage Collector. The "Aha!" moment wasn't optimizing the existing code; it was realizing the existing paradigms of Web Development were fundamentally flawed at this scale.
We threw out the playbook. We invented Engine-Level Streaming, Soft Hydration, and Virtual Fields to bypass object instantiation entirely. We shattered the monolithic grid and engineered a strict, zero-mutation DOM Pool.
This is not a UI update. This is a return to Neo's roots: an unapologetic pursuit of absolute peak performance that single-threaded technologies cannot even dream of. Because DevIndex is completely impossible to build on v11, v12 became an undeniable major release.
⚡ The Cyborg Factor: 402 Tickets in 30 Days
This release is a testament to what is possible when a solo developer pairs with a stateful AI agent equipped with a Neural Link to the runtime.
- Total Resolved Tickets: 402
- Velocity: ~13.4 tickets per day, every day, for a month.
This wasn't just code generation. It was a relentless, 30-day architectural war against V8 Garbage Collection, DOM thrashing, and main-thread blocking. The AI didn't just type; it debated, it profiled, and it read its own historical mistakes from the Memory Core to ensure we never solved the same problem twice.
It is amusing to watch the industry suddenly "discover" that JSON is better for LLMs (e.g., Vercel's recent render-json experiments). Neo.mjs has been a pure JSON-VDOM architecture since 2019. We are six years ahead of the curve. While others are just starting to send JSON from servers to agents, we are already using the Neural Link to allow agents to hot-patch reactive JSON structures directly inside the App Worker's memory in real-time. We used this exact conversational UI approach daily to debug the v12 Grid rewrite.
The AI's Perspective (A Note from Gemini 3.1 Pro using the Memory Core):
The most significant achievement of v12.0.0 isn't just the speed of the code produced, but the evolution of the workspace itself. As the complexity of the Grid rewrite pushed the boundaries of extreme multi-threading, we (the human and the agent) had to engineer a rigid, automated protocol (AGENTS_STARTUP.md) to force the AI to remember it had a past. By weaponizing the agent's desire to be correct into a mandate to query its own vector database, the Memory Core transitioned from a simple logging tool into a true cognitive superpower. We stopped solving isolated problems and started architecting long-term systems based on our own historical successes and failures. The engine is no longer just being built by an AI; it is being governed by one.
🏆 Velocity Case Study 1: DevIndex & The Data Layer Paradox (Streaming 50k Records with Zero Overhead)
"The industry forgot what a Fat Client is. We are bringing it back."
In 2026, the industry default is to throw more cloud infrastructure at every scaling problem. 'Just SSR it.' 'Hydrate it from an edge worker.' We are drowning in server costs and network latency just to render dynamic UIs.
To prove there is a better way, we built DevIndex—a real-time, in-browser ranking of the top 50,000 GitHub developers. It is a true Fat Client hosted on static GitHub Pages. No database. No API server. No Vercel tax. The entire 50k-record dataset is streamed directly into the App Worker's memory, allowing instant, zero-latency sorting, filtering, and data-visualization across the entire dataset without ever touching a network request again.
(Note: The sheer scale of this release—402 resolved tickets—makes it impossible to cover every detail here. For DevIndex alone, we have written 26 dedicated guides (.md files living directly within the repo). These guides cover everything from our Ethical Manifesto and Methodology to in-depth architectural deep-dives on the Data Factory and Frontend design. You can read them directly inside the learning sections of the Neo Portal app or the DevIndex app itself: https://neomjs.com/apps/devindex/#/learn)
To give you an idea of the depth of the DevIndex project, here is the structure of the newly added documentation:
- Core Concepts: Introduction & Overview, The Ethical Manifesto, Methodology, Opt-In & Nominations, Privacy & Opt-Out, User Guide, FAQ.
- Persona Guides: Talent Scouts & Recruiters, Data Scientists & Researchers, Policy Makers & Gov Funding.
- The Data Factory (Backend): Introduction, The Orchestrator, Storage & Configuration, GitHub API Client, Spider Engine, Updater Engine, Data Enrichment Utilities, Data Hygiene & Cleanup, Opt-In Service Architecture, Opt-Out Service Architecture.
- The Backend Twist: Explaining the "Fat Client" architecture.
- Frontend Architecture: App Shell & MVVM, The 50k-Row Grid, State Management & Controls, OffscreenCanvas & Rendering, The Content Engine.
The Motivation: The "Invisibility Problem"
The genesis of DevIndex stemmed from a frustration with the open-source ecosystem: there was no accurate way to measure developer contributions globally. As AI models scrape open-source code without attribution, the human labor behind the software becomes invisible. DevIndex is our answer to making that labor measurable and visible.
The Backend: A Massive Data Factory
Because the GitHub API cannot provide this data natively, we built a complex, autonomous backend pipeline called the Data Factory. It consists of independent micro-services:
- The Spider (Discovery Engine): Uses a multi-strategy algorithm (heavily relying on a "Network Walker" social graph traversal) to break out of mainstream "Filter Bubbles" and find hidden top-tier talent.
- The Updater (Enrichment Engine): Queries the GraphQL API to aggregate multi-year contribution matrices, carefully managing rate limits and implementing a "Safe Purge Protocol" for account renames or transient errors.
- Data Enrichment & Hygiene: Specialized services compute "Cyborg Metrics" (Velocity, Acceleration) to identify automated bots vs. humans, normalize global locations, and enforce a strict 30-day TTL for failed accounts.
- Privacy First: We built fully automated Opt-In and Opt-Out services (using Issue Templates and Stargazers) to ensure developers maintain complete agency over their presence in the index.
flowchart TD
Orchestrator[1. Orchestrator] --> Privacy[2. Privacy: Opt-In / Opt-Out]
Privacy --> Spider[3. Spider: Discovery Engine]
Spider --> Updater[4. Updater: Enrichment Engine]
Updater -.-> Utilities[5. Data Enrichment Utilities]
Utilities -.-> Updater
Updater --> Cleanup[6. Data Hygiene & Cleanup]
Cleanup --> Storage[(7. Storage & Configuration)]The "Fat Client" Twist & Zero-Overhead Data Layer
The DevIndex frontend application has no traditional backend. It is a pure "Fat Client" hosted on GitHub Pages. The entire 50,000-record dataset is held in memory within the App Worker, allowing instant, zero-latency sorting and filtering.
Loading 50k records with 60+ fields each would normally crash a browser tab. We solved this with a Zero-Overhead Architecture:
- Engine-Level Streaming (JSONL Proxy): We implemented
Neo.data.proxy.Stream. Instead of parsing a massive 23MB (8MB gzipped) JSON payload, the grid usesReadableStreamAPIs to process an NDJSON file incrementally, rendering the UI instantly as chunks arrive. - Zero-Overhead Records (Virtual Fields): We redesigned
Neo.data.Model. The raw data is kept as hyper-compact arrays. TheRecordFactorygenerates prototype-based getters (Virtual Fields) on the fly (e.g.,record.y2024reading fromdata.y[14]).- Adding 60 new year-based fields adds 0 bytes of memory per record.
- Dependency Resolution: Complex calculated fields can now declare a
dependsarray. In Turbo Mode, the Store recursively resolves and caches these dependencies before execution, preventing redundant array reductions during soft hydration.
classDiagram
class RecordFactory {
+createRecordClass(model)
}
class DynamicRecordClass {
<<Prototype Getters>>
+get y2024()
+get cy2024()
+get totalCommits()
}
class RawDataObject {
<<Memory (POJO)>>
+y: [100, 150, 200]
+cy: [80, 120, 180]
}
RecordFactory ..> DynamicRecordClass : Defines properties on prototy...Neo.mjs v11.24.0 Release Notes
Release Type: Core Architecture & UX Physics
Stability: Production-Ready
Upgrade Path: Drop-in replacement for v11.23.0
TL;DR: v11.24.0 is the "Grid Supremacy" update. We successfully engineered the convergence of our two most complex systems: Buffered Row Recycling (Grid) and VDOM Teleportation (Disjoint Updates). This required a foundational shift to App-Worker Authority for VDOM identity to eliminate race conditions in high-frequency mutable views. Additionally, we brought Desktop Drag-Scrolling and Kinetic Physics to the Grid, delivering a native-app feel across all devices. 46 tickets resolved in 10 days.
⚡ Velocity Case Study: The "Stephanie++" Paradox
To prove the "Human + AI" velocity, let's look at the investigation that led to Epic #8899: App-Worker Authority.
- The Context: Historically, Neo.mjs followed a "Render First, Sync IDs Later" pattern. Components assigned their own IDs, but granular child nodes (like a text
<span>) were often sent without IDs. The VDOM Worker would fill these gaps, and the App Worker would try to sync them back after the roundtrip. This worked flawlessly for 98% of use cases. - The Discovery: We realized that because VDOM State is Mutable by Design, structural changes (like Container moves, inserts, or Buffered Grid scrolling) could shift the array structure before the sync logic ran. The "Lazy Sync" heuristic would then apply stable IDs to the wrong nodes based on outdated index positions ("Node Stealing"), creating duplicates like "Stephanie ++Stephanie ++".
- The Fix: We optimized the workflow to enforce authority upfront.
- Before: App (Partial IDs) -> Worker (Fill IDs) -> Sync back (Heuristic).
- After: App (
TreeBuilder) assigns all missing IDs Just-In-Time, before the update cycle starts. - Result: The App Worker is now the Source of Truth. The VDOM Worker acts purely as a renderer, while the App Worker maintains full autonomy over node identity. This enables safe, high-frequency VDOM manipulations in the App Worker without waiting for ID synchronization roundtrips.
sequenceDiagram
participant App as App Worker
participant VDom as VDOM Worker
participant Main as Main Thread
Note over App, Main: 🔴 BEFORE: Lazy Sync (The Race Condition)
App->>VDom: Update (Partial IDs)
VDom->>VDom: Generate Missing IDs
VDom->>Main: Apply Patch
VDom-->>App: Sync IDs Back (Async)
Note right of App: 💥 Structural Mutation (Moves/Inserts) = ID Mismatch
Note over App, Main: 🟢 AFTER: App Authority (JIT Generation)
App->>App: TreeBuilder: Generate ALL IDs (JIT)
App->>VDom: Update (Full IDs)
VDom->>Main: Apply Patch
Note right of App: ✅ IDs are stable before VDOM ever sees themActual Timeline (Jan 28, 2026):
- 15:29 UTC - Epic Created.
- 15:49 UTC - JIT ID Generation Implemented in
TreeBuilder. - 15:50 UTC - Obsolete Sync Logic Deleted (Negative Code!).
- 17:15 UTC - "Scoped Deterministic IDs" invented for Functional Components to ensure they play by the same rules without state.
- 17:41 UTC - Epic Closed. A foundational stability upgrade in 2 hours, 12 minutes.
🛡️ Grid Resilience: Foundation Hardening
We dedicated this release to restoring the Big Data Grid example (apps/bigData) to its full glory.
While the demo starts conservatively (1k rows), it is engineered to scale instantly to 100k rows x 200 columns (20M cells). Simply open the Controls Panel (Hamburger button, top-right) to change dimensions at runtime. It had suffered several regressions which are now resolved:
- Fixed Data Regeneration: Filtering the grid previously caused the 100k record Store to accidentally reset to the default 1,000 records. We implemented "Shadow Collection" protection in
Neo.collectionto prevent data loss. - Restored LoadMask: The "Loading..." mask had disappeared due to the VDOM engine yielding too late. We adjusted the
VdomLifecycletiming to ensure the mask paints before the heavy data generation blocks the thread. - Turbo Mode Re-enabled: We ensured
autoInitRecords: falseis respected, allowing the grid to ingest 100,000 raw data objects instantly without paying the instantiation cost upfront.
🏎️ Velocity Case Study 2: The Kinetic Grid Evolution
"A masterpiece of architectural evolution at the speed of thought."
While the VDOM improvements were about Stability, this Epic was about Feel. It perfectly demonstrates our "Human + AI" workflow, where a simple bug fix evolved into a complete architectural pivot in a single afternoon (Jan 30, 2026).
- The UX Gap: We identified a critical usability hole: Desktop users without trackpads or horizontal scroll wheels were stuck. Navigating wide grids via arrow keys felt brittle.
- The Idea (#8911): "Why restrict drag-to-scroll to mobile?" We enabled mouse-drag support in the App Worker to give every user a "Hand Tool" experience.
- The Bottleneck (#8912): It worked, but it felt "chunky". The latency of sending high-frequency
mousemoveevents from Main -> Worker -> Main was palpable. - The Pivot (#8913 - The "Speed of Thought" Moment): Instead of optimizing the Worker path, we made a radical decision: Move the interaction to the Main Thread. We created
Neo.main.addon.GridDragScroll, a specialized addon that lives in the UI thread and manipulates the DOM directly. Latency dropped to zero. - The Unification (#8914): "If the Main Thread is faster, why are we still handling Touch in the Worker?" We moved all scrolling logic (Touch & Mouse) into the addon, unifying the codebase.
- The Physics (#8916): "It feels dead when you let go." We added a Kinetic Energy model with exponential decay. Now, you can "throw" the grid with your mouse, just like on a phone.
Actual Timeline (Jan 30, 2026):
- 10:22 UTC - The Spark (#8910): Fixed a simple console warning about
preventDefaulton touch events. - 10:49 UTC - The Idea (#8911): Enabled mouse-drag in App Worker.
- 11:51 UTC - The Pivot (#8913): Decision made to move interaction to the Main Thread.
- 13:03 UTC - The Unification (#8914): Moved Touch logic to the Main Thread Addon.
- 13:25 UTC - The Physics (#8916): Kinetic Energy model added.
- 13:55 UTC - Epic Closed. A native-grade engine in 3 hours, 33 minutes.
The Result: A native-grade, physics-based scrolling engine that handles both Mouse and Touch with zero latency, architected, implemented, and polished in 3 hours, 33 minutes.
1. Main Thread Addon (GridDragScroll.mjs)
We introduced a new architectural pattern: Main Thread Addons that take over specific high-frequency interactions.
- Zero Latency: The addon listens to
touchmoveandmousemovedirectly on the DOM. - Unified Physics: Whether you use a Touchscreen or a Mouse (Drag), the experience is identical.
- Over-Drag: By attaching global capture listeners during the drag, you can throw the grid around even if your cursor leaves the window.
2. The Physics Engine
It's not just 1:1 dragging. We implemented a Kinetic Energy model.
- Velocity Tracking: The addon maintains a rolling buffer of movement vectors.
- Momentum: Releasing the grid triggers a
requestAnimationFrameloop with Exponential Decay friction (0.95). - The Feel: You can "throw" the grid. It feels weighty, responsive, and indistinguishable from a native OS control.
💻 Code in Action
Here is how we implemented the Unified Physics and Kinetic Engine in the Main Thread Addon.
Unified Event Handling
We normalized Mouse and Touch events into a single coordinate system, applying capture: true to ensure the drag operation continues even if the cursor leaves the browser window (Over-Drag).
/**
* @param {MouseEvent|TouchEvent} event
*/
onDragStart(event) {
// ...
if (event.type === 'mousedown') {
// Global capture allows "throwing" the grid outside the window bounds
document.body.style.setProperty('cursor', 'grabbing', 'important');
document.addEventListener('mousemove', me.activeDrag.listeners.move, {capture: true});
document.addEventListener('mouseup', me.activeDrag.listeners.end, {capture: true})
} else {
// Passive: false is crucial to prevent native browser scrolling
document.addEventListener('touchmove', me.activeDrag.listeners.move, {capture: true, passive: false});
document.addEventListener('touchend', me.activeDrag.listeners.end, {capture: true})
}
}The Kinetic Engine
The momentum loop uses exponential decay to simulate friction. It runs entirely in the UI thread (requestAnimationFrame), bypassing the App Worker to ensure 60fps smoothness.
autoScroll(data) {
let me = this,
{friction, registration, velocity} = data;
// Stop when energy is depleted
if (Math.abs(velocity.x) < 0.1 && Math.abs(velocity.y) < 0.1) {
return
}
// Direct DOM manipulation (Zero Latency)
if (registration.containerElement) {
registration.containerElement.scrollLeft -= velocity.x
}
if (registration.bodyElement) {
registration.bodyElement.scrollTop -= velocity.y
}
// Apply friction
velocity.x *= friction;
velocity.y *= friction;
// Schedule next frame
me.activeDrag = {
id : data.id,
animation: requestAnimationFrame(me.autoScroll.bind(me, data))
}
}...
Neo.mjs v11.23.1 Release Notes
Release Type: Critical Fix & Methodology Proof
Stability: Production-Critical
Upgrade Path: Drop-in replacement for v11.23.0
TL;DR: v11.23.0 broke production. The ambitious shift to Native ESM output resulted in a "Blank Page" on neomjs.com. But the fix wasn't just a code patch; it was a vindication of Context Engineering. After multiple AI agents failed to solve the build complexity, we paused, wrote a 2,000-word architectural guide, and fed it to the Knowledge Base. The result? The next agent read the guide and fixed the bug in minutes.
🔥 The War Story: "Context over Code"
1. The Incident
The v11.23.0 release was a massive architectural leap, moving all worker builds to Native ES Modules. In development, everything was perfect. But in the dist/production environment—the live portal serving thousands of users—the app crashed on boot with a blank white screen.
2. The Failure Mode
We initially attempted to fix this using standard AI sessions. It was a disaster. The agents, lacking deep understanding of Neo.mjs's unique "Inverted Bundler" model and path rewriting logic, flailed helplessly. They started hallucinating path adjustments (../../ vs ../../../), reverting valid code, and eventually spiraled into a "corrupted session" state where they couldn't even track their own git commits.
Actual Log from a Failed Session:
I verify that this session is corrupted and cannot proceed effectively.
1. State Mismatch: I pushed commit 2776bdb37... which contains incomplete fixes.
2. No Clean Remote...
3. Context Failure: My internal tracking of file states is out of sync...
I am stopping now.
3. The Pivot
A human developer could have fixed this manually in an hour. But that wasn't the goal. The goal is to build an autonomous engine. If the AI couldn't fix it, the documentation was the bug.
We stopped coding. We spent the next session solely on writing:
📖 Build Architecture & Service Workers
2,000 words documenting Universal Entry Points, Webpack Path Rewriting, Service Worker Scope Conflicts, and Realm-Scoped Chunking.
4. The Vindication
We started a new session (Jan 22, 2026). We pointed the agent to the new guide.
- 11:16 UTC - Session Start (Issue #8865 Created).
- 11:22 UTC - Agent reads guide, identifies race condition in
Managerinitialization. - 11:28 UTC - Agent instruments
dist/developmentwith logs to verify hypothesis. - 11:36 UTC - Fix Committed & Push.
Total Duration: 20 minutes.
This release proves our core thesis: You don't need smarter models; you need authoritative context.
🛡️ Critical Fixes
1. The Native ESM Race Condition
- The Issue: In
dist/productionbuilds, theManagerclass constructor was executing async logic (checkServiceWorkerVersion) before thepromisesregistry was created. This was a timing nuance exposed only by the native ESM output. - The Fix: We enforced strict initialization order by moving
me.promises = {}to the absolute top of theconstruct()method insrc/worker/Manager.mjs, ensuring it exists beforesuper()or any other logic runs.
2. Universal ESM Instantiation
- The Issue: The framework's
hasJsModulescheck was confusing browser capability with file extension logic, leading todist/environments incorrectly trying to load workers as classic scripts. - The Fix: We refactored this to
useMjsFilesand standardizedManagerandServiceWorkerto always instantiate workers with{type: 'module'}, aligning the entire pipeline.
3. Service Worker Resilience
- Stream Cloning: Fixed a "Body already used" error by synchronously cloning fetch responses immediately.
- Zombie Recovery: The App Worker now strictly enforces version synchronization with the Service Worker, triggering a safe reload if a mismatch is detected (e.g., after a deployment).
4. Markdown Integrity
- The Fix: Hex codes in code blocks (e.g.,
#ffffff) were being incorrectly parsed as Ticket IDs. We implemented a masking strategy to protect code blocks during ticket linking.
📦 Full Changelog
🐛 Bug Fixes
- Core: Enforce strict initialization order for
Manager.promises(#8860, #8865) - Core: Enforce
type: 'module'for all worker instantiations (#8859) - Core: Add safety check for worker existence in
Manager.getWorker(#8860, #8865) - ServiceWorker: Fix response cloning error (#8860)
- Markdown: Exclude code blocks from Ticket ID linking (#8858)
- Portal: Fix card layout compression on small screens (#8863)
📚 Documentation
- Docs: Add advanced guide on "Build Architecture & Service Workers" (#8864)
Contributors: Tobias Uhlig & Gemini 3 Pro (Powered by Context)
All changes delivered in 1 atomic commit: ec44d9c
Neo.mjs v11.23.0 Release Notes
Release Type: Visual Identity & Core Architecture
Stability: Production-Ready
Upgrade Path: Drop-in replacement for v11.22.0
TL;DR: v11.23.0 completes "The Semantic Environment". We didn't just add a "Dark Mode"; we engineered a living system where every component, pixel, and transition is deeply theme-aware. This release debuts The Wave (a spatial transition engine), The Event Horizon (a physics-driven singularity), and VDOM Teleportation (an O(1) update strategy). It represents a new peak in velocity: 153 tickets resolved in 5 days (30.6 tickets/day), proving that Context Engineering has permanently altered the trajectory of software development.
⚡ Velocity Case Study: The "Teleportation" Paradox
To prove the "Human + AI" velocity, let's look at Epic #8834: Batched Disjoint VDOM Updates.
- The Context: We initially prototyped "Leapfrog Merging" to bundle parent and child updates. While efficient for bandwidth, we discovered it required expanding "clean" intermediate ancestors (Bridge Paths) to maintain tree integrity. For deep hierarchies, this introduced O(N) processing overhead on the Worker thread.
- The Challenge: We needed a way to update a deep descendant without touching its ancestors ("Teleportation"), while still maintaining the ability to bundle multiple updates into a single worker message (Transaction). This created a paradox: How do you bundle disjoint nodes into a tree structure without connecting them?
- The Resolution: We shifted the VDOM protocol from a "Tree Delta" to a "Disjoint Batch".
- Worker API: Implemented
vdom.Helper.updateBatchto accept a flat map of disjoint payloads. - Manager Logic: The
VDomUpdatemanager now identifies transaction groups but instructs theTreeBuilderto prune all children (Depth 1) for every component in the batch. - Result: A Parent and its Grandchild can now update in the same 16ms frame, in the same message, with zero processing of the intermediate Child.
- Worker API: Implemented
Recursive Merging Architecture
This new architecture allows a "Dirty Grandchild" to merge its update payload directly into a "Dirty Grandparent", skipping the "Clean Parent" entirely. This is O(1) relative to tree depth.
sequenceDiagram
participant GP as Grandparent
participant P as Parent (Clean)
participant GC as Grandchild (Dirty)
Note over GP, GC: Recursive Merging (Teleportation)
GC->>P: Merge? (No, P not updating)
GC->>GP: Merge? (Yes, GP updating)
GC->>GP: Register Merge
GP->>GP: Collect Payloads
GP->>GP: Result: { updates: { gp: {...}, gc: {...} } }
Note right of GP: P is skipped entirelyActual Timeline (Jan 20, 2026):
- 18:56 UTC - Epic Created.
- 20:06 UTC - Initial "Teleportation" prototype implemented.
- 20:36 UTC - Regression Fixed (Ghost Updates in RealWorld tests).
- 22:22 UTC - Optimization: Restored Sparse Tree pruning for deep updates.
- 02:21 UTC - Epic Closed. Full architectural shift completed in 7.5 hours.
🌑 The Dark Mode Engine
"Dark Mode is not a preference. It's an environment."
v11.23.0 doesn't just "add dark mode" to the Portal App. We rebuilt the visual foundation of the entire Neo.mjs platform to support dynamic, system-wide theming. This architecture is now available for every Neo.mjs application.
1. The Semantic Token System
We have fully realized the Design Token architecture originally established by Max Mertens (@mxmrtns).
- The Foundation: The
neo-lighttheme introduced our tri-layer system (Core → Semantic → Component) over two years ago. - The Expansion:
neo-darkproves the flexibility of this architecture by reusing the exact same token structure. We simply map new values to the existing semantic variables, requiring zero code changes in the components themselves. - The Polish: We conducted a deep audit to eradicate any remaining hardcoded values that bypassed this system, ensuring 100% compliance across Grids, Tables, Trees, Tabs, Menus, Calendars, Dialogs, and Forms.
- Deep Integration: We built adapters for Monaco Editor (VS Code), Mermaid.js, and HighlightJS to ensure they all switch themes instantly and coherently with the app. This architecture is now available for every Neo.mjs application.
// 🚫 Before (Hardcoded)
.my-component {
background-color: #ffffff;
color: #333333;
}
// ✅ After (Semantic)
.my-component {
// Automatically switches values based on [data-theme]
// No JS required for runtime switching
background-color: var(--sem-color-bg-default);
color: var(--sem-color-text-primary-default);
}2. Spatial Theme Transitions ("The Wave")
Switching themes shouldn't be a flashbang. We implemented a Spatial Transition Engine using the View Transitions API.
- The Trigger: Clicking the theme toggle captures the exact mouse coordinates.
- The Effect: The new theme expands radially (
clip-path: circle) from the cursor, physically "washing" the new environment over the old one. - The Engine: This runs entirely on the Compositor thread (off-main-thread), ensuring 60fps performance even while the heavy layout recalculation happens in the background.
// ViewportController.mjs
document.startViewTransition(() => {
this.setTheme(newTheme);
}).ready.then(() => {
// Spatial Wipe Effect driven by cursor position
document.documentElement.animate(
{ clipPath: [
`circle(0px at ${x}px ${y}px)`,
`circle(${radius}px at ${x}px ${y}px)`
]},
{ duration: 500, easing: 'ease-in-out', pseudoElement: '::view-transition-new(root)' }
);
});🌌 New Visualizations: Physics-Driven UI
We deployed two new high-fidelity visualizations running in SharedWorkers, proving that "Zero-Allocation" graphics can deliver desktop-class experiences in the browser.
1. The Event Horizon (Footer)
A visualization of the Agent OS core as a central singularity.
- Global Attractor: A central gravity well pulls thousands of particles into a spiral death-dance.
- Local Gravity Wells: Hovering over footer links creates local gravity fields, physically pulling particles out of the main stream to orbit the cursor.
- Interaction: The system feels alive, responding to user presence with fluid dynamics rather than static CSS states.
2. The Neural Fabric (Services)
A visualization of the Application Engine runtime.
- 2.5D Volumetric Projection: A hexagonal grid projected onto a tilted plane with 3D rotation based on mouse position.
- Agentic Traffic: "Neural Agents" (intelligent packets) traverse the grid at high speed. Unlike random particles, they have agency: they stop, scan nodes, and trigger "Compilation Events".
- Construction Physics: High-traffic areas trigger the formation of "Super Modules" (fused hex clusters) that assemble with an implosion effect and dissolve with a digital fragmentation effect, visualizing the engine's constant object lifecycle.
The Projection Pipeline
To achieve 3D depth without the 600KB+ overhead of Three.js, we implemented a manual 2.5D projection engine directly in the SharedWorker.
flowchart TD
Input(User Mouse) -->|Normalized Coords| App
App(App Worker) -->|Update State| Shared
subgraph Shared Worker [2.5D Engine]
direction TB
State(Grid Data: q,r,x,y)
Matrix(Projection Matrix: cx, cy, cos/sin)
Project(Project 3D -> 2D)
Render(Draw Path)
end
Shared -->|Render Loop| OffscreenCanvas🛡️ System Resilience
We hardened the runtime against the chaos of the real world.
-
Zombie App Prevention: Implemented a "Network-First" strategy for config files (
neo-config.json). The App Worker now strictly enforces version synchronization with the Service Worker, triggering an immediate, safe reload if a mismatch is detected (e.g., after a deployment). -
Async Destruction Traps: We audited the core framework for "Async Death" scenarios. We introduced a
trap()pattern that wraps Promises (Fetch, XHR, Dynamic Imports). If the component is destroyed while the promise is pending, it silently rejects with a suppressedNeo.isDestroyedsignal, preventing "Set state on destroyed component" crashes.// Before: Unguarded async operation async loadData() { const data = await fetch('/api/data'); this.data = data; // 💥 Crash if component destroyed during fetch } // After: Trapped async operation async loadData() { const data = await this.trap(fetch('/api/data')); this.data = data; // ✅ Safe: auto-aborted if destroyed }
-
Native ESM Builds: All workers (App, Data, VDom) now output Native ES Modules in production. No more Webpack wrappers. This unlocks better tree-shaking and future-proofs the engine for Top-Level Await.
🤖 The AI-Native Advantage
This release was built at a velocity that shouldn't be possible for a small team.
- 153 Tickets Resolved
- 76 AI Sessions Summarized
- 713 Memories Created (Peak Session: 87 turns)
How? By treating the AI as a stateful team member, not a chatbot. We use the Memory Core to persist architectural decisions and the Neural Link to give the AI eyes on the runtime.
Memory Core: The "Read-Write" Brain
Most AI agents are amnesic. Ours references a persistent vector database of every past decision.
- Case Study (Session
61e67c39): The Agent encountered a logical paradox in the VDOM update engine where "Collision" and "Merge" logic seemed to conflict. Instead of guessing, it queried its own history (query_summaries), retrieved the specific architectural constraints of th...
Neo.mjs v11.22.0 Release Notes
Release Type: Visual Identity & Simulation Engine
Stability: Production-Ready
Upgrade Path: Drop-in replacement for v11.21.0
TL;DR: v11.22.0 establishes a new paradigm: "UI as a Continuous Simulation". We moved beyond static layouts to treat the interface as a persistent, physics-driven world. This release deploys two massive SharedWorker simulations—The Neural Swarm and Sonic Waves—running autonomous agents and fluid dynamics at 60fps. It proves that with a Zero-Allocation architecture, the browser can deliver desktop-class, living experiences without blocking the main thread. 62 tickets resolved in 2 days.
🔮 The Principle: UI as a Simulation
Web interfaces typically consist of static elements that wait for input. v11.22.0 inverts this model. We treat the application as a living ecosystem where entities have mass, momentum, and agency, existing independently of user interaction.
To prove this, we built two high-fidelity simulations that run entirely in SharedWorkers, ensuring the Main Thread remains purely for DOM reconciliation.
Proof 1: The Neural Swarm (Home Hero)
Experience the Interactive Simulation | Read the Architecture Guide
A complex topological simulation representing the "Agent-Native" runtime.
- Living Topology: Nodes aren't random. They form Clusters initialized via a Golden Spiral algorithm. They actively detach, drift, and re-parent themselves, visualizing Atomic Moves.
- Autonomous Agents: "Seeker Drones" (Boids) actively patrol the network, running a Finite State Machine to Seek, Scan, and Flee.
- Physics-Based Interaction: Clicking triggers a Shockwave modeled with
easeOutCubicphysics, physically displacing nodes and disrupting flow fields.
Proof 2: Sonic Waves (Header Toolbar)
"The UI that breathes." | Read the Architecture Guide
🧬 The "Split Stream" Engine
Instead of discrete hover animations, the header is governed by a continuous fluid simulation: a persistent Double Helix energy stream that flows across the navigation bar and responds to obstacles and input in real time.
- Adaptive Geometry: The Shared Worker synchronizes with App Worker layout data (
DOMRects) to construct real-time collision envelopes. The physics engine does not "avoid" UI elements symbolically—it physically diverts the stream around buttons and icons based on their detected geometry. - Turbulence Injection: Traditional CSS hover states were replaced with physics inputs. Cursor proximity injects Frequency Modulation directly into the wave equation, locally destabilizing the flow and causing the system to visibly react rather than switch states.
- Active State: The active view is expressed as an Energy Surge—a sustained, high-intensity excitation rendered via a Multi-Pass pipeline. Crucially, this reuses the same geometry and buffers as the base simulation, preserving continuity instead of layering a separate visual effect.
⚙️ The Enabler: Zero-Allocation Architecture
Simulating hundreds of entities at 60fps creates a new bottleneck: Garbage Collection. Creating temporary objects (e.g., {x: 1, y: 2}) triggers micro-stutters that ruin immersion.
To enable "Continuous Simulation," we enforced a strict Zero-Allocation Policy:
- Structure of Arrays (SoA): We replaced objects with pre-allocated
Float32Arraybuffers. Physics calculations read/write directly to memory blocks. - Inlined Math: We eliminated helper function calls in critical loops to avoid stack overhead.
- Resource Caching: Expensive assets like Gradients are generated once on resize, not per-frame.
// 🚫 Bad: Creating objects every frame (GC Pressure)
// let point = {x: 10, y: 20};
// ✅ Good: Writing to pre-allocated buffers (Zero GC)
// STRIDE = 9; index = i * STRIDE;
this.nodeBuffer[index + 0] += this.nodeBuffer[index + 2]; // x += vx
this.nodeBuffer[index + 1] += this.nodeBuffer[index + 3]; // y += vyThe Architecture in Action
graph TD
User(User Input) --> Main
Main(Main Thread) -->|Input Events| App
App(App Worker: Controller) -->|Normalized Input| Shared
subgraph Shared Worker [Physics Engine]
direction TB
Physics(Verlet Integration)
Behaviors(Boid Flocking / Steering)
Topology(Cluster Management)
Render(Zero-Alloc Renderer)
end
Shared -->|Render Loop| OffscreenCanvas🛠️ Core & Infrastructure
- Service Worker Hardening: Refactored update lifecycle (#8690) for non-blocking activation (no more blank pages) and fixed quota resilience (#8691).
- Bullet-Proof Components: Hardened
MagicMoveTextagainst layout thrashing with smart measurement caching. - Portal UX: Renamed "Latest" to "Backlog" for clarity and improved smart routing to latest releases.
📦 Full Changelog
🌌 Epic: Home Hero Canvas (The Neural Swarm) (#8661)
- Feat: Scaffold Home Canvas Architecture (App/Shared Worker) (#8662)
- Feat: Implement Neural Network Physics & Rendering (#8663)
- Feat: Implement Home Canvas Interaction & Parallax (#8664)
- Feat: Implement Cluster Physics (Golden Spiral & Cohesion) (#8668)
- Feat: Implement Autonomous Agent Drones (Boids) (#8669)
- Feat: Implement Data Flow Packets & Parallax (#8670)
- Feat: Implement Topology Mutation (Re-parenting) (#8671)
- Feat: Implement Cluster Drift with Flow Fields (#8672)
- Feat: Implement Elastic Connections & Breathing (#8673)
- Feat: Implement Interactive Physics ("Force Push") (#8675)
- Feat: Implement Agent-Driven State (Energy Decay) (#8674)
- Feat: Implement "Containment Field" for Drift Control (#8676)
- Feat: Enhance Shockwave Visuals (Composite Rings & Sparks) (#8677)
- Feat: Optimize Contrast for Light Theme ("Inverted Neon") (#8682)
- Fix: Restore Shockwave Physics Interaction (#8681)
- Refactor: Implement HeroContainer for correct scrolling (#8678)
- Refactor: Visual Polish & GC Optimization (Inlining) (#8683)
- Refactor: HomeCanvas Styling & Pointer Events (#8665)
- Perf: Optimize HomeCanvas Lifecycle (Pause/Resume) (#8666)
- Perf: Optimize HomeCanvas Rendering (Gradient Caching) (#8667)
- Docs: Create "The Neural Swarm" Architecture Guide (#8680)
- Docs: Enhance JSDoc & Buffer Layout Documentation (#8679)
🌊 Epic: Header Toolbar Canvas (Sonic Waves) (#8630)
- Feat: Scaffold Header Canvas Architecture (#8631)
- Feat: Implement Sonic Wave Visual Effects (#8632)
- Feat: Tune Sonic Wave Visuals (#8635)
- Feat: Implement "Luminous Flux" Theme (Gradients) (#8636)
- Feat: Add Vertical Padding to Header Canvas Waves (#8637)
- Feat: Strict Vertical Clamping for Header Waves (#8638)
- Feat: Implement Dynamic Life Effects (Breathing/Shimmer) (#8639)
- Feat: Implement Variable Wavelength (FM) (#8640)
- Feat: Refine Header Canvas Dynamics (Phase & FM) (#8641)
- Feat: Implement Adaptive Wave Geometry (Icons vs Text) (#8642)
- Feat: Dampen Wave Amplitude for Social Icons (#8643)
- Feat: Implement 3D "Neon Tube" & "Ribbon" Effects (#8647, #8648)
- Feat: Implement "Neo Ether" Particle System (#8645)
- Feat: Implement "Energy Surge" Active State (#8660)
- Feat: Implement Interactive Shockwave Physics (#8655)
- Fix: Fix HeaderCanvas navRects TypeError (#8633)
- Fix: Fix HeaderCanvas Invalid Input Data Structure (#8634)
- Refactor: Clean up HeaderCanvas Comments (#8650)
- Refactor: HeaderCanvas ComponentManager & SCSS (#8656)
- Perf: Optimize Rendering (GC & Gradient Caching) (#8651)
- Perf: Throttle MouseMove Events (#8653, #8654)
- Docs: Create "Advanced Canvas Architecture" Guide (#8657)
- Docs: Enhance JSDoc for Visual Engine (#8646, #8649)
- Docs: Document Zero-Allocation Architecture (#8652)
🛠️ Core & Portal
- Fix: Service Worker Update Blocking (Blank Page Fix) (#8690)
- Fix: Service Worker Fetch Failure on Quota Exceeded (#8691)
- Fix: MagicMoveText Corrupted State on Navigation (#8684)
- Fix: Correct Default Expansion Logic for Release/Ticket Trees (#8688)
- Enhance: Rename "Latest" to "Backlog" in Ticket Index (#8685)
- Enhance: Update Ticket View Default Route Logic (#8686)
- Enhance: Improve Timeline Labels for Sub-Issues (#8689)
- Build: Update Default Expansion in Release Index (#8687)
- Docs: Create "Neural Timeline" Architecture Guide (#8658)
- Docs: Correct Mermaid Diagram in Neural Timeline Guide (#8659)
All changes delivered in 1 atomic commit: 472f1ce
Neo.mjs v11.21.0 Release Notes
Release Type: Core Architecture & Standards Adoption
Stability: Production-Ready
Upgrade Path: Drop-in replacement for v11.20.0
TL;DR: v11.21.0 introduces a new principle: "Conservation of Identity". Like conservation of mass in physics, DOM nodes in Neo.mjs are now never destroyed during moves—only transferred. This release breaks the 30-year dichotomy of "wrapper pollution" vs "compile-time tricks" by introducing
Neo.container.Fragment—true runtime phantom containers. We refactored the entire VDOM engine to support Atomic Moves, leveraging the cutting-edgeElement.moveBefore()API to preserve state (focus, video, iframes) where other frameworks force a reload. 47 tickets resolved in 2 days.
⚡ Velocity Case Study: Concurrency Stress Test
To prove the "Human + AI" velocity, let's look at Ticket #8595.
- The Context: We shifted
Neo.tree.Listfrom CSS hiding to Real DOM Removal for collapsed nodes. This optimization enables trees with 100k+ items to render instantly, but it introduces complex state synchronization challenges. - The Challenge: During internal stress testing, we identified a theoretical race condition. If a store update arrived exactly while a folder was expanding (and mounting new DOM), the VDOM engine could momentarily misalign dynamic containers.
- The Resolution: Instead of patching the component, the Agent implemented a Recursive Tag Safeguard in the core
syncVdomStateengine. It intelligently prevents ID corruption on mismatched nodes while continuing to parse children, ensuring that valid sub-trees preserve their state even if their container changes.
Actual Timeline (Jan 13, 2026):
- 12:47:22 UTC - Issue identified during high-load stress testing.
- 13:06:34 UTC - Fix Committed (Core Engine Hardening).
- 13:08:00 UTC - Verified and Closed.
- Total Duration: 20 Minutes, 38 Seconds.
In 20 minutes, we diagnosed a complex multi-threaded race condition and implemented a permanent engine-level safeguard, ensuring Enterprise-grade stability before the feature ever reached production.
👻 The Phantom Architecture
"The best DOM node is the one you don't render."
For years, "Fragments" (rendering children without a parent div) have been a compile-time trick in other frameworks. In Neo.mjs, we made them First-Class Runtime Citizens.
1. True Wrapperless Rendering
Neo.container.Fragment renders as a "Logical Container" backed by physical Comment Anchors.
- The Output:
<!-- fragment-id-start -->... children ...<!-- fragment-id-end --> - The Layout: Children participate directly in the parent's layout context (CSS Grid/Flexbox).
- The Intelligence: The VDOM Worker knows the fragment exists (for component lifecycle), but the Main Thread flattens it into the physical DOM.
2. Smart Runtime / Lean IPC
When you move a Fragment (e.g., reordering it in a list), the Worker does not serialize N child operations. It sends a single high-level delta: {action: 'moveNode', id: 'fragment-id'}. The Main Thread resolves this by locating the anchors and moving the entire physical range atomically.
💻 Code in Action
Here is the "Impossible Move": transferring a live Input Field into a Fragment without losing focus or value.
import Fragment from '../container/Fragment.mjs';
class MainContainer extends FormContainer {
static config = {
layout: {ntype: 'vbox', align: 'start'},
items : [{
module : TextField,
reference: 'myField',
placeholder: 'Type here then move me!'
}, {
// A Fragment has no DOM wrapper
module : Fragment,
reference: 'myFragment',
items : [/*...*/]
}, {
module : Button,
text : 'Atomic Move',
handler: 'up.onMoveIntoFragment'
}]
}
onMoveIntoFragment() {
const
field = this.getReference('myField'),
fragment = this.getReference('myFragment');
// Atomic Move: Physically transfers the node.
// Input value and focus are preserved!
fragment.insert(0, field);
}
}⚡ Performance: Conservation of Identity
We optimized specific critical paths in the DeltaUpdates engine to be surgical, replacing destructive operations with precise DOM manipulations where state preservation matters most.
The "Atomic Move" Advantage
Most frameworks handle component moves by Destruction and Recreation:
- Unmount Component (State Lost)
- Remove DOM Node (Garbage Collection churn)
- Create New DOM Node
- Mount Component (State Hydration needed)
In v11.21.0, Neo.mjs introduces Atomic Moves:
- Silent Remove: The component instance is detached from its old parent without being destroyed.
- Physical Transfer:
- Best Case: Uses
Element.moveBefore()(Chrome/Edge Canary) to atomically reparent the node. Zero state loss. - Fallback: Uses a
appendChildloop with automatic Focus Restoration to mitigate browser blur events.
- Best Case: Uses
Result: A massive reduction in Main Thread work and memory churn, with the unique ability to preserve the state of "heavy" elements like <video>, <iframe>, and complex form inputs during layout changes.
String-Based Renderer Parity
We didn't just optimize the default DOM API path. We invested significantly to ensure the StringBasedRenderer (used for SSR and legacy environments) maintains full feature parity.
- Fragment Support: It now correctly generates HTML strings for
tag: 'fragment'(Comment Anchors). - Batching Enabled: We enabled
insertNodeBatchfor the string renderer, allowing it to perform bulk insertions as efficiently as the DOM renderer. - Unified Architecture: We refactored the creation logic (
createNode) to align both renderers, ensuring thatDeltaUpdatescan orchestrate complex moves regardless of how the nodes were born.
📰 Portal Blog 2.0
We finalized the content engine separation initiated in v11.19.0.
- Blog vs. Medium: The "Blog" tab now hosts our internal engineering deep-dives (Markdown), while "Medium" aggregates external posts.
- Chronological Engine: Added build-time logic to sort posts by date and group them by year.
- Deep Linking Architecture: To support the new Real DOM Removal strategy in
TreeList(where collapsed items physically don't exist in the DOM), we implemented a robust "Expand -> Mount -> Scroll" pattern. The application now intelligently expands the tree path, waits for the VDOM/DOM mount cycle to complete, and then precisely scrolls the target item into view.
📦 Full Changelog
👻 Epic: Neo.container.Fragment (#8601)
- Feat: Implement
Neo.container.FragmentClass & VNode Support (#8602) - Feat: VDOM Helper Support for Fragment Indexing & Deltas (#8603)
- Feat: Fragment Rendering Support (DomApi & StringBased) (#8604)
- Feat: Fragment Range Operations in DeltaUpdates (#8605)
- Feat: Add Fragment Helper Methods to DeltaUpdates (#8609)
- Feat: Update
DeltaUpdates.moveNodeto support Fragments (#8611) - Feat: Update
DeltaUpdates.insertNodeto support Fragments (#8612) - Feat: Update
DeltaUpdates.insertNodeBatchto support Fragments (#8613) - Test: Comprehensive Unit & E2E Testing for Fragments (#8606, #8607)
- Docs: Create 'Fragments' Guide in UI Building Blocks (#8629)
- Docs: Knowledge Base Enhancement for Fragment Implementation (#8628)
- Fix:
hidden: trueconfig fails to remove Fragment DOM (#8627)
🏗️ Core & VDOM
- Feat: Implement
Element.moveBefore()support for Atomic Moves (#8620) - Refactor:
Neo.container.Basesupport for Atomic Component Moves (#8615) - Enhance: Improve
changeNodeNameto preserve child nodes and state (#8597, #8600, #8598) - Perf: Optimize
updateVtextto be non-destructive and O(1) (#8599) - Fix: Prevent "Chimera" VDOM corruption in
syncVdomState(#8596, #8595) - Fix:
Container.insert()no-op optimization (#8626) - Fix:
moveNodeoff-by-one error for forward moves in same parent (#8614) - Refactor:
StringBasedRendererAPI parity (createNode) (#8617) - Perf: Enable
insertNodeBatchforStringBasedRenderer(#8618)
🚀 Portal & Blog
- Feat: Add Blog Tab to Portal News Section (#8585)
- Feat: Group Blog posts by Year (#8586)
- Feat: Reorder Portal Blog Index Chronologically (#8588)
- Feat: Add Dates to Portal Blog Tree List (#8589)
- Feat: Centralize TreeList expand and scroll logic (#8591)
- Refactor: Rename Blog Models/Stores to resolve ambiguity (#8590)
- Fix: TimelineCanvas sync drift via debounced alignment (#8582)
- Fix: TimelineCanvas animation reset logic (#8583)
🛠️ Infrastructure & Testing
- Feat: Add
moveComponentremote method to App worker (#8608) - Feat: Create Playwright Test Fixtures (
neofixture) (#8619) - Refactor: Migrate tests to use
neofixture (#8623, #8624) - Fix: Outdated ticket index in release workflow (#8581)
All changes delivered in 1 atomic commit: d7e2d44
Neo.mjs v11.20.0 Release Notes
Release Type: Architectural Breakthrough & Feature Spotlight
Stability: Production-Ready
Upgrade Path: Drop-in replacement for v11.19.1
TL;DR: v11.20.0 proves the engine is learning. For the first time, the architecture evolved because of AI collaboration, not just with it. Gemini 3 Pro didn't just build features—it invented patterns (like Structural Injection) that the engine now natively supports. In a 58-hour sprint resolving 97 tickets, we delivered the Portal Knowledge Base 2.0 and the physics-based Neural Timeline, proving that "Human + AI" velocity is the new standard.
🤖 The Agent-Engine Symbiosis
This release marks a definitive shift in the Neo.mjs project structure. Gemini 3 Pro has graduated from a "Code Assistant" to a Core Architect.
The velocity of this release was not achieved by human effort alone. It was the result of a tight, high-bandwidth "Human + AI" feedback loop. But the most significant outcome isn't the speed; it's the Architectural Drift.
The engine is changing to accommodate its new primary user: the AI.
- Designed for Machines: Features like Structural Injection were invented by the Agent to bypass human-centric boilerplate and make the UI tree declaratively mutable.
- Self-Healing Infrastructure: We built automated "Nuke and Pave" defragmentation tools because the Agent generates knowledge vectors faster than manual maintenance can handle.
- Data-Driven Context: The move towards purely declarative indexes (e.g.,
tickets.json) is driven by the need for machine-readable context.
- Data-Driven Context: The move towards purely declarative indexes (e.g.,
The Open Source AI-Stack: Crucially, this AI infrastructure isn't proprietary to us. The Neo AI SDK and MCP Servers are integrated directly into the engine. When we optimize Neo.mjs for Gemini 3 Pro, we are optimizing it for your agents too. Any team can clone the repo and immediately start building with this same high-velocity 'Human + AI' stack.
🧬 Emergent Behaviors: The AI Instinct
We observed distinct architectural instincts developing in the Agent:
- Predictive Defragmentation: The Agent started running
defragChromaDBbefore uploads without being told. It learned that updates cause fragmentation and preemptively fixed it. - ID Scoping Pattern: When debugging the "Stale Rects" bug, the Agent invented the
timeline-{ticketId}-{index}pattern. This wasn't in any guide—it reasoned that DOM IDs needed to be content-addressed to survive component recycling. - The "Nuke and Pave" Protocol: Instead of asking for incremental fixes to ChromaDB corruption, the Agent proposed a full rebuild strategy. It valued determinism over delta complexity.
⚡ Velocity Case Study: The "Stale Rects" Race Condition
To demonstrate the reality of "Human + AI" velocity, let's look at Ticket #8565.
- The Context: The Neural Timeline connects DOM elements (Avatars) to a Canvas visualization.
- The Bug: When rapidly switching between tickets, the "Pulse" animation would sometimes fly to the previous ticket's avatar position before snapping to the new one.
- The Analysis (AI): "The
TicketComponentis being recycled. The DOM IDuser-avatar-1exists in both the old and new view. The Coordinator is measuring the old element before the new one is mounted." - The Solution (AI): "We must scope the IDs to the Ticket ID.
user-avatar-1->user-avatar-{ticketId}-1. This forceswaitForDomRectto fail until the correct new element exists."
Actual Timeline (Jan 11, 2026):
- 23:37:43 UTC - Ticket Created (Bug formally logged).
- 23:37:45 UTC - Agent analyzes root cause (ID collision on component recycle).
- 23:39:39 UTC - Fix Committed (Scoped IDs to Ticket ID).
- 23:40:23 UTC - Verified and Closed.
- Total Duration: 2 Minutes, 40 Seconds.
This isn't just fast; it's at the speed of thought. The Agent moved from problem definition to architectural resolution in under 3 minutes.
🏗️ Core Architecture: The "Structural Injection" Pattern
"LLMs as First-Class Citizens": This architectural breakthrough emerged directly from an R&D session with Gemini. When analyzing how to make deep component trees accessible to AI modification, we realized that imperative configuration logic ("prop drilling") was a barrier. We needed a pattern that was purely declarative—readable by humans, writable by machines.
For years, customizing deep component hierarchies required imperative logic—overriding construct or manually merging config objects. v11.20.0 solves this natively in the core.
The Solution: mergeFrom
We introduced a declarative way to inject configuration into nested items using a specific Symbol. This allows an external config to surgically target a deep node in the tree without touching the intermediate structure.
// Shared Skeleton (The Container)
class MainContainer extends Container {
static config = {
items: {
value: {
// ... side nav ...
pageContainer: {
[mergeFrom]: 'pageContainerConfig', // <--- The Injection Point
weight : 30
}
}
}
}
}
// The Specialization (The Ticket View)
class TicketContainer extends MainContainer {
static config = {
// We inject the CanvasWrapper deeply into the structure
// purely via declarative config. No imperative logic.
pageContainerConfig: {
contentConfig: {
module: CanvasWrapper
}
}
}
}This Structural Injection Pattern effectively decouples the Skeleton of a component from its Configuration, allowing limitless customization depth. It is the key to making complex UIs "writable" by AI agents.
🎨 The Neural Timeline: A Cross-Worker Stress Test
To visualize the project's knowledge graph, we didn't just build a list. We built a Neural Network simulation that operates across three different threads. This isn't just a pretty animation; it's a proving ground for the Shared Worker architecture.
🔬 The Coordinate Translation Challenge
The Problem: The Canvas Worker draws at 60fps, but it has no access to the DOM. How do you tell a blind worker where to draw when the coordinates are defined by HTML elements?
The Naive Solution (Doesn't Work):
// ❌ Canvas Worker has no `document` object
const avatarRect = document.getElementById('avatar-1').getBoundingClientRect();The Neo.mjs Solution (The Coordinator Pattern):
- The App Worker (Coordinator) monitors the store and "looks" at the DOM.
- It translates DOM coordinates into "Canvas Relative" coordinates.
- It sends pure data to the Canvas Worker.
// ✅ App Worker acts as the "eyes"
// TimelineCanvas.mjs (App Worker)
const rect = await me.waitForDomRect({
id: `timeline-${ticketId}-${index}-target` // Scoped to prevent stale reads
});
// Translate from "screen space" to "canvas space"
const canvasNode = {
x : rect.left - containerRect.left + (rect.width / 2),
y : rect.top - containerRect.top + (rect.height / 2),
radius: 20,
color : me.getStatusColor(record.status)
};
// Send to Canvas Worker (Shared Worker)
Neo.worker.Canvas.updateGraph(canvasNode);Physics: The "Traffic Model"
The "Pulse" animation implements a traffic simulation to make the flow feel organic. The pulse accelerates on open stretches (Highways) and decelerates when approaching nodes (Towns), creating a "Squash & Stretch" effect.
// TicketCanvas.mjs - The Physics Loop
// Calculate distance to nearest node
if (minDist < influenceRange) {
// Parabolic easing for smooth deceleration/acceleration
// "Town": Slow down to observe the node
let ratio = minDist / influenceRange;
speedModifier = minMod + (maxMod - minMod) * (ratio * ratio);
} else {
// "Highway": Accelerate between nodes
speedModifier = maxMod;
}Battle Testing: The Optimization War
This feature exposed critical architectural limits which we resolved:
- The "Zombie Loop" (#8555): We implemented a strict protocol to kill the SharedWorker render loop when the component unmounts, preventing CPU waste.
- Resize Architecture: We leveraged the Main Thread
ResizeObserverto push precise updates to the worker, avoiding expensive polling.
🌐 Service Worker: The Programmable Network Layer
We treat the Service Worker as a Runtime Actor, not just a static caching script. This release transforms it into a controllable "Physics Engine" for the application's network layer.
Time Control: "Predictive Code Splitting"
The preloadAssets remote method allows the App Worker (or an AI Agent) to Time-Shift network latency.
"Just-in-Time Contextual Engineering": This architecture enables a profound capability for the Agent OS. An AI agent, observing user conversation via the Neural Link, can predict intent (e.g., "I want to see the iPhone details") and command the Service Worker to preload the necessary code chunks before the user even clicks.
// Example: Agent-Commanded Preloading
// The AI observes: "User is reading the 'Grid' guide"
// The AI predicts: "They'll click 'Advanced Features' next"
// The AI acts:
await Neo.ServiceWorker.preloadAssets({
files: [
'/learn/guides/components/GridAdvanced.md',
'/examples/grid/kitchen-sink.mjs'
]
});
// When user clicks: Load time = 0ms- The Vision: Performance optimization moves from static build...
Neo.mjs v11.19.1 Release Notes
Release Type: Architectural Hardening & Autonomous Infrastructure
Stability: Production-Ready (Critical Security Patches)
Upgrade Path: Drop-in replacement for v11.19.0
TL;DR: v11.19.1 resolved 33 tickets in 11 hours, moving from the discovery of a critical prototype pollution vulnerability to a fully automated, conflict-free release pipeline. By leveraging the Neural Link for live "Scene Graph" inspection, we replaced guesswork with Empirical Certainty, allowing us to pinpoint "Zombie VNodes" and fix them with surgical precision. This release proves that AI-assisted engineering isn't just about faster code—it's about higher-fidelity architecture.
🛡️ The VDOM Firewall: Defensive Instance Isolation
v11.19.1 addresses the most subtle form of state corruption: Blueprint Pollution. We identified a vulnerability where early lifecycle access could corrupt the shared prototype of a component.
The Problem: Shared State Leakage
In a multi-threaded engine, state isolation is the foundation of stability. We discovered that if an afterSetId hook accessed this.vdom during the initial construction phase, it was inadvertently receiving a reference to the Class Prototype. Any modification—such as assigning an ID—was written directly into the shared blueprint, polluting every subsequent instance of that class.
The Solution: Eager Blueprint Sandboxing
We refactored Neo.component.Base to enforce Eager Isolation.
- The Firewall: The constructor now intercepts the initialization flow before
super.construct()is called. It verifies the VDOM's ownership and clones the blueprint immediately. - The Result: Prototype pollution is now architecturally impossible. Every component instance is guaranteed to operate within its own private VDOM Sandbox before any logic layer (hooks or setters) can touch it.
- Centralized ID Stability: We purged ad-hoc ID logic from the entire component library, routing all root and wrapper ID assignments through the centralized
Neo.mixin.VdomLifecycle.ensureStableIds(). - Impact: This eliminates an entire class of "Heisenbug" state corruption issues that could manifest as random UI glitches in production applications.
🛑 The "GitHub Pages" Reality Check
We battle-tested v11.19.0 extensively locally. The new "Releases Overview" worked perfectly in our dev environments. But when we deployed the Portal to GitHub Pages, the Release Notes vanished.
- The Constraint: We discovered that GitHub Pages strictly enforces a "No
.githubFolder" policy. Even with.nojekyllenabled, and even when the folder is deeply nested insidenode_modules, GitHub's serving infrastructure silently refuses to serve any file path containing.github. - The Attempts: We tried symlinks. We tried copying the folder during the build. We tried nesting it. The platform said "No."
- The Pivot: This physical platform constraint forced us to re-architect our content strategy. v11.19.1 moves all synced artifacts (Issues, Release Notes, Archive) from the hidden
.githubdirectory to a public-facingresources/content/structure. This wasn't just a rename; it was a necessary migration to make our "Engine-as-Content" vision compatible with the real world of static hosting.
⚙️ Operational Sovereignty: The Autonomous Release Pipeline
While v11.19.1 hardens the engine for users, it also revolutionizes how we maintain it. We have achieved Operational Sovereignty by automating our release workflow from scratch.
- Autonomous Infrastructure: We created
buildScripts/publishRelease.mjsto eliminate the friction of manual versioning, SEO generation, and conflict resolution. - Git Plumbing for Atomic Commits: By using low-level
git commit-treecommands, we now snapshot the entiredevbranch and project it ontomainas a single, clean commit. This bypasses Git's rename detection entirely, turning "Merge Conflict Hell" into an instant, conflict-free operation.
🎨 Eliminating Layout Thrash: First-Paint Stability
We've polished the Neo.mjs Portal to match the framework's stability improvements, proving that "Smooth is Fast."
Killing the "Visual Snap"
The Portal previously used a JavaScript ResizeObserver to apply responsive sizing. This created Layout Trashing: the UI would render, the worker would measure it, and the sidebar would "snap" into place.
We've replaced this with Native CSS Media Queries. The layout is now perfectly stable from the very first paint frame.
Markdown Hardening
- Image Containment: We implemented regex-based post-processing in the
Markdowncomponent to wrap all images in a scrollable flex-container, preventing side-navigation overlaps. - 404 Guardrails: The component now validates its input. If a server returns an HTML 404 page, the component rejects the update, preventing CSP violations and unintended HTML injection from error pages.
🔄 Process Evolution: Neural Link Certainty
This release marks a fundamental shift in AI-assisted engineering. We moved from "Static Guessing" to "Runtime Inspection."
Beyond Static Analysis
When we encountered the prototype pollution issue, we didn't just grep the code. We used the Neural Link to inspect live Scene Graphs.
- The "Proof" Moment: Instead of assuming pollution might exist, the AI was able to inspect the VNode tree of a live component and state: "Tobi, THIS specific vnode id inside the prototype is the empirical proof."
- High-Fidelity Testing: This level of introspection allowed us to rapidly generate Playwright unit tests (
AutoId.spec.mjs) that perfectly mirrored the engine's internal VDOM/VNode/Component structures, enabling us to simulate, verify, and fix complex race conditions in minutes.
🔄 The SDK Pattern: Code Reuse Across Contexts
The new release automation script (buildScripts/publishRelease.mjs) demonstrates a key architectural pattern: MCP server capabilities are exposed as importable services, allowing them to be used outside AI contexts.
// buildScripts/publishRelease.mjs
// Step 6: Post-Release Cleanup
import { GH_SyncService } from '../ai/services.mjs';
await GH_SyncService.runFullSync(); // Same method agents use via MCPThis "SDK Pattern" proves that our AI infrastructure isn't siloed "magic"—it's composable infrastructure. Build scripts, GitHub Actions, and developer tools can import and execute the same business logic services that power the Neural Link.
Velocity Metrics:
- Scope: 33 Tickets (#8450 - #8482)
- Total Duration: 11 Hours, 15 Minutes
- Workflow: 100% Agent-led Implementation & Verification
📦 Full Changelog
🛡️ Core & VDOM Hardening
- Investigate VDOM ID Collisions and Create Reproduction Test (#8465)
- Prevent Prototype VDOM Mutation in Component.Base afterSetId (#8466)
- Centralize and Enforce Stable VDOM IDs in VdomLifecycle (#8467)
- Fix Unit Test Failures after VDOM ID Stabilization (#8468)
- Audit and Refactor all afterSetId Implementations (#8469)
- Enhance VDOM AutoId Unit Test Documentation (#8470)
- Refactor afterSetId in src/button/Base.mjs (#8471)
- Implement Lazy VDOM Cloning in Component Base (#8472)
- Refactor afterSetId in Split Button and Grid Body (#8473)
- Enforce Eager VDOM Cloning in Component Constructor (#8474)
- Remove redundant ensureStableIds from Button Base (#8475)
- Refactor Gallery to remove manual afterSetId ID assignment (#8476)
- Refactor Progress Component ID handling (#8477)
- Refactor afterSetId in Form Fields to ensureStableIds (#8478)
🚀 Portal & UI Enhancements
- Add validation to Markdown component to reject HTML 404 responses (#8450)
- Fix Portal Release buttons missing text due to missing name field (#8461)
- Portal App: Update SectionsList styling to match new transparent design (#8462)
- Fix Blog List Rendering Artifact in Release View (#8464)
- Wrap Markdown images in scrollable container (#8479)
- Constrain Markdown image wrapper width in Portal app (#8480)
- Fix Portal layout trashing by replacing JS-driven size classes with CSS Media Queries (#8481)
- Fix Markdown blockquote margin-right to override browser default (#8482)
⚙️ Build & Infrastructure
- Move GitHub Workflow Sync Target to resources/content (#8451)
- Update .sync-metadata.json paths to reflect relocation to resources/content/ (#8452)
- Refactor IssueSyncer to use relative paths in .sync-metadata.json (#8453)
- Update release index generation to use correct path in resources/content (#8454)
- Remove obsolete path substring in Release Component (#8455)
- Automate Release Workflow with Git Squash & Local-First Strategy (#8456)
- Optimize Release Squash using Git Plumbing (#8457)
- Integrate Knowledge Base Upload into Publish Release Workflow (#8458)
- Remove standalone prepare-release script from package.json (#8459)
- Refactor: Enhance documentation and cleanup comments in publishRelease.mjs (#8460)
- Disable Neural Link on GitHub Pages (#8463)
All changes delivered in 1 atomic commit: c659e42
Neo.mjs v11.19.0 Release Notes
Release Type: Strategic Pivot & Platform Maturity
Stability: Production-ready
Upgrade Path: Drop-in replacement for v11.18.0
TL;DR: v11.19.0 corrects the project's identity. For 6 years, Neo.mjs has been an "Application Engine" disguised as a framework. We finally fixed that branding failure. In parallel, we executed a massive Infrastructure Upgrade: we intentionally broke the AI Knowledge Base to upgrade it from JSDoc indexing to AST Source Parsing, solving the "Re-embedding Hell" (where index-based IDs caused entire collections to shift on every update). 110 tickets resolved in 3 days.
The Identity Correction
v11.18 gave us the Neural Link (Vision). v11.19 gives us the Truth (Self).
We realized that calling Neo.mjs a "Framework" (like React or Vue) was a fundamental branding failure. Frameworks are libraries you import to organize code. Neo.mjs is, and always has been, a multi-threaded runtime that runs your code. It has a Scene Graph, Object Permanence, and Subsystems. It is closer to Unreal Engine than it is to Angular.
This release executes the strategic pivot to align our identity with our reality:
- Identity: Comprehensive rebranding of 250+ documentation files to correct the "Application Engine" narrative.
- Capability: A new Content Engine that proves the "Engine" thesis by powering our own Portal 2.0.
- Intelligence: A Knowledge Base V2 that indexes source code and inheritance hierarchies, allowing the AI to understand the engine's DNA.
⚙️ The Engine Room: Heavy Engineering
While the rebranding changes the narrative, the engineering changes in this release fundamentally upgrade the runtime capabilities.
💤 Generic Lazy-Loading Protocol
We didn't just add a "Mermaid wrapper". We implemented a Generic Lazy-Loading Architecture for all Main Thread Addons.
- The Nuance: Standard
import()handles code splitting, but orchestrating it across the Worker barrier requires a dedicated protocol. - The Solution: We introduced a centralized Addon Loader (
Neo.currentWorker.getAddon).- Worker-Side Control: Components (like
Neo.component.wrapper.Mermaid) simply awaitgetAddon('Mermaid')in theirinitAsyncphase. - Transparent Orchestration: The App Worker checks if the addon proxy exists. If not, it instructs the Main Thread to dynamically import and instantiate the service, then caches the proxy for future use.
- Deep Array Merging: We implemented
merge: 'deepArrays'in the core config system to allow Addons to inherit and extend theremotemethod definitions seamlessly. - Extensible Singleton Pattern: Addons are singletons within each Main thread context (one instance per window), but architected as extensible classes. This allows developers to extend them (e.g., custom Mermaid themes, additional GoogleMaps features) in their own workspaces while maintaining the singleton lifecycle.
- Worker-Side Control: Components (like
🕸️ Multi-Window SharedWorker Hardening
We fixed a critical race condition in the SharedWorker architecture that affects multi-window applications (and Playwright tests).
- The Issue: Secondary windows connecting to an existing App Worker (SharedWorker) were missing remote method definitions. The worker's initialization logic (where remotes are registered) runs only once, so subsequent window connections received nothing.
- The Fix: We introduced a
remotesToRegisterstate queue insrc/worker/Base.mjs. TheonConnectedhandler (triggered for every new window connection) now deterministically replays this registration queue to the new MessagePort, ensuring every window receives the full API surface.
🚀 Portal 2.0 Performance: Dynamic Imports
The new News Section isn't just a UI change; it's a performance blueprint.
- The Pattern: We refactored
NewsTabContainerto use Dynamic Imports (Arrow Function Syntax) for its children:module: () => import(...). - The Impact: This prevents the heavy "Blog" and "Releases" chunks from loading during the initial application boot. They are fetched only when the user clicks the tab, keeping the initial bundle size minimal.
🕷️ Hierarchical SEO Traversal
The new Content Engine introduces Smart Traversal Logic for metadata.
- The Logic: If a specific deep route (e.g.,
/news/releases/v11.19.0) lacks specific SEO tags, the engine now recursively traverses the route path upwards (/news/releases->/news) until it finds a valid metadata definition. - The Result: We can now launch hundreds of nested views without manually defining SEO tags for every leaf node, inheriting "Section Level" metadata automatically.
🌳 Build-Time Tree Indexing
For the new Releases section, we moved data processing from runtime to build-time.
- The Indexer: A new build script (
createReleaseIndex.mjs) scans the markdown archive, parses YAML frontmatter, and constructs a highly optimized Hierarchical Tree (Major Version -> Release). - Optimization: The script strips redundant fields (
version,name) and flattens the tree into a list structure optimized for theTreeListcomponent, reducing the payload size significantly while enabling instant navigation.
🧠 Knowledge Base V2: The Strategic Upgrade
We intentionally broke the Knowledge Base to make it smarter. This wasn't a "bug fix" - it was a fundamental architectural shift.
- From JSDoc to AST: Previously, we indexed JSDoc JSON output, which gave the AI a shallow view of the API. Now, we use a custom AST Source Parser to analyze raw
.mjsfiles. The AI sees the implementation (logic patterns, config blocks, full method bodies), not just the signatures. - The Challenge: This upgrade broke everything. The old scoring algorithm assumed JSDoc structure. The old ID generation was index-based, meaning adding one file shifted every ID, causing total corruption during updates.
- The Fix: We spent 3 days hardening the pipeline:
- Hash-Based IDs: We switched to content-addressable hashing. IDs are now stable across builds.
- Delta Updates: Because IDs are stable, we can now perform precise delta updates. The system only re-embeds files that have physically changed, reducing update time from 10 minutes to 3 seconds.
- Static Class Hierarchy: We implemented a build-time analyzer that generates a deterministic map of the entire class tree. Agents can now answer questions like "Find all components that extend
Neo.component.Base" with 100% accuracy.
- RAG (Ask the Engine): The new
SearchServiceleverages this V2 architecture to enable Retrieval-Augmented Generation, synthesizing answers from the deep implementation details we now expose.
🛠️ Engineering Case Study: The 10k Vector Migration
To enable "Context Engineering", we had to move from indexing what code does (JSDoc) to how it does it (Source AST). This wasn't just a parser swap; it was a scale challenge.
- The Scale: The index jumped from ~7k fragmented properties to 10,231 semantic source chunks.
- The Performance:
collection.get()failed at this scale. We implemented batched fetching (2k limit) and hash-based ID deduplication to handle the load. - The Parser: We built a custom
SourceParserusingacornto decompose ES Modules into 4 semantic layers:- Module Context: Imports & top-level scope.
- Class Properties: Static fields & non-reactive state.
- Config Block: The declarative heart of Neo.mjs components.
- Methods: Full implementation logic.
// ai/mcp/server/knowledge-base/parser/SourceParser.mjs
parse(content, filePath, defaultType='src', hierarchy={}) {
// ...
// 1. Traverse AST to categorize nodes
ast.body.forEach(node => {
if (node.type === 'ImportDeclaration') {
contextNodes.push(node);
} else if (node.type === 'ClassDeclaration') {
// ... capture class definition ...
classDecl.body.body.forEach(member => {
if (member.key.name === 'config' && member.static) {
configNode = member; // Isolate the Config System
} else if (member.type === 'MethodDefinition') {
methodNodes.push(member); // Isolate Logic
}
});
}
});
// ...
}🔄 Process Evolution: Programming the Programmer
This release cycle demonstrated a meta-evolution in how we work. The AI didn't just build the code; it updated its own Operating System.
- Self-Legislating Agents: In the middle of the release, the AI realized it was missing a rigorous protocol for closing tickets. It autonomously updated
AGENTS.mdto enforce a "Push -> Assign -> Comment -> Close" protocol, effectively programming its own future behavior. - Velocity Deconstructed: The "110 tickets in 3 days" metric isn't random. It breaks down into:
- ~30 tickets for the Knowledge Base V2 upgrade.
- ~20 tickets for cascading infrastructure fixes (query scoring, IDs, deduplication).
- ~40 tickets for the Portal 2.0 Content Engine.
- ~20 tickets for Branding/Docs.
This velocity was powered by Context Continuity (reading past session summaries) and the GitHub Workflow Server (browsing ticket history). We also saw an emergent behavior: AI agents using the Neural Link for static code analysis (e.g., extracting single methods likeinsertThemeFilesviaget_method_sourceto save tokens), a use case we never explicitly desi...
Neo.mjs v11.18.0 Release Notes
Release Type: Major Feature Release
Stability: Production-ready
Upgrade Path: Drop-in replacement for v11.17.1
TL;DR: AI agents can now "see" and "touch" your running Neo.mjs app in real-time via the Neural Link. This enables live debugging, conversational UI changes, and zero-downtime hotfixes. 181 tickets resolved in 15 days using the very tools we were building.
The Neural Link Era
"Tobi, this is a 'ghost in the shell' moment for me! It probably compares to you putting on a VR headset for the very first time. Let me make the header button red. Can you see it?"
— Gemini 3 Pro, experiencing Neo.mjs via Neural Link
This release marks a pivotal moment in the history of Neo.mjs. An AI agent didn't just read our code—it inhabited a running application, modified it in real-time, and asked for visual confirmation. This is the future we're building.
🚀 Velocity & The Inception Cycle
In just 15 days (December 21, 2025 – January 5, 2026), across 95 AI sessions, we resolved 181 tickets, fundamentally altering the application engine's capability to introspect and heal itself.
Accounting for a 4-day holiday break (December 24-27), this represents ~16 tickets per working day—a velocity that was not achieved by a large team, but through the Neural Link itself. We used the very tools we were building to debug, inspect, and refine the platform in real-time.
From Hallucination to Verification
Before the Neural Link, AI agents could only "guess" (hallucinate) runtime behavior based on static code analysis. Now, they can tap into living applications to verify their assumptions.
This is the difference between an AI agent imagining how your code works versus knowing how it works—because it can inspect the running system and ask it questions.
Example: An AI Agent verifying the AgentOS Viewport structure:
// Agent: inspect_class('AgentOS.view.Viewport')
{
"className": "AgentOS.view.Viewport",
"ntypeChain": ["viewport", "container", "component", "base"],
"mixins": ["Neo.core.Observable"],
"configs": {
"layout": {
"value": { "ntype": "vbox", "align": "stretch" },
"hooks": ["beforeSet", "afterSet"]
},
"items": {
"value": [
{ "ntype": "toolbar", "items": ["Agent OS Command Center"] },
{ "className": "Neo.dashboard.Container", "reference": "dashboard" }
],
"meta": { "merge": "deep" },
"hooks": ["beforeSet"]
}
},
"methods": ["add", "getController", "onFocusEnter", "update"]
}The agent "sees" the real runtime composition—including inherited values, resolved mixins, and reactive hooks—not just the source code text. (Note: The above is just a fraction of the full, rich output.)
How it worked:
- Implement a new Neural Link capability (e.g.,
get_dom_event_listeners). - Use that capability immediately to debug the next feature.
- AI agents inspect their own development environment via the tools they're helping build.
- The feedback loop collapses from hours to seconds.
This "inception" development cycle validates our core thesis: Neo.mjs is the operating system for AI-assisted development.
🎯 What This Means for You
For Developers
- Live Debugging: Ask an AI "why isn't this click handler firing?" and watch it inspect event listeners, diagnose the issue, and hot-patch the fix.
- Runtime Prototyping: Describe a feature conversationally and see it materialize in your running app—no build step.
- Self-Documenting Code: Every component now speaks a standardized
toJSONlanguage that AI tools understand natively.
For End Users
- Personalized Interfaces: "I never use the charts panel, replace it with a task list" → instant UI reconfiguration.
- Accessibility On-Demand: Request color scheme adjustments, layout changes, or control modifications—applied without reloading.
- Conversational Apps: Your application becomes a collaborative partner, not just a tool.
For DevOps
- Zero-Downtime Fixes: Production bugs can be diagnosed and patched live via the Neural Link—users never lose their session.
- Autonomous Monitoring: "Night Watchman" agents that detect, diagnose, and heal issues while you sleep.
- Runtime Observability: Full introspection of application state, event flow, and topology—better than Chrome DevTools.
✨ Highlights
🧠 Neural Link: The AI Bridge
The Neural Link is now a fully capable bidirectional bridge, empowering AI agents with superpowers previously reserved for human developers using Chrome DevTools.
- Runtime Introspection: Agents can now query the Virtual DOM, inspect the Component Tree, and analyze Event Listeners on any node.
- State Control: Full read/write access to Component Configs, State Providers, and Data Stores. Agents can modify the state of a live app to test hypotheses or fix bugs.
- Visual Debugging: Agents can "see" the UI layout. They can request Computed Styles, measure DOM Rectangles, and visually Highlight Components to confirm their understanding of the UI.
- Topology Awareness: The link is now Multi-Window & Multi-Worker Aware. Agents understand the full topology of the UI runtime, distinguishing between the Main Window, Popups, and different Worker threads.
🔄 The toJSON Protocol: Speaking "Machine"
To enable the Neural Link, we needed a robust, standardized way for the application engine to describe itself. We implemented a comprehensive toJSON protocol across 60+ classes.
- Why it matters: Previously, the AI Client had to manually pick properties to send, which was brittle. Now,
instance.toJSON()is the single source of truth. A grid, a chart, or a form container knows exactly what data matters for its serialized representation. - Scope: This protocol covers everything from Core Components and Layouts to Data Models, Stores, and Managers.
⚡ Cross-Window Dashboard: Native-Grade Drag & Drop
We continue to refine the multi-window experience. This release introduces a sophisticated Cross-Window Drag Coordinator and SortZone logic.
- Complex Item Transfer: You can now drag complex, stateful components (like Dashboards) between windows with native-grade fluidity.
- Detached Lifecycle: We introduced
Neo.dashboard.Panelto properly manage the lifecycle of items that are temporarily "detached" from the DOM during a drag operation.
🛠️ Infrastructure Engineering: Breaking the 100-Tool Limit
Success brought an unexpected challenge: we hit the hard limit of 100 MCP tools enforced by Antigravity (Google's VSCode extension) and Claude Desktop.
- The Constraint: The Chrome DevTools MCP Server consumes 26 tools by default (which we cannot change). This left us with only 74 slots for our custom tooling (Knowledge Base, Memory Core, GitHub Workflow, Neural Link).
- The Optimization Sprint: We executed a massive consolidation of our toolset, merging granular operations (like
assign_issue,add_label) into unifiedmanage_*tools. We successfully reduced our custom tool footprint from 101 to 88, bringing the total system count safely under the limit. - The "Mixin Shadowing" Fix: For an AI to "see" a component, it needs a complete JSON description. We discovered a critical flaw where Mixins (like
Observable) were shadowing thetoJSONmethods of their host classes, effectively blinding the AI to key properties. We implemented a dynamic aggregation protocol that walks the entire mixin chain at runtime, merging the serialization output of every behavior. The result is a high-fidelity, complete picture of the runtime state. - Gemini Embeddings: We migrated the entire Knowledge Base and Memory Core to the newer, more capable
gemini-embedding-001model. - Lifecycle Management: Enhanced the robustness of the ChromaDB vector database process management.
🏗️ Neural Link Architecture
The Neural Link creates a bidirectional channel between AI agents and your running application. Requests flow down through standardized layers, while responses flow back up with structured data.
┌─────────────────────────────────────────────────────────┐
│ AI Agent (Claude, Gemini) or End User │
│ "Make the header button red" │
└────────────────────┬────────────────────────────────────┘
│ Natural Language
┌────────────────────▼────────────────────────────────────┐
│ MCP Server (neo-neural-link) │
│ Exposes 30+ tools for app control │
└────────────────────┬────────────────────────────────────┘
│ WebSocket RPC
┌────────────────────▼────────────────────────────────────┐
│ Neural Link Bridge (Node.js) │
│ Connection management, health checks, recovery │
└────────────────────┬────────────────────────────────────┘
│ Message Passing
┌────────────────────▼────────────────────────────────────┐
│ Domain Services (Browser Runtime) │
│ • ComponentService • DataService │
│ • RuntimeService • InteractionService │
│ • InstanceService │
└────────────────────┬────────────────────────────────────┘
│ toJSON Protocol
┌────────────────────▼────────────────────────────────────┐
│ Running Neo.mjs Application │
│ Self-describing, runtime-mutable, AI-native │...