replace artifact heuristics/regexes with protocol messages (#8996)
This commit is contained in:
@@ -1,186 +0,0 @@
|
||||
import { readFileSync, readdirSync } from "node:fs";
|
||||
import { join, relative } from "node:path";
|
||||
|
||||
const DEFAULT_LIMIT = 500;
|
||||
|
||||
// Add narrowly scoped exceptions here with justification
|
||||
const EXCEPTIONS = {
|
||||
"src/features/sidebar/ui/SidebarProjectsSection.tsx": {
|
||||
limit: 570,
|
||||
justification:
|
||||
"Drag-and-drop handlers for session-to-project moves and project reorder, plus activeProjectId highlight.",
|
||||
},
|
||||
"src/features/chat/ui/ChatView.tsx": {
|
||||
limit: 570,
|
||||
justification:
|
||||
"ACP prewarm guards, project-aware working dir selection, working context sync, chat bootstrapping, context-ring compaction wiring, and gated [perf:chatview] logging via perfLog (dev-only by default).",
|
||||
},
|
||||
"src/features/chat/hooks/useChat.ts": {
|
||||
limit: 510,
|
||||
justification:
|
||||
"Session preparation, provider/model handoff, persona-aware sends, cancellation, and compaction replay still live in one chat lifecycle hook.",
|
||||
},
|
||||
"src/shared/api/acpNotificationHandler.ts": {
|
||||
limit: 570,
|
||||
justification:
|
||||
"ACP replay/live update handling, pending session buffering, model/config propagation, MCP structured tool output, and streaming perf tracking still share one notification entrypoint.",
|
||||
},
|
||||
"src/shared/api/__tests__/acpNotificationHandler.test.ts": {
|
||||
limit: 540,
|
||||
justification:
|
||||
"Notification handler regression coverage spans live streaming, replay ordering, MCP app payload attachment, and structured tool output preservation in one integration-style suite.",
|
||||
},
|
||||
"src/features/chat/ui/__tests__/ContextPanel.test.tsx": {
|
||||
limit: 550,
|
||||
justification:
|
||||
"Workspace widget integration tests cover branch switching, worktree creation, dirty-state dialogs, and picker interactions.",
|
||||
},
|
||||
"src/features/sidebar/ui/Sidebar.tsx": {
|
||||
limit: 580,
|
||||
justification:
|
||||
"Search-as-you-type filtering and draft-aware sidebar highlight logic.",
|
||||
},
|
||||
"src/app/AppShell.tsx": {
|
||||
limit: 780,
|
||||
justification:
|
||||
"Shell still coordinates ACP session loading, replay-buffer cleanup on load failure, project reassignment, home-session restoration, app-level chat routing, restored project-draft reuse, and app-level compaction settings deep links. Includes gated [perf:load]/[perf:newtab] logging via perfLog (dev-only by default).",
|
||||
},
|
||||
"src/features/chat/hooks/useChatSessionController.ts": {
|
||||
limit: 840,
|
||||
justification:
|
||||
"Controller now centralizes home-to-chat pending state transfer, workspace/project preparation, provider/model/persona handoff, Goose cross-provider model selection sequencing with rollback, context-usage readiness resets, queued-target compaction gating, and auto-compaction-aware send orchestration pending a later decomposition pass.",
|
||||
},
|
||||
"src/features/chat/hooks/__tests__/useChatSessionController.test.ts": {
|
||||
limit: 520,
|
||||
justification:
|
||||
"Controller regression coverage now spans model/provider rollback, stale usage resets, compact-before-send, and queued-persona auto-compaction support checks in one hook suite.",
|
||||
},
|
||||
"src/features/chat/stores/chatStore.ts": {
|
||||
limit: 520,
|
||||
justification:
|
||||
"Chat runtime state, queued-message persistence, replay loading flags, and usage snapshot tracking still live together in one Zustand store.",
|
||||
},
|
||||
"src/features/chat/ui/AgentModelPicker.tsx": {
|
||||
limit: 570,
|
||||
justification:
|
||||
"Agent-first picker currently keeps the full trigger, recommended-model view, searchable full-model view, and ACP/goose-specific labeling logic in one component pending later extraction.",
|
||||
},
|
||||
"src/features/chat/stores/__tests__/chatSessionStore.test.ts": {
|
||||
limit: 540,
|
||||
justification:
|
||||
"ACP session overlay regressions currently need one broad integration-style store suite.",
|
||||
},
|
||||
"src/features/chat/stores/chatSessionStore.ts": {
|
||||
limit: 640,
|
||||
justification:
|
||||
"ACP-backed session overlay persistence, draft migration, and sidebar-facing session merge logic live together for now.",
|
||||
},
|
||||
"src/features/chat/ui/ChatInput.tsx": {
|
||||
limit: 510,
|
||||
justification:
|
||||
"Voice dictation send/stop guards, attachment handling, and mention/picker coordination still share one chat composer component.",
|
||||
},
|
||||
"src/features/chat/ui/MessageBubble.tsx": {
|
||||
limit: 580,
|
||||
justification:
|
||||
"Bubble rendering still owns assistant identity, grouped tool output, attachments, inline MCP app tool/result wiring, app-initiated message plumbing, full-width inline layout handling, inline auto-scroll callback plumbing, and the inline actions tray pending a later extraction pass.",
|
||||
},
|
||||
"src/features/chat/ui/__tests__/MessageBubble.test.tsx": {
|
||||
limit: 520,
|
||||
justification:
|
||||
"Message bubble regression coverage still keeps copy state, action tray layout, provider/persona identity, tool chains, and shared rendering behavior in one suite while the MCP app-specific assertions live in a companion test file.",
|
||||
},
|
||||
"src/features/skills/ui/SkillsView.tsx": {
|
||||
limit: 620,
|
||||
justification:
|
||||
"SkillsView currently centralizes list/detail state, project-aware skill hydration, category/source filtering, import/export flows, and detail-page action wiring pending a later decomposition.",
|
||||
},
|
||||
"src/features/chat/ui/__tests__/ChatInput.test.tsx": {
|
||||
limit: 570,
|
||||
justification:
|
||||
"Composer regression coverage spans personas, queueing, attachments, voice-input edge cases, and the compaction popover/settings ingress in one interaction-heavy suite.",
|
||||
},
|
||||
"src-tauri/src/commands/projects.rs": {
|
||||
limit: 520,
|
||||
justification:
|
||||
"Project CRUD plus reorder_projects command for sidebar drag-and-drop ordering.",
|
||||
},
|
||||
"src-tauri/src/commands/system.rs": {
|
||||
limit: 640,
|
||||
justification:
|
||||
"Desktop system commands still centralize file mentions, attachment inspection, platform-aware path dedupe, guarded image loading, and export helpers in one Tauri command surface.",
|
||||
},
|
||||
};
|
||||
|
||||
// Directories excluded from size checks (imported library code)
|
||||
const EXCLUDED_DIRS = [
|
||||
"src/shared/ui",
|
||||
"src/components/ai-elements",
|
||||
"src/hooks",
|
||||
];
|
||||
|
||||
const DIRS_TO_CHECK = [
|
||||
{ dir: "src/app", glob: /\.[jt]sx?$/ },
|
||||
{ dir: "src/features", glob: /\.[jt]sx?$/ },
|
||||
{ dir: "src/shared", glob: /\.[jt]sx?$/ },
|
||||
{ dir: "src/components", glob: /\.[jt]sx?$/ },
|
||||
{ dir: "src/hooks", glob: /\.[jt]sx?$/ },
|
||||
{ dir: "src-tauri/src", glob: /\.rs$/ },
|
||||
];
|
||||
|
||||
function countLines(filePath) {
|
||||
const content = readFileSync(filePath, "utf8");
|
||||
return content.split("\n").length;
|
||||
}
|
||||
|
||||
function isExcluded(filePath) {
|
||||
const rel = relative(".", filePath);
|
||||
return EXCLUDED_DIRS.some((dir) => rel.startsWith(dir));
|
||||
}
|
||||
|
||||
function walkDir(dir, pattern) {
|
||||
const results = [];
|
||||
let entries;
|
||||
try {
|
||||
entries = readdirSync(dir, { withFileTypes: true });
|
||||
} catch {
|
||||
return results;
|
||||
}
|
||||
for (const entry of entries) {
|
||||
const fullPath = join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
results.push(...walkDir(fullPath, pattern));
|
||||
} else if (pattern.test(entry.name)) {
|
||||
results.push(fullPath);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
const violations = [];
|
||||
|
||||
for (const { dir, glob } of DIRS_TO_CHECK) {
|
||||
const files = walkDir(dir, glob);
|
||||
for (const file of files) {
|
||||
if (isExcluded(file)) continue;
|
||||
const rel = relative(".", file);
|
||||
const limit = EXCEPTIONS[rel]?.limit ?? DEFAULT_LIMIT;
|
||||
const lines = countLines(file);
|
||||
if (lines > limit) {
|
||||
violations.push({ file: rel, lines, limit });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (violations.length > 0) {
|
||||
console.error("Desktop file size check failed:");
|
||||
for (const v of violations) {
|
||||
console.error(` - ${v.file}: ${v.lines} lines (limit ${v.limit})`);
|
||||
}
|
||||
console.error(
|
||||
"\nSplit the file or add a narrowly scoped exception in `scripts/check-file-sizes.mjs`.",
|
||||
);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log("File size check passed.");
|
||||
}
|
||||
Reference in New Issue
Block a user