Metadata-Version: 2.4
Name: debugflow
Version: 1.0.2
Summary: DebugFlow — real-time execution tracer and HUD for Python
Author-email: Manikandan <mani1756067@gmail.com>
License: MIT License
        
        Copyright (c) 2026 Manikandan
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
Project-URL: Homepage, https://github.com/yourname/debugflow
Project-URL: Repository, https://github.com/yourname/debugflow
Project-URL: Issues, https://github.com/yourname/debugflow/issues
Keywords: debugger,tracer,visualization,profiling,hud,python,execution,ml
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Debuggers
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: license
Requires-Dist: dearpygui<3,>=2.0
Requires-Dist: pynput>=1.7.6
Requires-Dist: psutil>=5.9
Requires-Dist: torch
Requires-Dist: numpy
Requires-Dist: pandas
Dynamic: license-file

# DebugFlow — NeuralFlow Logic Engine

**A real-time execution tracer and Heads-Up Display for Python — see your functions fire as they happen, on a translucent "cybernetic spine" that lives on the side of your screen.**

Built for two audiences:

- **Developers** debugging Python scripts who want a non-intrusive, always-on visualisation of call flow, parameters, return values, and exceptions — no breakpoints, no `print()` statements.
- **AI / ML engineers** tracing data pipelines, model inference, and training loops, where seeing tensor shapes, sample sizes, and per-step timings live on screen beats reading log files after the fact.

---

## Quick Demo

```text
flow activate                  # Start the background sentinel
                               # press Ctrl+Alt+F to summon the HUD
                               # press Ctrl+Alt+S to fire your script
```

### What it looks like in flight

| Live call flow | Returns + exceptions | Hover for metadata |
|---|---|---|
| ![Live call flow](images/demo_pulse.gif) | ![Returns + exceptions](images/demo_returns.gif) | ![Hover metadata](images/demo_hover.gif) |
| Each node pulses cyan as the function fires, sits **yellow** while running, then settles **green** on success. | Return pulses travel back **up** the spine. A function that raises flashes **red** and keeps its exception text. | Hovering a node dims the others and reveals the **module name** and **per-call duration** in the metadata overlay. |

> The HUD docks to the side of your screen and stays out of the way — translucent background, monospace labels, no title bar, click-through anywhere outside the spine. The GIFs above are rendered from the same palette and geometry the production HUD uses.

A real spine snapshot from a live ghost-pass run:

![Real HUD snapshot — Ghost run on a request pipeline](images/image.png)

Nodes pulse cyan when called and travel back up to their parent on return. Hover any node to see its source module and timing. Click a node to jump straight to that line in your editor (VS Code, Cursor, Sublime, PyCharm — auto-detected).

> The demo GIFs are generated by `scripts/build_demo_gifs.py` (Pillow only, no GUI required) so you can rebuild them after any palette/animation tweak.

---

## Installation

Requires **Python 3.10+** on Windows, macOS, or Linux (with X11/Wayland for the global hotkey hooks).

```bash
# From the project root
pip install -e .
```

This installs the `debugflow` package and three console scripts: `flow`, `flow-logs`, `flow-logs-on`, `flow-logs-off`.

Dependencies (auto-installed):

| Package    | Why                                              |
| ---------- | ------------------------------------------------ |
| `dearpygui` | GPU-accelerated drawlist for the HUD canvas      |
| `pynput`    | Cross-platform global hotkeys (no root on Linux) |
| `psutil`    | PID lifecycle + zombie process cleanup           |

---

## Minimal Usage

### Option 1 — Hotkey-driven (recommended)

```bash
cd /path/to/your/project
flow activate           # Sentinel daemon starts in the background
```

You'll see the active hotkeys printed:

```
  ──────────────────────────────────────
  DebugFlow hotkeys active:
        Toggle HUD     : Ctrl + Alt + F
        Run / Trigger  : Ctrl + Alt + S
  ──────────────────────────────────────
```

Then:

1. Press **Ctrl+Alt+F** — the translucent HUD docks to the right edge of your screen.
2. Press **Ctrl+Alt+S** — DebugFlow auto-runs your most recently modified `.py` file and streams every call into the HUD.

### Option 2 — Programmatic (no daemon needed)

```python
from debugflow.flow_engine import launch

def my_function(x, y):
    return x + y

if __name__ == "__main__":
    launch("my_function", Ghost=True, Real_Time=True)
```

Run the script directly. As long as the HUD is open on port 5555, traces flow in.

### Stopping it

```bash
flow status      # See if the sentinel is alive
flow deactivate  # Kill the sentinel and the HUD
```

---

## Problem + Motivation

Traditional Python debugging falls into three categories, and each one breaks the flow of writing code:

1. **`print()` statements** — you delete them, you re-add them, they pollute output, they teach you nothing about timing or call order.
2. **Step debuggers (`pdb`, IDE breakpoints)** — they pause execution, which is useless for any code that depends on real-time behaviour: ML training loops, async pipelines, sensor streams, anything with timing.
3. **Log scraping** — you write logs, run the script, scroll a 5000-line log trying to reconstruct what happened. By the time you understand the flow, you've forgotten the bug.

DebugFlow solves a fourth case the above don't: **"I want to *watch* my code run, in real time, without changing it."** It uses Python's built-in `sys.settrace` to intercept every function call without touching your source, ships the events to a side-of-screen HUD, and shows you the live execution as a vertical spine of glowing nodes.

For ML/AI work specifically: when training takes 40 minutes per epoch and the bug only shows up at step 12,000, you don't want to attach a debugger — you want a non-intrusive monitor that tells you "this function ran, took 230ms, returned a Tensor of shape `[64, 1024]`" without slowing the training loop.

---

## Key Features

- **Zero-edit tracing** — uses `sys.settrace`, so you never touch the code you're debugging.
- **Type + value inspection** — params and returns shown as `name: type=value` (e.g. `lr: float=0.001`, `batch: Tensor[64, 256]`).
- **Per-node timing** — every call is stamped with `time.perf_counter()` and the duration is shown on hover (`880us` / `12.4ms` / `1.23s`, auto-units).
- **Click-to-source** — clicking a node opens the file at the correct line in your editor. Auto-detects VS Code, Cursor, Windsurf, Sublime, PyCharm; override with `FLOW_EDITOR_CMD`.
- **Cross-platform global hotkeys** — `pynput.GlobalHotKeys`, no root needed on Linux. Both hotkeys configurable via env vars (default `Ctrl+Alt+F` for HUD, `Ctrl+Alt+S` for trigger — chosen specifically to *not* clash with editor save).
- **Producer-consumer architecture** — three threads (engine, socket listener, UI loop) communicate over a local TCP socket on port `5555`. UI never blocks on user code.
- **Loop & input safety** — bounded ghost-pass (50 calls / 3s / 5 inputs max) so a runaway loop in user code can never freeze the HUD.
- **Project-rooted logs** — `flow-logs on` writes to `<your_project>/logs/debugflow.log`, never to the package directory or `C:\Users\...`.
- **Pulse animation** — cyan downward pulse on `call`, upward pulse on `return`, red flash on `exception`, green flash on success.
- **Smooth-scroll focus** — once 5+ nodes spawn, the canvas slides up so the active call always sits in the centre "Focus Zone".
- **Hover metadata overlay** — module path and total duration appear in dim cyan when you hover a node, so the default view stays clean.
- **Headless-safe bridge** — if no HUD is listening, the engine logs the drop and continues; your script never crashes because the HUD isn't open.

---

## API Usage / Examples

### Tracing a single function

```python
from debugflow.flow_engine import launch

def add(x: int, y: int) -> int:
    return x + y

def runme():
    add(2, 3)
    add(10, 20)

launch("runme", Ghost=True, Real_Time=True)
```

| Flag         | Default | Effect                                                       |
| ------------ | :-----: | ------------------------------------------------------------ |
| `Ghost`      | `True`  | Bounded dry-run pass that maps the architecture before live trace fires. Enables loop/input guards. |
| `Real_Time`  | `True`  | Stream pulses to the HUD as they happen instead of buffering. |

#### Ghost mode needs type hints to be useful

The dry-run pass invents mock arguments based on each function's annotated
parameter types. If a parameter has no annotation it gets `None`, which
will usually crash on the first attribute access — and that branch of the
call graph won't be mapped. **For ghost mode to populate more than the
entry node, every function in the chain needs type hints on its parameters.**

Recognised annotations (smallest possible mock used in each case):

| Annotation                                | Mock value         |
| ----------------------------------------- | ------------------ |
| `int`, `str`, `float`, `bool`             | `1`, `"mock_val"`, `1.0`, `True` |
| `list`, `dict`, `tuple`                   | `[]`, `{}`, `()`   |
| `torch.Tensor`                            | `torch.zeros(1)`   |
| `numpy.ndarray`                           | `np.zeros(1)`      |
| `pandas.DataFrame`, `pandas.Series`       | empty `DataFrame` / `Series` |
| anything else (custom class, `nn.Module`, dataclass, `TypedDict`, …) | `None` |

ML / scientific libs are detected by qualified name and imported lazily
— DebugFlow has no hard dependency on torch/numpy/pandas; they're only
touched when you actually annotate a parameter with one of their types.

For pipelines built around custom classes (a model object, a config
dataclass, a session, etc.) where mocks aren't viable, set `Ghost=False`
and let real-time tracing do the work — the live trace doesn't need
mocks since it watches the real call.

### Tracing an ML pipeline

```python
from debugflow.flow_engine import launch
import torch

def load_batch(idx: int):
    return torch.randn(64, 256)

def forward(batch: torch.Tensor):
    return batch.mean(dim=1)

def training_step(idx: int):
    batch = load_batch(idx)
    out = forward(batch)
    return out.sum().item()

def epoch():
    for i in range(100):
        training_step(i)

launch("epoch", Ghost=False, Real_Time=True)
```

The HUD will show `load_batch`, `forward`, and `training_step` pulsing in sequence, with tensor shapes and per-call timing on hover. Ghost-pass off so the loop runs to completion.

### Programmatic pulses (manual mode)

For when `sys.settrace` is too coarse and you want to mark specific events:

```python
from debugflow.flow_bridge import Flow

Flow("127.0.0.1", 5555)
Flow.init("my-session-id")

Flow.pulse("checkpoint_saved",
           params={"epoch": 3, "loss": 0.142},
           returns="ok",
           node_type="success")
```

### Configuration via environment variables

| Variable               | Default            | Purpose                                              |
| ---------------------- | ------------------ | ---------------------------------------------------- |
| `FLOW_PROJECT_ROOT`    | (cwd of `flow activate`) | Directory the engine scans for `.py` files     |
| `FLOW_HUD_HOTKEY`      | `<ctrl>+<alt>+f`   | Toggle HUD open/close                                |
| `FLOW_TRIGGER_HOTKEY`  | `<ctrl>+<alt>+s`   | Fire engine on the most recent script                |
| `FLOW_EDITOR_CMD`      | (auto-detect)      | Click-to-source override, e.g. `code -g {file}:{line}` |
| `FLOW_SYNC_ID`         | (auto)             | Internal — correlates engine subprocess with HUD     |

### Console scripts

```bash
flow activate           # Start sentinel + bind hotkeys
flow deactivate         # Stop sentinel + close HUD
flow status             # Show running state
flow                    # Show usage banner

flow-logs on            # Enable file logging to <project>/logs/debugflow.log
flow-logs off           # Disable
flow-logs               # Toggle current state
```

---

## Project Status

**Version:** 1.0.1 — usable as a daily debugging companion.

**Stable:**

- Cross-platform sentinel (Windows / macOS / Linux/X11)
- Hotkey daemon with per-hotkey debounce and env-var overrides
- Tracer with ghost-pass loop guard and bounded `input()` shim
- HUD with smooth-scroll, hover metadata, click-to-source
- Project-rooted logs and deterministic engine cwd
- Type + value formatting for params and returns
- Per-call timing with auto-unit display

**In progress:**

- Deep-inspection formatters for ML objects (Tensor shapes, DataFrame dims, sparse matrices) — currently shown as generic `type=value`.

**Known limitations:**

- Headless cloud environments (e.g. Replit container) can run the engine but cannot show the HUD — there's no display server and global hotkeys can't bind. Run on a desktop OS to see the HUD.
- Very long parameter strings still bleed past the 400px HUD column (truncation rules planned).
- Port `5555` is hard-coded; a process-level conflict will print a clear error in the log but currently requires a manual restart.
- Things ghost mode can't see without annotations
- To prevent ModuleNotFoundError in the HUD, always run flow activate from your Project Root (the same folder where you run your main script) so that relative imports resolve correctly.

**Ghost Mode Limits**

- Ghost mode simulates execution using type hints and works best for simple, well-typed functions.
- Any unannotated parameter is treated as None, which typically causes failures when accessing attributes, indexing, or performing operations.
- Ghost mode cannot handle most custom or user-defined types, including classes, dataclasses, Pydantic models, ORM objects, and machine learning models like torch.nn.Module.
- Generic and parameterised types such as list[int], dict[str, int], Optional, Union, and Callable are not matched correctly and fall back to None.
- Several standard library types like pathlib.Path, datetime, UUID, file handles, and async-related types are not supported.
- Many scientific and ML ecosystem types, including TensorFlow, JAX, Polars, Dask, Xarray, SciPy, and PIL objects, are also unsupported.
- Forward references like "MyClass" are treated as plain strings and cannot be resolved to actual types.
- Method receivers like self and cls are not annotated and become None, so class methods usually fail immediately.
- Variadic parameters such as *args and **kwargs are not handled correctly and may prevent the function from executing at all.
- Default parameter values are ignored, so functions are executed with mocked values instead of their defaults.
- Logic that depends on specific values, such as comparisons, parsing, indexing, or validation, often fails because mock values do not satisfy real conditions.
- Any dependency on external state, including files, databases, network connections, environment variables, or hardware, will cause failures.
- Ghost mode is best suited for small, pure functions that use basic built-in types and minimal external dependencies.

**Roadmap:**

- Strict truncation rules for ML object reprs (Tensors, DataFrames, sparse arrays).
- Run-history persistence — save each completed spine to `logs/runs/<sync_id>.json` for replay/diff.
- Optional Nuitka build for single-file distribution.
- Last-Run status panel in the HUD chrome (script name, node count, total ms).

---

## Contributing

Pull requests welcome. The codebase is small and well-commented; a tour:

| File                      | Responsibility                                    |
| ------------------------- | ------------------------------------------------- |
| `src/debugflow/flow_service.py`  | Sentinel daemon, hotkey binding, HUD lifecycle |
| `src/debugflow/flow_engine.py`   | `sys.settrace` hook, ghost-pass, secure_gate  |
| `src/debugflow/flow_bridge.py`   | Socket bridge, `Flow.pulse()` payload assembly |
| `src/debugflow/flow_hud.py`      | Dear PyGui HUD, socket listener, render loop  |
| `src/debugflow/animation.py`     | Pulse + node animator (heartbeat, glow)       |
| `src/debugflow/logger_system.py` | File logger with project-rooted log path      |


---

## License

MIT — do whatever you want, just don't hold the author liable. See `LICENSE` for the full text.
