plugins/somtech-somcraft-deployer/skills/deploy-somcraft/SKILL.md
Déployer une instance SomCraft pour un client existant (migrations Supabase + Fly.io + skills). Orchestre 7 phases : pré-flight, plan, migrations, seed, déploiement, smoke tests, installation des skills. TRIGGERS : deploy-somcraft, déployer somcraft, installer somcraft, somcraft client, setup somcraft, upgrade somcraft, status somcraft
npx skillsauth add SomtechSolutionMAxime/somtech-pack deploy-somcraftInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Déployer une instance SomCraft dédiée pour un client existant. Ce skill orchestre l'ensemble du processus en 7 phases.
Ce skill supporte 3 modes selon la commande qui l'invoque :
install (défaut, depuis /deploy-somcraft) — Déploiement initial complet, toutes les phasesupgrade (depuis /deploy-somcraft-upgrade) — Saute pré-flight configuration, ne fait que migrations + redéploiementstatus (depuis /deploy-somcraft-status) — Lecture seule, rapporte l'état sans modifierDétecter le mode en lisant le prompt de l'utilisateur.
Référence détaillée : references/preflight-checks.md
Lis .somtech/app.yaml du projet courant (créé par /lier-app, voir STD-027). Extrais :
servicedesk.client_name → {client-name}servicedesk.app_slug → utilisé pour dériver {client-slug} (généralement {client-slug} = servicedesk.app_slug ou un slug stable du client)servicedesk.client_id (UUID) — pour traçabilité et vérificationSi .somtech/app.yaml n'existe pas : arrêter avec le message exact suivant et ne PAS deviner le nom client depuis CLAUDE.md ou autre source :
Erreur : .somtech/app.yaml absent. Ce repo n'est pas lié à une application Somtech.
Lancez /lier-app pour créer .somtech/app.yaml avant de relancer /deploy-somcraft.
Lis .mcp.json. Vérifie qu'il contient une entrée pour Supabase MCP avec un project_ref valide.
Lis fly.toml. Extrais :
app (nom de l'app Fly.io actuelle)primary_regionfly apps list si pas dans le toml)Vérifie que package.json existe (pas une validation stricte, juste confirmer qu'on est dans un repo Node).
Exécute fly auth whoami. Si erreur, arrête et affiche : "Fly CLI non authentifié. Exécutez fly auth login."
Utilise AskUserQuestion pour demander l'environnement cible :
Question: "Sur quel environnement déployer SomCraft ?"
Options:
- staging : Environnement de développement/test
- production : Environnement de production client
{client} sur {env} ? (oui/non)"Si l'une de ces étapes échoue, arrête et affiche l'erreur clairement.
Avant de procéder, affiche un tableau récapitulatif :
| Item | Valeur |
|-------------------|------------------------------------------|
| Client | {client-name} |
| Slug | {client-slug} |
| Environnement | {env} |
| Supabase project | {project-ref} |
| Fly app | somcraft-{client-slug}-{env} |
| Fly org | {fly-org} |
| Image Docker | ghcr.io/somtech-solutions/somcraft:{somcraft-version} |
| Workspace initial | {client-name} - Docs |
| Admin email | (demandé à la prochaine étape) |
| Migrations | (détecté après clone) |
Demande confirmation finale avec AskUserQuestion :
Question: "Procéder au déploiement ?"
Options:
- oui, procéder : Lance toutes les phases
- annuler : Arrête ici
Référence détaillée : references/migrations-workflow.md
plugin.json :# Résout la version. Si plugin.json contient "latest" (valeur par défaut),
# on récupère le dernier tag vX.Y.Z publié sur le repo SomCraft.
SOMCRAFT_VERSION_RAW=$(jq -r .somcraftVersion "$PLUGIN_ROOT/.claude-plugin/plugin.json")
if [ "$SOMCRAFT_VERSION_RAW" = "latest" ]; then
SOMCRAFT_VERSION=$(git ls-remote --tags --refs https://github.com/Somtech-Solutions/somcraft.git \
| awk -F/ '{print $NF}' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -1 | sed 's/^v//')
else
SOMCRAFT_VERSION="$SOMCRAFT_VERSION_RAW"
fi
[ -z "$SOMCRAFT_VERSION" ] && { echo "Erreur : impossible de résoudre la version SomCraft."; exit 1; }
echo "Version SomCraft cible : v$SOMCRAFT_VERSION"
TMP_DIR=$(mktemp -d)
git clone --depth 1 --branch "v$SOMCRAFT_VERSION" https://github.com/Somtech-Solutions/somcraft.git "$TMP_DIR"
Note : --branch vlatest n'existe pas — le bloc ci-dessus résout "latest" en tag réel avant le clone.
ls $TMP_DIR/supabase/migrations/*.sql | sortmcp__supabase__execute_sql), lis supabase_migrations.schema_migrations pour détecter les migrations déjà appliquées.schema_migrations).mcp__supabase__apply_migration (OU mcp__supabase__execute_sql si apply_migration n'est pas disponible) en mode transactionnelschema_migrations avec son version (timestamp du nom de fichier)sc-{client-slug} via MCP Supabase :INSERT INTO storage.buckets (id, name, public)
VALUES ('sc-{client-slug}', 'sc-{client-slug}', false)
ON CONFLICT DO NOTHING;
sc_workspaces et sc_documents sont actives :SELECT tablename, rowsecurity FROM pg_tables WHERE tablename LIKE 'sc_%';
Toutes les tables doivent avoir rowsecurity = true. Sinon, afficher un warning.
IMPORTANT : Ne JAMAIS utiliser supabase db push --linked.
Référence détaillée : references/seed-workflow.md
AskUserQuestion :Question: "Quel email pour l'utilisateur admin de cette instance ?"
Options:
- admin@{client-slug}.com : Email générique par défaut
- Autre email : Saisir un email personnalisé
auth.identities requise pour le login email/password, contrairement à un INSERT SQL brut) :ADMIN_PW=$(openssl rand -base64 18)
curl -fsS -X POST "https://${PROJECT_REF}.supabase.co/auth/v1/admin/users" \
-H "apikey: ${SUPABASE_SERVICE_ROLE_KEY}" \
-H "Authorization: Bearer ${SUPABASE_SERVICE_ROLE_KEY}" \
-H "Content-Type: application/json" \
-d "{\"email\":\"${ADMIN_EMAIL}\",\"password\":\"${ADMIN_PW}\",\"email_confirm\":true,\"user_metadata\":{\"role\":\"admin\",\"name\":\"Admin\"}}"
# Récupérer l'`id` retourné comme ADMIN_USER_ID.
Fallback SQL (si le réseau ne permet pas d'atteindre l'endpoint Auth) : voir references/seed-workflow.md — l'INSERT dans auth.users doit être accompagné d'un INSERT dans auth.identities, sinon le login email/password échoue sur les versions récentes de GoTrue.
INSERT INTO sc_workspaces (name, slug, storage_bucket, created_by)
VALUES ('{client-name} - Docs', '{client-slug}-docs', 'sc-{client-slug}', '{admin-user-id}')
RETURNING id;
sk_ + 32 caractères [a-z0-9], identique à generateWorkspaceApiKey() côté code SomCraft) :API_KEY="sk_$(LC_ALL=C tr -dc 'a-z0-9' < /dev/urandom | head -c 32)"
Note auth (SomCraft ≥ v0.20) : la clé de workspace (
sk_…) reste supportée et résolue contresc_workspaces.api_key. Le modèle recommandé pour faire opérer un agent IA est désormais la clé agentsk_agent_…(registresc_agents+sc_agent_api_keys, accès workspace viasc_agent_workspace_access). Pour un seed initial mono-workspace, la clé de workspace suffit ; bascule vers une clé agent depuis/settings/agentsquand plusieurs agents/clés scopées sont nécessaires.
sc_workspaces :UPDATE sc_workspaces SET api_key = '{api-key}' WHERE id = '{workspace-id}';
INSERT INTO sc_workspace_members (workspace_id, user_id, role)
VALUES ('{workspace-id}', '{admin-user-id}', 'admin');
/tmp/somcraft-deploy-{client-slug}-credentials.txt pour l'afficher dans le rapport final.Référence détaillée : references/fly-deployment.md
FLY_APP="somcraft-{client-slug}-{env}"
fly apps list | grep "$FLY_APP"
Si elle n'existe pas, la créer :
fly apps create "$FLY_APP" --org "{fly-org}"
fly.toml temporaire depuis templates/fly-toml.tpl en remplaçant les variables.fly secrets set :fly secrets set \
ANTHROPIC_API_KEY="{anthropic-key}" \
NEXT_PUBLIC_SUPABASE_URL="https://{project-ref}.supabase.co" \
NEXT_PUBLIC_SUPABASE_ANON_KEY="{anon-key}" \
SUPABASE_SERVICE_ROLE_KEY="{service-role-key}" \
NEXTAUTH_SECRET="$(openssl rand -base64 32)" \
SOMCRAFT_MCP_API_KEY="{api-key-from-phase-3}" \
-a "$FLY_APP"
Note : Les secrets ANTHROPIC_API_KEY, les clés Supabase, etc., doivent être lus depuis le .env.local du projet client OU demandés interactivement via AskUserQuestion.
fly deploy -a "$FLY_APP" \
--image "ghcr.io/somtech-solutions/somcraft:$SOMCRAFT_VERSION" \
--config /tmp/fly-somcraft-{client-slug}.toml
fly status -a "$FLY_APP"
Retry jusqu'à 2 minutes (polling toutes les 10s).
Référence détaillée : references/smoke-tests.md
APP_URL=$(fly info -a "$FLY_APP" --json | jq -r .Hostname)curl -f "https://$APP_URL/api/health"
Attendu : 200 OK avec {"status":"ok"}
curl -X POST "https://$APP_URL/api/mcp/mcp" \
-H "Authorization: Bearer $SOMCRAFT_MCP_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Attendu : JSON avec la liste des tools MCP (doit inclure list_workspaces).
curl -X POST "https://$APP_URL/api/sc/documents" \
-H "Authorization: Bearer $SOMCRAFT_MCP_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"workspace_id\":\"$WORKSPACE_ID\",\"filename\":\"welcome.md\",\"type\":\"file\"}"
Attendu : 201 Created.
somcraft :
~/.claude/skills/somcraft/SKILL.md existeskills/somcraft/ du plugin vers ~/.claude/skills/somcraft/version: si présent, sinon comparer la date de modification)PLUGIN_SOMCRAFT_SKILL="$PLUGIN_ROOT/skills/somcraft"
TARGET_SOMCRAFT_SKILL="$HOME/.claude/skills/somcraft"
mkdir -p "$TARGET_SOMCRAFT_SKILL"
cp -r "$PLUGIN_SOMCRAFT_SKILL"/* "$TARGET_SOMCRAFT_SKILL/"
somcraft-{client-slug} :
$PLUGIN_ROOT/templates/project-skill.md.tplsed ou équivalent).claude/skills/somcraft-{client-slug}/SKILL.md du projet courantTARGET_DIR=".claude/skills/somcraft-{client-slug}"
mkdir -p "$TARGET_DIR"
sed \
-e "s|{{CLIENT_SLUG}}|{client-slug}|g" \
-e "s|{{CLIENT_NAME}}|{client-name}|g" \
-e "s|{{STAGING_URL}}|$STAGING_URL|g" \
-e "s|{{PROD_URL}}|$PROD_URL|g" \
-e "s|{{STAGING_SUPABASE_REF}}|$STAGING_REF|g" \
-e "s|{{PROD_SUPABASE_REF}}|$PROD_REF|g" \
-e "s|{{STORAGE_BUCKET}}|sc-{client-slug}|g" \
-e "s|{{FLY_ORG}}|$FLY_ORG|g" \
-e "s|{{FLY_APP_STAGING}}|somcraft-{client-slug}-staging|g" \
-e "s|{{FLY_APP_PROD}}|somcraft-{client-slug}|g" \
-e "s|{{WORKSPACE_ID}}|$WORKSPACE_ID|g" \
-e "s|{{WORKSPACE_NAME}}|{client-name} - Docs|g" \
-e "s|{{ADMIN_EMAIL}}|$ADMIN_EMAIL|g" \
-e "s|{{DEPLOY_DATE}}|$(date +%Y-%m-%d)|g" \
-e "s|{{SOMCRAFT_VERSION}}|$SOMCRAFT_VERSION|g" \
"$PLUGIN_ROOT/templates/project-skill.md.tpl" > "$TARGET_DIR/SKILL.md"
Afficher le rapport suivant :
════════════════════════════════════════════════════════
✓ SomCraft déployé pour {client-name}
════════════════════════════════════════════════════════
Environnement : {env}
Version : {somcraft-version}
URL : https://{app-url}
Workspace initial :
ID : {workspace-id}
Nom : {client-name} - Docs
Admin :
Email : {admin-email}
Password : {random-password}
⚠ Stocker dans 1Password : somcraft-{client-slug}-admin
API Key MCP :
{api-key}
⚠ Stocker dans 1Password : somcraft-{client-slug}-mcp
Skills installés :
✓ ~/.claude/skills/somcraft/ (global, v{plugin-version})
✓ .claude/skills/somcraft-{client-slug}/ (projet, v{plugin-version})
Prochaines étapes :
1. Stocker les credentials dans 1Password
2. Configurer votre .mcp.json local pour accéder à cette instance :
{
"somcraft-{client-slug}": {
"type": "http",
"url": "https://{app-url}/api/mcp/mcp",
"headers": { "Authorization": "Bearer <from-1password>", "Accept": "application/json, text/event-stream" }
}
}
3. Tester l'instance en ouvrant https://{app-url} dans un navigateur
4. Invoquer le skill 'somcraft-{client-slug}' pour toute opération future
════════════════════════════════════════════════════════
Si le mode est upgrade :
.claude/skills/somcraft-{client-slug}/SKILL.mdSi le mode est status :
.claude/skills/somcraft-{client-slug}/SKILL.mdfly status -a {app-staging} et fly status -a {app-prod}tools
Documentation de référence SomCraft — DMS Markdown-native avec AI, MCP server, et Studio. À consulter pour toute question sur l'architecture, les APIs, les concepts, ou l'exploitation d'une instance SomCraft. TRIGGERS : somcraft, dms, document management, workspace somcraft, studio somcraft, mcp somcraft, api somcraft
tools
Génère l'intégralité de la configuration d'un silo SomTech : docker-compose, services Fly.io, constitutions d'agents, et templates d'environnement. Valide les métadonnées d'application avant génération. À utiliser après validation initiale du client et avant déploiement.
development
Exécute le déploiement complet d'une silo après sa génération : conteneurs Docker, environnement de développement Fly.io, branche Git, et configuration Netlify. Transforme les configs générées en infrastructure active avec URLs stables et builds automatisés.
tools
Connaissances sur le Somtech RAG Service — indexation de documents, recherche sémantique, génération de réponses sourcées. Utiliser quand on travaille avec le RAG Service, qu'on cherche comment l'appeler, comment déboguer, ou comment il cohabite avec Somcraft. TRIGGERS : RAG, document_chunks, rag_search, rag_push_document, hybrid search, embeddings, pgvector, somtech-rag-service, RagClient