* Scan messages for Read tool_use blocks and collect their file_path inputs * (normalized via expandPath). Used to dedup post-compact file restoration * against what's already visible in the preserved tail. * * Skips Reads whose tool_result is a dedup stub — the stub points at an * earlier full
(messages: Message[])
| 1683 | * createPostCompactFileAttachments to re-inject the real content. |
| 1684 | */ |
| 1685 | function collectReadToolFilePaths(messages: Message[]): Set<string> { |
| 1686 | const stubIds = new Set<string>() |
| 1687 | for (const message of messages) { |
| 1688 | if (message.type !== 'user' || !Array.isArray(message.message.content)) { |
| 1689 | continue |
| 1690 | } |
| 1691 | for (const block of message.message.content) { |
| 1692 | if ( |
| 1693 | block.type === 'tool_result' && |
| 1694 | typeof block.content === 'string' && |
| 1695 | block.content.startsWith(FILE_UNCHANGED_STUB) |
| 1696 | ) { |
| 1697 | stubIds.add(block.tool_use_id) |
| 1698 | } |
| 1699 | } |
| 1700 | } |
| 1701 | |
| 1702 | const paths = new Set<string>() |
| 1703 | for (const message of messages) { |
| 1704 | if ( |
| 1705 | message.type !== 'assistant' || |
| 1706 | !Array.isArray(message.message.content) |
| 1707 | ) { |
| 1708 | continue |
| 1709 | } |
| 1710 | for (const block of message.message.content) { |
| 1711 | if ( |
| 1712 | block.type !== 'tool_use' || |
| 1713 | block.name !== FILE_READ_TOOL_NAME || |
| 1714 | stubIds.has(block.id) |
| 1715 | ) { |
| 1716 | continue |
| 1717 | } |
| 1718 | const input = block.input |
| 1719 | if ( |
| 1720 | input && |
| 1721 | typeof input === 'object' && |
| 1722 | 'file_path' in input && |
| 1723 | typeof input.file_path === 'string' |
| 1724 | ) { |
| 1725 | paths.add(expandPath(input.file_path)) |
| 1726 | } |
| 1727 | } |
| 1728 | } |
| 1729 | return paths |
| 1730 | } |
| 1731 | |
| 1732 | const SKILL_TRUNCATION_MARKER = |
| 1733 | '\n\n[... skill content truncated for compaction; use Read on the skill path if you need the full text]' |
no test coverage detected