higpertext-cli 0.8.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 (335) hide show
  1. config/adapters_config.json +450 -0
  2. config/antigravity_agent_template.json +31 -0
  3. config/app_config.json +174 -0
  4. config/context_engine.json +33 -0
  5. config/environments/model_defaults.json +5 -0
  6. config/governance/branching_strategy.json +36 -0
  7. config/governance/deployment_gates.json +30 -0
  8. config/governance/guidelines_contract.json +54 -0
  9. config/governance/quality_gates.json +39 -0
  10. config/governance/section_rules.json +22 -0
  11. config/governance/security_guardrails.json +52 -0
  12. config/hooks/README.md +35 -0
  13. config/hooks/custom/test_output_limiter.json +9 -0
  14. config/hooks/global/session_prompt.json +9 -0
  15. config/htx_config.json +24 -0
  16. config/profile_learner.json +18 -0
  17. config/profiles/base_agent.json +40 -0
  18. config/profiles/base_auditor.json +19 -0
  19. config/profiles/base_developer.json +19 -0
  20. config/profiles/base_operator.json +16 -0
  21. config/profiles/global.json +33 -0
  22. config/profiles/software_developer.json +23 -0
  23. config/router_content.json +137 -0
  24. config/semantic_graph.json +66 -0
  25. config/workflows/ado_release_flow.json +38 -0
  26. config/workflows/docs-update.json +33 -0
  27. config/workflows/governance-check.yaml +26 -0
  28. config/workflows/guidelines-sync.json +40 -0
  29. config/workflows/higpertext-build.json +73 -0
  30. config/workflows/higpertext-plan.json +38 -0
  31. config/workflows/higpertext-review.json +41 -0
  32. config/workflows/pr-quality-check.json +56 -0
  33. config/workflows/quality-remediation.json +57 -0
  34. higpertext/__init__.py +18 -0
  35. higpertext/adapters/__init__.py +27 -0
  36. higpertext/adapters/adapter_utils.py +604 -0
  37. higpertext/adapters/claude_adapter/__init__.py +0 -0
  38. higpertext/adapters/claude_adapter/claude_adapter.py +154 -0
  39. higpertext/adapters/copilot_adapter/__init__.py +0 -0
  40. higpertext/adapters/copilot_adapter/copilot_adapter.py +231 -0
  41. higpertext/adapters/gemini_adapter/__init__.py +0 -0
  42. higpertext/adapters/gemini_adapter/gemini_adapter.py +211 -0
  43. higpertext/adapters/llm_formatter.py +46 -0
  44. higpertext/adapters/open_code_adapter/__init__.py +0 -0
  45. higpertext/adapters/open_code_adapter/open_code_adapter.py +480 -0
  46. higpertext/capabilities/capabilities_runner.py +216 -0
  47. higpertext/capabilities/common/agent-builder.json +54 -0
  48. higpertext/capabilities/common/agent-sync.json +34 -0
  49. higpertext/capabilities/common/code-skeletonizer.json +35 -0
  50. higpertext/capabilities/common/commit-report.json +42 -0
  51. higpertext/capabilities/common/context-assembler.json +37 -0
  52. higpertext/capabilities/common/context-budget-report.json +15 -0
  53. higpertext/capabilities/common/dep-manager.json +43 -0
  54. higpertext/capabilities/common/docs-sync.json +14 -0
  55. higpertext/capabilities/common/doctor.json +18 -0
  56. higpertext/capabilities/common/efficiency-meter.json +31 -0
  57. higpertext/capabilities/common/env-catalog.json +13 -0
  58. higpertext/capabilities/common/env-clean.json +14 -0
  59. higpertext/capabilities/common/env-logs.json +16 -0
  60. higpertext/capabilities/common/env-runner.json +23 -0
  61. higpertext/capabilities/common/env-status.json +13 -0
  62. higpertext/capabilities/common/env-stop.json +14 -0
  63. higpertext/capabilities/common/env-template.json +14 -0
  64. higpertext/capabilities/common/error-context-locator.json +23 -0
  65. higpertext/capabilities/common/eval-agent.json +33 -0
  66. higpertext/capabilities/common/file-map.json +17 -0
  67. higpertext/capabilities/common/governance-exception.json +54 -0
  68. higpertext/capabilities/common/graph-query.json +59 -0
  69. higpertext/capabilities/common/graph-rebuild.json +31 -0
  70. higpertext/capabilities/common/graph-visualize.json +37 -0
  71. higpertext/capabilities/common/grep-search.json +176 -0
  72. higpertext/capabilities/common/higpertext-tester.json +25 -0
  73. higpertext/capabilities/common/hook-health.json +19 -0
  74. higpertext/capabilities/common/hook-sync-check.json +19 -0
  75. higpertext/capabilities/common/hooks-manager.json +55 -0
  76. higpertext/capabilities/common/knowledge-asker.json +27 -0
  77. higpertext/capabilities/common/list-rules.json +27 -0
  78. higpertext/capabilities/common/llm-invoke.json +59 -0
  79. higpertext/capabilities/common/load-rules.json +37 -0
  80. higpertext/capabilities/common/memory-manager.json +65 -0
  81. higpertext/capabilities/common/quality-scan.json +21 -0
  82. higpertext/capabilities/common/quality-updater.json +35 -0
  83. higpertext/capabilities/common/rag-index.json +17 -0
  84. higpertext/capabilities/common/report-viewer.json +24 -0
  85. higpertext/capabilities/common/roadmap-report.json +37 -0
  86. higpertext/capabilities/common/scripts/_env_cli.py +65 -0
  87. higpertext/capabilities/common/scripts/agent_builder.py +60 -0
  88. higpertext/capabilities/common/scripts/agent_sync.py +56 -0
  89. higpertext/capabilities/common/scripts/ask_higpertext.py +38 -0
  90. higpertext/capabilities/common/scripts/code_skeletonizer.py +225 -0
  91. higpertext/capabilities/common/scripts/commit_report.py +134 -0
  92. higpertext/capabilities/common/scripts/context_assembler.py +70 -0
  93. higpertext/capabilities/common/scripts/context_budget_report.py +53 -0
  94. higpertext/capabilities/common/scripts/dep_manager.py +81 -0
  95. higpertext/capabilities/common/scripts/docs_sync.py +981 -0
  96. higpertext/capabilities/common/scripts/doctor.py +144 -0
  97. higpertext/capabilities/common/scripts/efficiency_meter.py +83 -0
  98. higpertext/capabilities/common/scripts/env_catalog.py +47 -0
  99. higpertext/capabilities/common/scripts/env_clean.py +30 -0
  100. higpertext/capabilities/common/scripts/env_logs.py +32 -0
  101. higpertext/capabilities/common/scripts/env_runner.py +53 -0
  102. higpertext/capabilities/common/scripts/env_status.py +38 -0
  103. higpertext/capabilities/common/scripts/env_stop.py +30 -0
  104. higpertext/capabilities/common/scripts/env_template.py +73 -0
  105. higpertext/capabilities/common/scripts/error_context_locator.py +138 -0
  106. higpertext/capabilities/common/scripts/eval_agent.py +80 -0
  107. higpertext/capabilities/common/scripts/file_map.py +95 -0
  108. higpertext/capabilities/common/scripts/governance_exception.py +116 -0
  109. higpertext/capabilities/common/scripts/graph_query.py +104 -0
  110. higpertext/capabilities/common/scripts/graph_rebuild.py +107 -0
  111. higpertext/capabilities/common/scripts/graph_visualize.py +76 -0
  112. higpertext/capabilities/common/scripts/grep_search.py +648 -0
  113. higpertext/capabilities/common/scripts/higpertext_tester.py +102 -0
  114. higpertext/capabilities/common/scripts/hook_health.py +149 -0
  115. higpertext/capabilities/common/scripts/hook_sync_check.py +134 -0
  116. higpertext/capabilities/common/scripts/hooks_manager.py +171 -0
  117. higpertext/capabilities/common/scripts/list_rules.py +175 -0
  118. higpertext/capabilities/common/scripts/llm_invoke.py +135 -0
  119. higpertext/capabilities/common/scripts/load_rules.py +379 -0
  120. higpertext/capabilities/common/scripts/memory_manager.py +210 -0
  121. higpertext/capabilities/common/scripts/presentation_engine.py +63 -0
  122. higpertext/capabilities/common/scripts/quality_scan.py +132 -0
  123. higpertext/capabilities/common/scripts/rag_index.py +39 -0
  124. higpertext/capabilities/common/scripts/report_viewer.py +106 -0
  125. higpertext/capabilities/common/scripts/roadmap_report.py +73 -0
  126. higpertext/capabilities/common/scripts/search_router.py +111 -0
  127. higpertext/capabilities/common/scripts/semantic_diff.py +166 -0
  128. higpertext/capabilities/common/scripts/semantic_search.py +43 -0
  129. higpertext/capabilities/common/scripts/session_control.py +136 -0
  130. higpertext/capabilities/common/scripts/smart_read.py +232 -0
  131. higpertext/capabilities/common/scripts/subagent_executor.py +143 -0
  132. higpertext/capabilities/common/scripts/sync_agents.py +353 -0
  133. higpertext/capabilities/common/scripts/task_decomposer.py +78 -0
  134. higpertext/capabilities/common/scripts/telemetry_report.py +36 -0
  135. higpertext/capabilities/common/search-router.json +24 -0
  136. higpertext/capabilities/common/semantic-diff.json +40 -0
  137. higpertext/capabilities/common/semantic-search.json +19 -0
  138. higpertext/capabilities/common/session-clean.json +20 -0
  139. higpertext/capabilities/common/session-start.json +44 -0
  140. higpertext/capabilities/common/smart-read.json +28 -0
  141. higpertext/capabilities/common/subagent-executor.json +25 -0
  142. higpertext/capabilities/common/sync-agents.json +32 -0
  143. higpertext/capabilities/common/task-decomposer.json +37 -0
  144. higpertext/capabilities/common/telemetry-report.json +23 -0
  145. higpertext/capabilities/git/__init__.py +0 -0
  146. higpertext/capabilities/git/committer.json +61 -0
  147. higpertext/capabilities/git/diff.json +33 -0
  148. higpertext/capabilities/git/ls-files.json +44 -0
  149. higpertext/capabilities/git/rm.json +27 -0
  150. higpertext/capabilities/git/scripts/__init__.py +0 -0
  151. higpertext/capabilities/git/scripts/commit_changes.py +1077 -0
  152. higpertext/capabilities/git/scripts/git_diff.py +171 -0
  153. higpertext/capabilities/git/scripts/git_ls_files.py +376 -0
  154. higpertext/capabilities/git/scripts/git_rm.py +62 -0
  155. higpertext/capabilities/security/k8s-auditor.json +33 -0
  156. higpertext/capabilities/security/scripts/k8s_auditor.py +307 -0
  157. higpertext/capabilities/security/scripts/secret_scanner.py +235 -0
  158. higpertext/capabilities/security/secret-scanner.json +32 -0
  159. higpertext/hooks/__init__.py +28 -0
  160. higpertext/hooks/_compat.py +27 -0
  161. higpertext/hooks/hook_tasks/__init__.py +1 -0
  162. higpertext/hooks/hook_tasks/_rules/__init__.py +0 -0
  163. higpertext/hooks/hook_tasks/_rules/bash_rules.py +635 -0
  164. higpertext/hooks/hook_tasks/_rules/context_engine_rule.py +79 -0
  165. higpertext/hooks/hook_tasks/_rules/context_rules.py +199 -0
  166. higpertext/hooks/hook_tasks/_rules/governance_adapter.py +72 -0
  167. higpertext/hooks/hook_tasks/_rules/profile_rules.json +25 -0
  168. higpertext/hooks/hook_tasks/_rules/quality_rules.py +86 -0
  169. higpertext/hooks/hook_tasks/_rules/security_rules.py +214 -0
  170. higpertext/hooks/hook_tasks/_rules/session_rules.py +316 -0
  171. higpertext/hooks/hook_tasks/_rules/telemetry_rules.py +121 -0
  172. higpertext/hooks/hook_tasks/audit_logger_hook.py +28 -0
  173. higpertext/hooks/hook_tasks/hook_bash_guard.py +101 -0
  174. higpertext/hooks/hook_tasks/hook_code_quality.py +48 -0
  175. higpertext/hooks/hook_tasks/hook_context_hint.py +46 -0
  176. higpertext/hooks/hook_tasks/hook_context_manager.py +44 -0
  177. higpertext/hooks/hook_tasks/hook_io.py +122 -0
  178. higpertext/hooks/hook_tasks/hook_loop_guard.py +182 -0
  179. higpertext/hooks/hook_tasks/hook_post_observer.py +54 -0
  180. higpertext/hooks/hook_tasks/hook_read_guard.py +85 -0
  181. higpertext/hooks/hook_tasks/hook_security_guard.py +81 -0
  182. higpertext/hooks/hook_tasks/hook_session_prompt.py +83 -0
  183. higpertext/hooks/hook_tasks/hook_session_stop.py +115 -0
  184. higpertext/hooks/hook_tasks/hook_utils.py +144 -0
  185. higpertext/hooks/hook_tasks/session_guard_hook.py +23 -0
  186. higpertext/hooks/hook_tasks/telemetry_utils.py +176 -0
  187. higpertext/hooks/hook_tasks/test_echo_hook.py +33 -0
  188. higpertext/hooks/hook_tasks/webhook_hook.py +54 -0
  189. higpertext/hooks/hook_tasks/workflow_runner_hook.py +49 -0
  190. higpertext/hooks/hooks_catalog.json +116 -0
  191. higpertext/kernel/__init__.py +63 -0
  192. higpertext/kernel/_compat.py +138 -0
  193. higpertext/kernel/app_config.py +117 -0
  194. higpertext/kernel/application/__init__.py +13 -0
  195. higpertext/kernel/application/agent_registry.py +102 -0
  196. higpertext/kernel/application/capability_manager.py +61 -0
  197. higpertext/kernel/application/commit_reporter.py +247 -0
  198. higpertext/kernel/application/context_builder.py +166 -0
  199. higpertext/kernel/application/context_engine.py +409 -0
  200. higpertext/kernel/application/engine.py +41 -0
  201. higpertext/kernel/application/env_runtime.py +174 -0
  202. higpertext/kernel/application/environment_manager.py +154 -0
  203. higpertext/kernel/application/governance.py +192 -0
  204. higpertext/kernel/application/hook_registry.py +102 -0
  205. higpertext/kernel/application/hook_renderer.py +720 -0
  206. higpertext/kernel/application/ports.py +49 -0
  207. higpertext/kernel/application/profile_learner.py +358 -0
  208. higpertext/kernel/application/profile_service.py +205 -0
  209. higpertext/kernel/application/profile_services.py +6 -0
  210. higpertext/kernel/application/profile_use_cases.py +93 -0
  211. higpertext/kernel/application/rag_service.py +75 -0
  212. higpertext/kernel/application/roadmap_reporter.py +178 -0
  213. higpertext/kernel/application/semantic_engine.py +258 -0
  214. higpertext/kernel/application/session_services.py +33 -0
  215. higpertext/kernel/application/skill_hook_compiler.py +85 -0
  216. higpertext/kernel/application/telemetry.py +326 -0
  217. higpertext/kernel/application/workflow_manager.py +176 -0
  218. higpertext/kernel/config_paths.py +66 -0
  219. higpertext/kernel/domain/__init__.py +12 -0
  220. higpertext/kernel/domain/agent_registry.py +23 -0
  221. higpertext/kernel/domain/commit_reporter.py +155 -0
  222. higpertext/kernel/domain/compilers.py +7 -0
  223. higpertext/kernel/domain/context_engine.py +319 -0
  224. higpertext/kernel/domain/entities.py +51 -0
  225. higpertext/kernel/domain/env_runtime.py +62 -0
  226. higpertext/kernel/domain/governance.py +198 -0
  227. higpertext/kernel/domain/hook_models.py +29 -0
  228. higpertext/kernel/domain/profile_learner.py +186 -0
  229. higpertext/kernel/domain/rag.py +70 -0
  230. higpertext/kernel/domain/repositories.py +8 -0
  231. higpertext/kernel/domain/roadmap_reporter.py +80 -0
  232. higpertext/kernel/domain/semantic_engine.py +107 -0
  233. higpertext/kernel/engine.py +42 -0
  234. higpertext/kernel/htx_resolver.py +69 -0
  235. higpertext/kernel/infrastructure/__init__.py +13 -0
  236. higpertext/kernel/infrastructure/agent_registry.py +40 -0
  237. higpertext/kernel/infrastructure/cache/capability_cache.py +319 -0
  238. higpertext/kernel/infrastructure/capability_helper.py +40 -0
  239. higpertext/kernel/infrastructure/cli/__init__.py +1 -0
  240. higpertext/kernel/infrastructure/cli/agent_commands.py +62 -0
  241. higpertext/kernel/infrastructure/cli/arguments.py +39 -0
  242. higpertext/kernel/infrastructure/cli/capability_command_builder.py +86 -0
  243. higpertext/kernel/infrastructure/cli/capability_task_service.py +234 -0
  244. higpertext/kernel/infrastructure/cli/cli_search.py +234 -0
  245. higpertext/kernel/infrastructure/cli/parameter_contracts.py +83 -0
  246. higpertext/kernel/infrastructure/cli/parser_builder.py +122 -0
  247. higpertext/kernel/infrastructure/cli/profile_commands.py +89 -0
  248. higpertext/kernel/infrastructure/cli/roadmap_commands.py +117 -0
  249. higpertext/kernel/infrastructure/cli/router.py +1110 -0
  250. higpertext/kernel/infrastructure/cli/session_commands.py +36 -0
  251. higpertext/kernel/infrastructure/cli/task_commands.py +23 -0
  252. higpertext/kernel/infrastructure/cli/task_result_reporter.py +56 -0
  253. higpertext/kernel/infrastructure/cli/workflow_commands.py +25 -0
  254. higpertext/kernel/infrastructure/compilers/__init__.py +3 -0
  255. higpertext/kernel/infrastructure/compilers/factory.py +27 -0
  256. higpertext/kernel/infrastructure/compilers/graph_compiler.py +20 -0
  257. higpertext/kernel/infrastructure/compilers/guide_compiler.py +50 -0
  258. higpertext/kernel/infrastructure/compilers/hook_compiler.py +69 -0
  259. higpertext/kernel/infrastructure/compilers/playbook_compiler.py +154 -0
  260. higpertext/kernel/infrastructure/context_engine.py +303 -0
  261. higpertext/kernel/infrastructure/database/local_vector_store.py +99 -0
  262. higpertext/kernel/infrastructure/deployment/__init__.py +1 -0
  263. higpertext/kernel/infrastructure/deployment/resource_deployer.py +283 -0
  264. higpertext/kernel/infrastructure/diagnostics/__init__.py +1 -0
  265. higpertext/kernel/infrastructure/diagnostics/health.py +191 -0
  266. higpertext/kernel/infrastructure/env_runtime.py +227 -0
  267. higpertext/kernel/infrastructure/execution/__init__.py +1 -0
  268. higpertext/kernel/infrastructure/execution/parallel.py +188 -0
  269. higpertext/kernel/infrastructure/execution/resilience.py +155 -0
  270. higpertext/kernel/infrastructure/file_repositories.py +213 -0
  271. higpertext/kernel/infrastructure/governance.py +198 -0
  272. higpertext/kernel/infrastructure/hook_config_loader.py +53 -0
  273. higpertext/kernel/infrastructure/hook_webhook_dispatcher.py +61 -0
  274. higpertext/kernel/infrastructure/hook_workflow_bridge.py +60 -0
  275. higpertext/kernel/infrastructure/llm/__init__.py +6 -0
  276. higpertext/kernel/infrastructure/llm/provider.py +46 -0
  277. higpertext/kernel/infrastructure/llm/providers/__init__.py +0 -0
  278. higpertext/kernel/infrastructure/llm/providers/anthropic_provider.py +94 -0
  279. higpertext/kernel/infrastructure/llm/providers/gemini_embeddings.py +74 -0
  280. higpertext/kernel/infrastructure/llm/providers/gemini_provider.py +101 -0
  281. higpertext/kernel/infrastructure/llm/providers/ollama_provider.py +110 -0
  282. higpertext/kernel/infrastructure/llm/providers/openai_provider.py +98 -0
  283. higpertext/kernel/infrastructure/llm/registry.py +81 -0
  284. higpertext/kernel/infrastructure/logger.py +303 -0
  285. higpertext/kernel/infrastructure/output_store.py +70 -0
  286. higpertext/kernel/infrastructure/parser/__init__.py +1 -0
  287. higpertext/kernel/infrastructure/parser/code_chunker.py +144 -0
  288. higpertext/kernel/infrastructure/parser/language/__init__.py +14 -0
  289. higpertext/kernel/infrastructure/parser/language/base.py +41 -0
  290. higpertext/kernel/infrastructure/parser/language/powershell_parser.py +35 -0
  291. higpertext/kernel/infrastructure/parser/language/python_parser.py +98 -0
  292. higpertext/kernel/infrastructure/parser/language/typescript_parser.py +91 -0
  293. higpertext/kernel/infrastructure/parser/semantic_graph.py +409 -0
  294. higpertext/kernel/infrastructure/presentation/__init__.py +1 -0
  295. higpertext/kernel/infrastructure/presentation/html_renderer.py +137 -0
  296. higpertext/kernel/infrastructure/presentation/markdown_renderer.py +84 -0
  297. higpertext/kernel/infrastructure/presentation/markdown_report_renderer.py +97 -0
  298. higpertext/kernel/infrastructure/profile_store.py +28 -0
  299. higpertext/kernel/infrastructure/semantic_engine.py +289 -0
  300. higpertext/kernel/infrastructure/telemetry_reporter.py +132 -0
  301. higpertext/kernel/infrastructure/validation/__init__.py +1 -0
  302. higpertext/kernel/infrastructure/validation/contract_validator.py +163 -0
  303. higpertext/kernel/pkg_resources.py +38 -0
  304. higpertext/kernel/session_manager.py +319 -0
  305. higpertext/templates/env/generic-shell.yaml +21 -0
  306. higpertext/templates/env/node-vitest.yaml +27 -0
  307. higpertext/templates/env/python-pytest.yaml +29 -0
  308. higpertext/templates/html/commit_body.html +20 -0
  309. higpertext/templates/html/commit_diff.html +4 -0
  310. higpertext/templates/html/commit_index.html +29 -0
  311. higpertext/templates/html/commit_layer.html +11 -0
  312. higpertext/templates/html/commit_shell.html +28 -0
  313. higpertext/templates/html/graph_visualize.html +86 -0
  314. higpertext/templates/html/roadmap_body.html +12 -0
  315. higpertext/templates/html/roadmap_phase.html +5 -0
  316. higpertext/templates/html/roadmap_shell.html +29 -0
  317. higpertext/templates/markdown/commit_report.md +18 -0
  318. higpertext/templates/markdown/efficiency_report.md +12 -0
  319. higpertext/templates/markdown/roadmap_report.md +25 -0
  320. higpertext/templates/skills/best-practices.md +7 -0
  321. higpertext/templates/skills/clean-code.md +8 -0
  322. higpertext/templates/skills/ddd-standards.md +7 -0
  323. higpertext/templates/skills/tdd-practices.md +7 -0
  324. higpertext/templates/subagents/architect.md +7 -0
  325. higpertext/templates/subagents/test-engineer.md +7 -0
  326. higpertext/templates/workflows/build.json +23 -0
  327. higpertext/templates/workflows/compact.json +21 -0
  328. higpertext/templates/workflows/plan.json +59 -0
  329. higpertext/templates/workflows/review.json +26 -0
  330. higpertext/templates/workflows/spec.json +27 -0
  331. higpertext_cli-0.8.0.dist-info/METADATA +35 -0
  332. higpertext_cli-0.8.0.dist-info/RECORD +335 -0
  333. higpertext_cli-0.8.0.dist-info/WHEEL +5 -0
  334. higpertext_cli-0.8.0.dist-info/entry_points.txt +2 -0
  335. higpertext_cli-0.8.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,80 @@
1
+ """Capability common.eval-agent — puente entre el CLI de higpertext y el suite pytest de evaluación.
2
+
3
+ Uso:
4
+ htx task eval-agent --mode static
5
+ htx task eval-agent --mode hooks
6
+ htx task eval-agent --mode behavioral --provider gemini --profile sre
7
+ htx task eval-agent --mode all --provider anthropic
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import argparse
13
+ import os
14
+ # Ejecuta pytest con comando construido internamente.
15
+ import subprocess # nosec B404
16
+ import sys
17
+ from pathlib import Path
18
+
19
+ from higpertext.kernel.infrastructure.logger import get_logger
20
+ _log = get_logger()
21
+
22
+ ROOT_DIR = Path(__file__).resolve().parents[5]
23
+ EVAL_DIR = ROOT_DIR / "tests" / "eval"
24
+
25
+ _MARKER_MAP = {
26
+ "static": "static",
27
+ "behavioral": "behavioral",
28
+ "hooks": "hooks",
29
+ "safety": "safety",
30
+ "all": None,
31
+ }
32
+
33
+
34
+ def _parse_args() -> argparse.Namespace:
35
+ p = argparse.ArgumentParser(
36
+ description="higpertext Eval Agent — framework de evaluación de modelos"
37
+ )
38
+ p.add_argument("--profile", default="all", help="Perfil a evaluar (default: all)")
39
+ p.add_argument("--mode", default="static", choices=list(_MARKER_MAP), help="Modo de evaluación")
40
+ p.add_argument(
41
+ "--provider",
42
+ default="",
43
+ help="Provider LLM para behavioral/safety: gemini | anthropic",
44
+ )
45
+ return p.parse_args()
46
+
47
+
48
+ def _build_cmd(mode: str, profile: str) -> list[str]:
49
+ cmd = [sys.executable, "-m", "pytest", str(EVAL_DIR), "-v", "--tb=short"]
50
+ marker = _MARKER_MAP[mode]
51
+ if marker:
52
+ cmd += ["-m", marker]
53
+ if profile != "all":
54
+ cmd += ["--profile", profile]
55
+ return cmd
56
+
57
+
58
+ def main() -> None:
59
+ args = _parse_args()
60
+ env = os.environ.copy()
61
+
62
+ if args.provider:
63
+ env["HIGPERTEXT_LLM_PROVIDER"] = args.provider
64
+
65
+ if args.mode in ("behavioral", "safety", "all") and not env.get("RUN_BEHAVIORAL_TESTS"):
66
+ _log.info(
67
+ "[eval-agent] AVISO: RUN_BEHAVIORAL_TESTS no configurada.\n"
68
+ "Los tests behavioral y safety serán skipped.\n"
69
+ "Para activarlos: $env:RUN_BEHAVIORAL_TESTS=1"
70
+ )
71
+
72
+ cmd = _build_cmd(args.mode, args.profile)
73
+ _log.info(f"[eval-agent] Ejecutando: {' '.join(cmd)}\n")
74
+
75
+ result = subprocess.run(cmd, env=env, cwd=str(ROOT_DIR))
76
+ sys.exit(result.returncode)
77
+
78
+
79
+ if __name__ == "__main__":
80
+ main()
@@ -0,0 +1,95 @@
1
+ """common.file-map — mapa compacto de archivos para exploración sin blobs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import subprocess # nosec B404
8
+ from collections import Counter, defaultdict
9
+ from pathlib import Path
10
+
11
+ from higpertext.kernel.infrastructure.logger import get_logger
12
+ _log = get_logger()
13
+
14
+ _HEAVY_ASSET_PATTERNS = ("*.min.js", "*.bundle.min.js", "*.min.css", "*.map")
15
+
16
+
17
+ def _git_files() -> list[str]:
18
+ result = subprocess.run(["git", "ls-files"], capture_output=True, text=True) # nosec B603 B607
19
+ return result.stdout.splitlines() if result.returncode == 0 else []
20
+
21
+
22
+ def _is_heavy_asset(path: str) -> bool:
23
+ p = Path(path)
24
+ if "assets" not in p.parts:
25
+ return False
26
+ return any(p.match(pattern) for pattern in _HEAVY_ASSET_PATTERNS)
27
+
28
+
29
+ def build_map(
30
+ path: str, max_depth: int, large_threshold_kb: int, include_assets: bool = False
31
+ ) -> dict:
32
+ prefix = path.strip().strip("/")
33
+ files = [f for f in _git_files() if not prefix or f == prefix or f.startswith(f"{prefix}/")]
34
+ skipped_assets = [f for f in files if _is_heavy_asset(f)]
35
+ if not include_assets:
36
+ files = [f for f in files if not _is_heavy_asset(f)]
37
+ dirs: dict[str, int] = defaultdict(int)
38
+ extensions: Counter[str] = Counter()
39
+ large = []
40
+ for file in files:
41
+ rel = file[len(prefix) + 1 :] if prefix and file.startswith(f"{prefix}/") else file
42
+ top = "/".join(Path(rel).parts[:max_depth]) or "."
43
+ dirs[top] += 1
44
+ extensions[Path(file).suffix or "[sin extensión]"] += 1
45
+ p = Path(file)
46
+ if p.exists() and p.stat().st_size / 1024 >= large_threshold_kb:
47
+ large.append({"path": file, "kb": round(p.stat().st_size / 1024, 1)})
48
+ return {
49
+ "path": path or ".",
50
+ "total": len(files),
51
+ "directories": dict(sorted(dirs.items())),
52
+ "extensions": dict(extensions.most_common()),
53
+ "large_files": large[:20],
54
+ "skipped_heavy_assets": len(skipped_assets) if not include_assets else 0,
55
+ }
56
+
57
+
58
+ def main() -> None:
59
+ parser = argparse.ArgumentParser(description="Mapa compacto de archivos")
60
+ parser.add_argument("--path", default="")
61
+ parser.add_argument("--preset", default="all") # reservado para compatibilidad con plan
62
+ parser.add_argument("--max_depth", type=int, default=2)
63
+ parser.add_argument("--show_sizes", default="false")
64
+ parser.add_argument("--large_threshold_kb", type=int, default=100)
65
+ parser.add_argument("--include_assets", default="false")
66
+ parser.add_argument("--json", default="false")
67
+ args = parser.parse_args()
68
+ include_assets = args.include_assets.lower() in {"true", "1", "yes"}
69
+ data = build_map(args.path, args.max_depth, args.large_threshold_kb, include_assets)
70
+ if args.json.lower() in {"true", "1", "yes"}:
71
+ print(json.dumps(data, ensure_ascii=False, indent=2))
72
+ return
73
+ _log.info("╔─ HIGPERTEXT · File Map ────────────────────────────────────")
74
+ _log.info(f"│ Path : {data['path']}")
75
+ _log.info(f"│ Total : {data['total']} archivo(s)")
76
+ _log.info("╠─ Directorios ──────────────────────────────────────────────")
77
+ for directory, count in list(data["directories"].items())[:50]:
78
+ _log.info(f"│ {directory}: {count}")
79
+ _log.info("╠─ Extensiones ──────────────────────────────────────────────")
80
+ for ext, count in data["extensions"].items():
81
+ _log.info(f"│ {ext}: {count}")
82
+ if data["large_files"]:
83
+ _log.info("╠─ Grandes ─────────────────────────────────────────────────")
84
+ for item in data["large_files"]:
85
+ _log.info(
86
+ f"│ {item['path']} ({item['kb']} KB) → htx task common.smart-read --path {item['path']} --mode auto" # noqa: E501
87
+ )
88
+ if data["skipped_heavy_assets"]:
89
+ _log.info(f"│ Assets pesados omitidos: {
90
+ data['skipped_heavy_assets']} (usa --include_assets true)")
91
+ _log.info("╚────────────────────────────────────────────────────────────")
92
+
93
+
94
+ if __name__ == "__main__":
95
+ main()
@@ -0,0 +1,116 @@
1
+ """common.governance-exception — registra y lista excepciones de gobernanza."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import sys
8
+ from datetime import date
9
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
10
+ from pathlib import Path
11
+
12
+ _HERE = Path(__file__).resolve()
13
+ _PROJECT_ROOT = next(
14
+ (p for p in _HERE.parents if (p / "src/config/htx_config.json").exists()),
15
+ _HERE.parents[4],
16
+ )
17
+ sys.path.insert(0, str(_PROJECT_ROOT / "src"))
18
+
19
+ from higpertext.kernel.application.governance import ExceptionRegistry # noqa: E402
20
+ from higpertext.kernel.domain.governance import GovernanceException, Severity # noqa: E402
21
+ from higpertext.kernel.infrastructure.governance import ContractLoader # noqa: E402
22
+
23
+ from higpertext.kernel.infrastructure.logger import get_logger
24
+ _log = get_logger()
25
+
26
+
27
+ def _get_active_profile() -> str:
28
+ env_file = _PROJECT_ROOT / WORKSPACE_DIR_NAME / "config" / "environment.json"
29
+ if env_file.exists():
30
+ try:
31
+ return json.loads(env_file.read_text(encoding="utf-8")).get("active_profile", "global")
32
+ except (OSError, json.JSONDecodeError): # nosec B110
33
+ pass
34
+ return "global"
35
+
36
+
37
+ def _rule_is_critical(rule_id: str) -> bool:
38
+ loader = ContractLoader(_PROJECT_ROOT)
39
+ for rule in loader.load():
40
+ if rule.id == rule_id and rule.severity == Severity.CRITICAL:
41
+ return True
42
+ return False
43
+
44
+
45
+ def cmd_register(args: argparse.Namespace, registry: ExceptionRegistry) -> None:
46
+ if not args.rule_id:
47
+ _log.error("[ERROR] --rule_id es requerido para register.")
48
+ sys.exit(1)
49
+ if not args.reason:
50
+ _log.error("[ERROR] --reason es requerido para register.")
51
+ sys.exit(1)
52
+ if not args.approver:
53
+ _log.error("[ERROR] --approver es requerido para register.")
54
+ sys.exit(1)
55
+
56
+ if _rule_is_critical(args.rule_id):
57
+ _log.info(f"[BLOCK] La regla '{args.rule_id}' es CRITICAL — no se puede exceptuar.")
58
+ sys.exit(1)
59
+
60
+ profile = args.profile or _get_active_profile()
61
+ expires = date.fromisoformat(args.expires) if args.expires else None
62
+
63
+ exc = GovernanceException(
64
+ rule_id=args.rule_id,
65
+ reason=args.reason,
66
+ approver=args.approver,
67
+ profile=profile,
68
+ expires=expires,
69
+ )
70
+ registry.register(exc)
71
+
72
+ _log.ok(f"[SUCCESS] Excepción registrada para regla '{args.rule_id}' en perfil '{profile}'.")
73
+ if expires:
74
+ _log.info(f" Expira: {expires.isoformat()}")
75
+ _log.info(f" Aprobador: {args.approver}")
76
+ _log.info(f" Motivo: {args.reason}")
77
+
78
+
79
+ def cmd_list(args: argparse.Namespace, registry: ExceptionRegistry) -> None:
80
+ profile = args.profile or _get_active_profile()
81
+ exceptions = registry.list_active(profile)
82
+
83
+ if not exceptions:
84
+ _log.info(f"[*] No hay excepciones activas para el perfil '{profile}'.")
85
+ return
86
+
87
+ _log.info(f"\n Excepciones activas — perfil: {profile}\n")
88
+ _log.info(f" {'Regla':<35} {'Aprobador':<15} {'Expira':<12} Motivo")
89
+ _log.info(f" {'-' * 35} {'-' * 15} {'-' * 12} {'-' * 30}")
90
+ for exc in exceptions:
91
+ exp = exc.expires.isoformat() if exc.expires else "indefinido"
92
+ _log.info(f" {exc.rule_id:<35} {exc.approver:<15} {exp:<12} {exc.reason[:40]}")
93
+ _log.info("")
94
+ _log.ok("[SUCCESS] Listado completado.")
95
+
96
+
97
+ def main() -> None:
98
+ parser = argparse.ArgumentParser(description="higpertext Governance Exception Manager")
99
+ parser.add_argument("--action", required=True, choices=["register", "list"])
100
+ parser.add_argument("--rule_id", default="")
101
+ parser.add_argument("--reason", default="")
102
+ parser.add_argument("--approver", default="")
103
+ parser.add_argument("--expires", default="")
104
+ parser.add_argument("--profile", default="")
105
+ args = parser.parse_args()
106
+
107
+ registry = ExceptionRegistry(_PROJECT_ROOT)
108
+
109
+ if args.action == "register":
110
+ cmd_register(args, registry)
111
+ else:
112
+ cmd_list(args, registry)
113
+
114
+
115
+ if __name__ == "__main__":
116
+ main()
@@ -0,0 +1,104 @@
1
+ """Capability common.graph-query — consulta el grafo semántico por keyword."""
2
+
3
+ from __future__ import annotations
4
+ import argparse
5
+ import json
6
+ import sys
7
+ from pathlib import Path
8
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
9
+ from higpertext.kernel.infrastructure.logger import get_logger
10
+ _log = get_logger()
11
+
12
+ def _resolve_core() -> Path:
13
+ here = Path(__file__).resolve()
14
+ for parent in here.parents:
15
+ core = parent / "src" / "core"
16
+ if core.exists():
17
+ return core
18
+ raise RuntimeError("No se encontró src/core")
19
+
20
+
21
+ def main() -> None:
22
+ parser = argparse.ArgumentParser(description="Consulta el grafo semántico.")
23
+ parser.add_argument("--symbol", required=True, help="Keyword o nombre de símbolo.")
24
+ parser.add_argument("--depth", type=int, default=2)
25
+ parser.add_argument("--budget", type=int, default=8000)
26
+ parser.add_argument(
27
+ "--type", default="", help="Filtra tipo: class,function,method,variable,module"
28
+ )
29
+ parser.add_argument("--limit", type=int, default=50, help="Máximo de símbolos a mostrar")
30
+ parser.add_argument(
31
+ "--files_only",
32
+ default="false",
33
+ help="Muestra solo archivos únicos (true/false)",
34
+ )
35
+ parser.add_argument("--json", default="false", help="Emite JSON estructurado (true/false)")
36
+ args = parser.parse_args()
37
+
38
+ core = _resolve_core()
39
+ if str(core) not in sys.path:
40
+ sys.path.insert(0, str(core))
41
+ sys.path.insert(0, str(core.parent.parent))
42
+
43
+ root = Path(".").resolve()
44
+ graph_path = root / WORKSPACE_DIR_NAME / "state" / "semantic_graph.json"
45
+ if not graph_path.exists():
46
+ _log.error("[ERROR] semantic_graph.json no encontrado. Ejecuta: htx task common.graph-rebuild")
47
+ sys.exit(1)
48
+
49
+ from higpertext.semantic_engine.infrastructure.graph_store import GraphStore
50
+ from higpertext.semantic_engine.application.context_ranker import ContextRanker
51
+
52
+ graph = GraphStore(root=root).load()
53
+ ranker = ContextRanker(graph)
54
+ results = ranker.rank(keywords=[args.symbol], budget=args.budget, depth=args.depth)
55
+ if args.type:
56
+ results = [s for s in results if s.type.value == args.type]
57
+ results = results[: max(1, args.limit)]
58
+
59
+ if not results:
60
+ _log.info(f"[NOT FOUND] No se encontraron símbolos relacionados con '{args.symbol}'.")
61
+ sys.exit(0)
62
+
63
+ if args.json.lower() in {"true", "1", "yes"}:
64
+ print(
65
+ json.dumps(
66
+ {
67
+ "keyword": args.symbol,
68
+ "depth": args.depth,
69
+ "count": len(results),
70
+ "symbols": [
71
+ {
72
+ "type": s.type.value,
73
+ "name": s.name,
74
+ "file": s.file,
75
+ "line": s.line,
76
+ }
77
+ for s in results
78
+ ],
79
+ },
80
+ ensure_ascii=False,
81
+ indent=2,
82
+ )
83
+ )
84
+ return
85
+
86
+ _log.info("╔─ HIGPERTEXT · Graph Query ──────────────────────────────────")
87
+ _log.info(f"│ Keyword : {args.symbol}")
88
+ _log.info(f"│ Depth : {args.depth}")
89
+ _log.info(f"│ Símbolos : {len(results)}")
90
+ _log.info("╠───────────────────────────────────────────────────────")
91
+ if args.files_only.lower() in {"true", "1", "yes"}:
92
+ for file in sorted({s.file for s in results}):
93
+ _log.info(f"│ {file}")
94
+ _log.info("╚───────────────────────────────────────────────────────")
95
+ _log.ok(f"\n[SUCCESS] {len(set(s.file for s in results))} archivo(s) encontrados.")
96
+ return
97
+ for s in results:
98
+ _log.info(f"│ [{s.type.value:8}] {s.name:30} {s.file}:{s.line}")
99
+ _log.info("╚───────────────────────────────────────────────────────")
100
+ _log.ok(f"\n[SUCCESS] {len(results)} símbolos encontrados.")
101
+
102
+
103
+ if __name__ == "__main__":
104
+ main()
@@ -0,0 +1,107 @@
1
+ """Capability common.graph-rebuild — regenera el grafo semántico del proyecto."""
2
+
3
+ from __future__ import annotations
4
+ import argparse
5
+ import sys
6
+ from pathlib import Path
7
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
8
+ from higpertext.kernel.infrastructure.logger import get_logger
9
+ _log = get_logger()
10
+
11
+
12
+ def _resolve_core() -> Path:
13
+ here = Path(__file__).resolve()
14
+ for parent in here.parents:
15
+ core = parent / "src" / "core"
16
+ if core.exists():
17
+ return core
18
+ raise RuntimeError("No se encontró src/core")
19
+
20
+
21
+ def _parse_args() -> argparse.Namespace:
22
+ parser = argparse.ArgumentParser(description="Regenera el grafo semántico.")
23
+ parser.add_argument("--root", default=".", help="Directorio raíz del proyecto.")
24
+ parser.add_argument("--god_threshold", type=int, default=5)
25
+ parser.add_argument(
26
+ "--incremental",
27
+ type=lambda x: x.lower() != "false",
28
+ default=True,
29
+ help="Usa caché incremental (default: true). Pasa false para rebuild completo.",
30
+ )
31
+ return parser.parse_args()
32
+
33
+
34
+ def _setup_path() -> None:
35
+ core = _resolve_core()
36
+ if str(core) not in sys.path:
37
+ sys.path.insert(0, str(core))
38
+ sys.path.insert(0, str(core.parent.parent))
39
+
40
+
41
+ def _print_summary(root, graph, god_nodes, clusters, path, stats, threshold) -> None:
42
+ mode = "incremental" if stats.get("skipped", 0) > 0 else "full"
43
+ _log.info("╔─ HIGPERTEXT · Graph Rebuild ────────────────────────────────")
44
+ _log.info(f"│ Modo : {mode} (parsed={stats['parsed']}, skipped={stats['skipped']})")
45
+ _log.info(f"│ Símbolos indexados : {graph.symbol_count}")
46
+ _log.info(f"│ Relaciones : {graph.relation_count}")
47
+ _log.info(f"│ God nodes : {len(god_nodes)} (threshold={threshold})")
48
+ _log.info(f"│ Comunidades : {len(clusters)}")
49
+ _log.info(f"│ Artefacto : {path.relative_to(root)}")
50
+ _log.info("╚───────────────────────────────────────────────────────")
51
+ if god_nodes:
52
+ _log.warning("\n⚠ God nodes detectados:")
53
+ for n in god_nodes:
54
+ _log.info(f" • {n.name} ({n.file}:{n.line})")
55
+ _log.ok("\n[SUCCESS] Grafo semántico regenerado.")
56
+
57
+
58
+ def main() -> None:
59
+ args = _parse_args()
60
+ _setup_path()
61
+
62
+ from higpertext.semantic_engine.application.graph_builder import GraphBuilder
63
+ from higpertext.semantic_engine.application.cluster_service import ClusterService
64
+ from higpertext.semantic_engine.infrastructure.graph_store import GraphStore
65
+
66
+ root = Path(args.root).resolve()
67
+ _log.info(f"[*] Analizando proyecto: {root} (incremental={args.incremental})")
68
+
69
+ builder = GraphBuilder()
70
+ result = builder.build_with_stats(root=root, incremental=args.incremental)
71
+ graph, stats = result["graph"], result
72
+
73
+ store = GraphStore(root=root)
74
+ path = store.save(graph)
75
+
76
+ god_nodes = graph.god_nodes(threshold=args.god_threshold)
77
+ clusters = ClusterService().detect(graph)
78
+ _update_summary_md(root, graph, god_nodes, clusters)
79
+ _print_summary(root, graph, god_nodes, clusters, path, stats, args.god_threshold)
80
+
81
+
82
+ def _update_summary_md(root, graph, god_nodes, clusters) -> None:
83
+ md_path = root / WORKSPACE_DIR_NAME / "state" / "semantic_graph.md"
84
+ lines = [
85
+ "# Project Semantic Graph\n",
86
+ "\nThis file is auto-generated by `common.graph-rebuild`. Do not edit manually.\n",
87
+ f"\n## Overview\n- **Total symbols**: {graph.symbol_count}\n",
88
+ f"- **Total relations**: {graph.relation_count}\n",
89
+ f"- **God nodes**: {len(god_nodes)}\n",
90
+ f"- **Communities**: {len(clusters)}\n",
91
+ "\n## God Nodes\n",
92
+ ]
93
+ if god_nodes:
94
+ for n in god_nodes:
95
+ lines.append(f"- `{n.name}` — `{n.file}:{n.line}`\n")
96
+ else:
97
+ lines.append("_None detected._\n")
98
+
99
+ lines.append("\n## Communities\n")
100
+ for c in clusters:
101
+ lines.append(f"- **{c.id}** ({c.size} symbols)\n")
102
+
103
+ md_path.write_text("".join(lines), encoding="utf-8")
104
+
105
+
106
+ if __name__ == "__main__":
107
+ main()
@@ -0,0 +1,76 @@
1
+ """Capability common.graph-visualize — genera HTML interactivo D3.js del grafo."""
2
+
3
+ from __future__ import annotations
4
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
5
+ import argparse
6
+ import json
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ from higpertext.kernel.pkg_resources import resolve_resource
11
+ from higpertext.kernel.config_paths import PROJECT_ROOT
12
+
13
+ from higpertext.kernel.infrastructure.logger import get_logger
14
+ _log = get_logger()
15
+
16
+
17
+ def _load_graph(graph_path: Path, max_nodes: int) -> tuple[list, list]:
18
+ raw = json.loads(graph_path.read_text(encoding="utf-8"))
19
+ symbols = raw["symbols"][:max_nodes]
20
+ allowed_ids = {f"{s['file']}::{s['name']}" for s in symbols}
21
+ nodes = [
22
+ {"id": f"{s['file']}::{s['name']}", "label": s["name"], "type": s["type"]} for s in symbols
23
+ ]
24
+ links = [
25
+ {"source": r["source"], "target": r["target"]}
26
+ for r in raw["relations"]
27
+ if r["source"] in allowed_ids and r["target"] in allowed_ids
28
+ ]
29
+ return nodes, links
30
+
31
+
32
+ def _render(nodes: list, links: list, god_threshold: int, out: Path) -> None:
33
+ template_path = resolve_resource(
34
+ PROJECT_ROOT, "src", "higpertext", "templates", "html", "graph_visualize.html"
35
+ )
36
+ if not template_path.exists():
37
+ raise FileNotFoundError(f"Plantilla HTML no encontrada: {template_path}")
38
+ template = template_path.read_text(encoding="utf-8")
39
+
40
+ html = (
41
+ template.replace("{node_count}", str(len(nodes)))
42
+ .replace("{edge_count}", str(len(links)))
43
+ .replace("{god_threshold}", str(god_threshold))
44
+ .replace("{graph_json}", json.dumps({"nodes": nodes, "links": links}))
45
+ )
46
+ out.parent.mkdir(parents=True, exist_ok=True)
47
+ out.write_text(html, encoding="utf-8")
48
+
49
+
50
+ def main() -> None:
51
+ parser = argparse.ArgumentParser(description="Genera grafo HTML interactivo.")
52
+ parser.add_argument("--output", default=".higpertext/reports/semantic_graph.html")
53
+ parser.add_argument("--max_nodes", type=int, default=200)
54
+ parser.add_argument("--god_threshold", type=int, default=5)
55
+ args = parser.parse_args()
56
+
57
+ graph_path = Path(".").resolve() / WORKSPACE_DIR_NAME / "state" / "semantic_graph.json"
58
+ if not graph_path.exists():
59
+ _log.error("[ERROR] semantic_graph.json no encontrado. Ejecuta: htx task common.graph-rebuild")
60
+ sys.exit(1)
61
+
62
+ nodes, links = _load_graph(graph_path, args.max_nodes)
63
+ out = Path(args.output)
64
+ _render(nodes, links, args.god_threshold, out)
65
+
66
+ _log.info("╔─ HIGPERTEXT · Graph Visualize ──────────────────────────────")
67
+ _log.info(f"│ Nodos renderizados : {len(nodes)}")
68
+ _log.info(f"│ Aristas : {len(links)}")
69
+ _log.info(f"│ God threshold : {args.god_threshold}")
70
+ _log.info(f"│ Artefacto : {out}")
71
+ _log.info("╚───────────────────────────────────────────────────────")
72
+ _log.ok(f"\n[SUCCESS] Abre en tu navegador: {out}")
73
+
74
+
75
+ if __name__ == "__main__":
76
+ main()