# Capabilities and limits

## GS Loom: GrowSite’s own engine

GS Loom is GrowSite’s own template engine. A package contains `loom.json`, HTML, separate JSON schemas, dictionaries, styles and optional assets. The compiler accepts the GS Loom contract and rejects unsupported template syntax.

## Directives and expressions

| Syntax | Behavior |
| --- | --- |
| `gs-text="section.settings.title"` | Safely replaces element text |
| `[[ section.settings.title ]]` | Interpolates text or an attribute value |
| `gs-href`, `gs-src` | Bind a URL with protocol validation |
| `gs-if`, `gs-else-if`, `gs-else` | Choose a branch; alternatives must be siblings |
| `gs-repeat="item in content.items"` | Repeat an element with `loop.index` and `loop.index0` |
| `gs-component="link"` | Include HTML from `snippets`, `components` or `sections` |
| `gs-prop-label="block.settings.label"` | Pass a component parameter |
| `gs-group="header"` | Render a section group |
| `gs-slot="blocks"` | Render allowed children in `block_order` |
| `gs-block="_signature" gs-id="signature"` | Include a static block |
| `gs-slot="layout"` | Insert page content into its layout |
| `gs-attr-checked="enabled"` | Set an attribute; false and null omit it |

Directives can be placed on `<template>`, which adds no container. Expressions support data paths, array indexes, literals, comparisons, `and`/`or`, `not`, concatenation with `+` and `condition ? yes : no`. False and null are falsey; compare with `blank` to check empty text.

Available helpers are `safe_url(value)`, `split(value, separator)`, `first(list)`, `slice(value, start, length)`, `str(value)`, `t(key)`, `asset_url(name)` and `date(value, "%Y")`. Arbitrary JavaScript method calls are unavailable. Use `gs-set` with `gs-value` to name an expression result in the local scope.

## Plugins and existing websites

`gs-form`, `gs-menu`, `gs-blog` and `gs-comments` use GrowSite integrations. Instant retains its form presentation. Victorie uses the shared document renderer and form instance bindings. Paylio retains pricing and FAQ behavior in its package runtime. This contract does not promise shopping carts or booking integrations that the platform does not provide.

GrowSite Skeleton uses the stable key `growsite-skeleton`. Editable section data is stored in `content.loom`, and global theme data in `theme_settings.loom`. Bindings such as `loom.settings.title` refer to these documents. The naming migration preserves catalog IDs, site assignments and version history.

## Boundaries and safety

The engine has no network, filesystem or database access. It sees only package files and explicitly supplied data. Text and attributes are escaped; prototype access is blocked. Limits include 500 KB per file, 2 million source characters per package, 1000 list entries, 24 invocation levels and a bounded rendering workload. Modules in `runtime/*.ts` are trusted application code installed and bundled by the maintainer, never executable code entered in a customer field.

The contract is implemented by `scripts/loom-themes.mjs`, `packages/templates/src/lib/loom/runtime.ts` and `api/app/Rules/LoomDocument.php`. The panel assistant does not automatically install new theme packages. AI-authored packages follow exactly the same validation and testing process as manually authored code.
