Restructure src/ modules with consistent internal organization

Reorganize major src/ directories to follow a consistent pattern with
core/, menu/, submenu/, inputs/, logs/, layout/, feedback/ subdirectories.

Changes by module:

- stores/: Move 5 store files to stores/core/
- utils/: Create core/ (terminal, tools, etc.) and menu/ (progress-bar)
- api/: Create copilot/core/, copilot/auth/, ollama/core/
- providers/: Create core/, copilot/core/, copilot/auth/, ollama/core/, login/core/
- ui/: Create core/, banner/core/, banner/menu/, spinner/core/,
       input-editor/core/, components/core/, components/menu/
- tools/: Create core/ for registry.ts and types.ts
- tui-solid/: Reorganize components/ into menu/, submenu/, inputs/,
              logs/, modals/, panels/, layout/, feedback/
- commands/: Create core/ for runner.ts and handlers.ts
- services/: Create core/ for agent.ts, permissions.ts, session.ts,
             executor.ts, config.ts

All imports updated to use new paths. TypeScript compilation verified.
This commit is contained in:
2026-02-04 18:47:03 -05:00
parent c1b4384890
commit f0609e423e
191 changed files with 3162 additions and 824 deletions

View File

@@ -21,7 +21,7 @@ import type {
PatchRollback,
ParsedFilePatch,
} from "@/types/apply-patch";
import type { ToolContext, ToolResult } from "@tools/types";
import type { ToolContext, ToolResult } from "@tools/core/types";
// Rollback storage (in-memory for session)
const rollbackStore: Map<string, PatchRollback> = new Map();

View File

@@ -4,7 +4,7 @@
* Applies unified diff patches to files with fuzzy matching support.
*/
import type { ToolDefinition } from "@tools/types";
import type { ToolDefinition } from "@tools/core/types";
import { applyPatchParams } from "@tools/apply-patch/params";
import { executeApplyPatch } from "@tools/apply-patch/execute";

View File

@@ -9,7 +9,7 @@ import {
BASH_MESSAGES,
BASH_DESCRIPTION,
} from "@constants/bash";
import { promptPermission } from "@services/permissions";
import { promptPermission } from "@services/core/permissions";
import { bashParams } from "@tools/bash/params";
import {
truncateOutput,

6
src/tools/core/index.ts Normal file
View File

@@ -0,0 +1,6 @@
/**
* Tools Core - Registry and Types
*/
export * from "./registry";
export * from "./types";

219
src/tools/core/registry.ts Normal file
View File

@@ -0,0 +1,219 @@
/**
* Tool Registry
*
* Central registry for all available tools with support for
* built-in tools, MCP tools, and plugin tools.
*/
import type { ToolDefinition, FunctionDefinition } from "@tools/core/types";
import { toolToFunction } from "@tools/core/types";
import { bashTool } from "@/tools/bash";
import { readTool } from "@/tools/read";
import { writeTool } from "@/tools/write";
import { editTool } from "@/tools/edit";
import { todoWriteTool } from "@/tools/todo-write";
import { todoReadTool } from "@/tools/todo-read";
import { globToolDefinition } from "@/tools/glob/definition";
import { grepToolDefinition } from "@/tools/grep/definition";
import { webSearchTool } from "@/tools/web-search";
import { webFetchTool } from "@/tools/web-fetch";
import { multiEditTool } from "@/tools/multi-edit";
import { lspTool } from "@/tools/lsp";
import { applyPatchTool } from "@/tools/apply-patch";
import {
isMCPTool,
executeMCPTool,
getMCPToolsForApi,
} from "@/services/mcp/tools";
import {
isPluginTool,
getPluginTool,
getPluginToolsForApi,
} from "@/services/plugin-service";
import { z } from "zod";
/**
* All built-in tools
*/
export const tools: ToolDefinition[] = [
bashTool,
readTool,
writeTool,
editTool,
multiEditTool,
globToolDefinition,
grepToolDefinition,
todoWriteTool,
todoReadTool,
webSearchTool,
webFetchTool,
lspTool,
applyPatchTool,
];
/**
* Tools that are read-only (allowed in chat mode)
*/
const READ_ONLY_TOOLS = new Set([
"read",
"glob",
"grep",
"todo_read",
"web_search",
"web_fetch",
"lsp",
]);
/**
* Map of tools by name for fast lookup
*/
export const toolMap: Map<string, ToolDefinition> = new Map(
tools.map((t) => [t.name, t]),
);
/**
* Cached MCP tools
*/
let mcpToolsCache: Awaited<ReturnType<typeof getMCPToolsForApi>> | null = null;
/**
* Get tool by name (including MCP tools and plugin tools)
*/
export const getTool = (name: string): ToolDefinition | undefined => {
const builtInTool = toolMap.get(name);
if (builtInTool) {
return builtInTool;
}
if (isPluginTool(name)) {
return getPluginTool(name);
}
if (isMCPTool(name)) {
return {
name,
description: `MCP tool: ${name}`,
parameters: z.object({}).passthrough(),
execute: async (args) => {
const result = await executeMCPTool(
name,
args as Record<string, unknown>,
);
return {
success: result.success,
title: name,
output: result.output,
error: result.error,
};
},
};
}
return undefined;
};
/**
* Get all tools as OpenAI function definitions
*/
export const getToolFunctions = (): FunctionDefinition[] => {
return tools.map(toolToFunction);
};
/**
* Filter tools based on chat mode (read-only vs full access)
*/
const filterToolsForMode = (
toolList: ToolDefinition[],
chatMode: boolean,
): ToolDefinition[] => {
if (!chatMode) return toolList;
return toolList.filter((t) => READ_ONLY_TOOLS.has(t.name));
};
/**
* Get tools as format expected by Copilot/OpenAI API
* This includes both built-in tools and MCP tools
* @param chatMode - If true, only return read-only tools (no file modifications)
*/
export const getToolsForApiAsync = async (
chatMode = false,
): Promise<
{
type: "function";
function: FunctionDefinition;
}[]
> => {
const filteredTools = filterToolsForMode(tools, chatMode);
const builtInTools = filteredTools.map((t) => ({
type: "function" as const,
function: toolToFunction(t),
}));
if (chatMode) {
return builtInTools;
}
try {
mcpToolsCache = await getMCPToolsForApi();
const pluginTools = getPluginToolsForApi();
return [...builtInTools, ...pluginTools, ...mcpToolsCache];
} catch {
const pluginTools = getPluginToolsForApi();
return [...builtInTools, ...pluginTools];
}
};
/**
* Get tools synchronously (uses cached MCP tools if available)
* @param chatMode - If true, only return read-only tools (no file modifications)
*/
export const getToolsForApi = (
chatMode = false,
): {
type: "function";
function: FunctionDefinition;
}[] => {
const filteredTools = filterToolsForMode(tools, chatMode);
const builtInTools = filteredTools.map((t) => ({
type: "function" as const,
function: toolToFunction(t),
}));
if (chatMode) {
return builtInTools;
}
const pluginTools = getPluginToolsForApi();
if (mcpToolsCache) {
return [...builtInTools, ...pluginTools, ...mcpToolsCache];
}
return [...builtInTools, ...pluginTools];
};
/**
* Refresh MCP tools cache
* Returns information about the refresh result for logging
*/
export const refreshMCPTools = async (): Promise<{
success: boolean;
toolCount: number;
error?: string;
}> => {
try {
mcpToolsCache = await getMCPToolsForApi();
return {
success: true,
toolCount: mcpToolsCache.length,
};
} catch (err) {
mcpToolsCache = null;
const errorMessage = err instanceof Error ? err.message : String(err);
return {
success: false,
toolCount: 0,
error: errorMessage,
};
}
};

View File

@@ -6,7 +6,7 @@ import fs from "fs/promises";
import path from "path";
import { EDIT_MESSAGES, EDIT_TITLES, EDIT_DESCRIPTION } from "@constants/edit";
import { isFileOpAllowed, promptFilePermission } from "@services/permissions";
import { isFileOpAllowed, promptFilePermission } from "@services/core/permissions";
import { formatDiff } from "@utils/diff/format";
import { generateDiff } from "@utils/diff/generate";
import { editParams } from "@tools/edit/params";

View File

@@ -2,7 +2,7 @@
* Tool registry - exports all available tools
*/
export * from "@tools/types";
export * from "@tools/core/types";
export { bashTool } from "@tools/bash";
export { readTool } from "@tools/read";
export { writeTool } from "@tools/write";
@@ -17,8 +17,8 @@ export { multiEditTool } from "@tools/multi-edit";
export { lspTool } from "@tools/lsp";
export { applyPatchTool } from "@tools/apply-patch";
import type { ToolDefinition, FunctionDefinition } from "@tools/types";
import { toolToFunction } from "@tools/types";
import type { ToolDefinition, FunctionDefinition } from "@tools/core/types";
import { toolToFunction } from "@tools/core/types";
import { bashTool } from "@tools/bash";
import { readTool } from "@tools/read";
import { writeTool } from "@tools/write";

View File

@@ -17,7 +17,7 @@ import {
type DocumentSymbol,
type Hover,
} from "@services/lsp/index";
import type { ToolDefinition } from "@tools/types";
import type { ToolDefinition } from "@tools/core/types";
import fs from "fs/promises";
const PositionSchema = z.object({

View File

@@ -13,7 +13,7 @@ import {
MULTI_EDIT_TITLES,
MULTI_EDIT_DESCRIPTION,
} from "@constants/multi-edit";
import { isFileOpAllowed, promptFilePermission } from "@services/permissions";
import { isFileOpAllowed, promptFilePermission } from "@services/core/permissions";
import { formatDiff } from "@utils/diff/format";
import { generateDiff } from "@utils/diff/generate";
import { multiEditParams } from "@tools/multi-edit/params";

View File

@@ -11,7 +11,7 @@ import {
READ_TITLES,
READ_DESCRIPTION,
} from "@constants/read";
import { isFileOpAllowed, promptFilePermission } from "@services/permissions";
import { isFileOpAllowed, promptFilePermission } from "@services/core/permissions";
import { readParams } from "@tools/read/params";
import { processLines } from "@tools/read/format";
import type {

View File

@@ -5,8 +5,8 @@
*/
import { z } from "zod";
import { todoStore } from "@stores/todo-store";
import type { ToolDefinition } from "@tools/types";
import { todoStore } from "@stores/core/todo-store";
import type { ToolDefinition } from "@tools/core/types";
const parametersSchema = z.object({});

View File

@@ -5,8 +5,8 @@
*/
import { z } from "zod";
import { todoStore } from "@stores/todo-store";
import type { ToolDefinition } from "@tools/types";
import { todoStore } from "@stores/core/todo-store";
import type { ToolDefinition } from "@tools/core/types";
import type { TodoStatus } from "@/types/todo";
const TodoItemSchema = z.object({

View File

@@ -10,7 +10,7 @@ import {
WRITE_TITLES,
WRITE_DESCRIPTION,
} from "@constants/write";
import { isFileOpAllowed, promptFilePermission } from "@services/permissions";
import { isFileOpAllowed, promptFilePermission } from "@services/core/permissions";
import { formatDiff } from "@utils/diff/format";
import { generateDiff } from "@utils/diff/generate";
import { writeParams } from "@tools/write/params";