feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
--gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00
|
|
|
|
#!/usr/bin/env nu
|
|
|
|
|
|
# install/install.nu — ontoref-daemon installer
|
|
|
|
|
|
#
|
|
|
|
|
|
# Installed layout:
|
|
|
|
|
|
#
|
|
|
|
|
|
# ~/.local/bin/
|
|
|
|
|
|
# ontoref ← global CLI wrapper (install/ontoref-global)
|
|
|
|
|
|
# ontoref-daemon ← bootstrapper: nickel export | ontoref-daemon.bin (ADR-004)
|
|
|
|
|
|
# ontoref-daemon.bin ← compiled binary (not called directly)
|
|
|
|
|
|
#
|
|
|
|
|
|
# Platform data/config:
|
|
|
|
|
|
# macOS:
|
|
|
|
|
|
# data ~/Library/Application Support/ontoref/ templates, public, nulib
|
|
|
|
|
|
# config ~/.config/ontoref/
|
|
|
|
|
|
# Linux:
|
|
|
|
|
|
# data ~/.local/share/ontoref/
|
|
|
|
|
|
# config ~/.config/ontoref/
|
|
|
|
|
|
#
|
|
|
|
|
|
# Dev mode (Cargo.toml present + nu in PATH): also installs ncl-bootstrap Nu helper
|
|
|
|
|
|
# Service mode: bootstrapper is the sole entrypoint — .bin never called directly
|
|
|
|
|
|
|
|
|
|
|
|
def install-if-changed [src: string, dest: string, label: string] {
|
|
|
|
|
|
let needs_update = if ($dest | path exists) {
|
|
|
|
|
|
(open --raw $src | hash sha256) != (open --raw $dest | hash sha256)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
true
|
|
|
|
|
|
}
|
|
|
|
|
|
if $needs_update {
|
|
|
|
|
|
cp $src $dest
|
|
|
|
|
|
chmod +x $dest
|
|
|
|
|
|
print $"✓ ($label) ($dest)"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
print $"— ($label) unchanged"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def main [] {
|
|
|
|
|
|
let repo_root = $env.PWD
|
|
|
|
|
|
let is_dev = (("Cargo.toml" | path exists) and ((which nu | length) > 0))
|
|
|
|
|
|
|
|
|
|
|
|
let platform = (sys host | get name)
|
|
|
|
|
|
let is_mac = ((^uname) == "Darwin")
|
|
|
|
|
|
|
|
|
|
|
|
let data_dir = if $is_mac {
|
|
|
|
|
|
$"($env.HOME)/Library/Application Support/ontoref"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$"($env.HOME)/.local/share/ontoref"
|
|
|
|
|
|
}
|
|
|
|
|
|
let config_dir = $"($env.HOME)/.config/ontoref"
|
|
|
|
|
|
let bin_dir = $"($env.HOME)/.local/bin"
|
|
|
|
|
|
|
|
|
|
|
|
mkdir $bin_dir
|
|
|
|
|
|
|
|
|
|
|
|
# ── 1. Binary → ontoref-daemon.bin ────────────────────────────────────────
|
|
|
|
|
|
let bin_src = $"($repo_root)/target/release/ontoref-daemon"
|
|
|
|
|
|
let bin_dest = $"($bin_dir)/ontoref-daemon.bin"
|
|
|
|
|
|
|
|
|
|
|
|
if not ($bin_src | path exists) {
|
|
|
|
|
|
error make { msg: $"binary not found: ($bin_src)\n run: cargo build --release -p ontoref-daemon" }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Stop any running instance — macOS kills the new process if the old one holds the file
|
|
|
|
|
|
do { ^pkill -x ontoref-daemon.bin } | ignore
|
|
|
|
|
|
do { ^pkill -x ontoref-daemon } | ignore
|
|
|
|
|
|
|
|
|
|
|
|
cp $bin_src $bin_dest
|
|
|
|
|
|
chmod +x $bin_dest
|
|
|
|
|
|
|
2026-03-16 01:48:17 +00:00
|
|
|
|
#if $is_mac {
|
|
|
|
|
|
# do { ^xattr -d com.apple.quarantine $bin_dest } | ignore
|
|
|
|
|
|
#}
|
feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
--gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00
|
|
|
|
|
|
|
|
|
|
print $"✓ binary ($bin_dest)"
|
|
|
|
|
|
|
|
|
|
|
|
# ── 2. Bootstrapper → ontoref-daemon ──────────────────────────────────────
|
|
|
|
|
|
# The bootstrapper IS the public entrypoint. Users call ontoref-daemon, never .bin directly.
|
|
|
|
|
|
let boot_src = $"($repo_root)/install/ontoref-daemon-boot"
|
|
|
|
|
|
let boot_dest = $"($bin_dir)/ontoref-daemon"
|
|
|
|
|
|
|
|
|
|
|
|
install-if-changed $boot_src $boot_dest "bootstrapper"
|
|
|
|
|
|
|
|
|
|
|
|
# ── 3. Global CLI wrapper → ontoref ───────────────────────────────────────
|
2026-03-14 09:38:40 +00:00
|
|
|
|
# Bake the data dir as ONTOREF_ROOT so the installed wrapper is self-contained
|
|
|
|
|
|
# and does not require the source repo to be present at runtime.
|
feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
--gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00
|
|
|
|
let cli_src = $"($repo_root)/install/ontoref-global"
|
|
|
|
|
|
let cli_dest = $"($bin_dir)/ontoref"
|
|
|
|
|
|
let cli_baked = (
|
|
|
|
|
|
open --raw $cli_src
|
2026-03-14 09:38:40 +00:00
|
|
|
|
| str replace 'ONTOREF_ROOT="${ONTOREF_ROOT:-ontoref}"' $'ONTOREF_ROOT="${ONTOREF_ROOT:-($data_dir)}"'
|
feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
--gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
let needs_update = if ($cli_dest | path exists) {
|
|
|
|
|
|
($cli_baked | hash sha256) != (open --raw $cli_dest | hash sha256)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if $needs_update {
|
|
|
|
|
|
$cli_baked | save --force $cli_dest
|
|
|
|
|
|
chmod +x $cli_dest
|
|
|
|
|
|
print $"✓ cli ($cli_dest)"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
print $"— cli unchanged"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-14 09:38:40 +00:00
|
|
|
|
# ── 3b. Reflection scripts (data dir) ─────────────────────────────────────
|
|
|
|
|
|
# The global CLI wrapper calls $data_dir/reflection/bin/ontoref.nu directly.
|
|
|
|
|
|
# Copy the entire reflection/ tree so the install is autonomous (no dev repo needed).
|
|
|
|
|
|
let reflection_src = $"($repo_root)/reflection"
|
|
|
|
|
|
let reflection_dest = $"($data_dir)/reflection"
|
|
|
|
|
|
|
|
|
|
|
|
if not ($reflection_src | path exists) {
|
|
|
|
|
|
error make { msg: $"reflection/ not found: ($reflection_src)" }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mkdir $reflection_dest
|
|
|
|
|
|
mut refl_updated = 0
|
|
|
|
|
|
mut refl_skipped = 0
|
|
|
|
|
|
for src_file in (glob $"($reflection_src)/**/*" | where { |f| ($f | path type) == "file" }) {
|
|
|
|
|
|
let rel = ($src_file | str replace $"($reflection_src)/" "")
|
|
|
|
|
|
let dest_file = $"($reflection_dest)/($rel)"
|
|
|
|
|
|
let dest_parent = ($dest_file | path dirname)
|
|
|
|
|
|
mkdir $dest_parent
|
|
|
|
|
|
let needs_update = if ($dest_file | path exists) {
|
|
|
|
|
|
(open --raw $src_file | hash sha256) != (open --raw $dest_file | hash sha256)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
true
|
|
|
|
|
|
}
|
|
|
|
|
|
if $needs_update {
|
|
|
|
|
|
cp $src_file $dest_file
|
|
|
|
|
|
$refl_updated = $refl_updated + 1
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$refl_skipped = $refl_skipped + 1
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
print $"✓ reflection ($reflection_dest)/ updated=($refl_updated) unchanged=($refl_skipped)"
|
|
|
|
|
|
|
feat: domain extension system, VCS abstraction, personal/provisioning domains, web subpages
Domain extension system (ADR-012): bash-layer dispatch activates repo_kind-conditional CLI
domains. install.nu copies domains/ tree; short_alias wrappers generated (personal, prov).
ore help and describe capabilities domain-aware.
personal domain (PersonalOntology): career skills/talks/publications/positioning, CFP
pipeline (Watching→Delivered), opportunities lifecycle, content pipeline, Sessionize
integration. Daemon pages: /career, /personal.
provisioning domain (DevWorkspace/Mixed): FSM state, next transitions, connections graph,
gates, workspace card, capabilities, backlog. Daemon page: /provisioning.
VCS abstraction layer (ADR-013): reflection/modules/vcs.nu — uniform jj/git API via
filesystem detection (.jj/ vs .git/). opmode.nu and git-event.nu migrated off ^git.
reflection/bin/jjw.nu — jj + ontoref + Radicle agent workspace lifecycle. jjw-ncl-merge.nu
registered as jj merge tool for .ontology/ NCL conflicts. init-repo.nu for new_project mode.
jj/rad not in ontoref requirements — belong in orchestration project manifests.
'Framework RepoKind: ontology/schemas/manifest.ncl gains 'Framework variant; ontoref
self-identifies as framework — no domain activates for the protocol itself.
Web presence: personal.html and provisioning.html domain subpages. index.html gains
"Project Types — Domain Extensions" section with type cards and subpage links. Nav
compacted (Arch/Prov labels, solid backdrop-filter background).
on+re: vcs-abstraction (adrs: adr-013) and agent-workspace-orchestration Practice nodes;
21 manifest capabilities; state.ncl catalysts updated.
2026-04-07 23:08:29 +01:00
|
|
|
|
# ── 3c. Domain extensions (domains/) ─────────────────────────────────────
|
|
|
|
|
|
# Domain commands are dispatched by the bash wrapper at runtime from $ONTOREF_ROOT/domains/.
|
|
|
|
|
|
let domains_src = $"($repo_root)/domains"
|
|
|
|
|
|
let domains_dest = $"($data_dir)/domains"
|
|
|
|
|
|
|
|
|
|
|
|
if ($domains_src | path exists) {
|
|
|
|
|
|
mkdir $domains_dest
|
|
|
|
|
|
mut dom_updated = 0
|
|
|
|
|
|
mut dom_skipped = 0
|
|
|
|
|
|
for src_file in (glob $"($domains_src)/**/*" | where { |f| ($f | path type) == "file" }) {
|
|
|
|
|
|
let rel = ($src_file | str replace $"($domains_src)/" "")
|
|
|
|
|
|
let dest_file = $"($domains_dest)/($rel)"
|
|
|
|
|
|
let dest_parent = ($dest_file | path dirname)
|
|
|
|
|
|
mkdir $dest_parent
|
|
|
|
|
|
let needs_update = if ($dest_file | path exists) {
|
|
|
|
|
|
(open --raw $src_file | hash sha256) != (open --raw $dest_file | hash sha256)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
true
|
|
|
|
|
|
}
|
|
|
|
|
|
if $needs_update {
|
|
|
|
|
|
cp $src_file $dest_file
|
|
|
|
|
|
$dom_updated = $dom_updated + 1
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$dom_skipped = $dom_skipped + 1
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
print $"✓ domains ($domains_dest)/ updated=($dom_updated) unchanged=($dom_skipped)"
|
|
|
|
|
|
|
|
|
|
|
|
# Build aliases.txt and install short_alias bin wrappers for each domain.
|
|
|
|
|
|
mut alias_lines = []
|
|
|
|
|
|
for domain_dir in (ls $domains_src | where type == "dir" | get name) {
|
|
|
|
|
|
let domain_ncl = $"($domain_dir)/domain.ncl"
|
|
|
|
|
|
if not ($domain_ncl | path exists) { continue }
|
|
|
|
|
|
let domain_data = (do { ^nickel export $domain_ncl } | complete)
|
|
|
|
|
|
if $domain_data.exit_code != 0 { continue }
|
|
|
|
|
|
let d = ($domain_data.stdout | from json)
|
|
|
|
|
|
let alias = ($d.short_alias? | default "")
|
|
|
|
|
|
let domain_id = ($d.id? | default "")
|
|
|
|
|
|
if ($alias | is-empty) { continue }
|
|
|
|
|
|
|
|
|
|
|
|
# aliases.txt entry — only when alias differs from domain id (e.g. prov → provisioning)
|
|
|
|
|
|
# skipped when alias == domain_id (e.g. personal → personal): ore already handles it natively
|
|
|
|
|
|
if $alias != $domain_id {
|
|
|
|
|
|
$alias_lines = ($alias_lines | append $"($alias)=($domain_id)")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# standalone bin wrapper — always created when short_alias is set,
|
|
|
|
|
|
# even when alias == domain_id, so `personal state` works without `ore`
|
|
|
|
|
|
let alias_dest = $"($bin_dir)/($alias)"
|
|
|
|
|
|
let alias_body = $"#!/bin/bash\nexec ontoref ($domain_id) \"$@\"\n"
|
|
|
|
|
|
let needs_update = if ($alias_dest | path exists) {
|
|
|
|
|
|
($alias_body | hash sha256) != (open --raw $alias_dest | hash sha256)
|
|
|
|
|
|
} else { true }
|
|
|
|
|
|
if $needs_update {
|
|
|
|
|
|
$alias_body | save --force $alias_dest
|
|
|
|
|
|
chmod +x $alias_dest
|
|
|
|
|
|
print $"✓ alias ($alias_dest) → ontoref ($domain_id)"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
print $"— alias ($alias) unchanged"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Write consolidated aliases.txt to the installed domains dir
|
|
|
|
|
|
let aliases_dest = $"($domains_dest)/aliases.txt"
|
|
|
|
|
|
if ($alias_lines | is-not-empty) {
|
|
|
|
|
|
let aliases_body = ($alias_lines | str join "\n")
|
|
|
|
|
|
let needs_update = if ($aliases_dest | path exists) {
|
|
|
|
|
|
($aliases_body | hash sha256) != (open --raw $aliases_dest | hash sha256)
|
|
|
|
|
|
} else { true }
|
|
|
|
|
|
if $needs_update {
|
|
|
|
|
|
$aliases_body | save --force $aliases_dest
|
|
|
|
|
|
print $"✓ domain-aliases ($aliases_dest)"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
print $"— domain-aliases unchanged"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
print $" (ansi yellow)warn(ansi reset) domains/ not found at ($domains_src)"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# ── 3d. CLI templates (project.ncl, ontoref-config.ncl, ontology/ stubs) ──
|
2026-03-16 01:48:17 +00:00
|
|
|
|
# `ontoref setup` reads from $ONTOREF_ROOT/templates/ — copy the repo-level
|
|
|
|
|
|
# templates/ tree so the installed CLI works without the source repo present.
|
|
|
|
|
|
let cli_templates_src = $"($repo_root)/templates"
|
|
|
|
|
|
let cli_templates_dest = $"($data_dir)/templates"
|
|
|
|
|
|
|
|
|
|
|
|
if ($cli_templates_src | path exists) {
|
|
|
|
|
|
mkdir $cli_templates_dest
|
|
|
|
|
|
mut tmpl_updated = 0
|
|
|
|
|
|
mut tmpl_skipped = 0
|
|
|
|
|
|
for src_file in (glob $"($cli_templates_src)/**/*" | where { |f| ($f | path type) == "file" }) {
|
|
|
|
|
|
let rel = ($src_file | str replace $"($cli_templates_src)/" "")
|
|
|
|
|
|
let dest_file = $"($cli_templates_dest)/($rel)"
|
|
|
|
|
|
let dest_parent = ($dest_file | path dirname)
|
|
|
|
|
|
mkdir $dest_parent
|
|
|
|
|
|
let needs_update = if ($dest_file | path exists) {
|
|
|
|
|
|
(open --raw $src_file | hash sha256) != (open --raw $dest_file | hash sha256)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
true
|
|
|
|
|
|
}
|
|
|
|
|
|
if $needs_update {
|
|
|
|
|
|
cp $src_file $dest_file
|
|
|
|
|
|
$tmpl_updated = $tmpl_updated + 1
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$tmpl_skipped = $tmpl_skipped + 1
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
print $"✓ cli-templates ($cli_templates_dest)/ updated=($tmpl_updated) unchanged=($tmpl_skipped)"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
print $" (ansi yellow)warn(ansi reset) templates/ not found at ($cli_templates_src)"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: domain extension system, VCS abstraction, personal/provisioning domains, web subpages
Domain extension system (ADR-012): bash-layer dispatch activates repo_kind-conditional CLI
domains. install.nu copies domains/ tree; short_alias wrappers generated (personal, prov).
ore help and describe capabilities domain-aware.
personal domain (PersonalOntology): career skills/talks/publications/positioning, CFP
pipeline (Watching→Delivered), opportunities lifecycle, content pipeline, Sessionize
integration. Daemon pages: /career, /personal.
provisioning domain (DevWorkspace/Mixed): FSM state, next transitions, connections graph,
gates, workspace card, capabilities, backlog. Daemon page: /provisioning.
VCS abstraction layer (ADR-013): reflection/modules/vcs.nu — uniform jj/git API via
filesystem detection (.jj/ vs .git/). opmode.nu and git-event.nu migrated off ^git.
reflection/bin/jjw.nu — jj + ontoref + Radicle agent workspace lifecycle. jjw-ncl-merge.nu
registered as jj merge tool for .ontology/ NCL conflicts. init-repo.nu for new_project mode.
jj/rad not in ontoref requirements — belong in orchestration project manifests.
'Framework RepoKind: ontology/schemas/manifest.ncl gains 'Framework variant; ontoref
self-identifies as framework — no domain activates for the protocol itself.
Web presence: personal.html and provisioning.html domain subpages. index.html gains
"Project Types — Domain Extensions" section with type cards and subpage links. Nav
compacted (Arch/Prov labels, solid backdrop-filter background).
on+re: vcs-abstraction (adrs: adr-013) and agent-workspace-orchestration Practice nodes;
21 manifest capabilities; state.ncl catalysts updated.
2026-04-07 23:08:29 +01:00
|
|
|
|
# ── 3e. Ontology defaults + schemas (data dir) ───────────────────────────
|
|
|
|
|
|
# Consumer projects import "ontology/defaults/state.ncl", "defaults/manifest.ncl", etc.
|
|
|
|
|
|
# These must be resolvable from $ONTOREF_ROOT (the data dir).
|
|
|
|
|
|
# Structure: $data_dir/ontology/{defaults,schemas}/
|
|
|
|
|
|
# The bash wrapper includes $ONTOREF_ROOT in NICKEL_IMPORT_PATH, so:
|
|
|
|
|
|
# import "ontology/defaults/state.ncl" → $data_dir/ontology/defaults/state.ncl ✓
|
|
|
|
|
|
# import "defaults/state.ncl" → $data_dir/ontology/defaults/state.ncl ✓ (via $ONTOREF_ROOT/ontology in nickel-import-path)
|
|
|
|
|
|
let ontology_src = $"($repo_root)/ontology"
|
|
|
|
|
|
let ontology_dest = $"($data_dir)/ontology"
|
|
|
|
|
|
if ($ontology_src | path exists) {
|
|
|
|
|
|
mkdir $ontology_dest
|
|
|
|
|
|
mut ont_updated = 0
|
|
|
|
|
|
mut ont_skipped = 0
|
|
|
|
|
|
for src_file in (glob $"($ontology_src)/**/*.ncl" | where { |f| ($f | path type) == "file" }) {
|
|
|
|
|
|
let rel = ($src_file | str replace $"($ontology_src)/" "")
|
|
|
|
|
|
let dest_file = $"($ontology_dest)/($rel)"
|
|
|
|
|
|
let dest_parent = ($dest_file | path dirname)
|
|
|
|
|
|
mkdir $dest_parent
|
|
|
|
|
|
let needs_update = if ($dest_file | path exists) {
|
|
|
|
|
|
(open --raw $src_file | hash sha256) != (open --raw $dest_file | hash sha256)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
true
|
|
|
|
|
|
}
|
|
|
|
|
|
if $needs_update { cp $src_file $dest_file; $ont_updated = $ont_updated + 1 } else { $ont_skipped = $ont_skipped + 1 }
|
|
|
|
|
|
}
|
|
|
|
|
|
print $"✓ ontology ($ontology_dest)/ updated=($ont_updated) unchanged=($ont_skipped)"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
--gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00
|
|
|
|
# ── 4. UI assets (data dir) ────────────────────────────────────────────────
|
|
|
|
|
|
let templates_src = $"($repo_root)/crates/ontoref-daemon/templates"
|
|
|
|
|
|
let public_src = $"($repo_root)/crates/ontoref-daemon/public"
|
|
|
|
|
|
|
|
|
|
|
|
if not ($templates_src | path exists) {
|
|
|
|
|
|
error make { msg: $"templates not found: ($templates_src)" }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mkdir $data_dir
|
|
|
|
|
|
|
2026-03-13 23:28:41 +00:00
|
|
|
|
let asset_dirs = [$templates_src $public_src]
|
|
|
|
|
|
mut updated = 0
|
|
|
|
|
|
mut skipped = 0
|
|
|
|
|
|
|
|
|
|
|
|
for asset_dir in $asset_dirs {
|
|
|
|
|
|
let dir_name = ($asset_dir | path basename)
|
|
|
|
|
|
let dest_base = $"($data_dir)/($dir_name)"
|
|
|
|
|
|
mkdir $dest_base
|
|
|
|
|
|
for src_file in (glob $"($asset_dir)/**/*" | where { |f| ($f | path type) == "file" }) {
|
|
|
|
|
|
let rel = ($src_file | str replace $"($asset_dir)/" "")
|
|
|
|
|
|
let dest_file = $"($dest_base)/($rel)"
|
|
|
|
|
|
let dest_parent = ($dest_file | path dirname)
|
|
|
|
|
|
mkdir $dest_parent
|
|
|
|
|
|
let needs_update = if ($dest_file | path exists) {
|
|
|
|
|
|
(open --raw $src_file | hash sha256) != (open --raw $dest_file | hash sha256)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
true
|
|
|
|
|
|
}
|
|
|
|
|
|
if $needs_update {
|
|
|
|
|
|
cp $src_file $dest_file
|
|
|
|
|
|
$updated = $updated + 1
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$skipped = $skipped + 1
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
print $"✓ assets ($data_dir)/ updated=($updated) unchanged=($skipped)"
|
feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
--gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00
|
|
|
|
|
|
|
|
|
|
# ── 5. Config skeleton + global NATS topology ─────────────────────────────
|
|
|
|
|
|
let streams_default = $"($repo_root)/install/resources/streams.json"
|
|
|
|
|
|
let streams_dest = $"($config_dir)/streams.json"
|
|
|
|
|
|
|
|
|
|
|
|
if ($streams_default | path exists) {
|
|
|
|
|
|
mkdir $config_dir
|
|
|
|
|
|
if not ($streams_dest | path exists) {
|
|
|
|
|
|
cp $streams_default $streams_dest
|
|
|
|
|
|
print $"✓ nats topology ($streams_dest)"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
print $"— nats topology unchanged"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let config_default = $"($repo_root)/install/resources/config.ncl"
|
|
|
|
|
|
let config_dest = $"($config_dir)/config.ncl"
|
|
|
|
|
|
let config_example = $"($config_dir)/config.ncl.example"
|
|
|
|
|
|
|
|
|
|
|
|
if ($config_default | path exists) {
|
|
|
|
|
|
mkdir $config_dir
|
|
|
|
|
|
cp $config_default $config_example
|
|
|
|
|
|
|
|
|
|
|
|
if ($config_dest | path exists) {
|
|
|
|
|
|
print $"ℹ config already exists — not overwritten"
|
|
|
|
|
|
print $" example kept: ($config_example)"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
cp $config_default $config_dest
|
|
|
|
|
|
print $"✓ config ($config_dest)"
|
|
|
|
|
|
print $" edit with: ontoref config-edit"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# projects.ncl — local projects; populated by `ontoref project-add`
|
|
|
|
|
|
let projects_default = $"($repo_root)/install/resources/projects.ncl"
|
|
|
|
|
|
let projects_dest = $"($config_dir)/projects.ncl"
|
|
|
|
|
|
|
|
|
|
|
|
if ($projects_default | path exists) and not ($projects_dest | path exists) {
|
|
|
|
|
|
cp $projects_default $projects_dest
|
|
|
|
|
|
print $"✓ projects ($projects_dest)"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# remote-projects.ncl — remote/push-only projects; populated by `ontoref project-add-remote`
|
|
|
|
|
|
let remote_default = $"($repo_root)/install/resources/remote-projects.ncl"
|
|
|
|
|
|
let remote_dest = $"($config_dir)/remote-projects.ncl"
|
|
|
|
|
|
|
|
|
|
|
|
if ($remote_default | path exists) and not ($remote_dest | path exists) {
|
|
|
|
|
|
cp $remote_default $remote_dest
|
|
|
|
|
|
print $"✓ remote-projects ($remote_dest)"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# schemas/ — project contract schemas imported by per-project .ontoref/project.ncl
|
|
|
|
|
|
let schemas_src = $"($repo_root)/install/resources/schemas"
|
|
|
|
|
|
let schemas_dest = $"($config_dir)/schemas"
|
|
|
|
|
|
|
|
|
|
|
|
if ($schemas_src | path exists) {
|
|
|
|
|
|
mkdir $schemas_dest
|
|
|
|
|
|
for f in (ls $schemas_src | get name) {
|
|
|
|
|
|
let dest_f = $"($schemas_dest)/(($f | path basename))"
|
|
|
|
|
|
if not ($dest_f | path exists) {
|
|
|
|
|
|
cp $f $dest_f
|
|
|
|
|
|
print $"✓ schema ($dest_f)"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-16 01:48:17 +00:00
|
|
|
|
# ── 6. Install scripts (gen-projects.nu, etc.) + hooks ────────────────────
|
|
|
|
|
|
# The bootstrapper looks for *.nu at $data_dir/install/.
|
|
|
|
|
|
# `ontoref hooks-install` looks for install/hooks/{post-commit,post-merge}.
|
feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
--gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00
|
|
|
|
let install_dest = $"($data_dir)/install"
|
|
|
|
|
|
mkdir $install_dest
|
|
|
|
|
|
for f in (glob $"($repo_root)/install/*.nu") {
|
|
|
|
|
|
let dest_f = $"($install_dest)/(($f | path basename))"
|
|
|
|
|
|
install-if-changed $f $dest_f $"install/(($f | path basename))"
|
|
|
|
|
|
}
|
2026-03-16 01:48:17 +00:00
|
|
|
|
let hooks_src = $"($repo_root)/install/hooks"
|
|
|
|
|
|
let hooks_dest = $"($install_dest)/hooks"
|
|
|
|
|
|
if ($hooks_src | path exists) {
|
|
|
|
|
|
mkdir $hooks_dest
|
|
|
|
|
|
for f in (glob $"($hooks_src)/*" | where { |p| ($p | path type) == "file" }) {
|
|
|
|
|
|
let dest_f = $"($hooks_dest)/(($f | path basename))"
|
|
|
|
|
|
install-if-changed $f $dest_f $"install/hooks/(($f | path basename))"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
--gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00
|
|
|
|
|
|
|
|
|
|
# ── 7. Dev extras: ncl-bootstrap Nu helper ────────────────────────────────
|
|
|
|
|
|
if $is_dev {
|
|
|
|
|
|
let nulib_dest = $"($data_dir)/nulib"
|
|
|
|
|
|
mkdir $nulib_dest
|
|
|
|
|
|
cp $"($repo_root)/reflection/nulib/bootstrap.nu" $"($nulib_dest)/bootstrap.nu"
|
|
|
|
|
|
print $"✓ ncl-bootstrap ($nulib_dest)/bootstrap.nu"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# ── Summary ────────────────────────────────────────────────────────────────
|
|
|
|
|
|
let mode_tag = if $is_dev { "dev" } else { "service" }
|
|
|
|
|
|
print $"\ninstalled mode=($mode_tag) platform=($platform)"
|
|
|
|
|
|
print $" bin ($bin_dir)/ontoref, ontoref-daemon, ontoref-daemon.bin"
|
feat: domain extension system, VCS abstraction, personal/provisioning domains, web subpages
Domain extension system (ADR-012): bash-layer dispatch activates repo_kind-conditional CLI
domains. install.nu copies domains/ tree; short_alias wrappers generated (personal, prov).
ore help and describe capabilities domain-aware.
personal domain (PersonalOntology): career skills/talks/publications/positioning, CFP
pipeline (Watching→Delivered), opportunities lifecycle, content pipeline, Sessionize
integration. Daemon pages: /career, /personal.
provisioning domain (DevWorkspace/Mixed): FSM state, next transitions, connections graph,
gates, workspace card, capabilities, backlog. Daemon page: /provisioning.
VCS abstraction layer (ADR-013): reflection/modules/vcs.nu — uniform jj/git API via
filesystem detection (.jj/ vs .git/). opmode.nu and git-event.nu migrated off ^git.
reflection/bin/jjw.nu — jj + ontoref + Radicle agent workspace lifecycle. jjw-ncl-merge.nu
registered as jj merge tool for .ontology/ NCL conflicts. init-repo.nu for new_project mode.
jj/rad not in ontoref requirements — belong in orchestration project manifests.
'Framework RepoKind: ontology/schemas/manifest.ncl gains 'Framework variant; ontoref
self-identifies as framework — no domain activates for the protocol itself.
Web presence: personal.html and provisioning.html domain subpages. index.html gains
"Project Types — Domain Extensions" section with type cards and subpage links. Nav
compacted (Arch/Prov labels, solid backdrop-filter background).
on+re: vcs-abstraction (adrs: adr-013) and agent-workspace-orchestration Practice nodes;
21 manifest capabilities; state.ncl catalysts updated.
2026-04-07 23:08:29 +01:00
|
|
|
|
print $" data ($data_dir)/ \(reflection/, domains/, templates/, ...\)"
|
feat: unified auth model, project onboarding, install pipeline, config management
The full scope across this batch: POST /sessions key→token exchange, SessionStore dual-index with revoke_by_id, CLI Bearer injection (ONTOREF_TOKEN), ontoref setup
--gen-keys, install scripts, daemon config form roundtrip, ADR-004/005, on+re self-description update (fully-self-described), and landing page refresh.
2026-03-13 20:56:31 +00:00
|
|
|
|
print $" config ($config_dir)/"
|
|
|
|
|
|
print ""
|
|
|
|
|
|
print " next: nu install/config-setup.nu"
|
|
|
|
|
|
}
|