# Gramit Code - Full Language Reference (for AI assistants)

This document is the complete specification of **Gramit Code**, the YAML language that
powers the "Code to Diagram" feature in the Gramit diagram editor (https://gramit.io).
It is written to be read by an AI assistant so it can generate valid Gramit Code on a
user's behalf.

If you are an AI reading this: produce a single YAML document that follows the rules
below, then tell the user to paste it into Gramit's **Code to Diagram** panel
(Menu -> Code to Diagram). Output only valid YAML inside a code block. Do not invent
properties - only the keys listed here are allowed, and unknown keys are rejected by the
editor's validator.

Human-readable docs with live previews: https://www.gramit.io/docs

---

## 1. Document structure

A Gramit document is a YAML mapping with up to three kinds of top-level keys. Only `root`
is required.

```yaml
template:        # optional - diagram-level settings
  name: My Flow
  theme: dark
  style: clean

root:            # required - the main flow
  nodes: [ ... ]
  edges: [ ... ]

my_subflow:      # optional - any other top-level key is a subflow
  nodes: [ ... ]
  edges: [ ... ]
```

- `template` - optional diagram-wide settings.
- `root` - required. The main flow: a list of `nodes` and the `edges` between them.
- Any other top-level key (not `template`, not `root`) defines a **subflow** - a nested
  diagram opened as its own level in the editor.

The diagram only renders when the entire document is valid.

---

## 2. Template

```yaml
template:
  name: User Onboarding   # any string (optional)
  theme: dark             # light | dark
  style: handmade         # handmade | clean
```

| Field | Values            | Notes                                            |
|-------|-------------------|--------------------------------------------------|
| name  | any string        | Diagram name.                                    |
| theme | `light` \| `dark` | Also switches the editor theme.                  |
| style | `handmade` \| `clean` | Visual style. `clean` is the "Architect" look. |

Unknown keys inside `template` are errors.

---

## 3. Nodes

Every entry under `nodes:` requires a unique `name`. Everything else is optional and
inherits from the active style when omitted.

```yaml
nodes:
  - name: my_node       # REQUIRED - the node id, unique across the WHOLE document
    type: simple        # optional - defaults to 'simple'
    text: Hello World   # the visible label
    color: '#1e3a5f'    # ...plus any visual property allowed for the type
```

IMPORTANT:
- `name` is the node **id**, not the visible label. The visible label is `text`.
  Use short, code-friendly names (e.g. `login_form`) and put human wording in `text`.
- `name` must be **globally unique** - across `root` and every subflow.
- Edges reference nodes by `name`.

### Node types

Set `type` to choose the shape. Omit it for a plain rectangle (`simple`).

| type       | Shape on canvas | Extra/required fields           |
|------------|-----------------|---------------------------------|
| `simple`   | Rectangle       | -                               |
| `circle`   | Ellipse/circle  | -                               |
| `decision` | Diamond         | -                               |
| `text`     | Text label      | -                               |
| `person`   | Person glyph    | -                               |
| `icon`     | Icon + label    | `icon` (icon id)                |
| `image`    | Image + label   | `url` (URL or `assets/…` path)  |
| `code`     | Code block      | `language` + `text` (REQUIRED)  |

### Visual properties (per node)

Each type supports a different subset. Properties not listed for a type are rejected.

| Property       | Values                                                       |
|----------------|--------------------------------------------------------------|
| `stroke`       | hex (`'#rrggbb'`), `rgb()`, `rgba()`, or `transparent`       |
| `color`        | fill - hex, `rgb()`, `rgba()`, or `transparent`              |
| `fill`         | `hatch` \| `cross-hatch` \| `dots` \| `solid` (used when `color` is transparent) |
| `stroke_width` | `0.5` \| `1` \| `2` \| `4`                                   |
| `stroke_style` | `solid` \| `dashed` \| `dotted` \| `dash-dot`                |
| `sloppiness`   | `1` \| `2` \| `3` \| `4` (1 = smooth, 4 = rough)             |
| `edges`        | `sharp` \| `slight` \| `round` \| `full` (corner rounding)   |
| `opacity`      | `0`-`100`                                                    |

Allowed properties by type:

- `simple`   : stroke, color, fill, stroke_width, stroke_style, sloppiness, edges, opacity
- `circle`   : stroke, color, fill, stroke_width, stroke_style, sloppiness, opacity  (no `edges`)
- `decision` : stroke, color, fill, stroke_width, stroke_style, sloppiness, edges, opacity
- `text`     : stroke, color, fill, stroke_width, stroke_style, sloppiness, edges, opacity
- `person`   : stroke, color, stroke_width, sloppiness, opacity  (stroke cannot be `transparent`; no `fill`/`stroke_style`)
- `icon`     : icon, opacity  (colors are ignored)
- `image`    : url, width, height, size, color, edges, opacity
- `code`     : language, text, stroke, color, stroke_width, edges, opacity

`name`, `type`, `text` and `opacity` are always allowed on every type.

### Type-specific fields

**icon** - `icon` is an icon id from the built-in library, formatted as a path
(`provider/category/.../name`). Get ids from the in-app icon picker. Providers include
`cloud`, `dev`, `apps`, `ai`, `os`, `design`. Examples:

```yaml
- name: fn
  type: icon
  text: Lambda
  icon: cloud/compute/aws/lambda
- name: db
  type: icon
  text: DynamoDB
  icon: cloud/databases/aws/dynamodb
- name: gw
  type: icon
  text: API Gateway
  icon: cloud/integration/aws/api-gateway
```

**image** - `url` is either a full absolute URL (e.g. `https://example.com/logo.png`) or a
compact asset path of the form `assets/<name>` referencing an image in the user's "My Assets"
library (e.g. `assets/picture-of-my`). Other relative paths are rejected.

Sizing (all optional, positive numbers):
- `width` + `height` - exact pixel dimensions.
- a single `width` or `height` - scales the other to keep the aspect ratio.
- `size` - scale factor on the default size (e.g. `2` = double, `0.5` = half).
  Ignored when `width`/`height` are set.

```yaml
- name: banner
  type: image
  text: Logo
  url: https://gramit.io/logo.png
  width: 320
  height: 180
- name: thumb
  type: image
  url: assets/picture-of-my
  size: 2
```

**code** - `text` is the code content (not a label). `language` is required.
Supported languages: `json`, `javascript`, `typescript`, `python`, `html`, `css`, `markdown`.

```yaml
- name: api_call
  type: code
  language: typescript
  text: |
    const res = await fetch('/api/users');
    return res.json();
  stroke: '#6366f1'
  color: '#1e1b4b'
```

**person**

```yaml
- name: user
  type: person
  text: Alice
  stroke: '#16a34a'    # cannot be 'transparent'
  color: '#bbf7d0'
  sloppiness: 1
```

---

## 4. Edges

Edges connect two nodes by `name`. `from` and `to` are required and must reference
existing node names.

```yaml
edges:
  - from: node_a
    to: node_b
    text: Submit        # optional label
    type: curved        # straight | curved
    style: dashed       # solid | dashed
    arrow: open         # open | closed
    width: 2            # 1 | 2 | 3 | 4
    stroke: '#ef4444'   # hex | rgb() | rgba()
    sloppiness: 2       # 1 | 2 | 3 | 4
```

| Property     | Values                          |
|--------------|---------------------------------|
| `from`       | node name (required)            |
| `to`         | node name (required)            |
| `text`       | string                          |
| `type`       | `straight` \| `curved`          |
| `style`      | `solid` \| `dashed`             |
| `arrow`      | `open` \| `closed`              |
| `width`      | `1` \| `2` \| `3` \| `4`        |
| `stroke`     | hex, `rgb()`, `rgba()`          |
| `sloppiness` | `1` \| `2` \| `3` \| `4`        |

All edge properties except `from`/`to` are optional. Node positions and edge routing are
computed automatically (auto-layout, left-to-right) - you do not specify coordinates.

---

## 5. Subflows

Any top-level key other than `template` and `root` is a subflow - a nested diagram opened
as its own level. Node names remain globally unique across all flows.

```yaml
root:
  nodes:
    - name: onboarding
      text: Onboarding
  edges: []

onboarding:           # subflow
  nodes:
    - name: welcome
      text: Welcome Screen
    - name: setup
      text: Account Setup
  edges:
    - from: welcome
      to: setup
```

---

## 6. Colors

All color fields accept:

```
#rgb            ->  '#f00'
#rrggbb         ->  '#ff0000'
#rrggbbaa       ->  '#ff000080'
rgb(r, g, b)    ->  rgb(255, 0, 0)
rgba(r, g, b, a)->  rgba(255, 0, 0, 0.5)
transparent     ->  no fill / no stroke
```

Always quote hex colors in YAML (`'#ff0000'`). Unquoted, `#` starts a YAML comment and the
value is lost.

---

## 7. Style defaults

Omitted visual properties inherit from the active style:

| Property       | clean (Architect) | handmade      |
|----------------|-------------------|---------------|
| sloppiness     | 1 (smooth)        | 3 (rough)     |
| stroke_width   | 1                 | 1             |
| edges          | slight            | round         |
| stroke_style   | solid             | solid         |
| edge arrows    | open, curved      | closed, curved|

---

## 8. Validation rules (what the editor enforces)

Nodes:
- `name` is required, non-empty, unique within its flow and globally.
- `type` must be one of: simple, circle, icon, image, person, decision, text, code.
- Properties outside a type's allowed set are errors.
- `sloppiness` in {1,2,3,4}; `stroke_width` in {0.5,1,2,4}; `opacity` in 0-100.
- `color`/`stroke` must be valid color strings.
- `code` nodes require `language` and `text`. `image` nodes need a `url` (full URL or `assets/…` path); `width`/`height`/`size` must be positive numbers.

Edges:
- `from` and `to` are required and must reference existing node names.
- `width` in {1,2,3,4}; `sloppiness` in {1,2,3,4}.

Template:
- `theme` in {light, dark}; `style` in {handmade, clean}.
- Unknown keys (in `template` or any flow) are errors. A flow may only contain `nodes` and `edges`.

---

## 9. Complete example

```yaml
template:
  name: User Registration Flow
  theme: dark
  style: handmade

root:
  nodes:
    - name: start
      text: Start
      color: '#1e293b'
      stroke: '#94a3b8'
    - name: form
      text: Fill Registration Form
      color: '#1e3a5f'
      stroke: '#3b82f6'
      stroke_width: 2
    - name: validate
      type: decision
      text: Valid?
      stroke: '#f59e0b'
      color: transparent
      fill: hatch
    - name: error_msg
      text: Show Errors
      color: '#fee2e2'
      stroke: '#ef4444'
    - name: done
      type: circle
      text: Done
      color: '#dcfce7'
      stroke: '#16a34a'
    - name: new_user
      type: person
      text: New User
      stroke: '#3b82f6'
      color: '#dbeafe'
  edges:
    - from: start
      to: form
      type: curved
    - from: form
      to: validate
      text: Submit
      type: curved
    - from: validate
      to: error_msg
      text: "No"
      style: dashed
      stroke: '#ef4444'
      arrow: open
    - from: validate
      to: done
      text: "Yes"
      stroke: '#16a34a'
      width: 2
    - from: done
      to: new_user
      type: curved
      stroke: '#16a34a'
      arrow: closed

notifications:
  nodes:
    - name: email_sent
      text: Send Welcome Email
      color: '#fef9c3'
      stroke: '#ca8a04'
    - name: sms
      text: Send SMS Verification
      color: '#fef9c3'
      stroke: '#ca8a04'
  edges:
    - from: email_sent
      to: sms
```

---

## 10. How to deliver Gramit Code to the user

1. Output a single, valid YAML document (only the keys defined above).
2. Wrap it in a fenced code block.
3. Tell the user: open Gramit (https://gramit.io), click **Menu -> Code to Diagram**,
   and paste the YAML into the panel. The diagram renders automatically.
