Skip to content

DOC

CLI Go (v5+) — fonctionnement

CLI Go (v5+) — fonctionnement

Source : framework/cli/ · Spec détaillée : docs/spec-cli-go.md

À partir de v5, ulk est distribué comme un binaire Go unique (ulk) qui remplace progressivement install.sh. Le script bash devient un wrapper mince qui délègue au binaire si présent, sinon retombe sur l’ancienne logique.


Architecture

ulk (cobra root)
├── install     cmd/install.go
├── update      cmd/update.go
├── uninstall   cmd/uninstall.go
├── status      cmd/status.go      → modules ✓/○ + version
├── verify      cmd/status.go      → chemins + prérequis + LLM locaux
└── check       cmd/status.go      → CLIs + skills installés

internal/
├── installer/
│   ├── modules.go    catalogue des 14 modules
│   ├── state.go      ~/.ulk/state.json (persistance atomique)
│   ├── installer.go  orchestration de la copie
│   └── rollback.go   backup/restore
├── config/
│   └── hooks.go      fusion settings.json (hooks)
└── registry/
    └── diff.go       checksums SHA256 (pour update)

tui/
├── wizard.go     sélecteur de modules interactif (bubbletea)
├── progress.go   barre de progression (lipgloss)
└── status.go     affichage statut

Flux ulk install

1. Charger state.json (~/.ulk/state.json)
   └─ premier run → NewState() avec modules par défaut

2. Si premier run + pas de --no-tui :
   └─ TUI wizard (bubbletea) → l'utilisateur coche/décoche les modules

3. Pour chaque module activé, Installer.Run() :
   ├─ copyCommands()        framework/commands/  →  ~/.claude/commands/ulk/
   ├─ copySubagents()       .claude/agents/*.md  →  ~/.claude/agents/ulk-*.md
   ├─ copyUlkSkills()       framework/skills/    →  ~/.claude/skills/ulk-*/
   ├─ copyCommunitySkills() framework/community-skills/  →  ~/.claude/skills/<prefix>*/
   └─ mergeHooks()          .claude/hooks-examples/*.json  →  ~/.claude/settings.json

4. Save(state) — écrit state.json atomiquement (tmp+rename)
   └─ seulement si toutes les étapes ont réussi

L’écriture atomique (os.WriteFile puis os.Rename) garantit qu’un crash en cours ne corrompt pas l’état existant : soit l’ancien state.json reste en place, soit le nouveau est complet.


Les 14 modules

Définis dans internal/installer/modules.go. Chaque module a :

ChampRôle
Keyclé dans state.json (ex : figma-skills)
Flagflag CLI (ex : --with-figma-skills)
Label / Descriptionaffichés dans le TUI wizard
EnabledByDefaulttrue pour les 4 essentiels (Figma, Swift, Flutter, context-audit)
RemoveGlobschemins relatifs à ~/.claude/ à effacer sur uninstall --module
DependsOnmodules requis avant celui-ci

Modules disponibles : figma-skills, swift-skills, flutter-skills, context-audit, vps, agent-teams, addy-skills, a11y-skills, obsidian-skills, nothing-design, memory-loop, xavier-hook, cli-telemetry, cwb-app-icon.


State persistant — ~/.ulk/state.json

{
  "version": "5.0.0",
  "source": "github.com/izo/ulk",
  "installedAt": "2026-04-26T12:00:00Z",
  "updatedAt":   "2026-04-26T12:00:00Z",
  "modules": { "figma-skills": true, "vps": false },
  "checksums": { "commands/ulk/bruce.md": "sha256:..." },
  "claudeDir": "/Users/x/.claude",
  "backup": { "path": "/tmp/ulk-backup-...", "version": "4.9.0" }
}

Trois usages :

  1. Savoir quels modules sont actifs (pour status et uninstall --module)
  2. Détecter les fichiers modifiés (update compare checksums avant copie)
  3. Pointer vers le backup pour rollback automatique

Update intelligent

ulk update utilise internal/registry/diff.go :

  1. Calcule les checksums SHA256 par bucket (commands, subagents, ulk-skills, community-skills)
  2. Compare avec ceux dans state.json
  3. Affiche un diff (Added / Modified / Removed) avec --check (dry-run)
  4. Sans --check : applique les changements + rollback automatique en cas d’erreur

Rollback

internal/installer/rollback.go :

  • Avant install/update : Backup() snapshot uniquement les chemins ulk-owned (préserve les configs tierces)
  • Sur erreur : Restore() restaure le backup
  • Manuel : ulk rollback revient à l’état précédent

TUI

Trois composants bubbletea/lipgloss dans tui/ :

FichierRôle
wizard.gosélecteur de modules à l’install (cases à cocher, preview, navigation clavier)
progress.gobarre de progression pendant copie/merge
status.goaffichage tabulaire pour ulk status

Le wizard se lance automatiquement au premier run sauf si --no-tui ou --dry-run.


Distribution

CibleOutil
Build multi-archgoreleaser (4 cibles : darwin/linux × arm64/amd64)
Release GitHub.github/workflows/release.yml (tests Go pré-release)
Homebrewtap OSS via goreleaser-homebrew-action (template framework/cli/homebrew/ulk.rb.template)

Relation avec install.sh

install.sh est désormais un wrapper mince :

if command -v ulk >/dev/null 2>&1; then
  exec ulk install "$@"   # délègue au binaire Go
fi
# fallback : ancienne logique bash

Le binaire Go est la v5 ; le bash est conservé comme fallback de compatibilité jusqu’en v5.1, puis sera supprimé.


Build local

cd framework/cli
make build        # binaire dans ./bin/ulk
make test         # 75+ tests unitaires
make release-dry  # simule une release goreleaser

Couverture cible :

  • config/hooks 95% (≥90% requis)
  • installer/state 90% Load / 75% Save
  • registry/diff 85%
  • installer/rollback 85% / 80%

Voir aussi

  • Spec complète — décomposition par tâche (ULK-160 à ULK-180)
  • Audit ingénierie — décision Go vs alternatives
  • framework/cli/Makefile — toutes les commandes de build/test