website-from-webdav
Skill42 starsChanged 50 days agoMITView on GitHub
Publish a static HTML/CSS/JS website (generated by an RDF-Turtle + SHACL + Jinja2 pipeline, e.g. sites/openlink/rdf/build.py) to a Virtuoso WebDAV root and map a public route to it via isql/VHOST_DEFINE. Use for deploying or updating an already-built OpenLink-style portfolio site onto a WebDAV target, verifying a live route serves the generated content, or producing a deployable bundle when live credentials aren't available. Triggers on phrases like "publish this site to WebDAV", "deploy the generated site", "set up an initial OpenLink site from a WebDAV root", "is this site live", or any request to push a pre-rendered static site onto a Virtuoso WebDAV/VHOST target. Does not author or edit RDF content, run the SHACL/Jinja2 pipeline's internal logic, or render pages live from SPARQL — see references/rdf-content-mode.md for the boundary.
In this repository45 other files it gives its agents.
- agent-rdf-memory/AGENTS.mdAGENTS.md
- AGENTS.mdAGENTS.md
- a2a-clientSkill
- acp-clientSkill
- csv-to-rdf-det-generatorSkill
- data-twinglerSkill
- dbpedia-query-skillSkill
- document-to-kg-skillSkill
- fediverse-crudSkill
- fuxi-engineerSkill
- infographic-describerSkill
- iodbc-dsn-managerSkill
- kg-generatorSkill
- linked-data-skillsSkill
- llm-routing-skillSkill
- monidSkill
- mpp-stripe-clientSkill
- mtls-curlSkill
- opal-agent-skill-assemblerSkill
- openlink-license-managerSkill
- openlink-license-readerSkill
- openlink-request-broker-configuratorSkill
- opml-rss-readerSkill
- osdi-inclusion-engineSkill
- pinchtabSkill
- rdf-det-variant-generatorSkill
- rdf-infographic-skillSkill
- resource-access-offers-generatorSkill
- rss-feed-generatorSkill
- s3-query-skillSkill
- screencast-recorderSkill
- set-webdav-resource-propertySkill
- sparql-faceted-browserSkill
- ucp-clientSkill
- uriburner-opal-agent-skillsSkill
- virtuoso-rdf-bulk-loaderSkill
- virtuoso-rdf-loaderSkill
- virtuoso-support-agentSkill
- wc2026-match-reportSkill
- weblog-from-webdavSkill
- wikidata-query-skillSkill
- world-cup-2026-navigatorSkill
- x402-buyerSkill
- xmla-clientSkill
- youidSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 1 is distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 19
Read references/webdav-website-engine-gate.md before claiming either.
- Very specific: line 34
Before writing anything, search prior memory/work for validate_generated_weblog_bundle, VHOST_DEFINE, DAV_RES_UPLOAD_STRSES_INT, …
- Very specific: line 38
Verify: fetch the live route, confirm the served bytes match the local generated/ file (allowing only whitespace/attribute-order …
- Very specific: line 51
Never run rdf/build.py's SHACL validation with warnings suppressed or --skip-validate-style shortcuts.
- Very specific: line 53
Avoid $1, $2, and similar tokens in any SQL loaded through isql.
- Very specific: line 55
Delete any prior conflicting VHOST_DEFINE for the same host/path before redefining it, same as weblog-from-webdav's …
- Very specific: line 56
Treat the certificate-bearing identity and the delegated principal as separate facts: -X/--cert identifies the calling agent, …
- Distinctive: line 57
Never write credentials into the skill, generated SQL, logs, or committed files.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Website From WebDAV
Use this skill to take a static, already-generated HTML/CSS/JS site — the output of an RDF-Turtle + SHACL + Jinja2 pipeline such as sites/openlink/rdf/build.py — and publish it to a Virtuoso WebDAV root with a mapped public route. The site's content model (ontology, SHACL shapes, ordering) is authored and validated upstream of this skill; this skill's job starts at "here is a generated/ folder of finished HTML, get it live."
This is deliberately narrower than weblog-from-webdav or osdi-inclusion-engine: those skills render content live on every request (WebDAV-collection enumeration inside a bespoke VSP, or a shared XSLT skin wrapping WebDAV-sourced HTML). This skill's content is already fully rendered before it arrives — publishing it is a plain WebDAV PUT plus a static-file VHOST_DEFINE, no VSP execution and no live SPARQL query involved. See references/webdav-website-engine-gate.md for why that choice was made and when it would change.
Blocking Gate — A Local File Is Not a Valid Completion
When the user asks to publish, deploy, or "make live" a generated site, a description of what would happen, or a claim that files exist locally, is not a valid completion unless the user explicitly asks only for a local/preview check. The default deliverable is either:
- a live, verified published site: the target route returns the same content as the local
generated/output, or - a complete deployable bundle:
generated/*.html, the site'sassets/(site.css,theme.js), a path-substitutedtemplates/deploy-website-route.sql, and a README/run-notes file — withscripts/validate_generated_website_bundle.pypassing against it.
Read references/webdav-website-engine-gate.md before claiming either. If deployment credentials (WebDAV and/or isql) are unavailable, stop at the deployable bundle and say plainly that live publication is blocked by missing authenticated access — do not describe hypothetical success.
First decisions
Establish these before publishing anything:
- Source pipeline directory (e.g.
{LLM_ROOT}/Claude Generated/sites/openlink/) and whetherrdf/build.pyneeds to be (re)run first, orgenerated/is already current. - Target DAV collection, e.g.
/DAV/home/kidehen/sites/openlink/. - Public route, e.g.
https://linkeddata.uriburner.com/sites/openlink/. - Identity mode: SQL username/password,
isqlWebID-TLS, WebID-TLS plus delegation, WebDAV username/password, WebDAV mTLS, or WebDAV mTLS plusOn-Behalf-Of. - Whether this is a first-time route bootstrap (
isql+deploy-website-route.sqlrequired) or a content-only republish of an existing route (WebDAV publish only, perreferences/webdav-publish-mode.md's out-of-scope boundary — it never touches route configuration).
Workflow
- Confirm the source
generated/output is current: if asked to (re)build, run the pipeline's ownrdf/validate_shacl.pythenrdf/build.pyunchanged — this skill does not reimplement or bypass that validation. Seereferences/rdf-content-mode.md. - Before writing anything, search prior memory/work for
validate_generated_weblog_bundle,VHOST_DEFINE,DAV_RES_UPLOAD_STRSES_INT,website-from-webdav; reuse proven fixes rather than rediscovering them. - Determine whether the target route already exists (query
DB.DBA.HTTP_PATHandWS.WS.SYS_DAV_RESfor the target path viaisql). If not, bootstrap it: patchtemplates/deploy-website-route.sqlwith the real DAV path/route/title, then run it withisql. Seereferences/isql-route-mode.md. - Validate the bundle with
scripts/validate_generated_website_bundle.pybefore any publish. This is blocking. - Publish via WebDAV using
scripts/publish_static_bundle.py— PUTsgenerated/*.htmlandassets/*recursively, verifies each write with a follow-up GET/PROPFIND compare. Seereferences/webdav-publish-mode.md. - Verify: fetch the live route, confirm the served bytes match the local
generated/file (allowing only whitespace/attribute-order differences, same tolerance the pipeline's own Phase 1 verification uses), confirmassets/site.css/theme.jsload with correct MIME types. - Report exactly what happened: route bootstrapped or reused, files published with their DAV paths, verification result — or, if credentials were missing, the deployable bundle location and the explicit statement that live publication did not happen.
Mode references
- For route bootstrap and
isqlTLS/WebID syntax, readreferences/isql-route-mode.md. - For WebDAV publication and its out-of-scope boundary, read
references/webdav-publish-mode.md. - For the pipeline boundary (what this skill does and does not touch in
rdf/), readreferences/rdf-content-mode.md. - For why live SPARQL/VSP rendering was not chosen, read
references/webdav-website-engine-gate.md. - For agent-callable operations, read
references/opal-tool-mode.md— not implemented in v1; documented as the extension point.
Practical guardrails
- Never run
rdf/build.py's SHACL validation with warnings suppressed or--skip-validate-style shortcuts; a failing gate means the content is not ready to publish, not an obstacle to route around. DB.DBA.DAV_RES_UPLOAD_STRSES_INT(if used for any non-static-file step) needs astring_output()stream populated viahttp(content, stream), not a plain string.- Avoid
$1,$2, and similar tokens in any SQL loaded throughisql; they can trigger macro substitution. - A static-file
VHOST_DEFINEusesis_dav=>1,is_brws=>0,def_page=>'index.html'— do not setdef_page=>'index.vsp'unless a VSP entry point genuinely exists; adef_pagepointing at a nonexistent VSP resource serves raw source or a 404, not the site. - Delete any prior conflicting
VHOST_DEFINEfor the same host/path before redefining it, same asweblog-from-webdav's route-remove-then-redefine pattern. - Treat the certificate-bearing identity and the delegated principal as separate facts:
-X/--certidentifies the calling agent,-W/On-Behalf-Ofidentifies the WebID principal whose ACL rights should be evaluated. - Never write credentials into the skill, generated SQL, logs, or committed files.
- Remote uploads and removals follow the same HTTP → WebDAV → iSQL order and principal PKCS#12 pattern (
howto/remote-webdav-upload.ttl,howto/remote-resource-removal.ttl, prefs Steps 215–216). URIBurner writes/deletes go to port 5443. Report:5443GET and public 443 GET separately after PUT; after DELETE, verify the user-named URL, slash variants,:5443GET, and the folder listing before claiming removal.
Safe Virtuoso ISQL Error Output
Whenever this workflow invokes OpenLink's native Virtuoso isql client, pass the bare client option COMMAND_TEXT_ON_ERROR=OFF, for example isql {host}:{port} {user} {password} COMMAND_TEXT_ON_ERROR=OFF {script.sql}. Place it before SQL input, script arguments, or -i. OFF maps to the client's internal value 0 and prevents the client from appending the full failed command to error output. The client accepts OFF/ON; literal 0 is rejected. Do not use -u for this setting (-u populates the U argument array). This does not redact secrets from server diagnostics, shell history, or process arguments, so keep credentials out of SQL text and logs. Do not apply this Virtuoso-specific option to unixODBC/iODBC isql clients.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

