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,23 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Protocol
|
|
4
|
+
|
|
5
|
+
@dataclass(frozen=True)
|
|
6
|
+
class AgentRecord:
|
|
7
|
+
name: str
|
|
8
|
+
path: str
|
|
9
|
+
profile: str
|
|
10
|
+
registered_at: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class SyncResult:
|
|
15
|
+
name: str
|
|
16
|
+
success: bool
|
|
17
|
+
message: str
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class IAgentRegistryRepository(Protocol):
|
|
21
|
+
def load(self) -> list[AgentRecord]: ...
|
|
22
|
+
def save(self, agents: list[AgentRecord]) -> None: ...
|
|
23
|
+
def find_by_name(self, name: str) -> AgentRecord | None: ...
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from collections import defaultdict
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CommitType(str, Enum):
|
|
9
|
+
FEAT = "feat"
|
|
10
|
+
FIX = "fix"
|
|
11
|
+
DOCS = "docs"
|
|
12
|
+
REFACTOR = "refactor"
|
|
13
|
+
TEST = "test"
|
|
14
|
+
CHORE = "chore"
|
|
15
|
+
PERF = "perf"
|
|
16
|
+
CI = "ci"
|
|
17
|
+
OTHER = "other"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass(frozen=True)
|
|
23
|
+
class ParsedCommitMessage:
|
|
24
|
+
type: str
|
|
25
|
+
scope: str | None
|
|
26
|
+
subject: str
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def parse_commit_message(message: str) -> ParsedCommitMessage | None:
|
|
30
|
+
"""Parsea Conventional Commits en tiempo lineal, evitando regex con backtracking."""
|
|
31
|
+
prefix, separator, subject = message.partition(":")
|
|
32
|
+
if not separator or not subject.strip():
|
|
33
|
+
return None
|
|
34
|
+
scope: str | None = None
|
|
35
|
+
commit_type = prefix.strip()
|
|
36
|
+
if "(" in commit_type:
|
|
37
|
+
type_part, scope_part = commit_type.split("(", 1)
|
|
38
|
+
if not scope_part.endswith(")"):
|
|
39
|
+
return None
|
|
40
|
+
commit_type = type_part
|
|
41
|
+
scope = scope_part[:-1] or None
|
|
42
|
+
if not commit_type or not commit_type.replace("_", "").isalnum():
|
|
43
|
+
return None
|
|
44
|
+
return ParsedCommitMessage(commit_type, scope, subject.strip())
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass(frozen=True)
|
|
48
|
+
class Commit:
|
|
49
|
+
hash: str
|
|
50
|
+
message: str
|
|
51
|
+
author: str
|
|
52
|
+
date: str
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def short_hash(self) -> str:
|
|
56
|
+
return self.hash[:7]
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def _parsed(self) -> ParsedCommitMessage | None:
|
|
60
|
+
return parse_commit_message(self.message)
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def commit_type(self) -> CommitType:
|
|
64
|
+
m = self._parsed
|
|
65
|
+
if not m:
|
|
66
|
+
return CommitType.OTHER
|
|
67
|
+
try:
|
|
68
|
+
return CommitType(m.type.lower())
|
|
69
|
+
except ValueError:
|
|
70
|
+
return CommitType.OTHER
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def scope(self) -> str | None:
|
|
74
|
+
m = self._parsed
|
|
75
|
+
return m.scope if m else None
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def subject(self) -> str:
|
|
79
|
+
m = self._parsed
|
|
80
|
+
return m.subject if m else self.message
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class Layer(str, Enum):
|
|
84
|
+
DOMAIN = "domain"
|
|
85
|
+
APPLICATION = "application"
|
|
86
|
+
INFRASTRUCTURE = "infrastructure"
|
|
87
|
+
TEST = "test"
|
|
88
|
+
CAPABILITY = "capability"
|
|
89
|
+
OTHER = "other"
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _classify(path: str) -> Layer:
|
|
93
|
+
p = path.replace("\\", "/")
|
|
94
|
+
if p.startswith("tests/") or "/tests/" in p:
|
|
95
|
+
return Layer.TEST
|
|
96
|
+
if "capabilities/" in p:
|
|
97
|
+
return Layer.CAPABILITY
|
|
98
|
+
if "/domain/" in p:
|
|
99
|
+
return Layer.DOMAIN
|
|
100
|
+
if "/application/" in p:
|
|
101
|
+
return Layer.APPLICATION
|
|
102
|
+
if "/infrastructure/" in p:
|
|
103
|
+
return Layer.INFRASTRUCTURE
|
|
104
|
+
return Layer.OTHER
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@dataclass(frozen=True)
|
|
108
|
+
class FileChange:
|
|
109
|
+
path: str
|
|
110
|
+
additions: int
|
|
111
|
+
deletions: int
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def layer(self) -> Layer:
|
|
115
|
+
return _classify(self.path)
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def net_lines(self) -> int:
|
|
119
|
+
return self.additions - self.deletions
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def filename(self) -> str:
|
|
123
|
+
return Path(self.path).name
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@dataclass
|
|
127
|
+
class CommitReport:
|
|
128
|
+
commit: Commit
|
|
129
|
+
changes: list[FileChange]
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def total_additions(self) -> int:
|
|
133
|
+
return sum(c.additions for c in self.changes)
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def total_deletions(self) -> int:
|
|
137
|
+
return sum(c.deletions for c in self.changes)
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def changed_files_count(self) -> int:
|
|
141
|
+
return len(self.changes)
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def has_new_tests(self) -> bool:
|
|
145
|
+
return any(c.layer == Layer.TEST and c.additions > 0 for c in self.changes)
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def has_new_capabilities(self) -> bool:
|
|
149
|
+
return any(c.layer == Layer.CAPABILITY and c.additions > 0 for c in self.changes)
|
|
150
|
+
|
|
151
|
+
def files_by_layer(self) -> dict[Layer, list[FileChange]]:
|
|
152
|
+
groups: dict[Layer, list[FileChange]] = defaultdict(list)
|
|
153
|
+
for change in self.changes:
|
|
154
|
+
groups[change.layer].append(change)
|
|
155
|
+
return dict(groups)
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"""Context Engine Domain layer — ContextPack, EfficiencyReport, TaskGraph, TaskIntent, TaskNode, and WindowState."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import re
|
|
7
|
+
import time
|
|
8
|
+
from collections import Counter
|
|
9
|
+
from dataclasses import dataclass, field, asdict
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class SymbolRef:
|
|
15
|
+
"""Referencia a un símbolo del semantic graph (clase o función)."""
|
|
16
|
+
|
|
17
|
+
file: str
|
|
18
|
+
name: str
|
|
19
|
+
kind: str # "class" | "function" | "method"
|
|
20
|
+
doc: str = ""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(frozen=True)
|
|
24
|
+
class FileSkeleton:
|
|
25
|
+
"""Esqueleto comprimido de un archivo (firmas sin cuerpos)."""
|
|
26
|
+
|
|
27
|
+
file: str
|
|
28
|
+
skeleton: str
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
_CE_CONFIG_PATH = Path(__file__).resolve().parents[4] / "src" / "config" / "context_engine.json"
|
|
32
|
+
_CE_CFG: dict = json.loads(_CE_CONFIG_PATH.read_text(encoding="utf-8"))
|
|
33
|
+
|
|
34
|
+
_STOPWORDS = frozenset(_CE_CFG["stopwords"])
|
|
35
|
+
_MD = _CE_CFG["markdown"]
|
|
36
|
+
_RM = _CE_CFG["roadmap"]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class TaskIntent:
|
|
41
|
+
"""Intención de tarea: objetivo, tipo y keywords derivados."""
|
|
42
|
+
|
|
43
|
+
goal: str
|
|
44
|
+
task_type: str
|
|
45
|
+
keywords: tuple[str, ...] = field(default_factory=tuple)
|
|
46
|
+
token_budget: int = 8000
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def from_goal(cls, goal: str, task_type: str, token_budget: int = 8000) -> TaskIntent:
|
|
50
|
+
keywords = tuple(cls._extract_keywords(goal))
|
|
51
|
+
return cls(goal=goal, task_type=task_type, keywords=keywords, token_budget=token_budget)
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def _extract_keywords(goal: str, top_n: int = 8) -> list[str]:
|
|
55
|
+
tokens = re.findall(r"[^\W\d_][\w]{2,}", goal.lower(), re.UNICODE)
|
|
56
|
+
filtered = [t for t in tokens if t not in _STOPWORDS]
|
|
57
|
+
counts = Counter(filtered)
|
|
58
|
+
return [t for t, _ in counts.most_common(top_n)]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass
|
|
62
|
+
class ContextPack:
|
|
63
|
+
"""Conjunto curado de assets relevantes para una TaskIntent."""
|
|
64
|
+
|
|
65
|
+
intent: TaskIntent
|
|
66
|
+
relevant_symbols: list[SymbolRef] = field(default_factory=list)
|
|
67
|
+
applicable_memories: list[str] = field(default_factory=list)
|
|
68
|
+
skeletons: list[FileSkeleton] = field(default_factory=list)
|
|
69
|
+
estimated_tokens: int = 0
|
|
70
|
+
|
|
71
|
+
def _header_lines(self) -> list[str]:
|
|
72
|
+
return [
|
|
73
|
+
f"# Context Pack — {self.intent.task_type}",
|
|
74
|
+
f"> **Objetivo**: {self.intent.goal}",
|
|
75
|
+
f"> **Keywords**: {', '.join(self.intent.keywords) or '—'}",
|
|
76
|
+
f"> **Tokens estimados**: {self.estimated_tokens} / {self.intent.token_budget}",
|
|
77
|
+
"",
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
def _symbols_lines(self) -> list[str]:
|
|
81
|
+
if not self.relevant_symbols:
|
|
82
|
+
return []
|
|
83
|
+
|
|
84
|
+
lines = [_MD["symbols_header"], ""]
|
|
85
|
+
by_file: dict[str, list[SymbolRef]] = {}
|
|
86
|
+
for s in self.relevant_symbols:
|
|
87
|
+
by_file.setdefault(s.file, []).append(s)
|
|
88
|
+
for file, symbols in by_file.items():
|
|
89
|
+
lines.append(f"### [{file}](file:///{file})")
|
|
90
|
+
for s in symbols:
|
|
91
|
+
doc = f" — {s.doc}" if s.doc else ""
|
|
92
|
+
lines.append(f"- `{s.kind} {s.name}`{doc}")
|
|
93
|
+
lines.append("")
|
|
94
|
+
return lines
|
|
95
|
+
|
|
96
|
+
def _memories_lines(self) -> list[str]:
|
|
97
|
+
if not self.applicable_memories:
|
|
98
|
+
return []
|
|
99
|
+
|
|
100
|
+
lines = [_MD["memories_header"], ""]
|
|
101
|
+
for m in self.applicable_memories:
|
|
102
|
+
lines.append(f"- {m}")
|
|
103
|
+
lines.append("")
|
|
104
|
+
return lines
|
|
105
|
+
|
|
106
|
+
def _skeletons_lines(self) -> list[str]:
|
|
107
|
+
if not self.skeletons:
|
|
108
|
+
return []
|
|
109
|
+
|
|
110
|
+
lines = [_MD["skeletons_header"], ""]
|
|
111
|
+
for sk in self.skeletons:
|
|
112
|
+
lines += [f"### {sk.file}", "```", sk.skeleton, "```", ""]
|
|
113
|
+
return lines
|
|
114
|
+
|
|
115
|
+
def to_markdown(self) -> str:
|
|
116
|
+
lines = self._header_lines()
|
|
117
|
+
lines += self._symbols_lines()
|
|
118
|
+
lines += self._memories_lines()
|
|
119
|
+
lines += self._skeletons_lines()
|
|
120
|
+
return "\n".join(lines)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@dataclass
|
|
124
|
+
class EfficiencyReport:
|
|
125
|
+
"""Métricas calculadas al cierre de sesión para medir el valor del contexto."""
|
|
126
|
+
|
|
127
|
+
session_id: str
|
|
128
|
+
total_tokens: int
|
|
129
|
+
total_cost_usd: float
|
|
130
|
+
exploration_reads: int
|
|
131
|
+
higpertext_reads: int
|
|
132
|
+
hook_intercepts: int
|
|
133
|
+
context_hit_rate: float
|
|
134
|
+
exploration_waste_ratio: float
|
|
135
|
+
window_usage_pct: float = 0.0
|
|
136
|
+
peak_window_tokens: int = 0
|
|
137
|
+
|
|
138
|
+
def to_dict(self) -> dict:
|
|
139
|
+
return asdict(self)
|
|
140
|
+
|
|
141
|
+
def to_markdown(self) -> str:
|
|
142
|
+
waste_pct = f"{self.exploration_waste_ratio * 100:.1f}%"
|
|
143
|
+
hit_pct = f"{self.context_hit_rate * 100:.1f}%"
|
|
144
|
+
win_pct = f"{self.window_usage_pct * 100:.1f}%"
|
|
145
|
+
return "\n".join(
|
|
146
|
+
[
|
|
147
|
+
_MD["efficiency_report_title"].format(session_id=self.session_id),
|
|
148
|
+
"",
|
|
149
|
+
_MD["efficiency_table_header"][0],
|
|
150
|
+
_MD["efficiency_table_header"][1],
|
|
151
|
+
f"| Tokens totales | {self.total_tokens:,} |",
|
|
152
|
+
f"| Costo estimado | ${self.total_cost_usd:.4f} USD |",
|
|
153
|
+
f"| Lecturas de exploración (sin higpertext) | {self.exploration_reads} |",
|
|
154
|
+
f"| Lecturas vía higpertext | {self.higpertext_reads} |",
|
|
155
|
+
f"| Hook intercepts | {self.hook_intercepts} |",
|
|
156
|
+
f"| Context hit rate | {hit_pct} |",
|
|
157
|
+
f"| Exploration waste ratio | {waste_pct} |",
|
|
158
|
+
f"| Pico de uso de ventana | {win_pct} ({self.peak_window_tokens:,} tokens) |",
|
|
159
|
+
]
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@dataclass
|
|
164
|
+
class TaskNode:
|
|
165
|
+
"""Unidad atómica de trabajo: descripción, dependencias y pack de contexto."""
|
|
166
|
+
|
|
167
|
+
id: str
|
|
168
|
+
description: str
|
|
169
|
+
depends_on: list[str] = field(default_factory=list)
|
|
170
|
+
context_pack_ref: str = ""
|
|
171
|
+
status: str = "pending" # pending | active | done
|
|
172
|
+
skills: list[str] = field(default_factory=list)
|
|
173
|
+
subagents: list[str] = field(default_factory=list)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@dataclass
|
|
177
|
+
class TaskGraph:
|
|
178
|
+
"""Grafo dirigido acíclico (DAG) de tareas con orden de ejecución."""
|
|
179
|
+
|
|
180
|
+
nodes: list[TaskNode] = field(default_factory=list)
|
|
181
|
+
goal: str = ""
|
|
182
|
+
|
|
183
|
+
def is_acyclic(self) -> bool:
|
|
184
|
+
ids = {n.id for n in self.nodes}
|
|
185
|
+
deps = {n.id: [d for d in n.depends_on if d in ids] for n in self.nodes}
|
|
186
|
+
WHITE, GRAY, BLACK = 0, 1, 2
|
|
187
|
+
color = {nid: WHITE for nid in ids}
|
|
188
|
+
|
|
189
|
+
def visit(nid: str) -> bool:
|
|
190
|
+
if color[nid] == GRAY:
|
|
191
|
+
return False
|
|
192
|
+
if color[nid] == BLACK:
|
|
193
|
+
return True
|
|
194
|
+
color[nid] = GRAY
|
|
195
|
+
for dep in deps.get(nid, []):
|
|
196
|
+
if not visit(dep):
|
|
197
|
+
return False
|
|
198
|
+
color[nid] = BLACK
|
|
199
|
+
return True
|
|
200
|
+
|
|
201
|
+
return all(visit(nid) for nid in ids if color[nid] == WHITE)
|
|
202
|
+
|
|
203
|
+
def topological_order(self) -> list[TaskNode]:
|
|
204
|
+
ids = {n.id: n for n in self.nodes}
|
|
205
|
+
deps = {n.id: [d for d in n.depends_on if d in ids] for n in self.nodes}
|
|
206
|
+
visited: set[str] = set()
|
|
207
|
+
result: list[TaskNode] = []
|
|
208
|
+
|
|
209
|
+
def visit(nid: str) -> None:
|
|
210
|
+
if nid in visited:
|
|
211
|
+
return
|
|
212
|
+
visited.add(nid)
|
|
213
|
+
for dep in deps.get(nid, []):
|
|
214
|
+
visit(dep)
|
|
215
|
+
result.append(ids[nid])
|
|
216
|
+
|
|
217
|
+
for nid in ids:
|
|
218
|
+
visit(nid)
|
|
219
|
+
return result
|
|
220
|
+
|
|
221
|
+
def to_roadmap_dict(self) -> dict:
|
|
222
|
+
all_skills: list[str] = []
|
|
223
|
+
all_subagents: list[str] = []
|
|
224
|
+
phases = []
|
|
225
|
+
for node in self.topological_order():
|
|
226
|
+
for s in node.skills:
|
|
227
|
+
if s not in all_skills:
|
|
228
|
+
all_skills.append(s)
|
|
229
|
+
for sa in node.subagents:
|
|
230
|
+
if sa not in all_subagents:
|
|
231
|
+
all_subagents.append(sa)
|
|
232
|
+
phases.append(
|
|
233
|
+
{
|
|
234
|
+
"id": node.id,
|
|
235
|
+
"name": node.description[:_RM["name_truncation"]],
|
|
236
|
+
"description": node.description,
|
|
237
|
+
"status": node.status,
|
|
238
|
+
"skills": node.skills,
|
|
239
|
+
"subagents": node.subagents,
|
|
240
|
+
"depends_on": node.depends_on,
|
|
241
|
+
"context_pack_ref": node.context_pack_ref,
|
|
242
|
+
}
|
|
243
|
+
)
|
|
244
|
+
return {
|
|
245
|
+
"version": _RM["version"],
|
|
246
|
+
"project": self.goal[:_RM["project_truncation"]] if self.goal else _RM["default_project"],
|
|
247
|
+
"created_at": _today(),
|
|
248
|
+
"session_resources": {
|
|
249
|
+
"skills": all_skills or list(_RM["fallback_skills"]),
|
|
250
|
+
"subagents": all_subagents or list(_RM["fallback_subagents"]),
|
|
251
|
+
},
|
|
252
|
+
"phases": phases,
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def _today() -> str:
|
|
257
|
+
import datetime
|
|
258
|
+
return datetime.date.today().isoformat()
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
_STATE_FILE = Path(_CE_CFG["state_file_path"])
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def _window_limit() -> int:
|
|
265
|
+
try:
|
|
266
|
+
return int(os.environ.get(_CE_CFG["window_limit"]["env_var"], _CE_CFG["window_limit"]["default_str"]))
|
|
267
|
+
except ValueError:
|
|
268
|
+
return _CE_CFG["window_limit"]["default_int"]
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
@dataclass
|
|
272
|
+
class WindowState:
|
|
273
|
+
accumulated_tokens: int = 0
|
|
274
|
+
peak_tokens: int = 0
|
|
275
|
+
turn: int = 0
|
|
276
|
+
last_updated: float = 0.0
|
|
277
|
+
|
|
278
|
+
def add(self, tokens: int) -> None:
|
|
279
|
+
self.accumulated_tokens += tokens
|
|
280
|
+
if self.accumulated_tokens > self.peak_tokens:
|
|
281
|
+
self.peak_tokens = self.accumulated_tokens
|
|
282
|
+
self.last_updated = time.time()
|
|
283
|
+
|
|
284
|
+
def usage_pct(self, window_limit: int) -> float:
|
|
285
|
+
if window_limit <= 0:
|
|
286
|
+
return 0.0
|
|
287
|
+
return min(self.accumulated_tokens / window_limit, 1.0)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def load_window_state(root: Path) -> WindowState:
|
|
291
|
+
path = root / _STATE_FILE
|
|
292
|
+
if not path.exists():
|
|
293
|
+
return WindowState()
|
|
294
|
+
try:
|
|
295
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
296
|
+
return WindowState(**{k: data[k] for k in WindowState.__dataclass_fields__ if k in data})
|
|
297
|
+
except (json.JSONDecodeError, TypeError, OSError):
|
|
298
|
+
return WindowState()
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def save_window_state(root: Path, state: WindowState) -> None:
|
|
302
|
+
path = root / _STATE_FILE
|
|
303
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
304
|
+
tmp = path.with_suffix(".tmp")
|
|
305
|
+
tmp.write_text(json.dumps(asdict(state), indent=2, ensure_ascii=False), encoding="utf-8")
|
|
306
|
+
tmp.replace(path)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def reset_window_state(root: Path, turn: int | None = None) -> WindowState:
|
|
310
|
+
prev = load_window_state(root)
|
|
311
|
+
new_turn = (prev.turn + 1) if turn is None else turn
|
|
312
|
+
fresh = WindowState(
|
|
313
|
+
accumulated_tokens=0,
|
|
314
|
+
peak_tokens=prev.peak_tokens,
|
|
315
|
+
turn=new_turn,
|
|
316
|
+
last_updated=time.time(),
|
|
317
|
+
)
|
|
318
|
+
save_window_state(root, fresh)
|
|
319
|
+
return fresh
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Modelos e invariantes del Dominio del Kernel de higpertext."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass(frozen=True)
|
|
8
|
+
class Profile:
|
|
9
|
+
name: str
|
|
10
|
+
description: str
|
|
11
|
+
system_prompt: str
|
|
12
|
+
capabilities: list[str] = field(default_factory=list)
|
|
13
|
+
session_skills: list[str] = field(default_factory=list)
|
|
14
|
+
session_subagents: list[str] = field(default_factory=list)
|
|
15
|
+
governance_access: bool = False
|
|
16
|
+
extends: str | None = None
|
|
17
|
+
model: str | None = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass(frozen=True)
|
|
21
|
+
class Capability:
|
|
22
|
+
id: str
|
|
23
|
+
version: str
|
|
24
|
+
name: str
|
|
25
|
+
description: str
|
|
26
|
+
entrypoint: str
|
|
27
|
+
language: str
|
|
28
|
+
parameters: list[dict] = field(default_factory=list)
|
|
29
|
+
security: dict = field(default_factory=dict)
|
|
30
|
+
hook_task_id: str | None = None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass(frozen=True)
|
|
34
|
+
class Workflow:
|
|
35
|
+
id: str
|
|
36
|
+
name: str
|
|
37
|
+
description: str
|
|
38
|
+
steps: list[dict] = field(default_factory=list)
|
|
39
|
+
required_profile: str = ""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass(frozen=True)
|
|
43
|
+
class Session:
|
|
44
|
+
session_id: str
|
|
45
|
+
profile: str
|
|
46
|
+
assistant: str
|
|
47
|
+
status: str
|
|
48
|
+
created_at: str
|
|
49
|
+
active_skills: list[str] = field(default_factory=list)
|
|
50
|
+
active_subagents: list[str] = field(default_factory=list)
|
|
51
|
+
tasks: list[dict] = field(default_factory=list)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Modelos del runtime local de entornos (Dominio)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from datetime import datetime, timezone
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass(frozen=True)
|
|
11
|
+
class EnvironmentTemplate:
|
|
12
|
+
"""Plantilla declarativa de un ambiente ejecutable."""
|
|
13
|
+
|
|
14
|
+
id: str
|
|
15
|
+
description: str
|
|
16
|
+
services: dict[str, dict[str, Any]]
|
|
17
|
+
defaults: dict[str, Any] = field(default_factory=dict)
|
|
18
|
+
tasks: dict[str, dict[str, Any]] = field(default_factory=dict)
|
|
19
|
+
limits: dict[str, Any] = field(default_factory=dict)
|
|
20
|
+
security: dict[str, Any] = field(default_factory=dict)
|
|
21
|
+
source: Path | None = None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(frozen=True)
|
|
25
|
+
class RunSpec:
|
|
26
|
+
"""Solicitud de ejecución de un entorno."""
|
|
27
|
+
|
|
28
|
+
template_id: str
|
|
29
|
+
engine: str = "auto"
|
|
30
|
+
task: str = ""
|
|
31
|
+
command: str = ""
|
|
32
|
+
service: str = ""
|
|
33
|
+
detach: bool = False
|
|
34
|
+
timeout_seconds: int = 300
|
|
35
|
+
keep_alive: bool = False
|
|
36
|
+
cleanup: bool = True
|
|
37
|
+
env: dict[str, str] = field(default_factory=dict)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass
|
|
41
|
+
class RunState:
|
|
42
|
+
"""Estado persistido de una ejecución."""
|
|
43
|
+
|
|
44
|
+
run_id: str
|
|
45
|
+
template_id: str
|
|
46
|
+
engine: str
|
|
47
|
+
status: str
|
|
48
|
+
project_name: str
|
|
49
|
+
run_dir: str
|
|
50
|
+
service: str
|
|
51
|
+
command: str
|
|
52
|
+
exit_code: int | None = None
|
|
53
|
+
started_at: str = field(default_factory=lambda: datetime.now(timezone.utc).isoformat())
|
|
54
|
+
finished_at: str = ""
|
|
55
|
+
summary: str = ""
|
|
56
|
+
|
|
57
|
+
def to_dict(self) -> dict[str, Any]:
|
|
58
|
+
return self.__dict__.copy()
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def from_dict(cls, data: dict[str, Any]) -> "RunState":
|
|
62
|
+
return cls(**data)
|