Remove legacy React/Ink TUI and fix TypeScript errors

- Delete old tui/ React/Ink implementation (App.tsx, components/, hooks/, store.ts)
  - Migrate to tui-solid/ as the sole TUI implementation
  - Update tui/index.ts to re-export from tui-solid and @/types/tui

  TypeScript fixes:
  - Add missing PreCompact to hook event constants
  - Fix path aliases (@src/ -> @/, @constants/)
  - Remove unused imports across service files
  - Add explicit type annotations to callback parameters
  - Replace Bun.file/write with Node.js fs/promises in mcp/registry
  - Fix Map.some() -> Array.from().some() in registry
  - Fix addServer() call signature
  - Add missing description to brain-mcp schema items
  - Fix typo in progress-bar import (@interfactes -> @interfaces)
This commit is contained in:
2026-02-04 01:21:43 -05:00
parent 5c2d79c802
commit c1b4384890
61 changed files with 80 additions and 8123 deletions

View File

@@ -4,21 +4,20 @@
*/
import { readFile, readdir } from "node:fs/promises";
import { join, basename, extname } from "node:path";
import { join, extname } from "node:path";
import { existsSync } from "node:fs";
import { homedir } from "node:os";
import type {
AgentDefinition,
AgentFrontmatter,
AgentDefinitionFile,
AgentRegistry,
AgentLoadResult,
AgentTier,
AgentColor,
} from "@src/types/agent-definition";
import { DEFAULT_AGENT_DEFINITION, AGENT_DEFINITION_SCHEMA } from "@src/types/agent-definition";
import { AGENT_DEFINITION, AGENT_DEFINITION_PATHS, AGENT_MESSAGES } from "@src/constants/agent-definition";
} from "@/types/agent-definition";
import { DEFAULT_AGENT_DEFINITION, AGENT_DEFINITION_SCHEMA } from "@/types/agent-definition";
import { AGENT_DEFINITION, AGENT_DEFINITION_PATHS, AGENT_MESSAGES } from "@constants/agent-definition";
const parseFrontmatter = (content: string): { frontmatter: Record<string, unknown>; body: string } | null => {
const delimiter = AGENT_DEFINITION.FRONTMATTER_DELIMITER;
@@ -207,12 +206,12 @@ export const loadAllAgentDefinitions = async (
agents.set(agent.name, agent);
// Index by trigger phrases
agent.triggerPhrases?.forEach((phrase) => {
agent.triggerPhrases?.forEach((phrase: string) => {
byTrigger.set(phrase.toLowerCase(), agent.name);
});
// Index by capabilities
agent.capabilities?.forEach((capability) => {
agent.capabilities?.forEach((capability: string) => {
const existing = byCapability.get(capability) || [];
byCapability.set(capability, [...existing, agent.name]);
});
@@ -245,8 +244,8 @@ export const findAgentsByCapability = (
): ReadonlyArray<AgentDefinition> => {
const agentNames = registry.byCapability.get(capability) || [];
return agentNames
.map((name) => registry.agents.get(name))
.filter((a): a is AgentDefinition => a !== undefined);
.map((name: string) => registry.agents.get(name))
.filter((a: AgentDefinition | undefined): a is AgentDefinition => a !== undefined);
};
export const getAgentByName = (
@@ -273,12 +272,12 @@ export const createAgentDefinitionContent = (agent: AgentDefinition): string =>
if (agent.triggerPhrases && agent.triggerPhrases.length > 0) {
frontmatter.push("triggerPhrases:");
agent.triggerPhrases.forEach((phrase) => frontmatter.push(` - ${phrase}`));
agent.triggerPhrases.forEach((phrase: string) => frontmatter.push(` - ${phrase}`));
}
if (agent.capabilities && agent.capabilities.length > 0) {
frontmatter.push("capabilities:");
agent.capabilities.forEach((cap) => frontmatter.push(` - ${cap}`));
agent.capabilities.forEach((cap: string) => frontmatter.push(` - ${cap}`));
}
frontmatter.push("---");

View File

@@ -19,16 +19,13 @@ import type {
TaskError,
TaskMetadata,
TaskNotification,
TaskStep,
TaskArtifact,
} from "@src/types/background-task";
import { DEFAULT_BACKGROUND_TASK_CONFIG, BACKGROUND_TASK_PRIORITIES } from "@src/types/background-task";
} from "@/types/background-task";
import { DEFAULT_BACKGROUND_TASK_CONFIG, BACKGROUND_TASK_PRIORITIES } from "@/types/background-task";
import {
BACKGROUND_TASK,
BACKGROUND_TASK_STORAGE,
BACKGROUND_TASK_MESSAGES,
BACKGROUND_TASK_STATUS_ICONS,
} from "@src/constants/background-task";
} from "@constants/background-task";
type TaskHandler = (task: BackgroundTask, updateProgress: (progress: Partial<TaskProgress>) => void) => Promise<TaskResult>;
type NotificationHandler = (notification: TaskNotification) => void;

View File

@@ -4,7 +4,6 @@
*/
import { createServer, type Server, type IncomingMessage, type ServerResponse } from "node:http";
import { randomUUID } from "node:crypto";
import type {
BrainMcpServerConfig,
@@ -14,18 +13,17 @@ import type {
BrainMcpToolName,
McpContent,
McpError,
} from "@src/types/brain-mcp";
BrainMcpTool,
} from "@/types/brain-mcp";
import {
DEFAULT_BRAIN_MCP_SERVER_CONFIG,
BRAIN_MCP_TOOLS,
MCP_ERROR_CODES,
} from "@src/types/brain-mcp";
} from "@/types/brain-mcp";
import {
BRAIN_MCP_SERVER,
BRAIN_MCP_MESSAGES,
BRAIN_MCP_ERRORS,
BRAIN_MCP_AUTH,
} from "@src/constants/brain-mcp";
} from "@constants/brain-mcp";
type BrainService = {
recall: (query: string, limit?: number) => Promise<unknown>;
@@ -135,7 +133,7 @@ const handleToolCall = async (
throw createMcpError(MCP_ERROR_CODES.BRAIN_UNAVAILABLE, "Brain service not connected");
}
const tool = BRAIN_MCP_TOOLS.find((t) => t.name === toolName);
const tool = BRAIN_MCP_TOOLS.find((t: BrainMcpTool) => t.name === toolName);
if (!tool) {
throw createMcpError(MCP_ERROR_CODES.TOOL_NOT_FOUND, `Tool not found: ${toolName}`);
}
@@ -167,7 +165,7 @@ const handleToolCall = async (
brain_stats: () => state.brainService!.getStats(),
brain_projects: async () => {
// Import dynamically to avoid circular dependency
const { listProjects } = await import("@src/services/brain/project-service");
const { listProjects } = await import("@services/brain/project-service");
return listProjects();
},
};
@@ -254,7 +252,7 @@ const handleRequest = async (
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(createMcpResponse(mcpRequest.id, content)));
} else if (mcpRequest.method === "tools/list") {
const tools = BRAIN_MCP_TOOLS.map((tool) => ({
const tools = BRAIN_MCP_TOOLS.map((tool: BrainMcpTool) => ({
name: tool.name,
description: tool.description,
inputSchema: tool.inputSchema,
@@ -351,4 +349,4 @@ export const updateConfig = (config: Partial<BrainMcpServerConfig>): void => {
};
export const getAvailableTools = (): ReadonlyArray<{ name: string; description: string }> =>
BRAIN_MCP_TOOLS.map((t) => ({ name: t.name, description: t.description }));
BRAIN_MCP_TOOLS.map((t: BrainMcpTool) => ({ name: t.name, description: t.description }));

View File

@@ -18,21 +18,16 @@ import type {
BrainProjectListResult,
BrainProjectExport,
BrainProjectImportResult,
ExportedConcept,
ExportedMemory,
ExportedRelationship,
} from "@src/types/brain-project";
} from "@/types/brain-project";
import {
DEFAULT_BRAIN_PROJECT_SETTINGS,
BRAIN_PROJECT_EXPORT_VERSION,
} from "@src/types/brain-project";
} from "@/types/brain-project";
import {
BRAIN_PROJECT,
BRAIN_PROJECT_STORAGE,
BRAIN_PROJECT_PATHS,
BRAIN_PROJECT_MESSAGES,
BRAIN_PROJECT_API,
} from "@src/constants/brain-project";
} from "@constants/brain-project";
interface ProjectServiceState {
projects: Map<number, BrainProject>;

View File

@@ -11,12 +11,12 @@ import type {
FilteredResult,
ValidationResult,
ConfidenceFilterStats,
} from "@src/types/confidence-filter";
} from "@/types/confidence-filter";
import {
CONFIDENCE_LEVELS,
DEFAULT_CONFIDENCE_FILTER_CONFIG,
} from "@src/types/confidence-filter";
import { CONFIDENCE_FILTER, CONFIDENCE_WEIGHTS } from "@src/constants/confidence-filter";
} from "@/types/confidence-filter";
import { CONFIDENCE_FILTER, CONFIDENCE_WEIGHTS } from "@constants/confidence-filter";
export const calculateConfidenceLevel = (score: number): ConfidenceLevel => {
const levels = Object.entries(CONFIDENCE_LEVELS) as Array<[ConfidenceLevel, { min: number; max: number }]>;
@@ -158,7 +158,7 @@ export const formatConfidenceScore = (confidence: ConfidenceScore, showFactors:
if (showFactors && confidence.factors.length > 0) {
const factorLines = confidence.factors
.map((f) => ` - ${f.name}: ${f.score}% (weight: ${f.weight})`)
.map((f: ConfidenceFactor) => ` - ${f.name}: ${f.score}% (weight: ${f.weight})`)
.join("\n");
result += `\n${factorLines}`;
}

View File

@@ -19,7 +19,6 @@ import {
MCP_REGISTRY_CACHE,
MCP_REGISTRY_SOURCES,
MCP_REGISTRY_ERRORS,
MCP_REGISTRY_SUCCESS,
MCP_SEARCH_DEFAULTS,
} from "@constants/mcp-registry";
import { addServer, connectServer, getServerInstances } from "./manager";
@@ -42,11 +41,9 @@ const getCacheFilePath = (): string => {
const loadCache = async (): Promise<MCPRegistryCache | null> => {
try {
const cachePath = getCacheFilePath();
const file = Bun.file(cachePath);
if (await file.exists()) {
const data = await file.json();
return data as MCPRegistryCache;
}
const fs = await import("fs/promises");
const content = await fs.readFile(cachePath, "utf-8");
return JSON.parse(content) as MCPRegistryCache;
} catch {
// Cache doesn't exist or is invalid
}
@@ -59,7 +56,10 @@ const loadCache = async (): Promise<MCPRegistryCache | null> => {
const saveCache = async (cache: MCPRegistryCache): Promise<void> => {
try {
const cachePath = getCacheFilePath();
await Bun.write(cachePath, JSON.stringify(cache, null, 2));
const fs = await import("fs/promises");
const path = await import("path");
await fs.mkdir(path.dirname(cachePath), { recursive: true });
await fs.writeFile(cachePath, JSON.stringify(cache, null, 2));
} catch {
// Ignore cache write errors
}
@@ -300,7 +300,7 @@ export const getServersByCategory = async (
*/
export const isServerInstalled = (serverId: string): boolean => {
const instances = getServerInstances();
return instances.some((instance) =>
return Array.from(instances.values()).some((instance) =>
instance.config.name === serverId ||
instance.config.name.toLowerCase() === serverId.toLowerCase()
);
@@ -332,8 +332,8 @@ export const installServer = async (
try {
// Add server to configuration
await addServer(
server.id,
{
name: server.id,
command: server.command,
args: customArgs || server.args,
transport: server.transport,
@@ -447,10 +447,8 @@ export const clearRegistryCache = async (): Promise<void> => {
registryCache = null;
try {
const cachePath = getCacheFilePath();
const file = Bun.file(cachePath);
if (await file.exists()) {
await Bun.write(cachePath, "");
}
const fs = await import("fs/promises");
await fs.unlink(cachePath);
} catch {
// Ignore
}

View File

@@ -21,7 +21,6 @@ import {
compactConversation,
checkCompactionNeeded,
getModelCompactionConfig,
createCompactionSummary,
} from "@services/auto-compaction";
import { appStore } from "@tui-solid/context/app";