Metadata-Version: 2.4
Name: omp_graph
Version: 0.1.0
Summary: OMP plugin for manual graph construction and LLM context synthesis from source code.
Project-URL: Homepage, https://github.com/thinmanj/oh-my-graph
Project-URL: Bug Tracker, https://github.com/thinmanj/oh-my-graph/issues
Author-email: Julio Ona <thinmanj@gmail.com>
License: MIT
License-File: LICENSE
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.11
Requires-Dist: duckdb>=0.10.0
Requires-Dist: networkx>=3.0
Requires-Dist: pydantic>=2.0
Requires-Dist: python-dateutil>=2.8
Requires-Dist: rich>=13.0
Requires-Dist: typing-extensions>=4.0
Provides-Extra: dev
Requires-Dist: black>=24.0; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=6.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# omp-graph

[![](https://img.shields.io/pypi/v/omp-graph.svg)](https://pypi.org/project/omp-graph/)
[![](https://img.shields.io/github/actions/workflow/status/thinmanj/oh-my-graph/ci.yml?branch=master)](https://github.com/thinmanj/oh-my-graph/actions)
[![](https://img.shields.io/pypi/pyversions/omp-graph.svg)](https://pypi.org/project/omp-graph/)

An OMP plugin for manual graph construction and LLM context synthesis from source code.

Build knowledge graphs of your codebase, define tasks, and generate rich context for AI-powered development workflows.

## Repository

📦 **GitHub:** [thinmanj/oh-my-graph](https://github.com/thinmanj/oh-my-graph)

```bash
# Clone the repository
git clone https://github.com/thinmanj/oh-my-graph.git

# Navigate into the project
cd oh-my-graph

# Install in development mode
pip install -e .[dev]
```

## Overview

`omp-graph` lets you:

1. **Scan codebases** using graphify extractors to discover code symbols
2. **Build graphs manually** via an interactive TUI — define nodes and edges with precise control
3. **Generate LLM context** from graphs, focusing on specific nodes with configurable depth
4. **Integrate with OMP tasks** to feed structured context to AI agents

Unlike fully-automatic graph tools, `omp-graph` emphasizes **manual control** — you decide which symbols to include and how they relate. This is essential when handling large codebases where precision matters.

## Installation

### From PyPI (when published)

```bash
pip install omp-graph
```

### From Source

```bash
pip install -e .
```

### Dependencies

- **duckdb** — Persistent graph storage (analytical engine)
- **graphify** — Multi-language symbol extraction (Python, JS/TS, Java, C/C++, and more)
- **rich** — TUI for interactive graph building
- **networkx** — Graph algorithms and traversals
- **pydantic** — Data validation

## Quick Start

### Interactive Builder

```bash
# Launch the interactive builder
omp-graph

# Commands in the TUI:
#   1. Scan codebase — discover symbols via graphify
#   2. Add manual node — create custom nodes
#   3. Create edge — connect nodes with typed relationships
#   4. View graph — inspect nodes, edges, communities
#   5. Validate graph — check for orphaned nodes and broken references
#   6. Save graph — persist to DuckDB
#   7. Load graph — restore from storage
#   8. Export context — generate LLM prompt from graph
#   9. View workflow log
```

### Programmatic Usage

```python
from omp_graph.builder import create_builder
from omp_graph.context import build_llm_context
from omp_graph.storage import GraphStorage

# Create a builder
builder = create_builder()

# Scan a codebase
builder.scan_and_populate("/path/to/project", recursive=True)

# Add a manual node
node_id = builder.add_manual_node(
    title="Architecture Decision: User Auth",
    content="Use JWT tokens for stateless authentication",
    source_path="docs/architecture.md"
)

# Create edges between symbols
builder.create_edge(
    "app/main.py::main_function",
    "auth/jwt.py::generate_token",
    edge_type="CALLS",
    confidence=0.95,
    rationale="main() calls generate_token() during login"
)

# Validate graph
issues = builder.validate_graph()

# Generate LLM context
context = build_llm_context(
    builder.graph,
    target_node_id="app/main.py::main_function",
    depth=2
)
print(context)

# Save to storage
storage = GraphStorage("/path/to/graph.db")
builder.save_to_storage(storage, "my-project-graph")
```

## Graph Model

### Nodes

Nodes represent code symbols (functions, classes, modules) or manual concepts.

| Field | Type | Description |
|-------|------|-------------|
| `id` | str | Stable unique identifier |
| `title` | str | Display name |
| `content` | str | Content or description |
| `source_path` | str? | File path if code symbol |
| `symbol` | str? | Code symbol name |
| `tags` | List[str] | Classification tags (e.g., "function", "class") |
| `community` | str\|int? | Grouping/clustering |
| `metadata` | Dict | Arbitrary key-value metadata |
| `parent_id` | str? | ID of parent node (hierarchical) |
| `children` | List[str] | IDs of child nodes |

### Edges

Edges represent relationships between nodes.

| Field | Type | Description |
|-------|------|-------------|
| `source_id` | str | Source node ID |
| `target_id` | str | Target node ID |
| `edge_type` | str | Relationship type (CALLS, DEPENDS_ON, IMPLEMENTS, etc.) |
| `confidence` | float | 0.0–1.0 confidence score |
| `rationale` | str | Human-readable explanation |

### Edge Types

| Type | Meaning |
|------|---------|
| `DEPENDS_ON` | General dependency |
| `CALLS` | Function/method call |
| `IMPLEMENTS` | Implementation/interface relationship |
| `CONTAINS` | Containment (e.g., module contains class) |
| `IMPORTS` | Import statement |
| `EXTENDS` | Inheritance/extension |
| `USES` | Usage relationship |

## Scanner Integration

The built-in scanner wraps graphify's extractors for these languages:

| Extension | Language |
|-----------|----------|
| `.py` | Python |
| `.js`, `.mjs` | JavaScript |
| `.ts` | TypeScript |
| `.tsx` | TypeScript + JSX |
| `.java` | Java |
| `.cpp`, `.cc`, `.cxx` | C++ |
| `.h`, `.hpp` | C/C++ header |

## LLM Context Formats

The context builder supports multiple output formats:

### Code Analysis Format (default)
```
=== CODE ANALYSIS CONTEXT ===
TARGET: main_function
Type: code_symbol
Location: app/main.py
...
=== CONTEXT END ===
```

### OpenAI Chat Format
```python
builder.format_for_openai(graph, target_node_id="...", depth=1)
# Returns: [{"role": "system", "content": ...}, {"role": "user", "content": ...}]
```

### Claude Format
```python
builder.format_for_claude(graph, target_node_id="...", depth=1)
# Returns: "system prompt\n\nuser prompt"
```

## Storage

Graphs are persisted using DuckDB with a fallback in-memory storage mode.

### Schema

```sql
-- Nodes table
CREATE TABLE nodes (
    id VARCHAR PRIMARY KEY,
    title VARCHAR,
    content VARCHAR,
    source_path VARCHAR,
    symbol VARCHAR,
    parent_id VARCHAR,
    depth INTEGER,
    community VARCHAR,
    metadata JSON
);

-- Edges table
CREATE TABLE edges (
    source_id VARCHAR,
    target_id VARCHAR,
    edge_type VARCHAR,
    confidence DOUBLE,
    rationale VARCHAR,
    metadata JSON
);
```

### Storage API

```python
from omp_graph.storage import GraphStorage

# Auto-connects to omp_graph.db in current directory
storage = GraphStorage()

# Use a custom path
storage = GraphStorage("/path/to/graph.db")

# Save and load
storage.save_graph(graph)
loaded_graph = storage.load_graph()

# Export to JSON
json_data = storage.export_as_json()

# Import from JSON
graph = storage.import_from_json(json_data)
```

## OMP Plugin Integration

The plugin exposes the following commands via the OMP plugin system:

| Command | Description |
|---------|-------------|
| `graph build` | Launch interactive graph builder CLI |
| `graph scan` | Scan codebase and populate graph |
| `graph context` | Generate LLM context from graph |
| `graph validate` | Validate graph integrity |
| `graph save` | Save current graph to storage |
| `graph load` | Load graph from storage |

## Development

```bash
# Install in development mode
pip install -e .[dev]

# Run all tests
pytest tests/ -v

# Run specific test file
pytest tests/test_models_storage.py -v

# Format code
black omp_graph/ tests/

# Lint
ruff check omp_graph/ tests/

# Type check
mypy omp_graph/
```

### Running Tests

```bash
# Run full test suite
pytest tests/ -v

# Run with coverage
pytest tests/ --cov=omp_graph --cov-report=html
```

## TODO / Future Work

- [ ] Publish to PyPI
- [ ] Automated graph building from CI/CD
- [ ] Team collaboration features
- [ ] Visualization export (GraphML, Neo4j)
- [ ] Incremental updates to existing graphs

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                    OMP Plugin System                        │
├─────────────────────────────────────────────────────────────┤
│  omp_graph/plugin.py                                        │
│                                                             │
│  Commands:                                                  │
│  • omp-graph scan   → scan_and_populate()                   │
│  • omp-graph build  → launch CLI                            │
│  • omp-graph context → build_llm_context()                  │
│  • omp-graph save/load → GraphStorage                       │
└──────────────┬──────────────────────────────────────────────┘
               │
    ┌──────────┴──────────┬───────────────┬───────────────┐
    │                     │               │               │
    ▼                     ▼               ▼               ▼
  builder.py          scanner.py      context.py       storage.py
  (manual graph)   (graphify       (LLM context       (DuckDB
                    extraction)      synthesis)        backend)
                    
    ┌──────────────────────┐
    │                      │
    ▼                      ▼
  models.py           cli.py
  (Node, Edge,        (Rich TUI)
   Graph)
```

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request