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,154 @@
1
+ """higpertext Environment Manager — initializes and manages environment context (Application)."""
2
+
3
+ import os
4
+ import sys
5
+ import json
6
+ import shutil
7
+ import datetime
8
+ from pathlib import Path
9
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
10
+
11
+ from higpertext.kernel.infrastructure.logger import get_logger
12
+ _log = get_logger()
13
+
14
+ # Adjusting parents[2] to parents[3] since the file is now in application/
15
+ _MODEL_DEFAULTS_FILE = Path(__file__).parents[3] / "config" / "environments" / "model_defaults.json"
16
+
17
+
18
+ def load_model_defaults() -> dict:
19
+ """Carga model_config desde src/config/environments/model_defaults.json."""
20
+ try:
21
+ return json.loads(_MODEL_DEFAULTS_FILE.read_text(encoding="utf-8")).get("model_config", {})
22
+ except (OSError, json.JSONDecodeError):
23
+ return {}
24
+
25
+
26
+ class EnvironmentManager:
27
+ """Gestiona la inicialización y persistencia del contexto del entorno
28
+ en .higpertext/environment.json."""
29
+
30
+ def __init__(self, target_dir: Path):
31
+ self.target_dir = target_dir
32
+ self.higpertext_dir = target_dir / WORKSPACE_DIR_NAME
33
+ self.env_file = self.higpertext_dir / "config" / "environment.json"
34
+
35
+ def is_initialized(self) -> bool:
36
+ """Verifica si el proyecto ya ha sido inicializado por higpertext."""
37
+ return self.env_file.exists()
38
+
39
+ def load_environment(self) -> dict:
40
+ """Carga los metadatos y variables del entorno desde el archivo JSON."""
41
+ if not self.is_initialized():
42
+ return {}
43
+ try:
44
+ return json.loads(self.env_file.read_text(encoding="utf-8"))
45
+ except (OSError, json.JSONDecodeError) as e:
46
+ _log.warning(f"[!] Error leyendo {self.env_file}: {e}")
47
+ return {}
48
+
49
+ def save_environment(self, data: dict) -> None:
50
+ """Guarda los metadatos y variables de entorno en el archivo JSON."""
51
+ self.higpertext_dir.mkdir(parents=True, exist_ok=True)
52
+ self.env_file.parent.mkdir(parents=True, exist_ok=True)
53
+ self.env_file.write_text(json.dumps(data, indent=4, ensure_ascii=False), encoding="utf-8")
54
+ _log.ok(f"[*] Entorno guardado exitosamente en: {self.env_file}")
55
+
56
+ def _merge_list(self, existing: dict, key: str, new_val: str, fallback: str) -> list:
57
+ """Fusiona listas únicas preservando valores previos."""
58
+ result = list(existing.get(key, []))
59
+ legacy = existing.get(key[:-1]) # e.g. "assistant" from "assistants"
60
+ if legacy and legacy not in result:
61
+ result.append(legacy)
62
+ if new_val and new_val not in result:
63
+ result.append(new_val)
64
+ return result or [fallback]
65
+
66
+ # Campos que el kernel gestiona — no se propagan desde existing al merge final
67
+ _MANAGED_KEYS = {
68
+ "schema_version",
69
+ "project_name",
70
+ "initialized_at",
71
+ "last_updated",
72
+ "assistants",
73
+ "assistant",
74
+ "active_profiles",
75
+ "active_profile",
76
+ "system_environment",
77
+ "variables",
78
+ "wikis",
79
+ "model_config",
80
+ }
81
+
82
+ def initialize_environment(self, profile_name: str, assistant: str) -> dict:
83
+ """Inicializa o actualiza el archivo de entorno capturando variables clave del sistema."""
84
+ existing = self.load_environment()
85
+ existing_vars = existing.get("variables", {})
86
+
87
+ assistants = self._merge_list(existing, "assistants", assistant, "gemini")
88
+ active_profiles = self._merge_list(existing, "active_profiles", profile_name, "ado_admin")
89
+
90
+ org_url = os.getenv(
91
+ "ADO_ORG_URL",
92
+ existing_vars.get("organization_url"),
93
+ )
94
+ guidelines_source = os.getenv(
95
+ "HIGPERTEXT_GUIDELINES_SOURCE", existing_vars.get("guidelines_source")
96
+ )
97
+ _reserved_vars = {
98
+ "default_branch",
99
+ "repository_id",
100
+ "repo_id",
101
+ "organization_url",
102
+ "guidelines_source",
103
+ }
104
+ variables = {
105
+ "default_branch": existing_vars.get("default_branch", "main"),
106
+ "repository_id": existing_vars.get("repository_id", self.target_dir.name),
107
+ "repo_id": existing_vars.get("repo_id", self.target_dir.name),
108
+ "organization_url": org_url,
109
+ "guidelines_source": guidelines_source,
110
+ **{k: v for k, v in existing_vars.items() if k not in _reserved_vars},
111
+ }
112
+
113
+ # Preservar campos custom del usuario que no son gestionados por el kernel
114
+ user_custom = {k: v for k, v in existing.items() if k not in self._MANAGED_KEYS}
115
+
116
+ data = {
117
+ **user_custom,
118
+ "schema_version": "5.0.0",
119
+ "project_name": self.target_dir.name,
120
+ "initialized_at": existing.get("initialized_at", datetime.datetime.now().isoformat()),
121
+ "last_updated": datetime.datetime.now().isoformat(),
122
+ "assistants": assistants,
123
+ "assistant": assistant or existing.get("assistant", "gemini"),
124
+ "active_profiles": active_profiles,
125
+ "active_profile": profile_name or existing.get("active_profile", "ado_admin"),
126
+ "system_environment": {
127
+ "os": sys.platform,
128
+ "python_executable": sys.executable,
129
+ "has_powershell": bool(shutil.which("powershell") or shutil.which("pwsh")),
130
+ "project_root": str(self.target_dir.absolute()),
131
+ },
132
+ "variables": variables,
133
+ "wikis": existing.get("wikis", {}),
134
+ "model_config": existing.get("model_config", {}),
135
+ }
136
+ self.save_environment(data)
137
+ return data
138
+
139
+ def add_active_profile(self, profile_name: str) -> dict:
140
+ """Añade y registra de forma permanente un nuevo perfil en el proyecto activo."""
141
+ data = self.load_environment()
142
+ if not data:
143
+ return {}
144
+ active_profiles = data.get("active_profiles", [])
145
+ if "active_profile" in data and data["active_profile"] not in active_profiles:
146
+ active_profiles.append(data["active_profile"])
147
+ if profile_name and profile_name not in active_profiles:
148
+ active_profiles.append(profile_name)
149
+ data["active_profiles"] = active_profiles
150
+ data["active_profile"] = profile_name
151
+ data["last_updated"] = datetime.datetime.now().isoformat()
152
+ data["model_config"] = data.get("model_config", {})
153
+ self.save_environment(data)
154
+ return data
@@ -0,0 +1,192 @@
1
+ """Casos de uso y coordinadores de Gobernanza (Aplicación)."""
2
+
3
+ from __future__ import annotations
4
+ from pathlib import Path
5
+ import json
6
+ from datetime import datetime, timezone
7
+ import re
8
+
9
+ from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
10
+ from higpertext.kernel.domain.governance import Scope, Severity, Finding, Verdict, GovernanceException
11
+ from higpertext.kernel.infrastructure.governance import ContractLoader, AuditLog
12
+
13
+
14
+ class ExceptionRegistry:
15
+ def __init__(self, project_root: Path) -> None:
16
+ self._store = project_root / WORKSPACE_DIR_NAME / "state" / "governance_exceptions.json"
17
+
18
+ def register(self, exc: GovernanceException) -> None:
19
+ exceptions = self._load_all()
20
+ key = f"{exc.profile}:{exc.rule_id}"
21
+ data = exc.to_dict()
22
+ data["created_at"] = datetime.now(timezone.utc).isoformat(timespec="seconds")
23
+ exceptions[key] = data
24
+ self._save(exceptions)
25
+
26
+ def is_excepted(self, rule_id: str, profile: str) -> bool:
27
+ exceptions = self._load_all()
28
+ key = f"{profile}:{rule_id}"
29
+ entry = exceptions.get(key) or exceptions.get(f"global:{rule_id}")
30
+ if not entry:
31
+ return False
32
+ exc = GovernanceException.from_dict(entry)
33
+ return exc.is_active()
34
+
35
+ def list_active(self, profile: str = "") -> list[GovernanceException]:
36
+ all_exc = self._load_all()
37
+ result = []
38
+ for key, data in all_exc.items():
39
+ exc = GovernanceException.from_dict(data)
40
+ if not exc.is_active():
41
+ continue
42
+ if profile and exc.profile not in (profile, "global"):
43
+ continue
44
+ result.append(exc)
45
+ return result
46
+
47
+ def _load_all(self) -> dict:
48
+ if not self._store.exists():
49
+ return {}
50
+ try:
51
+ return json.loads(self._store.read_text(encoding="utf-8"))
52
+ except (OSError, json.JSONDecodeError):
53
+ return {}
54
+
55
+ def _save(self, data: dict) -> None:
56
+ self._store.parent.mkdir(parents=True, exist_ok=True)
57
+ self._store.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding="utf-8")
58
+
59
+
60
+ class GovernanceEnforcer:
61
+ """Evalúa gobernanza efectiva para un perfil y scope, con excepciones y audit trail."""
62
+
63
+ def __init__(self, project_root: Path) -> None:
64
+ self._root = project_root
65
+ self._loader = ContractLoader(project_root)
66
+ self._audit = AuditLog(project_root)
67
+ self._exceptions = ExceptionRegistry(project_root)
68
+
69
+ def evaluate(
70
+ self,
71
+ scope: str,
72
+ profile: str = "",
73
+ triggered_by: str = "",
74
+ context: dict | None = None,
75
+ ) -> Verdict:
76
+ """Evalúa todas las reglas aplicables al scope y perfil dados."""
77
+ scope_enum = self._normalize_scope(scope)
78
+ rules = self._loader.load(profile)
79
+ verdict = Verdict(scope=scope)
80
+
81
+ for rule in rules:
82
+ if self._should_skip_rule(rule, profile, scope_enum):
83
+ continue
84
+ self._apply_rule(rule, verdict, profile, context)
85
+
86
+ self._audit.record(verdict, profile=profile, triggered_by=triggered_by)
87
+ return verdict
88
+
89
+ def _normalize_scope(self, scope: str) -> Scope:
90
+ try:
91
+ return Scope(scope)
92
+ except ValueError:
93
+ return Scope.ANY
94
+
95
+ def _should_skip_rule(self, rule, profile: str, scope_enum: Scope) -> bool:
96
+ return (
97
+ not rule.applies_to(scope_enum)
98
+ or self._exceptions.is_excepted(rule.id, profile)
99
+ )
100
+
101
+ def _apply_rule(self, rule, verdict: Verdict, profile: str, context: dict | None) -> None:
102
+ if rule.automated and context:
103
+ finding = self._run_automated_check(rule, context, profile)
104
+ if finding:
105
+ verdict.add(finding)
106
+ return
107
+
108
+ if not rule.automated and rule.severity == Severity.HIGH:
109
+ verdict.add(
110
+ Finding(
111
+ rule_id=rule.id,
112
+ severity=Severity.MEDIUM, # degradar a WARN, nunca BLOCK
113
+ message=rule.description,
114
+ source=rule.source,
115
+ detail="Verificación manual requerida.",
116
+ )
117
+ )
118
+
119
+ def _run_automated_check(self, rule, context: dict, profile: str) -> Finding | None:
120
+ """Ejecuta verificaciones automáticas según el ID de la regla."""
121
+ checks = {
122
+ "security.no-hardcoded-secrets": self._check_no_secrets,
123
+ "code_quality.max-function-lines": self._check_function_lines,
124
+ "code_quality.min-coverage": self._check_coverage,
125
+ "gitflow_commits.conventional-format": self._check_commit_format,
126
+ }
127
+ checker = checks.get(rule.id)
128
+ if checker:
129
+ return checker(rule, context, profile)
130
+ return None
131
+
132
+ @staticmethod
133
+ def _check_no_secrets(rule, context: dict, profile: str) -> Finding | None:
134
+ patterns = [
135
+ r"(?i)(password|passwd|secret|token|api_key|apikey)\s*=\s*['\"][^'\"]{4,}['\"]",
136
+ r"(?i)bearer\s+[a-zA-Z0-9\-._~+/]{20,}",
137
+ ]
138
+ diff = context.get("diff", "")
139
+ for pat in patterns:
140
+ if re.search(pat, diff):
141
+ return Finding(
142
+ rule_id=rule.id,
143
+ severity=rule.severity,
144
+ message="Posible secret hardcodeado detectado en el diff.",
145
+ source=rule.source,
146
+ detail="Usa variables de entorno o un secrets manager.",
147
+ )
148
+ return None
149
+
150
+ @staticmethod
151
+ def _check_function_lines(rule, context: dict, profile: str) -> Finding | None:
152
+ threshold = rule.numeric_threshold or 30
153
+ violations = context.get("function_line_violations", [])
154
+ if violations:
155
+ return Finding(
156
+ rule_id=rule.id,
157
+ severity=rule.severity,
158
+ message=f"{len(violations)} función(es) exceden {int(threshold)} líneas.",
159
+ source=rule.source,
160
+ detail=", ".join(violations[:5]),
161
+ )
162
+ return None
163
+
164
+ @staticmethod
165
+ def _check_coverage(rule, context: dict, profile: str) -> Finding | None:
166
+ threshold = rule.numeric_threshold or 80.0
167
+ coverage = context.get("coverage_pct")
168
+ if coverage is not None and coverage < threshold:
169
+ return Finding(
170
+ rule_id=rule.id,
171
+ severity=rule.severity,
172
+ message=f"Cobertura {coverage:.1f}% < umbral {threshold:.0f}%.",
173
+ source=rule.source,
174
+ )
175
+ return None
176
+
177
+ @staticmethod
178
+ def _check_commit_format(rule, context: dict, profile: str) -> Finding | None:
179
+ msg = context.get("commit_message", "")
180
+ pattern = (
181
+ r"^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)"
182
+ r"(\([^)]+\))?(!)?: .+"
183
+ )
184
+ if msg and not re.match(pattern, msg):
185
+ return Finding(
186
+ rule_id=rule.id,
187
+ severity=rule.severity,
188
+ message="Mensaje de commit no sigue Conventional Commits.",
189
+ source=rule.source,
190
+ detail=f"Recibido: '{msg[:60]}'",
191
+ )
192
+ return None
@@ -0,0 +1,102 @@
1
+ """HookRegistry — carga hooks_config.json y filtra por asistente + perfil."""
2
+
3
+ from __future__ import annotations
4
+ from pathlib import Path
5
+
6
+ from higpertext.kernel.infrastructure.hook_config_loader import (
7
+ load_hooks_config,
8
+ save_hooks_config,
9
+ )
10
+ from higpertext.kernel.domain.hook_models import HookDefinition, WebhookEvent
11
+
12
+
13
+ class HookRegistry:
14
+ def __init__(self, project_root: Path) -> None:
15
+ self._project_root = project_root
16
+ self._data: dict = load_hooks_config(project_root)
17
+
18
+ def _get_valid_hooks(self) -> list[dict]:
19
+ all_hooks: list[dict] = self._data.get("hooks", []) + self._data.get("agent_hooks", [])
20
+ return [
21
+ h
22
+ for h in all_hooks
23
+ if isinstance(h, dict) and "id" in h and "event" in h and "script" in h
24
+ ]
25
+
26
+ def _get_profile_ids(self, profile: str) -> set[str]:
27
+ profile_ids: set[str] = set(self._data.get("profile_hooks", {}).get(profile, []))
28
+
29
+ # Siempre permite que los hooks locales del agente se ejecuten,
30
+ # asociándolos al perfil activo
31
+ for h in self._data.get("agent_hooks", []):
32
+ if isinstance(h, dict) and "id" in h:
33
+ profile_ids.add(h["id"])
34
+
35
+ return profile_ids
36
+
37
+ def _is_hook_allowed(self, raw: dict, assistant: str, profile: str, profile_ids: set[str]) -> bool:
38
+ if not raw.get("enabled", True):
39
+ return False
40
+
41
+ allowed_assistants = raw.get("assistants", [])
42
+ if allowed_assistants and assistant not in allowed_assistants:
43
+ return False
44
+
45
+ allowed_profiles = raw.get("profiles", [])
46
+ if allowed_profiles and profile not in allowed_profiles:
47
+ return False
48
+
49
+ return not profile_ids or raw["id"] in profile_ids
50
+
51
+ def get_hooks_for(self, assistant: str, profile: str) -> list[HookDefinition]:
52
+ """Devuelve hooks activos filtrados por asistente y perfil."""
53
+ all_hooks = self._get_valid_hooks()
54
+ profile_ids = self._get_profile_ids(profile)
55
+
56
+ result: list[HookDefinition] = []
57
+ for raw in all_hooks:
58
+ if not self._is_hook_allowed(raw, assistant, profile, profile_ids):
59
+ continue
60
+ result.append(
61
+ HookDefinition(
62
+ id=raw["id"],
63
+ event=raw["event"],
64
+ script=raw["script"],
65
+ description=raw.get("description", ""),
66
+ matcher=raw.get("matcher", ""),
67
+ timeout=raw.get("timeout", 10),
68
+ enabled=raw.get("enabled", True),
69
+ assistants=raw.get("assistants", []),
70
+ profiles=raw.get("profiles", []),
71
+ capability_id=raw.get("capability_id", ""),
72
+ )
73
+ )
74
+ return result
75
+
76
+ def get_webhooks_for(self, assistant: str) -> list[WebhookEvent]:
77
+ result: list[WebhookEvent] = []
78
+ for raw in self._data.get("webhooks", []):
79
+ if not raw.get("enabled", False):
80
+ continue
81
+ allowed = raw.get("assistants", [])
82
+ if allowed and assistant not in allowed:
83
+ continue
84
+ result.append(
85
+ WebhookEvent(
86
+ id=raw["id"],
87
+ event=raw["event"],
88
+ url=raw["url"],
89
+ payload_template=raw.get("payload_template", {}),
90
+ assistants=raw.get("assistants", []),
91
+ enabled=raw.get("enabled", False),
92
+ timeout=raw.get("timeout", 5),
93
+ )
94
+ )
95
+ return result
96
+
97
+ def get_all_hook_ids(self) -> list[str]:
98
+ return [h["id"] for h in self._data.get("hooks", [])]
99
+
100
+ def save(self, data: dict) -> None:
101
+ self._data = data
102
+ save_hooks_config(self._project_root, data)