✳ AI Skills
← arthurbonora

PUBLICAÇÃO DA COMUNIDADE

Publicar skill no AI Skills

Empacota e publica skills no AI Skills (aiskills.bonorasw.com.br), no espaço /arthurbonora: monta skill.json + SKILL.md + LICENSE, valida contra o schema, publica via API com token, confere o resultado e sabe versionar, retirar versão e forkar. Use quando pedirem para publicar, subir, atualizar, versionar ou retirar uma skill no AI Skills / aiskills.bonorasw.com.br / no meu espaço.

arthurbonora/publicar-skill-aiskills · MIT · v1.0.0

Instruções da skill

---
name: publicar-skill-aiskills
description: "Empacota e publica skills no AI Skills (aiskills.bonorasw.com.br), no espaço /arthurbonora: monta skill.json + SKILL.md + LICENSE, valida contra o schema, publica via API com token, confere o resultado e sabe versionar, retirar versão e forkar. Use quando pedirem para publicar, subir, atualizar, versionar ou retirar uma skill no AI Skills / aiskills.bonorasw.com.br / no meu espaço."
---

# Publicar skill no AI Skills

Publica skills no catálogo **AI Skills** (`https://aiskills.bonorasw.com.br`), no espaço padrão **`/arthurbonora`**.

Cada skill é um repositório em `/{usuario}/{skill}/` com histórico de versões. **Versão publicada é imutável** — não existe sobrescrever, só publicar versão nova ou retirar.

Escreva em português do Brasil, direto.

## Antes de qualquer coisa

```bash
BASE=https://aiskills.bonorasw.com.br
[ -n "$AISKILLS_TOKEN" ] && echo "token presente" || echo "TOKEN AUSENTE"
```

O token vem da variável de ambiente `AISKILLS_TOKEN`, criada em `/account/` (aparece uma única vez, vale 90 dias, publica **somente no espaço do dono**). Se não existir, pare e peça ao usuário para gerar o token e exportá-lo — **nunca** peça a senha, nunca coloque o token na URL, em arquivo do pacote, em log ou no relatório.

Confira também se o identificador já existe no espaço:

```bash
curl -sS $BASE/api/v1/users/arthurbonora/skills
curl -sS $BASE/api/v1/users/arthurbonora/skills/<skill>/index.json
```

Se existir, a publicação é **atualização**: mantenha o `id` e aumente a `version`.

## Estrutura obrigatória do pacote

```
<identificador>/
  skill.json
  SKILL.md
  LICENSE
  references/   # opcional
  scripts/      # opcional, distribuído como arquivo, nunca executado pelo servidor
  assets/       # opcional
```

Identificador: minúsculas ASCII, números e hífens, sem hífen duplo, até 64 caracteres (`^[a-z0-9]+(?:-[a-z0-9]+)*$`).

### `skill.json` — campos todos obrigatórios

```json
{
  "id": "minha-skill",
  "name": "Nome legível",
  "description": "O que faz e quando usar.",
  "version": "1.0.0",
  "author": "arthurbonora",
  "license": "MIT",
  "category": "desenvolvimento",
  "tags": ["exemplo"],
  "compatibility": ["agent-skills"],
  "dependencies": [],
  "permissions": [],
  "changelog": "Primeira publicação."
}
```

Regras do schema (`/schemas/skill.schema.json`), validar **antes** de enviar:

- `description`: 10 a 1024 caracteres — e deve deixar claro **quando** usar a skill
- `version`: semver estrito `X.Y.Z`
- `category`: mesmo padrão de slug do `id`; use uma das já existentes no catálogo — `infraestrutura`, `desenvolvimento`, `produtividade`, `dados`
- `tags`: 1 a 12, únicas, até 40 caracteres cada
- `compatibility`: `["agent-skills"]`
- `dependencies` e `permissions`: listas de frases (até 30 itens); declare os requisitos **reais** (acesso a terminal, rede, credenciais de terceiros)
- `changelog`: obrigatório, até 2000 caracteres
- Nenhum campo extra é aceito (`additionalProperties: false`)
- `author` é sobrescrito pelo usuário autenticado no servidor

### `SKILL.md`

Frontmatter YAML com `name` **idêntico ao `id`** e `description` **idêntica à do `skill.json`**. Divergir nesses dois campos é a causa mais comum de `400`.

### `LICENSE`

Texto integral da licença declarada. Publique só o que o usuário tem direito de distribuir.

### Nunca inclua

Credenciais, `.env`, arquivos privados, diretórios ocultos, virtualenvs, links simbólicos.

## Validação local antes de publicar

```bash
python3 - <<'PY'
import json,re,sys,pathlib
d=pathlib.Path("<identificador>")
m=json.loads((d/"skill.json").read_text())
req=["id","name","description","version","author","license","category",
     "tags","compatibility","dependencies","permissions","changelog"]
err=[f"faltando: {k}" for k in req if k not in m]
if not re.fullmatch(r"[a-z0-9]+(-[a-z0-9]+)*", m.get("id","")): err.append("id inválido")
if not re.fullmatch(r"(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)", m.get("version","")): err.append("version inválida")
if not 10 <= len(m.get("description","")) <= 1024: err.append("description fora de 10..1024")
txt=(d/"SKILL.md").read_text()
fm=txt.split("---")[1] if txt.startswith("---") else ""
if f"name: {m['id']}" not in fm: err.append("frontmatter name != id")
if m["description"] not in fm: err.append("frontmatter description != skill.json")
if not (d/"LICENSE").exists(): err.append("LICENSE ausente")
print("\n".join(err) or "OK")
PY
```

Confira também os limites: **2 MiB** de conteúdo por pacote, 100 arquivos, 100 versões por repositório, 50 repositórios e 100 MiB por usuário, 30 publicações por hora.

## Publicar

### ZIP (recomendado; obrigatório se houver binário)

O ZIP precisa conter a **pasta** `<identificador>/` na raiz.

```bash
zip -r <identificador>.zip <identificador> -x '*/.*' '*/__pycache__/*'

curl --fail-with-body -sS \
  -H "Authorization: Bearer $AISKILLS_TOKEN" \
  -F "package=@<identificador>.zip" \
  $BASE/api/v1/skills/publish
```

### JSON (só texto UTF-8)

```bash
curl --fail-with-body -sS \
  -H "Authorization: Bearer $AISKILLS_TOKEN" \
  -H "Content-Type: application/json" \
  --data @payload.json \
  $BASE/api/v1/skills/publish
```

`payload.json`: `{ "metadata": {...}, "skill_md": "...", "license_text": "...", "files": {"references/x.md": "..."} }`

Para publicar numa versão de repositório específico (exige ser dono):
`POST /api/v1/users/arthurbonora/skills/<skill>/versions`

## Depois de publicar

`201` devolve `owner`, `namespace`, `page_url`, `manifest_url`, `download_url`, `skill_url` e checksum (links relativos à raiz do site). Confirme e só então reporte sucesso:

```bash
curl -sS $BASE/api/v1/users/arthurbonora/skills/<skill>/index.json
curl -sSI $BASE/api/v1/users/arthurbonora/skills/<skill>/versions/<versao>/download.zip
```

Entregue ao usuário: a URL da página `/arthurbonora/<skill>/`, a versão publicada e o checksum.

## Erros

| Código | Significado | O que fazer |
| --- | --- | --- |
| 400 | pacote inválido | reveja schema, frontmatter e estrutura de pastas |
| 401 | token ausente/inválido | token expirado (90 dias) — peça um novo em `/account/` |
| 403 | sem permissão / CSRF | só dá para publicar no próprio espaço |
| 409 | versão já existe | aumente a `version`; nunca tente sobrescrever |
| 413 | corpo grande demais | 2 MiB de conteúdo, 4 MiB de corpo HTTP |
| 429 | limite de taxa | espere; o limite é 30 publicações/hora |

Nunca contorne um erro removendo validação ou reenviando em loop: leia o corpo da resposta (`--fail-with-body` já imprime) e corrija a causa.

## Atualizar uma versão

Mesmo `id`, `version` maior, `changelog` descrevendo o que mudou. Patch para correção de texto, minor para novos checks ou recursos, major para mudança incompatível de comportamento.

## Retirar uma versão

Só com pedido explícito do usuário e com motivo concreto — o pacote histórico continua acessível e continua contando para o armazenamento.

```bash
curl --fail-with-body -sS -X POST \
  -H "Authorization: Bearer $AISKILLS_TOKEN" -H "Content-Type: application/json" \
  -d '{"reason":"<motivo concreto>"}' \
  $BASE/api/v1/users/arthurbonora/skills/<skill>/versions/<versao>/withdraw
```

## Fork para o próprio espaço

```bash
curl --fail-with-body -sS -X POST \
  -H "Authorization: Bearer $AISKILLS_TOKEN" -H "Content-Type: application/json" \
  -d '{"kind":"community","owner":"alice","slug":"minha-skill","version":"1.0.0"}' \
  $BASE/api/v1/skills/fork
```

Para skill do catálogo curado: `"kind":"curated"` com `"owner":""`. O fork cria repositório novo e histórico independente; identificador já existente no espaço retorna conflito.

## Cuidados

- Publicação da comunidade passa só por validação automática de formato — **não** é revisão humana nem auditoria de segurança. Revise o conteúdo antes de subir.
- O nome de usuário é público e permanente; o conteúdo publicado é público.
- Confirme com o usuário antes de publicar, retirar ou forkar — são ações públicas e, no caso da publicação, irreversíveis.
- Prefira token a login por senha. O fluxo de sessão (`/api/v1/auth/session` → `/api/v1/auth/login` com `X-CSRFToken`) existe, mas não é para agente.

Requisitos

  • Acesso de rede HTTPS a aiskills.bonorasw.com.br.
  • curl, zip e python3 disponíveis no ambiente do agente.

Permissões declaradas

  • Leitura do token de publicação na variável de ambiente AISKILLS_TOKEN.
  • Leitura dos arquivos da skill a ser empacotada.
  • Envio de requisições HTTP autenticadas para a API do AI Skills.

Avaliações

Carregando…

Carregando recomendações…

Versões