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-time guessing to dynamic, runtime certainty.
- Resilience: The method now gracefully handles partial failures (e.g., one missing asset doesn't crash the batch), allowing for robust "best-effort" preloading.
📚 Engineering Case Study: Portal Knowledge Base 2.0
We executed Epic #8398 to fundamentally change how we document the application engine.
The Strategy: "Tickets are Documentation"
Previously, deep technical context was locked away in GitHub Issues. We realized that the "Why" behind every architectural decision lives in the tickets. We extracted a reusable Knowledge Base Engine (apps/portal/view/shared/content/) that now powers the Guides, the Ticket Archive and the Releases Overview.
The Pipeline
We built a robust data ingestion engine (buildScripts/createTicketIndex.mjs) that:
- Parses: Scans thousands of markdown files.
- Filters: Applies a signal-to-noise filter (excluding
chore,task) to ensure only high-value engineering context is indexed. - Structures: Generates a high-performance Tree Index (
tickets.json) enabling instant client-side searching.
🚀 Performance: The "Zero-Lag" Initiative
We executed a "Search and Destroy" mission on Main Thread latency.
- DOM Pruning:
Neo.tree.Listnow usesremoveDom: truefor collapsed nodes. A tree with 10,000 items now renders as fast as a list with 10 items if folders are collapsed. - Passive Listeners: We switched the global
wheellistener topassive: trueto eliminate scroll blocking, while implementing a Hybrid Strategy that allows specific components (like 3D Helix) to opt-in to blocking behavior locally. - Atomic Batching: We implemented Contiguous Batching in
DeltaUpdates.mjs. If 100insertNodeoperations target the same parent, they are now grouped into a singleDocumentFragment, reducing 100 layout reflows to 1.
📦 Full Changelog
🚀 Portal & Neural Timeline
- Feat: Implement Canvas-based "Neural" Timeline Animation (#8536)
- Feat: Implement "Orbit" flow animation and "Conservation of Mass" logic (#8542, #8543)
- Feat: Implement Physics-based "Traffic" animation with Squash & Stretch (#8544)
- Feat: Implement "Chameleon Pulse" with data-driven color interpolation (#8545)
- Feat: Implement "Tickets" View with TreeList navigation (#8505, #8506)
- Feat: Implement Timeline Navigation in Sections List (#8535)
- Feat: Rich HTML Timeline Rendering (Avatars, Events, Comments) (#8529, #8530, #8531)
- Feat: Smart Localized Timestamp Formatting (#8532, #8533)
- Feat: Add Tickets Tab to Portal News Section (#8506)
- Feat: Create Portal.model.Ticket (#8503)
- Feat: Create Portal.store.Tickets (#8504)
- Feat: Create SCSS for Tickets MainContainer (#8507)
- Feat: Implement Text Truncation for Portal TreeList (#8508)
- Feat: Enhance Ticket Markdown Rendering with Badges (#8511)
- Feat: Refactor Ticket Badges to use Dynamic Label Store (#8512)
- Feat: Enhance markdown rendering for ticket sub-issues (#8516)
- Feat: Link ticket author to GitHub profile in Portal (#8517)
- Feat: Use icons for task status in Ticket frontmatter (#8518)
- Feat: Fix vertical alignment of ticket sub-issues (#8519)
- Feat: Enhance Markdown Frontmatter Animation (#8520)
- Feat: Animate Frontmatter Toggle Icon (Rotate Plus to X) (#8521)
- Feat: Use Badge Style for Labels in Ticket Frontmatter (#8522)
- Feat: Implement Ticket Status Badges (Open/Closed) (#8523)
- Feat: Enhance TreeList navigation for internal routing and deep linking (#8524)
- Feat: Add Release badge to Ticket Header for navigation (#8525)
- Feat: Refactor Issue Syncer to use unified timeline (#8527)
- Feat: Enhance Issue Sync with additional timeline events (#8528)
- Feat: Integrate Ticket Body into Timeline view (#8530)
- Feat: Polish Portal Ticket Timeline: Author & Commit Links (#8531)
- Feat: Portal Ticket Timeline: Render Labels as Badges (#8534)
- Fix: Fix sticky folder visual regression in transparent TreeList navigation (#8495)
- Fix: Zombie Canvas Loop on unmount (#8555)
- Fix: Canvas Coordinate Drift using
waitForDomRect(#8536, #8562) - Fix: Timeline content overflow and wrapping (#8557)
- Fix: CSS collision for state badge icons in Tickets view (#8526)
- Fix: TimelineCanvas crash on ticket switch (records.map is not a function) (#8546)
- Fix: Portal App tree navigation scrolling behavior (#8547)
- Fix: Refactor PageContainer for Tickets View (#8548)
- Fix: Fix duplicate listener on TimelineCanvas during navigation (#8549)
- Refactor: TicketCanvas: Performance optimization and cleanup (#8551)
- Enhance: Neural Timeline: Limit spine and pulse to last item (#8556)
- Perf: Optimize TimelineCanvas data load delay (#8559)
- Perf: Prevent race condition in TimelineCanvas by making sections store update optional (#8563)
- Enhance: Reset TicketCanvas animation on data load (#8564)
- Fix: Scope timeline item IDs to Ticket ID to prevent stale rects on switch (#8565)
- Enhance: Change default Portal News route to Releases (#8493)
🏗️ Core & Architecture
- Feat: Native Declarative Config Injection (
mergeFrom) in Container Items (#8571) - Feat: Support Recursive
mergeFrominparseItemConfigs(#8572) - Feat: Enhance
Neo.mergeDeepArraysfor object merging (#8550) - Fix:
Neo.setupClassnon-reactive config descriptor unwrapping (#8569) - Fix: Anchor route regex to prevent unintended prefix matching (#8558)
- Refactor: Portal Shared Containers to use Structural Injection (#8566)
- Refactor: Portal Learn MainContainer to use Structural Injection Pattern (#8573)
- Enhance: Allow subclasses to override config descriptors in Neo.setupClass (#8574)
- Test: Verify Object-based Container Items and Deep Merging (#8568)
⚡ Performance
- Perf: Implement
DocumentFragmentbatching forinsertNode(#8576) - Perf: Refactor
Neo.tree.Listto useremoveDomfor collapsed nodes (#8577) - Perf: Switch global wheel listener to
passive: true(#8578) - Perf: Investigate and Fix Service Worker Cache Update Flakiness (#8494)
- Fix: ServiceWorker missing hasWorker() method causes initRemote failure (#8496)
- Fix: ServiceWorker: Implement Remote Method Broadcast and Replay for Multi-Client Support (#8497)
- Fix: ServiceWorker.preloadAssets crashes on 404s instead of handling errors gracefully (#8498)
- Perf: Replace hardcoded timeout in MainContainerController with deterministic wait (#8560)
- Perf: Remove arbitrary delay in TreeList afterSetCurrentPageRecord (#8561)
- Fix: Fix ListModel keyboard navigation for trees and filtered lists (#8579)
🛠️ Infrastructure & Build
- Feat: Generic ChromaDB Defragmentation Tool (#8485, #8489)
- Feat: Integrate Defrag into Knowledge Base Upload (#8486)
- Feat: Harden and Refactor ChromaDB Defrag Tool (#8490)
- Feat: Add file size measurement to ChromaDB defragmentation tool (#8491)
- Fix: Fix missing error flag in defragChromaDB extraction loop (#8492)
- Feat: Ticket Index Generation Script (#8501)
- Feat: Refine Ticket Index Structure for TreeList (#8502)
- Feat: Optimization: Minify Indices and Prune Release Model (#8509)
- Feat: Include Label Index Generation in Release Process (#8513)
- Refactor: createLabelIndex.mjs to use Commander and enhance JSDoc (#8514)
- Refactor: Neural Link ConnectionService to support autoConnect config (#8515)
- Enhance: Refine GitHub Release Content: Strip Frontmatter and Use H1 as Title (#8483)
- Enhance: Optimize uploadKnowledgeBase script: Early Exit and Robust Cleanup (#8484)
📝 Documentation
- Docs: Create Guide: Declarative Config Merging (#8575)
- Docs: Enhance
Neo.mjsJSDoc regarding core augmentation (#8570) - Docs: Enhance
Neo.tree.ListJSDoc (#8500) - Docs: Enhance
ServiceBase.mjsJSDoc (#8499) - Docs: Enhance
TicketCanvas&TimelineCanvasJSDoc (#8552) - Docs: Enhance
TimelineCanvasDocumentation (#8553) - Docs: Enhance
TicketComponentDocumentation (#8554) - Docs: Add JSDoc to
defragKnowledgeBase.mjs(#8487) - Docs: Add JSDoc to
uploadKnowledgeBase.mjs(#8488) - Docs: Enhance JSDoc for Ticket and Release Index Build Scripts (#8510)
All changes delivered in 1 atomic commit: 647ef14