# TASK: Downward call-graph (IDA-style "xrefs from") for {{TARGET}}

{{TARGET}} = a function identifier — either a hex VA (e.g. 4644FC) or a
resolved name (e.g. Form1.LoadPlugins).

Build the recursive callee tree rooted at {{TARGET}} — every function it calls,
everything those call, and so on — and emit it as a Graphviz DOT file.

NOTE: this analyzes "xrefs FROM" (callees / functions below the target).
Despite this file's name, it does NOT walk callers ("xrefs to"). If you want
the caller direction, invert step 4 to scan every function for calls TO the target.

PREREQUISITE: the "./../_claude_vbdec_ai_instructions.txt" must already be loaded in this
context (see claude_vbdec_instructions.txt).

## Procedure

1. Bind the ROT object: Set o = GetObject("vbdec.vbp")
2. Resolve {{TARGET}} to a CCodeBody:
   - hex VA  -> o.CodeBodyForVA2("<hex>")
   - name    -> match against .displayName(True) over all CodeObjects' .Methods2
   Abort with a clear message if it can't be resolved.
3. Build a one-time lookup of every project function: name/VA -> CCodeBody,
   by iterating o.CodeObjects -> .Methods2.
4. DFS/BFS from the root. For each function, scan its .Disasm line by line
   for call mnemonics and extract the callee operand:
     ImpAdCallI2 / ImpAdCallI4         -> module/proc call
     VCallHresult / ThisVCallHresult   -> method call
     ImpAdCallFPR4                     -> runtime (rtc*) or API call
     LateMemCall                       -> late-bound call (target not static)
   Classify each callee:
     - operand matches Proc_([0-9A-Fa-f]+) -> callee VA = that hex ->
       resolve via CodeBodyForVA2; if found it is an INTERNAL node -> recurse.
     - operand is Module.Name resolvable in the step-3 lookup -> INTERNAL -> recurse.
     - anything else (rtc*, kernel32.*, COM "Get App", VBGlobal, etc.) or a
       CodeBodyForVA2 miss -> EXTERNAL leaf node -> DO NOT recurse.
     - VCallAd to a control (e.g. Form1.lvDebug) is NOT a function call -> skip.
     - LateMemCall 'name' -> EXTERNAL leaf labelled late:name.
5. Maintain a visited set keyed by callee VA/name. On revisit, still draw the
   edge but do not re-expand. Mark recursion/back-edges distinctly.
6. Respect an optional depth cap: {{MAX_DEPTH}} (default = unlimited).

## DOT output spec

- digraph xrefs_from { rankdir=LR; ... }
- Node label = resolved displayName(True); if unresolved, the raw operand.
- Node styling:
    root      -> filled, bold, distinct fill (e.g. gold)
    internal  -> box; optionally fill by owner module (Form/Class/Module)
    external  -> ellipse, grey, dashed (API / rtc* / COM / late-bound)
- Edge: root chain solid; back-edges (recursion) dashed + red.
- One node per unique function; dedupe edges.

## Output

Write {Desktop}\xrefs_{{TARGET}}.dot
Then print a short summary: total internal nodes, external leaves, max depth
reached, and any recursion cycles found.
Render hint: dot -Tpng xrefs_{{TARGET}}.dot -o xrefs_{{TARGET}}.png

## Constraints

- Implement as a single cscript //nologo pass that walks and emits the DOT
  directly; delete the temp .vbs afterward.
- Downward only (callees / "xrefs from"). Do NOT walk callers.
- Stop at external boundaries — do not try to expand API/runtime/COM calls.
- Flag any callee operand you could not classify rather than silently dropping it.
