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.
- cyguide-1.0.0/LICENSE +21 -0
- cyguide-1.0.0/PKG-INFO +166 -0
- cyguide-1.0.0/README.md +142 -0
- cyguide-1.0.0/cyguide/__init__.py +0 -0
- cyguide-1.0.0/cyguide/app.py +154 -0
- cyguide-1.0.0/cyguide/engine/__init__.py +0 -0
- cyguide-1.0.0/cyguide/engine/adapter.py +40 -0
- cyguide-1.0.0/cyguide/engine/canonicalize.py +56 -0
- cyguide-1.0.0/cyguide/engine/diagnostics.py +327 -0
- cyguide-1.0.0/cyguide/engine/executor.py +236 -0
- cyguide-1.0.0/cyguide/engine/explainer.py +144 -0
- cyguide-1.0.0/cyguide/engine/gateway.py +103 -0
- cyguide-1.0.0/cyguide/engine/manifest.py +40 -0
- cyguide-1.0.0/cyguide/engine/power_facade.py +436 -0
- cyguide-1.0.0/cyguide/engine/recommendation.py +184 -0
- cyguide-1.0.0/cyguide/engine/registry.py +107 -0
- cyguide-1.0.0/cyguide/engine/reporter.py +217 -0
- cyguide-1.0.0/cyguide/engine/store.py +655 -0
- cyguide-1.0.0/cyguide/main.py +153 -0
- cyguide-1.0.0/cyguide/modes/__init__.py +0 -0
- cyguide-1.0.0/cyguide/modes/learning.py +68 -0
- cyguide-1.0.0/cyguide/modes/power.py +47 -0
- cyguide-1.0.0/cyguide/schemas/__init__.py +0 -0
- cyguide-1.0.0/cyguide/schemas/base.py +37 -0
- cyguide-1.0.0/cyguide/schemas/credential.py +33 -0
- cyguide-1.0.0/cyguide/schemas/dns.py +65 -0
- cyguide-1.0.0/cyguide/schemas/entity.py +18 -0
- cyguide-1.0.0/cyguide/schemas/host_internal.py +48 -0
- cyguide-1.0.0/cyguide/schemas/netblock.py +22 -0
- cyguide-1.0.0/cyguide/schemas/network.py +55 -0
- cyguide-1.0.0/cyguide/schemas/power.py +63 -0
- cyguide-1.0.0/cyguide/schemas/tls.py +26 -0
- cyguide-1.0.0/cyguide/schemas/vulnerability.py +35 -0
- cyguide-1.0.0/cyguide/schemas/web.py +64 -0
- cyguide-1.0.0/cyguide/ui/__init__.py +0 -0
- cyguide-1.0.0/cyguide/ui/screens/__init__.py +0 -0
- cyguide-1.0.0/cyguide/ui/screens/home.py +643 -0
- cyguide-1.0.0/cyguide/ui/screens/learning.py +527 -0
- cyguide-1.0.0/cyguide/ui/screens/power.py +787 -0
- cyguide-1.0.0/cyguide/ui/screens/tool_browser.py +102 -0
- cyguide-1.0.0/cyguide/ui/style.css +831 -0
- cyguide-1.0.0/cyguide/ui/widgets/__init__.py +0 -0
- cyguide-1.0.0/cyguide/ui/widgets/home.py +9 -0
- cyguide-1.0.0/cyguide/ui/widgets/power.py +568 -0
- cyguide-1.0.0/cyguide.egg-info/PKG-INFO +166 -0
- cyguide-1.0.0/cyguide.egg-info/SOURCES.txt +67 -0
- cyguide-1.0.0/cyguide.egg-info/dependency_links.txt +1 -0
- cyguide-1.0.0/cyguide.egg-info/entry_points.txt +2 -0
- cyguide-1.0.0/cyguide.egg-info/requires.txt +6 -0
- cyguide-1.0.0/cyguide.egg-info/top_level.txt +2 -0
- cyguide-1.0.0/pyproject.toml +50 -0
- cyguide-1.0.0/setup.cfg +4 -0
- cyguide-1.0.0/tools/__init__.py +0 -0
- cyguide-1.0.0/tools/gobuster/__init__.py +0 -0
- cyguide-1.0.0/tools/gobuster/adapter.py +94 -0
- cyguide-1.0.0/tools/gobuster/manifest.toml +34 -0
- cyguide-1.0.0/tools/gobuster/wordlist.txt +11 -0
- cyguide-1.0.0/tools/nikto/__init__.py +0 -0
- cyguide-1.0.0/tools/nikto/adapter.py +144 -0
- cyguide-1.0.0/tools/nikto/manifest.toml +34 -0
- cyguide-1.0.0/tools/nmap/__init__.py +0 -0
- cyguide-1.0.0/tools/nmap/adapter.py +83 -0
- cyguide-1.0.0/tools/nmap/manifest.toml +41 -0
- cyguide-1.0.0/tools/subfinder/__init__.py +0 -0
- cyguide-1.0.0/tools/subfinder/adapter.py +63 -0
- cyguide-1.0.0/tools/subfinder/manifest.toml +34 -0
- cyguide-1.0.0/tools/whois/__init__.py +0 -0
- cyguide-1.0.0/tools/whois/adapter.py +68 -0
- 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
|
+
|
cyguide-1.0.0/README.md
ADDED
|
@@ -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
|