Communitygithub.com

Site Web depuis WebDAV

Publie un site statique HTML/CSS/JS (généré par un pipeline RDF-Turtle + SHACL + Jinja2, par ex. sites/openlink/rdf/build.py) vers une racine WebDAV Virtuoso et y associe une route publique via isql/VHOST_DEFINE.

Qu'est-ce que Site Web depuis WebDAV ?

Ce skill permet de déployer un site web statique pré-généré (HTML/CSS/JS) issu d'un pipeline RDF-Turtle + SHACL + Jinja2 (comme `sites/openlink/rdf/build.py`) vers un serveur Virtuoso via WebDAV, avec une route publique configurée via `VHOST_DEFINE`. Il est conçu pour les cas où le contenu est déjà entièrement rendu – aucune exécution VSP ni requête SPARQL en direct. Le skill vérifie que la sortie `generated/` est à jour, valide le bundle avec `scripts/validate_generated_website_bundle.py`, publie les fichiers via WebDAV (PUT récursif suivi d'une vérification GET/PROPFIND), et configure la route si nécessaire via isql. Il prend en charge plusieurs modes d'authentification : SQL, WebID-TLS, délégation, WebDAV mTLS. Si les identifiants de déploiement ne sont pas disponibles, il produit un bundle déployable complet avec un README, sans décrire un succès hypothétique. Ce skill ne modifie pas le contenu RDF, n'exécute pas la logique interne du pipeline, et ne rend pas les pages à la volée – ces limites sont documentées dans les fichiers de référence.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/OpenLinkSoftware/ai-agent-skills/tree/HEAD/website-from-webdav

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait Site Web depuis WebDAV ?

Utilisez ce skill pour prendre un site statique déjà généré (HTML/CSS/JS) — le résultat d'un pipeline RDF-Turtle + SHACL + Jinja2 tel que sites/openlink/rdf/build.py — et le publier sur une racine WebDAV Virtuoso avec une route publique mappée. Le modèle de contenu du site (ontologie, formes SHACL, ordre) est créé et validé en amont de ce skill ; le travail de ce skill commence à "voici un dossier generated/ avec du HTML fini, mettez-le en ligne."

Ce skill est délibérément plus restreint que weblog-from-webdav ou osdi-inclusion-engine : ces skills rendent le contenu en direct à chaque requête (énumération de collection WebDAV dans un VSP personnalisé, ou une feuille de style XSLT partagée enveloppant du HTML provenant de WebDAV). Le contenu de ce skill est déjà entièrement rendu avant d'arriver — le publier est un simple PUT WebDAV plus un VHOST_DEFINE pour fichier statique, sans exécution VSP ni requête SPARQL en direct. Voir references/webdav-website-engine-gate.md pour comprendre pourquoi ce choix a été fait et quand il pourrait changer.

Barrière de blocage — Un fichier local n'est pas une complétion valide

Lorsque l'utilisateur demande de publier, déployer ou "mettre en ligne" un site généré, une description de ce qui se passerait, ou une affirmation que les fichiers existent localement, n'est pas une complétion valide sauf si l'utilisateur demande explicitement seulement une vérification locale/aperçu. Le livrable par défaut est soit :

  • un site publié et vérifié en direct : la route cible renvoie le même contenu que la sortie locale generated/, ou
  • un bundle déployable complet : generated/*.html, le dossier assets/ du site (site.css, theme.js), un templates/deploy-website-route.sql avec chemins substitués, et un fichier README/notes d'exécution — avec scripts/validate_generated_website_bundle.py qui réussit dessus.

Lisez references/webdav-website-engine-gate.md avant de prétendre l'un ou l'autre. Si les identifiants de déploiement (WebDAV et/ou isql) ne sont pas disponibles, arrêtez-vous au bundle déployable et dites clairement que la publication en direct est bloquée par l'absence d'accès authentifié — ne décrivez pas un succès hypothétique.

Premières décisions

Établissez ceci avant de publier quoi que ce soit :

  • Répertoire source du pipeline (par ex. {LLM_ROOT}/Claude Generated/sites/openlink/) et s'il faut (re)exécuter rdf/build.py d'abord, ou si generated/ est déjà à jour.
  • Collection DAV cible, par ex. /DAV/home/kidehen/sites/openlink/.
  • Route publique, par ex. https://linkeddata.uriburner.com/sites/openlink/.
  • Mode d'identité : nom d'utilisateur/mot de passe SQL, isql WebID-TLS, WebID-TLS avec délégation, nom d'utilisateur/mot de passe WebDAV, WebDAV mTLS, ou WebDAV mTLS avec On-Behalf-Of.
  • S'agit-il d'un premier démarrage de route (isql + deploy-website-route.sql requis) ou d'une republication de contenu uniquement sur une route existante (publication WebDAV uniquement, selon le périmètre de references/webdav-publish-mode.md — il ne touche jamais à la configuration de route).

Flux de travail

  1. Confirmer que la sortie source generated/ est à jour : si on demande de (re)construire, exécuter rdf/validate_shacl.py du pipeline puis rdf/build.py inchangé — ce skill ne réimplémente ni ne contourne cette validation. Voir references/rdf-content-mode.md.
  2. Avant d'écrire quoi que ce soit, rechercher dans la mémoire/travail antérieur validate_generated_weblog_bundle, VHOST_DEFINE, DAV_RES_UPLOAD_STRSES_INT, website-from-webdav ; réutiliser les correctifs éprouvés plutôt que de les redécouvrir.
  3. Déterminer si la route cible existe déjà (interroger DB.DBA.HTTP_PATH et WS.WS.SYS_DAV_RES pour le chemin cible via isql). Si non, l'amorcer : patcher templates/deploy-website-route.sql avec le vrai chemin DAV/route/titre, puis l'exécuter avec isql. Voir references/isql-route-mode.md.
  4. Valider le bundle avec scripts/validate_generated_website_bundle.py avant toute publication. C'est un blocage.
  5. Publier via WebDAV en utilisant scripts/publish_static_bundle.py — PUT récursif de generated/*.html et assets/*, vérifie chaque écriture avec un GET/PROPFIND de suivi. Voir references/webdav-publish-mode.md.
  6. Vérifier : récupérer la route en direct, confirmer que les octets servis correspondent au fichier local generated/ (en tolérant uniquement les différences d'espaces/ordre d'attributs, même tolérance que la vérification de Phase 1 du pipeline), confirmer que assets/site.css/theme.js se chargent avec les bons types MIME.
  7. Rapporter exactement ce qui s'est passé : route amorcée ou réutilisée, fichiers publiés avec leurs chemins DAV, résultat de la vérification — ou, si les identifiants manquaient, l'emplacement du bundle déployable et la déclaration explicite que la publication en direct n'a pas eu lieu.

Références de mode

  • Pour l'amorçage de route et la syntaxe TLS/WebID d'isql, lisez references/isql-route-mode.md.
  • Pour la publication WebDAV et son périmètre hors champ, lisez references/webdav-publish-mode.md.
  • Pour la limite du pipeline (ce que ce skill fait et ne touche pas dans rdf/), lisez references/rdf-content-mode.md.
  • Pour savoir pourquoi le rendu SPARQL/VSP en direct n'a pas été choisi, lisez references/webdav-website-engine-gate.md.
  • Pour les opérations appelables par un agent, lisez references/opal-tool-mode.md — non implémenté en v1 ; documenté comme point d'extension.

Garde-fous pratiques

  • N'exécutez jamais la validation SHACL de rdf/build.py avec les avertissements supprimés ou des raccourcis de style --skip-validate ; une barrière qui échoue signifie que le contenu n'est pas prêt à être publié, pas un obstacle à contourner.
  • DB.DBA.DAV_RES_UPLOAD_STRSES_INT (si utilisé pour une étape autre que fichier statique) nécessite un flux string_output() alimenté via http(content, stream), pas une simple chaîne.
  • Évitez $1, $2 et jetons similaires dans tout SQL chargé via isql ; ils peuvent déclencher une substitution de macro.
  • Un VHOST_DEFINE pour fichier statique utilise is_dav=>1, is_brws=>0, def_page=>'index.html' — ne mettez pas def_page=>'index.vsp' à moins qu'un point d'entrée VSP n'existe vraiment ; un def_page pointant vers une ressource VSP inexistante sert le code source brut ou une 404, pas le site.
  • Supprimez tout VHOST_DEFINE conflictuel antérieur pour le même hôte/chemin avant de le redéfinir, comme le modèle supprimer-puis-redéfinir de weblog-from-webdav.
  • Traitez l'identité porteuse du certificat et le mandant délégué comme des faits séparés : -X/--cert identifie l'agent appelant, -W/On-Behalf-Of identifie le principal WebID dont les droits ACL doivent être évalués.
  • N'écrivez jamais d'identifiants dans le skill, le SQL généré, les logs ou les fichiers commités.
  • Les téléversements et suppressions distants suivent le même ordre HTTP → WebDAV → iSQL et le même modèle PKCS#12 de principal (howto/remote-webdav-upload.ttl, howto/remote-resource-removal.ttl, préférences Étapes 215–216). Les écritures/suppressions URIBurner vont sur le port 5443. Rapportez séparément le GET :5443 et le GET public 443 après un PUT ; après un DELETE, vérifiez l'URL nommée par l'utilisateur, les variantes avec barre oblique, le GET :5443, et le listing du dossier avant de déclarer la suppression.

Sortie d'erreur ISQL Virtuoso sécurisée

Chaque fois que ce flux de travail invoque le client isql natif de Virtuoso, passez l'option client nue COMMAND_TEXT_ON_ERROR=OFF, par exemple isql {host}:{port} {user} {password} COMMAND_TEXT_ON_ERROR=OFF {script.sql}. Placez-la avant l'entrée SQL, les arguments de script ou -i. OFF correspond à la valeur interne 0 du client et empêche le client d'ajouter la commande échouée complète à la sortie d'erreur. Le client accepte OFF/ON ; le littéral 0 est rejeté. N'utilisez pas -u pour ce paramètre (-u remplit le tableau d'arguments U). Cela ne masque pas les secrets des diagnostics serveur, de l'historique du shell ou des arguments de processus, donc gardez les identifiants hors du texte SQL et des logs. N'appliquez pas cette option spécifique à Virtuoso aux clients isql unixODBC/iODBC.

Skills associés