O que é um repositório

O Clink lê pacotes de repositórios públicos do GitHub. Adiciona um pelo nome, o Clink lê a sua última versão publicada, e cada ficheiro é verificado antes de ser instalado. Nada é enviado e nada do que é seu corre num servidor.

Introduz owner/repository, github.com/owner/repository ou o URL HTTPS completo. O Clink verifica todos os manifestos de versão e ficheiros antes de qualquer transferência.

Escolha um tipo

Cada tipo de pacote tem a sua extensão de ficheiro e o seu nome de coleção dentro do manifesto, e o Clink aplica a cada um o seu próprio limite de tamanho. Escolha a linha que vai publicar e mantenha-se nela: um tema arquivado como painel simplesmente não é lido.

TipoFicheiroColeçãoFicheiro maior, em bytesRepositório oficial
Temas.clinkthemethemes128.000anti-ltd/clink-themes
Esquemas.clinklayoutlayouts512.000anti-ltd/clink-layouts
Perfis.clinkprofileprofiles256.000anti-ltd/clink-profiles
Sons.clinkpacksounds512.000anti-ltd/clink-sounds
Tipos de letra.otf .ttffonts32.000.000anti-ltd/clink-fonts
Painéis.clinkpanelpanels50.000anti-ltd/clink-panels
Ações.clinkextactions48.000anti-ltd/clink-actions
Plugins.clinkpluginplugins66.000anti-ltd/clink-plugins

Os pacotes de idioma são a exceção. Aí um pacote é um conjunto de ficheiros de léxico e de modelos, não um único documento, e o repositório oficial traz as ferramentas que os constroem. Comece pelo README dele em vez desta página.

Comece pelo repositório oficial

O caminho mais rápido é um fork. Chega com a pasta de pacotes, o gerador do manifesto e o fluxo de publicação já ligados, além de exemplos a funcionar que pode copiar.

# Everything a repository needs is already wired together in the official one.
gh repo fork anti-ltd/clink-panels --clone
cd clink-panels

# Your packs replace the examples. Keep tools/ and .github/.
rm Panels/*.clinkpanel
cp ~/Downloads/my-panel.clinkpanel Panels/kaomoji-plus.clinkpanel

Mantenha tools/ e .github/workflows/. São esses dois que transformam um push numa versão que o Clink consegue ler, e um fork sem eles não publica nada.

Ou construa-o com três ficheiros

Um repositório não tem nada de especial. Precisa de uma pasta de pacotes, de um script que escreva o manifesto e de um fluxo de trabalho que publique a versão.

my-panels/
├── Panels/
   └── kaomoji.clinkpanel        # one file per pack, the name is the id
├── tools/
   └── build-manifest.py         # writes manifest.json from that folder
└── .github/workflows/
    └── release.yml               # turns a push into a release

O fluxo faz três coisas: reconstrói o manifesto, apaga a versão anterior e publica uma nova com a etiqueta latest, com os ficheiros do pacote e o manifesto anexados. É tudo.

name: Release panels
on:
  push:
    branches: [main]
    paths: ["Panels/**", "tools/**", ".github/workflows/release.yml"]
permissions: { contents: write }
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: python3 tools/build-manifest.py
      - run: gh release delete latest --yes || true
        env: { GH_TOKEN: "${{ github.token }}" }
      - run: gh release create latest Panels/*.clinkpanel manifest.json --title "Latest panels" --latest
        env: { GH_TOKEN: "${{ github.token }}" }
.github/workflows/release.yml

O gerador percorre a pasta e escreve uma entrada por ficheiro. É o único sítio de onde vêm o hash e a contagem de bytes, e é por isso que corre no fluxo de trabalho e não à mão.

#!/usr/bin/env python3
import hashlib, json, os, pathlib

root = pathlib.Path(__file__).resolve().parents[1]
repository = os.environ.get("GITHUB_REPOSITORY", "<owner>/<repository>")
packs = []
for path in sorted((root / "Panels").glob("*.clinkpanel")):
    data = path.read_bytes()
    pack = json.loads(data)
    packs.append({
        "id": path.stem,
        "name": pack["name"],
        "version": "latest",
        "asset": {
            "path": path.name,
            "url": f"https://github.com/{repository}/releases/download/latest/{path.name}",
            "sha256": hashlib.sha256(data).hexdigest(),
            "byteCount": len(data),
        },
    })
(root / "manifest.json").write_text(json.dumps({"version": "latest", "panels": packs}, indent=2))
tools/build-manifest.py. Para outro tipo, mude a pasta, a extensão e o nome da coleção para os da linha que escolheu.

O manifesto

Cada versão publica manifest.json junto aos ficheiros do pacote, e o Clink lê-o da última versão em https://github.com/<owner>/<repository>/releases/latest/download/manifest.json. Cada entrada indica o ficheiro, o seu endereço dentro dessa mesma versão, o seu hash SHA-256 e a contagem exata de bytes.

{
  "version": "latest",
  "panels": [
    {
      "id": "kaomoji",
      "name": "Kaomoji",
      "version": "latest",
      "asset": {
        "path": "kaomoji.clinkpanel",
        "url": "https://github.com/<owner>/<repository>/releases/download/latest/kaomoji.clinkpanel",
        "sha256": "8f14e45fce…",
        "byteCount": 2048
      }
    }
  ]
}
Uma entrada do manifesto de um repositório de painéis.

O nome da coleção tem de corresponder ao tipo. Os painéis vão em panels, os temas em themes, e assim por toda a tabela acima.

Experimente antes de publicar

Um pacote num repositório é o mesmo ficheiro que pode abrir à mão, por isso teste-o primeiro pelo caminho curto: envie-o para o telemóvel por AirDrop, ou ponha-o na app Ficheiros e abra-o com o Clink. Depois confira o manifesto que o seu script escreve.

python3 tools/build-manifest.py
cat manifest.json
  1. Corra o gerador. Ele reescreve manifest.json a partir do que estiver na pasta nesse momento.
  2. Leia o que ele escreveu. Cada entrada deve nomear um ficheiro que exista mesmo, com uma contagem de bytes que corresponda.
  3. Abra o próprio ficheiro do pacote no Clink e use-o. Um painel ou uma ação aterram no seu editor, onde os pode executar.

Publicar

git add Panels manifest.json
git commit -m "Add my first panel"
git push

Envie para main e o fluxo de trabalho trata do resto. Ele substitui a versão latest em vez de acrescentar a ela, por isso o último push é sempre o que os outros recebem.

Abre este separador depois de o repositório publicar uma versão.

Adicione-o no Clink

  1. Abra Geral, depois Repositórios, e adicione proprietário/repositório.
  2. Abra o separador do seu tipo e puxe para atualizar. Os seus pacotes aparecem com os nomes que o manifesto lhes deu.
  3. Toque num para o transferir. O Clink verifica-o e instala-o como qualquer outro pacote.

Adicionar um repositório chega para os pacotes de dados: temas, esquemas, perfis, sons, tipos de letra e idiomas. Painéis, ações e plugins carregam lógica, por isso cada repositório precisa de um interruptor próprio antes de o Clink instalar qualquer um deles, e a app pergunta na primeira vez.

Os painéis contêm lógica interativa restrita. Permita apenas repositórios em que confia.

O que o Clink verifica

  1. O endereço é HTTPS em github.com, dentro das versões do repositório que adicionou.
  2. A transferência tem exatamente a contagem de bytes do manifesto e o seu hash SHA-256 de 64 caracteres coincide.
  3. O ficheiro tem a extensão certa e descodifica como o tipo de pacote que diz ser.
  4. Painéis, ações e plugins passam a política de código-fonte antes de serem guardados.

Quando uma transferência é recusada, é por uma destas cinco razões. A mensagem na app é curta de propósito, por isso verifique-as por ordem.

VerificaçãoRecusado quando
github.comO endereço não é HTTPS em github.com, dentro das versões do repositório que adicionou. Um manifesto não pode apontar para outro sítio, nem sequer para outro repositório seu.
byteCountO ficheiro não tem exatamente o tamanho que o manifesto indica, ou passa o limite do seu tipo. Reconstruir o manifesto depois de cada alteração resolve quase todos estes casos.
sha256O hash não corresponde aos bytes. Normalmente o manifesto foi escrito antes da última alteração ao ficheiro.
pathO nome do ficheiro não termina na extensão que o tipo exige, ou tenta sair da versão com dois pontos.
sourceUm painel, uma ação ou um plugin não passou a política de código-fonte: demasiado longo, ou com um fragmento que a política recusa.

Atualizar, e retirar algo

O id é o nome do ficheiro sem a extensão, e é o que faz de uma atualização uma atualização. Mantenha o nome e uma nova versão substitui a cópia que as pessoas já têm. Mude o nome e publicou um segundo pacote ao lado do primeiro.

Retirar um pacote do repositório trava novas transferências. Não chega aos telemóveis que já o têm, por isso trate uma versão má como algo a substituir, não a apagar.

Repositórios oficiais

Faça fork de qualquer um destes para começar. Cada um constrói o seu próprio manifesto e publica-se com GitHub Actions.

Descarregar na App Store