feat(FN-3155): add createAiSession plugin context API with DI wiring

This merge brings FN-3155's plugin `createAiSession` API (types, DI hooks, engine adapter, context wiring, docs, and tests), FN-3056's task title sanitization, and FN-3129's tokenized footer and mobile initialization for MissionManager. It also adds CentralCore Docker node management, a new AddNodeM

Fusion-Task-Id: FN-3155
This commit is contained in:
Fusion
2026-05-02 13:20:12 -07:00
committed by gsxdsm
parent 2769e4a57b
commit 5ebccc43cc
17 changed files with 540 additions and 122 deletions

View File

@@ -1,5 +1,5 @@
import { useState, useEffect, useRef, useCallback, useMemo, type KeyboardEvent as ReactKeyboardEvent } from "react";
import { Settings, Pause, Play, Square, LayoutGrid, List, Terminal, Lightbulb, Search, X, Activity, MoreHorizontal, Clock, Folder, History, GitBranch, Monitor, Server, Workflow, Bot, Target, ChevronRight, FileCode, Loader2, Grid3X3, Mail, MessageSquare, ChevronDown, Check, Map, Zap, Sparkles, FileText, Brain, CheckSquare } from "lucide-react";
import { Settings, Pause, Play, Square, LayoutGrid, List, Terminal, Lightbulb, Search, X, Activity, MoreHorizontal, Clock, Folder, History, GitBranch, Monitor, Server, Workflow, Bot, Target, ChevronRight, FileCode, Loader2, Grid3X3, Mail, MessageSquare, ChevronDown, Check, Zap, Sparkles, FileText, Brain, CheckSquare } from "lucide-react";
import "./Header.css";
// Header renders an inline ProjectSelector dropdown using project-selector-* classes.
import "./ProjectSelector.css";
@@ -338,19 +338,24 @@ export function Header({
return Object.entries(overflowScripts).sort(([a], [b]) => a.localeCompare(b));
}, [overflowScripts]);
const hasRoadmapsPluginView = useMemo(
() => pluginDashboardViews.some((entry) => entry.pluginId === "fusion-plugin-roadmap"),
[pluginDashboardViews],
);
const hasViewOverflowItems = useMemo(() => {
return !!(
experimentalFeatures?.researchView ||
todosEnabled ||
experimentalFeatures?.insights ||
experimentalFeatures?.roadmap ||
(experimentalFeatures?.roadmap && !hasRoadmapsPluginView) ||
showSkillsTab ||
experimentalFeatures?.memoryView ||
experimentalFeatures?.devServerView ||
!hideFullNav ||
pluginDashboardViews.some((entry) => entry.view.placement !== "primary")
);
}, [experimentalFeatures, todosEnabled, showSkillsTab, hideFullNav, pluginDashboardViews]);
}, [experimentalFeatures, todosEnabled, showSkillsTab, hideFullNav, pluginDashboardViews, hasRoadmapsPluginView]);
const getEffectiveViewport = useCallback(() => {
const vv = window.visualViewport;
@@ -1189,7 +1194,7 @@ export function Header({
<span>Insights</span>
</button>
)}
{experimentalFeatures?.roadmap && (
{experimentalFeatures?.roadmap && !hasRoadmapsPluginView && (
<button
className={`view-toggle-overflow-item${view === "roadmaps" ? " active" : ""}`}
onClick={() => {
@@ -1199,7 +1204,6 @@ export function Header({
role="menuitem"
data-testid="view-overflow-roadmaps"
>
<Map size={14} />
<span>Roadmaps</span>
</button>
)}