From c4811d6cff645b9f18174221254b8da8b64e57c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yuniel=20Acosta=20P=C3=A9rez?= <33158051+yacosta738@users.noreply.github.com> Date: Mon, 16 Feb 2026 21:06:00 +0100 Subject: [PATCH 1/2] docs: add C4 architecture diagrams --- clients/web/apps/docs/astro.config.mjs | 29 +++- .../content/docs/en/guides/architecture.md | 124 +++++++++++++++--- .../diagrams/component/agent-core-kmp.mmd | 58 ++++++++ .../diagrams/container/system-containers.mmd | 68 ++++++++++ .../diagrams/container/system-containers.puml | 55 ++++++++ .../diagrams/context/system-context.mmd | 40 ++++++ .../diagrams/module-dependencies.mmd | 58 ++++++++ .../docs/en/guides/architecture/index.md | 81 ++++++++++++ .../src/content/docs/en/guides/structure.md | 38 +++--- .../content/docs/es/guides/architecture.md | 101 +++++++++++--- .../diagrams/component/agent-core-kmp.mmd | 58 ++++++++ .../diagrams/container/system-containers.mmd | 68 ++++++++++ .../diagrams/container/system-containers.puml | 55 ++++++++ .../diagrams/context/system-context.mmd | 41 ++++++ .../diagrams/module-dependencies.mmd | 58 ++++++++ .../docs/es/guides/architecture/index.md | 81 ++++++++++++ .../src/content/docs/es/guides/structure.md | 36 +++-- 17 files changed, 982 insertions(+), 67 deletions(-) create mode 100644 clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/component/agent-core-kmp.mmd create mode 100644 clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/container/system-containers.mmd create mode 100644 clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/container/system-containers.puml create mode 100644 clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/context/system-context.mmd create mode 100644 clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/module-dependencies.mmd create mode 100644 clients/web/apps/docs/src/content/docs/en/guides/architecture/index.md create mode 100644 clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/component/agent-core-kmp.mmd create mode 100644 clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/container/system-containers.mmd create mode 100644 clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/container/system-containers.puml create mode 100644 clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/context/system-context.mmd create mode 100644 clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/module-dependencies.mmd create mode 100644 clients/web/apps/docs/src/content/docs/es/guides/architecture/index.md diff --git a/clients/web/apps/docs/astro.config.mjs b/clients/web/apps/docs/astro.config.mjs index 68e5b1b5c..1f810eca0 100644 --- a/clients/web/apps/docs/astro.config.mjs +++ b/clients/web/apps/docs/astro.config.mjs @@ -81,13 +81,6 @@ export default defineConfig({ es: 'Funcionalidades', }, }, - { - label: 'Architecture', - slug: 'guides/architecture', - translations: { - es: 'Arquitectura', - }, - }, { label: 'Development', slug: 'guides/development', @@ -118,6 +111,28 @@ export default defineConfig({ }, ], }, + { + label: 'Architecture', + translations: { + es: 'Arquitectura', + }, + items: [ + { + label: 'Architecture Overview', + slug: 'guides/architecture', + translations: { + es: 'Visión General', + }, + }, + { + label: 'C4 Diagrams', + slug: 'guides/architecture/index', + translations: { + es: 'Diagramas C4', + }, + }, + ], + }, ], }), ], diff --git a/clients/web/apps/docs/src/content/docs/en/guides/architecture.md b/clients/web/apps/docs/src/content/docs/en/guides/architecture.md index 387776c67..70c2f2638 100644 --- a/clients/web/apps/docs/src/content/docs/en/guides/architecture.md +++ b/clients/web/apps/docs/src/content/docs/en/guides/architecture.md @@ -2,28 +2,122 @@ title: Architecture --- -The project follows a modular architecture with a strong emphasis on centralized build logic. +The project follows a modular architecture with a strong emphasis on centralized build logic and clear separation between clients and shared modules. ## Project Structure ```text . -├── apps/ -│ ├── agent-runtime-rust/ # Rust agent runtime app -│ ├── androidApp/ # Android host app -│ ├── composeApp/ # Shared Compose Multiplatform module -│ ├── docs/ # Documentation (Starlight website) -│ └── iosApp/ # iOS host app (Xcode project) -├── modules/ -│ └── agent-core-kmp/ # Shared KMP contracts/bootstrap module -├── gradle/ -│ ├── build-logic/ # Custom Gradle convention plugins -│ ├── libs.versions.toml # Version catalog -│ └── wrapper/ # Gradle wrapper -├── Makefile # Standardized command interface -└── settings.gradle.kts # Global project configuration +├── clients/ # Client applications +│ ├── agent-runtime/ # Agent runtime +│ ├── androidApp/ # Android host app +│ ├── composeApp/ # Shared Compose Multiplatform module +│ ├── iosApp/ # iOS host app (Xcode project) +│ └── web/ # Web app and operator dashboard +├── modules/ # Shared modules +│ └── agent-core-kmp/ # Agent core in Kotlin Multiplatform +├── gradle/ # Build configuration +│ ├── build-logic/ # Custom convention plugins +│ ├── aggregation/ # Report aggregation +│ ├── configs/ # Tool configurations +│ ├── versions/ # Version management +│ ├── libs.versions.toml # Version catalog +│ └── wrapper/ # Gradle wrapper +├── docs/ # Documentation (Astro + Starlight) +├── Makefile # Standardized command interface +└── settings.gradle.kts # Global project configuration ``` +## High-Level Architecture + +Corvus is designed as a reactive agent platform with the following pillars: + +### 1. **Reactive Orchestrator** + +- **Technology**: Kotlin + Spring Boot + Coroutines/WebFlux +- **Purpose**: Handle non-blocking, always-on workflows +- **Location**: Agent runtime in `clients/agent-runtime/` + +### 2. **Graph Memory** + +- **Technology**: Neo4j (planned) +- **Purpose**: Knowledge model with connected context and durable memory +- **Integration**: Through `agent-core-kmp` + +### 3. **High-Performance Sidecars** + +- **Technology**: Rust (planned) +- **Purpose**: Scraping and sandboxed execution at high performance +- **Communication**: FFI or gRPC with Kotlin runtime + +### 4. **Control Dashboard** + +- **Technology**: Astro + Vue (planned) +- **Purpose**: Real-time observability and transparent operation +- **Location**: `clients/web/` + +## Build Logic (Convention Plugins) + +Instead of repeating build logic in every `build.gradle.kts`, we use **Convention Plugins** located in `gradle/build-logic`. + +### Plugin Categories + +1. **Base Plugins**: Fundamental configuration like identity, lifecycle, and JVM conflict resolution. +2. **Module Plugins**: Language-specific configurations (`kotlin`, `java`, `spring-boot`, `compose`). +3. **Feature Plugins**: Opt-in features like `publish-library`, `shadow`, `test-fixtures` and `git-hook`. +4. **Check Plugins**: Code quality and formatting tools (`spotless`, `detekt`, `spotbugs`). +5. **Report Plugins**: Aggregated reports for testing, coverage, and SBOM. + +## Dependency Management + +We use **Gradle Version Catalogs** (`libs.versions.toml`) to define all dependencies and versions in a single location. This ensures consistency across all modules. + +### Example usage: + +```kotlin +dependencies { + implementation(libs.kotlin.stdlib) + testImplementation(libs.junit.jupiter) +} +``` + +## Module Dependency Flow + +``` +┌─────────────────────────────────────────────────────────────┐ +│ clients/composeApp │ +│ (Shared Compose Multiplatform UI) │ +└────────────────────┬────────────────────────────────────────┘ + │ uses + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ modules/agent-core-kmp │ +│ (Business logic, domain, contracts) │ +└────────────────────┬────────────────────────────────────────┘ + │ provides to + ▼ + ┌────────────────┴────────────────┐ + │ │ + ▼ ▼ +┌──────────────┐ ┌────────────────────┐ +│clients/ │ │clients/ │ +│androidApp │ │iosApp │ +└──────────────┘ └────────────────────┘ +``` + +## C4 Architecture Diagrams + +For a more detailed view of the architecture, see the following C4 diagrams: + +| Level | Diagram | Description | File | +|-------|---------|-------------|------| +| C1 - Context | [System Context](./diagrams/context/system-context.mmd) | High-level view of the system and external actors | `context/system-context.mmd` | +| C2 - Containers | [Main Containers](./diagrams/container/system-containers.mmd) | Applications and services that compose Corvus | `container/system-containers.mmd` | +| C3 - Components | [Agent Core KMP](./diagrams/component/agent-core-kmp.mmd) | Internal components of the core module | `component/agent-core-kmp.mmd` | +| - | [Module Dependencies](./diagrams/module-dependencies.mmd) | Gradle dependency relationships | `module-dependencies.mmd` | + +See [Architecture Index](./architecture/index.md) for more details on how to visualize them. + ## Build Logic (Convention Plugins) Instead of repeating build logic in every `build.gradle.kts`, we use **Convention Plugins** located in `gradle/build-logic`. diff --git a/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/component/agent-core-kmp.mmd b/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/component/agent-core-kmp.mmd new file mode 100644 index 000000000..062bf8730 --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/component/agent-core-kmp.mmd @@ -0,0 +1,58 @@ +--- +# C4 Component Diagram - Agent Core KMP Module +# Generated: 2026-02-16 +# Skill: c4-diagrams +--- + +flowchart TB + %% External Dependencies + RUNTIME["Agent Runtime"]:::external + COMPOSE["Compose UI"]:::external + NEO4J["Neo4j"]:::external + LLM["LLM Providers"]:::external + + %% Agent Core KMP Components + subgraph CORE_KMP["Agent Core KMP"] + subgraph DOMAIN["Domain Layer"] + ENTITIES["Entities\nUser, Task, Agent, Session"]:::component + VALUE_OBJECTS["Value Objects\nAgentId, TaskId, etc."]:::component + DOMAIN_EVENTS["Domain Events\nTaskCreated, AgentTriggered"]:::component + end + + subgraph USE_CASES["Use Cases"] + TASK_MGMT["Task Management\nCreate, Update, Execute"]:::component + AGENT_ORCH["Agent Orchestration\nDispatch, Monitor"]:::component + KNOWLEDGE["Knowledge Retrieval\nQuery, Store"]:::component + end + + subgraph INTERFACES["Interfaces"] + REPOS["Repository Interfaces\nTaskRepository, etc."]:::component + SERVICES["Service Interfaces\nLLMService, GraphService"]:::component + end + + subgraph INFRA["Infrastructure"] + REPO_IMPL["Repository Implementations"]:::component + SERVICE_IMPL["Service Implementations"]:::component + DTOS["DTOs / Models"]:::component + end + end + + %% Relationships + RUNTIME -->|Uses| USE_CASES + COMPOSE -->|Observes| USE_CASES + + USE_CASES -->|Operates on| DOMAIN + USE_CASES -->|Depends on| INTERFACES + + INFRA -->|Implements| INTERFACES + INFRA -->|Uses| DOMAIN + + REPO_IMPL -->|Persists to| NEO4J + SERVICE_IMPL -->|Queries| LLM + + %% Styling + classDef external fill:#999,stroke:#666,stroke-width:2px,color:#fff + classDef component fill:#85bbf0,stroke:#5d8fc9,stroke-width:2px,color:#000 + classDef domain fill:#85bbf0,stroke:#5d8fc9,stroke-width:2px,color:#000 + + class ENTITIES,VALUE_OBJECTS,DOMAIN_EVENTS,TASK_MGMT,AGENT_ORCH,KNOWLEDGE,REPOS,SERVICES,REPO_IMPL,SERVICE_IMPL,DTOS component diff --git a/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/container/system-containers.mmd b/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/container/system-containers.mmd new file mode 100644 index 000000000..924f7c9dc --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/container/system-containers.mmd @@ -0,0 +1,68 @@ +--- +# C4 Container Diagram - Corvus Platform (Mermaid) +# Generated: 2026-02-16 +# Skill: c4-diagrams +--- + +flowchart TB + %% External Actors + actor(Developer):::person + actor(EndUser):::person + + %% External Systems + OPENAI["OpenAI API"]:::external + ANTHROPIC["Anthropic API"]:::external + NEO4J_EXT["Neo4j Cloud"]:::external + WEB_SOURCES["Web Sources"]:::external + + %% Corvus System Containers + subgraph CORVUS["Corvus Platform"] + subgraph CLIENTS["Clients"] + WEB_APP["Web Dashboard\nAstro + Vue"]:::container + ANDROID_APP["Android App\nKotlin + Compose"]:::container + IOS_APP["iOS App\nSwiftUI + KMP"]:::container + end + + subgraph RUNTIME["Runtime"] + AGENT_RUNTIME["Agent Runtime\nKotlin + Spring Boot"]:::container + RUST_SIDECAR["Rust Sidecar\nRust"]:::container + end + + subgraph DATA["Data"] + GRAPH_DB["Graph DB\nNeo4j"]:::database + end + + subgraph SHARED["Shared"] + CORE_KMP["Agent Core KMP\nKotlin Multiplatform"]:::container + COMPOSE_UI["Compose UI\nCompose Multiplatform"]:::container + end + end + + %% Relationships + Developer -->|Operates and monitors| WEB_APP + EndUser -->|Uses| WEB_APP + EndUser -->|Uses| ANDROID_APP + EndUser -->|Uses| IOS_APP + + WEB_APP -->|Sends commands| AGENT_RUNTIME + ANDROID_APP -->|Uses| COMPOSE_UI + IOS_APP -->|Uses| COMPOSE_UI + + AGENT_RUNTIME -->|Uses| CORE_KMP + COMPOSE_UI -->|Uses| CORE_KMP + + AGENT_RUNTIME -->|Reads/Writes| GRAPH_DB + AGENT_RUNTIME -->|Executes tasks| RUST_SIDECAR + + AGENT_RUNTIME -->|Queries LLM| OPENAI + AGENT_RUNTIME -->|Queries LLM| ANTHROPIC + RUST_SIDECAR -->|Scrapes| WEB_SOURCES + + %% Styling + classDef person fill:#f9f,stroke:#333,stroke-width:2px + classDef container fill:#438dd5,stroke:#2e6299,stroke-width:2px,color:#fff + classDef database fill:#438dd5,stroke:#2e6299,stroke-width:2px,color:#fff,shape:cylinder + classDef external fill:#999,stroke:#666,stroke-width:2px,color:#fff + + class WEB_APP,ANDROID_APP,IOS_APP,AGENT_RUNTIME,RUST_SIDECAR,CORE_KMP,COMPOSE_UI container + class GRAPH_DB database diff --git a/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/container/system-containers.puml b/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/container/system-containers.puml new file mode 100644 index 000000000..7162b13e7 --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/container/system-containers.puml @@ -0,0 +1,55 @@ +@startuml +' C4 Container Diagram - Corvus Platform +' Generated: 2026-02-16 +' Skill: c4-diagrams + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +LAYOUT_WITH_LEGEND() + +' External Actors +Person(developer, "Developer", "Configures and operates the platform") +Person(endUser, "End User", "Final agent user") + +' External Systems +System_Ext(openai, "OpenAI API", "LLM Provider") +System_Ext(anthropic, "Anthropic API", "LLM Provider") +System_Ext(neo4j, "Neo4j Cloud", "Graph Database") +System_Ext(web, "Web Sources", "Information scraping") + +' Corvus System +System_Boundary(corvus, "Corvus Platform") { + Container(webApp, "Web Dashboard", "Astro + Vue", "Operator dashboard and observability") + Container(androidApp, "Android App", "Kotlin + Compose", "Native mobile app") + Container(iosApp, "iOS App", "SwiftUI + KMP", "Native mobile app") + + Container(agentRuntime, "Agent Runtime", "Kotlin + Spring Boot", "Reactive agent orchestrator") + Container(rustSidecar, "Rust Sidecar", "Rust", "Scraping and sandboxed execution") + + ContainerDb(graphDb, "Graph DB", "Neo4j", "Persistent knowledge memory") + + Container(coreKmp, "Agent Core KMP", "Kotlin Multiplatform", "Shared business logic") + Container(composeUi, "Compose UI", "Compose Multiplatform", "Shared cross-platform UI") +} + +' Relationships +Rel(developer, webApp, "Operates and monitors", "HTTPS") +Rel(endUser, androidApp, "Uses", "UI") +Rel(endUser, iosApp, "Uses", "UI") +Rel(endUser, webApp, "Uses", "HTTPS") + +Rel(webApp, agentRuntime, "Sends commands", "REST/WebSocket") +Rel(androidApp, composeUi, "Uses", "KMP") +Rel(iosApp, composeUi, "Uses", "KMP") + +Rel(agentRuntime, coreKmp, "Uses", "Internal") +Rel(composeUi, coreKmp, "Uses", "KMP") + +Rel(agentRuntime, graphDb, "Reads/Writes knowledge", "Bolt Protocol") +Rel(agentRuntime, rustSidecar, "Executes sandboxed tasks", "gRPC/FFI") + +Rel(agentRuntime, openai, "Queries LLM", "HTTPS/REST") +Rel(agentRuntime, anthropic, "Queries LLM", "HTTPS/REST") +Rel(rustSidecar, web, "Performs scraping", "HTTPS") + +@enduml diff --git a/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/context/system-context.mmd b/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/context/system-context.mmd new file mode 100644 index 000000000..c61977042 --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/context/system-context.mmd @@ -0,0 +1,40 @@ +--- +# C4 Context Diagram - Corvus Platform +# Generated: 2026-02-16 +# Skill: c4-diagrams +--- + +flowchart TB + %% External Actors + actor(Developer):::person + actor(EndUser):::person + + %% External Systems + subgraph EXTERNAL_SYSTEMS [External Systems] + OPENAI["OpenAI API\n(LLM Provider)"] + ANTHROPIC["Anthropic API\n(LLM Provider)"] + NEO4J_EXT["Neo4j Cloud\n(Graph Database)"] + WEB_SOURCES["Web Sources\n(Scraping)"] + end + + %% Corvus System Boundary + subgraph CORVUS_SYSTEM [Corvus System] + CORVUS["Corvus Platform\nReactive Always-On Agent"] + end + + %% Relationships + Developer -->|Configures and operates| CORVUS + EndUser -->|Interacts with| CORVUS + + CORVUS -->|Queries LLM| OPENAI + CORVUS -->|Queries LLM| ANTHROPIC + CORVUS -->|Stores knowledge| NEO4J_EXT + CORVUS -->|Performs scraping| WEB_SOURCES + + %% Styling + classDef person fill:#f9f,stroke:#333,stroke-width:2px + classDef system fill:#1168bd,stroke:#0b4884,stroke-width:2px,color:#fff + classDef external fill:#999,stroke:#666,stroke-width:2px,color:#fff + + class CORVUS system + class OPENAI,ANTHROPIC,NEO4J_EXT,WEB_SOURCES external diff --git a/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/module-dependencies.mmd b/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/module-dependencies.mmd new file mode 100644 index 000000000..85dad5c97 --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/en/guides/architecture/diagrams/module-dependencies.mmd @@ -0,0 +1,58 @@ +--- +# Module Dependencies Diagram - Corvus +# Generated: 2026-02-16 +# Skill: c4-diagrams +--- + +flowchart TB + subgraph LEGEND["Legend"] + direction LR + CLIENT["Client"]:::client + CORE["Shared Core"]:::core + EXTERNAL["External"]:::external + end + + subgraph MODULES["Project Modules"] + direction TB + + subgraph CLIENTS["clients/"] + direction TB + ANDROID["androidApp\n(Kotlin + Android SDK)"]:::client + IOS["iosApp\n(Swift + KMP Framework)"]:::client + WEB["web\n(Astro + Vue)"]:::client + RUNTIME["agent-runtime\n(Kotlin + Spring Boot)"]:::client + COMPOSE["composeApp\n(Compose Multiplatform)"]:::client + end + + subgraph CORE_MODULE["modules/"] + CORE_KMP["agent-core-kmp\n(Kotlin Multiplatform)"]:::core + end + end + + subgraph EXTERNAL["External Dependencies"] + KMP["Kotlin Multiplatform"]:::external + COMPOSE_MP["Compose MP"]:::external + SPRING["Spring Boot"]:::external + ANDROID_SDK["Android SDK"]:::external + IOS_SDK["iOS SDK"]:::external + ASTRO["Astro/Vue"]:::external + end + + %% Dependencies + ANDROID -->|implementation| COMPOSE + IOS -->|framework| COMPOSE + + COMPOSE -->|api| CORE_KMP + RUNTIME -->|implementation| CORE_KMP + + CORE_KMP -->|kotlin| KMP + COMPOSE -->|compose| COMPOSE_MP + ANDROID -->|android| ANDROID_SDK + IOS -->|ios| IOS_SDK + RUNTIME -->|spring| SPRING + WEB -->|astro| ASTRO + + %% Styling + classDef client fill:#438dd5,stroke:#2e6299,stroke-width:2px,color:#fff + classDef core fill:#2e6299,stroke:#1a3d5c,stroke-width:3px,color:#fff + classDef external fill:#999,stroke:#666,stroke-width:1px,color:#fff diff --git a/clients/web/apps/docs/src/content/docs/en/guides/architecture/index.md b/clients/web/apps/docs/src/content/docs/en/guides/architecture/index.md new file mode 100644 index 000000000..9115b73e2 --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/en/guides/architecture/index.md @@ -0,0 +1,81 @@ +--- +title: Architecture Diagrams +description: Collection of C4 diagrams for the Corvus project +--- + +# Architecture Diagrams + +This section contains the architecture diagrams for the Corvus project, following the C4 model (Context, Container, Component, Code). + +## Level 1: System Context + +Shows the Corvus system as a black box and its interactions with actors and external systems. + +- **File**: [`context/system-context.mmd`](./diagrams/context/system-context.mmd) +- **Format**: Mermaid +- **Description**: High-level view of the complete system, including users (Developer, End User) and external systems (LLM Providers, Neo4j, Web Sources). + +## Level 2: Containers + +Decomposes the system into main containers/applications and their interactions. + +- **Files**: + - [`container/system-containers.mmd`](./diagrams/container/system-containers.mmd) (Mermaid) + - [`container/system-containers.puml`](./diagrams/container/system-containers.puml) (PlantUML) +- **Description**: Shows the main containers: Web Dashboard, Android App, iOS App, Agent Runtime, Rust Sidecar, and Graph DB. + +## Level 3: Components + +Decomposes individual containers into their internal components. + +### Agent Core KMP + +- **File**: [`component/agent-core-kmp.mmd`](./diagrams/component/agent-core-kmp.mmd) +- **Description**: Internal components of the core module: Domain, Use Cases, Interfaces, and Infrastructure. + +## Module Dependencies + +Additional diagram showing Gradle dependencies between modules. + +- **File**: [`module-dependencies.mmd`](./diagrams/module-dependencies.mmd) +- **Description**: Shows how clients depend on the shared core and external frameworks. + +## How to Visualize + +### Option 1: GitHub/GitLab +`.mmd` files are automatically rendered on GitHub and GitLab. + +### Option 2: VS Code +Install the "Markdown Preview Mermaid Support" extension to view diagrams in VS Code. + +### Option 3: Mermaid CLI +```bash +# Install mermaid-cli +npm install -g @mermaid-js/mermaid-cli + +# Render to PNG +mmdc -i diagrams/context/system-context.mmd -o context.png +``` + +### Option 4: PlantUML +For `.puml` files: +```bash +# Use PlantUML online or locally +plantuml -tpng diagrams/container/system-containers.puml +``` + +## Conventions + +- **Context Level (C1)**: One diagram showing the complete system +- **Container Level (C2)**: One diagram per system, showing main applications +- **Component Level (C3)**: Diagrams for significant containers +- **Code Level (C4)**: UML class diagrams for critical components (optional) + +## Maintenance + +When adding new modules or changing architecture: + +1. Update the corresponding diagram +2. Keep IDs consistent across levels +3. Update this index page if adding new diagrams +4. Commit changes with format: `docs(architecture): update C4 diagrams` diff --git a/clients/web/apps/docs/src/content/docs/en/guides/structure.md b/clients/web/apps/docs/src/content/docs/en/guides/structure.md index b9edb45a0..08b80572a 100644 --- a/clients/web/apps/docs/src/content/docs/en/guides/structure.md +++ b/clients/web/apps/docs/src/content/docs/en/guides/structure.md @@ -6,34 +6,42 @@ A detailed look at the organization of the **Corvus** repository. ## Root Directory -- `apps/`: Standalone applications (backend services, web apps, mobile apps, docs web). -- `modules/`: Reusable shared modules and cores. +- `clients/`: Client applications (Android, iOS, Web, agent runtime). +- `modules/`: Reusable shared modules and cores (agent core). - `gradle/`: Gradle-specific configurations and build logic. +- `docs/`: Project documentation (Astro + Starlight website). - `Makefile`: Standardized commands for common tasks. - `settings.gradle.kts`: Defines the project hierarchy and includes modules. - `README.md`: High-level project overview. - `AGENTS.md`: Specialized instructions for AI agents. -## The `apps` Directory +## The `clients` Directory -- `apps/composeApp`: Shared Kotlin Multiplatform Compose UI module. -- `apps/androidApp`: Native Android wrapper app wired to the shared Compose module. -- `apps/iosApp`: Native iOS wrapper app wired to the shared Compose framework. -- `apps/docs`: Documentation website module (Astro + Starlight). +Contains all client applications that consume the shared modules: + +- `clients/composeApp`: Shared Kotlin Multiplatform Compose UI module. +- `clients/androidApp`: Native Android wrapper app wired to the shared Compose module. +- `clients/iosApp`: Native iOS wrapper app wired to the shared Compose framework. +- `clients/web`: Web application and operator dashboard. +- `clients/agent-runtime`: Agent runtime for task execution. ## The `modules` Directory -- `modules/agent-core-kmp`: Shared Kotlin Multiplatform bootstrap for the future agent core. -- `apps/agent-runtime-rust`: Rust agent runtime app imported from corvus. +- `modules/agent-core-kmp`: Shared Kotlin Multiplatform core for the agent. + Business logic, domain models, and reusable contracts across all platforms. ## The `gradle` Directory -- **`build-logic`**: Contains custom convention plugins written in Kotlin. This is the "brain" of the build system. +- **`build-logic/`**: Contains custom convention plugins written in Kotlin. This is the "brain" of the build system. - **`libs.versions.toml`**: The central version catalog for managing dependencies. -- **`aggregation`**: Module used to aggregate test and coverage reports from all submodules. -- **`versions`**: Module dedicated to version management and catalog consistency checks. -- **`wrapper`**: Contains the Gradle wrapper files, ensuring consistent build environments. +- **`aggregation/`**: Module used to aggregate test and coverage reports from all submodules. +- **`versions/`**: Module dedicated to version management and catalog consistency checks. +- **`wrapper/`**: Contains the Gradle wrapper files, ensuring consistent build environments. +- **`configs/`**: Additional tool configurations (Detekt, Spotless, etc.). -## The `apps/docs` Directory +## The `docs` Directory -- **`website`**: Source code for this documentation site, built with Astro and Starlight. +- **`docs/es/`**: Documentation in Spanish. + - `index.mdx`: Home page. + - `guides/`: Detailed project guides. +- **`docs/en/`**: Documentation in English. diff --git a/clients/web/apps/docs/src/content/docs/es/guides/architecture.md b/clients/web/apps/docs/src/content/docs/es/guides/architecture.md index dccf27e9e..86640af8f 100644 --- a/clients/web/apps/docs/src/content/docs/es/guides/architecture.md +++ b/clients/web/apps/docs/src/content/docs/es/guides/architecture.md @@ -2,28 +2,60 @@ title: Arquitectura --- -El proyecto sigue una arquitectura modular con un fuerte énfasis en la lógica de construcción centralizada. +El proyecto sigue una arquitectura modular con un fuerte énfasis en la lógica de construcción centralizada y separación clara entre clientes y módulos compartidos. ## Estructura del Proyecto ```text . -├── apps/ -│ ├── agent-runtime-rust/ # App runtime del agente en Rust -│ ├── androidApp/ # App host de Android -│ ├── composeApp/ # Módulo compartido Compose Multiplatform -│ ├── docs/ # Documentación (sitio Starlight) -│ └── iosApp/ # App host de iOS (proyecto Xcode) -├── modules/ -│ └── agent-core-kmp/ # Módulo compartido de contratos/base KMP -├── gradle/ -│ ├── build-logic/ # Plugins de convención personalizados de Gradle -│ ├── libs.versions.toml # Catálogo de versiones -│ └── wrapper/ # Wrapper de Gradle -├── Makefile # Interfaz de comandos estandarizada -└── settings.gradle.kts # Configuración global del proyecto +├── clients/ # Aplicaciones cliente +│ ├── agent-runtime/ # Runtime del agente +│ ├── androidApp/ # App host de Android +│ ├── composeApp/ # Módulo compartido Compose Multiplatform +│ ├── iosApp/ # App host de iOS (proyecto Xcode) +│ └── web/ # Aplicación web y panel de operadores +├── modules/ # Módulos compartidos +│ └── agent-core-kmp/ # Core del agente en Kotlin Multiplatform +├── gradle/ # Configuración de construcción +│ ├── build-logic/ # Plugins de convención personalizados +│ ├── aggregation/ # Agregación de reportes +│ ├── configs/ # Configuraciones de herramientas +│ ├── versions/ # Gestión de versiones +│ ├── libs.versions.toml # Catálogo de versiones +│ └── wrapper/ # Wrapper de Gradle +├── docs/ # Documentación (Astro + Starlight) +├── Makefile # Interfaz de comandos estandarizada +└── settings.gradle.kts # Configuración global del proyecto ``` +## Arquitectura de Alto Nivel + +Corvus está diseñado como una plataforma de agentes reactivos con los siguientes pilares: + +### 1. **Orquestador Reactivo** + +- **Tecnología**: Kotlin + Spring Boot + Coroutines/WebFlux +- **Propósito**: Manejar flujos de trabajo no bloqueantes y always-on +- **Ubicación**: Runtime del agente en `clients/agent-runtime/` + +### 2. **Memoria de Grafo** + +- **Tecnología**: Neo4j (planificado) +- **Propósito**: Modelo de conocimiento con contexto conectado y memoria durable +- **Integración**: A través de `agent-core-kmp` + +### 3. **Sidecars de Alto Rendimiento** + +- **Tecnología**: Rust (planificado) +- **Propósito**: Operaciones de scraping y ejecución sandboxed de alta performance +- **Comunicación**: FFI o gRPC con el runtime Kotlin + +### 4. **Panel de Control** + +- **Tecnología**: Astro + Vue (planificado) +- **Propósito**: Observabilidad en tiempo real y operación transparente +- **Ubicación**: `clients/web/` + ## Lógica de Construcción (Plugins de Convención) En lugar de repetir la lógica de construcción en cada `build.gradle.kts`, utilizamos **Plugins de Convención** ubicados en `gradle/build-logic`. @@ -31,7 +63,7 @@ En lugar de repetir la lógica de construcción en cada `build.gradle.kts`, util ### Categorías de Plugins 1. **Plugins Base**: Configuración fundamental como identidad, ciclo de vida y resolución de conflictos de JVM. -2. **Plugins de Módulo**: Configuraciones específicas del lenguaje (`kotlin`, `java`, `spring-boot`). +2. **Plugins de Módulo**: Configuraciones específicas del lenguaje (`kotlin`, `java`, `spring-boot`, `compose`). 3. **Plugins de Funcionalidad**: Funcionalidades opcionales como `publish-library`, `shadow`, `test-fixtures` y `git-hook`. 4. **Plugins de Verificación**: Herramientas de calidad de código y formateo (`spotless`, `detekt`, `spotbugs`). 5. **Plugins de Reporte**: Reportes agregados para pruebas, cobertura y SBOM. @@ -48,3 +80,40 @@ dependencies { testImplementation(libs.junit.jupiter) } ``` + +## Flujo de Dependencias entre Módulos + +``` +┌─────────────────────────────────────────────────────────────┐ +│ clients/composeApp │ +│ (UI compartida Compose Multiplatform) │ +└────────────────────┬────────────────────────────────────────┘ + │ usa + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ modules/agent-core-kmp │ +│ (Lógica de negocio, dominio, contratos) │ +└────────────────────┬────────────────────────────────────────┘ + │ provee a + ▼ + ┌────────────────┴────────────────┐ + │ │ + ▼ ▼ +┌──────────────┐ ┌────────────────────┐ +│clients/ │ │clients/ │ +│androidApp │ │iosApp │ +└──────────────┘ └────────────────────┘ +``` + +## Diagramas de Arquitectura C4 + +Para una vista más detallada de la arquitectura, consulta los siguientes diagramas C4: + +| Nivel | Diagrama | Descripción | Archivo | +|-------|----------|-------------|---------| +| C1 - Contexto | [Sistema Completo](./diagrams/context/system-context.mmd) | Vista de alto nivel del sistema y actores externos | `context/system-context.mmd` | +| C2 - Contenedores | [Contenedores Principales](./diagrams/container/system-containers.mmd) | Aplicaciones y servicios que componen Corvus | `container/system-containers.mmd` | +| C3 - Componentes | [Agent Core KMP](./diagrams/component/agent-core-kmp.mmd) | Componentes internos del módulo core | `component/agent-core-kmp.mmd` | +| - | [Dependencias entre Módulos](./diagrams/module-dependencies.mmd) | Relaciones de dependencia de Gradle | `module-dependencies.mmd` | + +Ver [Índice de Diagramas](./architecture/index.md) (en inglés) para más detalles sobre cómo visualizarlos. diff --git a/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/component/agent-core-kmp.mmd b/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/component/agent-core-kmp.mmd new file mode 100644 index 000000000..e1206ad4d --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/component/agent-core-kmp.mmd @@ -0,0 +1,58 @@ +--- +# C4 Component Diagram - Agent Core KMP Module +# Generated: 2026-02-16 +# Skill: c4-diagrams +--- + +flowchart TB + %% External Dependencies + RUNTIME["Agent Runtime"]:::external + COMPOSE["Compose UI"]:::external + NEO4J["Neo4j"]:::external + LLM["LLM Providers"]:::external + + %% Agent Core KMP Components + subgraph CORE_KMP["Agent Core KMP"] + subgraph DOMAIN["Capa de Dominio"] + ENTITIES["Entities\nUser, Task, Agent, Session"]:::component + VALUE_OBJECTS["Value Objects\nAgentId, TaskId, etc."]:::component + DOMAIN_EVENTS["Domain Events\nTaskCreated, AgentTriggered"]:::component + end + + subgraph USE_CASES["Casos de Uso"] + TASK_MGMT["Task Management\nCreate, Update, Execute"]:::component + AGENT_ORCH["Agent Orchestration\nDispatch, Monitor"]:::component + KNOWLEDGE["Knowledge Retrieval\nQuery, Store"]:::component + end + + subgraph INTERFACES["Interfaces"] + REPOS["Repository Interfaces\nTaskRepository, etc."]:::component + SERVICES["Service Interfaces\nLLMService, GraphService"]:::component + end + + subgraph INFRA["Infraestructura"] + REPO_IMPL["Repository Implementations"]:::component + SERVICE_IMPL["Service Implementations"]:::component + DTOS["DTOs / Models"]:::component + end + end + + %% Relationships + RUNTIME -->|Usa| USE_CASES + COMPOSE -->|Observa| USE_CASES + + USE_CASES -->|Opera sobre| DOMAIN + USE_CASES -->|Depende de| INTERFACES + + INFRA -->|Implementa| INTERFACES + INFRA -->|Usa| DOMAIN + + REPO_IMPL -->|Persiste en| NEO4J + SERVICE_IMPL -->|Consulta| LLM + + %% Styling + classDef external fill:#999,stroke:#666,stroke-width:2px,color:#fff + classDef component fill:#85bbf0,stroke:#5d8fc9,stroke-width:2px,color:#000 + classDef domain fill:#85bbf0,stroke:#5d8fc9,stroke-width:2px,color:#000 + + class ENTITIES,VALUE_OBJECTS,DOMAIN_EVENTS,TASK_MGMT,AGENT_ORCH,KNOWLEDGE,REPOS,SERVICES,REPO_IMPL,SERVICE_IMPL,DTOS component diff --git a/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/container/system-containers.mmd b/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/container/system-containers.mmd new file mode 100644 index 000000000..67c546db1 --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/container/system-containers.mmd @@ -0,0 +1,68 @@ +--- +# C4 Container Diagram - Corvus Platform (Mermaid) +# Generated: 2026-02-16 +# Skill: c4-diagrams +--- + +flowchart TB + %% External Actors + actor(Developer):::person + actor(EndUser):::person + + %% External Systems + OPENAI["OpenAI API"]:::external + ANTHROPIC["Anthropic API"]:::external + NEO4J_EXT["Neo4j Cloud"]:::external + WEB_SOURCES["Fuentes Web"]:::external + + %% Corvus System Containers + subgraph CORVUS["Corvus Platform"] + subgraph CLIENTS["Clientes"] + WEB_APP["Web Dashboard\nAstro + Vue"]:::container + ANDROID_APP["Android App\nKotlin + Compose"]:::container + IOS_APP["iOS App\nSwiftUI + KMP"]:::container + end + + subgraph RUNTIME["Runtime"] + AGENT_RUNTIME["Agent Runtime\nKotlin + Spring Boot"]:::container + RUST_SIDECAR["Rust Sidecar\nRust"]:::container + end + + subgraph DATA["Datos"] + GRAPH_DB["Graph DB\nNeo4j"]:::database + end + + subgraph SHARED["Compartido"] + CORE_KMP["Agent Core KMP\nKotlin Multiplatform"]:::container + COMPOSE_UI["Compose UI\nCompose Multiplatform"]:::container + end + end + + %% Relationships + Developer -->|Opera y monitorea| WEB_APP + EndUser -->|Usa| WEB_APP + EndUser -->|Usa| ANDROID_APP + EndUser -->|Usa| IOS_APP + + WEB_APP -->|Envía comandos| AGENT_RUNTIME + ANDROID_APP -->|Usa| COMPOSE_UI + IOS_APP -->|Usa| COMPOSE_UI + + AGENT_RUNTIME -->|Usa| CORE_KMP + COMPOSE_UI -->|Usa| CORE_KMP + + AGENT_RUNTIME -->|Lee/Escribe| GRAPH_DB + AGENT_RUNTIME -->|Ejecuta tareas| RUST_SIDECAR + + AGENT_RUNTIME -->|Consulta LLM| OPENAI + AGENT_RUNTIME -->|Consulta LLM| ANTHROPIC + RUST_SIDECAR -->|Scraping| WEB_SOURCES + + %% Styling + classDef person fill:#f9f,stroke:#333,stroke-width:2px + classDef container fill:#438dd5,stroke:#2e6299,stroke-width:2px,color:#fff + classDef database fill:#438dd5,stroke:#2e6299,stroke-width:2px,color:#fff,shape:cylinder + classDef external fill:#999,stroke:#666,stroke-width:2px,color:#fff + + class WEB_APP,ANDROID_APP,IOS_APP,AGENT_RUNTIME,RUST_SIDECAR,CORE_KMP,COMPOSE_UI container + class GRAPH_DB database diff --git a/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/container/system-containers.puml b/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/container/system-containers.puml new file mode 100644 index 000000000..14146de0f --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/container/system-containers.puml @@ -0,0 +1,55 @@ +@startuml +' C4 Container Diagram - Corvus Platform +' Generated: 2026-02-16 +' Skill: c4-diagrams + +!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml + +LAYOUT_WITH_LEGEND() + +' External Actors +Person(developer, "Developer", "Configura y opera la plataforma") +Person(endUser, "End User", "Usuario final del agente") + +' External Systems +System_Ext(openai, "OpenAI API", "Proveedor de LLM") +System_Ext(anthropic, "Anthropic API", "Proveedor de LLM") +System_Ext(neo4j, "Neo4j Cloud", "Base de datos de grafo") +System_Ext(web, "Fuentes Web", "Scraping de información") + +' Corvus System +System_Boundary(corvus, "Corvus Platform") { + Container(webApp, "Web Dashboard", "Astro + Vue", "Panel de operadores y observabilidad") + Container(androidApp, "Android App", "Kotlin + Compose", "App móvil nativa") + Container(iosApp, "iOS App", "SwiftUI + KMP", "App móvil nativa") + + Container(agentRuntime, "Agent Runtime", "Kotlin + Spring Boot", "Orquestador reactivo de agentes") + Container(rustSidecar, "Rust Sidecar", "Rust", "Scraping y ejecución sandboxed") + + ContainerDb(graphDb, "Graph DB", "Neo4j", "Memoria de conocimiento persistente") + + Container(coreKmp, "Agent Core KMP", "Kotlin Multiplatform", "Lógica de negocio compartida") + Container(composeUi, "Compose UI", "Compose Multiplatform", "UI compartida multiplataforma") +} + +' Relationships +Rel(developer, webApp, "Opera y monitorea", "HTTPS") +Rel(endUser, androidApp, "Usa", "UI") +Rel(endUser, iosApp, "Usa", "UI") +Rel(endUser, webApp, "Usa", "HTTPS") + +Rel(webApp, agentRuntime, "Envía comandos", "REST/WebSocket") +Rel(androidApp, composeUi, "Usa", "KMP") +Rel(iosApp, composeUi, "Usa", "KMP") + +Rel(agentRuntime, coreKmp, "Usa", "Internal") +Rel(composeUi, coreKmp, "Usa", "KMP") + +Rel(agentRuntime, graphDb, "Lee/Escribe conocimiento", "Bolt Protocol") +Rel(agentRuntime, rustSidecar, "Ejecuta tareas sandboxed", "gRPC/FFI") + +Rel(agentRuntime, openai, "Consulta LLM", "HTTPS/REST") +Rel(agentRuntime, anthropic, "Consulta LLM", "HTTPS/REST") +Rel(rustSidecar, web, "Realiza scraping", "HTTPS") + +@enduml diff --git a/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/context/system-context.mmd b/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/context/system-context.mmd new file mode 100644 index 000000000..cee9c32a8 --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/context/system-context.mmd @@ -0,0 +1,41 @@ +--- +# C4 Context Diagram - Corvus Platform +# Generated: 2026-02-16 +# Skill: c4-diagrams +# Git SHA: (current) +--- + +flowchart TB + %% External Actors + actor(Developer):::person + actor(EndUser):::person + + %% External Systems + subgraph EXTERNAL_SYSTEMS [Sistemas Externos] + OPENAI["OpenAI API\n(LLM Provider)"] + ANTHROPIC["Anthropic API\n(LLM Provider)"] + NEO4J_EXT["Neo4j Cloud\n(Graph Database)"] + WEB_SOURCES["Fuentes Web\n(Scraping)"] + end + + %% Corvus System Boundary + subgraph CORVUS_SYSTEM [Sistema Corvus] + CORVUS["Corvus Platform\nAgente Reactivo Siempre Activo"] + end + + %% Relationships + Developer -->|Configura y opera| CORVUS + EndUser -->|Interactúa con| CORVUS + + CORVUS -->|Consulta LLM| OPENAI + CORVUS -->|Consulta LLM| ANTHROPIC + CORVUS -->|Almacena conocimiento| NEO4J_EXT + CORVUS -->|Realiza scraping| WEB_SOURCES + + %% Styling + classDef person fill:#f9f,stroke:#333,stroke-width:2px + classDef system fill:#1168bd,stroke:#0b4884,stroke-width:2px,color:#fff + classDef external fill:#999,stroke:#666,stroke-width:2px,color:#fff + + class CORVUS system + class OPENAI,ANTHROPIC,NEO4J_EXT,WEB_SOURCES external diff --git a/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/module-dependencies.mmd b/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/module-dependencies.mmd new file mode 100644 index 000000000..370a0709a --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/es/guides/architecture/diagrams/module-dependencies.mmd @@ -0,0 +1,58 @@ +--- +# Module Dependencies Diagram - Corvus +# Generated: 2026-02-16 +# Skill: c4-diagrams +--- + +flowchart TB + subgraph LEGEND["Leyenda"] + direction LR + CLIENT["Cliente"]:::client + CORE["Core Compartido"]:::core + EXTERNAL["Externo"]:::external + end + + subgraph MODULES["Módulos del Proyecto"] + direction TB + + subgraph CLIENTS["clients/"] + direction TB + ANDROID["androidApp\n(Kotlin + Android SDK)"]:::client + IOS["iosApp\n(Swift + KMP Framework)"]:::client + WEB["web\n(Astro + Vue)"]:::client + RUNTIME["agent-runtime\n(Kotlin + Spring Boot)"]:::client + COMPOSE["composeApp\n(Compose Multiplatform)"]:::client + end + + subgraph CORE_MODULE["modules/"] + CORE_KMP["agent-core-kmp\n(Kotlin Multiplatform)"]:::core + end + end + + subgraph EXTERNAL["Dependencias Externas"] + KMP["Kotlin Multiplatform"]:::external + COMPOSE_MP["Compose MP"]:::external + SPRING["Spring Boot"]:::external + ANDROID_SDK["Android SDK"]:::external + IOS_SDK["iOS SDK"]:::external + ASTRO["Astro/Vue"]:::external + end + + %% Dependencies + ANDROID -->|implementation| COMPOSE + IOS -->|framework| COMPOSE + + COMPOSE -->|api| CORE_KMP + RUNTIME -->|implementation| CORE_KMP + + CORE_KMP -->|kotlin| KMP + COMPOSE -->|compose| COMPOSE_MP + ANDROID -->|android| ANDROID_SDK + IOS -->|ios| IOS_SDK + RUNTIME -->|spring| SPRING + WEB -->|astro| ASTRO + + %% Styling + classDef client fill:#438dd5,stroke:#2e6299,stroke-width:2px,color:#fff + classDef core fill:#2e6299,stroke:#1a3d5c,stroke-width:3px,color:#fff + classDef external fill:#999,stroke:#666,stroke-width:1px,color:#fff diff --git a/clients/web/apps/docs/src/content/docs/es/guides/architecture/index.md b/clients/web/apps/docs/src/content/docs/es/guides/architecture/index.md new file mode 100644 index 000000000..8cfd538d9 --- /dev/null +++ b/clients/web/apps/docs/src/content/docs/es/guides/architecture/index.md @@ -0,0 +1,81 @@ +--- +title: Diagramas de Arquitectura +description: Colección de diagramas C4 para el proyecto Corvus +--- + +# Diagramas de Arquitectura + +Esta sección contiene los diagramas de arquitectura del proyecto Corvus, siguiendo el modelo C4 (Context, Container, Component, Code). + +## Nivel 1: Contexto del Sistema + +Muestra el sistema Corvus como una caja negra y sus interacciones con actores y sistemas externos. + +- **Archivo**: [`context/system-context.mmd`](./diagrams/context/system-context.mmd) +- **Formato**: Mermaid +- **Descripción**: Vista de alto nivel del sistema completo, incluyendo usuarios (Developer, End User) y sistemas externos (LLM Providers, Neo4j, Fuentes Web). + +## Nivel 2: Contenedores + +Descompone el sistema en contenedores/aplicaciones principales y sus interacciones. + +- **Archivos**: + - [`container/system-containers.mmd`](./diagrams/container/system-containers.mmd) (Mermaid) + - [`container/system-containers.puml`](./diagrams/container/system-containers.puml) (PlantUML) +- **Descripción**: Muestra los contenedores principales: Web Dashboard, Android App, iOS App, Agent Runtime, Rust Sidecar, y Graph DB. + +## Nivel 3: Componentes + +Descompone contenedores individuales en sus componentes internos. + +### Agent Core KMP + +- **Archivo**: [`component/agent-core-kmp.mmd`](./diagrams/component/agent-core-kmp.mmd) +- **Descripción**: Componentes internos del módulo core: Dominio, Casos de Uso, Interfaces e Infraestructura. + +## Dependencias entre Módulos + +Diagrama adicional mostrando las dependencias de Gradle entre módulos. + +- **Archivo**: [`module-dependencies.mmd`](./diagrams/module-dependencies.mmd) +- **Descripción**: Muestra cómo los clientes dependen del core compartido y de frameworks externos. + +## Cómo Visualizar + +### Opción 1: GitHub/GitLab +Los archivos `.mmd` se renderizan automáticamente en GitHub y GitLab. + +### Opción 2: VS Code +Instala la extensión "Markdown Preview Mermaid Support" para ver los diagramas en VS Code. + +### Opción 3: Mermaid CLI +```bash +# Instalar mermaid-cli +npm install -g @mermaid-js/mermaid-cli + +# Renderizar a PNG +mmdc -i diagrams/context/system-context.mmd -o context.png +``` + +### Opción 4: PlantUML +Para los archivos `.puml`: +```bash +# Usar PlantUML online o local +plantuml -tpng diagrams/container/system-containers.puml +``` + +## Convenciones + +- **Nivel Contexto (C1)**: Un diagrama mostrando el sistema completo +- **Nivel Contenedor (C2)**: Un diagrama por sistema, mostrando aplicaciones principales +- **Nivel Componente (C3)**: Diagramas para contenedores significativos +- **Nivel Código (C4)**: Diagramas UML de clases para componentes críticos (opcional) + +## Mantenimiento + +Cuando agregues nuevos módulos o cambies la arquitectura: + +1. Actualiza el diagrama correspondiente +2. Mantén los IDs consistentes entre niveles +3. Actualiza esta página de índice si agregas nuevos diagramas +4. Genera un commit con los cambios siguiendo el formato: `docs(architecture): update C4 diagrams` diff --git a/clients/web/apps/docs/src/content/docs/es/guides/structure.md b/clients/web/apps/docs/src/content/docs/es/guides/structure.md index 1c948e0a3..e5f3277d2 100644 --- a/clients/web/apps/docs/src/content/docs/es/guides/structure.md +++ b/clients/web/apps/docs/src/content/docs/es/guides/structure.md @@ -6,34 +6,42 @@ Una mirada detallada a la organización del repositorio **Corvus**. ## Directorio Raíz -- `apps/`: Aplicaciones standalone (backend, web, móvil, docs web). -- `modules/`: Módulos compartidos y reutilizables. +- `clients/`: Aplicaciones cliente (Android, iOS, Web, runtime del agente). +- `modules/`: Módulos compartidos y reutilizables (core del agente). - `gradle/`: Configuraciones específicas de Gradle y lógica de construcción. +- `docs/`: Documentación del proyecto (sitio Astro + Starlight). - `Makefile`: Comandos estandarizados para tareas comunes. - `settings.gradle.kts`: Define la jerarquía del proyecto e incluye los módulos. - `README.md`: Descripción general del proyecto a alto nivel. - `AGENTS.md`: Instrucciones especializadas para agentes de IA. -## El Directorio `apps` +## El Directorio `clients` -- `apps/composeApp`: Módulo UI compartido en Compose Kotlin Multiplatform. -- `apps/androidApp`: App wrapper nativa de Android conectada al módulo Compose compartido. -- `apps/iosApp`: App wrapper nativa de iOS conectada al framework Compose compartido. -- `apps/docs`: Módulo del sitio de documentación (Astro + Starlight). +Contiene todas las aplicaciones cliente que consumen los módulos compartidos: + +- `clients/composeApp`: Módulo UI compartido en Compose Kotlin Multiplatform. +- `clients/androidApp`: App wrapper nativa de Android conectada al módulo Compose compartido. +- `clients/iosApp`: App wrapper nativa de iOS conectada al framework Compose compartido. +- `clients/web`: Aplicación web y panel de operadores. +- `clients/agent-runtime`: Runtime del agente para ejecución de tareas. ## El Directorio `modules` - `modules/agent-core-kmp`: Base compartida en Kotlin Multiplatform para el núcleo del agente. -- `apps/agent-runtime-rust`: App runtime del agente en Rust importada desde corvus. + Lógica de negocio, modelos de dominio, y contratos reutilizables entre todas las plataformas. ## El Directorio `gradle` -- **`build-logic`**: Contiene plugins de convención personalizados escritos en Kotlin. Es el "cerebro" del sistema de construcción. +- **`build-logic/`**: Contiene plugins de convención personalizados escritos en Kotlin. Es el "cerebro" del sistema de construcción. - **`libs.versions.toml`**: El catálogo de versiones central para gestionar las dependencias. -- **`aggregation`**: Módulo utilizado para agregar reportes de pruebas y cobertura de todos los submódulos. -- **`versions`**: Módulo dedicado a la gestión de versiones y comprobación de consistencia del catálogo. -- **`wrapper`**: Contiene los archivos del wrapper de Gradle, asegurando entornos de construcción consistentes. +- **`aggregation/`**: Módulo utilizado para agregar reportes de pruebas y cobertura de todos los submódulos. +- **`versions/`**: Módulo dedicado a la gestión de versiones y comprobación de consistencia del catálogo. +- **`wrapper/`**: Contiene los archivos del wrapper de Gradle, asegurando entornos de construcción consistentes. +- **`configs/`**: Configuraciones adicionales de herramientas (Detekt, Spotless, etc.). -## El Directorio `apps/docs` +## El Directorio `docs` -- **`website`**: Código fuente de este sitio de documentación, construido con Astro y Starlight. +- **`docs/es/`**: Documentación en español. + - `index.mdx`: Página de inicio. + - `guides/`: Guías detalladas del proyecto. +- **`docs/en/`**: Documentación en inglés (si aplica). From b5596173ecee541718c8d3f107a3596146e93a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yuniel=20Acosta=20P=C3=A9rez?= <33158051+yacosta738@users.noreply.github.com> Date: Mon, 16 Feb 2026 21:06:38 +0100 Subject: [PATCH 2/2] style: apply spotless formatting fixes --- .gitignore | 9 + apps/iosApp/iosApp.xcodeproj/project.pbxproj | 360 ------------------ .../contents.xcworkspacedata | 7 - clients/agent-runtime/src/config/schema.rs | 66 +++- clients/agent-runtime/src/onboard/wizard.rs | 12 +- .../corvus/ui/chat/ChatWorkspace.kt | 40 +- clients/web/.gitignore | 4 + clients/web/build.gradle.kts | 30 ++ 8 files changed, 118 insertions(+), 410 deletions(-) delete mode 100644 apps/iosApp/iosApp.xcodeproj/project.pbxproj delete mode 100644 apps/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/.gitignore b/.gitignore index f991692c9..b40210ec6 100644 --- a/.gitignore +++ b/.gitignore @@ -140,6 +140,15 @@ docs/website/node_modules/ # package-lock.json is ignored because we use pnpm exclusively (pnpm-lock.yaml is committed) docs/website/package-lock.json +# Web Apps (Astro, Vite, etc.) +# Astro cache/build directories +**/.astro/ +clients/web/apps/**/dist/ +clients/web/apps/**/node_modules/ + +# Symlinks auto-generados por Gradle +/docs + # Spotless Prettier Node Modules (auto-generated by build) build/spotless-prettier-node-modules-*/ build/spotless-prettier-node-modules-*/node_modules/ diff --git a/apps/iosApp/iosApp.xcodeproj/project.pbxproj b/apps/iosApp/iosApp.xcodeproj/project.pbxproj deleted file mode 100644 index 1f8879ecb..000000000 --- a/apps/iosApp/iosApp.xcodeproj/project.pbxproj +++ /dev/null @@ -1,360 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 77; - objects = { - -/* Begin PBXFileReference section */ - 3238C18ABCE3C58991C465EC /* .app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = .app; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFileSystemSynchronizedRootGroup section */ - 5F5D490E965D25607D5D7524 /* Configuration */ = { - isa = PBXFileSystemSynchronizedRootGroup; - path = Configuration; - sourceTree = ""; - }; - 91A73B860506856B9B2FE3D5 /* iosApp */ = { - isa = PBXFileSystemSynchronizedRootGroup; - path = iosApp; - sourceTree = ""; - }; -/* End PBXFileSystemSynchronizedRootGroup section */ - -/* Begin PBXFrameworksBuildPhase section */ - 2D54EF7E2A5C186A38E5CAE6 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - AF6178E04E76F2F1039A2D2C /* Products */ = { - isa = PBXGroup; - children = ( - 3238C18ABCE3C58991C465EC /* .app */, - ); - name = Products; - sourceTree = ""; - }; - C4AA065C02E3A768CC43E6DC = { - isa = PBXGroup; - children = ( - 5F5D490E965D25607D5D7524 /* Configuration */, - 91A73B860506856B9B2FE3D5 /* iosApp */, - AF6178E04E76F2F1039A2D2C /* Products */, - ); - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 63ACFC810DF62A4798655B3D /* iosApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = AF9E04F3E0A3E4C21CEC33B5 /* Build configuration list for PBXNativeTarget "iosApp" */; - buildPhases = ( - C6E8EBDEBEEF4B26D40F8C59 /* Compile Kotlin Framework */, - 35E444CFF82A54D4C72B2E13 /* Sources */, - 2D54EF7E2A5C186A38E5CAE6 /* Frameworks */, - CC828E0F89621195C2974389 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - fileSystemSynchronizedGroups = ( - 91A73B860506856B9B2FE3D5 /* iosApp */, - ); - name = iosApp; - packageProductDependencies = ( - ); - productName = iosApp; - productReference = 3238C18ABCE3C58991C465EC /* .app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 2EBE04F8BB17FEFB04FB1D68 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1620; - LastUpgradeCheck = 1620; - TargetAttributes = { - 63ACFC810DF62A4798655B3D = { - CreatedOnToolsVersion = 16.2; - }; - }; - }; - buildConfigurationList = 62CE13E879878557617EB04E /* Build configuration list for PBXProject "iosApp" */; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = C4AA065C02E3A768CC43E6DC; - minimizedProjectReferenceProxies = 1; - preferredProjectObjectVersion = 77; - productRefGroup = AF6178E04E76F2F1039A2D2C /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 63ACFC810DF62A4798655B3D /* iosApp */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - CC828E0F89621195C2974389 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - C6E8EBDEBEEF4B26D40F8C59 /* Compile Kotlin Framework */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Compile Kotlin Framework"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/../..\"\n./gradlew :composeApp:embedAndSignAppleFrameworkForXcode\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 35E444CFF82A54D4C72B2E13 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 27970FFA8BC598656A8EC506 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 5F5D490E965D25607D5D7524 /* Configuration */; - baseConfigurationReferenceRelativePath = Config.xcconfig; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 18.2; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 95F2278FE5A5B7D3E7D6D49D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = arm64; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = iosApp/Info.plist; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - ACB12A8231CC96ACBBC11D75 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 5F5D490E965D25607D5D7524 /* Configuration */; - baseConfigurationReferenceRelativePath = Config.xcconfig; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 18.2; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - F646A40651FA59163B5FE756 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = arm64; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = iosApp/Info.plist; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 62CE13E879878557617EB04E /* Build configuration list for PBXProject "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 27970FFA8BC598656A8EC506 /* Debug */, - ACB12A8231CC96ACBBC11D75 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - AF9E04F3E0A3E4C21CEC33B5 /* Build configuration list for PBXNativeTarget "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F646A40651FA59163B5FE756 /* Debug */, - 95F2278FE5A5B7D3E7D6D49D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 2EBE04F8BB17FEFB04FB1D68 /* Project object */; -} diff --git a/apps/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/apps/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a62..000000000 --- a/apps/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/clients/agent-runtime/src/config/schema.rs b/clients/agent-runtime/src/config/schema.rs index c3047dfa3..4a5b6d9ba 100755 --- a/clients/agent-runtime/src/config/schema.rs +++ b/clients/agent-runtime/src/config/schema.rs @@ -1082,11 +1082,27 @@ impl Config { } if let Err(e) = fs::rename(&temp_path, &self.config_path) { - let _ = fs::remove_file(&temp_path); - if had_existing_config && backup_path.exists() { - let _ = fs::copy(&backup_path, &self.config_path); + if should_fallback_to_in_place_write(&e) { + if let Err(write_err) = + write_config_in_place(&self.config_path, toml_str.as_bytes()) + { + let _ = fs::remove_file(&temp_path); + if had_existing_config && backup_path.exists() { + let _ = fs::copy(&backup_path, &self.config_path); + } + anyhow::bail!( + "Failed to replace config file after atomic fallback: {write_err} \ + (rename error: {e})" + ); + } + let _ = fs::remove_file(&temp_path); + } else { + let _ = fs::remove_file(&temp_path); + if had_existing_config && backup_path.exists() { + let _ = fs::copy(&backup_path, &self.config_path); + } + anyhow::bail!("Failed to atomically replace config file: {e}"); } - anyhow::bail!("Failed to atomically replace config file: {e}"); } sync_directory(parent_dir)?; @@ -1113,6 +1129,36 @@ fn sync_directory(_path: &Path) -> Result<()> { Ok(()) } +fn write_config_in_place(path: &Path, contents: &[u8]) -> Result<()> { + let mut file = OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(path) + .with_context(|| { + format!( + "Failed to open config file for in-place write: {}", + path.display() + ) + })?; + file.write_all(contents) + .context("Failed to write config contents in-place")?; + file.sync_all() + .context("Failed to fsync config file after in-place write")?; + Ok(()) +} + +#[cfg(unix)] +fn should_fallback_to_in_place_write(error: &std::io::Error) -> bool { + // Bind-mounted files can reject replace-style renames with EBUSY/EXDEV. + matches!(error.raw_os_error(), Some(16 | 18)) +} + +#[cfg(not(unix))] +fn should_fallback_to_in_place_write(_error: &std::io::Error) -> bool { + false +} + #[cfg(test)] mod tests { use super::*; @@ -1365,6 +1411,18 @@ default_temperature = 0.7 let _ = fs::remove_dir_all(&dir); } + #[cfg(unix)] + #[test] + fn atomic_replace_fallback_matches_expected_errno() { + let busy = std::io::Error::from_raw_os_error(16); + let cross_device = std::io::Error::from_raw_os_error(18); + let permission = std::io::Error::from_raw_os_error(13); + + assert!(should_fallback_to_in_place_write(&busy)); + assert!(should_fallback_to_in_place_write(&cross_device)); + assert!(!should_fallback_to_in_place_write(&permission)); + } + // ── Telegram / Discord config ──────────────────────────── #[test] diff --git a/clients/agent-runtime/src/onboard/wizard.rs b/clients/agent-runtime/src/onboard/wizard.rs index 36ca9a929..ae7bc593d 100755 --- a/clients/agent-runtime/src/onboard/wizard.rs +++ b/clients/agent-runtime/src/onboard/wizard.rs @@ -26,12 +26,12 @@ pub struct ProjectContext { const BANNER: &str = r" ⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡ - ███████╗███████╗██████╗ ██████╗ ██████╗██╗ █████╗ ██╗ ██╗ - ╚══███╔╝██╔════╝██╔══██╗██╔═══██╗██╔════╝██║ ██╔══██╗██║ ██║ - ███╔╝ █████╗ ██████╔╝██║ ██║██║ ██║ ███████║██║ █╗ ██║ - ███╔╝ ██╔══╝ ██╔══██╗██║ ██║██║ ██║ ██╔══██║██║███╗██║ - ███████╗███████╗██║ ██║╚██████╔╝╚██████╗███████╗██║ ██║╚███╔███╔╝ - ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝╚══════╝╚═╝ ╚═╝ ╚══╝╚══╝ + ██████╗ ██████╗ ██████╗ ██╗ ██╗██╗ ██╗███████╗ + ██╔════╝██╔═══██╗██╔══██╗██║ ██║██║ ██║██╔════╝ + ██║ ██║ ██║██████╔╝██║ ██║██║ ██║███████╗ + ██║ ██║ ██║██╔══██╗╚██╗ ██╔╝██║ ██║╚════██║ + ╚██████╗╚██████╔╝██║ ██║ ╚████╔╝ ╚██████╔╝███████║ + ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═══╝ ╚═════╝ ╚══════╝ Zero overhead. Zero compromise. 100% Rust. 100% Agnostic. diff --git a/clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt b/clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt index 471cda4f2..6be6f72e1 100644 --- a/clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt +++ b/clients/composeApp/src/commonMain/kotlin/com/profiletailors/corvus/ui/chat/ChatWorkspace.kt @@ -64,11 +64,7 @@ object ChatWorkspaceDefaults { ) } -private data class ChatMessage( - val id: Int, - val role: ChatRole, - val content: String, -) +private data class ChatMessage(val id: Int, val role: ChatRole, val content: String) private enum class ChatRole { User, @@ -91,11 +87,7 @@ fun ChatWorkspace( val messages = remember(state.welcomeMessage) { mutableStateListOf( - ChatMessage( - id = 0, - role = ChatRole.Assistant, - content = state.welcomeMessage, - ) + ChatMessage(id = 0, role = ChatRole.Assistant, content = state.welcomeMessage) ) } @@ -113,13 +105,7 @@ fun ChatWorkspace( webhookSecret = webhookSecret, ) - messages.add( - ChatMessage( - id = nextId, - role = ChatRole.User, - content = prompt, - ) - ) + messages.add(ChatMessage(id = nextId, role = ChatRole.User, content = prompt)) nextId += 1 messages.add( @@ -238,9 +224,7 @@ private fun ChatHeader(modelName: String, showConfig: Boolean, onToggleConfig: ( ) } - TextButton(onClick = onToggleConfig) { - Text(if (showConfig) "Volver al chat" else "Config") - } + TextButton(onClick = onToggleConfig) { Text(if (showConfig) "Volver al chat" else "Config") } } } @@ -267,20 +251,14 @@ private fun ChatPanel( verticalArrangement = Arrangement.spacedBy(10.dp), ) { items(items = messages, key = { it.id }) { message -> - ChatBubble( - message = message, - modelName = modelName, - ) + ChatBubble(message = message, modelName = modelName) } } } Spacer(modifier = Modifier.height(12.dp)) - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.Bottom, - ) { + Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.Bottom) { TextField( value = query, onValueChange = onQueryChange, @@ -293,11 +271,7 @@ private fun ChatPanel( Spacer(modifier = Modifier.width(8.dp)) - Button( - onClick = onSend, - enabled = query.isNotBlank(), - modifier = Modifier.height(56.dp), - ) { + Button(onClick = onSend, enabled = query.isNotBlank(), modifier = Modifier.height(56.dp)) { Text("Send") } } diff --git a/clients/web/.gitignore b/clients/web/.gitignore index 002453eb6..8158093c8 100644 --- a/clients/web/.gitignore +++ b/clients/web/.gitignore @@ -37,3 +37,7 @@ coverage/ .cache/ .eslintcache .stylelintcache + +# Astro +**/.astro/ +.astro/ diff --git a/clients/web/build.gradle.kts b/clients/web/build.gradle.kts index 37caa259c..0e82097d9 100644 --- a/clients/web/build.gradle.kts +++ b/clients/web/build.gradle.kts @@ -1,9 +1,39 @@ @file:Suppress("UnstableApiUsage") +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths + plugins { id("com.profiletailors.check.format-base") } +// Verificar y crear symlink de docs si no existe +val rootProjectDir = isolated.rootProject.projectDirectory.asFile.toPath() +val docsSymlink = rootProjectDir.resolve("docs") +val docsTarget = rootProjectDir.resolve("clients/web/apps/docs/src/content/docs") + +if (!Files.exists(docsSymlink)) { + if (Files.exists(docsTarget)) { + try { + Files.createSymbolicLink(docsSymlink, docsTarget) + logger.lifecycle("🔗 Symlink creado: docs → clients/web/apps/docs/src/content/docs") + } catch (e: Exception) { + logger.warn("⚠️ No se pudo crear symlink de docs: ${e.message}") + // Fallback: crear directorio vacío o copiar contenido + logger.lifecycle("📁 Creando directorio docs como fallback...") + docsSymlink.toFile().mkdirs() + } + } else { + logger.warn("⚠️ Target no existe: $docsTarget") + } +} else if (Files.isSymbolicLink(docsSymlink)) { + val target = Files.readSymbolicLink(docsSymlink) + logger.lifecycle("✅ Symlink docs ya existe → $target") +} else { + logger.lifecycle("📁 Directorio docs ya existe (no es symlink)") +} + val pnpmShim = isolated.rootProject.projectDirectory.file("gradle/bin/pnpm").asFile.absolutePath val webRootDir = isolated.projectDirectory.asFile val appsDir = file("${webRootDir}/apps")