onboardai 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,189 @@
1
+ Metadata-Version: 2.4
2
+ Name: onboardai
3
+ Version: 0.1.0
4
+ Summary: An AI-powered onboarding intelligence layer on top of Graphify for MCP
5
+ Author-email: Your Name <your.email@example.com>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.12
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: fastapi>=0.100.0
12
+ Requires-Dist: uvicorn>=0.20.0
13
+ Requires-Dist: mcp>=1.0.0
14
+ Requires-Dist: networkx>=3.0
15
+ Requires-Dist: pydantic>=2.0
16
+
17
+ # OnboardAI: AI-Powered Onboarding Intelligence Layer
18
+
19
+ ![OnboardAI Use Case & Features](/C:/Users/RohitAnish/.gemini/antigravity/brain/9d4ee102-a356-4df9-9cb4-367ee82337e8/onboard_ai_infographic_1781504940514.png)
20
+
21
+ OnboardAI is a developer onboarding intelligence system that integrates with Claude Code and other MCP-compatible clients. It is designed to dramatically reduce the time it takes a new developer, intern, or employee to understand a codebase by converting raw repository data and Graphify knowledge graphs into interactive, onboarding-oriented insights.
22
+
23
+ ---
24
+
25
+ ## 1. Vision & Architecture
26
+
27
+ Rather than generating raw repository diagrams or acting as another codebase crawler, OnboardAI acts as a **structured guidance layer** on top of Graphify. It parses Graphify’s extraction data, maps relationships with NetworkX, groups code modules by directory structure, and answers questions relative to what tasks a developer has been assigned.
28
+
29
+ ### Core Architecture Flow
30
+
31
+ ```mermaid
32
+ flowchart TD
33
+ subgraph Client Layer
34
+ ClaudeCode[Claude Code / MCP Client]
35
+ end
36
+
37
+ subgraph OnboardAI MCP Server
38
+ Server[FastMCP Server]
39
+ Scanner[Project Scanner & Tech Detector]
40
+ Adapter[Graphify Adapter]
41
+ Roadmap[Roadmap Generator]
42
+ QA[Q&A & Context Engine]
43
+ Viz[Mermaid Visualizer]
44
+ end
45
+
46
+ subgraph Intelligence Engine
47
+ Graphify[Graphify extraction]
48
+ NX[NetworkX Directed Graph]
49
+ end
50
+
51
+ ClaudeCode <-->|JSON-RPC via Stdio/SSE| Server
52
+ Server <--> Scanner
53
+ Server <--> Adapter
54
+ Adapter <-->|Reads graphify-out/| Graphify
55
+ Adapter <-->|Builds| NX
56
+ Roadmap <--> Adapter
57
+ QA <--> Adapter
58
+ Viz <--> Adapter
59
+ ```
60
+
61
+ ---
62
+
63
+ ## 2. Directory Layout & Components
64
+
65
+ Here is the file structure of the OnboardAI project:
66
+
67
+ ```text
68
+ OnboardAI/
69
+ ├── .graphifyignore # Ignore rules to bypass LLM extraction for non-code files
70
+ ├── requirements.txt # Project dependencies (FastAPI, uvicorn, mcp, networkx)
71
+ ├── main.py # Launcher: starts MCP server in stdio or sse mode
72
+ ├── test_integration.py # Offline self-check verification test script
73
+ ├── test_client.py # Standard python MCP client session simulation script
74
+ ├── scanner/
75
+ │ ├── __init__.py
76
+ │ ├── project_scanner.py # Counts files and crawls folders
77
+ │ └── architecture_detector.py # Detects tech stacks (FastAPI, React, etc.)
78
+ ├── knowledge/
79
+ │ ├── __init__.py
80
+ │ ├── graphify_adapter.py # Integrates Graphify output and builds NetworkX graphs
81
+ │ ├── onboarding_plan.py # Generates day-by-day study paths
82
+ │ ├── repository_inventory.py# Structured module/class/function catalogs
83
+ │ └── qa_assistant.py # Performs graph-based Q&A and task instructions
84
+ └── graph/
85
+ ├── __init__.py
86
+ └── graph_generator.py # Generates Mermaid mindmaps, dependencies, and call-flows
87
+ ```
88
+
89
+ ---
90
+
91
+ ## 3. How Each Feature Works & How It's Built
92
+
93
+ ### Feature 1: Repository Scan & Graph Integration
94
+ - **How it's built**: Implemented in `scanner/project_scanner.py` and `scanner/architecture_detector.py`.
95
+ - **How it works**: Walks the codebase directories (excluding noise like `.git`, `node_modules`, and virtual environments). It looks for configuration signatures (e.g. `package.json`, `requirements.txt`, `manage.py`, `Dockerfile`) and extracts details.
96
+ - **Graphify Integration**: Located in `knowledge/graphify_adapter.py`. If `graphify-out/graph.json` is missing, the adapter automatically invokes `python -m graphify extract <repo_path>` via a subprocess to bootstrap the graph. It then builds a `networkx.DiGraph` to represent the entities and relationships.
97
+
98
+ ### Feature 2: Dependency-Aware Learning Roadmap
99
+ - **How it's built**: Implemented in `knowledge/onboarding_plan.py`.
100
+ - **How it works**: Groups files using Graphify’s community detection. It builds a directed graph of community dependencies (if Community A calls/imports elements in Community B, then B is foundational to A). It uses **topological sorting** (or sorting by in/out-degree ratios) to order the learning path:
101
+ - **Day 1**: Environment setup, tech summary, configs.
102
+ - **Day 2**: Foundational modules (utilities, schemas, database clients).
103
+ - **Day 3**: Mid-level business logic.
104
+ - **Day 4**: API controllers, routers, and entry points.
105
+ - **Day 5**: Automated tests and first contribution.
106
+
107
+ ### Feature 3: Mindmap & Dependency Visualization
108
+ - **How it's built**: Implemented in `graph/graph_generator.py`.
109
+ - **How it works**: Traversing the NetworkX graph, it extracts relationships and formats them directly into **Mermaid syntax**:
110
+ - `generate_mindmap()`: Creates a Mermaid `mindmap` showing high-level folders and key classes.
111
+ - `generate_call_flow()`: Creates a flow diagram (`flowchart TD`) of method-to-method calls.
112
+ - `generate_dependency_graph()`: Creates an import diagram (`flowchart LR`) of module dependencies.
113
+
114
+ ### Feature 4: Interactive Q&A & Task-Context Overlays
115
+ - **How it's built**: Implemented in `knowledge/qa_assistant.py`.
116
+ - **How it works**: Uses regex and keywords to search the graph. If a query matches a module (e.g. `ProjectScanner`), it generates a structured analysis of the component: *Purpose, Responsibilities, Methods, Dependencies,* and *Callers*.
117
+ - **Task-Context Overlays**: If the client provides a `work_context` string (e.g., *"I need to implement a visualizer"*), the Q&A assistant searches for components associated with those keywords in the graph and appends tailored, step-by-step developer instructions.
118
+
119
+ ---
120
+
121
+ ## 4. MCP Server & Protocols
122
+
123
+ The MCP Server is implemented in `mcp_server/server.py` using the high-level **FastMCP SDK**. This enables automatic tool schemas, JSON-RPC communication, and transport selection.
124
+
125
+ It exposes **10 tools** to any connected client:
126
+ 1. `analyze_repository(repo_path)`: High-level tech stack and file count summary.
127
+ 2. `generate_onboarding_plan(repo_path, role, team, target_module)`: Customized daily learning roadmap.
128
+ 3. `explain_project(repo_path)`: Basic codebase summary.
129
+ 4. `explain_module(repo_path, module_name)`: Full signature and relationship breakout for a module.
130
+ 5. `list_modules(repo_path)`: Direct directory list of files and components.
131
+ 6. `search_repository(repo_path, query)`: Search symbols/descriptions in the codebase.
132
+ 7. `get_architecture(repo_path, visualization_type)`: Generates Mermaid charts.
133
+ 8. `get_learning_path(repo_path)`: Retrieves recommended files to read first.
134
+ 9. `get_dependencies(repo_path)`: Returns internal couplings and external dependencies.
135
+ 10. `ask_repository_question(repo_path, question, work_context)`: Q&A helper with custom action items.
136
+
137
+ ---
138
+
139
+ ## 5. Setup & Integration Guide
140
+
141
+ ### Local Verification
142
+ Verify the server runs successfully on your machine by running the test client session simulation:
143
+ ```powershell
144
+ $env:PYTHONIOENCODING="utf-8"
145
+ python test_client.py
146
+ ```
147
+ This script acts as a local client session, connects to the server, retrieves the tools list, and invokes them locally.
148
+
149
+ ### Integrating with Claude Code
150
+ To register the server with the **Claude Code CLI**, run:
151
+ ```powershell
152
+ claude mcp add onboard-ai python "C:\Users\RohitAnish\.gemini\antigravity\scratch\OnboardAI\main.py"
153
+ ```
154
+
155
+ Once registered, launch Claude Code:
156
+ ```powershell
157
+ claude
158
+ ```
159
+
160
+ ### Integrating with Claude Desktop
161
+ To integrate with the **Claude Desktop App**, open your desktop configuration file:
162
+ - **Path**: `%APPDATA%\Claude\claude_desktop_config.json`
163
+ - **Configuration**:
164
+ ```json
165
+ {
166
+ "mcpServers": {
167
+ "onboard-ai": {
168
+ "command": "python",
169
+ "args": [
170
+ "C:/Users/RohitAnish/.gemini/antigravity/scratch/OnboardAI/main.py"
171
+ ]
172
+ }
173
+ }
174
+ }
175
+ ```
176
+
177
+ ---
178
+
179
+ ## 6. How to Ask Questions
180
+
181
+ Once integrated into Claude, the model will automatically pick the right tool based on your natural language prompt. Here are some examples:
182
+
183
+ | Question you ask Claude | Tool Claude calls under the hood |
184
+ | :--- | :--- |
185
+ | **"How should I learn this project?"** | `generate_onboarding_plan` |
186
+ | **"Explain the module ProjectScanner"** | `explain_module` |
187
+ | **"Which components are critical to look at?"** | `get_learning_path` |
188
+ | **"Show me the dependency mindmap"** | `get_architecture(visualization_type='mindmap')` |
189
+ | **"How does the project work? I am going to work on the visualizer."** | `ask_repository_question(work_context='visualizer')` |
@@ -0,0 +1,173 @@
1
+ # OnboardAI: AI-Powered Onboarding Intelligence Layer
2
+
3
+ ![OnboardAI Use Case & Features](/C:/Users/RohitAnish/.gemini/antigravity/brain/9d4ee102-a356-4df9-9cb4-367ee82337e8/onboard_ai_infographic_1781504940514.png)
4
+
5
+ OnboardAI is a developer onboarding intelligence system that integrates with Claude Code and other MCP-compatible clients. It is designed to dramatically reduce the time it takes a new developer, intern, or employee to understand a codebase by converting raw repository data and Graphify knowledge graphs into interactive, onboarding-oriented insights.
6
+
7
+ ---
8
+
9
+ ## 1. Vision & Architecture
10
+
11
+ Rather than generating raw repository diagrams or acting as another codebase crawler, OnboardAI acts as a **structured guidance layer** on top of Graphify. It parses Graphify’s extraction data, maps relationships with NetworkX, groups code modules by directory structure, and answers questions relative to what tasks a developer has been assigned.
12
+
13
+ ### Core Architecture Flow
14
+
15
+ ```mermaid
16
+ flowchart TD
17
+ subgraph Client Layer
18
+ ClaudeCode[Claude Code / MCP Client]
19
+ end
20
+
21
+ subgraph OnboardAI MCP Server
22
+ Server[FastMCP Server]
23
+ Scanner[Project Scanner & Tech Detector]
24
+ Adapter[Graphify Adapter]
25
+ Roadmap[Roadmap Generator]
26
+ QA[Q&A & Context Engine]
27
+ Viz[Mermaid Visualizer]
28
+ end
29
+
30
+ subgraph Intelligence Engine
31
+ Graphify[Graphify extraction]
32
+ NX[NetworkX Directed Graph]
33
+ end
34
+
35
+ ClaudeCode <-->|JSON-RPC via Stdio/SSE| Server
36
+ Server <--> Scanner
37
+ Server <--> Adapter
38
+ Adapter <-->|Reads graphify-out/| Graphify
39
+ Adapter <-->|Builds| NX
40
+ Roadmap <--> Adapter
41
+ QA <--> Adapter
42
+ Viz <--> Adapter
43
+ ```
44
+
45
+ ---
46
+
47
+ ## 2. Directory Layout & Components
48
+
49
+ Here is the file structure of the OnboardAI project:
50
+
51
+ ```text
52
+ OnboardAI/
53
+ ├── .graphifyignore # Ignore rules to bypass LLM extraction for non-code files
54
+ ├── requirements.txt # Project dependencies (FastAPI, uvicorn, mcp, networkx)
55
+ ├── main.py # Launcher: starts MCP server in stdio or sse mode
56
+ ├── test_integration.py # Offline self-check verification test script
57
+ ├── test_client.py # Standard python MCP client session simulation script
58
+ ├── scanner/
59
+ │ ├── __init__.py
60
+ │ ├── project_scanner.py # Counts files and crawls folders
61
+ │ └── architecture_detector.py # Detects tech stacks (FastAPI, React, etc.)
62
+ ├── knowledge/
63
+ │ ├── __init__.py
64
+ │ ├── graphify_adapter.py # Integrates Graphify output and builds NetworkX graphs
65
+ │ ├── onboarding_plan.py # Generates day-by-day study paths
66
+ │ ├── repository_inventory.py# Structured module/class/function catalogs
67
+ │ └── qa_assistant.py # Performs graph-based Q&A and task instructions
68
+ └── graph/
69
+ ├── __init__.py
70
+ └── graph_generator.py # Generates Mermaid mindmaps, dependencies, and call-flows
71
+ ```
72
+
73
+ ---
74
+
75
+ ## 3. How Each Feature Works & How It's Built
76
+
77
+ ### Feature 1: Repository Scan & Graph Integration
78
+ - **How it's built**: Implemented in `scanner/project_scanner.py` and `scanner/architecture_detector.py`.
79
+ - **How it works**: Walks the codebase directories (excluding noise like `.git`, `node_modules`, and virtual environments). It looks for configuration signatures (e.g. `package.json`, `requirements.txt`, `manage.py`, `Dockerfile`) and extracts details.
80
+ - **Graphify Integration**: Located in `knowledge/graphify_adapter.py`. If `graphify-out/graph.json` is missing, the adapter automatically invokes `python -m graphify extract <repo_path>` via a subprocess to bootstrap the graph. It then builds a `networkx.DiGraph` to represent the entities and relationships.
81
+
82
+ ### Feature 2: Dependency-Aware Learning Roadmap
83
+ - **How it's built**: Implemented in `knowledge/onboarding_plan.py`.
84
+ - **How it works**: Groups files using Graphify’s community detection. It builds a directed graph of community dependencies (if Community A calls/imports elements in Community B, then B is foundational to A). It uses **topological sorting** (or sorting by in/out-degree ratios) to order the learning path:
85
+ - **Day 1**: Environment setup, tech summary, configs.
86
+ - **Day 2**: Foundational modules (utilities, schemas, database clients).
87
+ - **Day 3**: Mid-level business logic.
88
+ - **Day 4**: API controllers, routers, and entry points.
89
+ - **Day 5**: Automated tests and first contribution.
90
+
91
+ ### Feature 3: Mindmap & Dependency Visualization
92
+ - **How it's built**: Implemented in `graph/graph_generator.py`.
93
+ - **How it works**: Traversing the NetworkX graph, it extracts relationships and formats them directly into **Mermaid syntax**:
94
+ - `generate_mindmap()`: Creates a Mermaid `mindmap` showing high-level folders and key classes.
95
+ - `generate_call_flow()`: Creates a flow diagram (`flowchart TD`) of method-to-method calls.
96
+ - `generate_dependency_graph()`: Creates an import diagram (`flowchart LR`) of module dependencies.
97
+
98
+ ### Feature 4: Interactive Q&A & Task-Context Overlays
99
+ - **How it's built**: Implemented in `knowledge/qa_assistant.py`.
100
+ - **How it works**: Uses regex and keywords to search the graph. If a query matches a module (e.g. `ProjectScanner`), it generates a structured analysis of the component: *Purpose, Responsibilities, Methods, Dependencies,* and *Callers*.
101
+ - **Task-Context Overlays**: If the client provides a `work_context` string (e.g., *"I need to implement a visualizer"*), the Q&A assistant searches for components associated with those keywords in the graph and appends tailored, step-by-step developer instructions.
102
+
103
+ ---
104
+
105
+ ## 4. MCP Server & Protocols
106
+
107
+ The MCP Server is implemented in `mcp_server/server.py` using the high-level **FastMCP SDK**. This enables automatic tool schemas, JSON-RPC communication, and transport selection.
108
+
109
+ It exposes **10 tools** to any connected client:
110
+ 1. `analyze_repository(repo_path)`: High-level tech stack and file count summary.
111
+ 2. `generate_onboarding_plan(repo_path, role, team, target_module)`: Customized daily learning roadmap.
112
+ 3. `explain_project(repo_path)`: Basic codebase summary.
113
+ 4. `explain_module(repo_path, module_name)`: Full signature and relationship breakout for a module.
114
+ 5. `list_modules(repo_path)`: Direct directory list of files and components.
115
+ 6. `search_repository(repo_path, query)`: Search symbols/descriptions in the codebase.
116
+ 7. `get_architecture(repo_path, visualization_type)`: Generates Mermaid charts.
117
+ 8. `get_learning_path(repo_path)`: Retrieves recommended files to read first.
118
+ 9. `get_dependencies(repo_path)`: Returns internal couplings and external dependencies.
119
+ 10. `ask_repository_question(repo_path, question, work_context)`: Q&A helper with custom action items.
120
+
121
+ ---
122
+
123
+ ## 5. Setup & Integration Guide
124
+
125
+ ### Local Verification
126
+ Verify the server runs successfully on your machine by running the test client session simulation:
127
+ ```powershell
128
+ $env:PYTHONIOENCODING="utf-8"
129
+ python test_client.py
130
+ ```
131
+ This script acts as a local client session, connects to the server, retrieves the tools list, and invokes them locally.
132
+
133
+ ### Integrating with Claude Code
134
+ To register the server with the **Claude Code CLI**, run:
135
+ ```powershell
136
+ claude mcp add onboard-ai python "C:\Users\RohitAnish\.gemini\antigravity\scratch\OnboardAI\main.py"
137
+ ```
138
+
139
+ Once registered, launch Claude Code:
140
+ ```powershell
141
+ claude
142
+ ```
143
+
144
+ ### Integrating with Claude Desktop
145
+ To integrate with the **Claude Desktop App**, open your desktop configuration file:
146
+ - **Path**: `%APPDATA%\Claude\claude_desktop_config.json`
147
+ - **Configuration**:
148
+ ```json
149
+ {
150
+ "mcpServers": {
151
+ "onboard-ai": {
152
+ "command": "python",
153
+ "args": [
154
+ "C:/Users/RohitAnish/.gemini/antigravity/scratch/OnboardAI/main.py"
155
+ ]
156
+ }
157
+ }
158
+ }
159
+ ```
160
+
161
+ ---
162
+
163
+ ## 6. How to Ask Questions
164
+
165
+ Once integrated into Claude, the model will automatically pick the right tool based on your natural language prompt. Here are some examples:
166
+
167
+ | Question you ask Claude | Tool Claude calls under the hood |
168
+ | :--- | :--- |
169
+ | **"How should I learn this project?"** | `generate_onboarding_plan` |
170
+ | **"Explain the module ProjectScanner"** | `explain_module` |
171
+ | **"Which components are critical to look at?"** | `get_learning_path` |
172
+ | **"Show me the dependency mindmap"** | `get_architecture(visualization_type='mindmap')` |
173
+ | **"How does the project work? I am going to work on the visualizer."** | `ask_repository_question(work_context='visualizer')` |
@@ -0,0 +1 @@
1
+ # OnboardAI graph module
@@ -0,0 +1,110 @@
1
+ from typing import Dict, Any, List
2
+ from knowledge.graphify_adapter import GraphifyAdapter
3
+
4
+ class GraphGenerator:
5
+ def __init__(self, adapter: GraphifyAdapter):
6
+ self.adapter = adapter
7
+
8
+ def generate_mindmap(self) -> str:
9
+ """
10
+ Generate a Mermaid mindmap representing the repository layout and core component dependencies.
11
+ """
12
+ if not self.adapter.G:
13
+ return "%% Graph not loaded %%"
14
+
15
+ proj_name = self.adapter.repo_path.name
16
+ mindmap = [
17
+ "mindmap",
18
+ f" root(({proj_name}))"
19
+ ]
20
+
21
+ # Group by directory
22
+ modules = self.adapter.get_modules()
23
+ for mod_name, items in list(modules.items())[:6]: # Limit to 6 modules to keep mindmap readable
24
+ mindmap.append(f" {mod_name}")
25
+
26
+ # Sub-items: key classes/files
27
+ seen_labels = set()
28
+ added_count = 0
29
+ for item in items:
30
+ lbl = item["label"]
31
+ if lbl not in seen_labels and item["type"] in ["class", "function", "file"]:
32
+ seen_labels.add(lbl)
33
+ clean_lbl = lbl.replace("(", "").replace(")", "").replace("[", "").replace("]", "").replace(" ", "_")
34
+ mindmap.append(f" {clean_lbl}")
35
+ added_count += 1
36
+ if added_count >= 4: # Cap at 4 items per branch
37
+ break
38
+
39
+ return "\n".join(mindmap)
40
+
41
+ def generate_call_flow(self) -> str:
42
+ """
43
+ Generate a Mermaid flow diagram showing function calls and method invocations.
44
+ """
45
+ if not self.adapter.G:
46
+ return "%% Graph not loaded %%"
47
+
48
+ mermaid = [
49
+ "flowchart TD"
50
+ ]
51
+
52
+ deps = self.adapter.get_dependencies()
53
+ call_edges = [edge for edge in deps["internal"] if edge["relation"] == "calls"]
54
+
55
+ seen_edges = set()
56
+ node_ids = set()
57
+ for edge in call_edges[:25]: # Limit to top 25 calls
58
+ u, v = edge["source"], edge["target"]
59
+ u_lbl = edge["source_label"].replace("(", "").replace(")", "")
60
+ v_lbl = edge["target_label"].replace("(", "").replace(")", "")
61
+
62
+ u_id = u.replace("/", "_").replace(".", "_").replace("-", "_").replace(":", "_").replace(" ", "_")
63
+ v_id = v.replace("/", "_").replace(".", "_").replace("-", "_").replace(":", "_").replace(" ", "_")
64
+
65
+ node_ids.add(f" {u_id}[\"{u_lbl}\"]")
66
+ node_ids.add(f" {v_id}[\"{v_lbl}\"]")
67
+
68
+ edge_key = (u_id, v_id)
69
+ if edge_key not in seen_edges:
70
+ seen_edges.add(edge_key)
71
+ mermaid.append(f" {u_id} -->|calls| {v_id}")
72
+
73
+ mermaid = [mermaid[0]] + list(node_ids) + mermaid[1:]
74
+
75
+ return "\n".join(mermaid)
76
+
77
+ def generate_dependency_graph(self) -> str:
78
+ """
79
+ Generate a Mermaid flowchart of module-to-module dependencies.
80
+ """
81
+ if not self.adapter.G:
82
+ return "%% Graph not loaded %%"
83
+
84
+ mermaid = [
85
+ "flowchart LR"
86
+ ]
87
+
88
+ deps = self.adapter.get_dependencies()
89
+ import_edges = [edge for edge in deps["internal"] if edge["relation"] == "imports"]
90
+
91
+ seen_edges = set()
92
+ node_ids = set()
93
+ for edge in import_edges[:30]: # Limit to 30 dependencies
94
+ u, v = edge["source"], edge["target"]
95
+ u_lbl = edge["source_label"].replace("[", "").replace("]", "")
96
+ v_lbl = edge["target_label"].replace("[", "").replace("]", "")
97
+
98
+ u_id = u.replace("/", "_").replace(".", "_").replace("-", "_").replace(":", "_").replace(" ", "_")
99
+ v_id = v.replace("/", "_").replace(".", "_").replace("-", "_").replace(":", "_").replace(" ", "_")
100
+
101
+ node_ids.add(f" {u_id}[\"{u_lbl}\"]")
102
+ node_ids.add(f" {v_id}[\"{v_lbl}\"]")
103
+
104
+ edge_key = (u_id, v_id)
105
+ if edge_key not in seen_edges:
106
+ seen_edges.add(edge_key)
107
+ mermaid.append(f" {u_id} -.-> {v_id}")
108
+
109
+ mermaid = [mermaid[0]] + list(node_ids) + mermaid[1:]
110
+ return "\n".join(mermaid)
@@ -0,0 +1 @@
1
+ # OnboardAI knowledge module