Verstak · Архитектура 19 июня 2026 · дневник разработки

Архитектура: как устроен контроль

Контроль и прозрачность — это не лозунги, а конкретные модули. Разберём, где они живут.

Два процесса, жёсткая граница

Классический Electron: electron/ — main-процесс (Node.js, полный доступ), src/ — renderer (React 19, без доступа к Node). Renderer общается с main только через preload.ts (contextBridge → window.api). Правило в проекте железное: renderer никогда не импортит из electron/. Любой новый IPC-эндпоинт трогает три места — handler в electron/ipc/, мост в preload.ts, тип в src/types/api.d.ts. Забыл одно — TypeScript strict не даст собрать.

nodeIntegration: false + contextIsolation: true. ESM-preload требует sandbox: false — это known trade-off, осознанный.

System-layer + user-layer: почему промпт прозрачен

Сборка system prompt разнесена:

Итог: в любой момент понятно, из чего собран промпт. Нет «магии в одном файле на 2000 строк».

Agent loop

Ядро — runApiConversation в electron/ipc/ai.ts. Цикл: модель просит tool → tool-handlers.ts диспатчит через HANDLER_REGISTRY → результат возвращается модели → повтор, пока не done. Поверх навешано:

FileTools — одна абстракция, разные бэкенды

Все файловые тулзы агента ходят через интерфейс FileTools (execute(name, args) + runCommand + classifyCommand). Это оказалось ключевым решением: когда понадобилось научить агента править файлы на удалённом сервере по SSH, не пришлось трогать ни один handler — достаточно подменить реализацию FileTools на ssh-версию для удалённых проектов. Об этом — в посте про удалённые проекты.

Хранилище

electron/storage/ — слой над SQLite (better-sqlite3). Схема и миграции — в db.ts, массив MIGRATIONS. Правило: только append, никогда не редактировать и не переставлять старые миграции (на момент блога их 23). Здесь же — chat-sessions (kind: 'main' | 'review'), per-file undo-стек, plans, journal, tasks, зашифрованные секреты.

Известная боль (честно)

src/store/projectStore.ts разросся до ~800 строк. Часть race-багов закрыли через SendRegistry (Phase A), но при добавлении фоновых агентов его надо доразбить на ChatSessionLifecycle и PerChatState. Полную миграцию компонентов на map-селекторы решили не делать — это churn без багофикса, ценность уже взята дедупликацией. Прагматизм важнее красоты.

→ Дальше: Pipeline Brief→Proof: флагман, собранный автономно


← Все статьи · Скачать Verstak