@golemui/gui-mcp 1.6.0 → 2.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { GET_CONCEPT_TOOL, JSON_GENERATE_FROM_OPENAPI_TOOL, JSON_GENERATE_FROM_SCHEMA_TOOL, JSON_GET_WIDGET_SPEC_TOOL, JSON_VALIDATE_FORM_DEFINITION_TOOL, generateFromJsonSchema, generateFromOpenapi, getConcept, getWidgetSpec, validateFormDefinition } from "./json.js";
2
- import { D, a, b, c, d, e, g, l, f, t } from "./list-dx-factories-DdWRo4bT.js";
2
+ import { D, a, b, c, d, e, g, l, f, t } from "./list-dx-factories-BelRM5SU.js";
3
3
  export {
4
4
  D as DX_CHECK_CODE_TOOL,
5
5
  a as DX_GET_SPEC_TOOL,
@@ -481,11 +481,11 @@ const FRAMEWORK_SETUP = {
481
481
  react: "RENDER (React) — `import { gui } from '@golemui/gui-shared'; import { GuiForm } from '@golemui/gui-react'; import type { FormSubmitEvent } from '@golemui/core';`, then render `<GuiForm config={{ formDef: form }} formSubmit={(e: FormSubmitEvent) => { /* e.data is the form data */ }} />`. A `gui.displays.display(() => <h2>…</h2>)` returns React JSX. For SSR (Next.js App Router) await `preloadFormWidgets({ widgetLoaders })` from `@golemui/core` before the first render on both server and client (a `'use client'` provider that `use()`s a module-scope promise); `widgetLoaders` comes from `@golemui/gui-react`. Set an explicit `formName`. Handlers run in the browser only.",
482
482
  angular: "RENDER (Angular) — `import { gui } from '@golemui/gui-shared'; import { FormComponent } from '@golemui/gui-angular';`, add `FormComponent` to the standalone component's `imports`, then in the template `<gui-form [config]=\"{ formDef: form }\" (formSubmit)=\"onSubmit($event)\"></gui-form>` — `$event` is a `FormSubmitEvent` (type from `@golemui/core`), `$event.data` is the form data. For SSR (`@angular/platform-server`) await `preloadFormWidgets({ widgetLoaders })` from `@golemui/core` before bootstrap on both server and client; `widgetLoaders` comes from `@golemui/gui-angular`. An explicit `formName` is required and handlers run in the browser only.",
483
483
  vue: "RENDER (Vue) — `import { gui } from '@golemui/gui-shared'; import { GuiForm } from '@golemui/gui-vue';`, then `<GuiForm :config=\"{ formDef: form }\" @form-submit=\"onSubmit\" />` — the handler receives a `FormSubmitEvent` (`.data` is the form data). The event is `form-submit` (kebab-case), not `formSubmit`. For SSR (Nuxt) await `preloadFormWidgets({ widgetLoaders })` from `@golemui/core` before the first render on both server and client (a Nuxt plugin); `widgetLoaders` comes from `@golemui/gui-vue`.",
484
- lit: "RENDER (Lit) — `import { gui } from '@golemui/gui-shared'; import '@golemui/gui-lit';` (registers the `<gui-form>` custom element), then `<gui-form .config=${{ formDef: form }} @" + formEventNames.submit + "=${(e: CustomEvent) => { /* e.detail is the FormSubmitEvent; e.detail.data */ }}></gui-form>`. The event name is `" + formEventNames.submit + "` (camelCase) — Lit dispatches a raw CustomEvent, so there is no kebab-case alias. For SSR (Astro, plain Node) the server renders the whole form with `renderGuiHtml` from `@golemui/lit/ssr` (needs `@lit-labs/ssr` >= 4.1.0) after `preloadFormWidgets({ widgetLoaders })`; the client preloads again and calls `resumeServerRenderedForm` from `@golemui/lit`. `formName` is mandatory; custom widgets register with `safeDefine` from `@golemui/lit`, not `@customElement`.",
484
+ lit: "RENDER (Lit) — `import { gui } from '@golemui/gui-shared'; import '@golemui/gui-lit';` (registers the `<gui-form>` custom element), then `<gui-form .config=${{ formDef: form }} @" + formEventNames.submit + "=${(e: CustomEvent) => { /* e.detail is the FormSubmitEvent; e.detail.data */ }}></gui-form>`. The event name is `" + formEventNames.submit + "` (camelCase) — Lit dispatches a raw CustomEvent, so there is no kebab-case alias. For SSR (Astro, plain Node) the server renders the whole form with `renderTemplate` from `@golemui/lit/ssr` (needs `@lit-labs/ssr` >= 4.1.0) after `preloadFormWidgets({ widgetLoaders })`; the client preloads again and calls `resumeServerRenderedForm` from `@golemui/lit`. `formName` is mandatory; custom widgets register with `safeDefine` from `@golemui/lit`, not `@customElement`.",
485
485
  vanilla: "RENDER (vanilla JS) — `import { gui } from '@golemui/gui-shared'; import '@golemui/gui-lit';` (registers `<gui-form>`), then `const el = document.querySelector('gui-form'); el.config = { formDef: form }; el.addEventListener('" + formEventNames.submit + "', (e) => { /* e.detail.data */ });`. In TypeScript, type the element — `import type { FormElement } from '@golemui/gui-lit'; const el = document.querySelector<FormElement>('gui-form');` — the published types do not register `gui-form` in `HTMLElementTagNameMap`, so an untyped `querySelector` yields `Element` and `el.config` fails to compile."
486
486
  };
487
487
  function commonNote(fw = "react") {
488
- return "GolemUI builds FORMS — data collection and validation. It is NOT a general-purpose UI toolkit: it never renders documents, page content, or markdown for display. A form is just an array of these items: `export const form = [ /* items */ ];`. " + FRAMEWORK_SETUP[fw] + " Import the component stylesheet ONCE — `@golemui/gui-components/index.css` — or the form renders unstyled. To RECEIVE A SUBMIT: add a `gui.actions.button({ label, actionType: 'submit' })` to the form and listen for the submit on the host component (the RENDER line above shows how for your framework) — the handler gets a `FormSubmitEvent` whose `.data` is the collected form data. To DISABLE submit until the form is valid, add `disabled: { when: '$formIsInvalid || $form.<requiredField> === undefined' }` to that button. `$formIsInvalid` is a built-in validity flag, but validation NEVER runs at mount, so on the pristine form it is `false` and `$formIsInvalid` ALONE leaves the button ENABLED while required fields are still empty — the extra data check covers that gap. See the conditional-and-state-props pattern. The SAME `formDef` renders in every framework (React/Angular/Vue/Lit/vanilla) — only the host wrapper changes. FORM-LEVEL CONFIG — `formDef` is ALWAYS the bare array. Anything form-wide (named `states`, `validateOn`) goes in a sibling `formConfig` on the config (`config={{ formDef: form, formConfig: { states, validateOn } }}`), NEVER inside `formDef`. Do NOT wrap the array as `{ states, form: [...] }` and pass THAT as `formDef` — `formDef` is typed `Record<string, any>` so it COMPILES, but the `gui.*` items are never resolved and the form renders BLANK with no error. See the form-level-states pattern. Common fields like `include`/`exclude` (conditional visibility) go INSIDE a factory’s config argument — never spread them onto the result (`{ ...gui.inputs.x(...), include }` compiles but silently does nothing). See the conditional-visibility pattern. STATIC CONTENT — a section heading or any non-input text/block is the HOST’s job, not GolemUI’s: use `gui.displays.display(() => <h2>…</h2>)` returning your framework’s own node (React JSX, Vue/Angular/Lit node) — it needs no dependency and always renders. MARKDOWN has exactly ONE use: `gui.inputs.markdown`, an INPUT where the user EDITS markdown (its value is their markdown string). There is NO markdown-for-display widget — never use markdown to render a heading or content; use `display` for that. VALIDATOR `type` — one rule, three cases (so you never have to guess): (1) choice widgets (`dropdown`, `radiogroup`, `select`) REQUIRE an explicit `type`: `validator: { type: 'string', required: true }`. (2) `repeater` (array), `tags` (array), `fileUpload` (file) and `multiFileUpload` (files) validators auto-supply their `type` — supply only the rules, e.g. `validator: { required: true, minItems: 1 }`, never `type`. (3) everything else (text, number, date) takes the loose validator with NO `type`: `validator: { required: true }`. EVENT HANDLERS — `onChange`/`onLoad`/`onFilter`/`onBlur` (inputs/layouts) and `onClick` (actions) are FUNCTIONS, never bare strings: return a string to dispatch a host event by that name (`onChange: () => 'languageChanged'`), or take the event to push live changes (`onChange: (event) => event.update({ path: 'city', options: [...] })`).";
488
+ return "GolemUI builds FORMS — data collection and validation. It is NOT a general-purpose UI toolkit: it never renders documents, page content, or markdown for display. A form is just an array of these items: `export const form = [ /* items */ ];`. " + FRAMEWORK_SETUP[fw] + " Import the two stylesheets ONCE, in this order — `@golemui/gui-components/index.css`, then `@golemui/gui-shared/forms.css` — or the form renders unstyled. To RECEIVE A SUBMIT: add a `gui.actions.button({ label, actionType: 'submit' })` to the form and listen for the submit on the host component (the RENDER line above shows how for your framework) — the handler gets a `FormSubmitEvent` whose `.data` is the collected form data. To DISABLE submit until the form is valid, add `disabled: { when: '$formIsInvalid || $form.<requiredField> === undefined' }` to that button. `$formIsInvalid` is a built-in validity flag, but validation NEVER runs at mount, so on the pristine form it is `false` and `$formIsInvalid` ALONE leaves the button ENABLED while required fields are still empty — the extra data check covers that gap. See the conditional-and-state-props pattern. The SAME `formDef` renders in every framework (React/Angular/Vue/Lit/vanilla) — only the host wrapper changes. FORM-LEVEL CONFIG — `formDef` is ALWAYS the bare array. Anything form-wide (named `states`, `validateOn`) goes in a sibling `formConfig` on the config (`config={{ formDef: form, formConfig: { states, validateOn } }}`), NEVER inside `formDef`. Do NOT wrap the array as `{ states, form: [...] }` and pass THAT as `formDef` — `formDef` is typed `Record<string, any>` so it COMPILES, but the `gui.*` items are never resolved and the form renders BLANK with no error. See the form-level-states pattern. Common fields like `include`/`exclude` (conditional visibility) go INSIDE a factory’s config argument — never spread them onto the result (`{ ...gui.inputs.x(...), include }` compiles but silently does nothing). See the conditional-visibility pattern. STATIC CONTENT — a section heading or any non-input text/block is the HOST’s job, not GolemUI’s: use `gui.displays.display(() => <h2>…</h2>)` returning your framework’s own node (React JSX, Vue/Angular/Lit node) — it needs no dependency and always renders. MARKDOWN has exactly ONE use: `gui.inputs.markdown`, an INPUT where the user EDITS markdown (its value is their markdown string). There is NO markdown-for-display widget — never use markdown to render a heading or content; use `display` for that. VALIDATOR `type` — one rule, three cases (so you never have to guess): (1) choice widgets (`dropdown`, `radiogroup`, `select`) REQUIRE an explicit `type`: `validator: { type: 'string', required: true }`. (2) `repeater` (array), `tags` (array), `fileUpload` (file) and `multiFileUpload` (files) validators auto-supply their `type` — supply only the rules, e.g. `validator: { required: true, minItems: 1 }`, never `type`. (3) everything else (text, number, date) takes the loose validator with NO `type`: `validator: { required: true }`. EVENT HANDLERS — `onChange`/`onLoad`/`onFilter`/`onBlur` (inputs/layouts) and `onClick` (actions) are FUNCTIONS, never bare strings: return a string to dispatch a host event by that name (`onChange: () => 'languageChanged'`), or take the event to push live changes (`onChange: (event) => event.update({ path: 'city', options: [...] })`).";
489
489
  }
490
490
  const PATTERNS = [
491
491
  {
@@ -713,7 +713,7 @@ const INPUTS = [
713
713
  factory: "dateTimeCalendar",
714
714
  namespace: "inputs",
715
715
  docSlug: "datetimecalendar",
716
- call: "gui.inputs.dateTimeCalendar(path, { label, minDate?, maxDate?, minTime?, maxTime?, minuteStep?, disabledTimeRanges?, allowCustomTime? })",
716
+ call: "gui.inputs.dateTimeCalendar(path, { label, minDate?, maxDate?, minTime?, maxTime?, minuteStep?, disabledTimeRanges?, allowCustomTime?, timeLabel? })",
717
717
  example: "gui.inputs.dateTimeCalendar('appointmentAt', { label: 'Appointment', minTime: '09:00', maxTime: '18:00' })",
718
718
  notes: [
719
719
  "An INLINE calendar with an embedded time picker: a segmented time input between the header and the days grid opens a time grid in place of the days (like the year selector).",
@@ -726,7 +726,7 @@ const INPUTS = [
726
726
  factory: "dateTimePicker",
727
727
  namespace: "inputs",
728
728
  docSlug: "datetimepicker",
729
- call: "gui.inputs.dateTimePicker(path, { label, minDate?, maxDate?, minTime?, maxTime?, minuteStep?, disabledTimeRanges?, allowCustomTime? })",
729
+ call: "gui.inputs.dateTimePicker(path, { label, minDate?, maxDate?, minTime?, maxTime?, minuteStep?, disabledTimeRanges?, allowCustomTime?, timeLabel? })",
730
730
  example: "gui.inputs.dateTimePicker('appointmentAt', { label: 'Appointment', minTime: '09:00', maxTime: '18:00' })",
731
731
  notes: [
732
732
  "A compact date-time FIELD that opens a `dateTimeCalendar` POPOVER on focus — the space-saving counterpart to the inline `dateTimeCalendar`, like `datePicker` is to `calendar`.",
@@ -948,40 +948,20 @@ const DISPLAYS = [
948
948
  }
949
949
  ];
950
950
  const LAYOUTS = [
951
- {
952
- factory: "flex",
953
- namespace: "layouts",
954
- docSlug: "flex",
955
- call: "gui.layouts.flex(children, props?)",
956
- example: "gui.layouts.flex([ gui.inputs.textInput('firstName', { label: 'First name' }), gui.inputs.textInput('lastName', { label: 'Last name' }) ])",
957
- notes: [
958
- "Layouts take the **children array first**, then optional props — unlike inputs (path first).",
959
- "Direction-locked variants: `verticalFlex`, `horizontalFlex` (and `grid` / `verticalGrid` / `horizontalGrid`)."
960
- ]
961
- },
962
- {
963
- factory: "verticalFlex",
964
- namespace: "layouts",
965
- docSlug: "flex",
966
- call: "gui.layouts.verticalFlex(children, props?)",
967
- example: "gui.layouts.verticalFlex([ gui.inputs.textInput('a', { label: 'A' }), gui.inputs.textInput('b', { label: 'B' }) ])",
968
- notes: ["A `flex` with direction fixed to vertical."]
969
- },
970
- {
971
- factory: "horizontalFlex",
972
- namespace: "layouts",
973
- docSlug: "flex",
974
- call: "gui.layouts.horizontalFlex(children, props?)",
975
- example: "gui.layouts.horizontalFlex([ gui.inputs.textInput('a', { label: 'A' }), gui.inputs.textInput('b', { label: 'B' }) ])",
976
- notes: ["A `flex` with direction fixed to horizontal."]
977
- },
978
951
  {
979
952
  factory: "grid",
980
953
  namespace: "layouts",
981
954
  docSlug: "grid",
982
955
  call: "gui.layouts.grid(children, props?)",
983
- example: "gui.layouts.grid([ gui.inputs.textInput('a', { label: 'A' }), gui.inputs.textInput('b', { label: 'B' }) ])",
984
- notes: ["Grid layout; `horizontalGrid` / `verticalGrid` lock the direction."]
956
+ example: "gui.layouts.grid([ gui.inputs.textInput('firstName', { label: 'First name', size: 2 }), gui.inputs.textInput('initial', { label: 'Initial' }) ], { direction: 'row', gap: 'lg' })",
957
+ notes: [
958
+ "Layouts take the **children array first**, then optional props — unlike inputs (path first).",
959
+ "The one layout. No `direction` stacks the children; `direction: 'row'` puts them on one line, sharing the width by each child's `size`; `columns: 3` (1–12) or `columns: 'auto'` wraps them in columns.",
960
+ "`gap`: `'none' | 'xs' | 'sm' | 'md'` (default) `| 'lg' | 'xl'` — never a number.",
961
+ "Rows only: `justify: 'start' | 'center' | 'end' | 'space-between'` keeps each child at its own width and places them, e.g. buttons on the right; the default `'stretch'` shares the width by `size`.",
962
+ "In a row or columns, labels, controls and errors line up across the fields on their own. Every grid stacks below a 480px wide container.",
963
+ "`gui.layouts.flex`, `verticalFlex` and `horizontalFlex` are deprecated: never use them."
964
+ ]
985
965
  },
986
966
  {
987
967
  factory: "verticalGrid",
@@ -989,15 +969,18 @@ const LAYOUTS = [
989
969
  docSlug: "grid",
990
970
  call: "gui.layouts.verticalGrid(children, props?)",
991
971
  example: "gui.layouts.verticalGrid([ gui.inputs.textInput('a', { label: 'A' }), gui.inputs.textInput('b', { label: 'B' }) ])",
992
- notes: ["A `grid` with direction fixed to vertical."]
972
+ notes: ["A `grid` stack, the same as `grid` with no direction."]
993
973
  },
994
974
  {
995
975
  factory: "horizontalGrid",
996
976
  namespace: "layouts",
997
977
  docSlug: "grid",
998
978
  call: "gui.layouts.horizontalGrid(children, props?)",
999
- example: "gui.layouts.horizontalGrid([ gui.inputs.textInput('a', { label: 'A' }), gui.inputs.textInput('b', { label: 'B' }) ])",
1000
- notes: ["A `grid` with direction fixed to horizontal."]
979
+ example: "gui.layouts.horizontalGrid([ gui.actions.button({ label: 'Cancel' }), gui.actions.button({ label: 'Save', actionType: 'submit' }) ], { justify: 'end' })",
980
+ notes: [
981
+ "A `grid` row: `grid` with `direction: 'row'`.",
982
+ "With `justify: 'end'` the children keep their own width and sit on the right: the usual place for form buttons."
983
+ ]
1001
984
  },
1002
985
  {
1003
986
  factory: "tabs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@golemui/gui-mcp",
3
- "version": "1.6.0",
3
+ "version": "2.0.0-rc.0",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -42,12 +42,12 @@
42
42
  "dependencies": {
43
43
  "ajv": "^8.17.1",
44
44
  "typescript": "^5.9.2",
45
- "@golemui/gui-schemas": "1.6.0",
46
- "@golemui/schemas": "1.6.0",
47
- "@golemui/gui-shared": "1.6.0",
48
- "@golemui/gui-validators": "1.6.0",
49
- "@golemui/dx": "1.6.0",
50
- "@golemui/core": "1.6.0",
45
+ "@golemui/gui-schemas": "2.0.0-rc.0",
46
+ "@golemui/schemas": "2.0.0-rc.0",
47
+ "@golemui/gui-shared": "2.0.0-rc.0",
48
+ "@golemui/gui-validators": "2.0.0-rc.0",
49
+ "@golemui/dx": "2.0.0-rc.0",
50
+ "@golemui/core": "2.0.0-rc.0",
51
51
  "@modelcontextprotocol/sdk": "^1.0.0",
52
52
  "zod": "^4.0.0",
53
53
  "@standard-schema/spec": "^1.0.0"