Files
d04b05b5c8 Detach retained CI and terminal tails from oversized strings (#20960)
* fix(memory): detach retained CI and terminal tails from oversized strings

* fix(terminal): detach retained error and reattach string slices

* fix(terminal): release oversized recent-output backing strings

* fix(terminal): release backing strings held by PTY detectors

* fix(memory): own bounded Claude background task labels

* fix: detach retained terminal mode scan tails

* fix: own retained plugin worker output strings

* fix: own incomplete OSC 133 carry strings

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
2026-09-17 20:34:19 -07:00

95 lines
3.8 KiB
JavaScript

const assert = require('node:assert/strict')
const fs = require('node:fs')
const path = require('node:path')
const Module = require('node:module')
const { createHash } = require('node:crypto')
const { build } = require('esbuild')
const { applyPatch, parsePatch, reversePatch } = require('diff')
const root = path.resolve(__dirname, '../../..')
const sourcePath = 'src/main/plugins/plugin-worker-output-buffer.ts'
const canonicalLf = (value) => value.replaceAll('\r\n', '\n')
const read = (file) => canonicalLf(fs.readFileSync(file, 'utf8'))
const sha = (value) => createHash('sha256').update(value).digest('hex')
function loadSources(readText = read) {
const versionsText = read(path.join(__dirname, 'source-versions.json'))
const versions = JSON.parse(versionsText)
const patches = parsePatch(canonicalLf(readText(path.join(__dirname, 'fix.patch'))))
assert.equal(patches.length, 1)
assert.equal(patches[0].newFileName, `b/${sourcePath}`)
const current = canonicalLf(readText(path.join(root, sourcePath)))
const before = applyPatch(current, reversePatch(patches[0]))
assert.notEqual(before, false, 'The parser no longer matches the reviewed patch')
assert.equal(sha(before), versions.baselineSha256)
assert.equal(sha(current), versions.fixedSha256)
const checkedSources = { [sourcePath]: sha(current) }
for (const [relative, expected] of Object.entries(versions.dependencies)) {
const actual = sha(canonicalLf(readText(path.join(root, relative))))
assert.equal(actual, expected, `Reviewed dependency changed: ${relative}`)
checkedSources[relative] = actual
}
return { before, current, checkedSources, versions, versionsSha256: sha(versionsText) }
}
async function load(variant) {
const checked = loadSources()
let source = variant === 'before' ? checked.before : checked.current
if (variant === 'tail-only') {
source = `import { ownRetainedString } from '../../shared/own-retained-string'\n${checked.before}`
assert.equal(source.split(' buffered += segment').length, 2)
source = source.replace(
' buffered += segment',
' buffered += newline === -1 ? ownRetainedString(segment) : segment'
)
assert.equal(sha(source), checked.versions.tailOnlySha256)
}
const entries = [
"export { pipePluginWorkerOutput } from './src/main/plugins/plugin-worker-output-buffer'",
"export { PluginLogBuffer } from './src/main/plugins/plugin-log-buffer'"
]
if (variant !== 'before') {
entries.push(
"export { ownRetainedString, resetOwnRetainedStringCopier } from './src/shared/own-retained-string'"
)
}
const evaluatedSources = {}
const built = await build({
stdin: { contents: entries.join('\n'), resolveDir: root },
platform: 'node',
format: 'cjs',
bundle: true,
write: false,
plugins: [
{
name: 'hash-fenced-plugin-output',
setup(builder) {
builder.onLoad({ filter: /\.ts$/ }, ({ path: file }) => {
const relative = path.relative(root, file).split(path.sep).join('/')
assert.ok(Object.hasOwn(checked.checkedSources, relative), relative)
const contents = relative === sourcePath ? source : read(file)
evaluatedSources[relative] = sha(contents)
return { contents, loader: 'ts' }
})
}
}
]
})
const filename = path.join(__dirname, `${variant}-bundle.cjs`)
const loaded = new Module(filename, module)
loaded.filename = filename
loaded.paths = Module._nodeModulePaths(root)
loaded._compile(built.outputFiles[0].text, filename)
return {
...loaded.exports,
provenance: {
checkedSources: checked.checkedSources,
evaluatedSources,
sourceVersionsSha256: checked.versionsSha256,
bundleSha256: sha(built.outputFiles[0].text)
}
}
}
module.exports = { load, loadSources, sha, read }