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.
- config/adapters_config.json +450 -0
- config/antigravity_agent_template.json +31 -0
- config/app_config.json +174 -0
- config/context_engine.json +33 -0
- config/environments/model_defaults.json +5 -0
- config/governance/branching_strategy.json +36 -0
- config/governance/deployment_gates.json +30 -0
- config/governance/guidelines_contract.json +54 -0
- config/governance/quality_gates.json +39 -0
- config/governance/section_rules.json +22 -0
- config/governance/security_guardrails.json +52 -0
- config/hooks/README.md +35 -0
- config/hooks/custom/test_output_limiter.json +9 -0
- config/hooks/global/session_prompt.json +9 -0
- config/htx_config.json +24 -0
- config/profile_learner.json +18 -0
- config/profiles/base_agent.json +40 -0
- config/profiles/base_auditor.json +19 -0
- config/profiles/base_developer.json +19 -0
- config/profiles/base_operator.json +16 -0
- config/profiles/global.json +33 -0
- config/profiles/software_developer.json +23 -0
- config/router_content.json +137 -0
- config/semantic_graph.json +66 -0
- config/workflows/ado_release_flow.json +38 -0
- config/workflows/docs-update.json +33 -0
- config/workflows/governance-check.yaml +26 -0
- config/workflows/guidelines-sync.json +40 -0
- config/workflows/higpertext-build.json +73 -0
- config/workflows/higpertext-plan.json +38 -0
- config/workflows/higpertext-review.json +41 -0
- config/workflows/pr-quality-check.json +56 -0
- config/workflows/quality-remediation.json +57 -0
- higpertext/__init__.py +18 -0
- higpertext/adapters/__init__.py +27 -0
- higpertext/adapters/adapter_utils.py +604 -0
- higpertext/adapters/claude_adapter/__init__.py +0 -0
- higpertext/adapters/claude_adapter/claude_adapter.py +154 -0
- higpertext/adapters/copilot_adapter/__init__.py +0 -0
- higpertext/adapters/copilot_adapter/copilot_adapter.py +231 -0
- higpertext/adapters/gemini_adapter/__init__.py +0 -0
- higpertext/adapters/gemini_adapter/gemini_adapter.py +211 -0
- higpertext/adapters/llm_formatter.py +46 -0
- higpertext/adapters/open_code_adapter/__init__.py +0 -0
- higpertext/adapters/open_code_adapter/open_code_adapter.py +480 -0
- higpertext/capabilities/capabilities_runner.py +216 -0
- higpertext/capabilities/common/agent-builder.json +54 -0
- higpertext/capabilities/common/agent-sync.json +34 -0
- higpertext/capabilities/common/code-skeletonizer.json +35 -0
- higpertext/capabilities/common/commit-report.json +42 -0
- higpertext/capabilities/common/context-assembler.json +37 -0
- higpertext/capabilities/common/context-budget-report.json +15 -0
- higpertext/capabilities/common/dep-manager.json +43 -0
- higpertext/capabilities/common/docs-sync.json +14 -0
- higpertext/capabilities/common/doctor.json +18 -0
- higpertext/capabilities/common/efficiency-meter.json +31 -0
- higpertext/capabilities/common/env-catalog.json +13 -0
- higpertext/capabilities/common/env-clean.json +14 -0
- higpertext/capabilities/common/env-logs.json +16 -0
- higpertext/capabilities/common/env-runner.json +23 -0
- higpertext/capabilities/common/env-status.json +13 -0
- higpertext/capabilities/common/env-stop.json +14 -0
- higpertext/capabilities/common/env-template.json +14 -0
- higpertext/capabilities/common/error-context-locator.json +23 -0
- higpertext/capabilities/common/eval-agent.json +33 -0
- higpertext/capabilities/common/file-map.json +17 -0
- higpertext/capabilities/common/governance-exception.json +54 -0
- higpertext/capabilities/common/graph-query.json +59 -0
- higpertext/capabilities/common/graph-rebuild.json +31 -0
- higpertext/capabilities/common/graph-visualize.json +37 -0
- higpertext/capabilities/common/grep-search.json +176 -0
- higpertext/capabilities/common/higpertext-tester.json +25 -0
- higpertext/capabilities/common/hook-health.json +19 -0
- higpertext/capabilities/common/hook-sync-check.json +19 -0
- higpertext/capabilities/common/hooks-manager.json +55 -0
- higpertext/capabilities/common/knowledge-asker.json +27 -0
- higpertext/capabilities/common/list-rules.json +27 -0
- higpertext/capabilities/common/llm-invoke.json +59 -0
- higpertext/capabilities/common/load-rules.json +37 -0
- higpertext/capabilities/common/memory-manager.json +65 -0
- higpertext/capabilities/common/quality-scan.json +21 -0
- higpertext/capabilities/common/quality-updater.json +35 -0
- higpertext/capabilities/common/rag-index.json +17 -0
- higpertext/capabilities/common/report-viewer.json +24 -0
- higpertext/capabilities/common/roadmap-report.json +37 -0
- higpertext/capabilities/common/scripts/_env_cli.py +65 -0
- higpertext/capabilities/common/scripts/agent_builder.py +60 -0
- higpertext/capabilities/common/scripts/agent_sync.py +56 -0
- higpertext/capabilities/common/scripts/ask_higpertext.py +38 -0
- higpertext/capabilities/common/scripts/code_skeletonizer.py +225 -0
- higpertext/capabilities/common/scripts/commit_report.py +134 -0
- higpertext/capabilities/common/scripts/context_assembler.py +70 -0
- higpertext/capabilities/common/scripts/context_budget_report.py +53 -0
- higpertext/capabilities/common/scripts/dep_manager.py +81 -0
- higpertext/capabilities/common/scripts/docs_sync.py +981 -0
- higpertext/capabilities/common/scripts/doctor.py +144 -0
- higpertext/capabilities/common/scripts/efficiency_meter.py +83 -0
- higpertext/capabilities/common/scripts/env_catalog.py +47 -0
- higpertext/capabilities/common/scripts/env_clean.py +30 -0
- higpertext/capabilities/common/scripts/env_logs.py +32 -0
- higpertext/capabilities/common/scripts/env_runner.py +53 -0
- higpertext/capabilities/common/scripts/env_status.py +38 -0
- higpertext/capabilities/common/scripts/env_stop.py +30 -0
- higpertext/capabilities/common/scripts/env_template.py +73 -0
- higpertext/capabilities/common/scripts/error_context_locator.py +138 -0
- higpertext/capabilities/common/scripts/eval_agent.py +80 -0
- higpertext/capabilities/common/scripts/file_map.py +95 -0
- higpertext/capabilities/common/scripts/governance_exception.py +116 -0
- higpertext/capabilities/common/scripts/graph_query.py +104 -0
- higpertext/capabilities/common/scripts/graph_rebuild.py +107 -0
- higpertext/capabilities/common/scripts/graph_visualize.py +76 -0
- higpertext/capabilities/common/scripts/grep_search.py +648 -0
- higpertext/capabilities/common/scripts/higpertext_tester.py +102 -0
- higpertext/capabilities/common/scripts/hook_health.py +149 -0
- higpertext/capabilities/common/scripts/hook_sync_check.py +134 -0
- higpertext/capabilities/common/scripts/hooks_manager.py +171 -0
- higpertext/capabilities/common/scripts/list_rules.py +175 -0
- higpertext/capabilities/common/scripts/llm_invoke.py +135 -0
- higpertext/capabilities/common/scripts/load_rules.py +379 -0
- higpertext/capabilities/common/scripts/memory_manager.py +210 -0
- higpertext/capabilities/common/scripts/presentation_engine.py +63 -0
- higpertext/capabilities/common/scripts/quality_scan.py +132 -0
- higpertext/capabilities/common/scripts/rag_index.py +39 -0
- higpertext/capabilities/common/scripts/report_viewer.py +106 -0
- higpertext/capabilities/common/scripts/roadmap_report.py +73 -0
- higpertext/capabilities/common/scripts/search_router.py +111 -0
- higpertext/capabilities/common/scripts/semantic_diff.py +166 -0
- higpertext/capabilities/common/scripts/semantic_search.py +43 -0
- higpertext/capabilities/common/scripts/session_control.py +136 -0
- higpertext/capabilities/common/scripts/smart_read.py +232 -0
- higpertext/capabilities/common/scripts/subagent_executor.py +143 -0
- higpertext/capabilities/common/scripts/sync_agents.py +353 -0
- higpertext/capabilities/common/scripts/task_decomposer.py +78 -0
- higpertext/capabilities/common/scripts/telemetry_report.py +36 -0
- higpertext/capabilities/common/search-router.json +24 -0
- higpertext/capabilities/common/semantic-diff.json +40 -0
- higpertext/capabilities/common/semantic-search.json +19 -0
- higpertext/capabilities/common/session-clean.json +20 -0
- higpertext/capabilities/common/session-start.json +44 -0
- higpertext/capabilities/common/smart-read.json +28 -0
- higpertext/capabilities/common/subagent-executor.json +25 -0
- higpertext/capabilities/common/sync-agents.json +32 -0
- higpertext/capabilities/common/task-decomposer.json +37 -0
- higpertext/capabilities/common/telemetry-report.json +23 -0
- higpertext/capabilities/git/__init__.py +0 -0
- higpertext/capabilities/git/committer.json +61 -0
- higpertext/capabilities/git/diff.json +33 -0
- higpertext/capabilities/git/ls-files.json +44 -0
- higpertext/capabilities/git/rm.json +27 -0
- higpertext/capabilities/git/scripts/__init__.py +0 -0
- higpertext/capabilities/git/scripts/commit_changes.py +1077 -0
- higpertext/capabilities/git/scripts/git_diff.py +171 -0
- higpertext/capabilities/git/scripts/git_ls_files.py +376 -0
- higpertext/capabilities/git/scripts/git_rm.py +62 -0
- higpertext/capabilities/security/k8s-auditor.json +33 -0
- higpertext/capabilities/security/scripts/k8s_auditor.py +307 -0
- higpertext/capabilities/security/scripts/secret_scanner.py +235 -0
- higpertext/capabilities/security/secret-scanner.json +32 -0
- higpertext/hooks/__init__.py +28 -0
- higpertext/hooks/_compat.py +27 -0
- higpertext/hooks/hook_tasks/__init__.py +1 -0
- higpertext/hooks/hook_tasks/_rules/__init__.py +0 -0
- higpertext/hooks/hook_tasks/_rules/bash_rules.py +635 -0
- higpertext/hooks/hook_tasks/_rules/context_engine_rule.py +79 -0
- higpertext/hooks/hook_tasks/_rules/context_rules.py +199 -0
- higpertext/hooks/hook_tasks/_rules/governance_adapter.py +72 -0
- higpertext/hooks/hook_tasks/_rules/profile_rules.json +25 -0
- higpertext/hooks/hook_tasks/_rules/quality_rules.py +86 -0
- higpertext/hooks/hook_tasks/_rules/security_rules.py +214 -0
- higpertext/hooks/hook_tasks/_rules/session_rules.py +316 -0
- higpertext/hooks/hook_tasks/_rules/telemetry_rules.py +121 -0
- higpertext/hooks/hook_tasks/audit_logger_hook.py +28 -0
- higpertext/hooks/hook_tasks/hook_bash_guard.py +101 -0
- higpertext/hooks/hook_tasks/hook_code_quality.py +48 -0
- higpertext/hooks/hook_tasks/hook_context_hint.py +46 -0
- higpertext/hooks/hook_tasks/hook_context_manager.py +44 -0
- higpertext/hooks/hook_tasks/hook_io.py +122 -0
- higpertext/hooks/hook_tasks/hook_loop_guard.py +182 -0
- higpertext/hooks/hook_tasks/hook_post_observer.py +54 -0
- higpertext/hooks/hook_tasks/hook_read_guard.py +85 -0
- higpertext/hooks/hook_tasks/hook_security_guard.py +81 -0
- higpertext/hooks/hook_tasks/hook_session_prompt.py +83 -0
- higpertext/hooks/hook_tasks/hook_session_stop.py +115 -0
- higpertext/hooks/hook_tasks/hook_utils.py +144 -0
- higpertext/hooks/hook_tasks/session_guard_hook.py +23 -0
- higpertext/hooks/hook_tasks/telemetry_utils.py +176 -0
- higpertext/hooks/hook_tasks/test_echo_hook.py +33 -0
- higpertext/hooks/hook_tasks/webhook_hook.py +54 -0
- higpertext/hooks/hook_tasks/workflow_runner_hook.py +49 -0
- higpertext/hooks/hooks_catalog.json +116 -0
- higpertext/kernel/__init__.py +63 -0
- higpertext/kernel/_compat.py +138 -0
- higpertext/kernel/app_config.py +117 -0
- higpertext/kernel/application/__init__.py +13 -0
- higpertext/kernel/application/agent_registry.py +102 -0
- higpertext/kernel/application/capability_manager.py +61 -0
- higpertext/kernel/application/commit_reporter.py +247 -0
- higpertext/kernel/application/context_builder.py +166 -0
- higpertext/kernel/application/context_engine.py +409 -0
- higpertext/kernel/application/engine.py +41 -0
- higpertext/kernel/application/env_runtime.py +174 -0
- higpertext/kernel/application/environment_manager.py +154 -0
- higpertext/kernel/application/governance.py +192 -0
- higpertext/kernel/application/hook_registry.py +102 -0
- higpertext/kernel/application/hook_renderer.py +720 -0
- higpertext/kernel/application/ports.py +49 -0
- higpertext/kernel/application/profile_learner.py +358 -0
- higpertext/kernel/application/profile_service.py +205 -0
- higpertext/kernel/application/profile_services.py +6 -0
- higpertext/kernel/application/profile_use_cases.py +93 -0
- higpertext/kernel/application/rag_service.py +75 -0
- higpertext/kernel/application/roadmap_reporter.py +178 -0
- higpertext/kernel/application/semantic_engine.py +258 -0
- higpertext/kernel/application/session_services.py +33 -0
- higpertext/kernel/application/skill_hook_compiler.py +85 -0
- higpertext/kernel/application/telemetry.py +326 -0
- higpertext/kernel/application/workflow_manager.py +176 -0
- higpertext/kernel/config_paths.py +66 -0
- higpertext/kernel/domain/__init__.py +12 -0
- higpertext/kernel/domain/agent_registry.py +23 -0
- higpertext/kernel/domain/commit_reporter.py +155 -0
- higpertext/kernel/domain/compilers.py +7 -0
- higpertext/kernel/domain/context_engine.py +319 -0
- higpertext/kernel/domain/entities.py +51 -0
- higpertext/kernel/domain/env_runtime.py +62 -0
- higpertext/kernel/domain/governance.py +198 -0
- higpertext/kernel/domain/hook_models.py +29 -0
- higpertext/kernel/domain/profile_learner.py +186 -0
- higpertext/kernel/domain/rag.py +70 -0
- higpertext/kernel/domain/repositories.py +8 -0
- higpertext/kernel/domain/roadmap_reporter.py +80 -0
- higpertext/kernel/domain/semantic_engine.py +107 -0
- higpertext/kernel/engine.py +42 -0
- higpertext/kernel/htx_resolver.py +69 -0
- higpertext/kernel/infrastructure/__init__.py +13 -0
- higpertext/kernel/infrastructure/agent_registry.py +40 -0
- higpertext/kernel/infrastructure/cache/capability_cache.py +319 -0
- higpertext/kernel/infrastructure/capability_helper.py +40 -0
- higpertext/kernel/infrastructure/cli/__init__.py +1 -0
- higpertext/kernel/infrastructure/cli/agent_commands.py +62 -0
- higpertext/kernel/infrastructure/cli/arguments.py +39 -0
- higpertext/kernel/infrastructure/cli/capability_command_builder.py +86 -0
- higpertext/kernel/infrastructure/cli/capability_task_service.py +234 -0
- higpertext/kernel/infrastructure/cli/cli_search.py +234 -0
- higpertext/kernel/infrastructure/cli/parameter_contracts.py +83 -0
- higpertext/kernel/infrastructure/cli/parser_builder.py +122 -0
- higpertext/kernel/infrastructure/cli/profile_commands.py +89 -0
- higpertext/kernel/infrastructure/cli/roadmap_commands.py +117 -0
- higpertext/kernel/infrastructure/cli/router.py +1110 -0
- higpertext/kernel/infrastructure/cli/session_commands.py +36 -0
- higpertext/kernel/infrastructure/cli/task_commands.py +23 -0
- higpertext/kernel/infrastructure/cli/task_result_reporter.py +56 -0
- higpertext/kernel/infrastructure/cli/workflow_commands.py +25 -0
- higpertext/kernel/infrastructure/compilers/__init__.py +3 -0
- higpertext/kernel/infrastructure/compilers/factory.py +27 -0
- higpertext/kernel/infrastructure/compilers/graph_compiler.py +20 -0
- higpertext/kernel/infrastructure/compilers/guide_compiler.py +50 -0
- higpertext/kernel/infrastructure/compilers/hook_compiler.py +69 -0
- higpertext/kernel/infrastructure/compilers/playbook_compiler.py +154 -0
- higpertext/kernel/infrastructure/context_engine.py +303 -0
- higpertext/kernel/infrastructure/database/local_vector_store.py +99 -0
- higpertext/kernel/infrastructure/deployment/__init__.py +1 -0
- higpertext/kernel/infrastructure/deployment/resource_deployer.py +283 -0
- higpertext/kernel/infrastructure/diagnostics/__init__.py +1 -0
- higpertext/kernel/infrastructure/diagnostics/health.py +191 -0
- higpertext/kernel/infrastructure/env_runtime.py +227 -0
- higpertext/kernel/infrastructure/execution/__init__.py +1 -0
- higpertext/kernel/infrastructure/execution/parallel.py +188 -0
- higpertext/kernel/infrastructure/execution/resilience.py +155 -0
- higpertext/kernel/infrastructure/file_repositories.py +213 -0
- higpertext/kernel/infrastructure/governance.py +198 -0
- higpertext/kernel/infrastructure/hook_config_loader.py +53 -0
- higpertext/kernel/infrastructure/hook_webhook_dispatcher.py +61 -0
- higpertext/kernel/infrastructure/hook_workflow_bridge.py +60 -0
- higpertext/kernel/infrastructure/llm/__init__.py +6 -0
- higpertext/kernel/infrastructure/llm/provider.py +46 -0
- higpertext/kernel/infrastructure/llm/providers/__init__.py +0 -0
- higpertext/kernel/infrastructure/llm/providers/anthropic_provider.py +94 -0
- higpertext/kernel/infrastructure/llm/providers/gemini_embeddings.py +74 -0
- higpertext/kernel/infrastructure/llm/providers/gemini_provider.py +101 -0
- higpertext/kernel/infrastructure/llm/providers/ollama_provider.py +110 -0
- higpertext/kernel/infrastructure/llm/providers/openai_provider.py +98 -0
- higpertext/kernel/infrastructure/llm/registry.py +81 -0
- higpertext/kernel/infrastructure/logger.py +303 -0
- higpertext/kernel/infrastructure/output_store.py +70 -0
- higpertext/kernel/infrastructure/parser/__init__.py +1 -0
- higpertext/kernel/infrastructure/parser/code_chunker.py +144 -0
- higpertext/kernel/infrastructure/parser/language/__init__.py +14 -0
- higpertext/kernel/infrastructure/parser/language/base.py +41 -0
- higpertext/kernel/infrastructure/parser/language/powershell_parser.py +35 -0
- higpertext/kernel/infrastructure/parser/language/python_parser.py +98 -0
- higpertext/kernel/infrastructure/parser/language/typescript_parser.py +91 -0
- higpertext/kernel/infrastructure/parser/semantic_graph.py +409 -0
- higpertext/kernel/infrastructure/presentation/__init__.py +1 -0
- higpertext/kernel/infrastructure/presentation/html_renderer.py +137 -0
- higpertext/kernel/infrastructure/presentation/markdown_renderer.py +84 -0
- higpertext/kernel/infrastructure/presentation/markdown_report_renderer.py +97 -0
- higpertext/kernel/infrastructure/profile_store.py +28 -0
- higpertext/kernel/infrastructure/semantic_engine.py +289 -0
- higpertext/kernel/infrastructure/telemetry_reporter.py +132 -0
- higpertext/kernel/infrastructure/validation/__init__.py +1 -0
- higpertext/kernel/infrastructure/validation/contract_validator.py +163 -0
- higpertext/kernel/pkg_resources.py +38 -0
- higpertext/kernel/session_manager.py +319 -0
- higpertext/templates/env/generic-shell.yaml +21 -0
- higpertext/templates/env/node-vitest.yaml +27 -0
- higpertext/templates/env/python-pytest.yaml +29 -0
- higpertext/templates/html/commit_body.html +20 -0
- higpertext/templates/html/commit_diff.html +4 -0
- higpertext/templates/html/commit_index.html +29 -0
- higpertext/templates/html/commit_layer.html +11 -0
- higpertext/templates/html/commit_shell.html +28 -0
- higpertext/templates/html/graph_visualize.html +86 -0
- higpertext/templates/html/roadmap_body.html +12 -0
- higpertext/templates/html/roadmap_phase.html +5 -0
- higpertext/templates/html/roadmap_shell.html +29 -0
- higpertext/templates/markdown/commit_report.md +18 -0
- higpertext/templates/markdown/efficiency_report.md +12 -0
- higpertext/templates/markdown/roadmap_report.md +25 -0
- higpertext/templates/skills/best-practices.md +7 -0
- higpertext/templates/skills/clean-code.md +8 -0
- higpertext/templates/skills/ddd-standards.md +7 -0
- higpertext/templates/skills/tdd-practices.md +7 -0
- higpertext/templates/subagents/architect.md +7 -0
- higpertext/templates/subagents/test-engineer.md +7 -0
- higpertext/templates/workflows/build.json +23 -0
- higpertext/templates/workflows/compact.json +21 -0
- higpertext/templates/workflows/plan.json +59 -0
- higpertext/templates/workflows/review.json +26 -0
- higpertext/templates/workflows/spec.json +27 -0
- higpertext_cli-0.8.0.dist-info/METADATA +35 -0
- higpertext_cli-0.8.0.dist-info/RECORD +335 -0
- higpertext_cli-0.8.0.dist-info/WHEEL +5 -0
- higpertext_cli-0.8.0.dist-info/entry_points.txt +2 -0
- higpertext_cli-0.8.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,981 @@
|
|
|
1
|
+
"""higpertext Docs Sync — regenera documentación completa en docs/reference/ y docs/guides/."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from higpertext.kernel.infrastructure.logger import get_logger
|
|
7
|
+
from higpertext.kernel.app_config import INDEX_LINK as _INDEX_LINK
|
|
8
|
+
_log = get_logger()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _resolve_project_root(start: Path | None = None) -> Path:
|
|
12
|
+
"""Encuentra la raíz del proyecto que contiene capacidades y perfiles fuente."""
|
|
13
|
+
current = (start or Path.cwd()).resolve()
|
|
14
|
+
if current.is_file():
|
|
15
|
+
current = current.parent
|
|
16
|
+
for candidate in (current, *current.parents):
|
|
17
|
+
capabilities = candidate / "src" / "higpertext" / "capabilities"
|
|
18
|
+
profiles = candidate / "src" / "config" / "profiles"
|
|
19
|
+
if capabilities.exists() and profiles.exists():
|
|
20
|
+
return candidate
|
|
21
|
+
return current
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _load_governance(project_root: Path) -> dict:
|
|
25
|
+
path = project_root / "src" / "config" / "governance" / "guidelines_contract.json"
|
|
26
|
+
if path.exists():
|
|
27
|
+
try:
|
|
28
|
+
return json.loads(path.read_text(encoding="utf-8"))
|
|
29
|
+
except (OSError, json.JSONDecodeError): # nosec B110
|
|
30
|
+
pass
|
|
31
|
+
return {}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# ---------------------------------------------------------------------------
|
|
35
|
+
# Loaders
|
|
36
|
+
# ---------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _load_capabilities(capabilities_dir: Path) -> tuple[list, dict]:
|
|
40
|
+
capabilities, cap_dict = [], {}
|
|
41
|
+
for json_file in capabilities_dir.rglob("*.json"):
|
|
42
|
+
try:
|
|
43
|
+
data = json.loads(json_file.read_text(encoding="utf-8"))
|
|
44
|
+
cap_id = data.get("id")
|
|
45
|
+
if cap_id:
|
|
46
|
+
capabilities.append(data)
|
|
47
|
+
cap_dict[cap_id] = data.get("description", "Sin descripción")
|
|
48
|
+
except (OSError, json.JSONDecodeError) as e:
|
|
49
|
+
_log.warning(f"[!] Error leyendo capacidad {json_file.name}: {e}")
|
|
50
|
+
capabilities.sort(key=lambda x: x.get("id", ""))
|
|
51
|
+
return capabilities, cap_dict
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _load_profiles(profiles_dir: Path) -> list:
|
|
55
|
+
profiles = []
|
|
56
|
+
for json_file in profiles_dir.glob("*.json"):
|
|
57
|
+
try:
|
|
58
|
+
data = json.loads(json_file.read_text(encoding="utf-8"))
|
|
59
|
+
if data.get("name"):
|
|
60
|
+
profiles.append(data)
|
|
61
|
+
except (OSError, json.JSONDecodeError) as e:
|
|
62
|
+
_log.warning(f"[!] Error leyendo perfil {json_file.name}: {e}")
|
|
63
|
+
return sorted(profiles, key=lambda x: x.get("name", ""))
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _group_by_area(capabilities: list) -> dict:
|
|
67
|
+
areas: dict = {}
|
|
68
|
+
for cap in capabilities:
|
|
69
|
+
cap_id = cap.get("id", "")
|
|
70
|
+
area = cap_id.split(".")[0] if "." in cap_id else "global"
|
|
71
|
+
areas.setdefault(area, []).append(cap)
|
|
72
|
+
return areas
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# ---------------------------------------------------------------------------
|
|
76
|
+
# Reference: capabilities-catalog.md
|
|
77
|
+
# ---------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _render_cap_entry(cap: dict) -> list[str]:
|
|
81
|
+
cap_id = cap.get("id", "")
|
|
82
|
+
description = cap.get("description", "Sin descripción.")
|
|
83
|
+
entrypoint = cap.get("entrypoint", "N/A")
|
|
84
|
+
params = cap.get("parameters", [])
|
|
85
|
+
rules = cap.get("contract", {}).get("rules", [])
|
|
86
|
+
intercept = cap.get("bash_intercept")
|
|
87
|
+
|
|
88
|
+
lines = [
|
|
89
|
+
f"### `{cap_id}`",
|
|
90
|
+
f"**Propósito**: {description}",
|
|
91
|
+
"",
|
|
92
|
+
f"- **Entrypoint**: `{entrypoint}`",
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
if params:
|
|
96
|
+
lines += [
|
|
97
|
+
"- **Parámetros**:",
|
|
98
|
+
" | Parámetro | Requerido | Descripción |",
|
|
99
|
+
" |---|---|---|",
|
|
100
|
+
]
|
|
101
|
+
for p in params:
|
|
102
|
+
req = "Sí" if p.get("required") else "No"
|
|
103
|
+
lines.append(f" | `--{p['name']}` | {req} | {p.get('description', '')} |")
|
|
104
|
+
else:
|
|
105
|
+
lines.append("- **Parámetros**: No requiere parámetros.")
|
|
106
|
+
|
|
107
|
+
if rules:
|
|
108
|
+
lines.append("- **Contrato técnico**:")
|
|
109
|
+
for rule in rules:
|
|
110
|
+
lines.append(f" - {rule}")
|
|
111
|
+
|
|
112
|
+
if intercept:
|
|
113
|
+
lines += [
|
|
114
|
+
"- **Hook de intercepción bash**:",
|
|
115
|
+
f" - Patrón: `{intercept.get('pattern', '')}`",
|
|
116
|
+
f" - Acción: {intercept.get('description', '')}",
|
|
117
|
+
f" - Comando correcto: `{intercept.get('example', '')}`",
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
lines += ["", "---", ""]
|
|
121
|
+
return lines
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _build_capabilities_catalog(capabilities: list, areas: dict) -> list[str]:
|
|
125
|
+
total_caps = len(capabilities)
|
|
126
|
+
areas_list = ", ".join(f"`{a}`" for a in sorted(areas.keys()))
|
|
127
|
+
intercepted = [c for c in capabilities if c.get("bash_intercept")]
|
|
128
|
+
|
|
129
|
+
lines = [
|
|
130
|
+
"# Catálogo de Capacidades",
|
|
131
|
+
"",
|
|
132
|
+
"Referencia técnica exhaustiva de cada capacidad del higpertext Engine.",
|
|
133
|
+
"",
|
|
134
|
+
f"**Total**: {total_caps} capacidades | **Áreas**: {areas_list}",
|
|
135
|
+
"",
|
|
136
|
+
"---",
|
|
137
|
+
"",
|
|
138
|
+
"## Índice de áreas",
|
|
139
|
+
"",
|
|
140
|
+
]
|
|
141
|
+
for area in sorted(areas.keys()):
|
|
142
|
+
lines.append(f"- [`{area}`](#{area})")
|
|
143
|
+
lines += ["", "---", ""]
|
|
144
|
+
|
|
145
|
+
# Hook intercepts summary table
|
|
146
|
+
if intercepted:
|
|
147
|
+
lines += [
|
|
148
|
+
"## Resumen de Hook Intercepts",
|
|
149
|
+
"",
|
|
150
|
+
"Comandos bash interceptados automáticamente y redirigidos a su capacidad higpertext.",
|
|
151
|
+
"",
|
|
152
|
+
"| Patrón bash | Capacidad | Comando correcto |",
|
|
153
|
+
"|---|---|---|",
|
|
154
|
+
]
|
|
155
|
+
for cap in intercepted:
|
|
156
|
+
i = cap["bash_intercept"]
|
|
157
|
+
lines.append(
|
|
158
|
+
f"| `{i.get('pattern', '')}` " f"| `{cap['id']}` " f"| `{i.get('example', '')}` |"
|
|
159
|
+
)
|
|
160
|
+
lines += ["", "---", ""]
|
|
161
|
+
|
|
162
|
+
for area in sorted(areas.keys()):
|
|
163
|
+
lines.append(f"## Área: `{area}` {{#{area}}}")
|
|
164
|
+
lines.append("")
|
|
165
|
+
for cap in areas[area]:
|
|
166
|
+
lines += _render_cap_entry(cap)
|
|
167
|
+
|
|
168
|
+
lines.append(_INDEX_LINK)
|
|
169
|
+
return lines
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# ---------------------------------------------------------------------------
|
|
173
|
+
# Reference: profiles-catalog.md
|
|
174
|
+
# ---------------------------------------------------------------------------
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _build_profiles_catalog(profiles: list, cap_dict: dict) -> list[str]:
|
|
178
|
+
lines = [
|
|
179
|
+
"# Catálogo de Perfiles",
|
|
180
|
+
"",
|
|
181
|
+
"Los perfiles definen el rol, system prompt y capacidades disponibles para cada agente.",
|
|
182
|
+
"Se cargan desde `src/config/profiles/*.json`.",
|
|
183
|
+
"",
|
|
184
|
+
"## Resumen",
|
|
185
|
+
"",
|
|
186
|
+
"| Perfil | Rol | Caps | Gobernanza | Skills sesión | Subagentes sesión |",
|
|
187
|
+
"|---|---|---|---|---|---|",
|
|
188
|
+
]
|
|
189
|
+
for prof in profiles:
|
|
190
|
+
name = prof.get("name", "")
|
|
191
|
+
desc = prof.get("description", "")
|
|
192
|
+
num_caps = len(prof.get("capabilities", []))
|
|
193
|
+
gov = "✅" if prof.get("governance_access") else "❌"
|
|
194
|
+
skills = ", ".join(f"`{s}`" for s in prof.get("session_skills", [])) or "—"
|
|
195
|
+
subagents = ", ".join(f"`{sa}`" for sa in prof.get("session_subagents", [])) or "—"
|
|
196
|
+
lines.append(f"| `{name}` | {desc} | {num_caps} | {gov} | {skills} | {subagents} |")
|
|
197
|
+
|
|
198
|
+
lines += ["", "---", ""]
|
|
199
|
+
|
|
200
|
+
for prof in profiles:
|
|
201
|
+
name = prof.get("name", "")
|
|
202
|
+
desc = prof.get("description", "")
|
|
203
|
+
prompt = prof.get("system_prompt", "")
|
|
204
|
+
caps = prof.get("capabilities", [])
|
|
205
|
+
raw_hooks = prof.get("hooks", [])
|
|
206
|
+
hooks = raw_hooks if isinstance(raw_hooks, list) else []
|
|
207
|
+
|
|
208
|
+
lines += [
|
|
209
|
+
f"## `{name}`",
|
|
210
|
+
"",
|
|
211
|
+
f"**Descripción**: {desc}",
|
|
212
|
+
"",
|
|
213
|
+
f"**System Prompt**: {prompt}",
|
|
214
|
+
"",
|
|
215
|
+
]
|
|
216
|
+
|
|
217
|
+
if caps:
|
|
218
|
+
lines += ["**Capacidades**:", "| ID | Propósito |", "|---|---|"]
|
|
219
|
+
for c in sorted(caps):
|
|
220
|
+
c_desc = cap_dict.get(c, "_No encontrada en el catálogo_")
|
|
221
|
+
lines.append(f"| `{c}` | {c_desc} |")
|
|
222
|
+
else:
|
|
223
|
+
lines.append("**Capacidades**: No tiene capacidades explícitas.")
|
|
224
|
+
|
|
225
|
+
if hooks:
|
|
226
|
+
lines += ["", "**Hooks activos**:", "| ID | Evento |", "|---|---|"]
|
|
227
|
+
for h in hooks:
|
|
228
|
+
lines.append(f"| `{h.get('id', '')}` | `{h.get('event', '')}` |")
|
|
229
|
+
|
|
230
|
+
lines += [
|
|
231
|
+
"",
|
|
232
|
+
"**Cargar perfil**:",
|
|
233
|
+
"```bash",
|
|
234
|
+
f"htx profile load {name} --assistant claude",
|
|
235
|
+
f"htx profile load {name} --assistant gemini",
|
|
236
|
+
"```",
|
|
237
|
+
"",
|
|
238
|
+
"---",
|
|
239
|
+
"",
|
|
240
|
+
]
|
|
241
|
+
|
|
242
|
+
lines += [
|
|
243
|
+
"## Cómo agregar un nuevo perfil",
|
|
244
|
+
"",
|
|
245
|
+
"1. Crea `src/config/profiles/<nombre>.json`:",
|
|
246
|
+
" ```json",
|
|
247
|
+
" {",
|
|
248
|
+
' "name": "mi-perfil",',
|
|
249
|
+
' "description": "Descripción del rol.",',
|
|
250
|
+
' "system_prompt": "Instrucciones base del agente.",',
|
|
251
|
+
' "capabilities": ["common.memory-manager"],',
|
|
252
|
+
' "governance_access": false,',
|
|
253
|
+
' "session_skills": [],',
|
|
254
|
+
' "session_subagents": []',
|
|
255
|
+
" }",
|
|
256
|
+
" ```",
|
|
257
|
+
"2. Ejecuta `htx task common.docs-sync` para regenerar este catálogo.",
|
|
258
|
+
"3. Verifica con `htx profile load mi-perfil --assistant claude`.",
|
|
259
|
+
"",
|
|
260
|
+
"---",
|
|
261
|
+
"",
|
|
262
|
+
_INDEX_LINK,
|
|
263
|
+
]
|
|
264
|
+
return lines
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
# ---------------------------------------------------------------------------
|
|
268
|
+
# Reference: hooks-reference.md (nuevo — técnico)
|
|
269
|
+
# ---------------------------------------------------------------------------
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def _build_hooks_reference(capabilities: list) -> list[str]:
|
|
273
|
+
intercepted = [c for c in capabilities if c.get("bash_intercept")]
|
|
274
|
+
|
|
275
|
+
lines = [
|
|
276
|
+
"# Referencia de Hooks — higpertext Engine",
|
|
277
|
+
"",
|
|
278
|
+
"Documentación técnica del sistema de hooks: arquitectura, flujo de ejecución,",
|
|
279
|
+
"intercepción de comandos bash y cómo extender las reglas.",
|
|
280
|
+
"",
|
|
281
|
+
"---",
|
|
282
|
+
"",
|
|
283
|
+
"## Arquitectura del Sistema de Hooks",
|
|
284
|
+
"",
|
|
285
|
+
"```",
|
|
286
|
+
"Usuario / Agente IA",
|
|
287
|
+
" │",
|
|
288
|
+
' │ tool_call: Bash(command="git status")',
|
|
289
|
+
" ▼",
|
|
290
|
+
"┌─────────────────────┐",
|
|
291
|
+
"│ Claude Code / IDE │",
|
|
292
|
+
"│ PreToolUse hook │──── stdin (JSON) ───▶ higpertext_enforcer.py",
|
|
293
|
+
"└─────────────────────┘ │",
|
|
294
|
+
" Lee bash_intercept",
|
|
295
|
+
" de cada capability JSON",
|
|
296
|
+
" │",
|
|
297
|
+
" ┌───────────────────────┴──────────────────────┐",
|
|
298
|
+
" │ ¿coincide algún patrón? │",
|
|
299
|
+
" │ │",
|
|
300
|
+
" SÍ │ NO │",
|
|
301
|
+
" ▼ ▼",
|
|
302
|
+
" continue:true + additionalContext continue:true (pasa)",
|
|
303
|
+
" (feedback al modelo, no corta el turno)",
|
|
304
|
+
" │",
|
|
305
|
+
" Modelo recibe feedback y auto-corrige",
|
|
306
|
+
" usando la capacidad higpertext correcta",
|
|
307
|
+
"```",
|
|
308
|
+
"",
|
|
309
|
+
"---",
|
|
310
|
+
"",
|
|
311
|
+
"## Tipos de Hook",
|
|
312
|
+
"",
|
|
313
|
+
"| Tipo | Comportamiento | Cuándo se usa |",
|
|
314
|
+
"|---|---|---|",
|
|
315
|
+
"| **Redirección** | `continue: true` + `additionalContext` | Comando bash con capacidad higpertext equivalente |", # noqa: E501
|
|
316
|
+
"| **Bloqueo duro** | `continue: false` | Violaciones de seguridad (`sudo`, comandos destructivos) |", # noqa: E501
|
|
317
|
+
"",
|
|
318
|
+
"> **Clave**: las redirecciones usan `continue: true` para que el modelo reciba",
|
|
319
|
+
"> el feedback sin cortar el turno ni la cadena de pensamiento.",
|
|
320
|
+
"",
|
|
321
|
+
"---",
|
|
322
|
+
"",
|
|
323
|
+
"## Whitelist — Comandos que nunca se interceptan",
|
|
324
|
+
"",
|
|
325
|
+
"```python",
|
|
326
|
+
"htx | .venv/bin/htx # el propio higpertext",
|
|
327
|
+
"git add | git push | git checkout # operaciones git de usuario",
|
|
328
|
+
"git merge | git rebase | git stash | git tag",
|
|
329
|
+
"```",
|
|
330
|
+
"",
|
|
331
|
+
"---",
|
|
332
|
+
"",
|
|
333
|
+
"## Reglas Dinámicas — `bash_intercept`",
|
|
334
|
+
"",
|
|
335
|
+
"El `higpertext_enforcer.py` **no tiene reglas hardcodeadas**. En cada ejecución escanea",
|
|
336
|
+
"todos los `*.json` de capacidades y extrae el campo `bash_intercept`:",
|
|
337
|
+
"",
|
|
338
|
+
"```json",
|
|
339
|
+
"{",
|
|
340
|
+
' "bash_intercept": {',
|
|
341
|
+
' "pattern": "\\\\bgit\\\\s+ls-files\\\\b",',
|
|
342
|
+
' "description": "Listar archivos trackeados en el índice git",',
|
|
343
|
+
' "example": "htx task ado_admin.git-ls-files --pattern \\"<filtro>\\"" ',
|
|
344
|
+
" }",
|
|
345
|
+
"}",
|
|
346
|
+
"```",
|
|
347
|
+
"",
|
|
348
|
+
"**Flujo de carga**:",
|
|
349
|
+
"```",
|
|
350
|
+
"higpertext_enforcer.py arranca",
|
|
351
|
+
" │",
|
|
352
|
+
" └─ _find_capabilities_root() → localiza src/capabilities/",
|
|
353
|
+
" │",
|
|
354
|
+
' └─ rglob("*.json") → itera todos los JSONs',
|
|
355
|
+
" │",
|
|
356
|
+
" └─ extrae bash_intercept.{pattern, description, example}",
|
|
357
|
+
" │",
|
|
358
|
+
" └─ construye lista de reglas en memoria",
|
|
359
|
+
"```",
|
|
360
|
+
"",
|
|
361
|
+
"**Ventaja**: agregar una nueva capacidad con `bash_intercept` activa",
|
|
362
|
+
"automáticamente su intercepción sin tocar el hook.",
|
|
363
|
+
"",
|
|
364
|
+
"---",
|
|
365
|
+
"",
|
|
366
|
+
"## Hook Intercepts activos",
|
|
367
|
+
"",
|
|
368
|
+
"| Capacidad | Patrón interceptado | Descripción | Comando correcto |",
|
|
369
|
+
"|---|---|---|---|",
|
|
370
|
+
]
|
|
371
|
+
|
|
372
|
+
for cap in intercepted:
|
|
373
|
+
i = cap["bash_intercept"]
|
|
374
|
+
lines.append(
|
|
375
|
+
f"| `{cap['id']}` "
|
|
376
|
+
f"| `{i.get('pattern', '')}` "
|
|
377
|
+
f"| {i.get('description', '')} "
|
|
378
|
+
f"| `{i.get('example', '')}` |"
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
lines += [
|
|
382
|
+
"",
|
|
383
|
+
"---",
|
|
384
|
+
"",
|
|
385
|
+
"## Cómo agregar una nueva regla de intercepción",
|
|
386
|
+
"",
|
|
387
|
+
"1. Abre el JSON de tu capacidad en `src/capabilities/<area>/<id>.json`",
|
|
388
|
+
"2. Agrega el campo `bash_intercept`:",
|
|
389
|
+
" ```json",
|
|
390
|
+
" {",
|
|
391
|
+
' "bash_intercept": {',
|
|
392
|
+
' "pattern": "\\\\bmi-comando\\\\b",',
|
|
393
|
+
' "description": "Descripción de qué hace",',
|
|
394
|
+
' "example": "htx task mi-area.mi-cap --param valor"',
|
|
395
|
+
" }",
|
|
396
|
+
" }",
|
|
397
|
+
" ```",
|
|
398
|
+
"3. Re-despliega los hooks: `htx profile load <perfil> --assistant claude`",
|
|
399
|
+
"4. La regla estará activa en el siguiente turno del agente.",
|
|
400
|
+
"",
|
|
401
|
+
"> No es necesario editar `higpertext_enforcer.py`.",
|
|
402
|
+
"",
|
|
403
|
+
"---",
|
|
404
|
+
"",
|
|
405
|
+
"## Cómo agregar un bloqueo duro",
|
|
406
|
+
"",
|
|
407
|
+
"Los bloqueos duros (como `sudo`) se definen directamente en `_HARD_BLOCKS`",
|
|
408
|
+
"dentro de `src/core/hooks/hook_tasks/higpertext_enforcer.py`:",
|
|
409
|
+
"",
|
|
410
|
+
"```python",
|
|
411
|
+
"_HARD_BLOCKS = [",
|
|
412
|
+
' (r"\\bsudo\\b", "sudo no está permitido por política de seguridad"),',
|
|
413
|
+
' (r"\\brm\\s+-rf\\b", "rm -rf está bloqueado — usa ado_admin.git-rm"),',
|
|
414
|
+
"]",
|
|
415
|
+
"```",
|
|
416
|
+
"",
|
|
417
|
+
"---",
|
|
418
|
+
"",
|
|
419
|
+
"## Archivos relevantes",
|
|
420
|
+
"",
|
|
421
|
+
"| Archivo | Rol |",
|
|
422
|
+
"|---|---|",
|
|
423
|
+
"| `src/core/hooks/hook_tasks/higpertext_enforcer.py` | Hook principal — carga reglas y evalúa comandos |", # noqa: E501
|
|
424
|
+
"| `src/core/hooks/hook_tasks/hook_utils.py` | Utilidades: `get_project_root()`, `run_higpertext_task()` |", # noqa: E501
|
|
425
|
+
"| `src/core/hooks/hook_registry.py` | Filtra hooks por asistente y perfil |",
|
|
426
|
+
"| `src/core/hooks/hook_renderer.py` | Genera config nativa por asistente (Claude, Gemini, Copilot) |", # noqa: E501
|
|
427
|
+
"| `src/core/hooks/config_loader.py` | Carga `.higpertext/hooks_config.json` |",
|
|
428
|
+
"| `.higpertext/hooks_config.json` | Registro de hooks activos con filtros por asistente/perfil |", # noqa: E501
|
|
429
|
+
"",
|
|
430
|
+
"---",
|
|
431
|
+
"",
|
|
432
|
+
_INDEX_LINK,
|
|
433
|
+
]
|
|
434
|
+
return lines
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
# ---------------------------------------------------------------------------
|
|
438
|
+
# Guide: hooks-guide.md (nuevo — usuario)
|
|
439
|
+
# ---------------------------------------------------------------------------
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def _build_hooks_guide(capabilities: list) -> list[str]:
|
|
443
|
+
intercepted = [c for c in capabilities if c.get("bash_intercept")]
|
|
444
|
+
|
|
445
|
+
lines = [
|
|
446
|
+
"# Guía de Hooks — Para el Agente y el Usuario",
|
|
447
|
+
"",
|
|
448
|
+
"Los hooks de higpertext actúan como un **guardia inteligente** entre el agente IA",
|
|
449
|
+
"y el sistema. Cuando el agente intenta usar un comando bash que tiene una",
|
|
450
|
+
"capacidad higpertext equivalente, el hook lo intercepta y le indica el comando correcto.",
|
|
451
|
+
"",
|
|
452
|
+
"---",
|
|
453
|
+
"",
|
|
454
|
+
"## ¿Por qué existen los hooks?",
|
|
455
|
+
"",
|
|
456
|
+
"El objetivo es que **todo pase por higpertext** en lugar de bash directo:",
|
|
457
|
+
"",
|
|
458
|
+
"| Sin hooks | Con hooks |",
|
|
459
|
+
"|---|---|",
|
|
460
|
+
"| `grep pattern ./src` | `htx task common.grep-search --pattern ...` |",
|
|
461
|
+
"| `git status` | `htx task ado_admin.git-diff` |",
|
|
462
|
+
"| `git ls-files` | `htx task ado_admin.git-ls-files` |",
|
|
463
|
+
"",
|
|
464
|
+
"**Ventaja**: el output de cada capacidad está formateado y controlado,",
|
|
465
|
+
"lo que permite mejorar la respuesta que recibe el agente sin tocar el código del modelo.",
|
|
466
|
+
"",
|
|
467
|
+
"---",
|
|
468
|
+
"",
|
|
469
|
+
"## ¿Cómo funciona para el agente?",
|
|
470
|
+
"",
|
|
471
|
+
"1. El agente intenta ejecutar `git status`",
|
|
472
|
+
"2. El hook intercepta antes de ejecutar",
|
|
473
|
+
"3. El agente recibe feedback con el comando correcto",
|
|
474
|
+
"4. El agente **no pierde el hilo de la conversación** — el turno continúa",
|
|
475
|
+
"5. El agente re-ejecuta con `htx task ado_admin.git-diff`",
|
|
476
|
+
"",
|
|
477
|
+
"---",
|
|
478
|
+
"",
|
|
479
|
+
"## Comandos interceptados actualmente",
|
|
480
|
+
"",
|
|
481
|
+
"| Si intentas... | Usa en su lugar... |",
|
|
482
|
+
"|---|---|",
|
|
483
|
+
]
|
|
484
|
+
|
|
485
|
+
for cap in intercepted:
|
|
486
|
+
i = cap["bash_intercept"]
|
|
487
|
+
lines.append(f"| `{
|
|
488
|
+
i.get(
|
|
489
|
+
'pattern',
|
|
490
|
+
'').replace(
|
|
491
|
+
chr(92) +
|
|
492
|
+
'b',
|
|
493
|
+
'').replace(
|
|
494
|
+
chr(92) +
|
|
495
|
+
's+',
|
|
496
|
+
' ').replace(
|
|
497
|
+
chr(92),
|
|
498
|
+
'').strip()}` | `{
|
|
499
|
+
i.get(
|
|
500
|
+
'example',
|
|
501
|
+
'')}` |")
|
|
502
|
+
|
|
503
|
+
lines += [
|
|
504
|
+
"",
|
|
505
|
+
"---",
|
|
506
|
+
"",
|
|
507
|
+
"## Comandos que NUNCA se interceptan",
|
|
508
|
+
"",
|
|
509
|
+
"Estos comandos git los ejecuta el **usuario**, no el agente:",
|
|
510
|
+
"",
|
|
511
|
+
"```bash",
|
|
512
|
+
"git push # solo el usuario hace push al remoto",
|
|
513
|
+
"git checkout # cambio de rama — decisión del usuario",
|
|
514
|
+
"git merge # merges — requieren revisión humana",
|
|
515
|
+
"git add # staging — parte del flujo del committer",
|
|
516
|
+
"```",
|
|
517
|
+
"",
|
|
518
|
+
"---",
|
|
519
|
+
"",
|
|
520
|
+
"## ¿Cómo se activan los hooks?",
|
|
521
|
+
"",
|
|
522
|
+
"Los hooks se despliegan automáticamente al cargar un perfil:",
|
|
523
|
+
"",
|
|
524
|
+
"```bash",
|
|
525
|
+
"htx profile load software_developer --assistant claude",
|
|
526
|
+
"```",
|
|
527
|
+
"",
|
|
528
|
+
"Esto copia los scripts de hook a `.claude/hooks/` y actualiza `.claude/settings.json`.",
|
|
529
|
+
"",
|
|
530
|
+
"---",
|
|
531
|
+
"",
|
|
532
|
+
"## ¿Qué pasa si el hook bloquea algo por error?",
|
|
533
|
+
"",
|
|
534
|
+
"Si un comando legítimo es interceptado y no tiene capacidad equivalente,",
|
|
535
|
+
"puedes agregarlo a la whitelist en `higpertext_enforcer.py` o crear una nueva",
|
|
536
|
+
"capacidad con su `bash_intercept`. Ver la [Referencia Técnica de Hooks](../reference/hooks-reference.md).", # noqa: E501
|
|
537
|
+
"",
|
|
538
|
+
"---",
|
|
539
|
+
"",
|
|
540
|
+
_INDEX_LINK,
|
|
541
|
+
]
|
|
542
|
+
return lines
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
# ---------------------------------------------------------------------------
|
|
546
|
+
# Guide: capability-development.md (actualizado con bash_intercept)
|
|
547
|
+
# ---------------------------------------------------------------------------
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
def _build_capability_dev_guide() -> list[str]:
|
|
551
|
+
return [
|
|
552
|
+
"# Desarrollo de Capacidades",
|
|
553
|
+
"",
|
|
554
|
+
"Cómo crear una nueva capacidad para el higpertext Engine.",
|
|
555
|
+
"",
|
|
556
|
+
"---",
|
|
557
|
+
"",
|
|
558
|
+
"## Estructura de una capacidad",
|
|
559
|
+
"",
|
|
560
|
+
"```",
|
|
561
|
+
"src/capabilities/<area>/",
|
|
562
|
+
"├── mi-capacidad.json ← registro: metadatos, parámetros, contrato",
|
|
563
|
+
"└── scripts/",
|
|
564
|
+
" └── mi_capacidad.py ← script ejecutable",
|
|
565
|
+
"```",
|
|
566
|
+
"",
|
|
567
|
+
"---",
|
|
568
|
+
"",
|
|
569
|
+
"## Paso 1 — Crear el script",
|
|
570
|
+
"",
|
|
571
|
+
"```python",
|
|
572
|
+
'"""higpertext Mi Capacidad — descripción breve."""',
|
|
573
|
+
"import argparse, sys",
|
|
574
|
+
"",
|
|
575
|
+
"def main():",
|
|
576
|
+
" parser = argparse.ArgumentParser()",
|
|
577
|
+
' parser.add_argument("--param", required=True)',
|
|
578
|
+
" args = parser.parse_args()",
|
|
579
|
+
' print(f"[OK] {args.param}")',
|
|
580
|
+
"",
|
|
581
|
+
'if __name__ == "__main__":',
|
|
582
|
+
" main()",
|
|
583
|
+
"```",
|
|
584
|
+
"",
|
|
585
|
+
"---",
|
|
586
|
+
"",
|
|
587
|
+
"## Paso 2 — Crear el JSON de registro",
|
|
588
|
+
"",
|
|
589
|
+
"```json",
|
|
590
|
+
"{",
|
|
591
|
+
' "id": "mi-area.mi-capacidad",',
|
|
592
|
+
' "version": "1.0.0",',
|
|
593
|
+
' "description": "Qué hace esta capacidad.",',
|
|
594
|
+
' "entrypoint": "capabilities/mi-area/scripts/mi_capacidad.py",',
|
|
595
|
+
' "language": "python",',
|
|
596
|
+
' "parameters": [',
|
|
597
|
+
" {",
|
|
598
|
+
' "name": "param",',
|
|
599
|
+
' "description": "Descripción del parámetro.",',
|
|
600
|
+
' "required": true',
|
|
601
|
+
" }",
|
|
602
|
+
" ],",
|
|
603
|
+
' "contract": {',
|
|
604
|
+
' "rules": [',
|
|
605
|
+
' "El output debe incluir [OK] al completarse."',
|
|
606
|
+
" ]",
|
|
607
|
+
" }",
|
|
608
|
+
"}",
|
|
609
|
+
"```",
|
|
610
|
+
"",
|
|
611
|
+
"---",
|
|
612
|
+
"",
|
|
613
|
+
"## Paso 3 — Agregar intercepción bash (opcional)",
|
|
614
|
+
"",
|
|
615
|
+
"Si tu capacidad reemplaza un comando bash, declara `bash_intercept`",
|
|
616
|
+
"en el JSON. El hook del agente lo detectará automáticamente:",
|
|
617
|
+
"",
|
|
618
|
+
"```json",
|
|
619
|
+
"{",
|
|
620
|
+
' "bash_intercept": {',
|
|
621
|
+
' "pattern": "\\\\bmi-comando\\\\b",',
|
|
622
|
+
' "description": "Descripción de qué intercepta",',
|
|
623
|
+
' "example": "htx task mi-area.mi-capacidad --param valor"',
|
|
624
|
+
" }",
|
|
625
|
+
"}",
|
|
626
|
+
"```",
|
|
627
|
+
"",
|
|
628
|
+
"No necesitas editar `higpertext_enforcer.py` — el hook carga las reglas",
|
|
629
|
+
"dinámicamente desde los JSONs en cada ejecución.",
|
|
630
|
+
"",
|
|
631
|
+
"---",
|
|
632
|
+
"",
|
|
633
|
+
"## Paso 4 — Registrar en el perfil",
|
|
634
|
+
"",
|
|
635
|
+
"Agrega el ID al array `capabilities` del perfil en `src/config/profiles/<perfil>.json`:",
|
|
636
|
+
"",
|
|
637
|
+
"```json",
|
|
638
|
+
'{ "capabilities": ["...", "mi-area.mi-capacidad"] }',
|
|
639
|
+
"```",
|
|
640
|
+
"",
|
|
641
|
+
"---",
|
|
642
|
+
"",
|
|
643
|
+
"## Paso 5 — Verificar",
|
|
644
|
+
"",
|
|
645
|
+
"```bash",
|
|
646
|
+
"htx task mi-area.mi-capacidad --param valor",
|
|
647
|
+
"htx task common.docs-sync # actualiza el catálogo",
|
|
648
|
+
"```",
|
|
649
|
+
"",
|
|
650
|
+
"---",
|
|
651
|
+
"",
|
|
652
|
+
_INDEX_LINK,
|
|
653
|
+
]
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
# ---------------------------------------------------------------------------
|
|
657
|
+
# README.md (índice principal)
|
|
658
|
+
# ---------------------------------------------------------------------------
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
def _build_readme(capabilities: list, profiles: list) -> list[str]:
|
|
662
|
+
total_caps = len(capabilities)
|
|
663
|
+
total_profiles = len(profiles)
|
|
664
|
+
intercepted = len([c for c in capabilities if c.get("bash_intercept")])
|
|
665
|
+
|
|
666
|
+
return [
|
|
667
|
+
"# Documentación — higpertext Engine v5.0",
|
|
668
|
+
"",
|
|
669
|
+
"Framework de orquestación de agentes IA para DevSecOps.",
|
|
670
|
+
f"**{total_caps}** capacidades · **{total_profiles}** perfiles · **{intercepted}** hook intercepts activos", # noqa: E501
|
|
671
|
+
"",
|
|
672
|
+
"---",
|
|
673
|
+
"",
|
|
674
|
+
"## Primeros pasos (`01-getting-started/`)",
|
|
675
|
+
"",
|
|
676
|
+
"| Doc | Contenido |",
|
|
677
|
+
"|---|---|",
|
|
678
|
+
"| [Instalación](01-getting-started/installation.md) | Requisitos, `.venv`, `.env` |",
|
|
679
|
+
"| [Primer arranque](01-getting-started/first-run.md) | `init`, `profile load`, `session-start` |", # noqa: E501
|
|
680
|
+
"| [Conceptos clave](01-getting-started/concepts.md) | Perfiles, capacidades, hooks, sesiones, workflows |", # noqa: E501
|
|
681
|
+
"",
|
|
682
|
+
"---",
|
|
683
|
+
"",
|
|
684
|
+
"## Guías de uso (`02-guides/`)",
|
|
685
|
+
"",
|
|
686
|
+
"| Doc | Contenido |",
|
|
687
|
+
"|---|---|",
|
|
688
|
+
"| [Sesiones de Desarrollo](02-guides/sessions.md) | Ciclo de vida de sesiones, skills y subagentes |", # noqa: E501
|
|
689
|
+
"| [Hooks — Guía de uso](02-guides/hooks-guide.md) | Qué interceptan los hooks y por qué existen |", # noqa: E501
|
|
690
|
+
"| [Gobernanza](02-guides/governance.md) | Lineamientos obligatorios: PRs, seguridad, deployments |", # noqa: E501
|
|
691
|
+
"| [Memoria del Agente](02-guides/agent-memory.md) | Cómo persiste y consulta el historial de acciones |", # noqa: E501
|
|
692
|
+
"| [FAQ](02-guides/faq.md) | Portabilidad, entornos virtuales, secretos |",
|
|
693
|
+
"",
|
|
694
|
+
"---",
|
|
695
|
+
"",
|
|
696
|
+
"## Extender el framework (`03-extending/`)",
|
|
697
|
+
"",
|
|
698
|
+
"| Doc | Contenido |",
|
|
699
|
+
"|---|---|",
|
|
700
|
+
"| [Desarrollo de Capacidades](03-extending/capability-development.md) | Crear nueva capacidad con contrato y hook |", # noqa: E501
|
|
701
|
+
"| [Workflows Personalizados](03-extending/custom-workflows.md) | Cómo crear flujos YAML por proyecto |", # noqa: E501
|
|
702
|
+
"| [Gobernanza Personalizada](03-extending/custom-guidelines.md) | Cómo estructurar lineamientos propios |", # noqa: E501
|
|
703
|
+
"",
|
|
704
|
+
"---",
|
|
705
|
+
"",
|
|
706
|
+
"## Referencia técnica (`04-reference/`)",
|
|
707
|
+
"",
|
|
708
|
+
"Especificaciones exhaustivas — qué existe y cómo funciona internamente.",
|
|
709
|
+
"",
|
|
710
|
+
"| Doc | Contenido |",
|
|
711
|
+
"|---|---|",
|
|
712
|
+
"| [Arquitectura](04-reference/architecture.md) | Kernel, perfiles, capacidades, adaptadores LLM y flujo de ejecución |", # noqa: E501
|
|
713
|
+
f"| [Catálogo de Capacidades](04-reference/capabilities-catalog.md) | {total_caps} capacidades con parámetros, contratos y hook intercepts |", # noqa: E501
|
|
714
|
+
f"| [Catálogo de Perfiles](04-reference/profiles-catalog.md) | {total_profiles} perfiles con capacidades y recursos de sesión |", # noqa: E501
|
|
715
|
+
"| [Hooks — Referencia técnica](04-reference/hooks-reference.md) | Arquitectura de hooks, reglas dinámicas, cómo extender |", # noqa: E501
|
|
716
|
+
"| [Gobernanza — Referencia](04-reference/governance-reference.md) | Lineamientos, formato de commit, reglas activas |", # noqa: E501
|
|
717
|
+
"| [Módulos del Kernel](04-reference/kernel-modules.md) | API interna de cada módulo Python del kernel |", # noqa: E501
|
|
718
|
+
"| [Adaptadores LLM](04-reference/llm-adapters.md) | Cómo cada adaptador genera reglas para su asistente IA |", # noqa: E501
|
|
719
|
+
"| [Telemetría](04-reference/telemetry.md) | Métricas de uso, tokens y productividad |",
|
|
720
|
+
"",
|
|
721
|
+
"---",
|
|
722
|
+
"",
|
|
723
|
+
"## Flujos de Trabajo (`workflows/`)",
|
|
724
|
+
"",
|
|
725
|
+
"| Doc | Dominio |",
|
|
726
|
+
"|---|---|",
|
|
727
|
+
"| [Spec → Plan → Sesión](workflows/how-to/spec-plan-session.md) | Ciclo de desarrollo |",
|
|
728
|
+
"| [Motor de Playbooks](workflows/engine/playbooks-reference.md) | Técnico |",
|
|
729
|
+
"| [De Incidente a Presentación](workflows/sre/postmortem-to-presentation.md) | SRE |",
|
|
730
|
+
"| [Monitoreo Continuo](workflows/sre/continuous-monitoring.md) | SRE |",
|
|
731
|
+
"| [Bootstrap Multi-Proyecto](workflows/ops/multi-project-migration.md) | Ops |",
|
|
732
|
+
"",
|
|
733
|
+
"Ver criterio workflow vs capacidad: [workflows/README.md](workflows/README.md)",
|
|
734
|
+
"",
|
|
735
|
+
"---",
|
|
736
|
+
"",
|
|
737
|
+
"## Inicio rápido",
|
|
738
|
+
"",
|
|
739
|
+
"```bash",
|
|
740
|
+
"# 1. Entorno",
|
|
741
|
+
"python -m venv .venv && source .venv/bin/activate",
|
|
742
|
+
"pip install -r requirements.txt",
|
|
743
|
+
"",
|
|
744
|
+
"# 2. Inicializar asistente",
|
|
745
|
+
"htx init --assistant claude",
|
|
746
|
+
"",
|
|
747
|
+
"# 3. Cargar perfil",
|
|
748
|
+
"htx profile load software_developer --assistant claude",
|
|
749
|
+
"",
|
|
750
|
+
"# 4. Verificar integridad",
|
|
751
|
+
"htx task common.higpertext-tester",
|
|
752
|
+
"",
|
|
753
|
+
"# 5. Ejecutar una tarea",
|
|
754
|
+
"htx task ado_admin.code-quality --path ./src",
|
|
755
|
+
"```",
|
|
756
|
+
"",
|
|
757
|
+
"---",
|
|
758
|
+
"",
|
|
759
|
+
"## Mapa de la documentación",
|
|
760
|
+
"",
|
|
761
|
+
"```",
|
|
762
|
+
"docs/",
|
|
763
|
+
"├── README.md ← este archivo",
|
|
764
|
+
"├── 01-getting-started/ ← empieza aquí",
|
|
765
|
+
"│ ├── installation.md",
|
|
766
|
+
"│ ├── first-run.md",
|
|
767
|
+
"│ └── concepts.md",
|
|
768
|
+
"├── 02-guides/ ← uso diario",
|
|
769
|
+
"│ ├── sessions.md",
|
|
770
|
+
"│ ├── hooks-guide.md ← auto-generado",
|
|
771
|
+
"│ ├── governance.md",
|
|
772
|
+
"│ ├── agent-memory.md",
|
|
773
|
+
"│ └── faq.md",
|
|
774
|
+
"├── 03-extending/ ← extender el framework",
|
|
775
|
+
"│ ├── capability-development.md ← auto-generado",
|
|
776
|
+
"│ ├── custom-workflows.md",
|
|
777
|
+
"│ └── custom-guidelines.md",
|
|
778
|
+
"├── 04-reference/ ← técnico / exhaustivo",
|
|
779
|
+
"│ ├── architecture.md",
|
|
780
|
+
"│ ├── capabilities-catalog.md ← auto-generado",
|
|
781
|
+
"│ ├── profiles-catalog.md ← auto-generado",
|
|
782
|
+
"│ ├── hooks-reference.md ← auto-generado",
|
|
783
|
+
"│ ├── kernel-modules.md",
|
|
784
|
+
"│ ├── llm-adapters.md",
|
|
785
|
+
"│ ├── telemetry.md",
|
|
786
|
+
"│ └── governance-reference.md",
|
|
787
|
+
"└── workflows/",
|
|
788
|
+
" ├── README.md ← criterio workflow vs capacidad",
|
|
789
|
+
" ├── how-to/",
|
|
790
|
+
" ├── engine/",
|
|
791
|
+
" ├── sre/",
|
|
792
|
+
" └── ops/",
|
|
793
|
+
"```",
|
|
794
|
+
"",
|
|
795
|
+
"---",
|
|
796
|
+
"",
|
|
797
|
+
"*higpertext Engine v5.0 · auto-generado por `common.docs-sync`*",
|
|
798
|
+
]
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
# ---------------------------------------------------------------------------
|
|
802
|
+
# Reference: governance-reference.md (técnico — auto-generado)
|
|
803
|
+
# ---------------------------------------------------------------------------
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
def _build_governance_reference(governance: dict) -> list[str]:
|
|
807
|
+
guidelines = governance.get("guidelines", {})
|
|
808
|
+
commit_fmt = governance.get("commit_format", {})
|
|
809
|
+
|
|
810
|
+
lines = [
|
|
811
|
+
"# Referencia de Gobernanza — higpertext Engine",
|
|
812
|
+
"",
|
|
813
|
+
"Lineamientos obligatorios cargados desde `src/config/governance/guidelines_contract.json`.", # noqa: E501
|
|
814
|
+
"Este archivo es **auto-generado** — no editar manualmente.",
|
|
815
|
+
"",
|
|
816
|
+
"---",
|
|
817
|
+
"",
|
|
818
|
+
]
|
|
819
|
+
|
|
820
|
+
# Secciones de lineamientos
|
|
821
|
+
section_titles = {
|
|
822
|
+
"pull_requests": "Pull Requests",
|
|
823
|
+
"security": "Seguridad",
|
|
824
|
+
"deployments": "Deployments",
|
|
825
|
+
"code_quality": "Calidad de Código",
|
|
826
|
+
"doc_as_code": "Documentación como Código",
|
|
827
|
+
"gitflow_commits": "Gitflow y Commits",
|
|
828
|
+
}
|
|
829
|
+
for key, title in section_titles.items():
|
|
830
|
+
rules = guidelines.get(key, [])
|
|
831
|
+
if not rules:
|
|
832
|
+
continue
|
|
833
|
+
lines += [f"## {title}", ""]
|
|
834
|
+
for rule in rules:
|
|
835
|
+
lines.append(f"- {rule}")
|
|
836
|
+
lines += ["", "---", ""]
|
|
837
|
+
|
|
838
|
+
# Sección especial: formato de commit
|
|
839
|
+
if commit_fmt:
|
|
840
|
+
types = commit_fmt.get("types", [])
|
|
841
|
+
max_subj = commit_fmt.get("max_subject_length", 72)
|
|
842
|
+
max_body = commit_fmt.get("max_body_line_length", 100)
|
|
843
|
+
require_scope = commit_fmt.get("require_scope_on_types", [])
|
|
844
|
+
footer_tokens = commit_fmt.get("footer_tokens", [])
|
|
845
|
+
|
|
846
|
+
lines += [
|
|
847
|
+
"## Formato de Commit (`commit_format`)",
|
|
848
|
+
"",
|
|
849
|
+
"Leído en runtime por `ado_admin.committer` para validar cada mensaje.",
|
|
850
|
+
"",
|
|
851
|
+
"| Campo | Valor |",
|
|
852
|
+
"|---|---|",
|
|
853
|
+
f"| Tipos permitidos | {', '.join(f'`{t}`' for t in types)} |",
|
|
854
|
+
f"| Longitud máxima del subject | `{max_subj}` caracteres |",
|
|
855
|
+
f"| Longitud máxima de línea en body | `{max_body}` caracteres |",
|
|
856
|
+
f"| Scope requerido en tipos | {', '.join(f'`{t}`' for t in require_scope) or '—'} |",
|
|
857
|
+
f"| Tokens de footer reconocidos | {
|
|
858
|
+
', '.join(
|
|
859
|
+
f'`{t}`' for t in footer_tokens) or '—'} |",
|
|
860
|
+
"",
|
|
861
|
+
"### Anatomía de un mensaje bien formado",
|
|
862
|
+
"",
|
|
863
|
+
"```",
|
|
864
|
+
"feat(hooks): add dynamic bash_intercept rules from capability JSONs",
|
|
865
|
+
"│ │ │",
|
|
866
|
+
"│ │ └─ description: imperativo, sin punto final, ≤ 72 chars",
|
|
867
|
+
"│ └─────── scope: módulo o área afectada (requerido en feat/fix)",
|
|
868
|
+
"└──────────── type: uno de los tipos permitidos",
|
|
869
|
+
"",
|
|
870
|
+
"Replace hardcoded _RULES list in higpertext_enforcer.py with runtime",
|
|
871
|
+
"loading from bash_intercept field in each capability JSON.",
|
|
872
|
+
"│",
|
|
873
|
+
"└─ body: explicación del porqué, ≤ 100 chars por línea",
|
|
874
|
+
"",
|
|
875
|
+
"Closes #42",
|
|
876
|
+
"│",
|
|
877
|
+
"└─ footer: referencias, breaking changes, co-autores",
|
|
878
|
+
"```",
|
|
879
|
+
"",
|
|
880
|
+
"### Ejemplos correctos",
|
|
881
|
+
"",
|
|
882
|
+
"```bash",
|
|
883
|
+
"# Mínimo válido",
|
|
884
|
+
"chore: update .gitignore",
|
|
885
|
+
"",
|
|
886
|
+
"# Con scope (requerido para feat/fix)",
|
|
887
|
+
"fix(committer): parse multiline messages correctly",
|
|
888
|
+
"",
|
|
889
|
+
"# Con body y footer",
|
|
890
|
+
"feat(hooks): block git push from agent",
|
|
891
|
+
"",
|
|
892
|
+
"Add git push to _HARD_BLOCKS so the agent cannot publish",
|
|
893
|
+
"changes to the remote without user approval.",
|
|
894
|
+
"",
|
|
895
|
+
"Closes #15",
|
|
896
|
+
"```",
|
|
897
|
+
"",
|
|
898
|
+
"### Cómo modificar las reglas",
|
|
899
|
+
"",
|
|
900
|
+
"Edita `src/config/governance/guidelines_contract.json` sección `commit_format`.",
|
|
901
|
+
"Los cambios aplican en el siguiente commit — no requiere redeploy.",
|
|
902
|
+
"",
|
|
903
|
+
"---",
|
|
904
|
+
"",
|
|
905
|
+
_INDEX_LINK,
|
|
906
|
+
]
|
|
907
|
+
else:
|
|
908
|
+
lines.append("> `commit_format` no definido en guidelines_contract.json.")
|
|
909
|
+
lines += ["", _INDEX_LINK]
|
|
910
|
+
|
|
911
|
+
return lines
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
# ---------------------------------------------------------------------------
|
|
915
|
+
# Entry point
|
|
916
|
+
# ---------------------------------------------------------------------------
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
def run(project_root: Path) -> None:
|
|
920
|
+
project_root = _resolve_project_root(project_root)
|
|
921
|
+
capabilities_dir = project_root / "src" / "higpertext" / "capabilities"
|
|
922
|
+
profiles_dir = project_root / "src" / "config" / "profiles"
|
|
923
|
+
docs_ref_dir = project_root / "docs" / "04-reference"
|
|
924
|
+
docs_guides_dir = project_root / "docs" / "02-guides"
|
|
925
|
+
docs_extending_dir = project_root / "docs" / "03-extending"
|
|
926
|
+
docs_dir = project_root / "docs"
|
|
927
|
+
|
|
928
|
+
docs_ref_dir.mkdir(parents=True, exist_ok=True)
|
|
929
|
+
docs_guides_dir.mkdir(parents=True, exist_ok=True)
|
|
930
|
+
docs_extending_dir.mkdir(parents=True, exist_ok=True)
|
|
931
|
+
|
|
932
|
+
capabilities, cap_dict = _load_capabilities(capabilities_dir)
|
|
933
|
+
profiles = _load_profiles(profiles_dir)
|
|
934
|
+
areas = _group_by_area(capabilities)
|
|
935
|
+
governance = _load_governance(project_root)
|
|
936
|
+
|
|
937
|
+
# reference/capabilities-catalog.md
|
|
938
|
+
cap_lines = _build_capabilities_catalog(capabilities, areas)
|
|
939
|
+
(docs_ref_dir / "capabilities-catalog.md").write_text("\n".join(cap_lines), encoding="utf-8")
|
|
940
|
+
_log.ok(f"[SUCCESS] capabilities-catalog.md regenerado con {len(capabilities)} capacidades.")
|
|
941
|
+
|
|
942
|
+
# reference/profiles-catalog.md
|
|
943
|
+
prof_lines = _build_profiles_catalog(profiles, cap_dict)
|
|
944
|
+
(docs_ref_dir / "profiles-catalog.md").write_text("\n".join(prof_lines), encoding="utf-8")
|
|
945
|
+
_log.ok(f"[SUCCESS] profiles-catalog.md regenerado con {len(profiles)} perfiles.")
|
|
946
|
+
|
|
947
|
+
# reference/hooks-reference.md (técnico)
|
|
948
|
+
hooks_ref_lines = _build_hooks_reference(capabilities)
|
|
949
|
+
(docs_ref_dir / "hooks-reference.md").write_text("\n".join(hooks_ref_lines), encoding="utf-8")
|
|
950
|
+
intercepted_count = len([c for c in capabilities if c.get("bash_intercept")])
|
|
951
|
+
_log.ok(f"[SUCCESS] hooks-reference.md regenerado con {intercepted_count} intercepts activos.")
|
|
952
|
+
|
|
953
|
+
# 02-guides/hooks-guide.md (usuario)
|
|
954
|
+
hooks_guide_lines = _build_hooks_guide(capabilities)
|
|
955
|
+
(docs_guides_dir / "hooks-guide.md").write_text("\n".join(hooks_guide_lines), encoding="utf-8")
|
|
956
|
+
_log.ok("[SUCCESS] hooks-guide.md regenerado.")
|
|
957
|
+
|
|
958
|
+
# 03-extending/capability-development.md (actualizado)
|
|
959
|
+
cap_dev_lines = _build_capability_dev_guide()
|
|
960
|
+
(docs_extending_dir / "capability-development.md").write_text(
|
|
961
|
+
"\n".join(cap_dev_lines), encoding="utf-8"
|
|
962
|
+
)
|
|
963
|
+
_log.ok("[SUCCESS] capability-development.md actualizado con sección bash_intercept.")
|
|
964
|
+
|
|
965
|
+
# reference/governance-reference.md (auto-generado)
|
|
966
|
+
gov_lines = _build_governance_reference(governance)
|
|
967
|
+
(docs_ref_dir / "governance-reference.md").write_text("\n".join(gov_lines), encoding="utf-8")
|
|
968
|
+
_log.ok("[SUCCESS] governance-reference.md regenerado.")
|
|
969
|
+
|
|
970
|
+
# docs/README.md (índice principal)
|
|
971
|
+
readme_lines = _build_readme(capabilities, profiles)
|
|
972
|
+
(docs_dir / "README.md").write_text("\n".join(readme_lines), encoding="utf-8")
|
|
973
|
+
_log.ok("[SUCCESS] docs/README.md regenerado.")
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
def main():
|
|
977
|
+
run(_resolve_project_root(Path(__file__)))
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
if __name__ == "__main__":
|
|
981
|
+
main()
|