# KOGRAL Forms & Configuration UI

This directory contains form definitions for the typedialog-web UI, enabling interactive configuration of KOGRAL knowledge bases.

## Architecture

Forms use a **fragment composition pattern** for modularity and maintainability:

```
kogral-config.toml (main form)
    ├── includes: fragments/graph.toml
    ├── includes: fragments/storage.toml
    ├── includes: fragments/embeddings.toml
    ├── includes: fragments/query.toml
    ├── includes: fragments/mcp.toml
    └── includes: fragments/sync.toml
```

## File Structure

```
forms/
├── kogral-config.toml          # Main form definition (composition)
├── README.md                   # This file
└── fragments/                  # Reusable configuration fragments
    ├── graph.toml             # Knowledge graph metadata
    ├── storage.toml           # Storage backend options
    ├── embeddings.toml        # Vector search & embedding provider
    ├── query.toml             # Query engine tuning
    ├── mcp.toml               # MCP server settings
    └── sync.toml              # Synchronization configuration
```

## Fragment Design

Each fragment contains:

1. **Section Headers** - Visual grouping in UI
2. **Field Elements** - Input controls with:
   - `nickel_path` - Path in Nickel config (e.g., `["storage", "primary"]`)
   - `type` - Field type (text, select, boolean, number, text_array)
   - `default` - Default value
   - `visible_if` - Conditional visibility rules
   - `help` - User help text

### Example Fragment

```toml
[[elements]]
border_top = true
name = "storage_section_header"
title = "💾 Storage Backend"
type = "section_header"

[[elements]]
default = "filesystem"
help = "Primary storage backend for knowledge base"
name = "storage_primary"
nickel_path = ["storage", "primary"]
options = ["filesystem", "memory", "surrealdb"]
prompt = "Primary Storage"
type = "select"
```

## nickel_path Mapping

The `nickel_path` field maps form fields to Nickel configuration structure:

```
nickel_path = ["storage", "primary"]
    ↓
Nickel: storage.primary = "filesystem"
    ↓
JSON export: { storage: { primary: "filesystem" } }
    ↓
Rust struct: config.storage.primary
```

## Conditional Visibility

Fields can appear/disappear based on other field values:

```toml
visible_if = "storage_secondary_enabled == true"
visible_if = "embeddings_provider != 'fastembed'"
visible_if = "sync_auto_index == true && query_cross_graph == true"
```

## Integration with typedialog-web

1. **Edit** - User modifies form in typedialog-web
2. **Validate** - Fields validated against nickel_path contracts
3. **Export** - Changes written back to `.ncl` files
4. **Generate** - `generate-configs.nu` exports to JSON
5. **Load** - Rust code loads from `.kogral/config.json`

## Adding New Configuration Sections

To add a new configuration section:

1. Add new type to `core/contracts.ncl`
2. Add defaults to `core/defaults.ncl`
3. Create fragment file: `fragments/new-section.toml`
4. Add `includes` reference in `kogral-config.toml`
5. Run validation: `nu scripts/validate-config.nu`

## Fragment Naming Convention

- Use descriptive names: `storage.toml`, `embeddings.toml`, not `section1.toml`
- For sub-sections: `fragments/mcp/tools.toml`, `fragments/storage/secondary.toml`
- Use lowercase with hyphens: `mcp-server.toml`, not `MCPServer.toml`
