()
| 3790 | handlers: messageActionHandlers |
| 3791 | } = useMessageActions(cursor, setCursor, cursorNavRef, messageActionCaps); |
| 3792 | async function onInit() { |
| 3793 | // Always verify API key on startup, so we can show the user an error in the |
| 3794 | // bottom right corner of the screen if the API key is invalid. |
| 3795 | void reverify(); |
| 3796 | |
| 3797 | // Populate readFileState with CLAUDE.md files at startup |
| 3798 | const memoryFiles = await getMemoryFiles(); |
| 3799 | if (memoryFiles.length > 0) { |
| 3800 | const fileList = memoryFiles.map(f => ` [${f.type}] ${f.path} (${f.content.length} chars)${f.parent ? ` (included by ${f.parent})` : ''}`).join('\n'); |
| 3801 | logForDebugging(`Loaded ${memoryFiles.length} CLAUDE.md/rules files:\n${fileList}`); |
| 3802 | } else { |
| 3803 | logForDebugging('No CLAUDE.md/rules files found'); |
| 3804 | } |
| 3805 | for (const file of memoryFiles) { |
| 3806 | // When the injected content doesn't match disk (stripped HTML comments, |
| 3807 | // stripped frontmatter, MEMORY.md truncation), cache the RAW disk bytes |
| 3808 | // with isPartialView so Edit/Write require a real Read first while |
| 3809 | // getChangedFiles + nested_memory dedup still work. |
| 3810 | readFileState.current.set(file.path, { |
| 3811 | content: file.contentDiffersFromDisk ? file.rawContent ?? file.content : file.content, |
| 3812 | timestamp: Date.now(), |
| 3813 | offset: undefined, |
| 3814 | limit: undefined, |
| 3815 | isPartialView: file.contentDiffersFromDisk |
| 3816 | }); |
| 3817 | } |
| 3818 | |
| 3819 | // Initial message handling is done via the initialMessage effect |
| 3820 | } |
| 3821 | |
| 3822 | // Register cost summary tracker |
| 3823 | useCostSummary(useFpsMetrics()); |
no test coverage detected