refactor(changes): dedup the op-preview path and align conventions
- redaction useMemo: one redactText pass per field (the outcome carries both text and hit; was a hit-scan plus a mask pass), and the banner condition drops the redundant redactionOn check (hit implies on) - three copy-pasted header toggles -> PaneToggle; the md reading body -> MdReadingView (absorbing the mermaid branch + codeLabels) - redaction preference persisted under the repo's dsh-sidebar:v1: prefix - render toggle limited to .html/.htm (the editor html viewer's ext set; .xhtml went beyond any claim) - tsx/jsx share TS_WORDS/JS_WORDS; CSS word list loses its duplicate entries and its nonexistent true/false constants - parseReadContent/parseReadLines share the contentLines() envelope core (content extraction + Showing-lines filter)
This commit is contained in:
@@ -201,6 +201,18 @@ export function knownContentBefore(ops: readonly FileOp[], path: string, before:
|
||||
return undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* The read-tool response's `<content>` body split into lines with the
|
||||
* "(Showing lines …)" note dropped — the shared envelope core both read
|
||||
* parsers consume: {@link parseReadLines} recovers line numbers from the
|
||||
* "<n>: " prefixes, {@link parseReadContent} keeps the raw text.
|
||||
*/
|
||||
function contentLines(raw: string): string[] {
|
||||
const contentMatch = raw.match(/<content>([\s\S]*?)<\/content>/)
|
||||
const body = contentMatch ? contentMatch[1]! : raw
|
||||
return body.split('\n').filter((line) => !/^\s*\(Showing lines .*\)\s*$/.test(line))
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip the DSH read-tool response envelope down to the file's raw content,
|
||||
* PRESERVING blank lines (unlike {@link parseReadLines}, which drops them):
|
||||
@@ -209,11 +221,7 @@ export function knownContentBefore(ops: readonly FileOp[], path: string, before:
|
||||
* because markdown block structure depends on them.
|
||||
*/
|
||||
export function parseReadContent(raw: string): string {
|
||||
const contentMatch = raw.match(/<content>([\s\S]*?)<\/content>/)
|
||||
const body = contentMatch ? contentMatch[1]! : raw
|
||||
return body
|
||||
.split('\n')
|
||||
.filter((line) => !/^\s*\(Showing lines .*\)\s*$/.test(line))
|
||||
return contentLines(raw)
|
||||
.map((line) => line.replace(/^\s*\d+:\s/, ''))
|
||||
.join('\n')
|
||||
.replace(/^[\n]+/, '')
|
||||
@@ -229,12 +237,9 @@ export interface ReadLine { readonly line: number; readonly text: string }
|
||||
* "<n>: " prefix as the line number, falling back to sequential counting.
|
||||
*/
|
||||
export function parseReadLines(raw: string): ReadLine[] {
|
||||
const contentMatch = raw.match(/<content>([\s\S]*?)<\/content>/)
|
||||
const body = contentMatch ? contentMatch[1]! : raw
|
||||
const result: ReadLine[] = []
|
||||
let fallback = 1
|
||||
for (const line of body.split('\n')) {
|
||||
if (/^\s*\(Showing lines .*\)\s*$/.test(line)) continue
|
||||
for (const line of contentLines(raw)) {
|
||||
if (line.length === 0) continue
|
||||
const match = line.match(/^\s*(\d+):\s?(.*)$/)
|
||||
if (match !== null) {
|
||||
|
||||
Reference in New Issue
Block a user