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,49 @@
1
+ """Puertos de aplicación para persistencia y carga de recursos del kernel."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+ from typing import TYPE_CHECKING
7
+
8
+ if TYPE_CHECKING:
9
+ from higpertext.kernel.domain.entities import Capability, Profile, Session, Workflow
10
+
11
+
12
+ class IProfileRepository(ABC):
13
+ @abstractmethod
14
+ def load(self, name: str) -> Profile:
15
+ """Carga un perfil por su nombre."""
16
+
17
+ @abstractmethod
18
+ def list_all(self) -> list[str]:
19
+ """Lista los nombres de todos los perfiles disponibles."""
20
+
21
+
22
+ class ICapabilityRepository(ABC):
23
+ @abstractmethod
24
+ def load(self, cap_id: str) -> Capability:
25
+ """Carga una capacidad por su ID."""
26
+
27
+ @abstractmethod
28
+ def list_all(self) -> list[Capability]:
29
+ """Lista todas las capacidades disponibles."""
30
+
31
+
32
+ class IWorkflowRepository(ABC):
33
+ @abstractmethod
34
+ def list_all(self) -> list[Workflow]:
35
+ """Lista todos los workflows disponibles."""
36
+
37
+
38
+ class ISessionRepository(ABC):
39
+ @abstractmethod
40
+ def load_active(self) -> Session | None:
41
+ """Carga la sesión activa si existe."""
42
+
43
+ @abstractmethod
44
+ def save(self, session: Session) -> None:
45
+ """Guarda el estado de la sesión."""
46
+
47
+ @abstractmethod
48
+ def delete(self) -> None:
49
+ """Elimina el estado de la sesión activa."""
@@ -0,0 +1,358 @@
1
+ """Profile Learner Application layer — ProfileExtractor, ProfileUpdater, and WeightsCalibrator."""
2
+
3
+ from __future__ import annotations
4
+ import math
5
+ import re
6
+ from collections import Counter
7
+ from pathlib import Path
8
+ from higpertext.kernel.domain.profile_learner import (
9
+ SessionPattern,
10
+ SkillProfile,
11
+ classify_patterns,
12
+ load_weights,
13
+ save_weights,
14
+ score_session,
15
+ )
16
+
17
+
18
+ class ProfileExtractor:
19
+ """Lee eventos de telemetría y extrae patrones de comportamiento del usuario."""
20
+
21
+ def __init__(self, project_root: Path) -> None:
22
+ self._root = project_root
23
+
24
+ def extract(self, days: int = 30) -> tuple[SkillProfile, list[SessionPattern]]:
25
+ from higpertext.kernel.application.telemetry import TelemetryAggregator
26
+
27
+ agg = TelemetryAggregator(self._root)
28
+ metrics = agg.compute(days)
29
+ if not metrics:
30
+ return SkillProfile(), []
31
+
32
+ events = agg.load(days)
33
+ patterns = self._build_patterns(events, metrics)
34
+ return self._build_profile(patterns, metrics), patterns
35
+
36
+ def _build_patterns(self, events: list[dict], metrics: dict) -> list[SessionPattern]:
37
+ from collections import defaultdict
38
+
39
+ sessions: dict[str, dict] = defaultdict(
40
+ lambda: {
41
+ "duration_min": 0.0,
42
+ "commits": [],
43
+ "caps": [],
44
+ "intercepts": [],
45
+ "higpertext_direct": 0,
46
+ "bash_direct": 0,
47
+ "adoption_pct": 0.0,
48
+ }
49
+ )
50
+
51
+ for e in events:
52
+ sid = e.get("session_id", "unknown")
53
+ ev = e.get("event", "")
54
+ if ev == "session_stop":
55
+ sessions[sid]["duration_min"] = e.get("duration_min", 0.0)
56
+ elif ev == "commit":
57
+ sessions[sid]["commits"].append(e)
58
+ elif ev == "capability_used":
59
+ sessions[sid]["caps"].append(e.get("capability", ""))
60
+ elif ev == "hook_intercept":
61
+ sessions[sid]["intercepts"].append(e.get("capability", ""))
62
+ elif ev == "tool_call":
63
+ if e.get("is_higpertext_call"):
64
+ sessions[sid]["higpertext_direct"] += 1
65
+ else:
66
+ sessions[sid]["bash_direct"] += 1
67
+
68
+ patterns = []
69
+ for sid, s in sessions.items():
70
+ higpertext_count = len(s["caps"]) + len(s["intercepts"]) + s["higpertext_direct"]
71
+ bash = s["bash_direct"]
72
+ total = higpertext_count + bash
73
+ adoption = round(higpertext_count / total * 100, 1) if total else 0.0
74
+
75
+ commit_types = tuple(_parse_commit_type(c.get("type", "")) for c in s["commits"])
76
+ commit_messages = tuple(c.get("scope", "") for c in s["commits"] if c.get("scope"))
77
+
78
+ patterns.append(
79
+ SessionPattern(
80
+ session_id=sid,
81
+ duration_min=s["duration_min"],
82
+ commits=len(s["commits"]),
83
+ higpertext_adoption_pct=adoption,
84
+ bash_direct_calls=bash,
85
+ capability_used_calls=len(s["caps"]),
86
+ hook_intercept_calls=len(s["intercepts"]),
87
+ higpertext_direct_calls=s["higpertext_direct"],
88
+ commit_types=commit_types,
89
+ commit_messages=commit_messages,
90
+ )
91
+ )
92
+ return patterns
93
+
94
+ def _build_profile(self, patterns: list[SessionPattern], metrics: dict) -> SkillProfile:
95
+ if not patterns:
96
+ return SkillProfile()
97
+
98
+ all_strong: Counter = Counter()
99
+ all_weak: Counter = Counter()
100
+ cap_counter: Counter = Counter()
101
+
102
+ for p in patterns:
103
+ strong, weak = classify_patterns(p)
104
+ for s in strong:
105
+ all_strong[s] += 1
106
+ for w in weak:
107
+ all_weak[w] += 1
108
+ cap_counter.update(p.commit_messages)
109
+
110
+ all_messages = [m for p in patterns for m in p.commit_messages]
111
+ topics = extract_commit_topics(all_messages, top_n=5)
112
+
113
+ corr = metrics.get("correlations", {})
114
+ avg_adoption = sum(p.higpertext_adoption_pct for p in patterns) / len(patterns)
115
+
116
+ effective = [p for p in patterns if p.is_effective]
117
+ best = (
118
+ f"sesiones <45min con ≥2 commits ({len(effective)} de {len(patterns)})"
119
+ if effective
120
+ else "sin patrón efectivo identificado aún"
121
+ )
122
+
123
+ return SkillProfile(
124
+ strong_patterns=[k for k, _ in all_strong.most_common(5)],
125
+ weak_patterns=[k for k, _ in all_weak.most_common(5)],
126
+ preferred_caps=[cap for cap, _ in cap_counter.most_common(5)],
127
+ commit_topics=topics,
128
+ cost_per_commit_avg=corr.get("cost_per_commit_usd", 0.0),
129
+ higpertext_adoption_trend=round(avg_adoption, 1),
130
+ best_session_pattern=best,
131
+ total_sessions_analyzed=len(patterns),
132
+ )
133
+
134
+
135
+ _DECAY = 0.8 # peso del perfil histórico vs. nuevo batch
136
+
137
+
138
+ class ProfileUpdater:
139
+ """Combina perfil existente con nuevo batch. Sesiones recientes pesan más."""
140
+
141
+ def merge(self, existing: SkillProfile | None, fresh: SkillProfile) -> SkillProfile:
142
+ if existing is None:
143
+ return fresh
144
+
145
+ return SkillProfile(
146
+ strong_patterns=_merge_lists(existing.strong_patterns, fresh.strong_patterns),
147
+ weak_patterns=_merge_lists(existing.weak_patterns, fresh.weak_patterns),
148
+ preferred_caps=_merge_lists(existing.preferred_caps, fresh.preferred_caps),
149
+ commit_topics=_merge_lists(existing.commit_topics, fresh.commit_topics),
150
+ cost_per_commit_avg=_decay_float(
151
+ existing.cost_per_commit_avg, fresh.cost_per_commit_avg
152
+ ),
153
+ higpertext_adoption_trend=_decay_float(
154
+ existing.higpertext_adoption_trend, fresh.higpertext_adoption_trend
155
+ ),
156
+ best_session_pattern=fresh.best_session_pattern or existing.best_session_pattern,
157
+ total_sessions_analyzed=(
158
+ existing.total_sessions_analyzed + fresh.total_sessions_analyzed
159
+ ),
160
+ )
161
+
162
+
163
+ def _decay_float(old: float, new: float) -> float:
164
+ return round(old * _DECAY + new * (1 - _DECAY), 4)
165
+
166
+
167
+ def _merge_lists(old: list[str], new: list[str]) -> list[str]:
168
+ """Une listas priorizando los del batch nuevo, sin duplicados."""
169
+ seen: set[str] = set()
170
+ result: list[str] = []
171
+ for item in new + old:
172
+ if item not in seen:
173
+ seen.add(item)
174
+ result.append(item)
175
+ return result[:5]
176
+
177
+
178
+ _MIN_SESSIONS_ZSCORE = 10
179
+ _MIN_SESSIONS_REGRESSION = 20
180
+ _LEARNING_RATE = 0.01
181
+ _EPOCHS = 500
182
+
183
+
184
+ class WeightsCalibrator:
185
+ """Ajusta pesos de scoring usando el historial de SessionPatterns.
186
+
187
+ - < 10 sesiones : solo carga pesos existentes (sin cambios)
188
+ - >= 10 sesiones: calibración z-score (normaliza distribución de scores)
189
+ - >= 20 sesiones: regresión lineal (optimiza predicción de productividad)
190
+ """
191
+
192
+ def __init__(self, project_root: Path) -> None:
193
+ self._root = project_root
194
+
195
+ def calibrate(self, patterns: list[SessionPattern]) -> dict:
196
+ n = len(patterns)
197
+ weights = load_weights(self._root)
198
+
199
+ if n < _MIN_SESSIONS_ZSCORE:
200
+ return weights
201
+
202
+ if n >= _MIN_SESSIONS_REGRESSION:
203
+ weights = self._regression_calibrate(patterns, weights)
204
+ else:
205
+ weights = self._zscore_calibrate(patterns, weights)
206
+
207
+ save_weights(weights, self._root)
208
+ return weights
209
+
210
+ def _zscore_calibrate(self, patterns: list[SessionPattern], weights: dict) -> dict:
211
+ """Ajusta el multiplicador global para que el score promedio sea 0."""
212
+ scores = [score_session(p, weights) for p in patterns]
213
+ mean = sum(scores) / len(scores)
214
+ variance = sum((s - mean) ** 2 for s in scores) / len(scores)
215
+ std = math.sqrt(variance) if variance > 0 else 1.0
216
+
217
+ # Escala todos los pesos numéricos para que std ≈ 10 (rango legible)
218
+ target_std = 10.0
219
+ if std < 0.01:
220
+ return weights
221
+ scale = target_std / std
222
+
223
+ calibrated = dict(weights)
224
+ _SCALE_KEYS = {
225
+ "hook_intercept",
226
+ "capability_used",
227
+ "higpertext_direct",
228
+ "bash_direct_penalty",
229
+ "zero_commits_penalty",
230
+ "conventional_commit",
231
+ "high_adoption_bonus",
232
+ "effective_session_bonus",
233
+ }
234
+ for key in _SCALE_KEYS:
235
+ if key in calibrated and isinstance(calibrated[key], (int, float)):
236
+ calibrated[key] = round(calibrated[key] * scale, 4)
237
+
238
+ return calibrated
239
+
240
+ def _regression_calibrate(self, patterns: list[SessionPattern], weights: dict) -> dict:
241
+ """Aprende pesos que mejor predicen commits_per_session (proxy de productividad)."""
242
+ features, targets = _build_feature_matrix(patterns)
243
+ if not features:
244
+ return weights
245
+
246
+ n_features = len(features[0])
247
+ w = [1.0] * n_features # pesos iniciales uniformes
248
+ n = len(features)
249
+
250
+ for _ in range(_EPOCHS):
251
+ grad = [0.0] * n_features
252
+ for x, y in zip(features, targets):
253
+ pred = sum(wi * xi for wi, xi in zip(w, x))
254
+ err = pred - y
255
+ for j in range(n_features):
256
+ grad[j] += (2 / n) * err * x[j]
257
+ w = [wi - _LEARNING_RATE * g for wi, g in zip(w, grad)]
258
+
259
+ calibrated = dict(weights)
260
+ _REGRESSION_KEYS = [
261
+ "hook_intercept",
262
+ "capability_used",
263
+ "higpertext_direct",
264
+ "bash_direct_penalty",
265
+ "conventional_commit",
266
+ ]
267
+ for i, key in enumerate(_REGRESSION_KEYS):
268
+ if i < len(w) and key in calibrated:
269
+ calibrated[key] = round(w[i], 4)
270
+
271
+ return calibrated
272
+
273
+
274
+ def _build_feature_matrix(
275
+ patterns: list[SessionPattern],
276
+ ) -> tuple[list[list[float]], list[float]]:
277
+ """Construye matriz de features y vector de targets para regresión lineal simple.
278
+
279
+ Features por sesión (normalización básica):
280
+ 0: hook_intercept_count / 10
281
+ 1: capability_count / 10
282
+ 2: higpertext_pct (0-1)
283
+ 3: duration_min / 60
284
+ Target: commits_per_session (proxy de productividad)
285
+ """
286
+ features: list[list[float]] = []
287
+ targets: list[float] = []
288
+
289
+ for p in patterns:
290
+ total_tools = (p.higpertext_direct_calls or 0) + (p.bash_direct_calls or 0) + 1
291
+ higpertext_pct = (p.higpertext_direct_calls or 0) / total_tools
292
+
293
+ feat = [
294
+ (p.hook_intercept_calls or 0) / 10.0,
295
+ (p.capability_used_calls or 0) / 10.0,
296
+ higpertext_pct,
297
+ (p.duration_min or 0.0) / 60.0,
298
+ ]
299
+ features.append(feat)
300
+ targets.append(float(p.commits or 0))
301
+
302
+ return features, targets
303
+
304
+
305
+ def extract_commit_topics(messages: list[str], top_n: int = 5) -> list[str]:
306
+ """Extrae temas recurrentes usando TF-IDF simplificado (sin dependencias externas)."""
307
+ if not messages:
308
+ return []
309
+
310
+ docs = [_tokenize(m) for m in messages]
311
+ n_docs = len(docs)
312
+
313
+ tf: list[Counter] = [Counter(d) for d in docs]
314
+ df: Counter = Counter()
315
+ for doc in docs:
316
+ df.update(set(doc))
317
+
318
+ import math
319
+
320
+ scores: Counter = Counter()
321
+ for doc_tf in tf:
322
+ total = sum(doc_tf.values()) or 1
323
+ for term, count in doc_tf.items():
324
+ tfidf = (count / total) * math.log((n_docs + 1) / (df[term] + 1))
325
+ scores[term] += tfidf
326
+
327
+ return [term for term, _ in scores.most_common(top_n)]
328
+
329
+
330
+ def _tokenize(text: str) -> list[str]:
331
+ tokens = re.findall(r"[a-zA-Z_][a-zA-Z0-9_]{2,}", text.lower())
332
+ stopwords = {
333
+ "the",
334
+ "and",
335
+ "for",
336
+ "fix",
337
+ "add",
338
+ "update",
339
+ "feat",
340
+ "chore",
341
+ "refactor",
342
+ "test",
343
+ "docs",
344
+ "style",
345
+ "perf",
346
+ "build",
347
+ "this",
348
+ "with",
349
+ "from",
350
+ "that",
351
+ "into",
352
+ "when",
353
+ }
354
+ return [t for t in tokens if t not in stopwords]
355
+
356
+
357
+ def _parse_commit_type(raw: str) -> str:
358
+ return raw.split("(")[0].strip().lower() if raw else "unknown"
@@ -0,0 +1,205 @@
1
+ """Servicio de Aplicación para resolución, validación y gestión de perfiles (DDD)."""
2
+
3
+ from __future__ import annotations
4
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
5
+ import json
6
+ import os
7
+ from dataclasses import asdict
8
+ from pathlib import Path
9
+ from higpertext.kernel.application.ports import (
10
+ IProfileRepository,
11
+ ICapabilityRepository,
12
+ )
13
+ from higpertext.kernel.domain.entities import Profile
14
+ from higpertext.kernel.pkg_resources import resolve_resource
15
+
16
+
17
+ class ProfileApplicationService:
18
+ def __init__(self, profile_repo: IProfileRepository):
19
+ self.profile_repo = profile_repo
20
+
21
+ def get_profile_data(self, name: str) -> dict:
22
+ profile = self.profile_repo.load(name)
23
+ return asdict(profile)
24
+
25
+ def get_all_profile_names(self) -> list[str]:
26
+ return self.profile_repo.list_all()
27
+
28
+
29
+ class ProfileManager:
30
+ """Facade que conecta FileProfileRepository + ProfileApplicationService."""
31
+
32
+ def __init__(self, profiles_dir: Path):
33
+ self.profiles_dir = profiles_dir
34
+ from higpertext.kernel.infrastructure.file_repositories import FileProfileRepository
35
+
36
+ self._repo = FileProfileRepository(profiles_dir)
37
+ self._service = ProfileApplicationService(self._repo)
38
+
39
+ def _get_custom_profiles_dir(self) -> Path:
40
+ return Path(os.getcwd()).resolve() / WORKSPACE_DIR_NAME / "profiles"
41
+
42
+ def _get_all_profile_files(self) -> list[Path]:
43
+ files = list(self.profiles_dir.glob("*.json"))
44
+ custom_dir = self._get_custom_profiles_dir()
45
+ if custom_dir.exists():
46
+ files.extend(custom_dir.glob("*.json"))
47
+ return files
48
+
49
+ def load_profile(self, profile_name: str) -> dict:
50
+ return self._service.get_profile_data(profile_name)
51
+
52
+ def list_profiles(self) -> list[str]:
53
+ return self._service.get_all_profile_names()
54
+
55
+
56
+ class ProfileService:
57
+ def __init__(
58
+ self,
59
+ profiles_repo: IProfileRepository,
60
+ caps_repo: ICapabilityRepository,
61
+ base_dir: Path,
62
+ ):
63
+ self.profiles_repo = profiles_repo
64
+ self.caps_repo = caps_repo
65
+ self.base_dir = base_dir
66
+
67
+ def resolve_hierarchy(self, profile_name: str, visited: set[str] | None = None) -> Profile:
68
+ """Resuelve recursivamente la herencia de un perfil mezclando sus campos."""
69
+ if visited is None:
70
+ visited = set()
71
+
72
+ name_lower = profile_name.lower()
73
+ if name_lower in visited:
74
+ cycle = " -> ".join(list(visited) + [profile_name])
75
+ raise ValueError(f"Herencia cíclica detectada en los perfiles: {cycle}")
76
+
77
+ visited.add(name_lower)
78
+ profile = self.profiles_repo.load(profile_name)
79
+
80
+ if not profile.extends:
81
+ return profile
82
+
83
+ parent = self.resolve_hierarchy(profile.extends, visited)
84
+
85
+ merged_caps = self._merge_lists(parent.capabilities, profile.capabilities)
86
+ merged_skills = self._merge_lists(parent.session_skills, profile.session_skills)
87
+ merged_subagents = self._merge_lists(parent.session_subagents, profile.session_subagents)
88
+
89
+ system_prompt = (
90
+ profile.system_prompt if profile.system_prompt.strip() else parent.system_prompt
91
+ )
92
+
93
+ return Profile(
94
+ name=profile.name,
95
+ description=profile.description or parent.description,
96
+ system_prompt=system_prompt,
97
+ capabilities=merged_caps,
98
+ session_skills=merged_skills,
99
+ session_subagents=merged_subagents,
100
+ governance_access=profile.governance_access or parent.governance_access,
101
+ extends=profile.extends,
102
+ model=profile.model or parent.model,
103
+ )
104
+
105
+ def _merge_lists(self, parent_list: list[str], child_list: list[str]) -> list[str]:
106
+ merged = list(parent_list)
107
+ for item in child_list:
108
+ if item not in merged:
109
+ merged.append(item)
110
+ return merged
111
+
112
+ def validate_profile(self, profile_name: str) -> tuple[bool, list[str], list[str]]:
113
+ """Valida la estructura, integridad, dependencias y saturación de contexto de un perfil."""
114
+ errors = []
115
+ warnings = []
116
+ try:
117
+ resolved = self.resolve_hierarchy(profile_name)
118
+ except (FileNotFoundError, ValueError) as e:
119
+ return False, [str(e)], []
120
+
121
+ self._validate_capabilities(resolved.capabilities, errors)
122
+
123
+ total_chars = len(resolved.system_prompt)
124
+ total_chars += self._validate_skills(resolved.session_skills, errors)
125
+ total_chars += self._validate_subagents(resolved.session_subagents, errors)
126
+
127
+ self._validate_context_saturation(total_chars, warnings)
128
+
129
+ return len(errors) == 0, errors, warnings
130
+
131
+ def _validate_capabilities(self, capabilities: list[str], errors: list[str]) -> None:
132
+ for cap_id in capabilities:
133
+ try:
134
+ self.caps_repo.load(cap_id)
135
+ except FileNotFoundError:
136
+ errors.append(f"Capacidad '{cap_id}' referenciada no encontrada en el repositorio.")
137
+
138
+ def _validate_skills(self, skills: list[str], errors: list[str]) -> int:
139
+ total_chars = 0
140
+ skills_dirs = self._resolve_template_dirs("skills")
141
+ for skill in skills:
142
+ matches = self._find_in_dirs(skills_dirs, f"{skill}.json")
143
+ if not matches:
144
+ errors.append(
145
+ f"Skill '{skill}' referenciada no tiene plantilla en templates/skills."
146
+ )
147
+ else:
148
+ try:
149
+ s_data = json.loads(matches[0].read_text(encoding="utf-8"))
150
+ total_chars += len(s_data.get("content", ""))
151
+ except Exception: # nosec B110
152
+ pass
153
+ return total_chars
154
+
155
+ def _validate_subagents(self, subagents: list[str], errors: list[str]) -> int:
156
+ total_chars = 0
157
+ subagents_dirs = self._resolve_template_dirs("subagents")
158
+ for subagent in subagents:
159
+ matches = self._find_in_dirs(subagents_dirs, f"{subagent}.json")
160
+ if not matches:
161
+ errors.append(
162
+ f"Subagent '{subagent}' referenciado no tiene"
163
+ " plantilla en templates/subagents."
164
+ )
165
+ else:
166
+ try:
167
+ total_chars += len(matches[0].read_text(encoding="utf-8"))
168
+ except Exception: # nosec B110
169
+ pass
170
+ return total_chars
171
+
172
+ def _validate_context_saturation(self, total_chars: int, warnings: list[str]) -> None:
173
+ if total_chars > 50000:
174
+ warnings.append(
175
+ f"Saturación crítica de contexto: El tamaño estimado"
176
+ f" del perfil ({total_chars} chars) "
177
+ "es demasiado alto y degradará el rendimiento del LLM."
178
+ )
179
+ elif total_chars > 25000:
180
+ warnings.append(
181
+ f"Riesgo de saturación de contexto: El tamaño estimado"
182
+ f" del perfil ({total_chars} chars) "
183
+ "es alto y podría diluir la atención del LLM."
184
+ )
185
+
186
+ def _resolve_template_dirs(self, subdir: str) -> list[Path]:
187
+ """Retorna lista de directorios de templates: core primero, luego agente externo."""
188
+ dirs = [resolve_resource(self.base_dir, "src", "higpertext", "templates", subdir)]
189
+ agent_templates = self.base_dir / WORKSPACE_DIR_NAME / "agent_templates" / subdir
190
+ if agent_templates.exists():
191
+ dirs.append(agent_templates)
192
+ return dirs
193
+
194
+ def _find_in_dirs(self, dirs: list[Path], filename: str) -> list[Path]:
195
+ """Busca filename (o skill.json en subdirectorio homónimo) en múltiples directorios."""
196
+ matches: list[Path] = []
197
+ stem = Path(filename).stem # e.g. "clean-code"
198
+ for d in dirs:
199
+ if not d.exists():
200
+ continue
201
+ matches.extend(d.rglob(filename))
202
+ subdir_skill = d / stem / "skill.json"
203
+ if subdir_skill.exists():
204
+ matches.append(subdir_skill)
205
+ return matches
@@ -0,0 +1,6 @@
1
+ """Re-export de compatibilidad — ver profile_service.py."""
2
+
3
+ from higpertext.kernel.application.profile_service import ( # noqa: F401
4
+ ProfileApplicationService,
5
+ ProfileManager,
6
+ )