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,132 @@
1
+ """TelemetryReporter — dashboard de telemetría en terminal (Infraestructura)."""
2
+
3
+ from __future__ import annotations
4
+ from pathlib import Path
5
+
6
+ from higpertext.kernel.app_config import (
7
+ TELEMETRY_BOX_WIDTH as _W,
8
+ TELEMETRY_BAR_WIDTH as _BAR_W,
9
+ TELEMETRY_EMPTY_TITLE,
10
+ TELEMETRY_EMPTY_LINES,
11
+ TELEMETRY_SECTION_LABELS as _LABELS,
12
+ TELEMETRY_ACTIVITY_ICONS as _ICONS,
13
+ )
14
+ from higpertext.kernel.application.telemetry import TelemetryAggregator
15
+ from higpertext.kernel.infrastructure.logger import HtxLogger, get_logger, render_box
16
+
17
+
18
+ def _box_row(text: str = "") -> str:
19
+ pad = _W - len(text) - 2
20
+ return f"║ {text}{' ' * pad}║"
21
+
22
+
23
+ def _sep() -> str:
24
+ return "─" * (_W + 2)
25
+
26
+
27
+ def render(
28
+ project_root: Path,
29
+ days: int = 7,
30
+ project_id: str | None = None,
31
+ *,
32
+ logger: HtxLogger | None = None,
33
+ ) -> str:
34
+ """Genera el dashboard de telemetría y lo emite vía logger.
35
+
36
+ Args:
37
+ project_root: Raíz del proyecto.
38
+ days: Ventana de días a analizar.
39
+ project_id: Filtro opcional de proyecto.
40
+ logger: Instancia HtxLogger a usar. Si es None se obtiene el singleton.
41
+
42
+ Returns:
43
+ El string renderizado (compatibilidad con callers que capturan output).
44
+ """
45
+ log: HtxLogger = logger or get_logger(project_root)
46
+ agg = TelemetryAggregator(project_root, project_id=project_id)
47
+ m = agg.compute(days)
48
+
49
+ if not m:
50
+ block = render_box(
51
+ TELEMETRY_EMPTY_TITLE,
52
+ [_box_row(line) for line in TELEMETRY_EMPTY_LINES],
53
+ )
54
+ log.warning(block)
55
+ return block + "\n"
56
+
57
+ project_label = f" · {project_id}" if project_id else ""
58
+ h = int(m["total_duration_min"] // 60)
59
+ mn = int(m["total_duration_min"] % 60)
60
+ duration_str = f"{h}h {mn}m" if h else f"{mn}m"
61
+
62
+ active_hint = f" (activa: {m['sessions_active']})" if m["sessions_active"] else ""
63
+
64
+ corr = m["correlations"]
65
+ adoption = corr["higpertext_adoption_pct"]
66
+ adoption_bar = _bar(adoption, 100)
67
+ higpertext_calls = corr["higpertext_calls"]
68
+ higpertext_direct = corr.get("higpertext_direct_calls", 0)
69
+ bash_direct = corr["bash_direct_calls"]
70
+
71
+ rows = [
72
+ _box_row(),
73
+ _box_row(f"Sesiones : {m['sessions_total']}{active_hint}"),
74
+ _box_row(f"Tiempo total : {duration_str}"),
75
+ _box_row(f"Commits : {m['commits_total']} (solicitudes resueltas)"),
76
+ _box_row(f"Tool calls : {m['tool_calls_total']}"),
77
+ _box_row(f"Tokens est. : {m['estimated_tokens']:,}"),
78
+ _box_row(f"Costo est. : ${m['estimated_cost_usd']:.4f} USD"),
79
+ _box_row(),
80
+ _box_row(_LABELS["correlations"]),
81
+ _box_row(_sep()[: _W - 2]),
82
+ _box_row(f"Tokens/sesión : {corr['tokens_per_session']:,}"),
83
+ _box_row(f"Costo/commit : ${corr['cost_per_commit_usd']:.4f} USD"),
84
+ _box_row(f"Commits/sesión : {corr['commits_per_session']}"),
85
+ _box_row(f"Adopción higpertext : {adoption_bar} {adoption}%"),
86
+ _box_row(
87
+ f" intercepts+caps: {higpertext_calls - higpertext_direct}"
88
+ f" · htx.py directo: {higpertext_direct}"
89
+ f" · bash: {bash_direct}"
90
+ ),
91
+ _box_row(),
92
+ ]
93
+
94
+ if m["top_capabilities"]:
95
+ rows.append(_box_row(_LABELS["top_caps"]))
96
+ rows.append(_box_row(_sep()[: _W - 2]))
97
+ for i, (cap, count) in enumerate(m["top_capabilities"], 1):
98
+ rows.append(_box_row(f" {i}. {cap:<30} ×{count}"))
99
+
100
+ if m.get("top_direct_tools"):
101
+ rows.append(_box_row(_LABELS["top_tools"]))
102
+ rows.append(_box_row(_sep()[: _W - 2]))
103
+ for i, (tool, count) in enumerate(m["top_direct_tools"], 1):
104
+ rows.append(_box_row(f" {i}. {tool:<30} ×{count}"))
105
+
106
+ recent = m.get("recent_activity", [])
107
+ if recent:
108
+ rows += [_box_row(), _box_row(_LABELS["recent_activity"])]
109
+ rows.append(_box_row(_sep()[: _W - 2]))
110
+ for act in recent:
111
+ icon = _activity_icon(act["op_type"])
112
+ target = act["target"]
113
+ max_target = _W - 12
114
+ if len(target) > max_target:
115
+ target = "…" + target[-(max_target - 1):]
116
+ rows.append(_box_row(f" {icon} {target}"))
117
+
118
+ rows.append(_box_row())
119
+
120
+ title = f"HIGPERTEXT TELEMETRY · últimos {days} días{project_label}"
121
+ block = render_box(title, rows)
122
+ log.info(block)
123
+ return block + "\n"
124
+
125
+
126
+ def _activity_icon(op_type: str) -> str:
127
+ return _ICONS.get(op_type, _ICONS["default"])
128
+
129
+
130
+ def _bar(value: float, total: float) -> str:
131
+ filled = int(round(value / total * _BAR_W)) if total else 0
132
+ return "█" * filled + "░" * (_BAR_W - filled)
@@ -0,0 +1 @@
1
+ # Infrastructure validation init
@@ -0,0 +1,163 @@
1
+ """Validador de contratos técnicos definidos en el JSON de cada capacidad (Infraestructura)."""
2
+
3
+ from __future__ import annotations
4
+ import re
5
+ import json
6
+ from pathlib import Path
7
+
8
+
9
+ class ContractValidator:
10
+ """Validador de contratos técnicos definidos en el JSON de cada capacidad."""
11
+
12
+ @staticmethod
13
+ def validate(
14
+ params: dict,
15
+ stdout: str,
16
+ stderr: str,
17
+ returncode: int,
18
+ capability_data: dict,
19
+ ) -> tuple[bool, list[str]]:
20
+ errors = []
21
+ errors.extend(ContractValidator._validate_params(params, capability_data))
22
+
23
+ contract = capability_data.get("contract", {})
24
+ if not contract:
25
+ return len(errors) == 0, errors
26
+
27
+ errors.extend(
28
+ ContractValidator._validate_contract(stdout, stderr, params, capability_data, contract)
29
+ )
30
+ return len(errors) == 0, errors
31
+
32
+ @staticmethod
33
+ def _validate_params(params: dict, capability_data: dict) -> list[str]:
34
+ errors = []
35
+ for param_def in capability_data.get("parameters", []):
36
+ name = param_def.get("name")
37
+ if name is None:
38
+ continue
39
+
40
+ if param_def.get("required", False) and name not in params:
41
+ errors.append(f"El parámetro obligatorio '{name}' no fue provisto.")
42
+ continue
43
+
44
+ if name in params:
45
+ validator = ContractValidator._param_type_validators().get(
46
+ param_def.get("type", "string").lower()
47
+ )
48
+ if validator:
49
+ errors.extend(validator(name, params[name]))
50
+ return errors
51
+
52
+ @staticmethod
53
+ def _param_type_validators() -> dict[str, callable]:
54
+ return {
55
+ "integer": ContractValidator._validate_integer_param,
56
+ "boolean": ContractValidator._validate_boolean_param,
57
+ "array": ContractValidator._validate_array_param,
58
+ }
59
+
60
+ @staticmethod
61
+ def _validate_integer_param(name: str, value) -> list[str]:
62
+ try:
63
+ int(value)
64
+ return []
65
+ except (ValueError, TypeError):
66
+ return [
67
+ f"El parámetro '{name}' debe ser de tipo entero (recibido: '{value}')."
68
+ ]
69
+
70
+ @staticmethod
71
+ def _validate_boolean_param(name: str, value) -> list[str]:
72
+ if isinstance(value, bool) or str(value).lower() in (
73
+ "true",
74
+ "false",
75
+ "1",
76
+ "0",
77
+ ):
78
+ return []
79
+ return [
80
+ f"El parámetro '{name}' debe ser booleano (recibido: '{value}')."
81
+ ]
82
+
83
+ @staticmethod
84
+ def _validate_array_param(name: str, value) -> list[str]:
85
+ if isinstance(value, (list, tuple)) or isinstance(value, str):
86
+ return []
87
+ return [
88
+ f"El parámetro '{name}' debe ser de tipo array (recibido: '{value}')."
89
+ ]
90
+
91
+ @staticmethod
92
+ def _validate_contract(
93
+ stdout: str,
94
+ stderr: str,
95
+ params: dict,
96
+ capability_data: dict,
97
+ contract: dict,
98
+ ) -> list[str]:
99
+ errors = []
100
+ expected_format = contract.get("format", "").lower()
101
+
102
+ if expected_format == "json":
103
+ errors.extend(
104
+ ContractValidator._validate_json_output(stdout, contract.get("required_fields", []))
105
+ )
106
+
107
+ errors.extend(ContractValidator._validate_patterns(stdout, stderr, contract))
108
+ errors.extend(
109
+ ContractValidator._validate_expected_files(params, capability_data, contract.get("expected_files", []))
110
+ )
111
+
112
+ return errors
113
+
114
+ @staticmethod
115
+ def _validate_json_output(stdout: str, required_fields: list[str]) -> list[str]:
116
+ errors = []
117
+ try:
118
+ json_data = json.loads(stdout)
119
+ for field in required_fields:
120
+ if field not in json_data:
121
+ errors.append(f"El output JSON no contiene el campo obligatorio: '{field}'")
122
+ except json.JSONDecodeError:
123
+ errors.append("El contrato exige formato JSON, pero el output no es JSON válido.")
124
+ return errors
125
+
126
+ @staticmethod
127
+ def _validate_patterns(stdout: str, stderr: str, contract: dict) -> list[str]:
128
+ errors = []
129
+ for pattern in contract.get("required_patterns", []):
130
+ if not re.search(pattern, stdout):
131
+ errors.append(f"El output no contiene el patrón requerido: '{pattern}'")
132
+
133
+ for pattern in contract.get("forbidden_patterns", []):
134
+ if re.search(pattern, stdout) or re.search(pattern, stderr):
135
+ errors.append(f"Se detectó un patrón prohibido en el output/stderr: '{pattern}'")
136
+ return errors
137
+
138
+ @staticmethod
139
+ def _validate_expected_files(
140
+ params: dict,
141
+ capability_data: dict,
142
+ file_templates: list[str],
143
+ ) -> list[str]:
144
+ errors = []
145
+ for file_template in file_templates:
146
+ try:
147
+ interpolated_path = file_template
148
+ for key, val in params.items():
149
+ interpolated_path = interpolated_path.replace(f"{{{key}}}", str(val))
150
+ for param_def in capability_data.get("parameters", []):
151
+ p_name = param_def.get("name")
152
+ if p_name and f"{{{p_name}}}" in interpolated_path and "default" in param_def:
153
+ interpolated_path = interpolated_path.replace(
154
+ f"{{{p_name}}}", str(param_def["default"])
155
+ )
156
+ target_file = Path(interpolated_path).resolve()
157
+ if not target_file.exists():
158
+ errors.append(f"Archivo esperado no fue creado: '{interpolated_path}'")
159
+ elif target_file.stat().st_size == 0:
160
+ errors.append(f"Archivo '{interpolated_path}' creado pero vacío (0 bytes).")
161
+ except OSError as e:
162
+ errors.append(f"Error validando archivo '{file_template}': {e}")
163
+ return errors
@@ -0,0 +1,38 @@
1
+ """Resolución de recursos empaquetados — fallback dev tree -> wheel instalado."""
2
+
3
+ from __future__ import annotations
4
+ from pathlib import Path
5
+
6
+
7
+ def pkg_data_root() -> Path | None:
8
+ """Raíz de higpertext_data (perfiles, capabilities json, templates, hooks_catalog)."""
9
+ try:
10
+ import higpertext_data
11
+
12
+ return Path(higpertext_data.__path__[0]).resolve()
13
+ except (ImportError, AttributeError, IndexError):
14
+ return None
15
+
16
+
17
+ def installed_src_root() -> Path | None:
18
+ """Raíz equivalente a src/ vía el paquete higpertext instalado (módulos .py reales)."""
19
+ try:
20
+ import higpertext
21
+
22
+ return Path(higpertext.__path__[0]).resolve().parent
23
+ except (ImportError, AttributeError, IndexError):
24
+ return None
25
+
26
+
27
+ def resolve_resource(base_dir: Path, *rel_parts: str) -> Path:
28
+ """base_dir/rel_parts si existe; si no, cae a pkg_data_root()/rel_parts[1:]
29
+ cuando rel_parts[0] == 'src'."""
30
+ dev_path = base_dir.joinpath(*rel_parts)
31
+ if dev_path.exists():
32
+ return dev_path
33
+ pkg_root = pkg_data_root()
34
+ if pkg_root is not None and rel_parts and rel_parts[0] == "src":
35
+ pkg_path = pkg_root.joinpath(*rel_parts[1:])
36
+ if pkg_path.exists():
37
+ return pkg_path
38
+ return dev_path
@@ -0,0 +1,319 @@
1
+ """higpertext Session Manager — fachada del ciclo de vida de sesiones temporales.
2
+
3
+ Delega en:
4
+ - SessionContextBuilder (resolución de skills/subagentes)
5
+ - ResourceDeployer (despliegue y restauración de recursos)
6
+ - MarkdownRenderer (generación de Markdown — via ResourceDeployer)
7
+ """
8
+
9
+ from __future__ import annotations
10
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
11
+
12
+ import datetime
13
+ import json
14
+ import os
15
+ import secrets
16
+ import shutil
17
+ from pathlib import Path
18
+
19
+ from higpertext.kernel.infrastructure.presentation.markdown_renderer import (
20
+ MarkdownRenderer,
21
+ )
22
+ from higpertext.kernel.infrastructure.deployment.resource_deployer import (
23
+ ResourceDeployer,
24
+ )
25
+ from higpertext.kernel.application.context_builder import SessionContextBuilder
26
+ from higpertext.kernel.infrastructure.logger import get_logger
27
+ from higpertext.kernel.app_config import (
28
+ DEFAULT_ASSISTANT as _DEFAULT_ASSISTANT,
29
+ DEFAULT_PROFILE as _DEFAULT_PROFILE,
30
+ ASSISTANT_PATHS as _ASSISTANT_PATHS,
31
+ )
32
+
33
+ _log = get_logger()
34
+
35
+
36
+ class SessionManager:
37
+ """Fachada: orquesta el ciclo de vida completo de una sesión temporal."""
38
+
39
+ def __init__(self, project_root: Path, root_dir: Path) -> None:
40
+ self.project_root = project_root
41
+ self.root_dir = root_dir
42
+ self.session_file = project_root / WORKSPACE_DIR_NAME / "state" / "session.json"
43
+ self.env_file = project_root / WORKSPACE_DIR_NAME / "config" / "environment.json"
44
+ self.session_file.parent.mkdir(parents=True, exist_ok=True)
45
+ self.env_file.parent.mkdir(parents=True, exist_ok=True)
46
+ self._context_builder = SessionContextBuilder(project_root, root_dir)
47
+ self._deployer = ResourceDeployer(project_root, root_dir)
48
+
49
+ # --- Environment helpers ---
50
+
51
+ def get_assistant_and_profile(self) -> tuple[str, str]:
52
+ if not self.env_file.exists():
53
+ return _DEFAULT_ASSISTANT, _DEFAULT_PROFILE
54
+ try:
55
+ data = json.loads(self.env_file.read_text(encoding="utf-8"))
56
+ return (
57
+ data.get("assistant", _DEFAULT_ASSISTANT),
58
+ data.get("active_profile", _DEFAULT_PROFILE),
59
+ )
60
+ except (OSError, json.JSONDecodeError):
61
+ return _DEFAULT_ASSISTANT, _DEFAULT_PROFILE
62
+
63
+ def get_model(self, assistant: str) -> str | None:
64
+ try:
65
+ if self.env_file.exists():
66
+ data = json.loads(self.env_file.read_text(encoding="utf-8"))
67
+ model = data.get("llm", {}).get("assistants", {}).get(assistant, {}).get("model")
68
+ if model:
69
+ return model
70
+ return None
71
+ except (OSError, json.JSONDecodeError):
72
+ return None
73
+
74
+ def get_paths(self, assistant: str) -> tuple[Path, Path, Path]:
75
+ wf, sk, sa = _ASSISTANT_PATHS.get(assistant, _ASSISTANT_PATHS[_DEFAULT_ASSISTANT])
76
+ root = self.project_root
77
+ return root / wf, root / sk, root / sa
78
+
79
+ def get_agent_system_dir(self) -> Path:
80
+ env_path = os.getenv("AGENT_SYSTEM_PATH")
81
+ if env_path and Path(env_path).exists():
82
+ return Path(env_path).resolve()
83
+ candidate = self.root_dir.parent.parent / "app" / "APP_Scripts_PowerShell" / "AgentSystem"
84
+ return candidate if candidate.exists() else self.root_dir
85
+
86
+ # --- Session lifecycle ---
87
+
88
+ def start_session(
89
+ self,
90
+ profile_name: str,
91
+ assistant: str,
92
+ skills: list | None = None,
93
+ subagents: list | None = None,
94
+ ) -> dict:
95
+ self.clean_session()
96
+ skills, subagents = self._context_builder.resolve_resources(profile_name, skills, subagents)
97
+
98
+ session_id = f"sess_{int(datetime.datetime.now().timestamp())}_{secrets.token_hex(2)}"
99
+ session_data = {
100
+ "session_id": session_id,
101
+ "profile": profile_name,
102
+ "assistant": assistant,
103
+ "status": "active",
104
+ "created_at": datetime.datetime.now().isoformat(),
105
+ "active_skills": skills,
106
+ "active_subagents": subagents,
107
+ "tasks": [],
108
+ }
109
+ self.session_file.parent.mkdir(parents=True, exist_ok=True)
110
+ self.session_file.write_text(
111
+ json.dumps(session_data, indent=4, ensure_ascii=False), encoding="utf-8"
112
+ )
113
+
114
+ wf_dest, sk_dest, sa_dest = self.get_paths(assistant)
115
+ self._run_adapter_hook(assistant, "on_session_start", profile_name)
116
+ self._deployer.deploy_skills(skills, sk_dest)
117
+ skills_str, beans_str = self._deployer.build_resource_links(
118
+ skills, subagents, sk_dest, sa_dest
119
+ )
120
+ self._deployer.deploy_subagents(subagents, sa_dest, skills_str)
121
+ self._deployer.deploy_playbooks(
122
+ wf_dest,
123
+ skills_str,
124
+ beans_str,
125
+ session_id,
126
+ assistant,
127
+ get_model_fn=self.get_model,
128
+ get_profile_fn=self._load_active_profile_data,
129
+ )
130
+ # Mirror gemini resources to .agents/ (antigravity deprecated, same flow)
131
+ if assistant == "gemini":
132
+ self._mirror_gemini_to_agents(self.project_root)
133
+ self._refresh_semantic_graph()
134
+ _log.ok(f"[SUCCESS] Sesión temporal '{session_id}' iniciada.")
135
+ return session_data
136
+
137
+ def _mirror_gemini_to_agents(self, project_root: Path) -> None:
138
+ import shutil as _shutil
139
+
140
+ mapping = {"skills": "skills", "agents": "agents", "workflows": "workflows"}
141
+ for src_sub, dst_sub in mapping.items():
142
+ src = project_root / ".gemini" / src_sub
143
+ dst = project_root / ".agents" / dst_sub
144
+ if not src.exists():
145
+ continue
146
+ dst.mkdir(parents=True, exist_ok=True)
147
+ for item in src.iterdir():
148
+ if item.is_file():
149
+ _shutil.copy2(item, dst / item.name)
150
+ elif item.is_dir():
151
+ _shutil.copytree(item, dst / item.name, dirs_exist_ok=True)
152
+
153
+ def clean_session(self) -> bool:
154
+ assistant = self._read_session_assistant()
155
+ wf_dest, sk_dest, sa_dest = self.get_paths(assistant)
156
+
157
+ for d in (sk_dest, sa_dest):
158
+ if d.exists():
159
+ try:
160
+ shutil.rmtree(d)
161
+ except OSError: # nosec B110
162
+ pass
163
+
164
+ if assistant == "gemini":
165
+ for sub in ("skills", "agents", "workflows"):
166
+ d = self.project_root / ".agents" / sub
167
+ if d.exists():
168
+ try:
169
+ shutil.rmtree(d)
170
+ except OSError: # nosec B110
171
+ pass
172
+
173
+ # Limpiar cache de capabilities
174
+ cache_dir = self.project_root / WORKSPACE_DIR_NAME / "__cache__"
175
+ if cache_dir.exists():
176
+ for f in cache_dir.glob("*.json"):
177
+ try:
178
+ f.unlink()
179
+ except OSError: # nosec B110
180
+ pass
181
+
182
+ self._run_adapter_hook(assistant, "on_session_clean")
183
+ self._deployer.restore_playbooks(
184
+ wf_dest,
185
+ assistant,
186
+ get_model_fn=self.get_model,
187
+ get_profile_fn=self._load_active_profile_data,
188
+ )
189
+
190
+ from higpertext.kernel.infrastructure.file_repositories import (
191
+ FileSessionRepository,
192
+ )
193
+ from higpertext.kernel.application.session_services import (
194
+ SessionApplicationService,
195
+ )
196
+ from higpertext.kernel.infrastructure.file_repositories import (
197
+ FileProfileRepository,
198
+ )
199
+
200
+ # Generar reporte de telemetría de forma automática antes de borrar recursos
201
+ try:
202
+ from higpertext.kernel.infrastructure.telemetry_reporter import render as render_telemetry
203
+ from higpertext.kernel.infrastructure import OutputStore
204
+
205
+ report_content = render_telemetry(self.project_root, days=7)
206
+ OutputStore(self.project_root).write(
207
+ "common.telemetry-report", report_content, fmt="txt"
208
+ )
209
+
210
+ # Generar el Diario de Decisiones
211
+ from higpertext.capabilities.common.scripts.commit_rationale_log import (
212
+ main as run_rationale_log,
213
+ )
214
+
215
+ try:
216
+ import sys as _sys
217
+
218
+ _orig = _sys.argv
219
+ _sys.argv = [_sys.argv[0]]
220
+ run_rationale_log()
221
+ _sys.argv = _orig
222
+ except Exception: # nosec B110
223
+ pass
224
+
225
+ # Generar el Análisis de Desviación Arquitectónica
226
+ from higpertext.capabilities.common.scripts.architecture_drift_report import (
227
+ main as run_drift_report,
228
+ )
229
+
230
+ try:
231
+ _sys.argv = [_sys.argv[0]]
232
+ run_drift_report()
233
+ except Exception: # nosec B110
234
+ pass
235
+ finally:
236
+ _sys.argv = _orig
237
+
238
+ from higpertext.capabilities.common.scripts.report_viewer import (
239
+ main as run_report_viewer,
240
+ )
241
+
242
+ try:
243
+ _sys.argv = [_sys.argv[0]]
244
+ run_report_viewer()
245
+ except Exception: # nosec B110
246
+ pass
247
+ finally:
248
+ _sys.argv = _orig
249
+ except Exception as e: # nosec B110
250
+ pass
251
+
252
+ session_repo = FileSessionRepository(self.session_file)
253
+ profile_repo = FileProfileRepository(self.project_root / "src" / "config" / "profiles")
254
+ session_service = SessionApplicationService(session_repo, profile_repo)
255
+ session_service.clean_session()
256
+
257
+ _log.ok("[SUCCESS] Sesión temporal y recursos limpiados exitosamente.")
258
+ return True
259
+
260
+ # --- Private helpers ---
261
+
262
+ def _read_session_assistant(self) -> str:
263
+ if self.session_file.exists():
264
+ try:
265
+ data = json.loads(self.session_file.read_text(encoding="utf-8"))
266
+ return data.get("assistant", _DEFAULT_ASSISTANT)
267
+ except (OSError, json.JSONDecodeError): # nosec B110
268
+ pass
269
+ assistant, _ = self.get_assistant_and_profile()
270
+ return assistant
271
+
272
+ def _refresh_semantic_graph(self) -> None:
273
+ try:
274
+ from higpertext.kernel.infrastructure.parser.semantic_graph import (
275
+ SemanticGraphGenerator,
276
+ )
277
+
278
+ _log.info("[*] Actualizando grafo semántico del proyecto...")
279
+ SemanticGraphGenerator.generate(self.project_root)
280
+ _log.ok("[SUCCESS] Grafo semántico actualizado.")
281
+ except (ImportError, OSError) as e:
282
+ _log.warning(f"[WARNING] No se pudo actualizar el grafo semántico: {e}")
283
+
284
+ def _load_active_profile_data(self):
285
+ try:
286
+ _, active_profile = self.get_assistant_and_profile()
287
+ from higpertext.kernel.engine import HigpertextEngine
288
+
289
+ engine = HigpertextEngine(self.root_dir)
290
+ return engine.profiles.load_profile(active_profile)
291
+ except Exception:
292
+ return None
293
+
294
+ def _run_adapter_hook(self, assistant: str, hook_name: str, profile_name: str = "") -> None:
295
+ try:
296
+ import sys
297
+
298
+ if str(self.root_dir) not in sys.path:
299
+ sys.path.append(str(self.root_dir))
300
+ from higpertext.adapters.adapter_utils import get_adapter_class
301
+
302
+ adapter_cls = get_adapter_class(assistant)
303
+ if not (adapter_cls and hasattr(adapter_cls, hook_name)):
304
+ return
305
+ if hook_name == "on_session_start" and profile_name:
306
+ from higpertext.kernel.engine import HigpertextEngine
307
+
308
+ engine = HigpertextEngine(self.root_dir)
309
+ context = engine.get_agent_context(profile_name)
310
+ if context:
311
+ getattr(adapter_cls, hook_name)(context, self.project_root)
312
+ else:
313
+ getattr(adapter_cls, hook_name)(self.project_root)
314
+ except Exception as e:
315
+ _log.warning(f"[!] Error ejecutando {hook_name} para '{assistant}': {e}")
316
+
317
+ @classmethod
318
+ def _generate_workflow_base_md(cls, data, assistant="gemini", profile_model=None):
319
+ return MarkdownRenderer.generate_workflow_base_md(data, assistant, profile_model)
@@ -0,0 +1,21 @@
1
+ id: generic-shell
2
+ description: Alpine shell runner for simple local commands
3
+ services:
4
+ app:
5
+ image: alpine:3.20
6
+ working_dir: /workspace
7
+ volumes:
8
+ - .:/workspace
9
+ command: sleep infinity
10
+ tasks:
11
+ echo:
12
+ service: app
13
+ command: echo higpertext-env-ready
14
+ defaults:
15
+ service: app
16
+ task: echo
17
+ timeout_seconds: 120
18
+ cleanup: true
19
+ security:
20
+ network: isolated
21
+ privileged: false