メインコンテンツまでスキップ

Renderer プロセス設計

Renderer プロセスはすべての UI レンダリングとユーザー操作を処理し、React 18 + TypeScript で構築されています。エントリファイルは packages/renderer/src/app/App.tsx です。

Context Provider 階層

App コンポーネントは厳密な Provider のネスト順序を定義します。外側の Provider は内側の Provider とコンポーネントからアクセスできます。

graph TB
LP[LocaleProvider — i18n internationalization]
TP[ThemeProvider — theme/wallpaper]
CDP[ConfirmDialogProvider — global confirm dialog]
AP[AuthProvider — auth state]
SDP[SettingsDataProvider — settings data]
EP[ElfiProvider — Elfi assistant]
WSP[WebSearchProvider — search]
ChatDP[ChatDataProvider — chat data cache]
CBP[ChatBackendProvider — WebSocket backend]
UCP[UnifiedChatProvider — unified chat API]
HPP[HtmlPreviewProvider — HTML preview]
DPP[DevPreviewProvider — dev preview]
PR[ProtectedRoute — route guard]
HR[HashRouter — frontend routing]
CTP[ChatTabsProvider — multi-tab management]
AR[AppRoutes — route definition]
AC[AppContent — main content]

LP --> TP --> CDP --> AP --> SDP --> EP --> WSP --> ChatDP --> CBP --> UCP --> HPP --> DPP --> PR --> HR --> CTP --> AR --> AC
// Actual nesting structure in App.tsx
function App() {
return (
<LocaleProvider>
<ThemeProvider>
<ConfirmDialogProvider>
<AuthProvider>
<SettingsDataProvider>
<ElfiProvider>
<WebSearchProvider>
<ChatDataProvider>
<ChatBackendProvider>
<UnifiedChatProvider>
<HtmlPreviewProvider>
<DevPreviewProvider>
<ProtectedRoute>
<HashRouter>
<ChatTabsProvider>
<AppRoutes>
<AppContent />
</AppRoutes>
</ChatTabsProvider>
</HashRouter>
</ProtectedRoute>
</DevPreviewProvider>
</HtmlPreviewProvider>
</UnifiedChatProvider>
</ChatBackendProvider>
</ChatDataProvider>
</WebSearchProvider>
</ElfiProvider>
</SettingsDataProvider>
</AuthProvider>
</ConfirmDialogProvider>
</ThemeProvider>
</LocaleProvider>
);
}

Zustand Store

高頻度で更新されるチャット状態には Zustand を使用し、Context による不要な再レンダリングを回避します。

chatStore

subscribeWithSelector ミドルウェアを使用して正確な購読を行う、チャット状態の中核ストレージです。

// Simplified chatStore state interface
interface ChatState {
// Sessions
sessions: Session[];
sessionsLoading: boolean;
sessionsError: Error | null;

// Assistants
assistants: ChatAssistant[];
assistantsLoading: boolean;

// Providers
providers: LLMProvider[];
providersLoading: boolean;

// Message cache (indexed by sessionId)
messageCache: Map<string, Message[]>;

// Streaming state
streamingState: StreamingState;

// Branch info
branchInfo: Map<string, BranchInfo>;

// Actions
fetchSessions(): Promise<void>;
fetchAssistants(): Promise<void>;
fetchProviders(): Promise<void>;
loadMessages(sessionId: string): Promise<void>;
setStreamingState(state: Partial<StreamingState>): void;
switchBranch(messageId: string, index: number): void;
}
// Use selector for precise subscription, avoid irrelevant re-renders
const sessions = useChatStore(state => state.sessions);
const isStreaming = useChatStore(state => state.streamingState.isStreaming);
Storeファイル責務
chatStoreshared/state/chatStore.tsセッション、メッセージ、ストリーミング状態、ブランチ
settingsStoreshared/state/settingsStore.ts設定状態
useChatStoreSyncshared/state/useChatStoreSync.tsChatDataContext → chatStore の同期

React Context の詳細

23 個以上の Context があり、それぞれが独立した責務を持ちます。

Contextファイル責務中核状態/メソッド
LocaleContextshared/state/LocaleContext.tsxi18n (en/zh/ja)useTranslation(), setLocale()
themeStoreshared/state/themeStore.ts (host app/ThemeHost.tsx)テーマモード、壁紙、カスタム CSSmode, resolvedMode, userTheme, customCss
ConfirmDialogHostshared/state/ConfirmDialogHost.tsxグローバル確認ダイアログconfirm(options)
authStoreshared/state/authStore.ts認証状態user, isAuthenticated, login(), logout()
SettingsDataHostapp/SettingsDataHost.tsx設定の読み書きsettings, updateSetting()
ElfiContextfeatures/elfi/state/ElfiContext.tsxElfi スマートアシスタントisOpen, messages, sendMessage()
webSearchStoreshared/state/webSearchStore.ts (host app/WebSearchHost.tsx)Web 検索search(), results
chatStoreshared/state/chatStore.tsチャットデータキャッシュ + 統合チャット API (旧 ChatDataContext / UnifiedChatContext はここへ移行)sessions, messages, sendMessage(), regenerate(), editMessage()
htmlPreviewStoreshared/state/htmlPreviewStore.ts (host app/HtmlPreviewHost.tsx)HTML コンテンツプレビューshowPreview(), previewContent
devPreviewStoreshared/state/devPreviewStore.ts (host app/DevPreviewHost.tsx)Dev モードプレビューisDevMode, devData
ChatTabsContextfeatures/chat/state/ChatTabsContext.tsx複数タブのチャット管理tabs, activeTabId, createTab(), closeTab()
AgentContextfeatures/agents/state/AgentContext.tsxAgent 状態agents, selectedAgent
subagentStoreshared/state/subagentStore.ts (host shared/state/SubagentHost.tsx)Subagent 状態subagents, status
MessageSelectionContextfeatures/chat/state/MessageSelectionContext.tsxメッセージの複数選択selectedIds, toggleSelect()
sessionOrganizerStoreshared/state/sessionOrganizerStore.ts (host shared/state/sessionOrganizerStore/SessionOrganizerHost.tsx)セッションの整理/分類folders, moveSession()
worksStoreshared/state/worksStore.tsWorks 管理works, createWork()
musicWorksStoreshared/state/musicWorksStore.ts音楽作品tracks, playTrack()
musicTemplateStoreshared/state/musicTemplateStore.ts音楽テンプレートtemplates
VideoWorksContextfeatures/media/state/VideoWorksContext.tsx動画作品videos
videoTemplateStoreshared/state/videoTemplateStore.ts動画テンプレートtemplates
TemplateContextfeatures/marketplace/state/TemplateContext.tsx画像テンプレートtemplates
useWorldInfoHighlightshared/hooks/characters/useWorldInfoHighlight.tsWI キーワードハイライトhighlightedKeywords

カスタム Hooks

機能ドメインごとに整理された 60 個以上のカスタム Hooks があります。

Chat 関連

Hookファイル目的
useAppStateshared/hooks/useAppState.tsビューフラグ、アクティブタブ、ユーザー設定を一元管理
useRouteSyncshared/hooks/useRouteSync.tsURL パスをビュー状態に同期
useSessionProtectionfeatures/chat/hooks/useSessionProtection.tsアクティブセッションの保護 (更新によるクリアを防止)
useDraftfeatures/chat/hooks/useDraft.ts入力ドラフトの保存/復元
useAutoUpdateshared/hooks/useAutoUpdate.tsアプリの自動更新
useAudioRecorderfeatures/media/hooks/useAudioRecorder.ts音声録音

Feature Hook ディレクトリ

ディレクトリ目的代表的な Hooks
features/chat/hooks/チャット操作useMessageStream, useBranchNavigation
features/marketplace/hooks/channel/Channel プラグインuseChannelPlugins
shared/hooks/characters/character/Character カードuseCharacterCards
shared/hooks/characters/worldinfo/World infouseWorldInfo
shared/hooks/characters/WI ハイライト / タグuseWorldInfoHighlight, useTagsData
features/characters/hooks/sprites/表情 spritesuseSprites
features/settings/components/tabs/tools-tab/hooks/MCP サーバーuseMcpManagement
features/kb/hooks/Notes システムuseNotesData
features/todo/hooks/TodosuseTodoData
features/tasks/hooks/タスク管理useTasksData
features/cron/hooks/予約タスクuseCronJobs
features/marketplace/hooks/skills/Skill 管理useSkillHub

コンポーネントアーキテクチャ

レイアウト構造

graph TB
Root["div.fixed.inset-0.flex.bg-background"]
WS[WorkspaceShell]
WR[WorkspaceRail — left navigation rail]
TB[TitleBar — tab bar + window control]
MC[Main Content — routed content area]

Root --> WS
WS --> WR
WS --> TB
WS --> MC

MC --> ChatPage
MC --> AgentPage
MC --> SettingsPage
MC --> RoleplayPage
MC --> NotesPage
MC --> CoworkPage
  • WorkspaceRail: 左側の固定ナビゲーションレール。Home、Agents、Settings のエントリポイントを含みます
  • WorkspaceShell: メインレイアウトコンテナ。Rail + タブバー + コンテンツ領域を管理します
  • TitleBar: 複数タブバー + ウィンドウ制御ボタン (最大化/最小化/閉じる)
  • Main Content: ルートごとにページコンポーネントを動的にレンダリングします

Workspace 拡張 (Workspace Registry)

Chat/Agent ページ間の「workspace panel」(エディタ / git diff / HTML プレビュー / canvas / design studio の領域で、ファイルツリーの右側) は WorkspaceDefinition registry によって拡張されます。ホストシェルである WorkspaceArea.tsx はレイアウト + registry dispatch のみを担当し、activeView === 'X' のようなビジネス分岐は持ちません

graph TB
WA["WorkspaceArea<br/>(layout + dispatch)"]
Reg["registry.ts<br/>WORKSPACE_REGISTRY[]"]
Slot["WorkspaceToolbarProvider<br/>(slot context)"]
Aff["host-affordances<br/>(cross-view coordination)"]
Defs["definitions/"]

WA -->|findActiveWorkspace| Reg
WA -->|wraps| Slot
WA -->|consumes| Aff
Reg -->|imports| Defs

Defs --> EW[EditorWorkspace]
Defs --> GW[GitWorkspace]
Defs --> HW[HtmlPreviewWorkspace]
Defs --> AW[A2UIWorkspace]
Defs --> DW[DevPreviewWorkspace]
Defs --> DS[DesignStudioWorkspace]
Defs --> CW[CanvasWorkspace]

WorkspaceDefinition は自身で次を管理します。

  • 独自の view 識別子 + isAvailable(ctx) predicate
  • 独自のビューモード状態 (split/code/preview などの内部 useState。ホストには漏れません)
  • useWorkspaceToolbar(config) で toolbar config を slot に公開します。ホストの <WorkspaceToolbar>useWorkspaceToolbarConfig() で読み取ります
  • 任意の onClose(ctx, cb) hook (閉じるボタンでトリガーされ、React tree の外で実行されるため、close-fn チャネルは WorkspaceCallbacks を使用します)

新しい workspace type の追加 = 2 ファイルを変更: registry.ts 配列にエントリを追加し、definitions/<Name>Workspace.tsx を作成します。WorkspaceArea.tsx の変更は不要です。詳細な手順は packages/renderer/CLAUDE.md の「🧩 Add New Workspace Type」セクション、contract spec は openspec/specs/workspace-registry/spec.md にあります。

ビュー間の連携 (例: エディタ内の「Preview」ボタンで htmlPreview view に移動する、HTML プレビューの最大化で workspace pane 全体を隠す) は host-affordances.ts に集約されています。ここだけが activeView === 'X' の判定を許可される場所です。

ファイル責務
features/chat/components/content/WorkspaceArea.tsxホストシェル (レイアウト + slot reader + registry dispatch、ビジネス分岐なし)
features/chat/components/content/workspaces/types.tsWorkspaceDefinition / WorkspaceHostContext / WorkspaceCallbacks contract
features/chat/components/content/workspaces/registry.tsWORKSPACE_REGISTRY の単一登録ポイント + findActiveWorkspace query
features/chat/components/content/workspaces/host-affordances.tsビュー間連携 (cross-view toggle + maximize hide)
features/chat/components/content/workspaces/workspace-toolbar-slot{,-internals,-hooks}.{tsx,ts}Toolbar slot trio (Provider / contexts / hooks)
features/chat/components/content/workspaces/definitions/<Name>Workspace.tsx7 つの workspace 定義 (editor / git / htmlPreview / a2ui / devPreview / designStudio / canvas)
features/chat/components/content/workspaces/inline-file-viewers.tsxInlineMarkdownViewer + InlineBinaryViewer (image/audio/video/pdf + 「プレビュー不可」fallback)
features/chat/components/content/workspaces/inline-file-viewers-types.tsgetBinaryFileType / isMarkdownFile / isNonTextFile file type detection
features/chat/components/content/unified-page/hooks/useWorkspaceState.tsWorkspace state hook (.htmlopenHtmlPreview() routing + handleFileSelect での binary file routing)

ルーティングシステム

HashRouter を使用します (Electron は BrowserRouter をサポートしていません)。useRouteSync Hook で URL をビュー状態に同期します。

// Sync route to view state
function useRouteSync(pathname: string, state: AppState) {
useEffect(() => {
if (pathname.startsWith('/chat')) {
state.setIsChatView(true);
state.setIsHomeView(false);
} else if (pathname.startsWith('/agents')) {
state.setIsAgentView(true);
} else if (pathname.startsWith('/settings')) {
state.setIsSettingsView(true);
}
}, [pathname]);
}

i18n 国際化

useTranslation() Hook を使用して 3 言語をサポートします。

言語ディレクトリファイル
英語locales/en/15+ JSON files
中国語 (簡体字)locales/zh/15+ JSON files
日本語locales/ja/15+ JSON files

翻訳ファイルは機能ドメインごとに分割されています: common.json, chat.json, settings.json, characters.json, elfi.json など。

AppState Hook

useAppState はグローバル UI 状態を一元管理します。

// Simplified AppState interface
interface AppState {
// View flags
isHomeView: boolean;
isChatView: boolean;
isAgentView: boolean;
isSettingsView: boolean;

// Active session
selectedSession: string | null;
activeSessions: Set<string>;
processingSessions: Set<string>;

// Tabs
activeTab: string;
settingsInitialTab: string;

// User preferences
autoExpandTools: boolean;
showRawParameters: boolean;
showThinking: boolean;
autoScrollToBottom: boolean;
sendByCtrlEnter: boolean;

// Modals
showVersionModal: boolean;
}

ビルド設定

ConfigValue
Build toolVite 7.0
StylingTailwind CSS 3.4 + CSS variables (semantic tokens)
Code splittingRoute-level lazy loading (lazy/ directory, 6 files + 1 barrel by purpose)
Tree shakingNamed imports
Main bundle limit500 KB

関連ファイル

ファイル説明
packages/renderer/src/app/App.tsxApp エントリ、Provider 階層とレイアウト
packages/renderer/src/shared/state/chatStore.tsZustand チャット状態 Store
packages/renderer/src/shared/state/settingsStore.tsZustand 設定状態 Store
packages/renderer/src/shared/state/chatStore.ts統合チャット API (旧 UnifiedChatContext は chatStore に移行済み)
packages/renderer/src/shared/state/themeStore.tsTheme Store (旧 ThemeContext)
packages/renderer/src/shared/hooks/useAppState.tsUI 状態の一元管理
packages/renderer/src/shared/hooks/useRouteSync.tsルート同期
packages/renderer/src/app/layout/WorkspaceShell.tsxメインレイアウトコンテナ
packages/renderer/src/app/layout/WorkspaceRail.tsx左側ナビゲーションレール
packages/renderer/src/app/title-bar/タブバーコンポーネント
packages/renderer/src/app/lazy/Lazy load component directory (pages.tsx / workspaces.tsx / inline.tsx / shell.tsx / skeletons.tsx / with-suspense.tsx, barrel in lazy/index.ts)
packages/renderer/src/features/chat/components/content/WorkspaceArea.tsx中央 workspace ホストシェル (レイアウト + registry dispatch、ビジネス分岐なし)
packages/renderer/src/features/chat/components/content/workspaces/Workspace registry (WorkspaceDefinition contract + 7 definition files + toolbar slot + host-affordances)
packages/renderer/src/app/railItems.tsナビゲーションレール設定
packages/renderer/src/app/mainContentRouter.tsxメインコンテンツルーター解析
packages/renderer/CLAUDE.mdフロントエンド UI 開発標準