cyguide 1.0.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.
Files changed (69) hide show
  1. cyguide-1.0.0/LICENSE +21 -0
  2. cyguide-1.0.0/PKG-INFO +166 -0
  3. cyguide-1.0.0/README.md +142 -0
  4. cyguide-1.0.0/cyguide/__init__.py +0 -0
  5. cyguide-1.0.0/cyguide/app.py +154 -0
  6. cyguide-1.0.0/cyguide/engine/__init__.py +0 -0
  7. cyguide-1.0.0/cyguide/engine/adapter.py +40 -0
  8. cyguide-1.0.0/cyguide/engine/canonicalize.py +56 -0
  9. cyguide-1.0.0/cyguide/engine/diagnostics.py +327 -0
  10. cyguide-1.0.0/cyguide/engine/executor.py +236 -0
  11. cyguide-1.0.0/cyguide/engine/explainer.py +144 -0
  12. cyguide-1.0.0/cyguide/engine/gateway.py +103 -0
  13. cyguide-1.0.0/cyguide/engine/manifest.py +40 -0
  14. cyguide-1.0.0/cyguide/engine/power_facade.py +436 -0
  15. cyguide-1.0.0/cyguide/engine/recommendation.py +184 -0
  16. cyguide-1.0.0/cyguide/engine/registry.py +107 -0
  17. cyguide-1.0.0/cyguide/engine/reporter.py +217 -0
  18. cyguide-1.0.0/cyguide/engine/store.py +655 -0
  19. cyguide-1.0.0/cyguide/main.py +153 -0
  20. cyguide-1.0.0/cyguide/modes/__init__.py +0 -0
  21. cyguide-1.0.0/cyguide/modes/learning.py +68 -0
  22. cyguide-1.0.0/cyguide/modes/power.py +47 -0
  23. cyguide-1.0.0/cyguide/schemas/__init__.py +0 -0
  24. cyguide-1.0.0/cyguide/schemas/base.py +37 -0
  25. cyguide-1.0.0/cyguide/schemas/credential.py +33 -0
  26. cyguide-1.0.0/cyguide/schemas/dns.py +65 -0
  27. cyguide-1.0.0/cyguide/schemas/entity.py +18 -0
  28. cyguide-1.0.0/cyguide/schemas/host_internal.py +48 -0
  29. cyguide-1.0.0/cyguide/schemas/netblock.py +22 -0
  30. cyguide-1.0.0/cyguide/schemas/network.py +55 -0
  31. cyguide-1.0.0/cyguide/schemas/power.py +63 -0
  32. cyguide-1.0.0/cyguide/schemas/tls.py +26 -0
  33. cyguide-1.0.0/cyguide/schemas/vulnerability.py +35 -0
  34. cyguide-1.0.0/cyguide/schemas/web.py +64 -0
  35. cyguide-1.0.0/cyguide/ui/__init__.py +0 -0
  36. cyguide-1.0.0/cyguide/ui/screens/__init__.py +0 -0
  37. cyguide-1.0.0/cyguide/ui/screens/home.py +643 -0
  38. cyguide-1.0.0/cyguide/ui/screens/learning.py +527 -0
  39. cyguide-1.0.0/cyguide/ui/screens/power.py +787 -0
  40. cyguide-1.0.0/cyguide/ui/screens/tool_browser.py +102 -0
  41. cyguide-1.0.0/cyguide/ui/style.css +831 -0
  42. cyguide-1.0.0/cyguide/ui/widgets/__init__.py +0 -0
  43. cyguide-1.0.0/cyguide/ui/widgets/home.py +9 -0
  44. cyguide-1.0.0/cyguide/ui/widgets/power.py +568 -0
  45. cyguide-1.0.0/cyguide.egg-info/PKG-INFO +166 -0
  46. cyguide-1.0.0/cyguide.egg-info/SOURCES.txt +67 -0
  47. cyguide-1.0.0/cyguide.egg-info/dependency_links.txt +1 -0
  48. cyguide-1.0.0/cyguide.egg-info/entry_points.txt +2 -0
  49. cyguide-1.0.0/cyguide.egg-info/requires.txt +6 -0
  50. cyguide-1.0.0/cyguide.egg-info/top_level.txt +2 -0
  51. cyguide-1.0.0/pyproject.toml +50 -0
  52. cyguide-1.0.0/setup.cfg +4 -0
  53. cyguide-1.0.0/tools/__init__.py +0 -0
  54. cyguide-1.0.0/tools/gobuster/__init__.py +0 -0
  55. cyguide-1.0.0/tools/gobuster/adapter.py +94 -0
  56. cyguide-1.0.0/tools/gobuster/manifest.toml +34 -0
  57. cyguide-1.0.0/tools/gobuster/wordlist.txt +11 -0
  58. cyguide-1.0.0/tools/nikto/__init__.py +0 -0
  59. cyguide-1.0.0/tools/nikto/adapter.py +144 -0
  60. cyguide-1.0.0/tools/nikto/manifest.toml +34 -0
  61. cyguide-1.0.0/tools/nmap/__init__.py +0 -0
  62. cyguide-1.0.0/tools/nmap/adapter.py +83 -0
  63. cyguide-1.0.0/tools/nmap/manifest.toml +41 -0
  64. cyguide-1.0.0/tools/subfinder/__init__.py +0 -0
  65. cyguide-1.0.0/tools/subfinder/adapter.py +63 -0
  66. cyguide-1.0.0/tools/subfinder/manifest.toml +34 -0
  67. cyguide-1.0.0/tools/whois/__init__.py +0 -0
  68. cyguide-1.0.0/tools/whois/adapter.py +68 -0
  69. cyguide-1.0.0/tools/whois/manifest.toml +29 -0
cyguide-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Harshwardhan Patil and Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
cyguide-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,166 @@
1
+ Metadata-Version: 2.4
2
+ Name: cyguide
3
+ Version: 1.0.0
4
+ Summary: A TUI-based guided cybersecurity learning platform
5
+ Author: Harshwardhan Patil, CyGuide Contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/h45sh/cyguide
8
+ Project-URL: Repository, https://github.com/h45sh/cyguide
9
+ Project-URL: Issues, https://github.com/h45sh/cyguide/issues
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Topic :: Security
13
+ Classifier: Intended Audience :: Education
14
+ Requires-Python: >=3.11
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: textual>=1.0.0
18
+ Requires-Dist: pydantic>=2.0.0
19
+ Requires-Dist: aiosqlite>=0.20.0
20
+ Requires-Dist: pyperclip>=1.9.0
21
+ Requires-Dist: httpx>=0.27.0
22
+ Requires-Dist: python-dotenv>=1.0.0
23
+ Dynamic: license-file
24
+
25
+ # CyGuide – TUI-Based Guided Cybersecurity Learning and Terminal Tool Orchestration Platform
26
+
27
+ CyGuide is a Terminal User Interface (TUI) platform for cybersecurity education, designed as a pluggable ecosystem for security tools.
28
+
29
+ ## 🏗️ New Plugin Architecture
30
+
31
+ CyGuide has been restructured into a "Smart Adapter / Stupid Framework" model:
32
+
33
+ - **Core Engine (`cyguide/engine`)**: Manages a stateful entity graph and event log using SQLite.
34
+ - **Unified Schemas (`cyguide/schemas`)**: Defines a shared language for security findings (Hosts, Services, Endpoints, etc.).
35
+ - **Plugin System (`tools/`)**: Allows adding new tools (nmap, gobuster, etc.) without touching the core codebase.
36
+ - **Textual TUI (`cyguide/ui`)**: A modern, async terminal interface.
37
+
38
+ ## 🚀 Getting Started
39
+
40
+ ### Prerequisites
41
+
42
+ - Python 3.11+
43
+ - (Optional) `Ollama` for local LLM explanations.
44
+
45
+ To automatically install all required security tools (`nmap`, `gobuster`, `nikto`, `whois`, `subfinder`) and their system dependencies on Linux/macOS, run:
46
+
47
+ ```bash
48
+ ./scripts/install_deps.sh
49
+ ```
50
+
51
+ ### Installation
52
+
53
+ ```bash
54
+ # Clone and install in editable mode
55
+ pip install -e .
56
+ ```
57
+
58
+ ### Launching
59
+
60
+ ```bash
61
+ # Launch with default database (data/cyguide.db)
62
+ cyg
63
+
64
+ # Launch with a custom SQLite database
65
+ cyg --db my_project.db
66
+ ```
67
+
68
+ ### LLM Configuration
69
+
70
+ CyGuide supports both local and cloud-based LLMs for generating explanations:
71
+
72
+ #### Local (Ollama)
73
+ Launch with the `--ollama` flag and optionally specify a model (defaults to `gemma`):
74
+ ```bash
75
+ cyg --ollama --ollama-model llama3
76
+ ```
77
+
78
+ #### Cloud APIs (OpenAI, Anthropic, OpenRouter, Grok, etc.)
79
+ CyGuide uses environment variables to configure cloud LLM providers. You can set these in your shell or copy `.env.example` to `.env`.
80
+
81
+ ```bash
82
+ # Required
83
+ export CYGUIDE_API_KEY="your_api_key_here"
84
+
85
+ # Optional overrides (defaults to OpenAI / gpt-4o)
86
+ export CYGUIDE_API_TYPE="openai" # Options: openai, anthropic
87
+ export CYGUIDE_API_BASE="https://api.openai.com/v1" # E.g., https://openrouter.ai/api/v1
88
+ export CYGUIDE_API_MODEL="gpt-4o" # E.g., claude-3-5-sonnet-20240620
89
+ ```
90
+
91
+ ### 🩺 Diagnostic Health Check
92
+ Verify your environment, database permissions, installed security tools, and AI backends:
93
+ ```bash
94
+ cyg check
95
+ ```
96
+ *(Use `cyg check --json` for scriptable JSON output in CI/CD pipelines).*
97
+
98
+ ### 💾 Session Portability & Reporting
99
+ CyGuide provides built-in mechanisms to export, import, and generate reports from your investigations:
100
+
101
+ #### 1. Machine-Readable Database Exports (`exports/`)
102
+ Export a standalone, self-contained SQLite archive of a specific session containing its full entity graph, relationships, and raw command execution logs:
103
+ ```bash
104
+ cyg export <session_id> exports/my_session.db
105
+ ```
106
+ Import a previously exported session `.db` into your local workspace on any machine:
107
+ ```bash
108
+ cyg import exports/my_session.db
109
+ ```
110
+ * **Who are Exports for?**
111
+ * **Instructors & Graders**: Students can export their lab/CTF session into an archive and submit it. Instructors can run `cyg import` to review findings, topology, and execution timelines in the TUI.
112
+ * **Security Teams**: Analysts can share specific engagement graphs with team members for peer review or shift handoffs without exposing the entire global database.
113
+ * **Archiving**: Lightweight, standalone backups of completed pentest engagements or CTF challenges.
114
+
115
+ #### 2. Human-Readable Markdown Reports (`reports/`)
116
+ Generate a formatted executive and technical Markdown report summarizing all discovered hosts, services, vulnerabilities, and executed commands:
117
+ ```bash
118
+ cyg export <session_id> exports/my_session.db --report reports/my_session_report.md
119
+ ```
120
+ *(You can also trigger automatic export and reporting directly inside Power Mode by pressing `Ctrl+E`).*
121
+
122
+ ## 📜 Utility Scripts
123
+
124
+ CyGuide includes dedicated helper scripts under `scripts/`:
125
+
126
+ | Script | Purpose |
127
+ | :--- | :--- |
128
+ | [`./scripts/install_deps.sh`](scripts/install_deps.sh) | Automatically installs required system tools (`nmap`, `gobuster`, `nikto`, `whois`, `subfinder`) and Perl XML dependencies across Debian/Ubuntu, Arch, Fedora/RHEL, and macOS (Homebrew). |
129
+ | [`./scripts/verify.sh`](scripts/verify.sh) | Runs the comprehensive verification pipeline: executes the 86-test pytest suite, validates and regenerates the 15-schema documentation, and checks integration pipelines. |
130
+ | [`./scripts/generate_schema_registry.py`](scripts/generate_schema_registry.py) | Introspects the `cyguide.schemas` module and dynamically updates `docs/developer/SCHEMA_REGISTRY.md` with active finding schemas and Primary Identity Keys (PIKs). |
131
+
132
+ ## ✅ Testing & Verification
133
+
134
+ To verify the codebase stability and ensure documentation is in sync with the schemas, run:
135
+
136
+ ```bash
137
+ ./scripts/verify.sh
138
+ ```
139
+
140
+ ## 🛠️ Adding a Tool
141
+
142
+ CyGuide is built for extensibility. See [docs/user/CONTRIBUTING.md](docs/user/CONTRIBUTING.md) to learn how to write a new adapter.
143
+
144
+ ## 📚 Documentation
145
+
146
+ * **[User Manual](docs/user/USER_MANUAL.md)**: Operating guide, keyboard shortcuts, UI panel descriptions, and export/import usage.
147
+ * **[Architecture & Domain Context](docs/developer/ARCHITECTURE.md)**: System design details, database schemas, and facade layers.
148
+ * **[Database Architecture & Specification](docs/developer/DATABASE.md)**: Exhaustive database models, PIK hashing, ER diagrams, and portability.
149
+ * **[Schema Registry](docs/developer/SCHEMA_REGISTRY.md)**: Standard 15-schema vocabulary and Primary Identity Key (PIK) rules.
150
+ * **[Roadmap & Progress Tracker](docs/developer/ROADMAP.md)**: Unified project phases, task checklists, and historical walkthroughs.
151
+ * **[Autonomous Agent Harness Vision](docs/developer/FUTURE_POWER_MODE.md)**: Architecture for autonomous AI agents, HITL safety gates, and multi-agent roles.
152
+ * **[Developer Performance Notes](docs/developer/DEVELOPER_NOTES.md)**: Real-time streaming, event loops, and CPU load roadblocks.
153
+ * **[Contributors](docs/developer/CONTRIBUTORS.md)**: Project ownership and governance.
154
+
155
+ ## 📂 Project Structure & Data Isolation
156
+
157
+ - `cyguide/`: The core application package (engine, schemas, modes, TUI).
158
+ - `tools/`: Tool plugin adapters and manifests (`nmap`, `gobuster`, `nikto`, `whois`, `subfinder`).
159
+ - `scripts/`: Development and system installation scripts.
160
+ - `docs/`: Technical and user documentation.
161
+ - `data/`: Default directory for local runtime SQLite databases (`cyguide.db`) and scratchpad notes (ignored from version control).
162
+ - `exports/`: Destination for exported portable session `.db` archives (ignored from version control).
163
+ - `reports/`: Destination for generated Markdown investigation reports (ignored from version control).
164
+
165
+ ---
166
+
@@ -0,0 +1,142 @@
1
+ # CyGuide – TUI-Based Guided Cybersecurity Learning and Terminal Tool Orchestration Platform
2
+
3
+ CyGuide is a Terminal User Interface (TUI) platform for cybersecurity education, designed as a pluggable ecosystem for security tools.
4
+
5
+ ## 🏗️ New Plugin Architecture
6
+
7
+ CyGuide has been restructured into a "Smart Adapter / Stupid Framework" model:
8
+
9
+ - **Core Engine (`cyguide/engine`)**: Manages a stateful entity graph and event log using SQLite.
10
+ - **Unified Schemas (`cyguide/schemas`)**: Defines a shared language for security findings (Hosts, Services, Endpoints, etc.).
11
+ - **Plugin System (`tools/`)**: Allows adding new tools (nmap, gobuster, etc.) without touching the core codebase.
12
+ - **Textual TUI (`cyguide/ui`)**: A modern, async terminal interface.
13
+
14
+ ## 🚀 Getting Started
15
+
16
+ ### Prerequisites
17
+
18
+ - Python 3.11+
19
+ - (Optional) `Ollama` for local LLM explanations.
20
+
21
+ To automatically install all required security tools (`nmap`, `gobuster`, `nikto`, `whois`, `subfinder`) and their system dependencies on Linux/macOS, run:
22
+
23
+ ```bash
24
+ ./scripts/install_deps.sh
25
+ ```
26
+
27
+ ### Installation
28
+
29
+ ```bash
30
+ # Clone and install in editable mode
31
+ pip install -e .
32
+ ```
33
+
34
+ ### Launching
35
+
36
+ ```bash
37
+ # Launch with default database (data/cyguide.db)
38
+ cyg
39
+
40
+ # Launch with a custom SQLite database
41
+ cyg --db my_project.db
42
+ ```
43
+
44
+ ### LLM Configuration
45
+
46
+ CyGuide supports both local and cloud-based LLMs for generating explanations:
47
+
48
+ #### Local (Ollama)
49
+ Launch with the `--ollama` flag and optionally specify a model (defaults to `gemma`):
50
+ ```bash
51
+ cyg --ollama --ollama-model llama3
52
+ ```
53
+
54
+ #### Cloud APIs (OpenAI, Anthropic, OpenRouter, Grok, etc.)
55
+ CyGuide uses environment variables to configure cloud LLM providers. You can set these in your shell or copy `.env.example` to `.env`.
56
+
57
+ ```bash
58
+ # Required
59
+ export CYGUIDE_API_KEY="your_api_key_here"
60
+
61
+ # Optional overrides (defaults to OpenAI / gpt-4o)
62
+ export CYGUIDE_API_TYPE="openai" # Options: openai, anthropic
63
+ export CYGUIDE_API_BASE="https://api.openai.com/v1" # E.g., https://openrouter.ai/api/v1
64
+ export CYGUIDE_API_MODEL="gpt-4o" # E.g., claude-3-5-sonnet-20240620
65
+ ```
66
+
67
+ ### 🩺 Diagnostic Health Check
68
+ Verify your environment, database permissions, installed security tools, and AI backends:
69
+ ```bash
70
+ cyg check
71
+ ```
72
+ *(Use `cyg check --json` for scriptable JSON output in CI/CD pipelines).*
73
+
74
+ ### 💾 Session Portability & Reporting
75
+ CyGuide provides built-in mechanisms to export, import, and generate reports from your investigations:
76
+
77
+ #### 1. Machine-Readable Database Exports (`exports/`)
78
+ Export a standalone, self-contained SQLite archive of a specific session containing its full entity graph, relationships, and raw command execution logs:
79
+ ```bash
80
+ cyg export <session_id> exports/my_session.db
81
+ ```
82
+ Import a previously exported session `.db` into your local workspace on any machine:
83
+ ```bash
84
+ cyg import exports/my_session.db
85
+ ```
86
+ * **Who are Exports for?**
87
+ * **Instructors & Graders**: Students can export their lab/CTF session into an archive and submit it. Instructors can run `cyg import` to review findings, topology, and execution timelines in the TUI.
88
+ * **Security Teams**: Analysts can share specific engagement graphs with team members for peer review or shift handoffs without exposing the entire global database.
89
+ * **Archiving**: Lightweight, standalone backups of completed pentest engagements or CTF challenges.
90
+
91
+ #### 2. Human-Readable Markdown Reports (`reports/`)
92
+ Generate a formatted executive and technical Markdown report summarizing all discovered hosts, services, vulnerabilities, and executed commands:
93
+ ```bash
94
+ cyg export <session_id> exports/my_session.db --report reports/my_session_report.md
95
+ ```
96
+ *(You can also trigger automatic export and reporting directly inside Power Mode by pressing `Ctrl+E`).*
97
+
98
+ ## 📜 Utility Scripts
99
+
100
+ CyGuide includes dedicated helper scripts under `scripts/`:
101
+
102
+ | Script | Purpose |
103
+ | :--- | :--- |
104
+ | [`./scripts/install_deps.sh`](scripts/install_deps.sh) | Automatically installs required system tools (`nmap`, `gobuster`, `nikto`, `whois`, `subfinder`) and Perl XML dependencies across Debian/Ubuntu, Arch, Fedora/RHEL, and macOS (Homebrew). |
105
+ | [`./scripts/verify.sh`](scripts/verify.sh) | Runs the comprehensive verification pipeline: executes the 86-test pytest suite, validates and regenerates the 15-schema documentation, and checks integration pipelines. |
106
+ | [`./scripts/generate_schema_registry.py`](scripts/generate_schema_registry.py) | Introspects the `cyguide.schemas` module and dynamically updates `docs/developer/SCHEMA_REGISTRY.md` with active finding schemas and Primary Identity Keys (PIKs). |
107
+
108
+ ## ✅ Testing & Verification
109
+
110
+ To verify the codebase stability and ensure documentation is in sync with the schemas, run:
111
+
112
+ ```bash
113
+ ./scripts/verify.sh
114
+ ```
115
+
116
+ ## 🛠️ Adding a Tool
117
+
118
+ CyGuide is built for extensibility. See [docs/user/CONTRIBUTING.md](docs/user/CONTRIBUTING.md) to learn how to write a new adapter.
119
+
120
+ ## 📚 Documentation
121
+
122
+ * **[User Manual](docs/user/USER_MANUAL.md)**: Operating guide, keyboard shortcuts, UI panel descriptions, and export/import usage.
123
+ * **[Architecture & Domain Context](docs/developer/ARCHITECTURE.md)**: System design details, database schemas, and facade layers.
124
+ * **[Database Architecture & Specification](docs/developer/DATABASE.md)**: Exhaustive database models, PIK hashing, ER diagrams, and portability.
125
+ * **[Schema Registry](docs/developer/SCHEMA_REGISTRY.md)**: Standard 15-schema vocabulary and Primary Identity Key (PIK) rules.
126
+ * **[Roadmap & Progress Tracker](docs/developer/ROADMAP.md)**: Unified project phases, task checklists, and historical walkthroughs.
127
+ * **[Autonomous Agent Harness Vision](docs/developer/FUTURE_POWER_MODE.md)**: Architecture for autonomous AI agents, HITL safety gates, and multi-agent roles.
128
+ * **[Developer Performance Notes](docs/developer/DEVELOPER_NOTES.md)**: Real-time streaming, event loops, and CPU load roadblocks.
129
+ * **[Contributors](docs/developer/CONTRIBUTORS.md)**: Project ownership and governance.
130
+
131
+ ## 📂 Project Structure & Data Isolation
132
+
133
+ - `cyguide/`: The core application package (engine, schemas, modes, TUI).
134
+ - `tools/`: Tool plugin adapters and manifests (`nmap`, `gobuster`, `nikto`, `whois`, `subfinder`).
135
+ - `scripts/`: Development and system installation scripts.
136
+ - `docs/`: Technical and user documentation.
137
+ - `data/`: Default directory for local runtime SQLite databases (`cyguide.db`) and scratchpad notes (ignored from version control).
138
+ - `exports/`: Destination for exported portable session `.db` archives (ignored from version control).
139
+ - `reports/`: Destination for generated Markdown investigation reports (ignored from version control).
140
+
141
+ ---
142
+
File without changes
@@ -0,0 +1,154 @@
1
+ """Main CyGuide TUI Application."""
2
+
3
+ import os
4
+ from textual.app import App, SystemCommand
5
+ from cyguide.ui.screens.home import DashboardScreen
6
+ from cyguide.ui.screens.learning import LearningModeScreen
7
+ from cyguide.ui.screens.tool_browser import ToolBrowserScreen
8
+ from cyguide.ui.screens.power import PowerModeScreen
9
+
10
+ from typing import Optional, Dict, Any, List
11
+ import subprocess
12
+
13
+ from cyguide.engine.registry import ToolRegistry
14
+ from cyguide.engine.store import GraphStore
15
+ from cyguide.engine.executor import Executor
16
+ from cyguide.engine.explainer import LearningExplainer, OllamaBackend
17
+ from cyguide.modes.learning import LearningModeEngine
18
+ from cyguide.modes.power import PowerModeEngine
19
+ from cyguide.engine.power_facade import PowerWorkspaceFacade
20
+
21
+ class CyGuideApp(App):
22
+ """The central orchestrator for the CyGuide TUI."""
23
+
24
+ CSS_PATH = "ui/style.css"
25
+ TITLE = "CyGuide"
26
+
27
+ # Register screens so they can be switched by name
28
+ SCREENS = {
29
+ "dashboard": DashboardScreen,
30
+ "tool_browser": ToolBrowserScreen,
31
+ "learning_mode": LearningModeScreen,
32
+ "power_mode": PowerModeScreen,
33
+ }
34
+
35
+ def __init__(self, db_path: str = "data/cyguide.db", use_ollama: bool = False, ollama_model: str = "gemma", tools_dir: str = None, **kwargs):
36
+ super().__init__(**kwargs)
37
+ self.db_path = db_path
38
+ self.use_ollama = use_ollama
39
+ self.ollama_model = ollama_model
40
+ self.tools_dir = tools_dir
41
+ self.selected_session_id: Optional[str] = None
42
+ self.selected_workspace_id: Optional[str] = None
43
+ self.user_env: Dict[str, str] = os.environ.copy()
44
+ self.user_shell: str = "/bin/bash"
45
+ # Ensure the directory for the database exists
46
+ db_dir = os.path.dirname(os.path.abspath(self.db_path))
47
+ os.makedirs(db_dir, exist_ok=True)
48
+
49
+ def detect_user_shell(self) -> str:
50
+ """Find the user's default shell."""
51
+ return os.environ.get("SHELL", "/bin/bash")
52
+
53
+ def get_shell_environment(self) -> Dict[str, str]:
54
+ """Capture the full login shell environment."""
55
+ shell = self.detect_user_shell()
56
+ try:
57
+ # Run a login shell to capture the fully resolved environment
58
+ result = subprocess.run(
59
+ [shell, "-l", "-c", "env"],
60
+ capture_output=True, text=True, timeout=5
61
+ )
62
+ env = {}
63
+ for line in result.stdout.splitlines():
64
+ if "=" in line:
65
+ key, _, val = line.partition("=")
66
+ env[key] = val
67
+ return env if env else os.environ.copy()
68
+ except Exception:
69
+ return os.environ.copy()
70
+
71
+ async def on_mount(self) -> None:
72
+ """Initialize the app with core components and the dashboard."""
73
+ self.user_shell = self.detect_user_shell()
74
+ self.user_env = self.get_shell_environment()
75
+
76
+ self.learning_mode_tool = "nmap" # Default
77
+ # 1. Initialize Engines
78
+ self.registry = ToolRegistry(tools_dir=self.tools_dir)
79
+ self.registry.load_tools()
80
+
81
+ self.store = GraphStore(self.db_path)
82
+ await self.store.initialize()
83
+
84
+ # Ensure singleton Learning Sandbox exists
85
+ self.learning_ws_id, self.learning_session_id = await self.store.get_or_create_learning_sandbox()
86
+
87
+ from cyguide.engine.recommendation import RecommendationEngine
88
+ self.recommendation_engine = RecommendationEngine(self.store)
89
+ self.store.on_upsert(self.recommendation_engine.handle_upsert)
90
+
91
+ self.executor = Executor(self.store)
92
+
93
+ # Setup Explainer
94
+ from dotenv import load_dotenv
95
+ load_dotenv()
96
+ if self.use_ollama:
97
+ self.explainer_backend = OllamaBackend(model=self.ollama_model)
98
+ else:
99
+ api_key = os.environ.get("CYGUIDE_API_KEY") or os.environ.get("GROQ_API_KEY")
100
+ if api_key:
101
+ from cyguide.engine.explainer import CloudAPIBackend
102
+ api_type = os.environ.get("CYGUIDE_API_TYPE", "openai")
103
+ if os.environ.get("GROQ_API_KEY") and not os.environ.get("CYGUIDE_API_BASE"):
104
+ api_base = "https://api.groq.com/openai/v1"
105
+ api_model = os.environ.get("CYGUIDE_API_MODEL", "llama-3.3-70b-versatile")
106
+ else:
107
+ api_base = os.environ.get("CYGUIDE_API_BASE", "https://api.openai.com/v1")
108
+ api_model = os.environ.get("CYGUIDE_API_MODEL", "gpt-4o")
109
+ self.explainer_backend = CloudAPIBackend(api_type, api_base, api_key, api_model)
110
+ else:
111
+ # Fallback to Ollama if no API key is provided and use_ollama is false
112
+ self.explainer_backend = OllamaBackend(model=self.ollama_model)
113
+
114
+ self.explainer = LearningExplainer(self.explainer_backend)
115
+
116
+ self.learning_engine = LearningModeEngine(self.registry, self.executor, self.explainer)
117
+ self.power_engine = PowerModeEngine(self.registry, self.executor)
118
+ self.power_facade = PowerWorkspaceFacade(self.store, self.executor, self.registry)
119
+ self.power_facade.user_env = self.user_env
120
+ self.power_facade.user_shell = self.user_shell
121
+
122
+ # 2. Setup UI
123
+ self.push_screen("dashboard")
124
+ self.animations_enabled = True
125
+
126
+ async def on_unmount(self) -> None:
127
+ """Cleanup resources before exit."""
128
+ if hasattr(self, "executor"):
129
+ await self.executor.shutdown()
130
+ if hasattr(self, "store"):
131
+ await self.store.close()
132
+
133
+ def action_toggle_animations(self) -> None:
134
+ """Toggle UI animations on or off via the command palette."""
135
+ self.animations_enabled = not self.animations_enabled
136
+ if self.animations_enabled:
137
+ self.remove_class("no-animations")
138
+ self.notify("Animations Enabled")
139
+ else:
140
+ self.add_class("no-animations")
141
+ self.notify("Animations Disabled")
142
+
143
+ def get_system_commands(self, screen):
144
+ """Add custom commands to the Command Palette (Ctrl+P)."""
145
+ yield from super().get_system_commands(screen)
146
+ yield SystemCommand(
147
+ "Toggle Animations",
148
+ "Turn sidebar animations on or off",
149
+ self.action_toggle_animations
150
+ )
151
+
152
+ if __name__ == "__main__":
153
+ app = CyGuideApp()
154
+ app.run()
File without changes
@@ -0,0 +1,40 @@
1
+ """Abstract base class for all tool plugins."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from typing import AsyncIterator, List, Dict, Any
5
+ from cyguide.schemas.base import BaseFinding
6
+
7
+
8
+ class ToolAdapter(ABC):
9
+ """
10
+ Contract for tool contributors.
11
+ Every tool in tools/ must implement this in adapter.py.
12
+ """
13
+
14
+ @abstractmethod
15
+ def validate_install(self) -> bool:
16
+ """Check if the tool binary is available on the system."""
17
+ pass
18
+
19
+ @abstractmethod
20
+ def build_command(self, target: BaseFinding, params: Dict[str, Any]) -> List[str]:
21
+ """
22
+ Build the command line arguments for the tool.
23
+
24
+ Args:
25
+ target: The finding being scanned (e.g. a network.host)
26
+ params: User-provided flags or options from the TUI
27
+ """
28
+ pass
29
+
30
+ @abstractmethod
31
+ async def parse_output(self, raw_stdout: str, target: BaseFinding, context: Dict[str, Any] = None) -> AsyncIterator[BaseFinding]:
32
+ """
33
+ Parse tool output and yield standardized findings.
34
+
35
+ Args:
36
+ raw_stdout: The raw output string from the tool
37
+ target: The original target finding (for context/parenting)
38
+ context: Optional dictionary for tracking state across lines (e.g. current host)
39
+ """
40
+ pass
@@ -0,0 +1,56 @@
1
+ # PROTECTED FILE — See CONTRIBUTING.md before modifying.
2
+ # Changes to this file require team agreement.
3
+ """Normalization filters for finding data."""
4
+
5
+ import urllib.parse
6
+
7
+
8
+ def canonicalize(value):
9
+ """Apply normalization rules based on the type of value."""
10
+ if isinstance(value, str):
11
+ # General string cleaning
12
+ value = value.strip()
13
+
14
+ # Lowercase hostnames (heuristic: no spaces, contains dots or is localhost)
15
+ if "." in value or value.lower() == "localhost":
16
+ if " " not in value and ":" not in value:
17
+ return value.lower()
18
+
19
+ return value
20
+
21
+
22
+ def canonicalize_host(ip_or_name: str) -> str:
23
+ """Normalize IP addresses and hostnames."""
24
+ val = ip_or_name.strip().lower()
25
+ if val in ("localhost", "127.0.0.1", "::1"):
26
+ return "127.0.0.1"
27
+ # Basic IP normalization (lowercase IPv6, etc)
28
+ return val
29
+
30
+
31
+ def canonicalize_url(url: str) -> str:
32
+ """Normalize a URL: lowercase scheme/host, strip default ports."""
33
+ try:
34
+ parsed = urllib.parse.urlparse(url)
35
+ scheme = parsed.scheme.lower()
36
+ netloc = parsed.netloc.lower()
37
+
38
+ # Strip default ports
39
+ if scheme == "http" and netloc.endswith(":80"):
40
+ netloc = netloc[:-3]
41
+ elif scheme == "https" and netloc.endswith(":443"):
42
+ netloc = netloc[:-4]
43
+
44
+ return urllib.parse.urlunparse(
45
+ (scheme, netloc, parsed.path, parsed.params, parsed.query, parsed.fragment)
46
+ )
47
+ except Exception:
48
+ return url
49
+
50
+
51
+ def canonicalize_port(port) -> int:
52
+ """Ensure port is an integer."""
53
+ try:
54
+ return int(port)
55
+ except (ValueError, TypeError):
56
+ return 0