@golemui/gui-mcp 1.0.2 → 1.1.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/json.js CHANGED
@@ -1,4 +1,4 @@
1
- import { G, J, a, b, c, g, d, e, f, v } from "./get-concept-Py3iLVmb.js";
1
+ import { G, J, a, b, c, g, d, e, f, v } from "./get-concept-e_HDPrW1.js";
2
2
  export {
3
3
  G as GET_CONCEPT_TOOL,
4
4
  J as JSON_GENERATE_FROM_OPENAPI_TOOL,
package/lib.js CHANGED
@@ -1,5 +1,5 @@
1
- import { G, J, a, b, c, g, d, e, f, v } from "./get-concept-Py3iLVmb.js";
2
- import { D, a as a2, b as b2, c as c2, d as d2, e as e2, g as g2, l, f as f2, t } from "./list-dx-factories-C-Z5Sc5E.js";
1
+ import { G, J, a, b, c, g, d, e, f, v } from "./get-concept-e_HDPrW1.js";
2
+ import { D, a as a2, b as b2, c as c2, d as d2, e as e2, g as g2, l, f as f2, t } from "./list-dx-factories-BlB_usDm.js";
3
3
  export {
4
4
  D as DX_CHECK_CODE_TOOL,
5
5
  a2 as DX_GET_SPEC_TOOL,
@@ -1,4 +1,4 @@
1
- import { h as checkReactiveExpression } from "./get-concept-Py3iLVmb.js";
1
+ import { h as checkReactiveExpression } from "./get-concept-e_HDPrW1.js";
2
2
  import { existsSync } from "node:fs";
3
3
  import { createRequire } from "node:module";
4
4
  import { resolve, join, dirname } from "node:path";
@@ -23,7 +23,7 @@ function lintDxSnippet(ts, sourceText, lineOffset) {
23
23
  while (ts.isPropertyAccessExpression(e)) e = e.expression;
24
24
  return ts.isIdentifier(e) && e.text === "gui";
25
25
  };
26
- const visit = (node) => {
26
+ const visit = (node, inTemplate) => {
27
27
  if (ts.isObjectLiteralExpression(node)) {
28
28
  const spreadsGui = node.properties.some(
29
29
  (p) => ts.isSpreadAssignment(p) && isGuiCall(p.expression)
@@ -46,13 +46,17 @@ function lintDxSnippet(ts, sourceText, lineOffset) {
46
46
  }
47
47
  if (ts.isPropertyAssignment(node) && nameOf(node.name) === "when" && ts.isStringLiteralLike(node.initializer)) {
48
48
  const { line, column } = posOf(node.initializer);
49
- for (const f of checkReactiveExpression(node.initializer.text, `when@${line}:${column}`)) {
49
+ const findings = checkReactiveExpression(node.initializer.text, `when@${line}:${column}`, {
50
+ inRepeaterTemplate: inTemplate
51
+ });
52
+ for (const f of findings) {
50
53
  expressionWarnings.push(f);
51
54
  }
52
55
  }
53
- ts.forEachChild(node, visit);
56
+ const childInTemplate = inTemplate || ts.isPropertyAssignment(node) && nameOf(node.name) === "template";
57
+ ts.forEachChild(node, (child) => visit(child, childInTemplate));
54
58
  };
55
- visit(sf);
59
+ visit(sf, false);
56
60
  return { diagnostics, expressionWarnings };
57
61
  }
58
62
  let cachedRequire;
@@ -365,6 +369,33 @@ const INPUTS = [
365
369
  "`minDate` / `maxDate` (ISO `YYYY-MM-DD` strings) constrain the accepted range — see `datePicker`."
366
370
  ]
367
371
  },
372
+ {
373
+ factory: "timeInput",
374
+ namespace: "inputs",
375
+ call: "gui.inputs.timeInput(path, { label, hourFormat?, minuteStep?, validator? })",
376
+ example: "gui.inputs.timeInput('meetingTime', { label: 'Meeting time', minuteStep: 15 })",
377
+ notes: [
378
+ "Typed time entry (hh:mm segments). Emits an ISO time string (`HH:mm:ss`) — pair with the `{ format: 'time' }` validator. `hourFormat` forces '12'/'24' (default: locale); `minuteStep` sets the arrow-key minute increment."
379
+ ]
380
+ },
381
+ {
382
+ factory: "timePicker",
383
+ namespace: "inputs",
384
+ call: "gui.inputs.timePicker(path, { label, minTime?, maxTime?, minuteStep?, disabledRanges?, allowCustomTime?, validator? })",
385
+ example: "gui.inputs.timePicker('meetingTime', { label: 'Meeting time', minTime: '09:00', maxTime: '18:00', minuteStep: 30 })",
386
+ notes: [
387
+ "Time field with a popover list of slots built from `minTime`..`maxTime` stepping `minuteStep` (default 30). `disabledRanges` (`{ start, end }[]`, inclusive) greys slots out. Typing is off unless `allowCustomTime: true`. Emits `HH:mm:ss` — pair with the `{ format: 'time' }` validator."
388
+ ]
389
+ },
390
+ {
391
+ factory: "dateTimeInput",
392
+ namespace: "inputs",
393
+ call: "gui.inputs.dateTimeInput(path, { label, hourFormat?, minuteStep?, validator? })",
394
+ example: "gui.inputs.dateTimeInput('meetingAt', { label: 'Meeting at' })",
395
+ notes: [
396
+ "Typed date+time entry in one locale-ordered row. Emits a local ISO date-time (`YYYY-MM-DDTHH:mm:ss`) — pair with the `{ format: 'date-time' }` validator. `hourFormat`/`minuteStep` as in `timeInput`."
397
+ ]
398
+ },
368
399
  {
369
400
  factory: "calendar",
370
401
  namespace: "inputs",
@@ -375,6 +406,28 @@ const INPUTS = [
375
406
  "`minDate` / `maxDate` (ISO `YYYY-MM-DD` strings) constrain the selectable range — see `datePicker`."
376
407
  ]
377
408
  },
409
+ {
410
+ factory: "dateTimeCalendar",
411
+ namespace: "inputs",
412
+ call: "gui.inputs.dateTimeCalendar(path, { label, minDate?, maxDate?, minTime?, maxTime?, minuteStep?, disabledTimeRanges?, allowCustomTime? })",
413
+ example: "gui.inputs.dateTimeCalendar('appointmentAt', { label: 'Appointment', minTime: '09:00', maxTime: '18:00' })",
414
+ notes: [
415
+ "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).",
416
+ "Emits a local ISO date-time (`YYYY-MM-DDTHH:mm:ss`) only when BOTH day and time are selected — pair with a `{ type: 'string', format: 'date-time' }` validator. Picking a different day clears the time and resets the value to null.",
417
+ "`disabledTimeRanges` entries take `start`/`end` ISO times plus optional `date` (ISO date) and/or `weekdays` (getDay() numbering: 0=Sunday … 6=Saturday) to scope the range to specific days."
418
+ ]
419
+ },
420
+ {
421
+ factory: "dateTimePicker",
422
+ namespace: "inputs",
423
+ call: "gui.inputs.dateTimePicker(path, { label, minDate?, maxDate?, minTime?, maxTime?, minuteStep?, disabledTimeRanges?, allowCustomTime? })",
424
+ example: "gui.inputs.dateTimePicker('appointmentAt', { label: 'Appointment', minTime: '09:00', maxTime: '18:00' })",
425
+ notes: [
426
+ "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`.",
427
+ "Emits a local ISO date-time (`YYYY-MM-DDTHH:mm:ss`); the popover closes only when BOTH day and time are selected. Pair with a `{ type: 'string', format: 'date-time' }` validator.",
428
+ "Takes the same time props as `dateTimeCalendar` (`minTime`/`maxTime`/`minuteStep`/`disabledTimeRanges` with per-date/weekday scoping/`allowCustomTime`) plus `icon` and `invalidDateMessage` for the typed input."
429
+ ]
430
+ },
378
431
  {
379
432
  factory: "markdown",
380
433
  namespace: "inputs",
@@ -428,12 +481,60 @@ const INPUTS = [
428
481
  example: "gui.inputs.rangeDateInput('stayDates', { label: 'Stay dates' })",
429
482
  notes: ["Typed start–end date **range** entry (the range sibling of `dateInput`)."]
430
483
  },
484
+ {
485
+ factory: "rangeTimeInput",
486
+ namespace: "inputs",
487
+ call: "gui.inputs.rangeTimeInput(path, { label?, minTime?, maxTime? })",
488
+ example: "gui.inputs.rangeTimeInput('shift', { label: 'Shift', minTime: '06:00:00', maxTime: '22:00:00' })",
489
+ notes: [
490
+ "Typed start–end time **range** entry (the range sibling of `timeInput`); value is `TimeRange[]`. End time must be after start time."
491
+ ]
492
+ },
493
+ {
494
+ factory: "rangeDateTimeInput",
495
+ namespace: "inputs",
496
+ call: "gui.inputs.rangeDateTimeInput(path, { label?, minDateTime?, maxDateTime? })",
497
+ example: "gui.inputs.rangeDateTimeInput('window', { label: 'Window', minDateTime: '2026-03-01T06:00:00', maxDateTime: '2026-03-31T22:00:00' })",
498
+ notes: [
499
+ "Typed start–end date-time **range** entry (the range sibling of `dateTimeInput`); value is `DateTimeRange[]`. A backward selection reorders (swaps) instead of erroring.",
500
+ "Each endpoint is an instant, so it is bounded by instants: use **`minDateTime`** / **`maxDateTime`** (ISO `YYYY-MM-DDTHH:mm:ss`), not `minDate`/`maxDate`. There is no `minTime`/`maxTime` here — a per-day time window is a different constraint from an instant bound."
501
+ ]
502
+ },
503
+ {
504
+ factory: "rangeDateTimeCalendar",
505
+ namespace: "inputs",
506
+ call: "gui.inputs.rangeDateTimeCalendar(path, { label?, minDateTime?, maxDateTime?, disabledRanges?, startTimeLabel?, endTimeLabel? })",
507
+ example: "gui.inputs.rangeDateTimeCalendar('stay', { label: 'Stay', startTimeLabel: 'Check-in', endTimeLabel: 'Check-out' })",
508
+ notes: [
509
+ "INLINE range calendar with TWO embedded time pickers (start/end); value is `DateTimeRange[]`, rendered as pills. Pick a date range, then a start time (enables the end time), then an end time to commit a pill. A day holding more than one range shows a count badge.",
510
+ "Everything is in instant-space: bounds are **`minDateTime`** / **`maxDateTime`** and **`disabledRanges`** are `DateTimeRange[]` instant spans (block a whole day with `00:00:00`–`23:59:59`). There is no `minDate`/`maxDate`/`minTime`/`maxTime`/`disabledTimeRanges` — a time-of-day constraint cannot bound a multi-day span."
511
+ ]
512
+ },
513
+ {
514
+ factory: "rangeDateTimePicker",
515
+ namespace: "inputs",
516
+ call: "gui.inputs.rangeDateTimePicker(path, { label?, minDateTime?, maxDateTime?, disabledRanges?, startTimeLabel?, endTimeLabel? })",
517
+ example: "gui.inputs.rangeDateTimePicker('stay', { label: 'Stay', startTimeLabel: 'Check-in', endTimeLabel: 'Check-out' })",
518
+ notes: [
519
+ "POPOVER date-time range picker: the typed `rangeDateTimeInput` as the trigger (pills live there) with the `rangeDateTimeCalendar` in a dropdown. Value is `DateTimeRange[]`. Committing a pill keeps the popover open so several ranges can be added; it closes on outside-click, blur or Escape.",
520
+ "Everything is in instant-space: bounds are **`minDateTime`** / **`maxDateTime`** and **`disabledRanges`** are `DateTimeRange[]` instant spans (block a whole day with `00:00:00`–`23:59:59`). There is no `minDate`/`maxDate`/`minTime`/`maxTime`/`disabledTimeRanges`."
521
+ ]
522
+ },
431
523
  {
432
524
  factory: "rangeDatePicker",
433
525
  namespace: "inputs",
434
526
  call: "gui.inputs.rangeDatePicker(path, { label? })",
435
527
  example: "gui.inputs.rangeDatePicker('stayDates', { label: 'Stay dates' })",
436
528
  notes: ["Popover calendar for a start–end date **range** (the range sibling of `datePicker`)."]
529
+ },
530
+ {
531
+ factory: "rangeTimePicker",
532
+ namespace: "inputs",
533
+ call: "gui.inputs.rangeTimePicker(path, { label?, minTime?, maxTime? })",
534
+ example: "gui.inputs.rangeTimePicker('shift', { label: 'Shift', minTime: '06:00:00', maxTime: '22:00:00' })",
535
+ notes: [
536
+ "Two-list popover for a start–end time **range** (the range sibling of `timePicker`); value is `TimeRange[]`. The out list floors one slot after the chosen in so end is strictly after start."
537
+ ]
437
538
  }
438
539
  ];
439
540
  const ACTIONS = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@golemui/gui-mcp",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "license": "MIT",
5
5
  "description": "Model Context Protocol server for GolemUI — gives AI coding assistants deterministic schema validation and form generation for GolemUI form definitions.",
6
6
  "type": "module",
@@ -40,10 +40,10 @@
40
40
  "ajv": "^8.17.1",
41
41
  "ajv-formats": "^3.0.1",
42
42
  "typescript": "^5.9.2",
43
- "@golemui/gui-schemas": "1.0.2",
44
- "@golemui/gui-shared": "1.0.2",
45
- "@golemui/gui-validators": "1.0.2",
46
- "@golemui/core": "1.0.2",
43
+ "@golemui/gui-schemas": "1.1.0",
44
+ "@golemui/gui-shared": "1.1.0",
45
+ "@golemui/gui-validators": "1.1.0",
46
+ "@golemui/core": "1.1.0",
47
47
  "zod": "^4.0.0",
48
48
  "@standard-schema/spec": "^1.0.0"
49
49
  },
@@ -16,6 +16,13 @@ export type ExpressionFinding = {
16
16
  * We deliberately don't try to fully parse: too easy to get false positives, too little gain.
17
17
  */
18
18
  export declare function lintReactiveExpressions(formDefinition: unknown): ExpressionFinding[];
19
+ export type CheckExpressionOptions = {
20
+ /**
21
+ * True when the expression lives inside a repeater `props.template`, where the
22
+ * `$item` and `$index` scope variables are available.
23
+ */
24
+ inRepeaterTemplate?: boolean;
25
+ };
19
26
  /**
20
27
  * Lint a single reactive expression string in isolation, against the same rules
21
28
  * `lintReactiveExpressions` applies while walking a JSON form definition. This is
@@ -23,4 +30,4 @@ export declare function lintReactiveExpressions(formDefinition: unknown): Expres
23
30
  * object tree, the DX linter has the AST — both funnel each `when` expression
24
31
  * through here so the two surfaces can never drift.
25
32
  */
26
- export declare function checkReactiveExpression(expression: string, path?: string): ExpressionFinding[];
33
+ export declare function checkReactiveExpression(expression: string, path?: string, options?: CheckExpressionOptions): ExpressionFinding[];