From 16cb66f9a2a1534f0406dc095fea840d93422da2 Mon Sep 17 00:00:00 2001 From: Mario Lurig Date: Fri, 30 Jan 2026 20:43:36 -0700 Subject: [PATCH 1/5] normalize EOL --- .gitattributes | 2 ++ trmnl-form-builder.js | 15 ++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ee36c91 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +*.yml text eol=lf +*.yaml text eol=lf diff --git a/trmnl-form-builder.js b/trmnl-form-builder.js index 91d3bc8..79e8e12 100644 --- a/trmnl-form-builder.js +++ b/trmnl-form-builder.js @@ -1833,15 +1833,16 @@ class TRMLYamlForm extends HTMLElement { } // Capture any i18n description keys - Object.keys(field).forEach(k => { - if (k.startsWith('description-')) { - lines.push( ` ${k}: "${field[k]}"`); - } + Object.keys(field) + .filter(k => k.startsWith('description-')) + .sort() + .forEach(k => { + lines.push(` ${k}: ${this.escapeYaml(field[k])}`); }); }); - return lines.join('\n'); + return lines.join('\n').replace(/\r\n/g, '\n').replace(/\r/g, '\n'); } escapeYaml(value) { @@ -2085,6 +2086,10 @@ class TRMLYamlForm extends HTMLElement { parseYaml(yamlText) { const fields = []; + yamlText = yamlText + .replace(/^\uFEFF/, '') // optional but recommended + .replace(/\r\n/g, '\n') + .replace(/\r/g, '\n') const lines = yamlText.split('\n'); let currentField = null; let currentArray = null; From 14e8533da2c7bd8e5992b2dc4c6cf65eb9f2e568 Mon Sep 17 00:00:00 2001 From: Mario Lurig Date: Fri, 30 Jan 2026 21:13:43 -0700 Subject: [PATCH 2/5] add markdown to EOL --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index ee36c91..a27c78a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ *.yml text eol=lf *.yaml text eol=lf +*.md text eol=lf From e6aa01f6213344fe7f466df9fb77a05736ef13eb Mon Sep 17 00:00:00 2001 From: Mario Lurig Date: Fri, 30 Jan 2026 21:14:07 -0700 Subject: [PATCH 3/5] Create Agents.MD for LLMs --- AGENTS.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..f58ac44 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,63 @@ +# AGENTS.md + +## Build/Lint/Test Commands + +### Running Tests +- `pnpm test` - Run all tests once +- `pnpm run test:watch` - Run tests in watch mode +- `pnpm run test:ui` - Run tests with Vitest UI +- `pnpm run test:coverage` - Run tests with coverage report +- `pnpm test -- --reporter=verbose` - Run single test with verbose output + +### Build Commands +- `pnpm run build` - No explicit build command found, project is a single JS file +- The main output file is `trmnl-form-builder.js` + +### Linting +No explicit linting commands found. Project appears to use standard JavaScript without linter configuration. + +## Code Style Guidelines + +### Imports +- Uses ES modules with `import` statements +- No specific import ordering requirements identified +- Component is registered as a custom element using `customElements.define()` + +### Formatting +- Uses standard JavaScript formatting conventions +- Indentation appears to be 2 spaces (based on code review) +- No specific formatter configured (prettier, eslint, etc.) + +### Types +- No explicit type definitions found +- Uses vanilla JavaScript without TypeScript +- Properties are set directly on elements + +### Naming Conventions +- Component name: `trmnl-form-builder` +- Method names follow camelCase convention +- Property names follow camelCase convention +- Constants are uppercase with underscores when appropriate + +### Error Handling +- Basic error handling through try/catch blocks where needed +- Validation of inputs and edge cases in functions like escapeYaml +- No comprehensive error logging or centralized error handling pattern + +### Code Structure +- Single JavaScript file implementation +- Uses class-based component structure for custom element +- Modular approach with separate methods for different functionality +- Self-contained component with no external dependencies beyond browser APIs + +### Testing +- Unit tests using Vitest framework +- Tests cover core functionality like YAML escaping/unescaping +- Tests use `describe`, `it`, and `expect` patterns +- Tests run in jsdom environment to simulate browser context + +### Additional Notes +- Component uses custom element API (`customElements.define`) +- Implements shadow DOM for encapsulation +- Follows web standards for component development +- No build tools or transpilation steps identified \ No newline at end of file From 109195200c24e47328ae68bf96441d49802b297d Mon Sep 17 00:00:00 2001 From: Mario Lurig Date: Fri, 30 Jan 2026 22:46:29 -0700 Subject: [PATCH 4/5] js EOL --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index a27c78a..c279aee 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ *.yml text eol=lf *.yaml text eol=lf *.md text eol=lf +*.js text eol=lf From 3b054d079a40df381a5c7efa6f70bd264d8e9ec0 Mon Sep 17 00:00:00 2001 From: Mario Lurig Date: Fri, 30 Jan 2026 23:00:04 -0700 Subject: [PATCH 5/5] docs: update AGENTS.md with build/lint/test commands and code style guidelines --- AGENTS.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index f58ac44..119aea9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -56,6 +56,26 @@ No explicit linting commands found. Project appears to use standard JavaScript w - Tests use `describe`, `it`, and `expect` patterns - Tests run in jsdom environment to simulate browser context +### Field Types +The form builder supports various field types including: +- string, textarea, number, email, url, password, select, checkbox, radio, author_bio +- xhrSelect and xhrSelectSearch for dynamic dropdowns with dependencies +- Special fields like copyable and copyable_webhook_url + +### Depends On Functionality +Fields can depend on other xhrSelect fields using the `depends_on` property. When a field has a `depends_on` property: +- The referenced parent field must be an xhrSelect type +- The parent field must appear before the child field in the form +- If these conditions are not met, the depends_on reference is automatically cleared +- This functionality ensures that dynamic dropdowns only load options when their dependencies are satisfied + +### YAML Generation +The component generates YAML configuration files for form definitions with proper escaping of special characters and handling of complex data types including: +- String values with proper quoting +- Label:Value pairs in select options +- Special handling for boolean literals and other YAML reserved words +- Proper indentation and structure according to YAML standards + ### Additional Notes - Component uses custom element API (`customElements.define`) - Implements shadow DOM for encapsulation