203 lines
7.2 KiB
Plaintext
203 lines
7.2 KiB
Plaintext
|
|
#!/usr/bin/env nu
|
||
|
|
# reflection/modules/forms.nu — form listing and execution.
|
||
|
|
#
|
||
|
|
# Error handling policy:
|
||
|
|
# forms list — daemon-export-safe; graceful skip on broken form file
|
||
|
|
# form run — daemon-export (fail loud); agent path renders NCL template via tera
|
||
|
|
# render-* — tera-render direct; fail loud on template error
|
||
|
|
|
||
|
|
use env.nu *
|
||
|
|
use store.nu [daemon-export, daemon-export-safe]
|
||
|
|
|
||
|
|
export def "forms list" [] {
|
||
|
|
form-files | each { |f|
|
||
|
|
let data = (daemon-export-safe $f)
|
||
|
|
if $data != null {
|
||
|
|
{
|
||
|
|
name: ($f | path basename | str replace ".ncl" ""),
|
||
|
|
description: ($data.description? | default ""),
|
||
|
|
}
|
||
|
|
} else { null }
|
||
|
|
} | compact
|
||
|
|
}
|
||
|
|
|
||
|
|
export def "form run" [
|
||
|
|
name: string,
|
||
|
|
--backend: string = "cli", # Backend: cli (default) | tui | web
|
||
|
|
] {
|
||
|
|
let actor = ($env.ONTOREF_ACTOR? | default "developer")
|
||
|
|
let forms_dir = $"($env.ONTOREF_ROOT)/reflection/forms"
|
||
|
|
let form_file = $"($forms_dir)/($name).ncl"
|
||
|
|
|
||
|
|
# Guard: form must exist
|
||
|
|
if not ($form_file | path exists) {
|
||
|
|
let available = (form-files | each { |f| $f | path basename | str replace ".ncl" "" })
|
||
|
|
print $"Form '($name)' not found."
|
||
|
|
print $"Available: ($available | str join ', ')"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
if $actor == "agent" {
|
||
|
|
agent-render $name $form_file
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
# Guard: typedialog must be present for interactive path
|
||
|
|
if (which typedialog | is-empty) {
|
||
|
|
print ""
|
||
|
|
print "typedialog is required for interactive forms."
|
||
|
|
print "Install: cargo install typedialog"
|
||
|
|
print ""
|
||
|
|
print "Agent path (no typedialog needed):"
|
||
|
|
agent-render-hint $name $form_file
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
run-interactive-form $name $form_file $backend
|
||
|
|
}
|
||
|
|
|
||
|
|
# Render an ADR from a piped record via tera-render.
|
||
|
|
# { id: "adr-005", title: "...", status: "Proposed" } | form render-adr | save adrs/adr-005-title.ncl
|
||
|
|
export def "form render-adr" [
|
||
|
|
--output: path,
|
||
|
|
] {
|
||
|
|
let tmpl = $"($env.ONTOREF_ROOT)/reflection/templates/adr.ncl.j2"
|
||
|
|
let rendered = $in | tera-render $tmpl
|
||
|
|
if ($output | is-not-empty) {
|
||
|
|
$rendered | save --force $output
|
||
|
|
print $"Written: ($output)"
|
||
|
|
} else {
|
||
|
|
$rendered
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Render a new-project script from a piped record via tera-render.
|
||
|
|
# { project_name: "myapp", project_dir: "/tmp/myapp" } | form render-project --output ~/create.nu
|
||
|
|
export def "form render-project" [
|
||
|
|
--output: path,
|
||
|
|
] {
|
||
|
|
let tmpl = $"($env.ONTOREF_ROOT)/reflection/templates/create_project.nu.j2"
|
||
|
|
let rendered = $in | tera-render $tmpl
|
||
|
|
if ($output | is-not-empty) {
|
||
|
|
$rendered | save --force $output
|
||
|
|
print $"Written: ($output)"
|
||
|
|
} else {
|
||
|
|
$rendered
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export def "forms help" [] {
|
||
|
|
let actor = ($env.ONTOREF_ACTOR? | default "developer")
|
||
|
|
print ""
|
||
|
|
print "Form commands:"
|
||
|
|
print " forms list list available forms"
|
||
|
|
print " form run <name> run a form (interactive or agent)"
|
||
|
|
print " form render-adr [--output <path>] render ADR from piped record"
|
||
|
|
print " form render-project [--output] render new-project script from piped record"
|
||
|
|
print ""
|
||
|
|
for f in (forms list) {
|
||
|
|
print $" ($f.name)"
|
||
|
|
print $" ($f.description)"
|
||
|
|
}
|
||
|
|
if $actor == "agent" {
|
||
|
|
print ""
|
||
|
|
print "Agent render pipeline:"
|
||
|
|
print " nickel-export adrs/_template.ncl | form render-adr --output adrs/adr-005-title.ncl"
|
||
|
|
print " { project_name: 'myapp', ... } | form render-project --output ~/create.nu"
|
||
|
|
print ""
|
||
|
|
print "Inspect form fields:"
|
||
|
|
print " nickel-export reflection/forms/<name>.ncl | get elements"
|
||
|
|
print " | where type != 'section_header' | select name prompt required nickel_path"
|
||
|
|
}
|
||
|
|
print ""
|
||
|
|
}
|
||
|
|
|
||
|
|
# ── Internal ───────────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
def form-files [] {
|
||
|
|
glob $"($env.ONTOREF_ROOT)/reflection/forms/*.ncl"
|
||
|
|
}
|
||
|
|
|
||
|
|
def next-adr-id [] {
|
||
|
|
let root = ($env.ONTOREF_PROJECT_ROOT? | default $env.ONTOREF_ROOT)
|
||
|
|
let nums = (
|
||
|
|
glob $"($root)/adrs/adr-*.ncl"
|
||
|
|
| each { |f| $f | path basename }
|
||
|
|
| parse "adr-{n}-{rest}.ncl"
|
||
|
|
| get n
|
||
|
|
| each { |n| $n | into int }
|
||
|
|
| sort
|
||
|
|
)
|
||
|
|
let next = if ($nums | is-empty) { 1 } else { ($nums | last) + 1 }
|
||
|
|
$"adr-($next | fill --alignment right --width 3 --character '0')"
|
||
|
|
}
|
||
|
|
|
||
|
|
def agent-render [name: string, form_file: string] {
|
||
|
|
if $name == "new_adr" {
|
||
|
|
let root = ($env.ONTOREF_PROJECT_ROOT? | default $env.ONTOREF_ROOT)
|
||
|
|
let template = $"($env.ONTOREF_ROOT)/adrs/_template.ncl"
|
||
|
|
let tmpl = $"($env.ONTOREF_ROOT)/reflection/templates/adr.ncl.j2"
|
||
|
|
let next_id = (next-adr-id)
|
||
|
|
let out = $"($root)/adrs/($next_id)-draft.ncl"
|
||
|
|
print $"Rendering ($next_id) from template — output: ($out)"
|
||
|
|
daemon-export $template | to json | tera-render $tmpl | save --force $out
|
||
|
|
print $"Run: nickel-validate ($out)"
|
||
|
|
} else {
|
||
|
|
agent-render-hint $name $form_file
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
def agent-render-hint [name: string, form_file: string] {
|
||
|
|
print ""
|
||
|
|
print $"Fields for '($name)':"
|
||
|
|
print $" nickel-export ($form_file) | get elements"
|
||
|
|
print " | where type != \"section_header\" | select name prompt required nickel_path"
|
||
|
|
print ""
|
||
|
|
}
|
||
|
|
|
||
|
|
def td-roundtrip [backend: string, input: string, form: string, output: string, ncl_template: string] {
|
||
|
|
match $backend {
|
||
|
|
"web" => { ^typedialog web nickel-roundtrip $input $form --output $output --ncl-template $ncl_template --open },
|
||
|
|
"tui" => { ^typedialog tui nickel-roundtrip $input $form --output $output --ncl-template $ncl_template },
|
||
|
|
_ => { ^typedialog nickel-roundtrip $input $form --output $output --ncl-template $ncl_template },
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
def td-form [backend: string, form: string, ...extra: string] {
|
||
|
|
match $backend {
|
||
|
|
"web" => { ^typedialog web form $form ...$extra },
|
||
|
|
"tui" => { ^typedialog tui $form ...$extra },
|
||
|
|
_ => { ^typedialog form $form ...$extra },
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
def run-interactive-form [name: string, form_file: string, backend: string] {
|
||
|
|
if $name == "new_adr" {
|
||
|
|
let root = ($env.ONTOREF_PROJECT_ROOT? | default $env.ONTOREF_ROOT)
|
||
|
|
let template = $"($env.ONTOREF_ROOT)/adrs/_template.ncl"
|
||
|
|
let tmpl = $"($env.ONTOREF_ROOT)/reflection/templates/adr.ncl.j2"
|
||
|
|
let next_id = (next-adr-id)
|
||
|
|
let out = $"($root)/adrs/($next_id)-draft.ncl"
|
||
|
|
let tmp = $"($env.HOME)/.ontoref-adr-tmp.ncl"
|
||
|
|
open $template | str replace '"adr-000"' $'"($next_id)"' | save --force $tmp
|
||
|
|
print $"Creating ($next_id) — output: ($out)"
|
||
|
|
td-roundtrip $backend $tmp $form_file $out $tmpl
|
||
|
|
rm --force $tmp
|
||
|
|
print $"Run: nickel typecheck ($out)"
|
||
|
|
} else if $name == "new_project" {
|
||
|
|
let tmpl = $"($env.ONTOREF_ROOT)/reflection/templates/create_project.nu.j2"
|
||
|
|
let out = $"($env.HOME)/ontoref-create-project.nu"
|
||
|
|
td-form $backend $form_file "--ncl-template" $tmpl "--output" $out
|
||
|
|
print $"Script generated: ($out)"
|
||
|
|
print $"Review then: nu ($out)"
|
||
|
|
} else if $name == "supersede_adr" {
|
||
|
|
let tmpl = $"($env.ONTOREF_ROOT)/reflection/templates/supersede_adr.nu.j2"
|
||
|
|
let out = $"($env.HOME)/ontoref-supersede.nu"
|
||
|
|
td-form $backend $form_file "--ncl-template" $tmpl "--output" $out
|
||
|
|
print $"Script generated: ($out)"
|
||
|
|
print $"Review then: nu ($out)"
|
||
|
|
} else {
|
||
|
|
td-form $backend $form_file
|
||
|
|
}
|
||
|
|
}
|