Jesús Pérez 85ce530733
feat: update provisioning core CLI, libraries, and plugins
Update core components including CLI, Nushell libraries, plugins system,
and utility scripts for the provisioning system.

CLI Updates:
- Command implementations
- CLI utilities and dispatching
- Help system improvements
- Command validation

Library Updates:
- Configuration management system
- Infrastructure validation
- Extension system improvements
- Secrets management
- Workspace operations
- Cache management system

Plugin System:
- Interactive form plugin (inquire)
- KCL integration plugin
- Performance optimization plugins
- Plugin registration system

Utilities:
- Build and distribution scripts
- Installation procedures
- Testing utilities
- Development tools

Documentation:
- Library module documentation
- Extension API guides
- Plugin usage guides
- Service management documentation

All changes are backward compatible. No breaking changes.
2025-12-11 21:57:05 +00:00
..

FormInquire Integration System

Dynamic form generation using Jinja2 templates rendered with nu_plugin_tera.

Architecture

provisioning/core/forminquire/
├── templates/                      # Jinja2 form templates (.j2)
│   ├── setup-wizard.form.j2
│   ├── workspace-init.form.j2
│   ├── settings-update.form.j2
│   ├── server-delete-confirm.form.j2
│   └── ...more templates
├── nulib/
│   └── forminquire.nu             # Nushell integration functions
└── wrappers/
    └── form.sh                    # Bash wrapper for FormInquire

How It Works

  1. Template Rendering: Jinja2 templates are rendered with data from config files
  2. Form Generation: Rendered templates are saved as TOML forms in cache
  3. User Interaction: FormInquire binary presents the form to user
  4. Result Processing: JSON output from FormInquire is returned to calling code
Config Data → Template Rendering → Form Generation → FormInquire → JSON Output
             (nu_plugin_tera)      (cache: ~/.cache/)  (interactive)

Quick Examples

Settings Update with Current Values as Defaults

use provisioning/core/forminquire/nulib/forminquire.nu *

# Load current settings and show form with them as defaults
let result = (settings-update-form)

if $result.success {
    # Process updated settings
    print $"Updated: ($result.values | to json)"
}

Setup Wizard

let result = (setup-wizard-form)

if $result.success {
    print "Setup configuration:"
    print ($result.values | to json)
}

Workspace Initialization

let result = (workspace-init-form "my-workspace")

if $result.success {
    print "Workspace created with settings:"
    print ($result.values | to json)
}

Server Delete Confirmation

let confirm = (server-delete-confirm-form "web-01" "192.168.1.10" "running")

if $confirm.success {
    let confirmation_text = $confirm.values.confirmation_text
    let final_confirm = $confirm.values.final_confirm

    if ($confirmation_text == "web-01" and $final_confirm) {
        print "Deleting server..."
    }
}

Template Variables

All templates have access to:

Automatic Variables (always available)

  • now_iso: Current timestamp in ISO 8601 format
  • home_dir: User's home directory
  • username: Current username
  • provisioning_root: Provisioning root directory

Custom Variables (passed per form)

  • Settings from config.defaults.toml
  • User preferences from ~/.config/provisioning/user_config.yaml
  • Workspace configuration from workspace config.toml
  • Any custom data passed to the form function

Cache Management

Forms are cached at: ~/.cache/provisioning/forms/

Cleanup Old Forms

let cleanup_result = (cleanup-form-cache)
print $"Cleaned up ($cleanup_result.cleaned) old form files"

List Generated Forms

list-cached-forms

Template Syntax

Templates use Jinja2 syntax with macros for common form elements:

[items.my_field]
type = "text"
prompt = "Enter value"
default = "{{ my_variable }}"
help = "Help text here"
required = true

Available Form Types

  • text: Text input
  • select: Dropdown selection
  • confirm: Yes/No confirmation
  • password: Masked password input
  • multiselect: Multiple selection

Available Functions

Form Execution

  • interactive-form [name] [template] [data] - Complete form flow
  • render-template [template_name] [data] - Render template only
  • generate-form [form_name] [template_name] [data] - Generate TOML form
  • run-form [form_path] - Execute FormInquire with form

Config Loading

  • load-user-preferences - Load user preferences from config
  • load-workspace-config [workspace_name] - Load workspace settings
  • load-system-defaults - Load system defaults
  • get-form-context [workspace_name] [custom_data] - Merged config context

Convenience Functions

  • settings-update-form - Update system settings
  • setup-wizard-form - Run setup wizard
  • workspace-init-form [name] - Initialize workspace
  • server-delete-confirm-form [name] [ip] [status] - Delete confirmation

Utilities

  • list-templates - List available templates
  • list-cached-forms - List generated forms in cache
  • cleanup-form-cache - Remove old cached forms

Shell Integration

Use the bash wrapper for shell scripts:

#!/bin/bash

# Generate form with Nushell
nu -c "use forminquire *; interactive-form 'my-form' 'my-template' {foo: 'bar'}" > /tmp/form.toml

# Or use form.sh wrapper directly
./provisioning/core/forminquire/wrappers/form.sh /path/to/form.toml json

Performance Notes

  • First form: ~200ms (template rendering + form generation)
  • Subsequent forms: ~50ms (cached config loading)
  • User interaction: Depends on FormInquire response time
  • Form cache: Automatically cleaned after 1+ days

Dependencies

  • forminquire - FormInquire binary (in PATH)
  • nu_plugin_tera - Nushell Jinja2 template plugin
  • Nushell 0.109.0+ - Core scripting language

Error Handling

All functions return structured results:

{
    success: bool          # Operation succeeded
    error: string          # Error message (empty if success)
    form_path: string      # Generated form path (if applicable)
    values: record         # FormInquire output values
}

Adding New Forms

  1. Create template in templates/ with .form.j2 extension
  2. Create convenience function in forminquire.nu like my-form-function
  3. Use in scripts: my-form-function [args...]

Example:

# templates/my-form.form.j2
[meta]
title = "My Custom Form"
[items.field1]
type = "text"
prompt = "Enter value"
default = "{{ default_value }}"
# In forminquire.nu
export def my-form-function [default_value: string = ""] {
    interactive-form "my-form" "my-form" {default_value: $default_value}
}

Limitations

  • Template rendering uses Jinja2 syntax only
  • FormInquire must be in PATH
  • nu_plugin_tera must be installed for template rendering
  • Form output limited to FormInquire-supported types