weaveback records a source map on every run and stores it in weaveback.db. Use it to answer "where did this line in a generated file come from?"

Tracing is always on — no flag needed.

Commands

# Trace a line to its literate source
weaveback trace <out_file> <line>

# Pinpoint a specific token by column (1-indexed character position)
weaveback trace <out_file> <line> --col <col>

Prints JSON to stdout. All line and column numbers are 1-indexed character positions. <out_file> is the path of the generated file as seen on disk. Reads weaveback.db from the current working directory.

Example

cd examples/c_enum
weaveback status.md --gen .
weaveback trace src/status.c 6
{
  "chunk": "string_cases",
  "kind": "MacroBody",
  "macro_name": "enum_val",
  "src_file": "/path/to/examples/c_enum/status.md",
  "src_line": 31,
  "out_file": "src/status.c",
  "out_line": 6
}

When a line contains tokens from different sources, pass --col to target the specific token you want to change:

weaveback trace src/config.nim 178 --col 10
{
  "kind": "MacroArg",
  "macro_name": "cfg_int",
  "param_name": "default_val",
  "src_file": "/path/to/config.nim.adoc",
  "src_line": 22
}

Output fields

Field Meaning

src_file

Literate source file to edit

src_line

1-indexed line in that file

src_col

1-indexed character position within src_line

kind

Literal, MacroBody, MacroArg, VarBinding, or Computed

macro_name

Macro name (when kind is MacroBody or MacroArg)

param_name

Parameter name (when kind is MacroArg)

var_name

Variable name (when kind is VarBinding)

def_locations

{file, line} for every %def/%rhaidef/%pydef that defined this macro (when kind is MacroBody)

set_locations

{file, line} for every %set that set this variable (when kind is VarBinding)

chunk

Noweb chunk containing this line

Reading the result

  • Literal: edit src_file at src_line directly.

  • MacroBody: the text is a literal fragment of a macro body. def_locations says where the macro was defined.

  • MacroArg: the text came from an argument at the call site. src_file:src_line is that call site; param_name names the parameter.

  • VarBinding: the text came from a %set call. set_locations lists all assignment sites; var_name names the variable.

Span attribution follows arguments through nested macro calls — src_file:src_line always points to the original literal text, not to an intermediate call site.


MCP server (weaveback mcp)

weaveback mcp starts a Model Context Protocol server over stdin/stdout, exposing tracing, editing, and context tools so IDE extensions and AI agents can work with the literate source without shelling out.

weaveback --gen . mcp

The server implements the MCP 2024-11-05 protocol over JSON-RPC 2.0 (one message per line on stdin/stdout).

Tools

Tool Description

weaveback_trace

Trace a generated file line to its literate source. Accepts out_file, out_line, and optional out_col. All 1-indexed character positions.

weaveback_apply_fix

Preferred tool for source edits. Replace a line or range in the literate source and oracle-verify it produces the expected output before writing. Accepts src_file, src_line, optional src_line_end (range, defaults to src_line), new_src_line or new_src_lines array, out_file, out_line, expected_output. All line numbers are 1-indexed.

weaveback_apply_back

Bulk baseline-reconciliation tool. Use only when gen/ files have already been edited by hand. Diffs each modified file against its stored baseline, traces changed lines back to the literate source, and patches in place. Accepts optional files array and dry_run flag.

weaveback_chunk_context

Return full context for a named noweb chunk: body, AsciiDoc section title breadcrumb, full prose of the enclosing section (paragraphs, admonitions, design notes), bodies of all direct dependencies, reverse-dep names, output files, and recent git log entries. Accepts file (path relative to project root), name, and optional nth (0-based, default 0).

weaveback_list_chunks

List all chunk definitions in the project. Returns an array of { file, name, nth, def_start, def_end } objects. Accepts optional file to filter to a single source file.

weaveback_find_chunk

Find which source file(s) define a given chunk name. Returns { file, nth, def_start, def_end } objects. Accepts name.

weaveback_lsp_definition

Find the semantic definition of a symbol at a generated file position and map it back to literate source. Requires a language server (e.g. rust-analyzer).

weaveback_lsp_references

Find all semantic references to a symbol and return their locations in the literate sources.

weaveback_lsp_hover

Get type information and documentation for a symbol, mapped back to literate source.

weaveback_lsp_diagnostics

Get current compiler errors/warnings for a generated file, mapped back to original literate source lines.

  1. Understand: call weaveback_chunk_context with the chunk name and source file to get the body, design prose, dep bodies, and git history in one call. Skip this step only if the chunk is trivially obvious.

  2. Locate: call weaveback_trace with the generated file and line number. Returns the exact src_file/src_line, even across multi-file chunk definitions and macro expansions. No grep required.

  3. Read: open src_file at src_line and read the surrounding context.

  4. Fix code: call weaveback_apply_fix with the replacement text and the exact output line you expect. The macro expander re-runs as an oracle — the file is written only if the output matches. No build needed.

  5. Check prose: re-read the prose section around src_line in the literate source and verify it still accurately describes the changed code. This step is not optional. The literate document is both code and documentation; a fix that leaves stale prose is incomplete.

  6. Fix prose: use a plain Edit if the surrounding prose is stale. No oracle is needed — prose changes do not affect generated output.

  7. Build: run the project build. Only linking and type-checking remain; correctness was already oracle-verified in step 4.

weaveback_apply_fix works for single-line replacements (src_line only) and multi-line ranges (src_line + src_line_end + new_src_lines array).

Why this is faster than editing the literate source directly
  • No grep hunting — trace gives the exact file and line instantly.

  • Fast feedback — the oracle rejects wrong edits before the build.

  • Prose location is free — trace lands you next to the relevant doc section.

  • Atomic — fix and baseline update happen together; apply_back is never needed in the normal flow.

weaveback_apply_back — escape hatch, not the normal path

weaveback_apply_back is for one specific situation: a generated file was already edited directly (by hand, by a language tool, or by an IDE). Use it to bulk-propagate those edits back to the literate source.

It supports multi-line replacements, insertions, and deletions by attributing changed hunks to the continuous source regions that produced them. If a hunk is too complex or spans multiple chunks, the tool will skip it and report where manual editing is required.

Context tools — understanding before editing

weaveback_chunk_context returns everything an agent needs to understand a chunk before touching it:

  • body — the raw source lines of the chunk

  • section_title_chain — the AsciiDoc heading breadcrumb, e.g. ["Module overview", "Parsing", "Error recovery"]

  • section_prose — all prose in the enclosing == section: paragraphs, lists, [NOTE]/[TIP]/[IMPORTANT] admonitions — without listing-block content. This is the author’s design intent, automatically.

  • dependencies — map of dep name → { file, body } for all [chunks] this chunk references

  • reverse_dependencies — names of chunks that reference this one

  • output_filesgen/ files this chunk contributes to

  • git_log — five most recent git log --oneline entries for the source file

Typical use: call weaveback_chunk_context first to understand the design intent, then use weaveback_apply_fix to make the change.

weaveback_list_chunks (with optional file filter) and weaveback_find_chunk (by name) are useful for orientation when starting work on an unfamiliar part of the codebase.

Gotchas

Line number drift: weaveback_apply_fix uses source line numbers from the current state of the literate file. If the file was edited directly before calling the tool, line numbers reported by trace may have shifted. Always re-read the target line before calling apply_fix to confirm it still contains the expected content.

Formatter interaction: when --formatter is configured (e.g. rs=rustfmt), the baseline stored in weaveback.db is the formatted output. The oracle also produces formatted output. Pass the formatted line as expected_output, not the raw macro expansion.

Claude Code / Claude Desktop configuration

Add a .mcp.json in your project root:

{
  "mcpServers": {
    "weaveback": {
      "command": "weaveback",
      "args": ["--db", "weaveback.db", "--gen", "src", "mcp"]
    }
  }
}

Adjust --gen to match your project’s generated-file directory.