@mrsf/cli 0.4.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/dist/browser.cjs +1046 -0
- package/dist/browser.cjs.map +7 -0
- package/dist/browser.d.ts +17 -1
- package/dist/browser.js +15 -0
- package/dist/commands/reanchor.js +3 -0
- package/dist/index.cjs +2184 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.js +10 -0
- package/dist/lib/comments.js +2 -2
- package/dist/lib/fuzzy.js +15 -152
- package/dist/lib/identity.d.ts +12 -0
- package/dist/lib/identity.js +23 -0
- package/dist/lib/parser.d.ts +4 -19
- package/dist/lib/parser.js +4 -140
- package/dist/lib/reanchor-core.d.ts +17 -1
- package/dist/lib/reanchor-core.js +141 -18
- package/dist/lib/reanchor.d.ts +1 -1
- package/dist/lib/reanchor.js +5 -3
- package/dist/lib/schema.d.ts +106 -0
- package/dist/lib/schema.js +3 -0
- package/dist/lib/serialize.d.ts +37 -0
- package/dist/lib/serialize.js +170 -0
- package/dist/lib/types.d.ts +25 -0
- package/dist/lib/validate-core.d.ts +6 -0
- package/dist/lib/validate-core.js +128 -0
- package/dist/lib/validator.js +4 -112
- package/dist/lib/writer.d.ts +1 -8
- package/dist/lib/writer.js +5 -14
- package/package.json +14 -6
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/browser.ts", "../src/lib/fuzzy.ts", "../src/lib/identity.ts", "../src/lib/reanchor-core.ts", "../src/lib/validate-core.ts", "../mrsf.schema.json", "../src/lib/schema.ts", "../src/lib/serialize.ts"],
|
|
4
|
+
"sourcesContent": ["import * as fuzzy from \"./lib/fuzzy.js\";\nimport * as identity from \"./lib/identity.js\";\nimport * as reanchorCore from \"./lib/reanchor-core.js\";\nimport * as validateCore from \"./lib/validate-core.js\";\nimport * as serialize from \"./lib/serialize.js\";\nimport { mrsfSchema } from \"./lib/schema.js\";\n\nexport type {\n AnchorPosition,\n Comment,\n DiffHunk,\n FuzzyCandidate,\n MrsfDocument,\n ReanchorResult,\n ReanchorStatus,\n ValidationDiagnostic,\n ValidationResult,\n DiagnosticSeverity,\n} from \"./lib/types.js\";\nexport type { ParsedAuthor } from \"./lib/identity.js\";\nexport type { LenientParseResult } from \"./lib/serialize.js\";\n\n// Parse / serialize (pure string \u21C4 document; no filesystem or argv deps).\nexport const parseSidecarContent = serialize.parseSidecarContent;\nexport const parseSidecarContentLenient = serialize.parseSidecarContentLenient;\nexport const toYaml = serialize.toYaml;\nexport const toJson = serialize.toJson;\n\nexport const combinedScore = fuzzy.combinedScore;\nexport const exactMatch = fuzzy.exactMatch;\nexport const fuzzySearch = fuzzy.fuzzySearch;\nexport const levenshteinScore = fuzzy.levenshteinScore;\nexport const normalizedMatch = fuzzy.normalizedMatch;\nexport const tokenLcsScore = fuzzy.tokenLcsScore;\n\nexport const applyReanchorResults = reanchorCore.applyReanchorResults;\nexport const DEFAULT_THRESHOLD = reanchorCore.DEFAULT_THRESHOLD;\nexport const HIGH_THRESHOLD = reanchorCore.HIGH_THRESHOLD;\nexport const reanchorComment = reanchorCore.reanchorComment;\nexport const reanchorDocumentLines = reanchorCore.reanchorDocumentLines;\nexport const reanchorDocumentText = reanchorCore.reanchorDocumentText;\nexport const resolveAnchor = reanchorCore.resolveAnchor;\nexport const toReanchorLines = reanchorCore.toReanchorLines;\n\nexport const validateDocument = validateCore.validateDocument;\nexport { mrsfSchema };\n\nexport const formatAuthor = identity.formatAuthor;\nexport const parseAuthor = identity.parseAuthor;\nexport const newCommentId = identity.newCommentId;\n", "/**\n * MRSF Fuzzy Matching Engine\n *\n * Provides exact, normalized, token-level LCS, and character-level\n * Levenshtein matching for re-anchoring selected_text.\n */\n\nimport { distance as levenshtein } from \"fastest-levenshtein\";\nimport type { FuzzyCandidate } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Exact matching\n// ---------------------------------------------------------------------------\n\n/**\n * Find all exact occurrences of `needle` in lines (1-based array).\n */\nexport function exactMatch(\n lines: string[],\n needle: string,\n): FuzzyCandidate[] {\n if (!needle) return [];\n\n const results: FuzzyCandidate[] = [];\n const needleLines = needle.split(\"\\n\");\n const needleLineCount = needleLines.length;\n\n // Slide a window across the document\n for (let startLine = 1; startLine <= lines.length - needleLineCount; startLine++) {\n // Build the text for this window\n const windowLines = lines.slice(startLine, startLine + needleLineCount);\n const windowText = windowLines.join(\"\\n\");\n\n // Check if the needle appears anywhere within this window (for single-line)\n if (needleLineCount === 1) {\n let col = 0;\n const line = windowLines[0];\n while (col < line.length) {\n const idx = line.indexOf(needle, col);\n if (idx === -1) break;\n results.push({\n text: needle,\n line: startLine,\n endLine: startLine,\n startColumn: idx,\n endColumn: idx + needle.length,\n score: 1.0,\n });\n col = idx + 1;\n }\n } else {\n // Multi-line: check if the window contains the exact needle\n const idx = windowText.indexOf(needle);\n if (idx !== -1) {\n // Calculate start column\n const beforeMatch = windowText.slice(0, idx);\n const linesBeforeEnd = beforeMatch.split(\"\\n\");\n const startCol = linesBeforeEnd[linesBeforeEnd.length - 1].length;\n\n // Calculate end column\n const afterMatch = needle.split(\"\\n\");\n const endCol = afterMatch[afterMatch.length - 1].length;\n if (startCol === 0 || linesBeforeEnd.length === 1) {\n results.push({\n text: needle,\n line: startLine + linesBeforeEnd.length - 1,\n endLine: startLine + linesBeforeEnd.length - 1 + afterMatch.length - 1,\n startColumn: startCol,\n endColumn: endCol,\n score: 1.0,\n });\n }\n }\n }\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Normalized matching (collapse whitespace)\n// ---------------------------------------------------------------------------\n\nfunction normalize(text: string): string {\n return text.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Find matches after normalizing whitespace.\n */\nexport function normalizedMatch(\n lines: string[],\n needle: string,\n): FuzzyCandidate[] {\n const normNeedle = normalize(needle);\n if (!normNeedle) return [];\n\n const results: FuzzyCandidate[] = [];\n\n // Try expanding windows of varying sizes\n const needleLineEstimate = needle.split(\"\\n\").length;\n const minWindow = Math.max(1, needleLineEstimate - 1);\n const maxWindow = Math.min(lines.length - 1, needleLineEstimate + 2);\n\n for (let winSize = minWindow; winSize <= maxWindow; winSize++) {\n for (let startLine = 1; startLine + winSize - 1 < lines.length; startLine++) {\n const windowLines = lines.slice(startLine, startLine + winSize);\n const windowText = windowLines.join(\"\\n\");\n const normWindow = normalize(windowText);\n\n if (normWindow.includes(normNeedle)) {\n results.push({\n text: windowText,\n line: startLine,\n endLine: startLine + winSize - 1,\n startColumn: 0,\n endColumn: windowLines[windowLines.length - 1].length,\n score: 0.95,\n });\n }\n }\n }\n\n return deduplicateCandidates(results);\n}\n\n// ---------------------------------------------------------------------------\n// Token-level LCS\n// ---------------------------------------------------------------------------\n\nfunction tokenize(text: string): string[] {\n return text.split(/\\s+/).filter((t) => t.length > 0);\n}\n\n/**\n * Longest Common Subsequence length of two token arrays.\n */\nfunction lcsLength(a: string[], b: string[]): number {\n const m = a.length;\n const n = b.length;\n // Optimize: use two rows instead of full matrix\n let prev = new Array<number>(n + 1).fill(0);\n let curr = new Array<number>(n + 1).fill(0);\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (a[i - 1] === b[j - 1]) {\n curr[j] = prev[j - 1] + 1;\n } else {\n curr[j] = Math.max(prev[j], curr[j - 1]);\n }\n }\n [prev, curr] = [curr, prev];\n curr.fill(0);\n }\n\n return prev[n];\n}\n\n/**\n * Score two texts using token-level LCS.\n * Returns 0.0\u20131.0.\n */\nexport function tokenLcsScore(a: string, b: string): number {\n const tokA = tokenize(a);\n const tokB = tokenize(b);\n if (tokA.length === 0 && tokB.length === 0) return 1.0;\n if (tokA.length === 0 || tokB.length === 0) return 0.0;\n const lcs = lcsLength(tokA, tokB);\n return lcs / Math.max(tokA.length, tokB.length);\n}\n\n// ---------------------------------------------------------------------------\n// Character-level Levenshtein score\n// ---------------------------------------------------------------------------\n\n/**\n * Normalized Levenshtein similarity 0.0\u20131.0.\n */\nexport function levenshteinScore(a: string, b: string): number {\n if (a.length === 0 && b.length === 0) return 1.0;\n const maxLen = Math.max(a.length, b.length);\n if (maxLen === 0) return 1.0;\n const dist = levenshtein(a, b);\n return 1 - dist / maxLen;\n}\n\n// ---------------------------------------------------------------------------\n// Combined fuzzy scoring\n// ---------------------------------------------------------------------------\n\n/**\n * Compute a combined similarity score between two text fragments.\n * Blends token LCS (structural) and Levenshtein (character-level).\n */\nexport function combinedScore(needle: string, candidate: string): number {\n const tScore = tokenLcsScore(needle, candidate);\n\n // Full Levenshtein is expensive for long texts; only use for short ones\n let lScore: number;\n if (needle.length < 500 && candidate.length < 500) {\n lScore = levenshteinScore(needle, candidate);\n } else {\n lScore = tScore; // fall back to token score only\n }\n\n // Weight: 60% token LCS, 40% Levenshtein\n return tScore * 0.6 + lScore * 0.4;\n}\n\n// ---------------------------------------------------------------------------\n// Fuzzy search across document\n// ---------------------------------------------------------------------------\n\n/**\n * Search the document for fuzzy matches of `needle`.\n *\n * @param lines 1-based line array (index 0 unused).\n * @param needle The original selected_text.\n * @param threshold Minimum score to include (0.0\u20131.0).\n * @param hintLine Optional original line number for proximity scoring.\n */\nexport function fuzzySearch(\n lines: string[],\n needle: string,\n threshold: number = 0.6,\n hintLine?: number,\n): FuzzyCandidate[] {\n if (!needle) return [];\n\n const needleLines = needle.split(\"\\n\");\n const needleLineCount = needleLines.length;\n const candidates: FuzzyCandidate[] = [];\n\n // Window sizes: \u00B130% of original line count, minimum 1\n const minWindow = Math.max(1, Math.floor(needleLineCount * 0.7));\n const maxWindow = Math.min(\n lines.length - 1,\n Math.ceil(needleLineCount * 1.3) + 1,\n );\n\n for (let winSize = minWindow; winSize <= maxWindow; winSize++) {\n for (let startLine = 1; startLine + winSize - 1 < lines.length; startLine++) {\n const windowLines = lines.slice(startLine, startLine + winSize);\n const windowText = windowLines.join(\"\\n\");\n\n const score = combinedScore(needle, windowText);\n\n if (score >= threshold) {\n candidates.push({\n text: windowText,\n line: startLine,\n endLine: startLine + winSize - 1,\n startColumn: 0,\n endColumn: windowLines[windowLines.length - 1].length,\n score,\n });\n }\n }\n }\n\n // For single-line needles, also try substring matching within each line\n if (needleLineCount === 1 && needle.length < 200) {\n for (let lineNum = 1; lineNum < lines.length; lineNum++) {\n const line = lines[lineNum];\n if (!line) continue;\n\n // Sliding window within line\n const winLen = needle.length;\n const minWinLen = Math.max(3, Math.floor(winLen * 0.7));\n const maxWinLen = Math.min(line.length, Math.ceil(winLen * 1.3));\n\n for (let len = minWinLen; len <= maxWinLen; len++) {\n for (let col = 0; col + len <= line.length; col++) {\n const sub = line.substring(col, col + len);\n const score = combinedScore(needle, sub);\n if (score >= threshold) {\n candidates.push({\n text: sub,\n line: lineNum,\n endLine: lineNum,\n startColumn: col,\n endColumn: col + len,\n score,\n });\n }\n }\n }\n }\n }\n\n // Deduplicate and sort\n let deduped = deduplicateCandidates(candidates);\n\n // Apply proximity bonus if hintLine is provided\n if (hintLine != null) {\n deduped = deduped.map((c) => {\n const dist = Math.abs(c.line - hintLine);\n // Small bonus for proximity (up to 0.1 for exact line match)\n const proximityBonus = 0.1 * Math.max(0, 1 - dist / 50);\n return { ...c, score: Math.min(1.0, c.score + proximityBonus) };\n });\n }\n\n return deduped.sort((a, b) => b.score - a.score);\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction deduplicateCandidates(\n candidates: FuzzyCandidate[],\n): FuzzyCandidate[] {\n const seen = new Map<string, FuzzyCandidate>();\n for (const c of candidates) {\n const key = `${c.line}:${c.startColumn}:${c.endLine}:${c.endColumn}`;\n const existing = seen.get(key);\n if (!existing || c.score > existing.score) {\n seen.set(key, c);\n }\n }\n return Array.from(seen.values());\n}\n", "import { v4 as uuidv4 } from \"uuid\";\n\nexport interface ParsedAuthor {\n name: string;\n handle?: string;\n}\n\nexport function formatAuthor(name: string, handle?: string): string {\n const trimmedName = name.trim();\n const trimmedHandle = handle?.trim();\n return trimmedHandle ? `${trimmedName} (${trimmedHandle})` : trimmedName;\n}\n\nexport function parseAuthor(author: string): ParsedAuthor {\n const trimmed = author.trim();\n const match = /^(.*?)\\s*\\(([^()]*)\\)\\s*$/.exec(trimmed);\n if (!match) return { name: trimmed };\n\n const name = match[1].trim();\n const handle = match[2].trim();\n return handle ? { name, handle } : { name };\n}\n\n/**\n * Create a collision-resistant MRSF comment id.\n * ULID is also permitted by the spec; UUIDv4 is the default for this package.\n */\nexport function newCommentId(): string {\n return uuidv4();\n}\n", "import type {\n AnchorPosition,\n Comment,\n DiffHunk,\n FuzzyCandidate,\n MrsfDocument,\n ReanchorResult,\n} from \"./types.js\";\nimport {\n exactMatch,\n fuzzySearch,\n normalizedMatch,\n} from \"./fuzzy.js\";\n\nexport const HIGH_THRESHOLD = 0.8;\nexport const DEFAULT_THRESHOLD = 0.6;\n\n/**\n * Default proximity window (in lines) for the \u00A77.4 step 1a relocation guard.\n *\n * A lone exact match of `selected_text` that lands farther than this many\n * lines from the comment's original `line` \u2014 while the text at the original\n * position has changed \u2014 is treated as an in-place edit rather than a\n * confident relocation. See {@link isImplausibleExactRelocation}.\n */\nexport const DEFAULT_PROXIMITY_WINDOW = 5;\n\nexport function toReanchorLines(documentText: string): string[] {\n return [\"\", ...documentText.replace(/\\r\\n/g, \"\\n\").split(\"\\n\")];\n}\n\nexport function reanchorComment(\n comment: Comment,\n documentLines: string[],\n opts: {\n diffHunks?: DiffHunk[];\n threshold?: number;\n commitIsStale?: boolean;\n proximityWindow?: number;\n } = {},\n): ReanchorResult {\n const threshold = opts.threshold ?? DEFAULT_THRESHOLD;\n const proximityWindow = opts.proximityWindow ?? DEFAULT_PROXIMITY_WINDOW;\n const commentId = comment.id;\n const selectedText = comment.selected_text;\n\n if (!selectedText && comment.line == null) {\n return {\n commentId,\n status: \"anchored\",\n score: 1.0,\n reason: \"Document-level comment (no anchor needed).\",\n };\n }\n\n if (comment.line != null && opts.diffHunks?.length) {\n const { shift, modified } = getLineShift(opts.diffHunks, comment.line);\n\n if (!selectedText) {\n const shiftedLine = comment.line + shift;\n const lineSpan =\n comment.end_line != null ? comment.end_line - comment.line : 0;\n const shiftedEndLine =\n comment.end_line != null ? shiftedLine + lineSpan : undefined;\n return {\n commentId,\n status: shift === 0 ? \"anchored\" : \"shifted\",\n score: 1.0,\n newLine: shiftedLine,\n newEndLine: shiftedEndLine,\n reason:\n shift === 0\n ? \"Line-only comment unchanged (diff confirms position).\"\n : `Line-only comment shifted by ${shift > 0 ? \"+\" : \"\"}${shift} line(s) via diff.`,\n };\n }\n\n if (!modified) {\n const shiftedLine = comment.line + shift;\n const lineSpan =\n comment.end_line != null ? comment.end_line - comment.line : 0;\n const shiftedEndLine =\n comment.end_line != null ? shiftedLine + lineSpan : undefined;\n\n const textAtShifted = extractText(\n documentLines,\n shiftedLine,\n shiftedEndLine,\n comment.start_column,\n comment.end_column,\n );\n\n if (textAtShifted === selectedText) {\n return {\n commentId,\n status: shift === 0 ? \"anchored\" : \"shifted\",\n score: 1.0,\n newLine: shiftedLine,\n newEndLine: shiftedEndLine,\n reason:\n shift === 0\n ? \"Diff confirms text unchanged at original position.\"\n : `Diff shifted by ${shift > 0 ? \"+\" : \"\"}${shift} line(s).`,\n };\n }\n }\n }\n\n if (selectedText) {\n const exactCandidates = exactMatch(documentLines, selectedText);\n\n // Pick the best exact candidate: the only one, or \u2014 when several remain \u2014\n // the one nearest to the original line (\u00A77.4 step 1b).\n let chosen: FuzzyCandidate | undefined;\n let chosenReason = \"\";\n if (exactCandidates.length === 1) {\n chosen = exactCandidates[0];\n chosenReason = \"Exact text match (unique).\";\n } else if (exactCandidates.length > 1 && comment.line != null) {\n chosen = closestToLine(exactCandidates, comment.line);\n chosenReason = `Exact text match (${exactCandidates.length} occurrences; chose nearest to original line ${comment.line}).`;\n }\n\n if (chosen) {\n // \u00A77.4 step 1a proximity guard: a lone/closest exact match that lands far\n // from the original position \u2014 while the text at the original position no\n // longer equals selected_text \u2014 most likely indicates an in-place edit of\n // the anchored text, not a genuine relocation. Keep the comment at its\n // original position and flag it for re-anchoring instead of teleporting it\n // onto an unrelated identical token with full confidence.\n if (isImplausibleExactRelocation(comment, chosen, documentLines, proximityWindow)) {\n const textAtOrigin = extractText(\n documentLines,\n comment.line as number,\n comment.end_line,\n comment.start_column,\n comment.end_column,\n );\n return {\n commentId,\n status: \"fuzzy\",\n score: 0.5,\n newLine: comment.line,\n newEndLine: comment.end_line,\n newStartColumn: comment.start_column,\n newEndColumn: comment.end_column,\n anchoredText: textAtOrigin ?? undefined,\n previousSelectedText: selectedText,\n reason:\n `Lone exact match at line ${chosen.line} is beyond the proximity window ` +\n `(\u00B1${proximityWindow}) of original line ${comment.line} and the text at the ` +\n `original position changed; kept at original position, needs re-anchoring.`,\n };\n }\n\n return {\n commentId,\n status: \"anchored\",\n score: 1.0,\n newLine: chosen.line,\n newEndLine: chosen.endLine,\n newStartColumn: chosen.startColumn,\n newEndColumn: chosen.endColumn,\n reason: chosenReason,\n };\n }\n\n const normCandidates = normalizedMatch(documentLines, selectedText);\n if (normCandidates.length === 1) {\n const candidate = normCandidates[0];\n return {\n commentId,\n status: \"fuzzy\",\n score: candidate.score,\n newLine: candidate.line,\n newEndLine: candidate.endLine,\n newStartColumn: candidate.startColumn,\n newEndColumn: candidate.endColumn,\n anchoredText: candidate.text,\n previousSelectedText: selectedText,\n reason: \"Normalized whitespace match.\",\n };\n }\n\n const fuzzyCandidates = fuzzySearch(\n documentLines,\n selectedText,\n HIGH_THRESHOLD,\n comment.line,\n );\n\n if (fuzzyCandidates.length === 1 || (fuzzyCandidates.length > 0 && fuzzyCandidates[0].score >= HIGH_THRESHOLD)) {\n const best =\n fuzzyCandidates.length === 1\n ? fuzzyCandidates[0]\n : closestToLine(fuzzyCandidates, comment.line ?? 1);\n return {\n commentId,\n status: \"fuzzy\",\n score: best.score,\n newLine: best.line,\n newEndLine: best.endLine,\n newStartColumn: best.startColumn,\n newEndColumn: best.endColumn,\n anchoredText: best.text,\n previousSelectedText: selectedText,\n reason: `High-confidence fuzzy match (score ${best.score.toFixed(3)}).`,\n };\n }\n }\n\n if (comment.line != null) {\n const lineIdx = comment.line;\n if (lineIdx > 0 && lineIdx < documentLines.length) {\n const qualifier = opts.commitIsStale\n ? \" (commit is stale \u2014 line may have shifted)\"\n : \"\";\n\n if (selectedText) {\n const lineText = documentLines[lineIdx];\n const candidates = fuzzySearch([\"\", lineText], selectedText, DEFAULT_THRESHOLD);\n if (candidates.length > 0) {\n return {\n commentId,\n status: \"fuzzy\",\n score: candidates[0].score,\n newLine: comment.line,\n newEndLine: comment.end_line,\n anchoredText: candidates[0].text,\n previousSelectedText: selectedText,\n reason: `Line-fallback with fuzzy text match (score ${candidates[0].score.toFixed(3)})${qualifier}.`,\n };\n }\n }\n\n const isLineOnly = !selectedText;\n return {\n commentId,\n status: isLineOnly ? \"anchored\" : (opts.commitIsStale ? \"ambiguous\" : \"anchored\"),\n score: isLineOnly ? 1.0 : (opts.commitIsStale ? 0.5 : 0.8),\n newLine: comment.line,\n newEndLine: comment.end_line,\n reason: isLineOnly\n ? \"Line-only comment (no selected_text to verify).\"\n : `Line/column fallback${qualifier}.`,\n };\n }\n }\n\n if (selectedText) {\n const lowCandidates = fuzzySearch(\n documentLines,\n selectedText,\n threshold,\n comment.line,\n );\n\n if (lowCandidates.length === 1) {\n const candidate = lowCandidates[0];\n return {\n commentId,\n status: \"fuzzy\",\n score: candidate.score,\n newLine: candidate.line,\n newEndLine: candidate.endLine,\n newStartColumn: candidate.startColumn,\n newEndColumn: candidate.endColumn,\n anchoredText: candidate.text,\n previousSelectedText: selectedText,\n reason: `Low-threshold fuzzy match (score ${candidate.score.toFixed(3)}).`,\n };\n }\n\n if (lowCandidates.length > 1) {\n const best = lowCandidates[0];\n return {\n commentId,\n status: \"ambiguous\",\n score: best.score,\n newLine: best.line,\n newEndLine: best.endLine,\n reason: `Ambiguous: ${lowCandidates.length} fuzzy matches (best score ${best.score.toFixed(3)}).`,\n };\n }\n }\n\n return {\n commentId,\n status: \"orphaned\",\n score: 0,\n reason: \"No match found. Comment is orphaned.\",\n };\n}\n\nexport function reanchorDocumentLines(\n doc: MrsfDocument,\n documentLines: string[],\n opts: { threshold?: number; proximityWindow?: number } = {},\n): ReanchorResult[] {\n return doc.comments.map((comment) => reanchorComment(comment, documentLines, opts));\n}\n\nexport function reanchorDocumentText(\n doc: MrsfDocument,\n documentText: string,\n opts: { threshold?: number; proximityWindow?: number } = {},\n): ReanchorResult[] {\n return reanchorDocumentLines(doc, toReanchorLines(documentText), opts);\n}\n\nexport function resolveAnchor(\n comment: Comment,\n documentText: string,\n opts: { threshold?: number; proximityWindow?: number } = {},\n): AnchorPosition {\n const normalizedText = documentText.replace(/\\r\\n/g, \"\\n\");\n const documentLines = toReanchorLines(documentText);\n const result = reanchorComment(comment, documentLines, opts);\n\n if (result.status === \"orphaned\") {\n return {\n status: \"orphaned\",\n score: result.score,\n reason: result.reason,\n };\n }\n\n const line = result.newLine ?? comment.line;\n if (line == null) {\n return {\n status: result.status,\n score: result.score,\n reason: result.reason,\n };\n }\n\n const rawLines = normalizedText.split(\"\\n\");\n const lineStarts = computeLineStarts(rawLines);\n const endLine = result.newEndLine ?? comment.end_line ?? line;\n const startColumn = result.newStartColumn ?? comment.start_column ?? 0;\n const endColumn = result.newEndColumn ?? comment.end_column;\n const from = offsetFor(lineStarts, rawLines, line, startColumn);\n const selectedText = comment.selected_text?.replace(/\\r\\n/g, \"\\n\");\n const to =\n endColumn != null\n ? offsetFor(lineStarts, rawLines, endLine, endColumn)\n : selectedText\n ? from + selectedText.length\n : offsetFor(lineStarts, rawLines, endLine, rawLines[endLine - 1]?.length ?? 0);\n\n return {\n status: result.status,\n score: result.score,\n from,\n to,\n line,\n endLine,\n startColumn,\n endColumn: endColumn ?? columnForOffset(lineStarts, rawLines, endLine, to),\n reason: result.reason,\n };\n}\n\nfunction computeLineStarts(lines: string[]): number[] {\n const starts = [0];\n let offset = 0;\n for (const line of lines) {\n starts.push(offset);\n offset += line.length + 1;\n }\n return starts;\n}\n\nfunction offsetFor(\n lineStarts: number[],\n lines: string[],\n line: number,\n column: number,\n): number {\n const start = lineStarts[line] ?? 0;\n const maxColumn = lines[line - 1]?.length ?? 0;\n return start + Math.max(0, Math.min(column, maxColumn));\n}\n\nfunction columnForOffset(\n lineStarts: number[],\n lines: string[],\n line: number,\n offset: number,\n): number {\n const start = lineStarts[line] ?? 0;\n const maxColumn = lines[line - 1]?.length ?? 0;\n return Math.max(0, Math.min(offset - start, maxColumn));\n}\n\nexport function applyReanchorResults(\n doc: MrsfDocument,\n results: ReanchorResult[],\n opts: { updateText?: boolean; force?: boolean; headCommit?: string } = {},\n): number {\n let changed = 0;\n const resultMap = new Map(results.map((result) => [result.commentId, result]));\n\n for (const comment of doc.comments) {\n const result = resultMap.get(comment.id);\n if (!result) continue;\n\n let isChanged = false;\n\n if (result.newLine != null && result.newLine !== comment.line) {\n comment.line = result.newLine;\n isChanged = true;\n }\n if (result.newEndLine != null && result.newEndLine !== comment.end_line) {\n comment.end_line = result.newEndLine;\n isChanged = true;\n }\n if (result.newStartColumn != null && result.newStartColumn !== comment.start_column) {\n comment.start_column = result.newStartColumn;\n isChanged = true;\n }\n if (result.newEndColumn != null && result.newEndColumn !== comment.end_column) {\n comment.end_column = result.newEndColumn;\n isChanged = true;\n }\n\n if (result.anchoredText != null && result.anchoredText !== comment.selected_text) {\n if (opts.updateText) {\n comment.selected_text = result.anchoredText;\n delete comment.anchored_text;\n } else {\n comment.anchored_text = result.anchoredText;\n }\n isChanged = true;\n } else if (result.anchoredText != null && result.anchoredText === comment.selected_text) {\n if (comment.anchored_text) {\n delete comment.anchored_text;\n isChanged = true;\n }\n }\n\n if (isChanged || result.status !== \"anchored\") {\n comment.x_reanchor_status = result.status;\n comment.x_reanchor_score = result.score;\n }\n\n if (\n opts.force\n && opts.headCommit\n && (result.status === \"anchored\" || result.status === \"shifted\")\n && result.score >= HIGH_THRESHOLD\n ) {\n comment.commit = opts.headCommit;\n delete comment.x_reanchor_status;\n delete comment.x_reanchor_score;\n if (comment.anchored_text && comment.anchored_text === comment.selected_text) {\n delete comment.anchored_text;\n }\n isChanged = true;\n }\n\n if (isChanged) {\n changed += 1;\n }\n }\n\n return changed;\n}\n\nfunction extractText(\n lines: string[],\n line: number,\n endLine?: number,\n startColumn?: number,\n endColumn?: number,\n): string | null {\n const startIdx = line;\n const endIdx = endLine ?? line;\n\n if (startIdx < 1 || endIdx >= lines.length) return null;\n\n if (startIdx === endIdx) {\n const text = lines[startIdx];\n if (startColumn != null && endColumn != null) {\n return text.slice(startColumn, endColumn);\n }\n return text;\n }\n\n const result: string[] = [];\n for (let index = startIdx; index <= endIdx; index += 1) {\n let currentLine = lines[index];\n if (index === startIdx && startColumn != null) currentLine = currentLine.slice(startColumn);\n if (index === endIdx && endColumn != null) currentLine = currentLine.slice(0, endColumn);\n result.push(currentLine);\n }\n return result.join(\"\\n\");\n}\n\nfunction closestToLine<T extends { line: number }>(candidates: T[], targetLine: number): T {\n return candidates.reduce((best, candidate) =>\n Math.abs(candidate.line - targetLine) < Math.abs(best.line - targetLine) ? candidate : best,\n );\n}\n\n/**\n * \u00A77.4 step 1a relocation guard.\n *\n * Returns true when a chosen exact-match candidate is an *implausible*\n * full-confidence relocation: the original `line` still exists in the document,\n * the candidate is farther than `proximityWindow` lines away, and the text now\n * at the original position no longer equals `selected_text`. This is the\n * signature of an in-place edit of the anchored text (which removed the\n * original occurrence) rather than a genuine move of the selection.\n *\n * When the original line no longer exists (the document shrank or the section\n * was removed) or no positional anchor is available, relocation is treated as a\n * legitimate \u00A77.4 step 3 contextual re-anchor and this returns false.\n */\nfunction isImplausibleExactRelocation(\n comment: Comment,\n candidate: FuzzyCandidate,\n lines: string[],\n proximityWindow: number,\n): boolean {\n if (comment.line == null) return false;\n\n // Original position must still exist to be a viable fallback anchor.\n if (comment.line <= 0 || comment.line >= lines.length) return false;\n\n // A nearby match is plausibly the same (or an adjacent) edit region.\n if (Math.abs(candidate.line - comment.line) <= proximityWindow) return false;\n\n // If the text at the original position still equals selected_text, the\n // original occurrence is intact and relocation is not a teleport.\n const textAtOrigin = extractText(\n lines,\n comment.line,\n comment.end_line,\n comment.start_column,\n comment.end_column,\n );\n if (textAtOrigin === comment.selected_text) return false;\n\n return true;\n}\n\nfunction getLineShift(diffHunks: DiffHunk[], line: number): { shift: number; modified: boolean } {\n let shift = 0;\n let modified = false;\n\n for (const hunk of diffHunks) {\n const oldStart = hunk.oldStart;\n const oldEnd = hunk.oldStart + Math.max(hunk.oldCount, 1) - 1;\n\n if (line >= oldStart && line <= oldEnd && hunk.oldCount > 0) {\n modified = true;\n }\n\n if (line > oldEnd || (hunk.oldCount === 0 && line >= oldStart)) {\n shift += hunk.newCount - hunk.oldCount;\n }\n }\n\n return { shift, modified };\n}", "import AjvModule from \"ajv\";\nimport addFormatsModule from \"ajv-formats\";\nimport { mrsfSchema } from \"./schema.js\";\nimport type {\n MrsfDocument,\n ValidationDiagnostic,\n ValidationResult,\n} from \"./types.js\";\n\nconst Ajv = (AjvModule as any).default ?? AjvModule;\nconst addFormats = (addFormatsModule as any).default ?? addFormatsModule;\n\nexport type HashFunction = (text: string) => string;\n\nexport function validateDocument(\n doc: MrsfDocument,\n schema: object = mrsfSchema,\n): ValidationResult {\n const errors: ValidationDiagnostic[] = [];\n const warnings: ValidationDiagnostic[] = [];\n\n validateSchema(doc, schema, errors);\n validateCrossFields(doc, errors, warnings);\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nexport function validateSchema(\n doc: MrsfDocument,\n rawSchema: object,\n errors: ValidationDiagnostic[],\n): void {\n const { $schema, ...schema } = rawSchema as Record<string, unknown>;\n void $schema;\n const ajv = new Ajv({ allErrors: true, strict: false });\n addFormats(ajv);\n const ajvValidate = ajv.compile(schema);\n const schemaValid = ajvValidate(doc);\n\n if (!schemaValid && ajvValidate.errors) {\n for (const err of ajvValidate.errors) {\n errors.push({\n severity: \"error\",\n code: \"schema-violation\",\n message: `${err.instancePath || \"/\"}: ${err.message ?? \"schema error\"}`,\n path: err.instancePath || \"/\",\n });\n }\n }\n}\n\nexport function validateCrossFields(\n doc: MrsfDocument,\n errors: ValidationDiagnostic[],\n warnings: ValidationDiagnostic[],\n hash?: HashFunction,\n): void {\n if (!Array.isArray(doc.comments)) return;\n\n const ids = new Set<string>();\n const allIds = doc.comments.map((x) => x.id);\n\n for (let i = 0; i < doc.comments.length; i++) {\n const c = doc.comments[i];\n const prefix = `/comments/${i}`;\n\n if (c.id) {\n if (ids.has(c.id)) {\n errors.push({\n severity: \"error\",\n code: \"duplicate-id\",\n message: `Duplicate comment id \"${c.id}\"`,\n path: `${prefix}/id`,\n commentId: c.id,\n });\n }\n ids.add(c.id);\n }\n\n if (c.line != null && c.end_line != null && c.end_line < c.line) {\n errors.push({\n severity: \"error\",\n code: \"end-line-before-line\",\n message: `end_line (${c.end_line}) must be \u2265 line (${c.line})`,\n path: `${prefix}/end_line`,\n commentId: c.id,\n });\n }\n\n if (\n c.start_column != null &&\n c.end_column != null &&\n (c.line == null || c.end_line == null || c.line === c.end_line) &&\n c.end_column < c.start_column\n ) {\n errors.push({\n severity: \"error\",\n code: \"end-column-before-start-column\",\n message: `end_column (${c.end_column}) must be \u2265 start_column (${c.start_column}) on the same line`,\n path: `${prefix}/end_column`,\n commentId: c.id,\n });\n }\n\n if (c.selected_text && c.selected_text.length > 4096) {\n errors.push({\n severity: \"error\",\n code: \"selected-text-too-long\",\n message: `selected_text exceeds 4096 characters (${c.selected_text.length})`,\n path: `${prefix}/selected_text`,\n commentId: c.id,\n });\n }\n\n if (c.text && c.text.length > 16384) {\n warnings.push({\n severity: \"warning\",\n code: \"text-too-long\",\n message: `text exceeds recommended 16384 characters (${c.text.length})`,\n path: `${prefix}/text`,\n commentId: c.id,\n });\n }\n\n // Browser-safe callers do not get the Node SHA-256 implementation.\n // The hash check runs only when a hash function is injected by the Node validator.\n if (hash && c.selected_text && c.selected_text_hash) {\n const expected = hash(c.selected_text);\n if (c.selected_text_hash !== expected) {\n warnings.push({\n severity: \"warning\",\n code: \"hash-mismatch\",\n message: `selected_text_hash mismatch (expected ${expected.slice(0, 12)}\u2026, got ${c.selected_text_hash.slice(0, 12)}\u2026)`,\n path: `${prefix}/selected_text_hash`,\n commentId: c.id,\n });\n }\n }\n\n if (c.reply_to && !ids.has(c.reply_to) && !allIds.includes(c.reply_to)) {\n warnings.push({\n severity: \"warning\",\n code: \"unresolved-reply-to\",\n message: `reply_to \"${c.reply_to}\" does not resolve to any comment id in this file`,\n path: `${prefix}/reply_to`,\n commentId: c.id,\n });\n }\n\n if (c.line != null && !c.selected_text) {\n warnings.push({\n severity: \"warning\",\n code: \"missing-selected-text\",\n message: \"Comment has line anchors but no selected_text \u2014 anchoring will be fragile across edits\",\n path: `${prefix}/selected_text`,\n commentId: c.id,\n });\n }\n }\n}\n", "\n{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://github.com/wictorwilen/MRSF/raw/main/mrsf.schema.json\",\n \"title\": \"Markdown Review Sidecar Format (MRSF) v1.0\",\n \"description\": \"Schema for MRSF review sidecar files. See MRSF-v1.0.md for the full specification.\",\n \"type\": \"object\",\n \"required\": [\"mrsf_version\", \"document\", \"comments\"],\n \"additionalProperties\": true,\n \"properties\": {\n \"mrsf_version\": {\n \"type\": \"string\",\n \"pattern\": \"^1\\\\.\\\\d+$\",\n \"description\": \"MRSF format version. MUST be a supported major.minor version (e.g., 1.0).\"\n },\n \"document\": {\n \"type\": \"string\",\n \"description\": \"Relative path to the Markdown document being reviewed.\"\n },\n \"comments\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\"id\", \"author\", \"timestamp\", \"text\", \"resolved\"],\n \"additionalProperties\": true,\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"description\": \"Globally unique, opaque, collision-resistant identifier for the comment.\"\n },\n \"author\": {\n \"type\": \"string\",\n \"description\": \"Creator of the comment. SHOULD follow the convention 'Display Name (identifier)'.\"\n },\n \"timestamp\": {\n \"type\": \"string\",\n \"format\": \"date-time\",\n \"description\": \"ISO 8601 / RFC 3339 timestamp of comment creation; SHOULD include timezone offset.\"\n },\n \"text\": {\n \"type\": \"string\",\n \"maxLength\": 16384,\n \"description\": \"The content of the review comment. MUST be plain text.\"\n },\n \"resolved\": {\n \"type\": \"boolean\",\n \"description\": \"Whether the comment has been resolved.\"\n },\n \"commit\": {\n \"type\": \"string\",\n \"description\": \"Git commit hash associated with the comment. SHOULD be the full (long) SHA.\"\n },\n \"type\": {\n \"type\": \"string\",\n \"description\": \"Categorization of the comment. Recommended values listed in examples.\",\n \"examples\": [\n \"suggestion\",\n \"issue\",\n \"question\",\n \"accuracy\",\n \"style\",\n \"clarity\"\n ]\n },\n \"severity\": {\n \"type\": \"string\",\n \"description\": \"Importance level of the comment.\",\n \"enum\": [\"low\", \"medium\", \"high\"]\n },\n \"reply_to\": {\n \"type\": \"string\",\n \"description\": \"ID of another comment in the same file that this comment replies to.\"\n },\n \"line\": {\n \"type\": \"integer\",\n \"minimum\": 1,\n \"description\": \"Starting line number (1-based) in the target document.\"\n },\n \"end_line\": {\n \"type\": \"integer\",\n \"minimum\": 1,\n \"description\": \"Ending line number (inclusive, 1-based). MUST be >= line.\"\n },\n \"start_column\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"description\": \"Starting column index (0-based) within the starting line.\"\n },\n \"end_column\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"description\": \"Ending column index. MUST be >= start_column when on the same line.\"\n },\n \"selected_text\": {\n \"type\": \"string\",\n \"maxLength\": 4096,\n \"description\": \"Exact text selected by the reviewer. SHOULD NOT be modified by re-anchoring tools. SHOULD NOT exceed 4096 characters.\"\n },\n \"anchored_text\": {\n \"type\": \"string\",\n \"maxLength\": 4096,\n \"description\": \"Text currently found at the resolved anchor position. Populated by re-anchoring tools when the document text differs from selected_text. SHOULD be omitted when identical to selected_text.\"\n },\n \"selected_text_hash\": {\n \"type\": \"string\",\n \"pattern\": \"^[a-f0-9]{64}$\",\n \"description\": \"Hex-encoded SHA-256 hash of selected_text. Immutable after creation; used for fast exact-match detection during re-anchoring, integrity verification, and staleness checks. SHOULD NOT be modified by re-anchoring tools unless selected_text is also replaced (opt-in behaviour), in which case it MUST be recomputed.\"\n }\n }\n }\n }\n }\n}\n", "import mrsfSchemaJson from \"../../mrsf.schema.json\" with { type: \"json\" };\n\nexport const mrsfSchema = mrsfSchemaJson;\n", "/**\n * MRSF string (de)serialization \u2014 pure, dependency-light helpers that parse and\n * serialize MRSF sidecar content to/from strings.\n *\n * This module intentionally has **no Node-only imports** (no `node:fs`,\n * `node:path`, `node:crypto`, \u2026) so it can be consumed from browser/host\n * adapters via the slim `@mrsf/cli/browser` entry point. Filesystem-bound\n * helpers (read/discover/write a file) live in `parser.ts` / `writer.ts`.\n */\n\nimport yaml from \"js-yaml\";\nimport { Document } from \"yaml\";\nimport type { MrsfDocument, Comment } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Lenient parse result\n// ---------------------------------------------------------------------------\n\n/** Result from a lenient (non-throwing) parse attempt. */\nexport interface LenientParseResult {\n /** Fully parsed document, or null if parsing failed entirely. */\n doc: MrsfDocument | null;\n /** If parsing failed or produced warnings, the error message. */\n error?: string;\n /** Comments that could be salvaged from a partially-corrupted sidecar. */\n partialComments?: Comment[];\n}\n\n// ---------------------------------------------------------------------------\n// Parsing (string \u2192 document)\n// ---------------------------------------------------------------------------\n\n/**\n * Parse MRSF sidecar content from a string.\n * Detects JSON vs YAML based on content or optional filename hint.\n */\nexport function parseSidecarContent(\n content: string,\n filenameHint?: string,\n): MrsfDocument {\n const trimmed = content.trim();\n\n let parsed: unknown;\n\n // Detect JSON by content or filename\n const isJson =\n trimmed.startsWith(\"{\") ||\n (filenameHint && filenameHint.endsWith(\".review.json\"));\n\n if (isJson) {\n try {\n parsed = JSON.parse(trimmed);\n } catch (e) {\n throw new Error(`Failed to parse JSON: ${(e as Error).message}`);\n }\n } else {\n try {\n parsed = yaml.load(trimmed, { schema: yaml.JSON_SCHEMA });\n } catch (e) {\n throw new Error(`Failed to parse YAML: ${(e as Error).message}`);\n }\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"MRSF sidecar must be a YAML/JSON object\");\n }\n\n return parsed as MrsfDocument;\n}\n\n/**\n * Lenient parse from string content.\n */\nexport function parseSidecarContentLenient(\n content: string,\n filenameHint?: string,\n): LenientParseResult {\n const trimmed = content.trim();\n if (!trimmed) {\n return { doc: null, error: \"File is empty\" };\n }\n\n const isJson =\n trimmed.startsWith(\"{\") ||\n (filenameHint && filenameHint.endsWith(\".review.json\"));\n\n // First, try a normal parse\n let parsed: unknown;\n try {\n parsed = isJson ? JSON.parse(trimmed) : yaml.load(trimmed, { schema: yaml.JSON_SCHEMA });\n } catch (e) {\n // Total parse failure \u2014 try to salvage what we can from YAML\n if (!isJson) {\n return salvageYaml(trimmed);\n }\n return { doc: null, error: `Failed to parse JSON: ${(e as Error).message}` };\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return { doc: null, error: \"MRSF sidecar must be a YAML/JSON object\" };\n }\n\n const obj = parsed as Record<string, unknown>;\n const doc: MrsfDocument = {\n mrsf_version: typeof obj.mrsf_version === \"string\" ? obj.mrsf_version : \"1.0\",\n document: typeof obj.document === \"string\" ? obj.document : \"unknown\",\n comments: [],\n };\n\n if (!Array.isArray(obj.comments)) {\n return {\n doc,\n error: \"comments field is not an array \u2014 file may be corrupted\",\n };\n }\n\n // Validate each comment individually\n const good: Comment[] = [];\n const bad: number[] = [];\n\n for (let i = 0; i < obj.comments.length; i++) {\n const c = obj.comments[i];\n if (c && typeof c === \"object\" && !Array.isArray(c) && typeof (c as Record<string, unknown>).id === \"string\") {\n good.push(c as Comment);\n } else {\n bad.push(i);\n }\n }\n\n doc.comments = good;\n\n if (bad.length > 0) {\n return {\n doc,\n error: `${bad.length} comment(s) at indices [${bad.join(\", \")}] were malformed and skipped`,\n partialComments: good,\n };\n }\n\n return { doc };\n}\n\n/**\n * Attempt to extract individual comment blocks from corrupted YAML by\n * splitting on `- id:` patterns and parsing each block independently.\n */\nfunction salvageYaml(content: string): LenientParseResult {\n const salvaged: Comment[] = [];\n let mrsf_version = \"1.0\";\n let document = \"unknown\";\n\n // Try to extract top-level fields from the beginning\n const versionMatch = content.match(/^mrsf_version:\\s*[\"']?([^\"'\\n]+)/m);\n if (versionMatch) mrsf_version = versionMatch[1].trim();\n\n const docMatch = content.match(/^document:\\s*[\"']?([^\"'\\n]+)/m);\n if (docMatch) document = docMatch[1].trim();\n\n // Split on comment block boundaries (- id: ...)\n const blocks = content.split(/(?=^ - id:\\s)/m);\n\n for (const block of blocks) {\n const trimmed = block.trim();\n if (!trimmed.startsWith(\"- id:\")) continue;\n\n // Wrap in a minimal YAML array context and try to parse\n try {\n const parsed = yaml.load(trimmed, { schema: yaml.JSON_SCHEMA });\n if (Array.isArray(parsed) && parsed.length > 0) {\n const c = parsed[0];\n if (c && typeof c === \"object\" && typeof (c as Record<string, unknown>).id === \"string\") {\n salvaged.push(c as Comment);\n }\n } else if (parsed && typeof parsed === \"object\" && typeof (parsed as Record<string, unknown>).id === \"string\") {\n salvaged.push(parsed as Comment);\n }\n } catch {\n // This block is unparseable \u2014 skip\n }\n }\n\n const doc: MrsfDocument = {\n mrsf_version,\n document,\n comments: salvaged,\n };\n\n return {\n doc: salvaged.length > 0 ? doc : null,\n error: `YAML parse failed. Salvaged ${salvaged.length} comment(s) from raw content.`,\n partialComments: salvaged.length > 0 ? salvaged : undefined,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Serialization (document \u2192 string)\n// ---------------------------------------------------------------------------\n\n/**\n * Serialize an MrsfDocument to YAML (for new files / non-round-trip use).\n */\nexport function toYaml(doc: MrsfDocument): string {\n const yamlDoc = new Document(doc);\n return yamlDoc.toString({ lineWidth: 0 });\n}\n\n/**\n * Serialize an MrsfDocument to JSON.\n */\nexport function toJson(doc: MrsfDocument): string {\n return JSON.stringify(doc, null, 2) + \"\\n\";\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["DEFAULT_THRESHOLD", "HIGH_THRESHOLD", "applyReanchorResults", "combinedScore", "exactMatch", "formatAuthor", "fuzzySearch", "levenshteinScore", "newCommentId", "normalizedMatch", "parseAuthor", "parseSidecarContent", "parseSidecarContentLenient", "reanchorComment", "reanchorDocumentLines", "reanchorDocumentText", "resolveAnchor", "toJson", "toReanchorLines", "toYaml", "tokenLcsScore", "validateDocument", "levenshtein", "uuidv4", "AjvModule", "addFormatsModule", "yaml", "parseSidecarContent", "parseSidecarContentLenient", "toYaml", "toJson", "combinedScore", "exactMatch", "fuzzySearch", "levenshteinScore", "normalizedMatch", "tokenLcsScore", "applyReanchorResults", "DEFAULT_THRESHOLD", "HIGH_THRESHOLD", "reanchorComment", "reanchorDocumentLines", "reanchorDocumentText", "resolveAnchor", "toReanchorLines", "validateDocument", "formatAuthor", "parseAuthor", "newCommentId"]
|
|
7
|
+
}
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import * as fuzzy from "./lib/fuzzy.js";
|
|
2
|
+
import * as identity from "./lib/identity.js";
|
|
2
3
|
import * as reanchorCore from "./lib/reanchor-core.js";
|
|
3
|
-
|
|
4
|
+
import * as validateCore from "./lib/validate-core.js";
|
|
5
|
+
import * as serialize from "./lib/serialize.js";
|
|
6
|
+
import { mrsfSchema } from "./lib/schema.js";
|
|
7
|
+
export type { AnchorPosition, Comment, DiffHunk, FuzzyCandidate, MrsfDocument, ReanchorResult, ReanchorStatus, ValidationDiagnostic, ValidationResult, DiagnosticSeverity, } from "./lib/types.js";
|
|
8
|
+
export type { ParsedAuthor } from "./lib/identity.js";
|
|
9
|
+
export type { LenientParseResult } from "./lib/serialize.js";
|
|
10
|
+
export declare const parseSidecarContent: typeof serialize.parseSidecarContent;
|
|
11
|
+
export declare const parseSidecarContentLenient: typeof serialize.parseSidecarContentLenient;
|
|
12
|
+
export declare const toYaml: typeof serialize.toYaml;
|
|
13
|
+
export declare const toJson: typeof serialize.toJson;
|
|
4
14
|
export declare const combinedScore: typeof fuzzy.combinedScore;
|
|
5
15
|
export declare const exactMatch: typeof fuzzy.exactMatch;
|
|
6
16
|
export declare const fuzzySearch: typeof fuzzy.fuzzySearch;
|
|
@@ -13,5 +23,11 @@ export declare const HIGH_THRESHOLD = 0.8;
|
|
|
13
23
|
export declare const reanchorComment: typeof reanchorCore.reanchorComment;
|
|
14
24
|
export declare const reanchorDocumentLines: typeof reanchorCore.reanchorDocumentLines;
|
|
15
25
|
export declare const reanchorDocumentText: typeof reanchorCore.reanchorDocumentText;
|
|
26
|
+
export declare const resolveAnchor: typeof reanchorCore.resolveAnchor;
|
|
16
27
|
export declare const toReanchorLines: typeof reanchorCore.toReanchorLines;
|
|
28
|
+
export declare const validateDocument: typeof validateCore.validateDocument;
|
|
29
|
+
export { mrsfSchema };
|
|
30
|
+
export declare const formatAuthor: typeof identity.formatAuthor;
|
|
31
|
+
export declare const parseAuthor: typeof identity.parseAuthor;
|
|
32
|
+
export declare const newCommentId: typeof identity.newCommentId;
|
|
17
33
|
//# sourceMappingURL=browser.d.ts.map
|
package/dist/browser.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import * as fuzzy from "./lib/fuzzy.js";
|
|
2
|
+
import * as identity from "./lib/identity.js";
|
|
2
3
|
import * as reanchorCore from "./lib/reanchor-core.js";
|
|
4
|
+
import * as validateCore from "./lib/validate-core.js";
|
|
5
|
+
import * as serialize from "./lib/serialize.js";
|
|
6
|
+
import { mrsfSchema } from "./lib/schema.js";
|
|
7
|
+
// Parse / serialize (pure string ⇄ document; no filesystem or argv deps).
|
|
8
|
+
export const parseSidecarContent = serialize.parseSidecarContent;
|
|
9
|
+
export const parseSidecarContentLenient = serialize.parseSidecarContentLenient;
|
|
10
|
+
export const toYaml = serialize.toYaml;
|
|
11
|
+
export const toJson = serialize.toJson;
|
|
3
12
|
export const combinedScore = fuzzy.combinedScore;
|
|
4
13
|
export const exactMatch = fuzzy.exactMatch;
|
|
5
14
|
export const fuzzySearch = fuzzy.fuzzySearch;
|
|
@@ -12,5 +21,11 @@ export const HIGH_THRESHOLD = reanchorCore.HIGH_THRESHOLD;
|
|
|
12
21
|
export const reanchorComment = reanchorCore.reanchorComment;
|
|
13
22
|
export const reanchorDocumentLines = reanchorCore.reanchorDocumentLines;
|
|
14
23
|
export const reanchorDocumentText = reanchorCore.reanchorDocumentText;
|
|
24
|
+
export const resolveAnchor = reanchorCore.resolveAnchor;
|
|
15
25
|
export const toReanchorLines = reanchorCore.toReanchorLines;
|
|
26
|
+
export const validateDocument = validateCore.validateDocument;
|
|
27
|
+
export { mrsfSchema };
|
|
28
|
+
export const formatAuthor = identity.formatAuthor;
|
|
29
|
+
export const parseAuthor = identity.parseAuthor;
|
|
30
|
+
export const newCommentId = identity.newCommentId;
|
|
16
31
|
//# sourceMappingURL=browser.js.map
|
|
@@ -16,6 +16,7 @@ export function registerReanchor(program) {
|
|
|
16
16
|
.description("Re-anchor comments to current document content")
|
|
17
17
|
.option("-n, --dry-run", "Report without modifying files")
|
|
18
18
|
.option("-t, --threshold <n>", "Fuzzy threshold 0.0–1.0", "0.6")
|
|
19
|
+
.option("--proximity-window <n>", "Max line distance for a lone exact match to relocate with full confidence (§7.4 step 1a guard)", "5")
|
|
19
20
|
.option("--staged", "Only process sidecars for staged files")
|
|
20
21
|
.option("--no-git", "Disable git integration")
|
|
21
22
|
.option("--from <commit>", "Override from-commit for all comments")
|
|
@@ -27,6 +28,7 @@ export function registerReanchor(program) {
|
|
|
27
28
|
const quiet = parentOpts.quiet ?? false;
|
|
28
29
|
const verbose = parentOpts.verbose ?? false;
|
|
29
30
|
const threshold = parseFloat(opts.threshold);
|
|
31
|
+
const proximityWindow = parseInt(opts.proximityWindow, 10);
|
|
30
32
|
const noGit = !opts.git;
|
|
31
33
|
let sidecarPaths;
|
|
32
34
|
if (opts.staged && !noGit) {
|
|
@@ -74,6 +76,7 @@ export function registerReanchor(program) {
|
|
|
74
76
|
const headCommit = repoRoot ? await getCurrentCommit(repoRoot) : undefined;
|
|
75
77
|
const results = await reanchorDocument(doc, lines, {
|
|
76
78
|
threshold,
|
|
79
|
+
proximityWindow,
|
|
77
80
|
noGit,
|
|
78
81
|
fromCommit: opts.from,
|
|
79
82
|
documentPath: docPath,
|