#!/usr/bin/env nu
# Project the ontology (core.ncl) into a SELF-CONTAINED, navigable Cytoscape graph
# page. This is the interactive "prize" the About graph block links to (ADR-057
# hook-static / prize-live) — but daemon-free: the data is embedded and the page
# uses the cytoscape libs already shipped under /js/. The site's own /graph
# (Leptos GraphView) renders an empty canvas under htmx-ssr (no WASM hydration),
# so we ship our own page instead.
#
# Served as a static file at /images/ontoref-graph.html (only /images, /js, /styles
# are static-served; bare paths are intercepted by the content router).
#
# Usage (from outreach/site):
# nu scripts/build/gen-graph-page.nu --root ../.. --out site/public/images/ontoref-graph.html
const TEMPLATE = r##'
ontoref · ontology graph
Axioms · __NAX__
Tensions · __NTN__
Practices · __NPR__
drag to pan · scroll to zoom · click a node to focus · click empty space to reset
'##
def main [
--root: string = "../.."
--out: string = "site/public/images/ontoref-graph.html"
] {
let ip = $"($root)/code/ontology"
let core = $"($root)/.ontoref/ontology/core.ncl"
if not ($core | path exists) { error make { msg: $"core.ncl not found: ($core)" } }
let graph = (nickel export --format json --import-path $ip $core | from json)
let nodes = ($graph | get nodes)
let edges = ($graph.edges? | default [])
let ids = ($nodes | each {|n| $n.id? | default "" } | where {|x| $x | is-not-empty })
let node_els = ($nodes | each {|n| { data: {
id: ($n.id? | default ""),
title: ($n.name? | default ($n.id? | default "")),
level: ($n.level? | default "Practice"),
} } })
let edge_els = ($edges | where {|e| (($e.from? | default "") in $ids) and (($e.to? | default "") in $ids) } | each {|e| { data: {
id: $"($e.from)__($e.to)__($e.kind? | default 'rel')",
source: ($e.from? | default ""),
target: ($e.to? | default ""),
kind: ($e.kind? | default ""),
} } })
let elements = ($node_els | append $edge_els | to json --raw)
let nax = ($nodes | where {|n| ($n.level? | default "") == "Axiom" } | length)
let ntn = ($nodes | where {|n| ($n.level? | default "") == "Tension" } | length)
let npr = ($nodes | where {|n| ($n.level? | default "") == "Practice" } | length)
let html = ($TEMPLATE
| str replace --all '__NCOUNT__' ($nodes | length | into string)
| str replace --all '__ECOUNT__' ($edge_els | length | into string)
| str replace --all '__NAX__' ($nax | into string)
| str replace --all '__NTN__' ($ntn | into string)
| str replace --all '__NPR__' ($npr | into string)
| str replace '/*__ELEMENTS__*/' $elements)
let parent = ($out | path dirname)
if ($parent | is-not-empty) { mkdir $parent }
$html | save -f $out
print $"gen-graph-page: ($nodes | length) nodes · ($edge_els | length) edges → ($out)"
}