agent-ecosystem/docs/iterations/edit-project/iter-0-refactoring.md
iliya d7fc71a5e6 feat: enhance project editor with file management, Git integration, and UI improvements
- Introduced `EditorFileWatcher` for live file change detection and `GitStatusService` for displaying Git status in the file tree.
- Added context menu for file operations (create, delete) and implemented multi-tab support for the editor.
- Enhanced user experience with keyboard shortcuts, search functionality, and breadcrumb navigation.
- Updated IPC channels for file operations and integrated conflict detection during file saves.
- Improved performance with file watcher optimizations and virtualized file tree rendering.
2026-02-28 13:35:22 +02:00

87 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# PR 0: Обязательные рефакторинги (R1-R4)
> Перед итерацией 1. Отдельный PR.
## Цель
Обязательные рефакторинги -- без них будет дублирование кода. Выполняются ДО написания нового кода. Тесты `ReviewFileTree` и `CodeMirrorDiffView` должны проходить после рефакторинга (zero behavior change).
## Почему отдельный PR
R1 затрагивает production `ReviewFileTree` (используется в `ChangeReviewDialog`), R3 затрагивает production `CodeMirrorDiffView`. Объединение рефакторинга production-кода + 15 новых файлов в одну итерацию — чрезмерный blast radius (28 файлов). Разделение:
- **PR 0 ("Refactoring")**: R1-R4 + тесты. Мёрдж только после проверки что ChangeReviewDialog работает корректно.
- **PR 1 ("Walking Skeleton")**: Новые editor-файлы. Зависит от PR 0.
## Рефакторинги
| # | Что извлечь | Откуда | Куда | LOC |
|---|-------------|--------|------|-----|
| R1 | `buildTree()` + `collapse()` + сортировка | `ReviewFileTree.tsx:42-83` | `src/renderer/utils/fileTreeBuilder.ts` | ~50 |
| R2 | `getSyncLanguageExtension()` + `getAsyncLanguageDesc()` | `CodeMirrorDiffView.tsx:64-128` | `src/renderer/utils/codemirrorLanguages.ts` | ~70 |
| R3 | Базовая тема CM (без diff-стилей) | `CodeMirrorDiffView.tsx:158-198` | `src/renderer/utils/codemirrorTheme.ts` | ~40 |
| R4 | `wrapReviewHandler<T>()` | `review.ts:133-145` | `src/main/ipc/ipcWrapper.ts` | ~15 |
## Детали каждого рефакторинга
### R1: `buildTree<T>()` — Generic tree builder
**NB**: `ReviewFileTree` работает с `FileChangeSummary` (имеет `status`, `additions`, `deletions`), а editor использует `FileTreeEntry` (имеет `size`, `children`). `buildTree<T>()` должен быть generic по типу node, принимая `getPath: (item: T) => string` и `isDirectory: (item: T) => boolean` как параметры.
```typescript
// src/renderer/utils/fileTreeBuilder.ts
function buildTree<T>(
items: T[],
getPath: (item: T) => string,
isDirectory: (item: T) => boolean
): TreeNode<T>[]
```
### R2: `getSyncLanguageExtension()` — Языковой маппинг
Извлечь из `CodeMirrorDiffView.tsx:64-128`. 16+ языков синхронно + `@codemirror/language-data` async fallback.
### R3: `baseEditorTheme` — Базовая тема
**NB**: `diffTheme` — один `EditorView.theme({...})` на 125 строк. Рефакторинг:
1. Извлечь строки 158-198 в `baseEditorTheme = EditorView.theme({...})` в `codemirrorTheme.ts`
2. В `CodeMirrorDiffView.tsx` создать `const diffSpecificTheme = EditorView.theme({...})` со строками 199-283
3. В `buildExtensions()` заменить `diffTheme` на `[baseEditorTheme, diffSpecificTheme]`
### R4: `createIpcWrapper()` — Общий IPC wrapper
**NB**: `teams.ts` имеет аналогичный `wrapTeamHandler` (40+ вызовов), но его миграция — отдельный follow-up PR после итерации 1. Blast radius слишком высокий (1755 строк) для совмещения с основной фичей. В итерации 1 R4 применяется ТОЛЬКО к `review.ts` + новому `editor.ts`.
```typescript
// src/main/ipc/ipcWrapper.ts
export function createIpcWrapper(logPrefix: string) {
const log = createLogger(logPrefix);
return async function wrap<T>(op: string, fn: () => Promise<T>): Promise<IpcResult<T>> {
try { return { success: true, data: await fn() }; }
catch (error) {
const msg = error instanceof Error ? error.message : String(error);
log.error(`handler error [${op}]:`, msg);
return { success: false, error: msg };
}
};
}
// review.ts:
const wrapHandler = createIpcWrapper('IPC:review');
// editor.ts:
const wrapHandler = createIpcWrapper('IPC:editor');
```
## После рефакторинга
- `ReviewFileTree.tsx` импортирует `buildTree`, `TreeNode` из `fileTreeBuilder.ts`
- `CodeMirrorDiffView.tsx` импортирует из `codemirrorLanguages.ts` и `codemirrorTheme.ts`
- `review.ts` импортирует `createIpcWrapper` из `ipcWrapper.ts`
- `teams.ts` — миграция `wrapTeamHandler``createIpcWrapper` в отдельном follow-up PR (40+ замен, высокий blast radius)
## Критерии готовности
- `pnpm typecheck` проходит
- Тесты `ReviewFileTree` и `CodeMirrorDiffView` проходят (zero behavior change)
- ChangeReviewDialog работает корректно (manual check)
- Новые unit-тесты для `fileTreeBuilder.ts` и `ipcWrapper.ts`