* feat(anthropic-auto-compact): add aggressive truncation and empty message recovery
Add truncateUntilTargetTokens method, empty content recovery mechanism, and
emptyContentAttemptBySession tracking for robust message handling.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
* feat(session-recovery): add auto-resume and recovery callbacks
Implement ResumeConfig, resumeSession() method, and callback support for
enhanced session recovery and resume functionality.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
* feat(config): add experimental config schema for gating unstable features
This adds a new 'experimental' config field to the OhMyOpenCode schema that enables fine-grained control over unstable/experimental features:
- aggressive_truncation: Enables aggressive token truncation in anthropic-auto-compact hook for more aggressive token limit handling
- empty_message_recovery: Enables empty message recovery mechanism in anthropic-auto-compact hook for fixing truncation-induced empty message errors
- auto_resume: Enables automatic session resume after recovery in session-recovery hook for seamless recovery experience
The experimental config is optional and all experimental features are disabled by default, ensuring backward compatibility while allowing early adopters to opt-in to cutting-edge features.
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Directly modify empty text parts in storage files before attempting
to inject new parts. This ensures that existing empty text parts are
replaced with placeholder text, fixing the issue where Anthropic API
returns 'messages.X: all messages must have non-empty content' error
even after recovery.
- Added replaceEmptyTextParts function to directly replace empty text parts
- Added findMessagesWithEmptyTextParts function to identify affected messages
- Modified recoverEmptyContentMessage to prioritize replacing existing empty parts
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Add pattern matching for 'content...is empty' format to detectErrorType function
in session-recovery hook. This fixes detection of Anthropic API errors like
'The content field in the Message object at messages.65 is empty'.
Previously only caught 'non-empty content' and 'must have non-empty content'
patterns, missing this actual API error format.
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
When OpenCode API doesn't return parts in message response,
read directly from filesystem using readParts(messageID).
This fixes session recovery failures where tool_use IDs couldn't
be extracted because API response had empty parts array.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Add findMessagesWithThinkingOnly() to detect orphan thinking messages
- Inject [user interrupted] placeholder for thinking-only messages
- Expand index offset handling from 2 to 3 attempts for better error recovery
- Use constant PLACEHOLDER_TEXT for consistency across recovery functions
- Add findMessageByIndexNeedingThinking for precise message targeting
- Detect "expected X found Y" error pattern for thinking block order
- Remove isLastMessage skip - recovery now handles final assistant messages
- Simplify orphan detection: any non-thinking first part is orphan
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Extract message index from Anthropic error messages (messages.N format)
- Sort messages by time.created instead of id for accurate ordering
- Remove last message skip logic that prevented recovery
- Prioritize recovery targets: index-matched > failedMsg > all empty
- Add error logging for debugging recovery failures
Fixes issue where 'messages.83: all messages must have non-empty content' errors were not being recovered properly due to incorrect message ordering and overly restrictive filtering.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Scan all non-final assistant messages for empty content, orphan thinking blocks, and disabled thinking
- Add storage utility functions: findMessagesWithThinkingBlocks, findMessagesWithOrphanThinking, stripThinkingParts, prependThinkingPart
- Fix: Previously only processed single failed message, now handles multiple broken messages in history
- Improve: Use filesystem-based recovery instead of unreliable SDK APIs
Split session-recovery.ts into modular structure:
- types.ts: SDK-aligned type definitions
- constants.ts: storage paths and part type sets
- storage.ts: reusable read/write operations
- index.ts: main recovery hook logic