# `.nornenv` Feature Showcase

A single `.nornenv` that touches every feature we've shipped — templates, multi-parent `extends`, diamond inheritance, secrets, connection-string templates, imports, plus every diagnostic. Open [.nornenv](./.nornenv) in VS Code and the editor experience does most of the talking.

## What to try, in order

1. **Open the file.** Non-active sections auto-collapse to one line; the smart header chips show `extends X, Y · N vars · K inherited · M overrides` plus any warning pills.
2. **Click `▶ Activate` on `[env:prod_eu]`.** It's the most feature-dense env. Watch the file change:
   - The `ACTIVE` pill appears on its header
   - A brand-gradient marker shows up in the gutter on its line
   - A teal tick appears on the right-side overview ruler
   - Every `{{...}}` reference in the file gets an inlay hint with the now-resolved value
   - Secrets render as `(secret)` rather than the raw value
3. **Hover anything** — a variable name on the left side of a `=`, or a `{{ref}}`. The hover shows the resolution chain: where it's defined, whether it was inherited, and the current resolved value.
4. **Try `▶ Peek inherited`** on a leaf env like `[env:prod_eu]` — a quick-pick lists all 8+ inherited variables with their source templates and resolved values.
5. **Type `var ` inside `[env:prod_eu]`** — IntelliSense suggests every inherited variable name, so you can pick one to override without retyping.
6. **Start a new section header `[`** — completion offers both `[env:` and `[template:`. After typing `[env:foo `, completion offers `extends`, then suggests every available template as a parent.
7. **Scroll to the bottom** — the diagnostics-only block deliberately triggers every linter check:
   - `[env:bad_unknown_parent extends prdo, us]` — `prdo` squiggles as `unknown-extends-parent` with a quick-fix suggesting `prod`
   - `var apiKy = oops-typo` — squiggles as `unknown-override-target` with a suggestion
   - `var dangling = {{kmsKey}}` — squiggles as `unresolved-cross-section-ref`
   - `[env:bad_env_parent extends prod_us]` — `prod_us` squiggles as `extends-env-parent`
   - `[template:loop_a]` / `[template:loop_b]` — both squiggle as `extends-cycle`

## What to try at the CLI

After `npm run compile`, run [showcase.norn](./showcase.norn) which prints every resolved value.

> **Heads-up about `{{…}}` inside `.nornenv` values:** the IDE's inlay hints show the **fully recursively resolved** form (e.g. `apiBase → "https://api.prod.example.com/v2"` under `prod_eu`). The `.norn` runtime substitution is single-level — when you print `{{apiBase}}` from a `.norn` file, you'll see the literal `https://api.{{stageHost}}.example.com/{{apiVersion}}` because `apiBase`'s *value* still contains template tokens. That's standard Norn behavior — switch to the IDE for the deep view, or use leaf vars (stageHost, region, dbHost, …) for clean CLI prints.

```bash
# Most feature-dense env (self-override + diamond touchpoints).
node ./dist/cli.js demos/nornenv-showcase/showcase.norn -e prod_eu

# Right-most-wins demo — prod_strict (rightmost prod-chain template) wins on collisions.
node ./dist/cli.js demos/nornenv-showcase/showcase.norn -e prod_eu_strict

# Diamond inheritance — shared ancestor merged once.
node ./dist/cli.js demos/nornenv-showcase/showcase.norn -e diamond

# Templates are not selectable — this should error and list only env names.
node ./dist/cli.js demos/nornenv-showcase/showcase.norn -e prod
```

## What each section demonstrates

| Section | Feature |
| --- | --- |
| `import "./shared/.nornenv"` | Multi-file composition; chained imports merge into common |
| top-of-file `var ...` | Common variables (shared by every env) |
| `var apiBase = https://api.{{stageHost}}…` | Common values may reference any name — resolves under the active env |
| `[template:dev/staging/prod]` | Stage building blocks (not selectable) |
| `[template:prod_strict extends prod]` | Template extending another template (chained) |
| `[template:us/eu]` | Region building blocks |
| `[template:db_main]` with `connectionString` + `secret connectionString` | Connection-string templates, plain and secret |
| `[env:dev_us extends dev, us, db_main]` | Composing 3 templates into one selectable env |
| `[env:prod_eu] ... var logLevel = error` | Self-override wins over every parent |
| `[env:prod_eu_strict extends prod_strict, eu, db_main]` | Right-most parent wins on collisions |
| `[env:diamond extends dev, prod_strict]` | Diamond: shared ancestor merged once |
| `[env:bad_unknown_parent ...]` | Unknown parent + typo override + dangling ref diagnostics |
| `[env:bad_env_parent extends prod_us]` | Env-as-parent diagnostic |
| `[template:loop_a/loop_b]` | Cycle diagnostic |
