feat(acidaos): adiciona plugin acidaos (agents, skills, knowledge e metadados do projeto)

This commit is contained in:
2026-10-28 16:08:17 +00:00
parent 02e19e5497
commit 5600fe7ac8
13 changed files with 906 additions and 0 deletions
+17
View File
@@ -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)
+5
View File
@@ -0,0 +1,5 @@
# CHANGELOG — skills
## 0.1.0 — 2026-06-30
### Adicionado
- Estrutura padrão (PROC-DEV-STANDARD)
+4
View File
@@ -0,0 +1,4 @@
# MEMORY.md — skills
## 2026-06-30
- Estrutura padrão aplicada via propagate-structure.sh
+3
View File
@@ -0,0 +1,3 @@
# skills
Subprojecto skills do ecossistema Descomplicar.
+8
View File
@@ -0,0 +1,8 @@
# STATUS.md — skills
**Versão:** 0.1 | **Data:** 2026-06-30 | **Agente:** —
## Estado actual
- Em curso: —
- Bloqueios: —
- Próximos passos: —
+6
View File
@@ -0,0 +1,6 @@
{
"task_id": null,
"project_id": null,
"customer_id": null,
"gitea_repo": null
}
+206
View File
@@ -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 <repo> # 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
+204
View File
@@ -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
* <AgentStatusCard
* agentId="agent-123"
* onRefresh={() => 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: "<acidaos-collection-id>"
})
```
---
### 4. Criar ADR (Architecture Decision Record)
**Template ADR:**
```markdown
# ADR-<NNN>: <Título da Decisão>
**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.*
+8
View File
@@ -0,0 +1,8 @@
# skills
## Documentação
- [README](README.md)
- [AGENTS](AGENTS.md)
- [STATUS](STATUS.md)
- [MEMORY](MEMORY.md)
+1
View File
@@ -0,0 +1 @@
## 2026-06-30 init | Estrutura padrão
+208
View File
@@ -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/<nome>/`
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-<nome>"
version = "0.1.0"
edition = "2021"
description = "<descrição>"
[dependencies]
tracing = "0.1"
serde = { version = "1", features = ["derive"] }
thiserror = "1"
tokio = { version = "1", features = ["full"] }
```
**Template `src/lib.rs`:**
```rust
//! # acidaos-<nome>
//!
//! <Descrição do módulo>
//!
//! ## Exemplo
//! ```rust
//! use acidaos_<nome>::<TipoPrincipal>;
//! ```
mod error;
pub use error::Error;
pub type Result<T> = std::result::Result<T, Error>;
```
**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 <NomeRequest> {
// campos do request
}
#[derive(Debug, Serialize)]
pub struct <NomeResponse> {
// campos do response
}
// --- Handler ---
#[instrument(skip(state))]
pub async fn <nome_handler>(
State(state): State<AppState>,
Json(req): Json<<NomeRequest>>,
) -> Result<Json<<NomeResponse>>, StatusCode> {
tracing::info!("Processando <nome>");
// lógica do handler
Ok(Json(<NomeResponse> {
// preencher response
}))
}
// --- Router ---
pub fn <nome>_router() -> Router<AppState> {
Router::new()
.route("/<path>", post(<nome_handler>))
}
```
**Princípios obrigatórios:**
- `#[instrument]` em todos os handlers (observabilidade)
- Erros retornam `StatusCode` ou tipo de erro custom (nunca `.unwrap()`)
- Estado partilhado via `State<AppState>` (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<Mutex<>>` |
| 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<Request>) -> Response { ... }
```
---
## Quality Gate
Antes de fazer commit:
```bash
ca
+208
View File
@@ -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-<nome> \
--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<T>(
endpoint: string,
options?: RequestInit
): Promise<T> {
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<T>;
}
```
`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/<Nome>/<Nome>.tsx`:
```typescript
/**
* <Nome> — <Descrição curta>
*
* @author Descomplicar® Crescimento Digital
*/
import { type FC } from 'react';
import { cn } from '@/lib/utils';
interface <Nome>Props {
// props do componente
className?: string;
}
export const <Nome>: FC<<Nome>Props> = ({ className }) => {
return (
<div className={cn('', className)}>
{/* conteúdo */}
</div>
);
};
<Nome>.displayName = '<Nome>';
```
**Template — teste (Vitest + Testing Library):**
`src/components/features/<Nome>/<Nome>.test.tsx`:
```typescript
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { <Nome> } from './<Nome>';
describe('<Nome>', () => {
it('renderiza sem erros', () => {
render(<<Nome> />);
// asserção específica ao componente
});
it('aceita className personalizada', () => {
const { container } = render(<<Nome> className="test-class" />);
expect(container.firstChild).toHaveClass('test-class');
});
});
```
**Template — Storybook:**
`src/components/features/<Nome>/<Nome>.stories.tsx`:
```typescript
import type { Meta, StoryObj } from '@storybook/react';
import { <Nome> } from './<Nome>';
const meta: Meta<typeof <Nome>> = {
title: 'Features/<Nome>',
component: <Nome>,
parameters: {
layout: 'centered',
},
};
export default meta;
type Story = StoryObj<typeof <Nome>>;
export const Default: Story = {
args: {},
};
```
**Criar index de exportação:**
`src/components/features/<Nome>/index.ts`:
```typescript
export { <Nome> } from './<Nome>';
export type { <Nome>Props } from './<Nome>';
```
---
## 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<Nome>.ts`
- Server Components por defeito; `'use client'` apenas quando necessário
### Performance