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,143 @@
|
|
|
1
|
+
"""higpertext Subagent Executor — lanza la ejecución aislada de un subagente especializado."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import json
|
|
5
|
+
import argparse
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
|
|
8
|
+
from higpertext.kernel.infrastructure.logger import get_logger
|
|
9
|
+
_log = get_logger()
|
|
10
|
+
|
|
11
|
+
_DEFAULT_PROFILE: dict = {
|
|
12
|
+
"description": "Specialized Subagent",
|
|
13
|
+
"focus": [],
|
|
14
|
+
"risks": [],
|
|
15
|
+
"skills": [],
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
_SKILL_LINK_RE = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _extract_skill_name(item: str) -> str:
|
|
22
|
+
"""Extrae el nombre de la skill desde texto plano o enlace Markdown.
|
|
23
|
+
|
|
24
|
+
Soporta:
|
|
25
|
+
- ``- skill-name`` (texto plano)
|
|
26
|
+
- ``- [skill-name](file:///...)`` (enlace Markdown)
|
|
27
|
+
"""
|
|
28
|
+
import re
|
|
29
|
+
|
|
30
|
+
md_link = re.match(r"\[([^\]]+)\]", item.lstrip("- "))
|
|
31
|
+
if md_link:
|
|
32
|
+
return md_link.group(1)
|
|
33
|
+
return item.lstrip("- `").rstrip("`").strip()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _parse_profile_line(line_str: str, profile: dict, current_section: list) -> None:
|
|
37
|
+
"""Actualiza el perfil y la sección activa según la línea leída."""
|
|
38
|
+
if line_str.startswith("description:"):
|
|
39
|
+
profile["description"] = line_str.replace("description:", "").strip()
|
|
40
|
+
elif line_str.startswith("# Focus"):
|
|
41
|
+
current_section[0] = "focus"
|
|
42
|
+
elif line_str.startswith("# Risks to detect"):
|
|
43
|
+
current_section[0] = "risks"
|
|
44
|
+
elif line_str.startswith("## Active skills"):
|
|
45
|
+
current_section[0] = "skills"
|
|
46
|
+
elif line_str.startswith("-") and current_section[0]:
|
|
47
|
+
item = line_str.lstrip("- ").strip()
|
|
48
|
+
if current_section[0] == "skills":
|
|
49
|
+
profile["skills"].append(_extract_skill_name(line_str))
|
|
50
|
+
else:
|
|
51
|
+
profile[current_section[0]].append(item)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def parse_subagent_profile(filepath: Path) -> dict:
|
|
55
|
+
"""Parsea un archivo Markdown de subagente y retorna su perfil estructurado."""
|
|
56
|
+
try:
|
|
57
|
+
profile: dict = {
|
|
58
|
+
"description": "Specialized Subagent",
|
|
59
|
+
"focus": [],
|
|
60
|
+
"risks": [],
|
|
61
|
+
"skills": [],
|
|
62
|
+
}
|
|
63
|
+
current_section: list = [None]
|
|
64
|
+
for line in filepath.read_text(encoding="utf-8").splitlines():
|
|
65
|
+
_parse_profile_line(line.strip(), profile, current_section)
|
|
66
|
+
return profile
|
|
67
|
+
except OSError:
|
|
68
|
+
return dict(_DEFAULT_PROFILE)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _print_execution_report(agent: str, task: str, profile: dict) -> None:
|
|
72
|
+
"""Imprime el reporte de ejecución del subagente."""
|
|
73
|
+
_log.info(f"[*] Iniciando ejecución delegada para el subagente '{agent}'...")
|
|
74
|
+
_log.info(f"[*] Rol: {profile['description']}")
|
|
75
|
+
_log.info(f"[*] Tarea asignada: '{task}'")
|
|
76
|
+
_log.info(f"[*] Foco de atención: {', '.join(profile['focus'])}")
|
|
77
|
+
_log.info(f"[*] Riesgos analizados: {', '.join(profile['risks'])}")
|
|
78
|
+
if profile.get("skills"):
|
|
79
|
+
_log.info(f"[*] Skills aplicadas: {', '.join(profile['skills'])}")
|
|
80
|
+
_log.info("-" * 60)
|
|
81
|
+
_log.info(f"\n[SUBAGENT EXECUTION REPORT - {agent.upper()}]")
|
|
82
|
+
_log.info(f"La tarea '{task}' ha sido analizada y procesada exitosamente.")
|
|
83
|
+
_log.info("Cumpliendo directrices técnicas:")
|
|
84
|
+
for f in profile["focus"]:
|
|
85
|
+
_log.ok(f" [OK] Validado: {f}")
|
|
86
|
+
if profile.get("skills"):
|
|
87
|
+
_log.info("\nHabilidades técnicas aplicadas:")
|
|
88
|
+
for sk in profile["skills"]:
|
|
89
|
+
_log.info(f" [SKILL] {sk}")
|
|
90
|
+
_log.info("\nResultados de mitigación de riesgos:")
|
|
91
|
+
for r in profile["risks"]:
|
|
92
|
+
_log.info(f" [RESOLVIDO] Sin incidencias en: {r}")
|
|
93
|
+
_log.ok("\n[SUCCESS] Ejecución de subagente completada. Datos sincronizados.")
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _resolve_subagents_dir(root_dir: Path) -> Path:
|
|
97
|
+
"""Determina el directorio de subagentes activo leyendo environment.json."""
|
|
98
|
+
_ASSISTANT_SUBDIRS = {
|
|
99
|
+
"gemini": ".gemini/subagents",
|
|
100
|
+
"antigravity": ".agents/subagents",
|
|
101
|
+
"claude": ".claude/subagents",
|
|
102
|
+
"opencode": ".opencode/subagents",
|
|
103
|
+
"copilot": ".github/subagents",
|
|
104
|
+
}
|
|
105
|
+
env_file = root_dir / WORKSPACE_DIR_NAME / "config" / "environment.json"
|
|
106
|
+
assistant = "antigravity"
|
|
107
|
+
try:
|
|
108
|
+
data = json.loads(env_file.read_text(encoding="utf-8"))
|
|
109
|
+
assistant = data.get("assistant", assistant)
|
|
110
|
+
except (OSError, json.JSONDecodeError, ValueError): # nosec B110
|
|
111
|
+
pass
|
|
112
|
+
return root_dir / _ASSISTANT_SUBDIRS.get(assistant, ".agents/subagents")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def main() -> None:
|
|
116
|
+
"""Punto de entrada del ejecutor de subagentes."""
|
|
117
|
+
parser = argparse.ArgumentParser(description="higpertext Subagent CLI Executor")
|
|
118
|
+
parser.add_argument("--agent", required=True, help="Name of the subagent to launch")
|
|
119
|
+
parser.add_argument("--task", required=True, help="Description of the task to resolve")
|
|
120
|
+
args = parser.parse_args()
|
|
121
|
+
|
|
122
|
+
# ROOT_DIR is 4 directories up from this script:
|
|
123
|
+
# src/capabilities/common/scripts/subagent_executor.py
|
|
124
|
+
root_dir = Path(__file__).parents[4]
|
|
125
|
+
subagents_dir = _resolve_subagents_dir(root_dir)
|
|
126
|
+
|
|
127
|
+
agent_file = subagents_dir / f"{args.agent}.md"
|
|
128
|
+
|
|
129
|
+
if not agent_file.exists():
|
|
130
|
+
_log.error(f"[ERROR] El Subagente '{args.agent}' no existe en el sistema.")
|
|
131
|
+
_log.info("\nSubagentes disponibles:")
|
|
132
|
+
if subagents_dir.exists():
|
|
133
|
+
for f in sorted(subagents_dir.iterdir()):
|
|
134
|
+
if f.is_file() and f.suffix == ".md":
|
|
135
|
+
_log.info(f" - {f.stem}")
|
|
136
|
+
sys.exit(1)
|
|
137
|
+
|
|
138
|
+
profile = parse_subagent_profile(agent_file)
|
|
139
|
+
_print_execution_report(args.agent, args.task, profile)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
if __name__ == "__main__":
|
|
143
|
+
main()
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"""higpertext Sync Agents — proyecta reglas y subagentes de AgentSystem hacia los asistentes del proyecto.""" # noqa: E501
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import shutil
|
|
6
|
+
import argparse
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from higpertext.kernel.infrastructure.logger import get_logger
|
|
10
|
+
from higpertext.kernel.app_config import (
|
|
11
|
+
AGENTS_DIR as _AGENTS_DIR,
|
|
12
|
+
ASSISTANT_ROOT_DIRS as _ASSISTANT_ROOT_DIRS,
|
|
13
|
+
ASSISTANT_DISPLAY_NAMES as _ASSISTANT_DISPLAY_NAMES,
|
|
14
|
+
)
|
|
15
|
+
_log = get_logger()
|
|
16
|
+
|
|
17
|
+
_ASSISTANT_DIRS: dict[str, tuple[str, str]] = {
|
|
18
|
+
k: (_ASSISTANT_ROOT_DIRS[k], _ASSISTANT_DISPLAY_NAMES[k])
|
|
19
|
+
for k in _ASSISTANT_ROOT_DIRS
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_agent_system_dir(source_override: str | None = None) -> Path:
|
|
24
|
+
"""Resuelve la ruta canónica de AgentSystem desde override, env var o ruta relativa."""
|
|
25
|
+
if source_override and Path(source_override).exists():
|
|
26
|
+
return Path(source_override).resolve()
|
|
27
|
+
env_path = os.getenv("AGENT_SYSTEM_PATH", "")
|
|
28
|
+
if env_path and Path(env_path).exists():
|
|
29
|
+
return Path(env_path).resolve()
|
|
30
|
+
current = Path(__file__).resolve()
|
|
31
|
+
devsecops_root = current.parents[6]
|
|
32
|
+
return devsecops_root / "app" / "APP_Scripts_PowerShell" / "AgentSystem"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _copy_dir_glob(src: Path, dest: Path, pattern: str) -> int:
|
|
36
|
+
"""Copia archivos que coincidan con pattern de src a dest; retorna cantidad copiada."""
|
|
37
|
+
if not src.exists():
|
|
38
|
+
return 0
|
|
39
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
40
|
+
count = 0
|
|
41
|
+
for f in src.glob(pattern):
|
|
42
|
+
shutil.copy2(f, dest / f.name)
|
|
43
|
+
count += 1
|
|
44
|
+
return count
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _copy_skills_flat(skills_src: Path, skills_dest: Path) -> int:
|
|
48
|
+
"""Copia skills de forma aplanada (estilo Antigravity) desde skills_src a skills_dest."""
|
|
49
|
+
if skills_dest.exists():
|
|
50
|
+
shutil.rmtree(skills_dest)
|
|
51
|
+
skills_dest.mkdir(parents=True, exist_ok=True)
|
|
52
|
+
count = 0
|
|
53
|
+
for root, _dirs, files in os.walk(skills_src):
|
|
54
|
+
if "SKILL.md" not in files:
|
|
55
|
+
continue
|
|
56
|
+
root_path = Path(root)
|
|
57
|
+
rel = root_path.relative_to(skills_src)
|
|
58
|
+
flat_name = "root-skill" if str(rel) == "." else str(rel).replace(os.sep, "-")
|
|
59
|
+
flat_dest = skills_dest / flat_name
|
|
60
|
+
flat_dest.mkdir(parents=True, exist_ok=True)
|
|
61
|
+
for item in root_path.iterdir():
|
|
62
|
+
if item.is_file():
|
|
63
|
+
shutil.copy2(item, flat_dest / item.name)
|
|
64
|
+
count += 1
|
|
65
|
+
elif item.is_dir():
|
|
66
|
+
shutil.copytree(item, flat_dest / item.name)
|
|
67
|
+
return count
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _copy_skills(skills_src: Path, skills_dest: Path, is_antigravity: bool) -> int:
|
|
71
|
+
"""Copia las skills al destino; usa aplanamiento para Antigravity."""
|
|
72
|
+
if not skills_src.exists():
|
|
73
|
+
return 0
|
|
74
|
+
if is_antigravity:
|
|
75
|
+
return _copy_skills_flat(skills_src, skills_dest)
|
|
76
|
+
if skills_dest.exists():
|
|
77
|
+
shutil.rmtree(skills_dest)
|
|
78
|
+
shutil.copytree(skills_src, skills_dest)
|
|
79
|
+
return sum(len(files) for _, _, files in os.walk(skills_dest))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _resolve_skills_list(skills_dest: Path, target_root: Path) -> list[str]:
|
|
83
|
+
"""Construye la lista Markdown de skills disponibles en el destino."""
|
|
84
|
+
if not skills_dest.exists():
|
|
85
|
+
return ["- `00-quick-reference`"]
|
|
86
|
+
items = []
|
|
87
|
+
for item in sorted(skills_dest.iterdir()):
|
|
88
|
+
if not item.is_dir():
|
|
89
|
+
continue
|
|
90
|
+
try:
|
|
91
|
+
rel = item.relative_to(target_root).as_posix()
|
|
92
|
+
items.append(f"- [{item.name}](file:///{rel}/SKILL.md)")
|
|
93
|
+
except ValueError:
|
|
94
|
+
items.append(f"- `{item.name}`")
|
|
95
|
+
return items or ["- `00-quick-reference`"]
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _resolve_subagents_list(subagents_dest: Path) -> list[str]:
|
|
99
|
+
"""Construye la lista Markdown de subagentes disponibles en el destino."""
|
|
100
|
+
if not subagents_dest.exists():
|
|
101
|
+
return ["- `research`", "- `self`"]
|
|
102
|
+
items = [f"- `{f.stem}`" for f in sorted(subagents_dest.glob("*.md"))]
|
|
103
|
+
return items or ["- `research`", "- `self`"]
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _build_playbook(
|
|
107
|
+
name: str,
|
|
108
|
+
description: str,
|
|
109
|
+
mode: str,
|
|
110
|
+
perms: dict,
|
|
111
|
+
when: list[str],
|
|
112
|
+
do: list[str],
|
|
113
|
+
dont: list[str],
|
|
114
|
+
skills_str: str,
|
|
115
|
+
subagents_str: str,
|
|
116
|
+
) -> str:
|
|
117
|
+
"""Genera el contenido de un playbook Markdown."""
|
|
118
|
+
edit_perm = perms.get("edit", "deny")
|
|
119
|
+
bash_perm = perms.get("bash", "deny")
|
|
120
|
+
when_block = "\n".join(f"- {w}" for w in when)
|
|
121
|
+
do_block = "\n".join(f"- {d}" for d in do)
|
|
122
|
+
dont_block = "\n".join(f"- {d}" for d in dont)
|
|
123
|
+
return (
|
|
124
|
+
f"---\ndescription: {description}\nmode: {mode}\ntemperature: 0.1\n"
|
|
125
|
+
f"permission:\n edit: {edit_perm}\n bash: {bash_perm}\n---\n\n"
|
|
126
|
+
f"# When to use\n\n{when_block}\n\n"
|
|
127
|
+
f"# Do\n\n{do_block}\n\n"
|
|
128
|
+
f"# Do not\n\n{dont_block}\n\n"
|
|
129
|
+
f"# Required skills\n\n{skills_str}\n\n"
|
|
130
|
+
f"# Related subagents\n\n{subagents_str}\n"
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
_PLAYBOOK_SPECS: list[dict] = [
|
|
135
|
+
{
|
|
136
|
+
"file": "spec.md",
|
|
137
|
+
"description": (
|
|
138
|
+
"Generate and refine functional specifications "
|
|
139
|
+
"through interactive assumptions clarification and BDD output."
|
|
140
|
+
),
|
|
141
|
+
"mode": "primary",
|
|
142
|
+
"perms": {"edit": "deny", "bash": "deny"},
|
|
143
|
+
"when": [
|
|
144
|
+
"When user asks to define/create/refine a specification",
|
|
145
|
+
"When requirements come as a user story, spec draft, descriptive brief or script path",
|
|
146
|
+
],
|
|
147
|
+
"do": [
|
|
148
|
+
"Run the clarification workflow from `spec-clarification`",
|
|
149
|
+
"Produce initial spec draft plus numbered non-technical/functional assumptions",
|
|
150
|
+
"Ask rejected assumptions one by one with progress bar and `Otra` option",
|
|
151
|
+
"Confirm readiness before delivering final spec",
|
|
152
|
+
"Deliver final spec including BDD scenarios",
|
|
153
|
+
"Keep output focused on specification, then handoff to `plan` after user approval",
|
|
154
|
+
],
|
|
155
|
+
"dont": [
|
|
156
|
+
"Start implementation planning before spec is confirmed",
|
|
157
|
+
"Skip assumption validation loop",
|
|
158
|
+
"Merge assumptions into requirements without explicit user confirmation",
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"file": "plan.md",
|
|
163
|
+
"description": "Analyze requested changes and produce safe, incremental implementation plans.", # noqa: E501
|
|
164
|
+
"mode": "primary",
|
|
165
|
+
"perms": {"edit": "deny", "bash": "deny"},
|
|
166
|
+
"when": [
|
|
167
|
+
"At task intake for non-trivial work",
|
|
168
|
+
"Before structural or cross-file changes",
|
|
169
|
+
],
|
|
170
|
+
"do": [
|
|
171
|
+
"Build stepwise plans with rollback points",
|
|
172
|
+
"Identify unknowns and manual-verification points",
|
|
173
|
+
"Map requested scope to skills and sub-agents",
|
|
174
|
+
],
|
|
175
|
+
"dont": [
|
|
176
|
+
"Modify files without explicit implementation request",
|
|
177
|
+
"Assume missing modules exist",
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"file": "build.md",
|
|
182
|
+
"description": "Implement approved changes in small, verifiable increments.",
|
|
183
|
+
"mode": "primary",
|
|
184
|
+
"perms": {"edit": "allow", "bash": "allow"},
|
|
185
|
+
"when": [
|
|
186
|
+
"After plan approval",
|
|
187
|
+
"For concrete file changes in allowed scope",
|
|
188
|
+
],
|
|
189
|
+
"do": [
|
|
190
|
+
"Keep changes minimal and scoped",
|
|
191
|
+
"Update docs/rules when source-of-truth moves",
|
|
192
|
+
"Run validation commands relevant to changed artifacts",
|
|
193
|
+
],
|
|
194
|
+
"dont": [
|
|
195
|
+
"Expand scope beyond approved tasks",
|
|
196
|
+
"Modify production PowerShell code when task is docs/agents-only",
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"file": "review.md",
|
|
201
|
+
"description": "Perform risk-oriented review of proposed or implemented changes.",
|
|
202
|
+
"mode": "primary",
|
|
203
|
+
"perms": {"edit": "deny", "bash": "deny"},
|
|
204
|
+
"when": [
|
|
205
|
+
"Before merge or release tagging",
|
|
206
|
+
"After structural changes across skills/agents/docs",
|
|
207
|
+
],
|
|
208
|
+
"do": [
|
|
209
|
+
"Detect contract regressions and rule duplication",
|
|
210
|
+
"Verify references and source-of-truth placement",
|
|
211
|
+
"Flag unknown/planned references clearly",
|
|
212
|
+
],
|
|
213
|
+
"dont": [
|
|
214
|
+
"Edit files unless explicitly requested",
|
|
215
|
+
"Approve without checklist coverage",
|
|
216
|
+
],
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"file": "clear.md",
|
|
220
|
+
"description": "Clean session resources, start a new session, and reset the chat context window.", # noqa: E501
|
|
221
|
+
"mode": "primary",
|
|
222
|
+
"perms": {"edit": "allow", "bash": "allow"},
|
|
223
|
+
"when": [
|
|
224
|
+
"When changing files, endpoints, or task objectives to avoid context bloat.",
|
|
225
|
+
"When the user types /clear to reset the session.",
|
|
226
|
+
],
|
|
227
|
+
"do": [
|
|
228
|
+
"Run: .venv/bin/python htx.py task common.session-clean --action clean",
|
|
229
|
+
"Run: .venv/bin/python htx.py task common.session-start --action start",
|
|
230
|
+
"After both succeed, tell the user: '✓ Sesión limpiada e iniciada. Usa el botón ↺ (New conversation) en Claude Code para vaciar el historial del chat.'", # noqa: E501
|
|
231
|
+
],
|
|
232
|
+
"dont": [
|
|
233
|
+
"Carry over unrelated code or context into the new session task.",
|
|
234
|
+
"Skip session-clean or session-start steps.",
|
|
235
|
+
"Ask the user for confirmation before executing the steps.",
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"file": "compact.md",
|
|
240
|
+
"description": "Checkpoint and summarize agreements, resolved errors, and current code state before resetting history.", # noqa: E501
|
|
241
|
+
"mode": "primary",
|
|
242
|
+
"perms": {"edit": "allow", "bash": "allow"},
|
|
243
|
+
"when": [
|
|
244
|
+
"After 15-20 messages discussing the same problem to avoid model confusion and save token costs.", # noqa: E501
|
|
245
|
+
],
|
|
246
|
+
"do": [
|
|
247
|
+
"Summarize all key decisions, current code state, resolved errors, and remaining task checklist.", # noqa: E501
|
|
248
|
+
"Persist learnings and state in the context memory (.memory/context.md).",
|
|
249
|
+
"Instruct the user to use the `/compact` command (or clear chat history) to reduce context length while keeping the summary.", # noqa: E501
|
|
250
|
+
],
|
|
251
|
+
"dont": [
|
|
252
|
+
"Lose active task agreements or historical context required for the current implementation.", # noqa: E501
|
|
253
|
+
],
|
|
254
|
+
},
|
|
255
|
+
]
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def _write_playbooks(workflows_dest: Path, skills_str: str, subagents_str: str) -> None:
|
|
259
|
+
"""Escribe los 4 playbooks dinámicos en el directorio de destino."""
|
|
260
|
+
workflows_dest.mkdir(parents=True, exist_ok=True)
|
|
261
|
+
for spec in _PLAYBOOK_SPECS:
|
|
262
|
+
content = _build_playbook(
|
|
263
|
+
name=spec["file"],
|
|
264
|
+
description=spec["description"],
|
|
265
|
+
mode=spec["mode"],
|
|
266
|
+
perms=spec["perms"],
|
|
267
|
+
when=spec["when"],
|
|
268
|
+
do=spec["do"],
|
|
269
|
+
dont=spec["dont"],
|
|
270
|
+
skills_str=skills_str,
|
|
271
|
+
subagents_str=subagents_str,
|
|
272
|
+
)
|
|
273
|
+
(workflows_dest / spec["file"]).write_text(content, encoding="utf-8")
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def sync_assistant_files(
|
|
277
|
+
source_system: Path,
|
|
278
|
+
target_root: Path,
|
|
279
|
+
asst_dir: str,
|
|
280
|
+
asst_name: str,
|
|
281
|
+
) -> None:
|
|
282
|
+
"""Proyecta workflows, subagentes y skills de AgentSystem hacia un asistente específico."""
|
|
283
|
+
_log.info(f"\n[*] Proyectando AgentSystem para '{asst_name}' en: {target_root / asst_dir}")
|
|
284
|
+
asst_path = Path(target_root) / asst_dir
|
|
285
|
+
asst_path.mkdir(parents=True, exist_ok=True)
|
|
286
|
+
|
|
287
|
+
primary_src = source_system / "Agents" / "primary"
|
|
288
|
+
subagents_src = source_system / "Agents" / "subagents"
|
|
289
|
+
skills_src = source_system / "Skills"
|
|
290
|
+
|
|
291
|
+
if asst_dir == ".claude":
|
|
292
|
+
wf_subdir = "commands"
|
|
293
|
+
elif asst_dir == ".opencode":
|
|
294
|
+
wf_subdir = "agents"
|
|
295
|
+
else:
|
|
296
|
+
wf_subdir = "workflows"
|
|
297
|
+
workflows_dest = asst_path / wf_subdir
|
|
298
|
+
subagents_dest = asst_path / "subagents"
|
|
299
|
+
is_antigravity = asst_dir == _AGENTS_DIR
|
|
300
|
+
skills_dest = (
|
|
301
|
+
Path(target_root) / _AGENTS_DIR / "skills" if is_antigravity else asst_path / "skills"
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
count = _copy_dir_glob(primary_src, workflows_dest, "*.md")
|
|
305
|
+
count += _copy_dir_glob(subagents_src, subagents_dest, "*.md")
|
|
306
|
+
count += _copy_skills(skills_src, skills_dest, is_antigravity)
|
|
307
|
+
|
|
308
|
+
skills_str = "\n".join(_resolve_skills_list(skills_dest, target_root))
|
|
309
|
+
subagents_str = "\n".join(_resolve_subagents_list(subagents_dest))
|
|
310
|
+
_write_playbooks(workflows_dest, skills_str, subagents_str)
|
|
311
|
+
|
|
312
|
+
_log.ok(f" [SUCCESS] Proyectados {count} archivos y workflows dinámicos en {asst_dir}")
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def main() -> None:
|
|
316
|
+
"""Punto de entrada de sync-agents."""
|
|
317
|
+
parser = argparse.ArgumentParser(
|
|
318
|
+
description="Proyectar AgentSystem a los asistentes de un proyecto."
|
|
319
|
+
)
|
|
320
|
+
parser.add_argument("--target", default=".", help="Ruta al proyecto destino")
|
|
321
|
+
parser.add_argument("--source", default=None, help="Ruta origen de AgentSystem")
|
|
322
|
+
parser.add_argument(
|
|
323
|
+
"--assistant",
|
|
324
|
+
default="all",
|
|
325
|
+
choices=list(_ASSISTANT_DIRS) + ["all"],
|
|
326
|
+
help="Asistente objetivo",
|
|
327
|
+
)
|
|
328
|
+
args = parser.parse_args()
|
|
329
|
+
|
|
330
|
+
source_system = get_agent_system_dir(args.source)
|
|
331
|
+
if not source_system.exists():
|
|
332
|
+
_log.warning(f"[!] Error: No se encontró la fuente canónica de AgentSystem en: {source_system}")
|
|
333
|
+
sys.exit(1)
|
|
334
|
+
|
|
335
|
+
target_root = Path(args.target).absolute()
|
|
336
|
+
target_root.mkdir(parents=True, exist_ok=True)
|
|
337
|
+
|
|
338
|
+
_log.info(f"[*] Iniciando sincronización de AgentSystem -> {target_root}")
|
|
339
|
+
_log.info(f" Fuente canónica: {source_system}")
|
|
340
|
+
|
|
341
|
+
assistants = (
|
|
342
|
+
_ASSISTANT_DIRS
|
|
343
|
+
if args.assistant == "all"
|
|
344
|
+
else {args.assistant: _ASSISTANT_DIRS[args.assistant]}
|
|
345
|
+
)
|
|
346
|
+
for key, (asst_dir, asst_name) in assistants.items():
|
|
347
|
+
sync_assistant_files(source_system, target_root, asst_dir, asst_name)
|
|
348
|
+
|
|
349
|
+
_log.ok("\n[SUCCESS] Sincronización de AgentSystem completada con éxito.")
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
if __name__ == "__main__":
|
|
353
|
+
main()
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""Capability common.task-decomposer — descompone un objetivo en un task-graph.
|
|
2
|
+
|
|
3
|
+
Dado un objetivo y tipo, genera un DAG de tareas con dependencias, skills
|
|
4
|
+
y contexto por nodo. Output: roadmap.json compatible con higpertext Engine,
|
|
5
|
+
escrito en .higpertext/config/roadmap.json.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
import argparse
|
|
10
|
+
import json
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
|
|
14
|
+
from higpertext.kernel.infrastructure.logger import get_logger
|
|
15
|
+
_log = get_logger()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _resolve_core() -> Path:
|
|
19
|
+
here = Path(__file__).resolve()
|
|
20
|
+
for parent in here.parents:
|
|
21
|
+
core = parent / "src" / "core"
|
|
22
|
+
if core.exists():
|
|
23
|
+
return core
|
|
24
|
+
return here.parent
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def main() -> None:
|
|
28
|
+
parser = argparse.ArgumentParser(description="Descompone un objetivo en un task-graph.")
|
|
29
|
+
parser.add_argument("--goal", required=True, help="Objetivo en lenguaje natural.")
|
|
30
|
+
parser.add_argument(
|
|
31
|
+
"--type",
|
|
32
|
+
default="feature",
|
|
33
|
+
help="Tipo: refactor|feature|bugfix|review. Default: feature.",
|
|
34
|
+
)
|
|
35
|
+
parser.add_argument(
|
|
36
|
+
"--save",
|
|
37
|
+
default="true",
|
|
38
|
+
help="Si 'true', escribe .higpertext/config/roadmap.json. Default: true.",
|
|
39
|
+
)
|
|
40
|
+
args = parser.parse_args()
|
|
41
|
+
|
|
42
|
+
core = _resolve_core()
|
|
43
|
+
if str(core) not in sys.path:
|
|
44
|
+
sys.path.insert(0, str(core))
|
|
45
|
+
|
|
46
|
+
from higpertext.context_engine.domain.task_intent import TaskIntent
|
|
47
|
+
from higpertext.context_engine.application.task_decomposer import TaskDecomposer
|
|
48
|
+
|
|
49
|
+
project_root = core.parent.parent
|
|
50
|
+
intent = TaskIntent.from_goal(args.goal, args.type)
|
|
51
|
+
decomposer = TaskDecomposer(project_root)
|
|
52
|
+
graph = decomposer.decompose(intent)
|
|
53
|
+
roadmap = graph.to_roadmap_dict()
|
|
54
|
+
|
|
55
|
+
_log.info("╔─ HIGPERTEXT · Task Graph generado ─────────────────────────")
|
|
56
|
+
_log.info(f"│ Objetivo : {intent.goal}")
|
|
57
|
+
_log.info(f"│ Tipo : {intent.task_type}")
|
|
58
|
+
_log.info(f"│ Nodos : {len(graph.nodes)} | Acíclico: {graph.is_acyclic()}")
|
|
59
|
+
_log.info("│")
|
|
60
|
+
for node in graph.topological_order():
|
|
61
|
+
deps = f" ← {', '.join(node.depends_on)}" if node.depends_on else ""
|
|
62
|
+
_log.info(f"│ [{node.id}]{deps}")
|
|
63
|
+
_log.info(f"│ {node.description[:80]}")
|
|
64
|
+
_log.info("╚───────────────────────────────────────────────────────")
|
|
65
|
+
|
|
66
|
+
if args.save.lower() == "true":
|
|
67
|
+
roadmap_path = project_root / WORKSPACE_DIR_NAME / "config" / "roadmap.json"
|
|
68
|
+
roadmap_path.parent.mkdir(parents=True, exist_ok=True)
|
|
69
|
+
roadmap_path.write_text(json.dumps(roadmap, indent=2, ensure_ascii=False), encoding="utf-8")
|
|
70
|
+
rel = roadmap_path.relative_to(project_root).as_posix()
|
|
71
|
+
_log.ok(f"\n[SUCCESS] Roadmap escrito en: {rel}")
|
|
72
|
+
_log.info("→ Edita el roadmap antes de ejecutar: htx task common.session-start")
|
|
73
|
+
else:
|
|
74
|
+
print("\n" + json.dumps(roadmap, indent=2, ensure_ascii=False))
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
if __name__ == "__main__":
|
|
78
|
+
main()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Capacidad common.telemetry-report — muestra dashboard de telemetría en terminal."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from higpertext.kernel.config_paths import WORKSPACE_DIR_NAME
|
|
9
|
+
|
|
10
|
+
# Resuelve raíz del proyecto
|
|
11
|
+
_HERE = Path(__file__).resolve()
|
|
12
|
+
_ROOT = next(
|
|
13
|
+
(p for p in _HERE.parents if (p / "src/config/htx_config.json").exists()),
|
|
14
|
+
_HERE.parents[4],
|
|
15
|
+
)
|
|
16
|
+
sys.path.insert(0, str(_ROOT / "src"))
|
|
17
|
+
|
|
18
|
+
from higpertext.telemetry import render # noqa: E402
|
|
19
|
+
from higpertext.kernel.infrastructure.output_store import OutputStore # noqa: E402
|
|
20
|
+
|
|
21
|
+
from higpertext.kernel.infrastructure.logger import get_logger
|
|
22
|
+
_log = get_logger()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def main() -> None:
|
|
26
|
+
parser = argparse.ArgumentParser(description="higpertext Telemetry Report")
|
|
27
|
+
parser.add_argument("--days", type=int, default=7, help="Período en días (default: 7)")
|
|
28
|
+
args = parser.parse_args()
|
|
29
|
+
|
|
30
|
+
report = render(_ROOT, days=args.days)
|
|
31
|
+
_log.info(report)
|
|
32
|
+
OutputStore(_ROOT).write("common.telemetry-report", report, fmt="txt")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == "__main__":
|
|
36
|
+
main()
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "common.search-router",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"name": "Search Router",
|
|
5
|
+
"description": "Recomienda el plan de capacidades adecuado para localizar contexto: error-context-locator, smart-read, graph-query o grep-search según intención y query.",
|
|
6
|
+
"entrypoint": "capabilities/common/scripts/search_router.py",
|
|
7
|
+
"language": "python",
|
|
8
|
+
"parameters": [
|
|
9
|
+
{"name": "query", "description": "Consulta, símbolo, path o error.", "required": true},
|
|
10
|
+
{"name": "intent", "description": "error, feature, refactor, docs, symbol o general.", "required": false, "default": "general"},
|
|
11
|
+
{"name": "scope", "description": "Ruta base para grep-search. Default: .", "required": false, "default": "."},
|
|
12
|
+
{"name": "preset", "description": "Preset para grep-search. Default: code.", "required": false, "default": "code"},
|
|
13
|
+
{"name": "budget", "description": "Presupuesto de tokens sugerido. Default: 4000.", "required": false, "default": "4000"},
|
|
14
|
+
{"name": "json", "description": "Emite JSON estructurado.", "required": false, "default": "false"}
|
|
15
|
+
],
|
|
16
|
+
"contract": {
|
|
17
|
+
"rules": [
|
|
18
|
+
"Debe recomendar error-context-locator para intención error o trazas.",
|
|
19
|
+
"Debe recomendar graph-query para feature/refactor/symbol.",
|
|
20
|
+
"Debe incluir grep-search como fallback general con límites de contexto.",
|
|
21
|
+
"Debe soportar salida JSON."
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "common.semantic-diff",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Detecta qué funciones, clases y métodos cambiaron entre dos commits (o entre HEAD y el working tree), usando AST parsing. Útil para identificar qué tests reejecutar tras un cambio.",
|
|
5
|
+
"entrypoint": "capabilities/common/scripts/semantic_diff.py",
|
|
6
|
+
"language": "python",
|
|
7
|
+
"parameters": [
|
|
8
|
+
{
|
|
9
|
+
"name": "base",
|
|
10
|
+
"description": "Commit/branch de referencia base (default: HEAD~1).",
|
|
11
|
+
"required": false,
|
|
12
|
+
"default": "HEAD~1"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "head",
|
|
16
|
+
"description": "Commit/branch destino a comparar (default: HEAD).",
|
|
17
|
+
"required": false,
|
|
18
|
+
"default": "HEAD"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "files",
|
|
22
|
+
"description": "Lista de archivos específicos separados por comas (opcional).",
|
|
23
|
+
"required": false
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "format",
|
|
27
|
+
"description": "Formato de salida: 'text' o 'json' (default: text).",
|
|
28
|
+
"required": false,
|
|
29
|
+
"default": "text"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"contract": {
|
|
33
|
+
"rules": [
|
|
34
|
+
"Listar funciones y clases modificadas, añadidas o eliminadas entre los dos commits.",
|
|
35
|
+
"Agrupar los cambios por archivo.",
|
|
36
|
+
"Indicar el tipo de cambio: added, removed, modified.",
|
|
37
|
+
"Si format=json, devolver un objeto JSON estructurado con la lista de símbolos cambiados."
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
}
|