# How Debugging Mode Captures and Logs Prompts and Completions in screenshot-to-code

> Learn how screenshot-to-code's debugging mode automatically logs LLM prompts and completions to timestamped JSON files for detailed analysis.

- Repository: [Abi Raja/screenshot-to-code](https://github.com/abi/screenshot-to-code)
- Tags: internals
- Published: 2026-03-02

---

**When the `IS_DEBUG_ENABLED` environment flag is set, the screenshot-to-code backend automatically records every LLM prompt and the HTML portion of the first successful completion to a timestamped JSON file for later analysis.**

The abi/screenshot-to-code repository provides a built-in debugging mechanism that helps developers audit exactly what data flows between the application and large language models. By toggling a single configuration flag, the system persists full prompt histories, model selections, and completion outputs to disk, enabling precise replay and troubleshooting of code generation requests.

## Enabling the Debug Flag

Debugging functionality is controlled by the `IS_DEBUG_ENABLED` environment variable defined in [`backend/config.py`](https://github.com/abi/screenshot-to-code/blob/main/backend/config.py) (lines 15–18). When this flag evaluates to truthy, the backend activates additional logging throughout the request pipeline.

```python

# backend/config.py

IS_DEBUG_ENABLED = bool(os.environ.get("IS_DEBUG_ENABLED", False))
DEBUG_DIR = os.environ.get("DEBUG_DIR", "")

```

Upon startup, [`backend/main.py`](https://github.com/abi/screenshot-to-code/blob/main/backend/main.py) (lines 16–18) prints the debug status to the console, providing immediate confirmation that the mode is active.

```python

# backend/main.py

debug_status = "ENABLED" if IS_DEBUG_ENABLED else "DISABLED"
print(f"Backend startup complete. Debug mode is {debug_status}.")

```

## Capturing Prompt Metadata and Model Selection

Once debugging is enabled, the system augments WebSocket communications with extra diagnostic information. In [`backend/routes/generate_code.py`](https://github.com/abi/screenshot-to-code/blob/main/backend/routes/generate_code.py) (lines 48–55), the `CodeGenerationMiddleware` emits a special `variantModels` message containing the list of model identifiers used for the request, but only when `IS_DEBUG_ENABLED` is true.

```python

# backend/routes/generate_code.py

if IS_DEBUG_ENABLED:
    await context.send_message(
        "variantModels",
        None,
        0,
        {"models": [model.value for model in context.variant_models]},
        None,
    )

```

Additionally, the `WebSocketCommunicator` prints every message type—including errors, status updates, and variant progress—to the server console (lines 77–86), providing real-time visibility into the generation pipeline when debugging is active.

## Extracting and Persisting Completions

After all variant generations finish, the `PostProcessingStage.process_completions` method in [`backend/routes/generate_code.py`](https://github.com/abi/screenshot-to-code/blob/main/backend/routes/generate_code.py) (lines 99–104) filters for valid completions, extracts the `<html>` fragment from the first non-empty result, and triggers the logging mechanism.

```python

# backend/routes/generate_code.py

valid_completions = [comp for comp in completions if comp]
if valid_completions:
    html_content = extract_html_content(valid_completions[0])
    write_logs(prompt_messages, html_content)

```

The `write_logs` function in [`backend/fs_logging/core.py`](https://github.com/abi/screenshot-to-code/blob/main/backend/fs_logging/core.py) (lines 7–24) handles the actual persistence. It creates a `run_logs` directory under the path specified by the `LOGS_PATH` environment variable (defaulting to the current working directory), then writes a JSON file named [`messages_YYYYMMDD_HHMMSS.json`](https://github.com/abi/screenshot-to-code/blob/main/messages_YYYYMMDD_HHMMSS.json) containing two keys: `prompt` (the list of messages sent to the LLM) and `completion` (the extracted HTML string).

```python

# backend/fs_logging/core.py

logs_path = os.environ.get("LOGS_PATH", os.getcwd())
logs_directory = os.path.join(logs_path, "run_logs")
os.makedirs(logs_directory, exist_ok=True)

filename = datetime.now().strftime(
    f"{logs_directory}/messages_%Y%m%d_%H%M%S.json"
)
with open(filename, "w") as f:
    f.write(json.dumps({"prompt": prompt_messages, "completion": completion}))

```

## Optional Artifact Storage Infrastructure

For future extensibility, the repository includes a `DebugFileWriter` class in [`backend/debug/DebugFileWriter.py`](https://github.com/abi/screenshot-to-code/blob/main/backend/debug/DebugFileWriter.py) (lines 10–18). When instantiated, this class creates a unique per-run directory under `DEBUG_DIR` to store auxiliary debug artifacts, though the current implementation primarily relies on the `fs_logging` module for prompt and completion persistence.

```python

# backend/debug/DebugFileWriter.py

if not IS_DEBUG_ENABLED:
    return
self.debug_artifacts_path = os.path.expanduser(
    f"{DEBUG_DIR}/{str(uuid.uuid4())}"
)
os.makedirs(self.debug_artifacts_path, exist_ok=True)

```

## Practical Implementation Example

To activate debugging for a local development session, export the environment flag before starting the backend:

```bash
export IS_DEBUG_ENABLED=1
export LOGS_PATH=/var/log/screenshot-to-code

```

After running a generation request, inspect the captured data using standard file operations:

```python
import json
from pathlib import Path

log_file = Path("/var/log/screenshot-to-code/run_logs/messages_20241012_153045.json")
data = json.loads(log_file.read_text())

# Inspect the exact prompt sent to the LLM

for message in data["prompt"]:
    print(message)

# View the extracted HTML completion

print(data["completion"])

```

## Summary

- **Activation**: Set the `IS_DEBUG_ENABLED` environment variable in [`backend/config.py`](https://github.com/abi/screenshot-to-code/blob/main/backend/config.py) to enable the debugging pipeline.
- **Metadata Capture**: The backend emits a `variantModels` WebSocket message and prints communication logs only when debugging is active.
- **Data Extraction**: The `PostProcessingStage.process_completions` method extracts the HTML fragment from the first valid completion and passes it to the logger.
- **Persistence**: The `write_logs` function in [`backend/fs_logging/core.py`](https://github.com/abi/screenshot-to-code/blob/main/backend/fs_logging/core.py) writes timestamped JSON files to the `run_logs` directory, preserving both the full prompt array and the resulting HTML.
- **Configuration**: Use `LOGS_PATH` to customize the output directory; use `DEBUG_DIR` for future artifact storage via `DebugFileWriter`.

## Frequently Asked Questions

### How do I enable debugging mode in screenshot-to-code?

Set the `IS_DEBUG_ENABLED` environment variable to `1` or `true` before starting the backend server. The startup sequence in [`backend/main.py`](https://github.com/abi/screenshot-to-code/blob/main/backend/main.py) will confirm the mode is active via console output.

### What file format does the debugging system use to store logs?

The system writes standard JSON files named [`messages_YYYYMMDD_HHMMS.json`](https://github.com/abi/screenshot-to-code/blob/main/messages_YYYYMMDD_HHMMS.json) containing two top-level keys: `prompt` (an array of message objects sent to the LLM) and `completion` (the extracted HTML string from the first successful response).

### Where are the debug logs stored by default?

By default, logs are written to a `run_logs` subdirectory within the current working directory. You can override this location by setting the `LOGS_PATH` environment variable to an absolute path before launching the application.

### Does debugging mode capture all completion variants or just the first one?

The current implementation extracts and logs the HTML content from only the **first** non-empty completion in the variants list, as implemented in `PostProcessingStage.process_completions` at lines 99–104 of [`backend/routes/generate_code.py`](https://github.com/abi/screenshot-to-code/blob/main/backend/routes/generate_code.py).