From 5600fe7ac8ab961b4210070cdbcd86290cf6ebc9 Mon Sep 17 00:00:00 2001 From: Emanuel Almeida Date: Wed, 28 Oct 2026 16:08:17 +0000 Subject: [PATCH] feat(acidaos): adiciona plugin acidaos (agents, skills, knowledge e metadados do projeto) --- acidaos/README.md | 28 ++++ acidaos/skills/AGENTS.md | 17 +++ acidaos/skills/CHANGELOG.md | 5 + acidaos/skills/MEMORY.md | 4 + acidaos/skills/README.md | 3 + acidaos/skills/STATUS.md | 8 ++ acidaos/skills/desk.project | 6 + acidaos/skills/devops/SKILL.md | 206 +++++++++++++++++++++++++++++ acidaos/skills/docs/SKILL.md | 204 +++++++++++++++++++++++++++++ acidaos/skills/index.md | 8 ++ acidaos/skills/log.md | 1 + acidaos/skills/rust-dev/SKILL.md | 208 ++++++++++++++++++++++++++++++ acidaos/skills/spoke-dev/SKILL.md | 208 ++++++++++++++++++++++++++++++ 13 files changed, 906 insertions(+) create mode 100644 acidaos/README.md create mode 100644 acidaos/skills/AGENTS.md create mode 100644 acidaos/skills/CHANGELOG.md create mode 100644 acidaos/skills/MEMORY.md create mode 100644 acidaos/skills/README.md create mode 100644 acidaos/skills/STATUS.md create mode 100644 acidaos/skills/desk.project create mode 100644 acidaos/skills/devops/SKILL.md create mode 100644 acidaos/skills/docs/SKILL.md create mode 100644 acidaos/skills/index.md create mode 100644 acidaos/skills/log.md create mode 100644 acidaos/skills/rust-dev/SKILL.md create mode 100644 acidaos/skills/spoke-dev/SKILL.md diff --git a/acidaos/README.md b/acidaos/README.md new file mode 100644 index 0000000..54a5ca9 --- /dev/null +++ b/acidaos/README.md @@ -0,0 +1,28 @@ +# Plugin: acidaos + +Skills especializadas para desenvolvimento do **AcidaOS** — o sistema operativo de negócio para PMEs da Descomplicar®. + +## Arquitectura + +O AcidaOS usa uma arquitectura Hub-and-Spoke: +- **Core (Hub):** Rust + Axum — motor de orquestração de agentes, API gRPC/REST interna +- **Spokes:** Next.js/TypeScript — dashboards, UI, aplicações de negócio + +## Skills disponíveis + +| Skill | Trigger | Descrição | +|-------|---------|-----------| +| `acidaos:rust-dev` | `/rust-dev`, desenvolvimento Core | Desenvolvimento do Core em Rust (Axum, Tokio) | +| `acidaos:spoke-dev` | `/spoke-dev`, desenvolvimento Spokes | Aplicações Next.js e componentes React | +| `acidaos:devops` | `/acidaos-pipeline`, CI/CD | Pipelines Gitea Actions para o AcidaOS | +| `acidaos:docs` | `/acidaos-docs`, documentação técnica | Gerar documentação a partir do código | + +## Referências + +- Arquitectura: `Hub/01-Planeamento/AcidaOS/Relatorio_Arquitetura_Core.md` +- SPECs: `Hub/01-Planeamento/AcidaOS/acidaos-core/SPECs.md` +- Visão estratégica: `Hub/01-Planeamento/AcidaOS/AcidaOS_Visao-Estrategica.md` +- Repositório: Gitea `acidaos-core`, `acidaos-dashboard` + +--- +**Versão**: 1.0.0 | **Autor**: Descomplicar® | **Data**: 2026-03-12 diff --git a/acidaos/skills/AGENTS.md b/acidaos/skills/AGENTS.md new file mode 100644 index 0000000..37d90a2 --- /dev/null +++ b/acidaos/skills/AGENTS.md @@ -0,0 +1,17 @@ +# AGENTS.md — skills + +Directrizes específicas deste projecto para agentes IA. + +## Referências obrigatórias + +- `ECOSYSTEM.md` — Hub/06-Operacoes/Documentacao/ECOSYSTEM.md +- `PROC-DEV-STANDARD` — D7-SIS-006 +- `PROC-AUDIT-STANDARD` — D7-SIS-007 + +## Protocolo de sessão + +Início: ler MEMORY.md + STATUS.md. Fim: actualizar ambos. + +## Convenções específicas + +- (a definir) diff --git a/acidaos/skills/CHANGELOG.md b/acidaos/skills/CHANGELOG.md new file mode 100644 index 0000000..5e14603 --- /dev/null +++ b/acidaos/skills/CHANGELOG.md @@ -0,0 +1,5 @@ +# CHANGELOG — skills + +## 0.1.0 — 2026-06-30 +### Adicionado +- Estrutura padrão (PROC-DEV-STANDARD) diff --git a/acidaos/skills/MEMORY.md b/acidaos/skills/MEMORY.md new file mode 100644 index 0000000..4971060 --- /dev/null +++ b/acidaos/skills/MEMORY.md @@ -0,0 +1,4 @@ +# MEMORY.md — skills + +## 2026-06-30 +- Estrutura padrão aplicada via propagate-structure.sh diff --git a/acidaos/skills/README.md b/acidaos/skills/README.md new file mode 100644 index 0000000..2ad232f --- /dev/null +++ b/acidaos/skills/README.md @@ -0,0 +1,3 @@ +# skills + +Subprojecto skills do ecossistema Descomplicar. diff --git a/acidaos/skills/STATUS.md b/acidaos/skills/STATUS.md new file mode 100644 index 0000000..07c1590 --- /dev/null +++ b/acidaos/skills/STATUS.md @@ -0,0 +1,8 @@ +# STATUS.md — skills + +**Versão:** 0.1 | **Data:** 2026-06-30 | **Agente:** — + +## Estado actual +- Em curso: — +- Bloqueios: — +- Próximos passos: — diff --git a/acidaos/skills/desk.project b/acidaos/skills/desk.project new file mode 100644 index 0000000..5678920 --- /dev/null +++ b/acidaos/skills/desk.project @@ -0,0 +1,6 @@ +{ + "task_id": null, + "project_id": null, + "customer_id": null, + "gitea_repo": null +} diff --git a/acidaos/skills/devops/SKILL.md b/acidaos/skills/devops/SKILL.md new file mode 100644 index 0000000..762a887 --- /dev/null +++ b/acidaos/skills/devops/SKILL.md @@ -0,0 +1,206 @@ +--- +name: devops +description: CI/CD pipelines para o AcidaOS via Gitea Actions — build, test, deploy para acidaos-core (Rust) e acidaos-dashboard (Next.js). Usar quando "pipeline acidaos", "gitea actions acidaos", "ci cd acidaos", "deploy acidaos", "workflow acidaos". +allowed-tools: Read, Write, Edit, Bash, mcp__gitea__list_repo_action_workflows, mcp__gitea__get_repo_action_workflow, mcp__gitea__create_file, mcp__gitea__update_file, mcp__mem_search_memories +layer: wiki +--- + +# AcidaOS DevOps — Gitea Actions + +Skill para criar e gerir pipelines CI/CD do AcidaOS via **Gitea Actions**. + +> **Atenção:** O AcidaOS usa **Gitea Actions**, não GitHub Actions. A sintaxe é compatível mas o runner é self-hosted em `gateway.descomplicar.pt`. + +## Contexto + +``` +Repositórios Gitea: + acidaos-core → Rust Core + acidaos-dashboard → Next.js Dashboard + +Runners: + self-hosted @ gateway.descomplicar.pt + Labels: [self-hosted, linux, rust, node] + +Deploy target: + EasyPanel (projectName: "descomplicar") + acidaos-core → serviceName: "acidaos-core" + acidaos-dashboard → serviceName: "acidaos-dashboard" +``` + +## Protocolo Inicial + +``` +mcp__mem_search_memories "acidaos devops pipeline" +mcp__gitea__list_repo_action_workflows # ver workflows existentes +``` + +--- + +## Pipelines Disponíveis + +### 1. Core Rust — CI Pipeline + +**Ficheiro:** `.gitea/workflows/ci.yml` + +```yaml +name: AcidaOS Core CI + +on: + push: + branches: [main, develop] + pull_request: + branches: [main] + +jobs: + check: + name: Verificar código + runs-on: [self-hosted, linux, rust] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Cache Cargo + uses: actions/cache@v3 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Cargo check + run: cargo check --all-features + + - name: Clippy + run: cargo clippy --all-features -- -D warnings + + - name: Formatação + run: cargo fmt --all -- --check + + test: + name: Testes + needs: check + runs-on: [self-hosted, linux, rust] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Cache Cargo + uses: actions/cache@v3 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Testes unitários + run: cargo test --all-features + + - name: Testes de integração + run: cargo test --test '*' --all-features + env: + ACIDAOS_ENV: test + DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }} + + security: + name: Auditoria de segurança + runs-on: [self-hosted, linux, rust] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: cargo-audit + run: | + cargo install cargo-audit --quiet + cargo audit +``` + +--- + +### 2. Core Rust — Deploy Pipeline + +**Ficheiro:** `.gitea/workflows/deploy.yml` + +```yaml +name: AcidaOS Core Deploy + +on: + push: + branches: [main] + tags: ['v*'] + +jobs: + deploy: + name: Deploy para EasyPanel + runs-on: [self-hosted, linux, rust] + environment: production + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Build release + run: cargo build --release + + - name: Build Docker image + run: | + docker build \ + -t acidaos-core:${{ gitea.sha }} \ + -t acidaos-core:latest \ + . + + - name: Push para registry + run: | + docker tag acidaos-core:latest \ + registry.descomplicar.pt/acidaos/core:latest + docker push registry.descomplicar.pt/acidaos/core:latest + env: + DOCKER_REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + + - name: Deploy via EasyPanel API + run: | + curl -X POST \ + "https://easypanel.descomplicar.pt/api/deploy" \ + -H "Authorization: Bearer ${{ secrets.EASYPANEL_TOKEN }}" \ + -H "Content-Type: application/json" \ + -d '{ + "projectName": "descomplicar", + "serviceName": "acidaos-core", + "image": "registry.descomplicar.pt/acidaos/core:latest" + }' + + - name: Verificar health + run: | + sleep 10 + curl -f http://acidaos-core.descomplicar.pt/health || exit 1 +``` + +--- + +### 3. Dashboard Next.js — CI Pipeline + +**Ficheiro:** `.gitea/workflows/ci.yml` (no repo acidaos-dashboard) + +```yaml +name: AcidaOS Dashboard CI + +on: + push: + branches: [main, develop] + pull_request: + branches: [main] + +jobs: + lint-typecheck: + name: Lint e TypeCheck + runs-on: [self-hosted, linux, node] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'pnpm \ No newline at end of file diff --git a/acidaos/skills/docs/SKILL.md b/acidaos/skills/docs/SKILL.md new file mode 100644 index 0000000..ff531b4 --- /dev/null +++ b/acidaos/skills/docs/SKILL.md @@ -0,0 +1,204 @@ +--- +name: docs +description: Gerar documentação técnica do AcidaOS a partir do código — Rust (rustdoc), TypeScript (TypeDoc), e publicar no Outline. Usar quando "documentação acidaos", "gerar docs", "rustdoc", "typedoc", "acidaos-docs", documentar código do projecto. +allowed-tools: Read, Write, Bash, mcp__gitea__get_file_content, mcp__gitea__get_dir_content, mcp__outline-api__create_document, mcp__outline-api__update_document, mcp__outline-api__search_documents, mcp__mem_search_memories +layer: wiki +--- + +# AcidaOS Docs + +Skill para gerar e publicar documentação técnica do AcidaOS. + +## Estratégia de Documentação + +| Camada | Ferramenta | Destino | +|--------|-----------|---------| +| API interna Rust | `rustdoc` + comentários `///` | `/docs` no repo | +| Componentes React | TypeDoc + Storybook | Storybook deployed | +| Arquitectura | Mermaid.js diagramas | Outline (Wiki) | +| Endpoints API | OpenAPI/Swagger | Outline (Wiki) | +| Decisões técnicas | ADRs em Markdown | Outline (Wiki) | + +## Protocolo + +``` +mcp__mem_search_memories "acidaos documentação" +mcp__outline-api__search_documents "acidaos" # ver docs existentes +``` + +--- + +## Operações + +### 1. Gerar documentação Rust (`rustdoc`) + +**Verificar comentários existentes:** +``` +mcp__gitea__get_dir_content acidaos-core/src/ +``` + +**Gerar localmente (no container dev):** +```bash +cd /root/Dev/acidaos-core +cargo doc --all-features --no-deps --open +``` + +**Verificar cobertura de documentação:** +```bash +cargo doc --all-features 2>&1 | grep "warning: missing documentation" +``` + +**Template comentários Rust:** +```rust +/// # ComponenteX +/// +/// Breve descrição em uma linha. +/// +/// ## Descrição detalhada +/// +/// Explicação mais longa do comportamento e propósito. +/// +/// ## Exemplos +/// +/// ```rust +/// use acidaos_core::ComponenteX; +/// +/// let c = ComponenteX::new("id"); +/// assert!(c.is_valid()); +/// ``` +/// +/// ## Erros +/// +/// Retorna [`Error::Init`] se a inicialização falhar. +pub struct ComponenteX { ... } +``` + +--- + +### 2. Gerar documentação TypeScript (TypeDoc) + +**Verificar configuração:** +``` +mcp__gitea__get_file_content acidaos-dashboard/typedoc.json +``` + +**Gerar (no container dev):** +```bash +cd /root/Dev/acidaos-dashboard +pnpm typedoc --out docs/api src/ +``` + +**Template JSDoc para componentes:** +```typescript +/** + * AgentStatusCard — Mostra o estado de um agente AcidaOS + * + * @example + * ```tsx + * refetch()} + * /> + * ``` + */ +export interface AgentStatusCardProps { + /** ID único do agente no Core */ + agentId: string; + /** Callback chamado ao clicar em refrescar */ + onRefresh?: () => void; +} +``` + +--- + +### 3. Publicar arquitectura no Outline + +**Criar/actualizar diagrama de arquitectura:** + +```javascript +mcp__outline-api__create_document({ + title: "AcidaOS — Arquitectura Core", + text: ` +# Arquitectura AcidaOS Core + +## Hub-and-Spoke + +\`\`\`mermaid +graph TD + A[acidaos-dashboard] -->|API REST| B[AcidaOS Core] + B --> C[Agent Kernel] + B --> D[Security & Sandboxing] + B --> E[Memory Engine] + B --> F[Observability] +\`\`\` + +## Componentes + +| Componente | Linguagem | Responsabilidade | +|-----------|-----------|-----------------| +| Core | Rust | Orquestração de agentes | +| Dashboard | Next.js | Interface de utilizador | + `, + collectionId: "" +}) +``` + +--- + +### 4. Criar ADR (Architecture Decision Record) + +**Template ADR:** +```markdown +# ADR-: + +**Data:** YYYY-MM-DD +**Estado:** [Proposto | Aceite | Depreciado | Substituído por ADR-NNN] + +## Contexto + +[Situação que levou à necessidade de tomar esta decisão] + +## Opções Consideradas + +1. **Opção A** — descrição breve +2. **Opção B** — descrição breve + +## Decisão + +[Opção escolhida e porquê] + +## Consequências + +**Positivas:** +- [Consequência positiva] + +**Negativas / Trade-offs:** +- [Limitação ou custo] +``` + +--- + +## Quality Gate de Documentação + +Antes de marcar tarefa como concluída: + +- [ ] Rust: zero `missing documentation` warnings em `cargo doc` +- [ ] TypeScript: TypeDoc gera sem erros +- [ ] Novos módulos têm exemplos de uso nos comentários +- [ ] Diagramas Mermaid actualizado se arquitectura mudou +- [ ] ADR criado para decisões técnicas significativas + +--- +**Versão**: 1.0.0 | **Autor**: Descomplicar® | **Plugin**: acidaos + +--- + +## Healing Log + +Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar. + +```jsonl +{"date":"","issue":"","fix":"","source":"user|auto"} +``` + +*Adicionar nova linha após cada erro corrigido.* diff --git a/acidaos/skills/index.md b/acidaos/skills/index.md new file mode 100644 index 0000000..1d7c6b4 --- /dev/null +++ b/acidaos/skills/index.md @@ -0,0 +1,8 @@ +# skills + +## Documentação + +- [README](README.md) +- [AGENTS](AGENTS.md) +- [STATUS](STATUS.md) +- [MEMORY](MEMORY.md) diff --git a/acidaos/skills/log.md b/acidaos/skills/log.md new file mode 100644 index 0000000..66e9c4d --- /dev/null +++ b/acidaos/skills/log.md @@ -0,0 +1 @@ +## 2026-06-30 init | Estrutura padrão diff --git a/acidaos/skills/rust-dev/SKILL.md b/acidaos/skills/rust-dev/SKILL.md new file mode 100644 index 0000000..fbb1b5e --- /dev/null +++ b/acidaos/skills/rust-dev/SKILL.md @@ -0,0 +1,208 @@ +--- +name: rust-dev +description: Desenvolvimento do AcidaOS Core em Rust — criar crates, definir endpoints Axum, debugar erros do compilador. Usar quando "rust", "axum", "cargo", "crate", "core", "acidaos core", "rust error", "borrow checker", desenvolvimento do motor central do AcidaOS. +allowed-tools: Read, Write, Edit, Bash, mcp__mem_search_memories, mcp__gitea__get_file_content, mcp__gitea__create_file, mcp__gitea__update_file +layer: wiki +--- + +# AcidaOS Rust Dev + +Skill para desenvolvimento do **Core do AcidaOS** em Rust. + +## Contexto do Projecto + +``` +acidaos-core (Rust) +├── src/ +│ ├── api/ ← endpoints Axum (REST/gRPC) +│ ├── kernel/ ← Agent Kernel & Scheduler +│ ├── security/ ← Sandboxing, isolamento WASM +│ ├── memory/ ← Context & Memory Engine +│ ├── registry/ ← Parsers de skills/plugins +│ ├── observability/← Logging, tracing +│ └── ethics/ ← Constitution Engine +├── crates/ ← bibliotecas internas +└── Cargo.toml +``` + +**Stack:** Rust stable | Axum | Tokio | Serde | Tracing | SQLx | wasmtime + +## Protocolo Inicial + +``` +mcp__mem_search_memories "acidaos core [componente]" +mcp__gitea__get_file_content acidaos-core/Cargo.toml # verificar dependências actuais +``` + +--- + +## Operações + +### 1. Criar novo crate (`/rust-create-crate`) + +**Input:** Nome do crate e propósito + +**Passos:** +1. Criar directório `crates//` +2. Gerar `Cargo.toml` com dependências mínimas +3. Criar `src/lib.rs` com estrutura base +4. Adicionar ao workspace `Cargo.toml` +5. Criar `src/error.rs` com tipo de erro custom usando `thiserror` + +**Template `Cargo.toml`:** +```toml +[package] +name = "acidaos-" +version = "0.1.0" +edition = "2021" +description = "" + +[dependencies] +tracing = "0.1" +serde = { version = "1", features = ["derive"] } +thiserror = "1" +tokio = { version = "1", features = ["full"] } +``` + +**Template `src/lib.rs`:** +```rust +//! # acidaos- +//! +//! +//! +//! ## Exemplo +//! ```rust +//! use acidaos_::; +//! ``` + +mod error; +pub use error::Error; + +pub type Result = std::result::Result; +``` + +**Template `src/error.rs`:** +```rust +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum Error { + #[error("Erro de inicialização: {0}")] + Init(String), + + #[error("Operação não suportada: {0}")] + Unsupported(String), +} +``` + +--- + +### 2. Definir endpoint Axum (`/rust-define-api-endpoint`) + +**Input:** Definição do endpoint (método, path, request/response types) de uma SPEC.md + +**Template de endpoint:** +```rust +use axum::{ + extract::{Path, State}, + http::StatusCode, + response::Json, + routing::{get, post}, + Router, +}; +use serde::{Deserialize, Serialize}; +use tracing::instrument; + +// --- Tipos --- + +#[derive(Debug, Deserialize)] +pub struct { + // campos do request +} + +#[derive(Debug, Serialize)] +pub struct { + // campos do response +} + +// --- Handler --- + +#[instrument(skip(state))] +pub async fn ( + State(state): State, + Json(req): Json<>, +) -> Result>, StatusCode> { + tracing::info!("Processando "); + + // lógica do handler + + Ok(Json( { + // preencher response + })) +} + +// --- Router --- + +pub fn _router() -> Router { + Router::new() + .route("/", post()) +} +``` + +**Princípios obrigatórios:** +- `#[instrument]` em todos os handlers (observabilidade) +- Erros retornam `StatusCode` ou tipo de erro custom (nunca `.unwrap()`) +- Estado partilhado via `State` (não globals) +- Validação de input antes de processamento + +--- + +### 3. Debugar erro do compilador (`/rust-debug-compiler-error`) + +**Input:** Output completo de `cargo build` ou `cargo check` + +**Protocolo de análise:** + +1. **Identificar categoria do erro:** + | Código | Categoria | Solução típica | + |--------|-----------|----------------| + | E0382 | Move após uso | Usar `clone()` ou referências `&` | + | E0502 | Borrow conflict | Reordenar operações, usar `Arc>` | + | E0308 | Type mismatch | Verificar tipos, usar `.into()` ou cast explícito | + | E0277 | Trait not impl | Implementar trait ou usar tipo diferente | + | E0499 | Multiple mut borrows | Usar `RefCell` ou reestruturar lógica | + +2. **Analisar mensagem de erro completa** (incluindo `help:` e `note:`) + +3. **Gerar código corrigido** com explicação da causa raiz + +4. **Verificar:** `cargo check` passa antes de `cargo build` + +**Padrões comuns no AcidaOS Core:** + +```rust +// ❌ Move não intencional +let data = fetch_data(); +process(data); +log(data); // ERRO: data foi moved + +// ✅ Correcto +let data = fetch_data(); +process(&data); // ou process(data.clone()) +log(&data); + +// ❌ Async + lifetime +async fn handler(req: &Request) -> Response { ... } // lifetime issue + +// ✅ Correcto — owned ou Arc +async fn handler(req: Arc) -> Response { ... } +``` + +--- + +## Quality Gate + +Antes de fazer commit: + +```bash +ca \ No newline at end of file diff --git a/acidaos/skills/spoke-dev/SKILL.md b/acidaos/skills/spoke-dev/SKILL.md new file mode 100644 index 0000000..8ef90fc --- /dev/null +++ b/acidaos/skills/spoke-dev/SKILL.md @@ -0,0 +1,208 @@ +--- +name: spoke-dev +description: Desenvolvimento de Spokes do AcidaOS em Next.js/TypeScript — criar aplicações Spoke, componentes React com testes e Storybook. Usar quando "spoke", "dashboard acidaos", "next.js acidaos", "componente react acidaos", "ts-create-spoke", "acidaos ui", "acidaos frontend". +allowed-tools: Read, Write, Edit, Bash, mcp__mem_search_memories, mcp__gitea__get_file_content, mcp__gitea__create_file, mcp__gitea__update_file +layer: wiki +--- + +# AcidaOS Spoke Dev + +Skill para desenvolvimento dos **Spokes do AcidaOS** em Next.js/TypeScript. + +## Contexto do Projecto + +Os Spokes são as aplicações de interface que comunicam com o Core via API interna: + +``` +acidaos-dashboard (Next.js 15 + App Router) +├── src/ +│ ├── app/ ← App Router pages +│ ├── components/ ← Componentes React +│ │ ├── ui/ ← Componentes base (shadcn/ui) +│ │ └── features/ ← Componentes de funcionalidade +│ ├── lib/ +│ │ ├── api/ ← Client para AcidaOS Core API +│ │ └── hooks/ ← React hooks custom +│ └── types/ ← TypeScript types partilhados +├── __tests__/ ← Jest + Testing Library +└── .storybook/ ← Storybook +``` + +**Stack:** Next.js 15 | TypeScript 5 | React 19 | Tailwind CSS | shadcn/ui | Vercel AI SDK | Vitest | Playwright + +## Protocolo Inicial + +``` +mcp__mem_search_memories "acidaos spoke dashboard [componente]" +mcp__gitea__get_file_content acidaos-dashboard/package.json +``` + +--- + +## Operações + +### 1. Criar nova aplicação Spoke (`/ts-create-spoke-app`) + +**Input:** Nome do Spoke e propósito + +**Estrutura a criar:** +```bash +# No container dev (Regra #48) +cd /root/Dev +npx create-next-app@latest acidaos- \ + --typescript \ + --tailwind \ + --app \ + --src-dir \ + --import-alias "@/*" \ + --no-git +``` + +**Ficheiros obrigatórios após scaffold:** + +`src/lib/api/core-client.ts` — cliente para o Core: +```typescript +/** + * AcidaOS Core API Client + * + * @author Descomplicar® Crescimento Digital + * @link https://descomplicar.pt + */ + +const CORE_API_URL = process.env.ACIDAOS_CORE_URL ?? 'http://localhost:3001'; + +export async function coreRequest( + endpoint: string, + options?: RequestInit +): Promise { + const res = await fetch(`${CORE_API_URL}${endpoint}`, { + ...options, + headers: { + 'Content-Type': 'application/json', + 'X-AcidaOS-Version': '1', + ...options?.headers, + }, + }); + + if (!res.ok) { + throw new Error(`Core API error: ${res.status} ${res.statusText}`); + } + + return res.json() as Promise; +} +``` + +`src/types/index.ts` — tipos base: +```typescript +export interface AgentTask { + id: string; + status: 'pending' | 'running' | 'completed' | 'failed'; + createdAt: string; + completedAt?: string; +} + +export interface CoreHealth { + status: 'healthy' | 'degraded' | 'down'; + version: string; + uptime: number; +} +``` + +--- + +### 2. Criar componente React (`/ts-create-react-component`) + +**Input:** Descrição do componente (nome, props, comportamento) + +**Template base — componente:** + +`src/components/features//.tsx`: +```typescript +/** + * — + * + * @author Descomplicar® Crescimento Digital + */ + +import { type FC } from 'react'; +import { cn } from '@/lib/utils'; + +interface Props { + // props do componente + className?: string; +} + +export const : FC<Props> = ({ className }) => { + return ( +
+ {/* conteúdo */} +
+ ); +}; + +.displayName = ''; +``` + +**Template — teste (Vitest + Testing Library):** + +`src/components/features//.test.tsx`: +```typescript +import { render, screen } from '@testing-library/react'; +import { describe, it, expect } from 'vitest'; +import { } from './'; + +describe('', () => { + it('renderiza sem erros', () => { + render(< />); + // asserção específica ao componente + }); + + it('aceita className personalizada', () => { + const { container } = render(< className="test-class" />); + expect(container.firstChild).toHaveClass('test-class'); + }); +}); +``` + +**Template — Storybook:** + +`src/components/features//.stories.tsx`: +```typescript +import type { Meta, StoryObj } from '@storybook/react'; +import { } from './'; + +const meta: Meta> = { + title: 'Features/', + component: , + parameters: { + layout: 'centered', + }, +}; + +export default meta; +type Story = StoryObj>; + +export const Default: Story = { + args: {}, +}; +``` + +**Criar index de exportação:** + +`src/components/features//index.ts`: +```typescript +export { } from './'; +export type { Props } from './'; +``` + +--- + +## Padrões Obrigatórios + +### TypeScript +- `strict: true` em `tsconfig.json` — sem `any` implícito +- Props sempre tipadas com interface exportada +- Hooks custom em `src/lib/hooks/use.ts` +- Server Components por defeito; `'use client'` apenas quando necessário + +### Performance \ No newline at end of file