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,144 @@
1
+ """common.doctor — diagnóstico integral rápido del workspace higpertext."""
2
+
3
+ from __future__ import annotations
4
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
5
+
6
+ import argparse
7
+ import json
8
+ import sys
9
+ from pathlib import Path
10
+ from higpertext.kernel.infrastructure.logger import get_logger
11
+ _log = get_logger()
12
+
13
+
14
+ def _read_json(path: Path) -> dict:
15
+ try:
16
+ return json.loads(path.read_text(encoding="utf-8"))
17
+ except (OSError, json.JSONDecodeError):
18
+ return {}
19
+
20
+
21
+ def _check(name: str, ok: bool, message: str, severity: str = "critical") -> dict:
22
+ return {
23
+ "name": name,
24
+ "status": "ok" if ok else "fail",
25
+ "severity": "ok" if ok else severity,
26
+ "message": message,
27
+ }
28
+
29
+
30
+ def run_doctor(root: Path) -> list[dict]:
31
+ """Ejecuta checks operativos sin requerir un asistente activo."""
32
+ checks = [
33
+ _check_htx(root),
34
+ _check_environment(root),
35
+ _check_capabilities(root),
36
+ _check_hooks(root),
37
+ _check_hook_sync(root),
38
+ _check_cache(root),
39
+ _check_reports(root),
40
+ ]
41
+ return checks
42
+
43
+
44
+ def _check_htx(root: Path) -> dict:
45
+ candidates = [root / ".venv" / "bin" / "htx", root / "htx.py"]
46
+ return _check("htx", any(path.exists() for path in candidates), "launcher htx disponible")
47
+
48
+
49
+ def _check_environment(root: Path) -> dict:
50
+ env = _read_json(root / WORKSPACE_DIR_NAME / "config" / "environment.json")
51
+ profile = env.get("active_profile") or env.get("profile")
52
+ assistant = env.get("assistant")
53
+ ok = bool(profile)
54
+ message = f"perfil={profile or '—'} assistant={assistant or '—'}"
55
+ return _check("environment", ok, message, "warning")
56
+
57
+
58
+ def _check_capabilities(root: Path) -> dict:
59
+ cap_dir = root / "src" / "higpertext" / "capabilities"
60
+ invalid: list[str] = []
61
+ total = 0
62
+ for path in cap_dir.rglob("*.json") if cap_dir.exists() else []:
63
+ total += 1
64
+ if not _read_json(path):
65
+ invalid.append(str(path.relative_to(root)))
66
+ ok = total > 0 and not invalid
67
+ message = f"{total} capabilities JSON; inválidos={len(invalid)}"
68
+ return _check("capabilities", ok, message)
69
+
70
+
71
+ def _check_hooks(root: Path) -> dict:
72
+ catalog = _read_json(root / "src" / "higpertext" / "hooks" / "hooks_catalog.json")
73
+ ids = {hook.get("id") for hook in catalog.get("hooks", [])}
74
+ required = {
75
+ "hook_bash_guard",
76
+ "hook_read_guard",
77
+ "hook_security_guard_pre",
78
+ "hook_security_guard_post",
79
+ "hook_post_observer",
80
+ }
81
+ missing = sorted(required - ids)
82
+ return _check("hooks", not missing, f"faltantes={missing or 'ninguno'}")
83
+
84
+
85
+ def _check_hook_sync(root: Path) -> dict:
86
+ try:
87
+ from higpertext.capabilities.common.scripts.hook_sync_check import (
88
+ run_sync_check,
89
+ )
90
+ except ImportError:
91
+ return _check("hook_sync", False, "hook-sync-check no disponible", "warning")
92
+ result = run_sync_check(root)
93
+ drift = [item["assistant"] for item in result["assistants"] if item["status"] == "drift"]
94
+ missing = [item["assistant"] for item in result["assistants"] if item["status"] == "missing"]
95
+ ok = not drift
96
+ message = f"drift={drift or 'ninguno'} missing={missing or 'ninguno'}"
97
+ return _check("hook_sync", ok, message, "warning")
98
+
99
+
100
+ def _check_cache(root: Path) -> dict:
101
+ cache_dir = root / WORKSPACE_DIR_NAME / "__cache__"
102
+ files = list(cache_dir.glob("*.json")) if cache_dir.exists() else []
103
+ stale = 0
104
+ for path in files:
105
+ data = _read_json(path)
106
+ if not data or "created_at" not in data:
107
+ stale += 1
108
+ ok = stale == 0
109
+ message = f"entradas={len(files)} corruptas={stale}"
110
+ return _check("cache", ok, message, "warning")
111
+
112
+
113
+ def _check_reports(root: Path) -> dict:
114
+ reports = root / WORKSPACE_DIR_NAME / "reports"
115
+ expected = ["test_resolution_map.md"]
116
+ missing = [name for name in expected if not (reports / name).exists()]
117
+ return _check("reports", True, f"faltantes opcionales={missing or 'ninguno'}", "warning")
118
+
119
+
120
+ def _print_human(checks: list[dict]) -> None:
121
+ _log.info("╔─ HIGPERTEXT · Doctor ─────────────────────────────────────")
122
+ for item in checks:
123
+ marker = "✓" if item["status"] == "ok" else "✗"
124
+ _log.info(f"│ {marker} {item['name']}: {item['message']}")
125
+ _log.info("╚────────────────────────────────────────────────────────────")
126
+
127
+
128
+ def main(argv: list[str] | None = None) -> None:
129
+ parser = argparse.ArgumentParser(description="Diagnóstico integral higpertext")
130
+ parser.add_argument("--json", default="false", help="Emitir JSON estructurado")
131
+ args = parser.parse_args(argv)
132
+
133
+ checks = run_doctor(Path.cwd())
134
+ ok = all(item["status"] == "ok" or item["severity"] == "warning" for item in checks)
135
+ if args.json.lower() in {"true", "1", "yes"}:
136
+ print(json.dumps({"ok": ok, "checks": checks}, ensure_ascii=False, indent=2))
137
+ else:
138
+ _print_human(checks)
139
+ if not ok:
140
+ sys.exit(1)
141
+
142
+
143
+ if __name__ == "__main__":
144
+ main()
@@ -0,0 +1,83 @@
1
+ """Capability common.efficiency-meter — mide la eficiencia de una sesión.
2
+
3
+ Cruza telemetry.jsonl + context_packs para calcular: tokens totales,
4
+ exploration_waste_ratio, context_hit_rate y hook_intercepts.
5
+ """
6
+
7
+ from __future__ import annotations
8
+ import argparse
9
+ import sys
10
+ from pathlib import Path
11
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
12
+ from higpertext.kernel.infrastructure.logger import get_logger
13
+ _log = get_logger()
14
+
15
+ def _resolve_core() -> Path:
16
+ here = Path(__file__).resolve()
17
+ for parent in here.parents:
18
+ core = parent / "src" / "core"
19
+ if core.exists():
20
+ return core
21
+ return here.parent
22
+
23
+
24
+ def main() -> None:
25
+ parser = argparse.ArgumentParser(description="Mide la eficiencia de una sesión.")
26
+ parser.add_argument(
27
+ "--session",
28
+ required=False,
29
+ default="",
30
+ help="ID de sesión. Si no se indica, usa la sesión activa.",
31
+ )
32
+ parser.add_argument(
33
+ "--format",
34
+ default="table",
35
+ help="Formato de salida: table|json|markdown. Default: table.",
36
+ )
37
+ args = parser.parse_args()
38
+
39
+ core = _resolve_core()
40
+ if str(core) not in sys.path:
41
+ sys.path.insert(0, str(core))
42
+
43
+ from higpertext.context_engine.application.efficiency_meter import EfficiencyMeter
44
+
45
+ project_root = core.parent.parent
46
+
47
+ session_id = args.session
48
+ if not session_id:
49
+ session_file = project_root / WORKSPACE_DIR_NAME / "state" / "session.json"
50
+ if session_file.exists():
51
+ import json
52
+
53
+ data = json.loads(session_file.read_text(encoding="utf-8"))
54
+ session_id = data.get("session_id", "")
55
+ if not session_id:
56
+ _log.error("[ERROR] No se encontró sesión activa. Usa --session <id>.")
57
+ sys.exit(1)
58
+
59
+ meter = EfficiencyMeter(project_root)
60
+ report = meter.measure_session(session_id)
61
+
62
+ if args.format == "json":
63
+ import json
64
+
65
+ print(json.dumps(report.to_dict(), indent=2))
66
+ elif args.format == "markdown":
67
+ _log.info(report.to_markdown())
68
+ else:
69
+ waste_pct = f"{report.exploration_waste_ratio * 100:.1f}%"
70
+ hit_pct = f"{report.context_hit_rate * 100:.1f}%"
71
+ _log.info("╔─ HIGPERTEXT · Efficiency Report ────────────────────────────")
72
+ _log.info(f"│ Sesión : {report.session_id}")
73
+ _log.info(f"│ Tokens totales : {report.total_tokens:,}")
74
+ _log.info(f"│ Costo estimado : ${report.total_cost_usd:.4f} USD")
75
+ _log.info(f"│ Exploration waste: {waste_pct} ({report.exploration_reads} reads ciegos)")
76
+ _log.info(f"│ higpertext reads : {report.higpertext_reads}")
77
+ _log.info(f"│ Hook intercepts : {report.hook_intercepts}")
78
+ _log.info(f"│ Context hit rate: {hit_pct}")
79
+ _log.info("╚───────────────────────────────────────────────────────")
80
+
81
+
82
+ if __name__ == "__main__":
83
+ main()
@@ -0,0 +1,47 @@
1
+ """Capability common.env-catalog — lista templates y motores disponibles."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+
7
+ from higpertext.capabilities.common.scripts._env_cli import print_json, service
8
+ from higpertext.kernel.infrastructure import ComposeBackend
9
+
10
+ from higpertext.kernel.infrastructure.logger import get_logger
11
+ _log = get_logger()
12
+
13
+
14
+ def main() -> None:
15
+ parser = argparse.ArgumentParser(description="Lista templates de entornos locales")
16
+ parser.add_argument("--engine", default="auto", choices=["auto", "docker", "podman"])
17
+ parser.add_argument("--json", default="false")
18
+ args = parser.parse_args()
19
+ templates = service().catalog()
20
+ payload = {
21
+ "engines": {
22
+ "docker": ComposeBackend("docker").available(),
23
+ "podman": ComposeBackend("podman").available(),
24
+ },
25
+ "templates": [
26
+ {
27
+ "id": item.id,
28
+ "description": item.description,
29
+ "source": str(item.source or ""),
30
+ }
31
+ for item in templates
32
+ ],
33
+ }
34
+ if args.json.lower() in {"true", "1", "yes"}:
35
+ print_json(payload)
36
+ return
37
+ _log.info("╔─ HIGPERTEXT · Env Catalog ─────────────────────────────────")
38
+ _log.info(f"│ Docker : {'ok' if payload['engines']['docker'] else 'no disponible'}")
39
+ _log.info(f"│ Podman : {'ok' if payload['engines']['podman'] else 'no disponible'}")
40
+ _log.info("╠─ Templates ────────────────────────────────────────────────")
41
+ for item in payload["templates"]:
42
+ _log.info(f"│ {item['id']}: {item['description']}")
43
+ _log.info("╚────────────────────────────────────────────────────────────")
44
+
45
+
46
+ if __name__ == "__main__":
47
+ main()
@@ -0,0 +1,30 @@
1
+ """Capability common.env-clean — limpia metadata de runs finalizados."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ from higpertext.kernel.infrastructure.logger import get_logger
7
+ _log = get_logger()
8
+
9
+ from higpertext.capabilities.common.scripts._env_cli import (
10
+ parse_bool,
11
+ print_json,
12
+ service,
13
+ )
14
+
15
+
16
+ def main() -> None:
17
+ parser = argparse.ArgumentParser(description="Limpia runs de entorno")
18
+ parser.add_argument("--all", default="false")
19
+ parser.add_argument("--older_than", default="")
20
+ parser.add_argument("--json", default="false")
21
+ args = parser.parse_args()
22
+ count = service().clean(parse_bool(args.all))
23
+ if parse_bool(args.json):
24
+ print_json({"deleted": count})
25
+ return
26
+ _log.ok(f"[SUCCESS] {count} run(s) limpiado(s).")
27
+
28
+
29
+ if __name__ == "__main__":
30
+ main()
@@ -0,0 +1,32 @@
1
+ """Capability common.env-logs — lee logs compactos de un run."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ from higpertext.kernel.infrastructure.logger import get_logger
7
+ _log = get_logger()
8
+
9
+ from higpertext.capabilities.common.scripts._env_cli import (
10
+ parse_bool,
11
+ print_json,
12
+ service,
13
+ )
14
+
15
+
16
+ def main() -> None:
17
+ parser = argparse.ArgumentParser(description="Lee logs de entorno")
18
+ parser.add_argument("--run_id", required=True)
19
+ parser.add_argument("--service", default="")
20
+ parser.add_argument("--tail", type=int, default=200)
21
+ parser.add_argument("--errors_only", default="false")
22
+ parser.add_argument("--json", default="false")
23
+ args = parser.parse_args()
24
+ logs = service().logs(args.run_id, args.service, args.tail, parse_bool(args.errors_only))
25
+ if parse_bool(args.json):
26
+ print_json({"run_id": args.run_id, "logs": logs})
27
+ return
28
+ _log.info(logs)
29
+
30
+
31
+ if __name__ == "__main__":
32
+ main()
@@ -0,0 +1,53 @@
1
+ """Capability common.env-runner — ejecuta un entorno Docker/Podman."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+
7
+ from higpertext.capabilities.common.scripts._env_cli import (
8
+ parse_bool,
9
+ parse_env,
10
+ print_json,
11
+ print_state,
12
+ service,
13
+ state_payload,
14
+ )
15
+ from higpertext.kernel.domain import RunSpec
16
+
17
+
18
+ def main() -> None:
19
+ parser = argparse.ArgumentParser(description="Ejecuta entornos locales Docker/Podman")
20
+ parser.add_argument("--template", required=True)
21
+ parser.add_argument("--engine", default="auto", choices=["auto", "docker", "podman"])
22
+ parser.add_argument("--task", default="")
23
+ parser.add_argument("--command", default="")
24
+ parser.add_argument("--service", default="")
25
+ parser.add_argument("--detach", default="false")
26
+ parser.add_argument("--parallel", default="false")
27
+ parser.add_argument("--timeout", type=int, default=300)
28
+ parser.add_argument("--keep_alive", default="false")
29
+ parser.add_argument("--cleanup", default="true")
30
+ parser.add_argument("--env", default="")
31
+ parser.add_argument("--json", default="false")
32
+ args = parser.parse_args()
33
+ spec = RunSpec(
34
+ template_id=args.template,
35
+ engine=args.engine,
36
+ task=args.task,
37
+ command=args.command,
38
+ service=args.service,
39
+ detach=parse_bool(args.detach),
40
+ timeout_seconds=args.timeout,
41
+ keep_alive=parse_bool(args.keep_alive),
42
+ cleanup=parse_bool(args.cleanup),
43
+ env=parse_env(args.env),
44
+ )
45
+ state = service().run(spec)
46
+ if parse_bool(args.json):
47
+ print_json(state_payload(state))
48
+ return
49
+ print_state(state)
50
+
51
+
52
+ if __name__ == "__main__":
53
+ main()
@@ -0,0 +1,38 @@
1
+ """Capability common.env-status — consulta estado de ejecuciones."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ from higpertext.kernel.infrastructure.logger import get_logger
7
+ _log = get_logger()
8
+
9
+ from higpertext.capabilities.common.scripts._env_cli import (
10
+ parse_bool,
11
+ print_json,
12
+ print_state,
13
+ service,
14
+ state_payload,
15
+ )
16
+
17
+
18
+ def main() -> None:
19
+ parser = argparse.ArgumentParser(description="Consulta estado de env runs")
20
+ parser.add_argument("--run_id", default="")
21
+ parser.add_argument("--json", default="false")
22
+ args = parser.parse_args()
23
+ result = service().status(args.run_id or None)
24
+ if parse_bool(args.json):
25
+ payload = state_payload(result) if args.run_id else [state_payload(item) for item in result]
26
+ print_json(payload)
27
+ return
28
+ if args.run_id:
29
+ print_state(result)
30
+ return
31
+ _log.info("╔─ HIGPERTEXT · Env Runs ────────────────────────────────────")
32
+ for state in result:
33
+ _log.info(f"│ {state.run_id} · {state.template_id} · {state.status} · {state.engine}")
34
+ _log.info("╚────────────────────────────────────────────────────────────")
35
+
36
+
37
+ if __name__ == "__main__":
38
+ main()
@@ -0,0 +1,30 @@
1
+ """Capability common.env-stop — detiene un entorno."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+
7
+ from higpertext.capabilities.common.scripts._env_cli import (
8
+ parse_bool,
9
+ print_json,
10
+ print_state,
11
+ service,
12
+ state_payload,
13
+ )
14
+
15
+
16
+ def main() -> None:
17
+ parser = argparse.ArgumentParser(description="Detiene entorno local")
18
+ parser.add_argument("--run_id", required=True)
19
+ parser.add_argument("--volumes", default="false")
20
+ parser.add_argument("--json", default="false")
21
+ args = parser.parse_args()
22
+ state = service().stop(args.run_id, parse_bool(args.volumes))
23
+ if parse_bool(args.json):
24
+ print_json(state_payload(state))
25
+ return
26
+ print_state(state)
27
+
28
+
29
+ if __name__ == "__main__":
30
+ main()
@@ -0,0 +1,73 @@
1
+ """Capability common.env-template — valida o muestra templates."""
2
+
3
+ from __future__ import annotations
4
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
5
+
6
+ import argparse
7
+ from higpertext.kernel.infrastructure.logger import get_logger
8
+ _log = get_logger()
9
+
10
+ from higpertext.capabilities.common.scripts._env_cli import (
11
+ parse_bool,
12
+ print_json,
13
+ project_root,
14
+ service,
15
+ )
16
+
17
+
18
+ def main() -> None:
19
+ parser = argparse.ArgumentParser(description="Gestiona templates de entorno")
20
+ parser.add_argument("--action", required=True, choices=["validate", "show", "create"])
21
+ parser.add_argument("--template", required=True)
22
+ parser.add_argument("--json", default="false")
23
+ args = parser.parse_args()
24
+ if args.action == "create":
25
+ target = project_root() / WORKSPACE_DIR_NAME / "env" / "templates" / f"{args.template}.yaml"
26
+ target.parent.mkdir(parents=True, exist_ok=True)
27
+ if not target.exists():
28
+ target.write_text(_starter_template(args.template), encoding="utf-8")
29
+ _log.ok(f"[SUCCESS] Template disponible en: {target}")
30
+ return
31
+ template = service().validate_template(args.template)
32
+ payload = {
33
+ "id": template.id,
34
+ "description": template.description,
35
+ "source": str(template.source or ""),
36
+ "services": list(template.services),
37
+ }
38
+ if parse_bool(args.json):
39
+ print_json(payload)
40
+ return
41
+ if args.action == "show":
42
+ print_json(payload)
43
+ else:
44
+ _log.ok(f"Template válido: {template.id}")
45
+
46
+
47
+ def _starter_template(template_id: str) -> str:
48
+ return f"""id: {template_id}
49
+ description: Custom local environment
50
+ services:
51
+ app:
52
+ image: alpine:3.20
53
+ working_dir: /workspace
54
+ volumes:
55
+ - .:/workspace
56
+ command: sleep infinity
57
+ tasks:
58
+ test:
59
+ service: app
60
+ command: echo 'custom task'
61
+ defaults:
62
+ service: app
63
+ task: test
64
+ timeout_seconds: 300
65
+ cleanup: true
66
+ security:
67
+ network: isolated
68
+ privileged: false
69
+ """
70
+
71
+
72
+ if __name__ == "__main__":
73
+ main()
@@ -0,0 +1,138 @@
1
+ """common.error-context-locator — localiza contexto mínimo desde errores/trazas."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import re
8
+ import sys
9
+ from dataclasses import dataclass
10
+ from pathlib import Path
11
+
12
+ from higpertext.kernel.infrastructure.logger import get_logger
13
+ _log = get_logger()
14
+
15
+ _PY_TRACE = re.compile(r'File "(?P<file>[^"]+)", line (?P<line>\d+)')
16
+ _GENERIC = re.compile(
17
+ r"(?P<file>[\w./\\-]+\.(?:py|js|ts|tsx|jsx|json|yaml|yml|toml|md))[:(](?P<line>\d+)"
18
+ )
19
+
20
+
21
+ @dataclass(frozen=True)
22
+ class ErrorLocation:
23
+ file: str
24
+ line: int
25
+ message: str = ""
26
+
27
+
28
+ def _read_error(args: argparse.Namespace) -> str:
29
+ if args.error_file:
30
+ return Path(args.error_file).read_text(encoding="utf-8", errors="ignore")
31
+ return args.error or sys.stdin.read()
32
+
33
+
34
+ def extract_locations(text: str, include_tests: bool = True) -> list[ErrorLocation]:
35
+ """Extrae ubicaciones file:line de trazas comunes."""
36
+ results: list[ErrorLocation] = []
37
+ for pattern in (_PY_TRACE, _GENERIC):
38
+ for match in pattern.finditer(text):
39
+ file = match.group("file").replace("\\", "/")
40
+ if not include_tests and _is_test_file(file):
41
+ continue
42
+ line = int(match.group("line"))
43
+ message = _nearby_error_line(text, match.start())
44
+ item = ErrorLocation(file=file, line=line, message=message)
45
+ if item not in results:
46
+ results.append(item)
47
+ return results
48
+
49
+
50
+ def _is_test_file(file: str) -> bool:
51
+ parts = set(Path(file).parts)
52
+ return bool(parts & {"tests", "test", "__tests__"}) or Path(file).name.startswith("test_")
53
+
54
+
55
+ def _nearby_error_line(text: str, index: int) -> str:
56
+ prefix = text[:index].splitlines()[-3:]
57
+ suffix = text[index:].splitlines()[:3]
58
+ for line in reversed(prefix + suffix):
59
+ stripped = line.strip()
60
+ if stripped and any(
61
+ token in stripped.lower() for token in ("error", "exception", "failed", "assert")
62
+ ):
63
+ return stripped[:240]
64
+ return ""
65
+
66
+
67
+ def _context_for(root: Path, location: ErrorLocation, max_context: int) -> str:
68
+ path = Path(location.file)
69
+ if not path.is_absolute():
70
+ path = root / path
71
+ if not path.exists() or not path.is_file():
72
+ return " [archivo no encontrado]"
73
+ lines = path.read_text(encoding="utf-8", errors="ignore").splitlines()
74
+ start = max(1, location.line - max_context)
75
+ end = min(len(lines), location.line + max_context)
76
+ output = []
77
+ for lineno in range(start, end + 1):
78
+ marker = ">>>" if lineno == location.line else " "
79
+ output.append(f" {marker} L{lineno:>4}: {lines[lineno - 1][:220]}")
80
+ return "\n".join(output)
81
+
82
+
83
+ def build_report(text: str, root: Path, max_context: int, include_tests: bool) -> str:
84
+ locations = extract_locations(text, include_tests)
85
+ if not locations:
86
+ return "[NOT FOUND] No se detectaron ubicaciones file:line en el error."
87
+ lines = ["╔─ HIGPERTEXT · Error Context Locator ───────────────────────"]
88
+ lines.append(f"│ Ubicaciones detectadas: {len(locations)}")
89
+ lines.append("╠────────────────────────────────────────────────────────────")
90
+ for loc in locations[:20]:
91
+ lines.append(f"│ {loc.file}:{loc.line}")
92
+ if loc.message:
93
+ lines.append(f"│ Error: {loc.message}")
94
+ lines.append("│ Contexto:")
95
+ lines.append(_context_for(root, loc, max_context))
96
+ lines.append("│ Sugerencia:")
97
+ lines.append(
98
+ f"│ htx task common.smart-read --path {loc.file} --around_line {loc.line} --limit {max_context}" # noqa: E501
99
+ )
100
+ lines.append("╚────────────────────────────────────────────────────────────")
101
+ return "\n".join(lines)
102
+
103
+
104
+ def _json_report(text: str, root: Path, max_context: int, include_tests: bool) -> dict:
105
+ locations = extract_locations(text, include_tests)
106
+ return {
107
+ "locations": [loc.__dict__ for loc in locations],
108
+ "suggestions": [
109
+ f"htx task common.smart-read --path {loc.file} --around_line {loc.line} --limit {max_context}" # noqa: E501
110
+ for loc in locations
111
+ ],
112
+ }
113
+
114
+
115
+ def main() -> None:
116
+ parser = argparse.ArgumentParser(description="Localiza contexto mínimo desde trazas de error")
117
+ parser.add_argument("--error", default="")
118
+ parser.add_argument("--error_file", default="")
119
+ parser.add_argument("--max_context", type=int, default=5)
120
+ parser.add_argument("--include_tests", default="true")
121
+ parser.add_argument("--json", default="false")
122
+ args = parser.parse_args()
123
+ text = _read_error(args)
124
+ include_tests = args.include_tests.lower() in {"true", "1", "yes"}
125
+ if args.json.lower() in {"true", "1", "yes"}:
126
+ _log.info(
127
+ json.dumps(
128
+ _json_report(text, Path.cwd(), args.max_context, include_tests),
129
+ ensure_ascii=False,
130
+ indent=2,
131
+ )
132
+ )
133
+ return
134
+ _log.info(build_report(text, Path.cwd(), args.max_context, include_tests))
135
+
136
+
137
+ if __name__ == "__main__":
138
+ main()