MCPcopy Index your code
hub / github.com/claude-code-best/claude-code / removeMessageByUuid

Method removeMessageByUuid

src/utils/sessionStorage.ts:893–973  ·  view source on GitHub ↗

* Remove a message from the transcript by UUID. * Used for tombstoning orphaned messages from failed streaming attempts. * * The target is almost always the most recently appended entry, so we * read only the tail, locate the line, and splice it out with a * positional write + truncat

(targetUuid: UUID)

Source from the content-addressed store, hash-verified

891 * positional write + truncate instead of rewriting the whole file.
892 */
893 async removeMessageByUuid(targetUuid: UUID): Promise<void> {
894 return this.trackWrite(async () => {
895 if (this.sessionFile === null) return
896 try {
897 let fileSize = 0
898 const fh = await fsOpen(this.sessionFile, 'r+')
899 try {
900 const { size } = await fh.stat()
901 fileSize = size
902 if (size === 0) return
903
904 const chunkLen = Math.min(size, LITE_READ_BUF_SIZE)
905 const tailStart = size - chunkLen
906 const buf = Buffer.allocUnsafe(chunkLen)
907 const { bytesRead } = await fh.read(buf, 0, chunkLen, tailStart)
908 const tail = buf.subarray(0, bytesRead)
909
910 // Entries are serialized via JSON.stringify (no key-value
911 // whitespace). Search for the full `"uuid":"..."` pattern, not
912 // just the bare UUID, so we do not match the same value sitting
913 // in `parentUuid` of a child entry. UUIDs are pure ASCII so a
914 // byte-level search is correct.
915 const needle = `"uuid":"${targetUuid}"`
916 const matchIdx = tail.lastIndexOf(needle)
917
918 if (matchIdx >= 0) {
919 // 0x0a never appears inside a UTF-8 multi-byte sequence, so
920 // byte-scanning for line boundaries is safe even if the chunk
921 // starts mid-character.
922 const prevNl = tail.lastIndexOf(0x0a, matchIdx)
923 // If the preceding newline is outside our chunk and we did not
924 // read from the start of the file, the line is longer than the
925 // window - fall through to the slow path.
926 if (prevNl >= 0 || tailStart === 0) {
927 const lineStart = prevNl + 1 // 0 when prevNl === -1
928 const nextNl = tail.indexOf(0x0a, matchIdx + needle.length)
929 const lineEnd = nextNl >= 0 ? nextNl + 1 : bytesRead
930
931 const absLineStart = tailStart + lineStart
932 const afterLen = bytesRead - lineEnd
933 // Truncate first, then re-append the trailing lines. In the
934 // common case (target is the last entry) afterLen is 0 and
935 // this is a single ftruncate.
936 await fh.truncate(absLineStart)
937 if (afterLen > 0) {
938 await fh.write(tail, lineEnd, afterLen, absLineStart)
939 }
940 return
941 }
942 }
943 } finally {
944 await fh.close()
945 }
946
947 // Slow path: target was not in the last 64KB. Rare - requires many
948 // large entries to have landed between the write and the tombstone.
949 if (fileSize > MAX_TOMBSTONE_REWRITE_BYTES) {
950 logForDebugging(

Callers 1

removeTranscriptMessageFunction · 0.80

Calls 8

trackWriteMethod · 0.95
formatFileSizeFunction · 0.85
readFileFunction · 0.85
jsonParseFunction · 0.85
logForDebuggingFunction · 0.70
closeMethod · 0.65
readMethod · 0.45
writeMethod · 0.45

Tested by

no test coverage detected