# Nickel Roundtrip Example

Complete example demonstrating the roundtrip workflow: load existing configuration, edit via interactive form, and regenerate with diff viewer.

## Scenario

CI configuration management - edit GitHub Actions settings through a form interface while preserving the Nickel structure.

## Files

- **config.ncl** - Input/output Nickel configuration
- **ci-form.toml** - Form definition with `nickel_path` mappings
- **config.ncl.j2** - Tera template for generating output
- **01-generate-initial-config.sh** - Create initial config
- **02-roundtrip-cli.sh** - Edit via CLI backend
- **03-roundtrip-tui.sh** - Edit via TUI backend
- **04-roundtrip-web.sh** - Edit via Web backend

## Quick Start

```bash
# 1. Generate initial configuration
./01-generate-initial-config.sh

# 2. Edit with your preferred backend

# CLI (command-line prompts)
./02-roundtrip-cli.sh

# TUI (full-screen terminal UI)
./03-roundtrip-tui.sh

# Web (browser-based form)
./04-roundtrip-web.sh
```text

## Key Features

### `nickel_path` Mapping

Every field in `ci-form.toml` has a `nickel_path` attribute mapping to the Nickel structure:

```toml
[[elements]]
name = "parallel_jobs"
type = "text"
prompt = "Parallel Jobs"
default = "4"
nickel_path = ["ci", "github_actions", "parallel_jobs"]
```text

Maps to:

```nickel
{
  ci = {
    github_actions = {
      parallel_jobs = 4
    }
  }
}
```text

### Template Rendering

The `config.ncl.j2` template uses form values to generate valid Nickel:

```jinja2
{
  project = {
    name = "{{ project_name }}",
    description = "{{ project_description }}",
  },

  ci = {
    github_actions = {
      enabled = {{ enable_github_actions }},
      parallel_jobs = {{ parallel_jobs }},
      timeout_minutes = {{ timeout_minutes }},
    }
  }
}
```text

### Summary with Diff

After editing, see what changed:

```text
╔════════════════════════════════════════════════════════════╗
║  ✅ Configuration Saved Successfully!                     ║
╠════════════════════════════════════════════════════════════╣
║  📄 File: config.ncl                                       ║
║  ✓ Validation: ✓ PASSED                                   ║
║  📊 Fields: 3/12 changed, 9 unchanged                      ║
╠════════════════════════════════════════════════════════════╣
║  📋 What Changed:                                          ║
║    ├─ parallel_jobs: 4 → 8                                 ║
║    ├─ timeout_minutes: 60 → 120                            ║
║    ├─ enable_cache: false → true                           ║
╠════════════════════════════════════════════════════════════╣
║  💡 Next Steps:                                            ║
║    • Review: cat config.ncl                                ║
║    • Apply CI tools: ./setup-ci.sh                         ║
║    • Re-configure: ./ci-configure.sh                       ║
╚════════════════════════════════════════════════════════════╝
```text

## Workflow Details

### 1. Load Defaults

Roundtrip reads `config.ncl` and extracts values using `nickel_path`:

```rust
// Internally:
nickel export config.ncl  // → JSON
extract_value_by_path(json, ["ci", "github_actions", "parallel_jobs"])  // → 4
```text

### 2. Populate Form

Form fields get pre-filled with current values:

- Text fields show current text
- Numbers show current numbers
- Booleans show current true/false
- Select fields pre-select current option

### 3. Edit Interactively

User edits via chosen backend (CLI/TUI/Web).

### 4. Generate Output

Template renders with new values:

```jinja2
parallel_jobs = {{ parallel_jobs }},  // User changed 4 → 8
```text

### 5. Validate

Automatic validation:

```bash
nickel typecheck config.ncl
```text

### 6. Show Summary

Terminal summary (all backends) + HTML summary (web only).

## Backend Comparison

| Feature | CLI | TUI | Web |
|---------|-----|-----|-----|
| Terminal UI | ✓ | ✓ | ✓ (summary only) |
| Browser UI | ✗ | ✗ | ✓ |
| Pre-populated values | ✓ | ✓ | ✓ |
| Real-time validation | ✗ | ✓ | ✓ |
| HTML diff viewer | ✗ | ✗ | ✓ |
| Download button | ✗ | ✗ | ✓ |

## Customization

### Add More Fields

1. **Update form:**

   ```toml
   [[elements]]
   name = "rust_version"
   type = "select"
   prompt = "Rust Version"
   options = [
     { value = "stable", label = "Stable" },
     { value = "nightly", label = "Nightly" }
   ]
   nickel_path = ["ci", "rust", "version"]
   ```

2. **Update template:**

   ```jinja2
   ci = {
     rust = {
       version = "{{ rust_version }}",
     }
   }
   ```

3. **Update initial config:**

   ```nickel
   {
     ci = {
       rust = {
         version = "stable"
       }
     }
   }
   ```

### Change Template Logic

Add conditionals:

```jinja2
{% if enable_cache %}
cache = {
  enabled = true,
  paths = {{ cache_paths | json }},
},
{% endif %}
```text

### Disable Validation

```bash
typedialog nickel-roundtrip \
  --input config.ncl \
  --form ci-form.toml \
  --output config.ncl \
  --ncl-template config.ncl.j2 \
  --no-validate  # ← Skip nickel typecheck
```text

## Troubleshooting

**No defaults loaded:**

```bash
# Check nickel export works
nickel export config.ncl

# Verify all fields have nickel_path
grep "nickel_path" ci-form.toml | wc -l
```text

**Template errors:**

```bash
# Test template separately
echo '{"project_name": "test"}' | \
  tera --template config.ncl.j2
```text

**Validation fails:**

```bash
# Check manually
nickel typecheck config.ncl
```text

## Learn More

- [nickel.md](../../docs/nickel.md) - Full roundtrip documentation
- [Nickel Language](https://nickel-lang.org) - Nickel reference
- [Tera Templates](https://tera.netlify.app) - Template syntax
