4201326467
Remove stale ToolConfig and ConfigFolder backend/frontend surfaces after the ConfigProfile refactor. Drop dead routers, schemas, model exports, frontend routes, clients, pages, and tests; keep ToolType API compatibility for existing interface/is_builtin response shape. Quality gates: backend LSP diagnostics passed; backend py_compile passed; backend ruff passed; frontend ToolWorkshopPage test passed. Frontend typecheck blocked by unrelated missing xterm-addon-serialize types.
83 lines
2.5 KiB
JavaScript
83 lines
2.5 KiB
JavaScript
#!/usr/bin/env node
|
|
/* eslint-disable */
|
|
/**
|
|
* Verifies repository structure conventions.
|
|
* Run with: node scripts/check-structure.js
|
|
*/
|
|
|
|
import fs from "fs";
|
|
import path from "path";
|
|
import { fileURLToPath } from "url";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const SRC_DIR = path.join(__dirname, "..", "src");
|
|
|
|
let errors = 0;
|
|
let warnings = 0;
|
|
|
|
// Known acceptable deviations — documented in naming.md
|
|
const OVERSIZE_ALLOWLIST = [
|
|
// Form-heavy admin tabs: 15+ fields each, splitting would create micro-components
|
|
"components/features/tool-workshop/ToolTypesTab.tsx",
|
|
// Complex terminal hook: WS lifecycle + ping-pong + echo + resize debouncing
|
|
"hooks/use-terminal-connection.ts",
|
|
// Terminal component: xterm lifecycle + resize observer + overlay UI
|
|
"components/features/terminal/TerminalComponent.tsx",
|
|
// Instance list with health polling + inline confirmations
|
|
"components/features/session/InstanceList.tsx",
|
|
// Dialog with form validation + SSH key handling
|
|
"components/features/project/RepositoryCreateDialog.tsx",
|
|
// Test files: complex test coverage
|
|
"hooks/use-terminal-connection.test.ts",
|
|
"pages/ToolWorkshopPage.test.tsx",
|
|
// Global utility CSS: will be further split in future iteration
|
|
"styles/utilities.css",
|
|
];
|
|
|
|
function checkFileSize(filePath, maxLines = 300) {
|
|
const content = fs.readFileSync(filePath, "utf-8");
|
|
const lines = content.split("\n").length;
|
|
const relative = path.relative(SRC_DIR, filePath);
|
|
if (lines > maxLines) {
|
|
if (OVERSIZE_ALLOWLIST.includes(relative)) {
|
|
console.warn(`⚠️ OVERSIZED (${lines} lines, allowlisted): ${relative}`);
|
|
warnings++;
|
|
} else {
|
|
console.error(`❌ OVERSIZED (${lines} lines): ${relative}`);
|
|
errors++;
|
|
}
|
|
}
|
|
}
|
|
|
|
function walk(dir, callback) {
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
const fullPath = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
|
|
walk(fullPath, callback);
|
|
} else {
|
|
callback(fullPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log("Checking file sizes...\n");
|
|
walk(SRC_DIR, (filePath) => {
|
|
const ext = path.extname(filePath);
|
|
if ([".ts", ".tsx", ".py", ".css"].includes(ext)) {
|
|
checkFileSize(filePath);
|
|
}
|
|
});
|
|
|
|
console.log("\n---");
|
|
if (errors === 0 && warnings === 0) {
|
|
console.log("✅ All checks passed!");
|
|
process.exit(0);
|
|
} else if (errors === 0) {
|
|
console.log(`✅ All checks passed with ${warnings} warning(s)`);
|
|
process.exit(0);
|
|
} else {
|
|
console.log(`❌ ${errors} error(s), ${warnings} warning(s)`);
|
|
process.exit(1);
|
|
}
|