Skip to content

DIT-13464: Capture the raw literal (snapshot_text) in source-code extractors - #3

Merged
laurakoye merged 2 commits into
laura/dit-13463-stable-occurrence-indexfrom
laura/dit-13464-capture-the-raw-literal-snapshot_text-in-source-code
Aug 18, 2026
Merged

DIT-13464: Capture the raw literal (snapshot_text) in source-code extractors#3
laurakoye merged 2 commits into
laura/dit-13463-stable-occurrence-indexfrom
laura/dit-13464-capture-the-raw-literal-snapshot_text-in-source-code

Conversation

@laurakoye

@laurakoye laurakoye commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Overview

Adds snapshot_text to scan candidates: the raw source span a value came from, quotes and escapes intact.

value_raw is decoded — "Line one\nLine two" arrives holding a real newline — so it can't be searched for in the file, and writing it back would mangle the syntax around it. snapshot_text is a verbatim slice, so source.includes(snapshot_text) always holds.

Nothing server-side is needed to merge — zod strips unknown keys, so the field is ignored on arrival for now.

Context

DIT-13464, part of DIT-13405. Stacked on #2 — review that first.

A code link identifies a string by (file, value, occurrence index) and stores snapshot_text as the code's own rendering of it. Schema design.

Screenshots

None — extraction output only.

Test Plan

1. The suite

yarn jest        # 23 suites, 160 tests — 16 new in src/lang/extractors/snapshot-text.test.ts
yarn typecheck   # clean

A describe.each table asserts, per extractor, that snapshotText is a string on every hit and that source.includes(hit.snapshotText) holds. Four further cases pin what the snapshot keeps and the value drops: escapes, quote style, a template literal's ${...}, and inline markup in a JSX text run.

2. Coverage on a real app

The suite runs on hand-written snippets. This checks a real codebase, and that the nulls land only where they should.

yarn build

mkdir -p /tmp/demo
git -C ../v0-demo archive HEAD | tar -x -C /tmp/demo

cat > snap.mjs <<'EOF'
import { runExtract } from "./dist/index.js";
const { candidates } = await runExtract({ inputPath: process.argv[2] });
const nulls = candidates.filter((c) => c.snapshot_text === null);
console.log(`${candidates.length - nulls.length}/${candidates.length} carry a snapshot`);
console.log("null kinds:", [...new Set(nulls.map((c) => c.detection_kind))]);
EOF

node snap.mjs /tmp/demo
rm snap.mjs

snap.mjs goes in the repo root — ./dist/index.js resolves relative to the script, not the working directory.

3. What to look for

140/200 carry a snapshot
null kinds: [ 'resource_value' ]

Every null is a resource_value. Expected: this PR only touches the source-code extractors, so resource files stay null until DIT-13480. Any other kind appearing in that list means an extractor emitted a value it can't point at in the source.

Note: yarn linking this into the CLI and running yarn scan does not exercise this code until cli#151 merges — the CLI still uses its own copy.

@jholiga jholiga left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@laurakoye
laurakoye merged commit be93498 into laura/dit-13463-stable-occurrence-index Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants