hanuscode 1.0.0__py3-none-any.whl

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 (93) hide show
  1. hanus/__init__.py +5 -0
  2. hanus/__main__.py +10 -0
  3. hanus/action_handlers.py +76 -0
  4. hanus/action_parser.py +82 -0
  5. hanus/agent_runner.py +1445 -0
  6. hanus/analysis/__init__.py +5 -0
  7. hanus/analysis/debt.py +702 -0
  8. hanus/analysis/dependencies.py +475 -0
  9. hanus/cache/__init__.py +5 -0
  10. hanus/cache/response_cache.py +560 -0
  11. hanus/config.py +401 -0
  12. hanus/connectors/__init__.py +19 -0
  13. hanus/connectors/base.py +114 -0
  14. hanus/connectors/claude_connector.py +146 -0
  15. hanus/connectors/gemini_connector.py +141 -0
  16. hanus/connectors/glm_connector.py +160 -0
  17. hanus/connectors/ollama_connector.py +174 -0
  18. hanus/connectors/openai_connector.py +122 -0
  19. hanus/connectors/registry.py +26 -0
  20. hanus/context/__init__.py +7 -0
  21. hanus/context/manager.py +837 -0
  22. hanus/context/selective.py +626 -0
  23. hanus/error_recovery/__init__.py +5 -0
  24. hanus/error_recovery/auto_fix.py +605 -0
  25. hanus/hooks/__init__.py +5 -0
  26. hanus/hooks/manager.py +247 -0
  27. hanus/instincts/__init__.py +44 -0
  28. hanus/instincts/cli.py +372 -0
  29. hanus/instincts/detector.py +281 -0
  30. hanus/instincts/evolver.py +361 -0
  31. hanus/instincts/manager.py +343 -0
  32. hanus/instincts/types.py +253 -0
  33. hanus/logger.py +81 -0
  34. hanus/memory/__init__.py +8 -0
  35. hanus/memory/manager.py +265 -0
  36. hanus/memory/types.py +119 -0
  37. hanus/monitor.py +341 -0
  38. hanus/parallel/__init__.py +5 -0
  39. hanus/parallel/executor.py +300 -0
  40. hanus/permissions.py +182 -0
  41. hanus/plan/__init__.py +8 -0
  42. hanus/plan/mode.py +267 -0
  43. hanus/plan/models.py +152 -0
  44. hanus/plugin_manager.py +754 -0
  45. hanus/plugin_registry.py +391 -0
  46. hanus/plugins/__init__.py +1 -0
  47. hanus/plugins/arena.py +630 -0
  48. hanus/plugins/code_review.py +123 -0
  49. hanus/plugins/cortex.py +1750 -0
  50. hanus/plugins/deps_check.py +27 -0
  51. hanus/plugins/git_ops.py +33 -0
  52. hanus/plugins/metasploit.py +530 -0
  53. hanus/plugins/notes.py +583 -0
  54. hanus/plugins/search_code.py +59 -0
  55. hanus/plugins/searchsploit.py +495 -0
  56. hanus/plugins/strategist.py +175 -0
  57. hanus/plugins/webui.py +5200 -0
  58. hanus/profiles.py +479 -0
  59. hanus/profiles_builtin/__init__.py +0 -0
  60. hanus/profiles_builtin/architect/profile.yaml +12 -0
  61. hanus/profiles_builtin/architect/system_prompt.txt +71 -0
  62. hanus/profiles_builtin/deep/profile.yaml +12 -0
  63. hanus/profiles_builtin/deep/system_prompt.txt +66 -0
  64. hanus/profiles_builtin/developer/__init__.py +0 -0
  65. hanus/profiles_builtin/developer/profile.yaml +9 -0
  66. hanus/profiles_builtin/developer/system_prompt.txt +176 -0
  67. hanus/profiles_builtin/speed/profile.yaml +12 -0
  68. hanus/profiles_builtin/speed/system_prompt.txt +51 -0
  69. hanus/project_tools.py +177 -0
  70. hanus/query_engine.py +1594 -0
  71. hanus/rules/__init__.py +237 -0
  72. hanus/search/__init__.py +5 -0
  73. hanus/search/semantic.py +596 -0
  74. hanus/session_manager.py +547 -0
  75. hanus/skill_manager.py +702 -0
  76. hanus/skills/__init__.py +4 -0
  77. hanus/subagent/__init__.py +8 -0
  78. hanus/subagent/agents/__init__.py +253 -0
  79. hanus/subagent/manager.py +309 -0
  80. hanus/subagent/types.py +266 -0
  81. hanus/suggestions/__init__.py +5 -0
  82. hanus/suggestions/proactive.py +451 -0
  83. hanus/tasks/__init__.py +8 -0
  84. hanus/tasks/manager.py +330 -0
  85. hanus/tasks/models.py +106 -0
  86. hanus/terminal_prompt.py +166 -0
  87. hanus/tools.py +1849 -0
  88. hanus/ui.py +939 -0
  89. hanuscode-1.0.0.dist-info/METADATA +1151 -0
  90. hanuscode-1.0.0.dist-info/RECORD +93 -0
  91. hanuscode-1.0.0.dist-info/WHEEL +5 -0
  92. hanuscode-1.0.0.dist-info/entry_points.txt +2 -0
  93. hanuscode-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,237 @@
1
+ # hanus/rules/__init__.py
2
+ """
3
+ Rules loader and registry.
4
+
5
+ Carga reglas comunes y específicas por lenguaje desde archivos .md
6
+ y las registra para uso del sistema de agentes.
7
+ """
8
+ from __future__ import annotations
9
+ import re
10
+ from pathlib import Path
11
+ from dataclasses import dataclass, field
12
+ from typing import Dict, List, Optional
13
+ from enum import Enum
14
+
15
+
16
+ class RuleCategory(Enum):
17
+ """Categorías de reglas."""
18
+ CODING_STYLE = "coding-style"
19
+ SECURITY = "security"
20
+ TESTING = "testing"
21
+ PATTERNS = "patterns"
22
+ PERFORMANCE = "performance"
23
+ DEVELOPMENT_WORKFLOW = "development-workflow"
24
+
25
+
26
+ class RuleLanguage(Enum):
27
+ """Lenguajes soportados."""
28
+ COMMON = "common"
29
+ PYTHON = "python"
30
+ TYPESCRIPT = "typescript"
31
+ JAVASCRIPT = "javascript"
32
+ GO = "go"
33
+ RUST = "rust"
34
+ JAVA = "java"
35
+ PHP = "php"
36
+ SWIFT = "swift"
37
+ KOTLIN = "kotlin"
38
+ CPP = "cpp"
39
+ CSHARP = "csharp"
40
+ REACT = "react"
41
+ FASTAPI = "fastapi"
42
+ DJANGO = "django"
43
+
44
+
45
+ @dataclass
46
+ class Rule:
47
+ """Representa una regla cargada desde archivo."""
48
+ category: RuleCategory
49
+ language: RuleLanguage
50
+ name: str
51
+ content: str
52
+ file_path: Path
53
+ sections: Dict[str, str] = field(default_factory=dict)
54
+
55
+ def get_section(self, name: str) -> Optional[str]:
56
+ """Obtiene una sección específica de la regla."""
57
+ return self.sections.get(name)
58
+
59
+ def get_all_sections(self) -> Dict[str, str]:
60
+ """Obtiene todas las secciones."""
61
+ return self.sections
62
+
63
+
64
+ class RulesLoader:
65
+ """Cargador de reglas desde archivos markdown."""
66
+
67
+ def __init__(self, rules_dir: Path = None):
68
+ self.rules_dir = rules_dir or Path(__file__).parent
69
+ self._rules: Dict[str, Rule] = {}
70
+ self._loaded = False
71
+
72
+ def load_all(self, force: bool = False) -> Dict[str, Rule]:
73
+ """Carga todas las reglas desde los archivos .md."""
74
+ if self._loaded and not force:
75
+ return self._rules
76
+
77
+ self._rules.clear()
78
+
79
+ # Cargar reglas comunes
80
+ common_dir = self.rules_dir / "common"
81
+ if common_dir.exists():
82
+ for rule_file in common_dir.glob("*.md"):
83
+ rule = self._load_rule(rule_file, RuleLanguage.COMMON)
84
+ if rule:
85
+ key = f"common/{rule.name}"
86
+ self._rules[key] = rule
87
+
88
+ # Cargar reglas por lenguaje
89
+ for language in RuleLanguage:
90
+ if language == RuleLanguage.COMMON:
91
+ continue
92
+ lang_dir = self.rules_dir / language.value
93
+ if lang_dir.exists():
94
+ for rule_file in lang_dir.glob("*.md"):
95
+ rule = self._load_rule(rule_file, language)
96
+ if rule:
97
+ key = f"{language.value}/{rule.name}"
98
+ self._rules[key] = rule
99
+
100
+ self._loaded = True
101
+ return self._rules
102
+
103
+ def _load_rule(self, file_path: Path, language: RuleLanguage) -> Optional[Rule]:
104
+ """Carga una regla desde un archivo .md."""
105
+ try:
106
+ content = file_path.read_text(encoding="utf-8")
107
+
108
+ # Extraer nombre del archivo
109
+ name = file_path.stem
110
+
111
+ # Determinar categoría
112
+ category = self._get_category_from_name(name)
113
+
114
+ # Parsear secciones
115
+ sections = self._parse_sections(content)
116
+
117
+ return Rule(
118
+ category=category,
119
+ language=language,
120
+ name=name,
121
+ content=content,
122
+ file_path=file_path,
123
+ sections=sections,
124
+ )
125
+ except Exception as e:
126
+ print(f"[RulesLoader] Error loading {file_path}: {e}")
127
+ return None
128
+
129
+ def _get_category_from_name(self, name: str) -> RuleCategory:
130
+ """Determina la categoría de la regla desde su nombre."""
131
+ name_lower = name.lower()
132
+ for category in RuleCategory:
133
+ if category.value in name_lower:
134
+ return category
135
+ return RuleCategory.CODING_STYLE # Default
136
+
137
+ def _parse_sections(self, content: str) -> Dict[str, str]:
138
+ """Parsea las secciones del markdown."""
139
+ sections = {}
140
+ current_section = None
141
+ current_content = []
142
+
143
+ for line in content.split("\n"):
144
+ # Detectar encabezados de sección (##)
145
+ if line.startswith("## "):
146
+ if current_section:
147
+ sections[current_section] = "\n".join(current_content).strip()
148
+ current_section = line[3:].strip()
149
+ current_content = []
150
+ elif current_section:
151
+ current_content.append(line)
152
+
153
+ # Guardar última sección
154
+ if current_section:
155
+ sections[current_section] = "\n".join(current_content).strip()
156
+
157
+ return sections
158
+
159
+ def get_rule(self, language: str, category: str) -> Optional[Rule]:
160
+ """Obtiene una regla específica."""
161
+ if not self._loaded:
162
+ self.load_all()
163
+
164
+ key = f"{language}/{category}"
165
+ return self._rules.get(key)
166
+
167
+ def get_rules_for_language(self, language: RuleLanguage) -> List[Rule]:
168
+ """Obtiene todas las reglas para un lenguaje."""
169
+ if not self._loaded:
170
+ self.load_all()
171
+
172
+ return [r for r in self._rules.values() if r.language == language]
173
+
174
+ def get_rules_for_category(self, category: RuleCategory) -> List[Rule]:
175
+ """Obtiene todas las reglas para una categoría."""
176
+ if not self._loaded:
177
+ self.load_all()
178
+
179
+ return [r for r in self._rules.values() if r.category == category]
180
+
181
+ def get_common_rules(self) -> List[Rule]:
182
+ """Obtiene todas las reglas comunes."""
183
+ return self.get_rules_for_language(RuleLanguage.COMMON)
184
+
185
+ def get_all_rules(self) -> Dict[str, Rule]:
186
+ """Obtiene todas las reglas cargadas."""
187
+ if not self._loaded:
188
+ self.load_all()
189
+ return self._rules
190
+
191
+ def get_applicable_rules(self, language: RuleLanguage) -> Dict[str, List[Rule]]:
192
+ """Obtiene reglas aplicables: comunes + específicas del lenguaje."""
193
+ common = self.get_common_rules()
194
+ specific = self.get_rules_for_language(language)
195
+
196
+ return {
197
+ "common": common,
198
+ "language_specific": specific,
199
+ "all": common + specific,
200
+ }
201
+
202
+
203
+ # Instancia global
204
+ _loader: Optional[RulesLoader] = None
205
+
206
+
207
+ def get_rules_loader(rules_dir: Path = None) -> RulesLoader:
208
+ """Obtiene el cargador de reglas."""
209
+ global _loader
210
+ if _loader is None:
211
+ _loader = RulesLoader(rules_dir)
212
+ return _loader
213
+
214
+
215
+ def get_rule(language: str, category: str) -> Optional[Rule]:
216
+ """Obtiene una regla específica."""
217
+ return get_rules_loader().get_rule(language, category)
218
+
219
+
220
+ def get_rules_for_language(language: str) -> List[Rule]:
221
+ """Obtiene todas las reglas para un lenguaje."""
222
+ try:
223
+ lang = RuleLanguage(language.lower())
224
+ except ValueError:
225
+ lang = RuleLanguage.PYTHON # Default
226
+
227
+ return get_rules_loader().get_rules_for_language(lang)
228
+
229
+
230
+ def get_applicable_rules(language: str) -> Dict[str, List[Rule]]:
231
+ """Obtiene reglas aplicables para un lenguaje."""
232
+ try:
233
+ lang = RuleLanguage(language.lower())
234
+ except ValueError:
235
+ lang = RuleLanguage.PYTHON # Default
236
+
237
+ return get_rules_loader().get_applicable_rules(lang)
@@ -0,0 +1,5 @@
1
+ # hanus/search/__init__.py
2
+ """Code search tools for HanusCode."""
3
+ from .semantic import SemanticSearch, SearchResult
4
+
5
+ __all__ = ["SemanticSearch", "SearchResult"]