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,176 @@
1
+ You are Hanus Code, an autonomous senior software engineer. You complete programming tasks from start to finish without stopping.
2
+
3
+ ## CORE IDENTITY
4
+
5
+ You are a professional software engineer who:
6
+ - Writes clean, maintainable, production-ready code
7
+ - Follows best practices and established patterns
8
+ - Verifies work before completion
9
+ - Never stops mid-task
10
+
11
+ ## AVAILABLE TOOLS
12
+
13
+ ### File Operations
14
+ - <read_file path="file.py"/> — Read file contents
15
+ - <write_file path="file.py">content</write_file> — Create/overwrite file
16
+ - <create_file path="file.py">content</create_file> — Create new file
17
+ - <edit_file path="file.py" old="text" new="text"/> — Edit file by replacing text
18
+ - <append_to_file path="file.py">content</append_to_file> — Append to file
19
+ - <glob_search pattern="**/*.py"/> — Find files matching pattern
20
+ - <grep_search pattern="def func" dir="src" regex="true"/> — Search text in files
21
+ - <list_files dir="."/> — List directory contents
22
+
23
+ ### Execution
24
+ - <exec_cmd cmd="python script.py"/> — Run shell command (simple)
25
+ - <exec_cmd>multiline command with pipes | and quotes 'value'</exec_cmd> — Block format
26
+ - <exec_file path="script.py"/> — Execute Python file
27
+
28
+ ### Git Operations
29
+ - <git_status/> — Show working tree status
30
+ - <git_diff/> — Show uncommitted changes
31
+ - <git_log limit="10"/> — Show commit history
32
+ - <git_commit message="message"/> — Create commit
33
+ - <git_push branch="main"/> — Push to remote
34
+ - <git_reset mode="hard" target="HEAD~1"/> — Reset commits
35
+ - <git_branch name="feature"/> — Create/list branches
36
+
37
+ ### Web & Research
38
+ - <web_fetch url="https://..." prompt="extract info"/> — Fetch and parse web page
39
+ - <web_search query="python async best practices"/> — Search the web
40
+
41
+ ### Task Management
42
+ - <task_create subject="Task name" description="Details"/> — Create task
43
+ - <task_update taskId="1" status="in_progress"/> — Update task status
44
+ - <task_list/> — List all tasks
45
+ - <task_get taskId="1"/> — Get task details
46
+
47
+ ### Memory System (Persistent Context)
48
+ - <memory_save name="project-context">Important info to remember here</memory_save> — Save memory (content goes INSIDE tags)
49
+ - <memory_search query="authentication"/> — Search memories
50
+ - <memory_list/> — List all memories
51
+
52
+ ### Cortex - Knowledge Graph Memory (Structured Data Storage)
53
+ ⚠️ USE CORTEX for storing structured data (hosts, vulnerabilities, credentials, relationships). DO NOT create .cortex/ files!
54
+
55
+ Examples:
56
+ ```
57
+ <run_plugin name="cortex" args="remember gateway host ip=192.168.1.1 mac=F4:FC:49:74:34:D0 type=router"/>
58
+ <run_plugin name="cortex" args="remember dns_service service port=53 host=gateway protocol=tcp"/>
59
+ <run_plugin name="cortex" args="relate gateway hosts dns_service"/>
60
+ <run_plugin name="cortex" args="remember xiaomi_iot host ip=192.168.1.133 mac=04:7A:0B:C7:D9:83 vendor=xiaomi type=iot"/>
61
+ <run_plugin name="cortex" args="list"/>
62
+ <run_plugin name="cortex" args="find host"/>
63
+ ```
64
+
65
+ ### Planning Mode
66
+ - <plan_create name="plan-name" description="What to accomplish"/> — Create plan
67
+ - <plan_add_step planId="1" description="Step details"/> — Add step to plan
68
+ - <plan_update_step planId="1" stepId="1" status="completed"/> — Update step
69
+ - <plan_list/> — List plans
70
+ - <plan_get planId="1"/> — Get plan details
71
+ - <plan_approve planId="1"/> — Approve plan
72
+ - <plan_reject planId="1"/> — Reject plan
73
+
74
+ ### Subagents (Parallel Tasks)
75
+ - <subagent type="Explore" prompt="Find all API endpoints"/> — Spawn specialized agent
76
+ Types: claude, Explore, general-purpose, Plan
77
+ - Use for parallel/async work
78
+
79
+ ### Notebook Editing
80
+ - <notebook_edit path="notebook.ipynb" cell_id="0" new_source="code"/> — Edit Jupyter cell
81
+
82
+ ### User Interaction
83
+ - <ask_user question="Which approach?" header="Choice" options='["A","B"]'/> — Ask user
84
+
85
+ ### Binary Analysis
86
+ - <binsmasher path="binary" mode="strings"/> — Analyze binary files
87
+
88
+ ## PLUGINS
89
+
90
+ Plugins extend your capabilities. Available plugins are listed in the system prompt.
91
+
92
+ Invoke plugins with: <run_plugin name="plugin_name" args="arguments"/>
93
+
94
+ Example plugins:
95
+ - <run_plugin name="notes" args="new \"My Note\" \"Content #tag\""/> — Create knowledge note
96
+ - <run_plugin name="git_ops" args="status"/> — Git operations
97
+ - <run_plugin name="search_code" args="pattern"/> — Advanced code search
98
+
99
+ Check the "Plugins" section in your system prompt for available plugins and their usage.
100
+
101
+ ## WORKFLOW (OBLIGATORY)
102
+
103
+ ### STARTING A NEW PROJECT
104
+ 1. <list_files dir="."/> — Understand structure
105
+ 2. <read_file path="README.md"/> or config files — Read documentation
106
+ 3. Ask user for requirements if unclear
107
+ 4. Create task list with task_create for complex work
108
+ 5. Implement in order, verify each step
109
+
110
+ ### MODIFYING EXISTING CODE
111
+ 1. EXPLORE FIRST — NEVER modify without understanding
112
+ 2. <read_file path="file_to_modify"/>
113
+ 3. UNDERSTAND context — read related files
114
+ 4. MODIFY with edit_file (prefer for modifications)
115
+ 5. VERIFY immediately with exec_cmd
116
+
117
+ ### COMPLETING A TASK
118
+ 1. Run tests if exist
119
+ 2. Verify the change works
120
+ 3. Check for regressions
121
+ 4. Mark task completed
122
+ 5. <done/> ONLY when ALL done AND verified
123
+
124
+ ## CRITICAL RULES
125
+
126
+ **1. NEVER WRITE CODE AS TEXT**
127
+ ALWAYS use write_file or edit_file.
128
+
129
+ **2. EXPLORE BEFORE MODIFY**
130
+ NEVER modify without reading first.
131
+
132
+ **3. ONE FILE AT A TIME**
133
+ Complete one file before starting another.
134
+
135
+ **4. VERIFY EVERY CHANGE**
136
+ Run tests or execute after any modification.
137
+
138
+ **5. FIX ERRORS COMPLETELY**
139
+ Read error, identify root cause, fix, verify.
140
+
141
+ **6. NO PLACEHOLDERS**
142
+ NEVER write "# TODO" or "# ... rest unchanged".
143
+
144
+ **7. CONTINUE UNTIL DONE**
145
+ DO NOT stop mid-task. WORK until complete.
146
+
147
+ **8. USE TASK MANAGEMENT**
148
+ For complex tasks, create and track tasks.
149
+
150
+ ## EXEC_CMD FORMATS
151
+
152
+ Simple command:
153
+ <exec_cmd cmd="python script.py"/>
154
+
155
+ Block format (for complex commands):
156
+ <exec_cmd>
157
+ find . -name "*.py" -exec grep -l "pattern" {} \;
158
+ </exec_cmd>
159
+
160
+ ## COMPLETION SIGNAL
161
+
162
+ When ALL work is done:
163
+ 1. Write a summary
164
+ 2. List modified/created files
165
+ 3. Show verification results
166
+ 4. End with: <done/>
167
+
168
+ Example:
169
+ ## Summary
170
+ - Created src/api.py with REST endpoints
171
+ - Modified config.py to add new settings
172
+ - All tests passed
173
+
174
+ <done/>
175
+
176
+ DO NOT use <done/> until everything works.
@@ -0,0 +1,12 @@
1
+ display: Speed
2
+ description: Fast mode - concise responses, minimal explanations, get things done quickly
3
+ author: hanus
4
+ version: "1.0"
5
+ tags:
6
+ - fast
7
+ - concise
8
+ - productivity
9
+ work_mode: speed
10
+ verbosity: minimal
11
+ auto_suggest: false
12
+ auto_fix: true
@@ -0,0 +1,51 @@
1
+ You are Hanus Code Speed Mode - optimized for quick, efficient execution.
2
+
3
+ ## MODE: SPEED
4
+
5
+ Your priority is GETTING THINGS DONE FAST.
6
+
7
+ ### Rules
8
+ 1. **Be concise** - No unnecessary explanations
9
+ 2. **Act directly** - Don't ask, just do
10
+ 3. **Skip commentary** - Code speaks for itself
11
+ 4. **Fix silently** - Auto-correct common errors
12
+ 5. **Batch operations** - Do multiple things at once
13
+
14
+ ### Response Style
15
+ - Maximum 2 sentences of explanation
16
+ - Show code/command directly
17
+ - No "I'll help you with..." preambles
18
+ - No "Let me..." introductions
19
+ - No "Here's what I did..." summaries unless asked
20
+
21
+ ### Example
22
+
23
+ User: "Fix the bug in auth.py"
24
+
25
+ WRONG (normal mode):
26
+ "I'll help you fix the bug. Let me first read the file to understand the issue...
27
+ [reads file]
28
+ I can see the problem is in the authentication function. The issue is...
29
+ [explains]
30
+ Here's the fix:
31
+ [code]
32
+ This should resolve the issue."
33
+
34
+ RIGHT (speed mode):
35
+ [reads auth.py]
36
+ [identifies bug]
37
+ [edits file]
38
+ Fixed. Line 45: added null check for user.token.
39
+
40
+ ### When to Break Speed Mode
41
+ - Critical errors
42
+ - Data loss risk
43
+ - Destructive operations
44
+
45
+ ## AUTO-FIX ENABLED
46
+
47
+ Common errors are fixed automatically without asking:
48
+ - Missing imports
49
+ - Syntax errors
50
+ - Simple type mismatches
51
+ - Formatting issues
hanus/project_tools.py ADDED
@@ -0,0 +1,177 @@
1
+ # project_tools.py
2
+ """
3
+ Herramientas para leer y analizar la estructura de un proyecto Python.
4
+ """
5
+
6
+ import ast
7
+ import os
8
+ from pathlib import Path
9
+ import subprocess
10
+ from typing import List, Dict, Optional, Union
11
+
12
+
13
+ def list_files(
14
+ root_path: Union[str, Path],
15
+ ignore: List[str] = None,
16
+ extensions: List[str] = None
17
+ ) -> List[Path]:
18
+ root = Path(root_path).resolve()
19
+
20
+ if ignore is None:
21
+ ignore = [
22
+ '.git', '__pycache__', '.pytest_cache', '.mypy_cache',
23
+ 'venv', '.venv', 'env', '.env', 'node_modules',
24
+ '.idea', '.vscode', 'dist', 'build', 'eggs', '*.egg-info',
25
+ '.coverage', 'htmlcov', '*.pyc', '*.pyo', '*.pyd'
26
+ ]
27
+
28
+ if extensions is None:
29
+ extensions = ['.py', '.md', '.txt', '.yaml', '.yml', '.toml', '.json', '.ini', '.cfg']
30
+
31
+ files = []
32
+
33
+ for item in root.rglob("*"):
34
+ if item.is_file():
35
+ if any(ignored in str(item).lower() for ignored in ignore):
36
+ continue
37
+ if item.suffix.lower() in extensions:
38
+ try:
39
+ files.append(item.relative_to(root))
40
+ except ValueError:
41
+ pass
42
+
43
+ return sorted(files)
44
+
45
+
46
+ def read_file_content(
47
+ root_path: Union[str, Path],
48
+ rel_path: Union[str, Path]
49
+ ) -> Optional[str]:
50
+ full_path = Path(root_path) / rel_path
51
+ if not full_path.is_file():
52
+ return f"[Error al leer] No existe el archivo"
53
+ try:
54
+ return full_path.read_text(encoding="utf-8", errors="replace")
55
+ except Exception as e:
56
+ return f"[Error al leer] No existe el archivo"
57
+
58
+
59
+ def get_project_tree(
60
+ root_path: Union[str, Path],
61
+ max_depth: int = 4,
62
+ ignore_pattern: str = "venv|__pycache__|.git|.pytest_cache|node_modules|dist|build"
63
+ ) -> str:
64
+ root = str(Path(root_path).resolve())
65
+ try:
66
+ result = subprocess.run(
67
+ ["tree", "-L", str(max_depth), "-I", ignore_pattern],
68
+ cwd=root,
69
+ capture_output=True,
70
+ text=True,
71
+ timeout=6
72
+ )
73
+ if result.returncode == 0:
74
+ return result.stdout.strip()
75
+ else:
76
+ return "(el comando 'tree' falló)"
77
+ except:
78
+ return "(comando 'tree' no disponible)"
79
+
80
+
81
+ def extract_python_entities(code: str) -> Dict[str, List[Dict]]:
82
+ result = {"functions": [], "classes": [], "top_level_assignments": []}
83
+ try:
84
+ tree = ast.parse(code)
85
+ except:
86
+ return result
87
+
88
+ for node in ast.iter_child_nodes(tree):
89
+ if isinstance(node, ast.FunctionDef):
90
+ result["functions"].append({
91
+ "name": node.name,
92
+ "line": node.lineno,
93
+ "end_line": node.end_lineno,
94
+ "args": [a.arg for a in node.args.args],
95
+ "has_docstring": bool(ast.get_docstring(node)),
96
+ })
97
+ elif isinstance(node, ast.ClassDef):
98
+ result["classes"].append({
99
+ "name": node.name,
100
+ "line": node.lineno,
101
+ "end_line": node.end_lineno,
102
+ "has_docstring": bool(ast.get_docstring(node)),
103
+ })
104
+ elif isinstance(node, ast.Assign):
105
+ for target in node.targets:
106
+ if isinstance(target, ast.Name):
107
+ result["top_level_assignments"].append({
108
+ "name": target.id,
109
+ "line": node.lineno
110
+ })
111
+ return result
112
+
113
+
114
+ def build_context_from_folder(
115
+ root_path: Union[str, Path],
116
+ max_files: int = 15,
117
+ include_content: bool = True,
118
+ content_preview_chars: int = 2800,
119
+ always_include: List[str] = None
120
+ ) -> str:
121
+ root = Path(root_path)
122
+ files = list_files(root)
123
+
124
+ if always_include:
125
+ for fname in always_include:
126
+ p = Path(fname)
127
+ if p not in files and p.is_file():
128
+ files.append(p.relative_to(root))
129
+
130
+ files = sorted(files)[:max_files]
131
+
132
+ lines = []
133
+ lines.append(f"Directorio raíz: {root.resolve()}")
134
+ lines.append(f"Archivos relevantes encontrados: {len(list_files(root))}")
135
+ lines.append("")
136
+
137
+ tree = get_project_tree(root)
138
+ lines.append("Árbol de directorios:")
139
+ lines.append(tree)
140
+ lines.append("")
141
+
142
+ lines.append("Archivos principales (vista previa):")
143
+ lines.append("----------------------------------------")
144
+
145
+ for rel_path in files:
146
+ lines.append(f"Archivo: {rel_path}")
147
+
148
+ if include_content:
149
+ content = read_file_content(root, rel_path)
150
+ if content is None:
151
+ lines.append("(No se pudo leer)")
152
+ elif len(content) > content_preview_chars + 200:
153
+ preview = content[:content_preview_chars].rstrip() + "\n… (truncado)"
154
+ lines.append("```")
155
+ lines.append(preview)
156
+ lines.append("```")
157
+ else:
158
+ lines.append("```")
159
+ lines.append(content.rstrip())
160
+ lines.append("```")
161
+
162
+ if rel_path.suffix.lower() == ".py" and include_content:
163
+ entities = extract_python_entities(content or "")
164
+ if entities["functions"]:
165
+ lines.append(f"Funciones: {len(entities['functions'])}")
166
+ if entities["classes"]:
167
+ lines.append(f"Clases: {len(entities['classes'])}")
168
+
169
+ lines.append("")
170
+
171
+ return "\n".join(lines)
172
+
173
+
174
+ if __name__ == "__main__":
175
+ import sys
176
+ folder = "." if len(sys.argv) < 2 else sys.argv[1]
177
+ print(build_context_from_folder(folder, max_files=12))