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,44 @@
1
+ """Hook PreCompact — preserva estado higpertext crítico antes de compresión de contexto."""
2
+
3
+ from __future__ import annotations
4
+ from higpertext.hooks.hook_tasks._rules.context_rules import check_context_pressure
5
+ from higpertext.hooks.hook_tasks.hook_utils import get_project_root
6
+ import json
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ from higpertext.kernel.infrastructure.logger import get_logger
11
+ _log = get_logger()
12
+
13
+ _SRC = Path(__file__).resolve().parents[3] # src/
14
+ if str(_SRC) not in sys.path:
15
+ sys.path.insert(0, str(_SRC))
16
+
17
+
18
+ sys.path.insert(0, str(Path(__file__).parent))
19
+
20
+
21
+ def main() -> None:
22
+ try:
23
+ root = get_project_root()
24
+ result = check_context_pressure(root)
25
+ if result.severity == "context":
26
+ print(
27
+ json.dumps(
28
+ {
29
+ "continue": True,
30
+ "hookSpecificOutput": {
31
+ "hookEventName": "PreCompact",
32
+ "additionalContext": result.message,
33
+ },
34
+ }
35
+ )
36
+ )
37
+ else:
38
+ print(json.dumps({"continue": True}))
39
+ except Exception as exc:
40
+ print(json.dumps({"continue": True, "error": str(exc)}))
41
+
42
+
43
+ if __name__ == "__main__":
44
+ main()
@@ -0,0 +1,122 @@
1
+ """Protocolo I/O centralizado para hook tasks de higpertext.
2
+
3
+ Single source of truth para:
4
+ - Leer el payload de stdin (read_payload, read_tool_command)
5
+ - Leer archivos JSON del disco (read_json_file)
6
+ - Emitir respuestas JSON al runtime del asistente
7
+ (emit_continue, emit_context, emit_block, emit_stop_reason)
8
+ - Whitelist cross-platform de comandos permitidos (WHITELIST)
9
+ - Directorios de skills/subagentes por asistente (SKILL_DIRS, AGENT_DIRS)
10
+ - Decorador @hook_main que envuelve cualquier main() con manejo de errores
11
+ """
12
+
13
+ from __future__ import annotations
14
+ from typing import Callable
15
+ import functools
16
+ import json
17
+ import re
18
+ import sys
19
+ from pathlib import Path
20
+
21
+ _SRC = Path(__file__).resolve().parents[3] # src/
22
+ if str(_SRC) not in sys.path:
23
+ sys.path.insert(0, str(_SRC))
24
+
25
+
26
+ # Directorios efímeros de sesión por asistente — single source para todos los hooks
27
+ SKILL_DIRS: dict[str, str] = {
28
+ "claude": ".claude/skills",
29
+ "gemini": ".gemini/skills",
30
+ "antigravity": ".agents/skills",
31
+ "opencode": ".opencode/skills",
32
+ "copilot": ".github/skills",
33
+ }
34
+
35
+ AGENT_DIRS: dict[str, str] = {
36
+ "claude": ".claude/subagents",
37
+ "gemini": ".gemini/subagents",
38
+ "antigravity": ".agents/subagents",
39
+ "opencode": ".opencode/subagents",
40
+ "copilot": ".github/subagents",
41
+ }
42
+
43
+ # Single source: permite htx.py directo o venv en Linux/Windows
44
+ WHITELIST = re.compile(r"python htx\.py|\.venv[/\\](bin|Scripts)[/\\]python")
45
+
46
+
47
+ def read_json_file(path: Path) -> dict:
48
+ """Lee y parsea un archivo JSON del disco. Retorna {} ante cualquier error."""
49
+ try:
50
+ return json.loads(path.read_text(encoding="utf-8"))
51
+ except (OSError, json.JSONDecodeError):
52
+ return {}
53
+
54
+
55
+ def read_payload() -> dict:
56
+ """Lee y parsea el JSON de stdin. Retorna {} ante cualquier error."""
57
+ try:
58
+ return json.load(sys.stdin)
59
+ except (json.JSONDecodeError, ValueError, EOFError):
60
+ return {}
61
+
62
+
63
+ def read_tool_command(payload: dict) -> str:
64
+ """Extrae el comando de tool_input, con fallback a CommandLine (PowerShell)."""
65
+ tool_input = payload.get("tool_input", {})
66
+ return tool_input.get("command") or tool_input.get("CommandLine") or ""
67
+
68
+
69
+ def emit_continue(error: str = "") -> None:
70
+ """Emite continue:True, opcionalmente con campo error."""
71
+ out: dict = {"continue": True}
72
+ if error:
73
+ out["error"] = error
74
+ print(json.dumps(out))
75
+
76
+
77
+ def emit_context(event: str, text: str) -> None:
78
+ """Emite continue:True con additionalContext (hook informativo)."""
79
+ print(
80
+ json.dumps(
81
+ {
82
+ "continue": True,
83
+ "hookSpecificOutput": {
84
+ "hookEventName": event,
85
+ "additionalContext": text,
86
+ },
87
+ }
88
+ )
89
+ )
90
+
91
+
92
+ def emit_block(event: str, text: str) -> None:
93
+ """Emite continue:False bloqueando la herramienta (hard block)."""
94
+ print(
95
+ json.dumps(
96
+ {
97
+ "continue": False,
98
+ "hookSpecificOutput": {
99
+ "hookEventName": event,
100
+ "additionalContext": text,
101
+ },
102
+ }
103
+ )
104
+ )
105
+
106
+
107
+ def emit_stop_reason(text: str) -> None:
108
+ """Emite continue:True con stopReason para el evento Stop."""
109
+ print(json.dumps({"continue": True, "stopReason": text}))
110
+
111
+
112
+ def hook_main(fn: Callable) -> Callable:
113
+ """Decorador que envuelve main() capturando excepciones → emit_continue+error."""
114
+
115
+ @functools.wraps(fn)
116
+ def wrapper(*args, **kwargs):
117
+ try:
118
+ fn(*args, **kwargs)
119
+ except Exception as exc:
120
+ emit_continue(str(exc))
121
+
122
+ return wrapper
@@ -0,0 +1,182 @@
1
+ """Hook PostToolUse + UserPromptSubmit — detección de bucle LLM en tiempo de ejecución.
2
+
3
+ Detecta dos síntomas de repetition-collapse:
4
+
5
+ 1. **Repetición de tool_input** (PostToolUse): el agente invocó exactamente la misma
6
+ herramienta con exactamente los mismos parámetros N veces consecutivas sin éxito.
7
+ → emit_block al 3er intento idéntico.
8
+
9
+ 2. **Saturación de contexto** (PostToolUse): la respuesta de una herramienta supera
10
+ LARGE_OUTPUT_CHARS caracteres (dump masivo de error o archivo completo).
11
+ → emit_context con aviso al modelo para que no re-emita el blob.
12
+
13
+ El estado de repetición se persiste en .higpertext/state/loop_guard.json dentro de la
14
+ sesión activa, de modo que sobrevive entre turnos del mismo asistente.
15
+ """
16
+
17
+ from __future__ import annotations
18
+ import higpertext.hooks.hook_tasks.telemetry_utils as telem
19
+ from higpertext.hooks.hook_tasks.hook_utils import get_project_root
20
+ from higpertext.hooks.hook_tasks.hook_io import (
21
+ emit_block,
22
+ emit_context,
23
+ emit_continue,
24
+ hook_main,
25
+ read_json_file,
26
+ )
27
+
28
+ import hashlib
29
+ import json
30
+ import sys
31
+ from pathlib import Path
32
+
33
+ _SRC = Path(__file__).resolve().parents[3] # src/
34
+ if str(_SRC) not in sys.path:
35
+ sys.path.insert(0, str(_SRC))
36
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
37
+ from higpertext.kernel.app_config import IGNORE_TOOLS as _IGNORE_TOOLS
38
+ from higpertext.kernel.infrastructure.logger import render_box
39
+
40
+ MAX_IDENTICAL = 3
41
+ LARGE_OUTPUT_CHARS = 8_000
42
+
43
+
44
+ def _state_path(root: Path) -> Path:
45
+ return root / WORKSPACE_DIR_NAME / "state" / "loop_guard.json"
46
+
47
+
48
+ def _load_state(root: Path) -> dict:
49
+ return read_json_file(_state_path(root))
50
+
51
+
52
+ def _save_state(root: Path, state: dict) -> None:
53
+ try:
54
+ _state_path(root).write_text(
55
+ json.dumps(state, ensure_ascii=False, indent=2), encoding="utf-8"
56
+ )
57
+ except OSError: # nosec B110
58
+ pass
59
+
60
+
61
+ def _tool_fingerprint(tool_name: str, tool_input: dict) -> str:
62
+ """Hash determinista del par (herramienta, parámetros)."""
63
+ raw = json.dumps({"t": tool_name, "i": tool_input}, sort_keys=True, ensure_ascii=False)
64
+ return hashlib.sha1(raw.encode()).hexdigest()[:16] # nosec B324
65
+
66
+
67
+ def _session_id(root: Path) -> str:
68
+ try:
69
+ data = json.loads(
70
+ (root / WORKSPACE_DIR_NAME / "state" / "session.json").read_text(encoding="utf-8")
71
+ )
72
+ return data.get("session_id", "unknown")
73
+ except (OSError, json.JSONDecodeError):
74
+ return "unknown"
75
+
76
+
77
+ def _handle_post_tool(root: Path, payload: dict) -> None:
78
+ tool_name = payload.get("tool_name", "")
79
+ tool_input = payload.get("tool_input", {}) or {}
80
+ tool_response = payload.get("tool_response", {}) or {}
81
+
82
+ if tool_name in _IGNORE_TOOLS:
83
+ emit_continue()
84
+ return
85
+
86
+ sid = _session_id(root)
87
+ state = _load_state(root)
88
+ fp = _tool_fingerprint(tool_name, tool_input)
89
+
90
+ # ── Check 1: Repetición de invocaciones idénticas ──────────────────────
91
+ last_fp = state.get("last_fp", "")
92
+ count = state.get("repeat_count", 0)
93
+
94
+ if fp == last_fp:
95
+ count += 1
96
+ else:
97
+ count = 1
98
+
99
+ state["last_fp"] = fp
100
+ state["repeat_count"] = count
101
+ state["last_tool"] = tool_name
102
+ _save_state(root, state)
103
+
104
+ if count >= MAX_IDENTICAL:
105
+ telem.record(
106
+ root,
107
+ "loop_guard_block",
108
+ session_id=sid,
109
+ tool=tool_name,
110
+ repeat_count=count,
111
+ fingerprint=fp,
112
+ )
113
+ state["repeat_count"] = 0
114
+ _save_state(root, state)
115
+ emit_block(
116
+ "PostToolUse",
117
+ render_box("HIGPERTEXT · Loop Guard · REPETICIÓN BLOQUEADA", [
118
+ f"│ Herramienta : {tool_name}",
119
+ f"│ Intentos : {count} invocaciones idénticas consecutivas",
120
+ "│",
121
+ "│ El agente está en bucle. DEBES hacer UNA de estas acciones:",
122
+ "│ (a) Cambiar el enfoque — usa una capacidad higpertext diferente",
123
+ "│ (b) Preguntar al usuario qué archivo/comando confirmar",
124
+ "│ (c) Escribir [LOOP DETECTED] y detener la tarea",
125
+ ]),
126
+ )
127
+ return
128
+
129
+ # ── Check 2: Saturación de contexto por output masivo ──────────────────
130
+ output_str = json.dumps(tool_response, ensure_ascii=False)
131
+ if len(output_str) > LARGE_OUTPUT_CHARS:
132
+ telem.record(
133
+ root,
134
+ "loop_guard_large_output",
135
+ session_id=sid,
136
+ tool=tool_name,
137
+ output_chars=len(output_str),
138
+ )
139
+ emit_context(
140
+ "PostToolUse",
141
+ render_box("HIGPERTEXT · Loop Guard · OUTPUT MASIVO DETECTADO", [
142
+ f"│ Herramienta : {tool_name}",
143
+ f"│ Tamaño : {len(output_str):,} caracteres",
144
+ "│",
145
+ "│ INSTRUCCIÓN ANTI-LOOP:",
146
+ "│ • NO re-emitas este contenido en tu respuesta.",
147
+ "│ • Referencia el archivo/resultado solo por nombre.",
148
+ "│ • Extrae ÚNICAMENTE la primera línea de error significativa.",
149
+ "│ • Si necesitas reprocesar este output, usa una capacidad",
150
+ "│ higpertext específica (common.grep-search, common.knowledge-asker).",
151
+ ]),
152
+ )
153
+ return
154
+
155
+ emit_continue()
156
+
157
+
158
+ def _handle_user_prompt(root: Path) -> None:
159
+ """En cada nuevo prompt del usuario, reinicia el contador de repetición."""
160
+ state = _load_state(root)
161
+ if state.get("repeat_count", 0) > 0:
162
+ state["repeat_count"] = 0
163
+ state["last_fp"] = ""
164
+ _save_state(root, state)
165
+ emit_continue()
166
+
167
+
168
+ @hook_main
169
+ def main() -> None:
170
+ payload = json.load(sys.stdin)
171
+ root = get_project_root()
172
+
173
+ # El hook se registra para PostToolUse y UserPromptSubmit.
174
+ # Distinguimos por la presencia de tool_name.
175
+ if "tool_name" in payload:
176
+ _handle_post_tool(root, payload)
177
+ else:
178
+ _handle_user_prompt(root)
179
+
180
+
181
+ if __name__ == "__main__":
182
+ main()
@@ -0,0 +1,54 @@
1
+ """Hook PostToolUse — registra telemetría de tokens y actividad por tool call."""
2
+
3
+ from __future__ import annotations
4
+ from higpertext.hooks.hook_tasks._rules.context_rules import (
5
+ check_large_output,
6
+ check_window_pressure,
7
+ )
8
+ from higpertext.hooks.hook_tasks._rules.telemetry_rules import record_telemetry
9
+ from higpertext.hooks.hook_tasks.hook_utils import get_project_root
10
+ import json
11
+ import sys
12
+ from pathlib import Path
13
+
14
+ from higpertext.kernel.infrastructure.logger import get_logger
15
+ _log = get_logger()
16
+
17
+ _SRC = Path(__file__).resolve().parents[3] # src/
18
+ if str(_SRC) not in sys.path:
19
+ sys.path.insert(0, str(_SRC))
20
+
21
+
22
+ sys.path.insert(0, str(Path(__file__).parent))
23
+
24
+
25
+ def main() -> None:
26
+ try:
27
+ payload = json.load(sys.stdin)
28
+ root = get_project_root()
29
+ record_telemetry(payload, root)
30
+
31
+ large = check_large_output(payload)
32
+ pressure = check_window_pressure(payload, root)
33
+
34
+ extra_parts = [r.message for r in (large, pressure) if r is not None]
35
+ if extra_parts:
36
+ print(
37
+ json.dumps(
38
+ {
39
+ "continue": True,
40
+ "hookSpecificOutput": {
41
+ "hookEventName": "PostToolUse",
42
+ "additionalContext": "\n".join(extra_parts),
43
+ },
44
+ }
45
+ )
46
+ )
47
+ else:
48
+ print(json.dumps({"continue": True}))
49
+ except Exception as exc:
50
+ print(json.dumps({"continue": True, "error": str(exc)}))
51
+
52
+
53
+ if __name__ == "__main__":
54
+ main()
@@ -0,0 +1,85 @@
1
+ """Hook PreToolUse:Read — bloquea lecturas completas de archivos grandes."""
2
+
3
+ from __future__ import annotations
4
+ from higpertext.hooks.hook_tasks.hook_utils import get_project_root
5
+ from higpertext.hooks.hook_tasks.hook_io import (
6
+ hook_main,
7
+ read_payload,
8
+ emit_continue,
9
+ emit_block,
10
+ )
11
+
12
+ import os
13
+ import sys
14
+ from pathlib import Path
15
+
16
+ _SRC = Path(__file__).resolve().parents[3]
17
+ if str(_SRC) not in sys.path:
18
+ sys.path.insert(0, str(_SRC))
19
+
20
+
21
+ def _threshold_bytes() -> int:
22
+ try:
23
+ return int(os.environ.get("HIGPERTEXT_READ_GUARD_BYTES", str(100 * 1024)))
24
+ except ValueError:
25
+ return 100 * 1024
26
+
27
+
28
+ def _extract_path(tool_input: dict) -> str:
29
+ return (
30
+ tool_input.get("filePath")
31
+ or tool_input.get("filepath")
32
+ or tool_input.get("path")
33
+ or tool_input.get("file")
34
+ or ""
35
+ )
36
+
37
+
38
+ def _has_range(tool_input: dict) -> bool:
39
+ return any(
40
+ key in tool_input and tool_input.get(key) not in (None, "") for key in ("offset", "limit")
41
+ )
42
+
43
+
44
+ def evaluate_read_guard(tool_input: dict, root: Path) -> str:
45
+ """Devuelve mensaje de bloqueo o cadena vacía si la lectura es segura."""
46
+ raw_path = _extract_path(tool_input)
47
+ if not raw_path or _has_range(tool_input):
48
+ return ""
49
+ path = Path(raw_path)
50
+ if not path.is_absolute():
51
+ path = root / path
52
+ if not path.exists() or not path.is_file():
53
+ return ""
54
+ threshold = _threshold_bytes()
55
+ size = path.stat().st_size
56
+ if size <= threshold:
57
+ return ""
58
+ display = raw_path
59
+ return "\n".join(
60
+ [
61
+ "╔─ HIGPERTEXT · Bloqueo de Read masivo ───────────────────",
62
+ f"│ Archivo : {display} ({size / 1024:.1f} KB)",
63
+ f"│ Límite : {threshold / 1024:.1f} KB",
64
+ "│ ⚠ Evita leer el archivo completo para no saturar contexto.",
65
+ "│ → Usa lectura inteligente:",
66
+ f"│ htx task common.smart-read --path {display} --mode auto",
67
+ "│ → O inspecciona firmas:",
68
+ f"│ htx task common.code-skeletonizer --path {display}",
69
+ "╚────────────────────────────────────────────────────────────",
70
+ ]
71
+ )
72
+
73
+
74
+ @hook_main
75
+ def main() -> None:
76
+ payload = read_payload()
77
+ message = evaluate_read_guard(payload.get("tool_input", {}), get_project_root())
78
+ if message:
79
+ emit_block("PreToolUse", message)
80
+ return
81
+ emit_continue()
82
+
83
+
84
+ if __name__ == "__main__":
85
+ main()
@@ -0,0 +1,81 @@
1
+ """Hook común de seguridad para PreToolUse y PostToolUse."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ _SRC = Path(__file__).resolve().parents[3]
10
+ if str(_SRC) not in sys.path:
11
+ sys.path.insert(0, str(_SRC))
12
+
13
+ from higpertext.hooks.hook_tasks.hook_io import ( # noqa: E402
14
+ hook_main,
15
+ read_payload,
16
+ read_tool_command,
17
+ emit_block,
18
+ emit_context,
19
+ emit_continue,
20
+ )
21
+ from higpertext.hooks.hook_tasks.hook_utils import get_project_root # noqa: E402
22
+ from higpertext.hooks.hook_tasks._rules.security_rules import ( # noqa: E402
23
+ evaluate_command_guard,
24
+ evaluate_path_guard,
25
+ mask_tool_output,
26
+ )
27
+ from higpertext.kernel.infrastructure.logger import get_logger
28
+
29
+ _log = get_logger()
30
+
31
+
32
+ def _tool_name(payload: dict) -> str:
33
+ return str(payload.get("tool_name") or payload.get("tool") or "")
34
+
35
+
36
+ def _emit_masked_output(message: str, replacement_output: str) -> None:
37
+ print(
38
+ json.dumps(
39
+ {
40
+ "continue": True,
41
+ "hookSpecificOutput": {
42
+ "hookEventName": "PostToolUse",
43
+ "additionalContext": message,
44
+ "replacementOutput": replacement_output,
45
+ },
46
+ }
47
+ )
48
+ )
49
+
50
+
51
+ @hook_main
52
+ def main() -> None:
53
+ payload = read_payload()
54
+ event = payload.get("event", "PreToolUse")
55
+ tool_name = _tool_name(payload)
56
+ root = get_project_root()
57
+
58
+ if event == "PreToolUse":
59
+ if tool_name in {"Bash", "PowerShell"}:
60
+ result = evaluate_command_guard(read_tool_command(payload), root)
61
+ else:
62
+ result = evaluate_path_guard(tool_name, payload.get("tool_input", {}))
63
+ if result:
64
+ if result.severity == "warn":
65
+ emit_context("PreToolUse", result.message)
66
+ return
67
+ emit_block("PreToolUse", result.message)
68
+ return
69
+ emit_continue()
70
+ return
71
+
72
+ if event == "PostToolUse":
73
+ result = mask_tool_output(payload.get("tool_response", {}), root)
74
+ if result:
75
+ _emit_masked_output(result.message, result.replacement_output)
76
+ return
77
+ emit_continue()
78
+
79
+
80
+ if __name__ == "__main__":
81
+ main()
@@ -0,0 +1,83 @@
1
+ """Hook UserPromptSubmit — inyecta estado de sesión y contexto de skills activas."""
2
+
3
+ from __future__ import annotations
4
+ from higpertext.hooks.hook_tasks._rules.context_engine_rule import inject_context_pack
5
+ from higpertext.hooks.hook_tasks._rules.session_rules import (
6
+ auto_start_session,
7
+ reset_window_accumulator,
8
+ inject_session_status,
9
+ inject_skills_context,
10
+ handle_compact_command,
11
+ )
12
+ from higpertext.hooks.hook_tasks.hook_io import read_payload
13
+ from higpertext.hooks.hook_tasks.hook_utils import get_project_root
14
+ import json
15
+ import sys
16
+ from pathlib import Path
17
+
18
+ _SRC = Path(__file__).resolve().parents[3] # src/
19
+ if str(_SRC) not in sys.path:
20
+ sys.path.insert(0, str(_SRC))
21
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
22
+
23
+ from higpertext.kernel.infrastructure.logger import get_logger
24
+ _log = get_logger()
25
+
26
+
27
+ def _emit_hook_context(message: str) -> None:
28
+ print(
29
+ json.dumps(
30
+ {
31
+ "continue": True,
32
+ "hookSpecificOutput": {
33
+ "hookEventName": "UserPromptSubmit",
34
+ "additionalContext": message,
35
+ },
36
+ }
37
+ )
38
+ )
39
+
40
+
41
+ def _handle_slash_commands(root: Path, prompt: str) -> bool:
42
+ if prompt == "/compact" or prompt.startswith("/compact "):
43
+ _emit_hook_context(handle_compact_command(root).message)
44
+ return True
45
+ return False
46
+
47
+
48
+ def _ensure_active_session(root: Path) -> None:
49
+ session_file = root / WORKSPACE_DIR_NAME / "state" / "session.json"
50
+ session = json.loads(session_file.read_text(encoding="utf-8")) if session_file.exists() else {}
51
+ if session.get("status") != "active":
52
+ auto_start_session(root)
53
+
54
+
55
+ def _build_context(root: Path, prompt: str) -> str:
56
+ reset_window_accumulator(root)
57
+ parts = [inject_session_status(root).message]
58
+ ctx = inject_skills_context(root)
59
+ if ctx and ctx.message:
60
+ parts.append(ctx.message)
61
+ pack = inject_context_pack(root, prompt)
62
+ if pack and pack.message:
63
+ parts.append(pack.message)
64
+ return "\n".join(parts)
65
+
66
+
67
+ def main() -> None:
68
+ try:
69
+ root = get_project_root()
70
+ payload = read_payload()
71
+ prompt = (payload.get("prompt", "") or payload.get("user_prompt", "") or "").strip().lower()
72
+
73
+ if _handle_slash_commands(root, prompt):
74
+ return
75
+
76
+ _ensure_active_session(root)
77
+ _emit_hook_context(_build_context(root, prompt))
78
+ except Exception as exc:
79
+ print(json.dumps({"continue": True, "error": str(exc)}))
80
+
81
+
82
+ if __name__ == "__main__":
83
+ main()