Files
fusion/packages/tui/src/index.tsx
gsxdsm 26732e7e43 feat(FN-1719): rebuild eslint baseline and add memory lessons
- Rebuild eslint config with context-aware flat config for better TypeScript/JSX handling
- Add memory lessons for lint/type/test baseline restoration
- Skip pre-existing flaky stream test (flushes a final complete event)
- Fix api.ts require import path
- Add ProjectEngineManager.startReconciliation mock to tests for main compatibility
2026-04-13 18:21:31 -07:00

158 lines
5.4 KiB
TypeScript

/**
* @fusion/tui — Terminal UI components for fn
*
* This package provides Ink-based React components for building terminal
* user interfaces that interact with Fusion task management.
*/
// Re-export FusionContext components and hooks
export { FusionProvider, useFusion, FusionContext } from "./fusion-context.js";
export type { FusionContextValue, FusionProviderProps } from "./fusion-context.js";
// Re-export project detection utility
export { detectProjectDir } from "./project-detect.js";
// Re-export components
export {
ScreenRouter,
SCREENS,
getScreenById,
getScreenIndex,
type ScreenId,
type Screen,
type ScreenRouterProps,
type ScreenComponentProps,
} from "./components/screen-router.js";
export {
ResponsiveHeader,
ResponsiveTable,
ResponsiveTaskRow,
ResponsiveStatusBar,
type TableColumn,
type ResponsiveTableProps,
type ResponsiveTaskRowProps,
} from "./components/responsive-layout.js";
// Re-export global shortcuts hooks
export {
useGlobalShortcuts,
HelpOverlay,
FocusGuardRef,
type UseGlobalShortcutsOptions,
type UseGlobalShortcutsResult,
type HelpOverlayProps,
} from "./hooks/use-global-shortcuts.js";
import React, { useState } from "react";
import { render, Box, Text } from "ink";
import { FusionProvider, useFusion } from "./fusion-context.js";
import { ScreenRouter, type ScreenId } from "./components/screen-router.js";
import { useGlobalShortcuts, HelpOverlay } from "./hooks/use-global-shortcuts.js";
import { ResponsiveHeader, ResponsiveTable, ResponsiveStatusBar } from "./components/responsive-layout.js";
import { fileURLToPath } from "url";
/**
* Demo application showing FusionProvider + ScreenRouter usage.
* Renders the screen router with placeholder screens for each tab.
* This demo only runs when the file is executed directly (not when imported).
*/
function DemoApp() {
const { projectPath } = useFusion();
const [activeScreen, setActiveScreen] = useState<ScreenId>("board");
// Global keyboard shortcuts - handles Ctrl+C, q, ?/h, 1-5
const { helpVisible, toggleHelp } = useGlobalShortcuts({
onScreenChange: setActiveScreen,
});
return (
<Box flexDirection="column" flexGrow={1}>
{/* Help Overlay - shown when toggled, displayed at top */}
{helpVisible && (
<Box marginBottom={1}>
<HelpOverlay onClose={toggleHelp} />
</Box>
)}
{/* Responsive Header */}
<ResponsiveHeader title={`Fusion TUI | Project: ${projectPath}`} />
{/* Screen Router */}
<ScreenRouter
activeScreen={activeScreen}
onScreenChange={setActiveScreen}
>
{({ activeScreen }) => (
<Box flexDirection="column" flexGrow={1}>
{activeScreen === "board" && (
<Box flexDirection="column" paddingY={1}>
<Text bold>Board Screen</Text>
<Text dimColor>View and manage tasks on the kanban board</Text>
{/* Demo: Responsive Task Table */}
<Box marginTop={1}>
<ResponsiveTable
columns={[
{ header: "ID", minWidth: 10 },
{ header: "Description", minWidth: 30, canGrow: true, preferredWidth: 60 },
{ header: "Status", minWidth: 12 },
{ header: "Size", minWidth: 6 },
]}
rows={[
["FN-001", "Implement user authentication with OAuth 2.0 integration", "todo", "M"],
["FN-002", "Fix memory leak in data processing pipeline caused by missing cleanup handlers", "in-progress", "L"],
["FN-003", "Update documentation", "done", "S"],
["FN-004", "Refactor API endpoints to use REST conventions and add proper error handling with retry logic", "review", "M"],
]}
/>
</Box>
</Box>
)}
{activeScreen === "detail" && (
<Box flexDirection="column" paddingY={1}>
<Text bold>Detail Screen</Text>
<Text dimColor>View and edit individual task details</Text>
</Box>
)}
{activeScreen === "activity" && (
<Box flexDirection="column" paddingY={1}>
<Text bold>Activity Screen</Text>
<Text dimColor>View recent activity and events</Text>
</Box>
)}
{activeScreen === "agents" && (
<Box flexDirection="column" paddingY={1}>
<Text bold>Agents Screen</Text>
<Text dimColor>Manage AI agents and their configurations</Text>
</Box>
)}
{activeScreen === "settings" && (
<Box flexDirection="column" paddingY={1}>
<Text bold>Settings Screen</Text>
<Text dimColor>Configure project settings and preferences</Text>
</Box>
)}
</Box>
)}
</ScreenRouter>
{/* Responsive Status Bar */}
<ResponsiveStatusBar />
</Box>
);
}
// Guard: only render if this file is being executed directly (not imported)
const currentFile = fileURLToPath(import.meta.url);
const isMainModule = process.argv[1] !== undefined && currentFile === process.argv[1];
const isDevRun = process.argv[1]?.includes("index.tsx");
if (isMainModule || isDevRun) {
render(
<FusionProvider>
<DemoApp />
</FusionProvider>
);
}