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,316 @@
1
+ """Reglas de sesión para UserPromptSubmit.
2
+
3
+ Inyecta estado de sesión y contexto de skills activas en cada prompt.
4
+ """
5
+
6
+ from __future__ import annotations
7
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
8
+ import json
9
+ import platform
10
+ import shutil
11
+ # Auto-start usa lista de argumentos sin shell.
12
+ import subprocess # nosec B404
13
+ from dataclasses import dataclass
14
+ from pathlib import Path
15
+ from typing import Literal
16
+
17
+ from higpertext.kernel.infrastructure.logger import get_logger
18
+
19
+ _log = get_logger()
20
+
21
+ try:
22
+ from higpertext.kernel.htx_resolver import get_htx_cmd
23
+ except ImportError:
24
+ get_htx_cmd = None
25
+
26
+ try:
27
+ from higpertext.kernel.domain.context_engine import reset_window_state
28
+ except ImportError:
29
+ reset_window_state = None
30
+
31
+ try:
32
+ import higpertext.hooks.hook_tasks.telemetry_utils as telem
33
+ except ImportError:
34
+ telem = None
35
+
36
+ from higpertext.kernel.app_config import (
37
+ ENVIRONMENT_FILE as _ENVIRONMENT_JSON,
38
+ SESSION_FILE as _SESSION_JSON,
39
+ SKILL_DIRS as _SKILL_DIRS,
40
+ AGENT_DIRS as _AGENT_DIRS,
41
+ )
42
+ RuleSeverity = Literal["continue", "context", "block"]
43
+
44
+
45
+ @dataclass
46
+ class RuleResult:
47
+ severity: RuleSeverity
48
+ message: str = ""
49
+
50
+
51
+ # ── Auto-inicio de sesión ─────────────────────────────────────────────────────
52
+
53
+
54
+ def _get_htx(root: Path) -> list[str]:
55
+ if get_htx_cmd is not None:
56
+ try:
57
+ return get_htx_cmd(root)
58
+ except Exception as exc:
59
+ _log.warning(f"[session] No se pudo resolver htx desde config: {exc}")
60
+
61
+ venv_htx = root / ".venv" / ("Scripts" if platform.system() == "Windows" else "bin") / "htx"
62
+ if venv_htx.exists():
63
+ return [str(venv_htx)]
64
+ if htx := shutil.which("htx"):
65
+ return [htx]
66
+ return [str(root / ".venv" / "bin" / "python"), str(root / "htx.py")]
67
+
68
+
69
+ def auto_start_session(root: Path) -> None:
70
+ """Inicia sesión automáticamente si no hay una activa."""
71
+ env = _read_json(root / WORKSPACE_DIR_NAME / "config" / _ENVIRONMENT_JSON)
72
+ profile = env.get("active_profile", "software_developer")
73
+ cmd = _get_htx(root) + [
74
+ "task",
75
+ "common.session-start",
76
+ "--action",
77
+ "start",
78
+ "--profile",
79
+ profile,
80
+ ]
81
+ try:
82
+ subprocess.run(cmd, cwd=str(root), timeout=20, capture_output=True) # nosec B603
83
+ except (OSError, subprocess.SubprocessError) as exc:
84
+ _log.warning(f"[session] Auto-start omitido: {exc}")
85
+
86
+
87
+ # ── Reset de ventana de contexto por turno ──────────────────────────────────
88
+
89
+
90
+ def reset_window_accumulator(root: Path) -> None:
91
+ """Reinicia el acumulador de tokens de la ventana para el nuevo turno."""
92
+ if reset_window_state is not None:
93
+ try:
94
+ reset_window_state(root)
95
+ except Exception as exc:
96
+ _log.warning(f"[session] No se pudo reiniciar window accumulator: {exc}")
97
+
98
+
99
+ # ── Regla 1: Estado de sesión (session_start) ─────────────────────────────────
100
+
101
+
102
+ def inject_session_status(root: Path) -> RuleResult:
103
+ session = _read_json(root / WORKSPACE_DIR_NAME / "state" / _SESSION_JSON)
104
+ env = _read_json(root / WORKSPACE_DIR_NAME / "config" / _ENVIRONMENT_JSON)
105
+ profile = env.get("active_profile", "global")
106
+ asst = env.get("assistant", "claude")
107
+ active = session.get("status") == "active"
108
+ sid = session.get("session_id", "—")
109
+
110
+ if active and not _already_recorded(root, sid):
111
+ if telem is not None:
112
+ telem.session_start(root, sid, profile)
113
+ reset_window_accumulator(root)
114
+
115
+ if not active:
116
+ available = _available_skills(root, profile)
117
+ skills_hint = f"Skills disponibles : {', '.join(available)}" if available else ""
118
+ lines = [
119
+ "╔─ HIGPERTEXT · Sin sesión activa ────────────────────────",
120
+ f"│ Perfil : {profile}",
121
+ ]
122
+ if skills_hint:
123
+ lines.append(f"│ {skills_hint}")
124
+ lines += [
125
+ f"│ → htx task common.session-start --profile {profile}",
126
+ "╚──────────────────────────────────────────────────────",
127
+ ]
128
+ return RuleResult(severity="context", message="\n".join(lines))
129
+
130
+ skills = _list_dir_names(root / _SKILL_DIRS.get(asst, ".claude/skills"))
131
+ subagents = _list_dir_names(root / _AGENT_DIRS.get(asst, ".claude/subagents"), "*.md")
132
+ lines = [
133
+ "╔─ HIGPERTEXT · Sesión activa ─────────────────────────────",
134
+ f"│ {sid} · perfil: {profile}",
135
+ f"│ Skills : {', '.join(skills) or '—'}",
136
+ f"│ Subagentes : {', '.join(subagents) or '—'}",
137
+ "╚───────────────────────────────────────────────────────",
138
+ ]
139
+
140
+ workflows = _available_workflows(root, profile)
141
+ if workflows:
142
+ wf_lines = ["╔─ HIGPERTEXT · Workflows del perfil ──────────────────────"]
143
+ for wf in workflows:
144
+ wf_lines.append(f"│ [{wf['id']}]")
145
+ wf_lines.append(f"│ Cuándo : {wf.get('when', '—')}")
146
+ wf_lines.append(f"│ Comando: {wf.get('command', '—')}")
147
+ wf_lines.append("╚───────────────────────────────────────────────────────")
148
+ lines.append("\n".join(wf_lines))
149
+
150
+ learned = _load_learned_profile(root)
151
+ profile_block = _render_profile_block(learned)
152
+ if profile_block:
153
+ lines.append(profile_block)
154
+
155
+ return RuleResult(severity="context", message="\n".join(lines))
156
+
157
+
158
+ # ── Regla 2: Contexto de skills activas (session_context) ────────────────────
159
+
160
+
161
+ def inject_skills_context(root: Path) -> RuleResult | None:
162
+ session = _read_json(root / WORKSPACE_DIR_NAME / "state" / _SESSION_JSON)
163
+ env = _read_json(root / WORKSPACE_DIR_NAME / "config" / _ENVIRONMENT_JSON)
164
+
165
+ if session.get("status") != "active":
166
+ return None
167
+
168
+ asst = env.get("assistant", "claude")
169
+ sid = session.get("session_id", "—")
170
+ skills_dir = root / _SKILL_DIRS.get(asst, ".claude/skills")
171
+
172
+ skill_entries: list[tuple[str, str]] = []
173
+ if skills_dir.exists():
174
+ for d in sorted(skills_dir.iterdir()):
175
+ if d.is_dir():
176
+ summary = _skill_summary(d)
177
+ skill_entries.append((d.name, summary))
178
+
179
+ if not skill_entries:
180
+ return None
181
+
182
+ lines = [f"╔─ HIGPERTEXT · Contexto de sesión · {sid} ─────────────"]
183
+ lines.append("│ Skills activas:")
184
+ for name, summary in skill_entries:
185
+ desc = f" {summary}" if summary else ""
186
+ lines.append(f"│ • {name}{desc}")
187
+ lines.append("╚───────────────────────────────────────────────────────")
188
+
189
+ return RuleResult(severity="context", message="\n".join(lines))
190
+
191
+
192
+ # ── Helpers ───────────────────────────────────────────────────────────────────
193
+
194
+
195
+ def _read_json(path: Path) -> dict:
196
+ try:
197
+ return json.loads(path.read_text(encoding="utf-8"))
198
+ except (OSError, json.JSONDecodeError):
199
+ return {}
200
+
201
+
202
+ def _list_dir_names(path: Path, glob: str = "*") -> list[str]:
203
+ if not path.exists():
204
+ return []
205
+ if glob == "*.md":
206
+ return sorted(f.stem for f in path.glob(glob))
207
+ return sorted(d.name for d in path.iterdir() if d.is_dir())
208
+
209
+
210
+ def _available_skills(root: Path, profile: str) -> list[str]:
211
+ data = _read_json(root / "src" / "config" / "profiles" / f"{profile}.json")
212
+ return data.get("session_skills", [])
213
+
214
+
215
+ def _available_workflows(root: Path, profile: str) -> list[dict]:
216
+ data = _read_json(root / "src" / "config" / "profiles" / f"{profile}.json")
217
+ return data.get("workflows", [])
218
+
219
+
220
+ def _already_recorded(root: Path, session_id: str) -> bool:
221
+ store = root / WORKSPACE_DIR_NAME / "state" / "telemetry.jsonl"
222
+ if not store.exists():
223
+ return False
224
+ try:
225
+ for line in store.read_text(encoding="utf-8").splitlines():
226
+ try:
227
+ e = json.loads(line)
228
+ if e.get("event") == "session_start" and e.get("session_id") == session_id:
229
+ return True
230
+ except (json.JSONDecodeError, TypeError):
231
+ continue
232
+ except OSError:
233
+ pass
234
+ return False
235
+
236
+
237
+ def _load_learned_profile(root: Path) -> dict:
238
+ return _read_json(root / WORKSPACE_DIR_NAME / "state" / "learned_profile.json")
239
+
240
+
241
+ def _render_profile_block(profile: dict) -> str | None:
242
+ if not profile:
243
+ return None
244
+ strong = ", ".join(profile.get("strong_patterns", [])[:3]) or "—"
245
+ weak = ", ".join(profile.get("weak_patterns", [])[:3]) or "—"
246
+ adoption = profile.get("higpertext_adoption_trend", 0)
247
+ topics = ", ".join(profile.get("commit_topics", [])[:4]) or "—"
248
+ best = profile.get("best_session_pattern", "—")
249
+ cost = profile.get("cost_per_commit_avg", 0.0)
250
+ return "\n".join(
251
+ [
252
+ "╔─ HIGPERTEXT · Perfil aprendido ──────────────────────────",
253
+ f"│ Fortalezas : {strong}",
254
+ f"│ Debilidades : {weak}",
255
+ f"│ Adopción prom : {adoption}%",
256
+ f"│ Temas commits : {topics}",
257
+ f"│ Mejor patrón : {best}",
258
+ f"│ Costo/commit : ${cost:.4f} USD",
259
+ "╚───────────────────────────────────────────────────────",
260
+ ]
261
+ )
262
+
263
+
264
+ def _skill_summary(skill_dir: Path) -> str:
265
+ md = skill_dir / "SKILL.md"
266
+ if not md.exists():
267
+ return ""
268
+ try:
269
+ for line in md.read_text(encoding="utf-8").splitlines()[1:]:
270
+ s = line.strip()
271
+ if s and not s.startswith("#"):
272
+ return s[:90]
273
+ except OSError: # nosec B110
274
+ pass
275
+ return ""
276
+
277
+
278
+ def handle_compact_command(root: Path) -> RuleResult:
279
+ """Genera el reporte de compactación y avisa de resetear el chat."""
280
+ session = _read_json(root / WORKSPACE_DIR_NAME / "state" / _SESSION_JSON)
281
+ env = _read_json(root / WORKSPACE_DIR_NAME / "config" / _ENVIRONMENT_JSON)
282
+ sid = session.get("session_id", "—")
283
+ profile = env.get("active_profile", "—")
284
+
285
+ changed_files = []
286
+ git_path = shutil.which("git") or "git"
287
+ try:
288
+ r = subprocess.run(
289
+ [git_path, "status", "--porcelain"], # nosec B603 B607
290
+ capture_output=True,
291
+ text=True,
292
+ cwd=str(root),
293
+ timeout=5,
294
+ )
295
+ changed_files = [line[3:].strip() for line in r.stdout.splitlines() if line.strip()]
296
+ except (OSError, subprocess.SubprocessError):
297
+ pass
298
+
299
+ files_str = ", ".join(changed_files[:5]) or "Ninguno"
300
+ if len(changed_files) > 5:
301
+ files_str += f" y {len(changed_files) - 5} más"
302
+
303
+ msg = "\n".join(
304
+ [
305
+ "╔─ HIGPERTEXT · Checkpoint de Compactación ──────────────",
306
+ f"│ Sesión Activa: {sid} ({profile})",
307
+ f"│ Archivos Modificados: {files_str}",
308
+ "│",
309
+ "│ ⚠ ¡REQUERIDO!: Guarda/actualiza acuerdos y estado clave",
310
+ "│ en '.memory/context.md' (o similar) antes de continuar.",
311
+ "│ → Una vez guardado, escribe '/clear' o usa el botón de",
312
+ "│ reseteo del chat para vaciar el historial redundante.",
313
+ "╚───────────────────────────────────────────────────────",
314
+ ]
315
+ )
316
+ return RuleResult(severity="context", message=msg)
@@ -0,0 +1,121 @@
1
+ """Reglas de observabilidad para tool calls (PostToolUse).
2
+
3
+ Registra telemetría de tokens y actividad. Sin efectos de bloqueo.
4
+ """
5
+
6
+ from __future__ import annotations
7
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
8
+ import json
9
+ import os
10
+ from dataclasses import dataclass
11
+ from pathlib import Path
12
+ from typing import Literal
13
+
14
+ RuleSeverity = Literal["continue", "context", "block"]
15
+
16
+
17
+ @dataclass
18
+ class RuleResult:
19
+ severity: RuleSeverity
20
+ message: str = ""
21
+
22
+
23
+ # ── Regla 1: Registro de telemetría de tokens ─────────────────────────────────
24
+
25
+
26
+ def record_telemetry(payload: dict, root: Path) -> RuleResult:
27
+ import higpertext.hooks.hook_tasks.telemetry_utils as telem
28
+
29
+ session = _read_json(root / WORKSPACE_DIR_NAME / "state" / "session.json")
30
+ sid = session.get("session_id", "unknown")
31
+
32
+ tool_name = payload.get("tool_name", "unknown")
33
+ tool_input = payload.get("tool_input", {})
34
+ tool_response = payload.get("tool_response", {})
35
+
36
+ input_str = json.dumps(tool_input, ensure_ascii=False)
37
+ output_str = json.dumps(tool_response, ensure_ascii=False)
38
+
39
+ cmd = (
40
+ (tool_input.get("command") or tool_input.get("CommandLine") or "")
41
+ if isinstance(tool_input, dict)
42
+ else ""
43
+ )
44
+ is_higpertext_call = "htx.py" in cmd and "task" in cmd
45
+
46
+ telem.tool_call(
47
+ root,
48
+ session_id=sid,
49
+ tool_name=tool_name,
50
+ input_chars=len(input_str),
51
+ output_chars=len(output_str),
52
+ is_higpertext_call=is_higpertext_call,
53
+ )
54
+
55
+ op_type, target, scope = _extract_activity(tool_name, tool_input, is_higpertext_call)
56
+ if op_type:
57
+ telem.activity(
58
+ root,
59
+ session_id=sid,
60
+ tool=tool_name,
61
+ op_type=op_type,
62
+ target=target,
63
+ scope=scope,
64
+ higpertext_related=is_higpertext_call,
65
+ )
66
+
67
+ return RuleResult(severity="continue")
68
+
69
+
70
+ # ── Helpers ───────────────────────────────────────────────────────────────────
71
+
72
+
73
+ def _rel(path_str: str) -> str:
74
+ try:
75
+ return str(Path(path_str).relative_to(os.getcwd()))
76
+ except ValueError:
77
+ return Path(path_str).name
78
+
79
+
80
+ def _extract_activity(
81
+ tool: str, tool_input: dict, is_higpertext_call: bool
82
+ ) -> tuple[str, str, str]:
83
+ if not isinstance(tool_input, dict):
84
+ return "", "", ""
85
+
86
+ if tool == "Edit":
87
+ rel = _rel(tool_input.get("file_path", ""))
88
+ return "code-change", rel, str(Path(rel).parent)
89
+
90
+ if tool == "Write":
91
+ rel = _rel(tool_input.get("file_path", ""))
92
+ return "new-file", rel, str(Path(rel).parent)
93
+
94
+ if tool == "Read":
95
+ rel = _rel(tool_input.get("file_path", ""))
96
+ return "file-read", rel, str(Path(rel).parent)
97
+
98
+ if tool in ("Bash", "PowerShell"):
99
+ cmd = (tool_input.get("command") or tool_input.get("CommandLine") or "")[:100]
100
+ if is_higpertext_call:
101
+ parts = cmd.split()
102
+ try:
103
+ idx = parts.index("task")
104
+ cap = parts[idx + 1] if idx + 1 < len(parts) else cmd
105
+ except ValueError:
106
+ cap = cmd
107
+ return "higpertext-task", cap, "higpertext"
108
+ return "bash-cmd", cmd, "bash"
109
+
110
+ if tool == "Skill":
111
+ skill = tool_input.get("skill", tool_input.get("name", "unknown"))
112
+ return "skill-invoked", skill, "skill"
113
+
114
+ return "", "", ""
115
+
116
+
117
+ def _read_json(path: Path) -> dict:
118
+ try:
119
+ return json.loads(path.read_text(encoding="utf-8"))
120
+ except (OSError, json.JSONDecodeError):
121
+ return {}
@@ -0,0 +1,28 @@
1
+ """Hook PostToolUse — registra cada tool use en .higpertext/audit.log."""
2
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
3
+
4
+ import sys
5
+ import json
6
+ import datetime
7
+ from higpertext.hooks.hook_tasks.hook_utils import get_project_root
8
+
9
+
10
+ def main() -> None:
11
+ data = json.load(sys.stdin)
12
+ tool_name = data.get("tool_name", "unknown")
13
+ session_id = data.get("session_id", "")
14
+ timestamp = datetime.datetime.now(datetime.timezone.utc).isoformat()
15
+
16
+ log_dir = get_project_root() / WORKSPACE_DIR_NAME
17
+ log_dir.mkdir(parents=True, exist_ok=True)
18
+ log_file = log_dir / "audit.log"
19
+
20
+ entry = json.dumps({"ts": timestamp, "tool": tool_name, "session": session_id})
21
+ with log_file.open("a", encoding="utf-8") as f:
22
+ f.write(entry + "\n")
23
+
24
+ print(json.dumps({"continue": True}))
25
+
26
+
27
+ if __name__ == "__main__":
28
+ main()
@@ -0,0 +1,101 @@
1
+ """Hook PreToolUse:Bash — evalúa todas las reglas de comandos Bash en cadena."""
2
+
3
+ from __future__ import annotations
4
+ from higpertext.hooks.hook_tasks._rules.bash_rules import (
5
+ RuleResult,
6
+ is_whitelisted,
7
+ check_git_commit_block,
8
+ check_hard_blocks,
9
+ check_branch_protection,
10
+ check_deployment_gate,
11
+ check_ls_redirect,
12
+ check_grep_redirect,
13
+ check_git_redirect,
14
+ check_knowledge_redirect,
15
+ check_large_file_read_redirect,
16
+ check_list_rules,
17
+ check_load_rules,
18
+ check_exit_guard,
19
+ check_higpertext_enforcer,
20
+ check_profile_rules,
21
+ )
22
+ import higpertext.hooks.hook_tasks.telemetry_utils as telem
23
+ from higpertext.hooks.hook_tasks.hook_utils import get_project_root
24
+ from higpertext.hooks.hook_tasks.hook_io import (
25
+ hook_main,
26
+ read_payload,
27
+ read_tool_command,
28
+ emit_continue,
29
+ emit_context,
30
+ emit_block,
31
+ )
32
+ import sys
33
+ from pathlib import Path
34
+
35
+ _SRC = Path(__file__).resolve().parents[3] # src/
36
+ if str(_SRC) not in sys.path:
37
+ sys.path.insert(0, str(_SRC))
38
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
39
+
40
+
41
+ sys.path.insert(0, str(Path(__file__).parent))
42
+
43
+ _RULES = [
44
+ check_git_commit_block,
45
+ check_hard_blocks,
46
+ check_branch_protection,
47
+ check_deployment_gate,
48
+ check_ls_redirect,
49
+ check_grep_redirect,
50
+ check_git_redirect,
51
+ check_knowledge_redirect,
52
+ check_large_file_read_redirect,
53
+ check_list_rules,
54
+ check_load_rules,
55
+ check_exit_guard,
56
+ check_higpertext_enforcer,
57
+ check_profile_rules,
58
+ ]
59
+
60
+
61
+ @hook_main
62
+ def main() -> None:
63
+ payload = read_payload()
64
+ cmd = read_tool_command(payload)
65
+
66
+ if is_whitelisted(cmd):
67
+ emit_continue()
68
+ return
69
+
70
+ root = get_project_root()
71
+ session_data = {}
72
+ try:
73
+ import json
74
+
75
+ session_data = json.loads(
76
+ (root / WORKSPACE_DIR_NAME / "state" / "session.json").read_text(encoding="utf-8")
77
+ )
78
+ except Exception: # nosec B110
79
+ pass
80
+ sid = session_data.get("session_id", "unknown")
81
+
82
+ for rule_fn in _RULES:
83
+ result: RuleResult | None = rule_fn(cmd, root)
84
+ if result is None:
85
+ continue
86
+
87
+ if result.severity == "block":
88
+ telem.hook_intercept(root, sid, result.capability or "BLOCKED", cmd)
89
+ emit_block("PreToolUse", result.message)
90
+ return
91
+
92
+ if result.severity == "context":
93
+ telem.hook_intercept(root, sid, result.capability or "context", cmd)
94
+ emit_context("PreToolUse", result.message)
95
+ return
96
+
97
+ emit_continue()
98
+
99
+
100
+ if __name__ == "__main__":
101
+ main()
@@ -0,0 +1,48 @@
1
+ """Hook PreToolUse:Write|Edit — evalúa calidad de código Python antes de escribir."""
2
+
3
+ from __future__ import annotations
4
+ from higpertext.hooks.hook_tasks._rules.quality_rules import (
5
+ check_code_length,
6
+ is_python_file,
7
+ )
8
+ from higpertext.hooks.hook_tasks.hook_utils import get_project_root
9
+ from higpertext.hooks.hook_tasks.hook_io import (
10
+ hook_main,
11
+ read_payload,
12
+ emit_continue,
13
+ emit_context,
14
+ )
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
+
22
+
23
+ sys.path.insert(0, str(Path(__file__).parent))
24
+
25
+
26
+ @hook_main
27
+ def main() -> None:
28
+ payload = read_payload()
29
+ tool_name = payload.get("tool_name", "")
30
+ tool_input = payload.get("tool_input", {})
31
+
32
+ file_path = tool_input.get("file_path", "") or tool_input.get("path", "")
33
+ if tool_name not in ("Write", "Edit") or not is_python_file(file_path):
34
+ emit_continue()
35
+ return
36
+
37
+ root = get_project_root()
38
+ result = check_code_length(file_path, root)
39
+
40
+ if result is None:
41
+ emit_continue()
42
+ return
43
+
44
+ emit_context("PreToolUse", result.message)
45
+
46
+
47
+ if __name__ == "__main__":
48
+ main()
@@ -0,0 +1,46 @@
1
+ """Hook UserPromptSubmit — sugiere context-assembler ante prompts de tarea.
2
+
3
+ Entrega híbrida (parte ligera): detecta verbos de tarea e inyecta un índice
4
+ de pocas líneas. El agente decide invocar la capability pesada si lo necesita.
5
+ """
6
+
7
+ from __future__ import annotations
8
+ import re
9
+ from higpertext.hooks.hook_tasks.hook_io import (
10
+ hook_main,
11
+ read_payload,
12
+ emit_continue,
13
+ emit_context,
14
+ )
15
+
16
+ # Verbos que indican una tarea de ingeniería sobre el código.
17
+ _TASK_VERBS = re.compile(
18
+ r"\b(refactoriz\w*|implement\w*|arregl\w*|corrig\w*|migr\w*|"
19
+ r"optimiz\w*|reestructur\w*|añad\w*|agreg\w*|crea\w+|"
20
+ r"refactor|implement|fix|bugfix|build|add)\b",
21
+ re.IGNORECASE,
22
+ )
23
+
24
+ _HINT = (
25
+ "╔─ HIGPERTEXT · Context Pack disponible ─────────────────────\n"
26
+ "│ Detecté una tarea de ingeniería. Para recibir contexto\n"
27
+ "│ curado (símbolos relevantes bajo presupuesto de tokens):\n"
28
+ '│ → htx task common.context-assembler --goal "<objetivo>" --type <refactor|feature|bugfix>\n'
29
+ "╚───────────────────────────────────────────────────────"
30
+ )
31
+
32
+
33
+ @hook_main
34
+ def main() -> None:
35
+ payload = read_payload()
36
+ prompt = payload.get("prompt", "") or payload.get("user_prompt", "")
37
+
38
+ if not _TASK_VERBS.search(prompt):
39
+ emit_continue()
40
+ return
41
+
42
+ emit_context("UserPromptSubmit", _HINT)
43
+
44
+
45
+ if __name__ == "__main__":
46
+ main()