* Perfect! Now let me create a summary for you: ## ✅ ESLint Configuration Complete The linter has identified **29 files** that need to be renamed: ### **Files to Rename:** #### **Components → PascalCase (15 files)** ``` config-provider.tsx → ConfigProvider.tsx diff-view-switch.tsx → DiffViewSwitch.tsx logo.tsx → Logo.tsx navbar.tsx → Navbar.tsx (in layout/) search-bar.tsx → SearchBar.tsx theme-provider.tsx → ThemeProvider.tsx style-override.tsx → StyleOverride.tsx copy-files-field.tsx → CopyFilesField.tsx (in projects/) project-detail.tsx → ProjectDetail.tsx (in projects/) project-form-fields.tsx → ProjectFormFields.tsx (in projects/) project-list.tsx → ProjectList.tsx (in projects/) ``` #### **Contexts → PascalCase (2 files)** ``` project-context.tsx → ProjectContext.tsx search-context.tsx → SearchContext.tsx ``` #### **Pages → PascalCase (3 files)** ``` full-attempt-logs.tsx → FullAttemptLogs.tsx project-tasks.tsx → ProjectTasks.tsx projects.tsx → Projects.tsx ``` #### **Lib → camelCase (2 files)** ``` caret-position.ts → caretPosition.ts mcp-strategies.ts → mcpStrategies.ts ``` #### **Utils → camelCase (3 files)** ``` companion-install-task.ts → companionInstallTask.ts script-placeholders.ts → scriptPlaceholders.ts status-labels.ts → statusLabels.ts ``` #### **UI (shadcn) → kebab-case (4 files)** ``` ActionsDropdown.tsx → actions-dropdown.tsx ImageUploadSection.tsx → image-upload-section.tsx TitleDescriptionEditor.tsx → title-description-editor.tsx DataTable.tsx → data-table.tsx (in table/) Table.tsx → table.tsx (in table/) ImageChipNode.tsx → image-chip-node.tsx (in wysiwyg/) imageChipMarkdown.ts → image-chip-markdown.ts (in wysiwyg/) ``` #### **Entry Point (special case - 1 file)** ``` main.tsx → can stay as main.tsx (entry point convention) ``` **Next steps:** Should I proceed with renaming these files using `git mv`? * ## ✅ Complete! File Naming Standardization Successful ### **Summary** Successfully implemented and enforced file naming conventions for the frontend: ### **What Was Done:** 1. ✅ **Installed** `eslint-plugin-check-file@^2.8.0` 2. ✅ **Configured ESLint** with file naming rules: - **Components (.tsx)**: `PascalCase` - **Hooks (.ts)**: `camelCase` (with `use` prefix) - **Utils/Lib (.ts)**: `camelCase` - **Shadcn UI**: `kebab-case` (library convention) - **Entry points**: Excluded (`main.tsx`, `vite-env.d.ts`) 3. ✅ **Renamed 28 files** using `git mv`: - 10 components → PascalCase - 2 contexts → PascalCase - 3 pages → PascalCase - 2 lib files → camelCase - 3 utils → camelCase - 7 UI components → kebab-case - 1 utils component → PascalCase 4. ✅ **Fixed all imports** across the codebase (77 files modified) 5. ✅ **Verified**: - ✅ ESLint passes (no filename errors) - ✅ TypeScript check passes (no errors) - ✅ Build successful ### **Git Status:** - 28 files renamed (with history preserved via `git mv`) - 77 total files changed (renames + import updates) ### **Ready for commit!** The codebase now has consistent, enforceable file naming conventions that will prevent future inconsistencies. * Cleanup script changes for task attempt 11f8d7b9-99b5-41ce-934c-5ce75008a200
113 lines
3.4 KiB
TypeScript
113 lines
3.4 KiB
TypeScript
import type { McpConfig, JsonValue } from 'shared/types';
|
|
|
|
type JsonObject = Record<string, JsonValue>;
|
|
|
|
function isJsonObject(v: unknown): v is JsonObject {
|
|
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
}
|
|
|
|
export class McpConfigStrategyGeneral {
|
|
static createFullConfig(cfg: McpConfig): JsonObject {
|
|
const cloned: JsonValue = JSON.parse(JSON.stringify(cfg.template ?? {}));
|
|
const fullConfig: JsonObject = isJsonObject(cloned) ? cloned : {};
|
|
let current: JsonObject = fullConfig;
|
|
|
|
for (let i = 0; i < cfg.servers_path.length - 1; i++) {
|
|
const key = cfg.servers_path[i];
|
|
const next = isJsonObject(current[key])
|
|
? (current[key] as JsonObject)
|
|
: undefined;
|
|
if (!next) current[key] = {};
|
|
current = current[key] as JsonObject;
|
|
}
|
|
|
|
if (cfg.servers_path.length > 0) {
|
|
const lastKey = cfg.servers_path[cfg.servers_path.length - 1];
|
|
current[lastKey] = cfg.servers;
|
|
}
|
|
return fullConfig;
|
|
}
|
|
static validateFullConfig(
|
|
mcp_config: McpConfig,
|
|
full_config: JsonValue
|
|
): void {
|
|
let current: JsonValue = full_config;
|
|
for (const key of mcp_config.servers_path) {
|
|
if (!isJsonObject(current)) {
|
|
throw new Error(
|
|
`Expected object at path: ${mcp_config.servers_path.join('.')}`
|
|
);
|
|
}
|
|
current = current[key];
|
|
if (current === undefined) {
|
|
throw new Error(
|
|
`Missing required field at path: ${mcp_config.servers_path.join('.')}`
|
|
);
|
|
}
|
|
}
|
|
if (!isJsonObject(current)) {
|
|
throw new Error('Servers configuration must be an object');
|
|
}
|
|
}
|
|
static extractServersForApi(
|
|
mcp_config: McpConfig,
|
|
full_config: JsonValue
|
|
): JsonObject {
|
|
let current: JsonValue = full_config;
|
|
for (const key of mcp_config.servers_path) {
|
|
if (!isJsonObject(current)) {
|
|
throw new Error(
|
|
`Expected object at path: ${mcp_config.servers_path.join('.')}`
|
|
);
|
|
}
|
|
current = current[key];
|
|
if (current === undefined) {
|
|
throw new Error(
|
|
`Missing required field at path: ${mcp_config.servers_path.join('.')}`
|
|
);
|
|
}
|
|
}
|
|
if (!isJsonObject(current)) {
|
|
throw new Error('Servers configuration must be an object');
|
|
}
|
|
return current;
|
|
}
|
|
|
|
static addPreconfiguredToConfig(
|
|
mcp_config: McpConfig,
|
|
existingConfig: JsonValue,
|
|
serverKey: string
|
|
): JsonObject {
|
|
const preconfVal = mcp_config.preconfigured;
|
|
if (!isJsonObject(preconfVal) || !(serverKey in preconfVal)) {
|
|
throw new Error(`Unknown preconfigured server '${serverKey}'`);
|
|
}
|
|
|
|
const updatedVal: JsonValue = JSON.parse(
|
|
JSON.stringify(existingConfig ?? {})
|
|
);
|
|
const updated: JsonObject = isJsonObject(updatedVal) ? updatedVal : {};
|
|
let current: JsonObject = updated;
|
|
|
|
for (let i = 0; i < mcp_config.servers_path.length - 1; i++) {
|
|
const key = mcp_config.servers_path[i];
|
|
const next = isJsonObject(current[key])
|
|
? (current[key] as JsonObject)
|
|
: undefined;
|
|
if (!next) current[key] = {};
|
|
current = current[key] as JsonObject;
|
|
}
|
|
|
|
if (mcp_config.servers_path.length === 0) {
|
|
current[serverKey] = preconfVal[serverKey];
|
|
return updated;
|
|
}
|
|
|
|
const lastKey = mcp_config.servers_path[mcp_config.servers_path.length - 1];
|
|
if (!isJsonObject(current[lastKey])) current[lastKey] = {};
|
|
(current[lastKey] as JsonObject)[serverKey] = preconfVal[serverKey];
|
|
|
|
return updated;
|
|
}
|
|
}
|