surshar / claude-code
Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.
Built by Anthropic · github.com/anthropics
| 1 | import type { SessionMessage } from 'claude-code' |
| 2 | |
| 3 | import Git from '../../git' |
| 4 | import type Types from '../types' |
| 5 | import { fileEditOf } from './file-edit-of' |
| 6 | import { PREVIEW_CHARS } from './preview-chars' |
| 7 | |
| 8 | /** |
| 9 | * One turn's rows (its prompt first) as the files its tool calls edited, |
| 10 | * as the built-in turn view reads them. |
| 11 | * |
| 12 | * A file edited twice keeps both calls' hunks (cut at MAX_LINES_PER_FILE |
| 13 | * in all) and the summed counts, and one created then edited stays new. |
| 14 | * |
| 15 | * @param rows the prompt row through the last row before the next prompt |
| 16 | * @param index the turn's number, from 1 |
| 17 | * @returns the turn; `files` empty when nothing was edited |
| 18 | */ |
| 19 | export function turnOf( |
| 20 | rows: readonly SessionMessage[], |
| 21 | index: number, |
| 22 | ): Types.TurnDiff { |
| 23 | const text = rows[0]?.text ?? '' |
| 24 | const isShort = [...text].length <= PREVIEW_CHARS |
| 25 | |
| 26 | const preview = isShort |
| 27 | ? text |
| 28 | : `${[...text].slice(0, PREVIEW_CHARS - 1).join('')}…` |
| 29 | |
| 30 | const edits = rows |
| 31 | .flatMap(row => (row.role === 'assistant' ? row.toolUses : [])) |
| 32 | .map(use => fileEditOf(use.result)) |
| 33 | .filter((edit): edit is Types.TurnFile => edit !== null) |
| 34 | |
| 35 | const byPath = new Map<string, Types.TurnFile>() |
| 36 | |
| 37 | for (const edit of edits) { |
| 38 | const earlier = byPath.get(edit.path) |
| 39 | |
| 40 | byPath.set( |
| 41 | edit.path, |
| 42 | earlier |
| 43 | ? { |
| 44 | path: edit.path, |
| 45 | hunks: [...earlier.hunks, ...edit.hunks], |
| 46 | added: earlier.added + edit.added, |
| 47 | removed: earlier.removed + edit.removed, |
| 48 | isNewFile: earlier.isNewFile || edit.isNewFile, |
| 49 | isTruncated: false, |
| 50 | } |
| 51 | : edit, |
| 52 | ) |
| 53 | } |
| 54 | |
| 55 | const files = [...byPath.values()].map(file => ({ |
| 56 | ...file, |
| 57 | ...Git.cutHunks(file.hunks), |
| 58 | })) |
| 59 | |
| 60 | return { index, preview, files } |
| 61 | } |