* 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[])
| 1608 | * createPostCompactFileAttachments to re-inject the real content. |
| 1609 | */ |
| 1610 | function collectReadToolFilePaths(messages: Message[]): Set<string> { |
| 1611 | const stubIds = new Set<string>() |
| 1612 | for (const message of messages) { |
| 1613 | if (message.type !== 'user' || !Array.isArray(message.message.content)) { |
| 1614 | continue |
| 1615 | } |
| 1616 | for (const block of message.message.content) { |
| 1617 | if ( |
| 1618 | block.type === 'tool_result' && |
| 1619 | typeof block.content === 'string' && |
| 1620 | block.content.startsWith(FILE_UNCHANGED_STUB) |
| 1621 | ) { |
| 1622 | stubIds.add(block.tool_use_id) |
| 1623 | } |
| 1624 | } |
| 1625 | } |
| 1626 | |
| 1627 | const paths = new Set<string>() |
| 1628 | for (const message of messages) { |
| 1629 | if ( |
| 1630 | message.type !== 'assistant' || |
| 1631 | !Array.isArray(message.message.content) |
| 1632 | ) { |
| 1633 | continue |
| 1634 | } |
| 1635 | for (const block of message.message.content) { |
| 1636 | if ( |
| 1637 | block.type !== 'tool_use' || |
| 1638 | block.name !== FILE_READ_TOOL_NAME || |
| 1639 | stubIds.has(block.id) |
| 1640 | ) { |
| 1641 | continue |
| 1642 | } |
| 1643 | const input = block.input |
| 1644 | if ( |
| 1645 | input && |
| 1646 | typeof input === 'object' && |
| 1647 | 'file_path' in input && |
| 1648 | typeof input.file_path === 'string' |
| 1649 | ) { |
| 1650 | paths.add(expandPath(input.file_path)) |
| 1651 | } |
| 1652 | } |
| 1653 | } |
| 1654 | return paths |
| 1655 | } |
| 1656 | |
| 1657 | const SKILL_TRUNCATION_MARKER = |
| 1658 | '\n\n[... skill content truncated for compaction; use Read on the skill path if you need the full text]' |
no test coverage detected