@webmcpui/core 0.1.1 → 0.2.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/dist/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
- import * as lit from 'lit';
2
- import { LitElement, CSSResultGroup, TemplateResult, nothing } from 'lit';
3
- import { J as JSONSchema } from './webmcp-DEspBoqq.js';
4
- export { T as ToolDisposer, W as WebMCPToolDefinition, a as WebMCPToolResult, b as WebMCPToolResultContent, e as exposeTool, i as isWebMCPAvailable } from './webmcp-DEspBoqq.js';
1
+ import { LitElement, CSSResultGroup, TemplateResult, nothing, CSSResult } from 'lit';
2
+ import { J as JSONSchema, W as WebMCPToolResult } from './webmcp-DbmbtX6x.js';
3
+ export { T as ToolDisposer, a as WebMCPToolDefinition, b as WebMCPToolResultContent, e as exposeTool, i as isWebMCPAvailable } from './webmcp-DbmbtX6x.js';
5
4
 
6
5
  /**
7
6
  * Minimal Standard Schema v1 types + a validation helper.
@@ -11,6 +10,10 @@ export { T as ToolDisposer, W as WebMCPToolDefinition, a as WebMCPToolResult, b
11
10
  * that implements `~standard`. This is the Skillet-avoidance decision: no
12
11
  * bespoke schema language, zero learning curve.
13
12
  */
13
+ /**
14
+ * The minimal [Standard Schema](https://standardschema.dev) v1 surface this
15
+ * package relies on — implemented by Zod, Valibot, ArkType, and others.
16
+ */
14
17
  interface StandardSchemaV1<Input = unknown, Output = Input> {
15
18
  readonly '~standard': StandardSchemaV1.Props<Input, Output>;
16
19
  }
@@ -41,6 +44,7 @@ declare namespace StandardSchemaV1 {
41
44
  readonly output: Output;
42
45
  }
43
46
  }
47
+ /** The normalized result of {@link validateStandard}: either a value or issues. */
44
48
  interface ValidationOutcome<Output> {
45
49
  /** True when the value passed validation. */
46
50
  readonly valid: boolean;
@@ -57,6 +61,51 @@ declare function validateStandard<Output>(schema: StandardSchemaV1<unknown, Outp
57
61
  /** Duck-type check that an unknown value is a Standard Schema. */
58
62
  declare function isStandardSchema(value: unknown): value is StandardSchemaV1;
59
63
 
64
+ /**
65
+ * Base for every element that can register itself as a WebMCP tool — both the
66
+ * *value* controls ({@link WmcpFormControl}) and the *action* elements
67
+ * ({@link WmcpAction}).
68
+ *
69
+ * It owns only the exposure *mechanism*: the `expose` / `tool-name` /
70
+ * `tool-description` opt-in surface, the tool's lifecycle (register on connect,
71
+ * dispose on disconnect, re-register when its identity changes, drop when
72
+ * `expose` is turned off), and the single `exposeTool` call. The spec-sensitive
73
+ * registration/disposal itself lives one layer down in `exposeTool`, so this is
74
+ * thin wiring over a single source of truth.
75
+ *
76
+ * Each subtree supplies the *policy* via four hooks — {@link resolvedToolName},
77
+ * {@link defaultToolDescription}, {@link toolInputSchema}, {@link executeTool} —
78
+ * plus {@link toolReactiveProps} when extra properties feed the tool's name or
79
+ * description. Abstract — not registered on its own.
80
+ */
81
+ declare abstract class WmcpExposable extends LitElement {
82
+ /** Whether to expose this element as a WebMCP tool. */
83
+ expose: boolean;
84
+ /** Override the generated WebMCP tool name. */
85
+ toolName: string;
86
+ /** Override the generated WebMCP tool description. */
87
+ toolDescription: string;
88
+ private toolDisposer;
89
+ /** The resolved WebMCP tool name. */
90
+ abstract get resolvedToolName(): string;
91
+ /** Description used when `tool-description` is not set. */
92
+ protected abstract get defaultToolDescription(): string;
93
+ /** JSON Schema for the tool's args. Defaults to a no-argument tool. */
94
+ protected toolInputSchema(): JSONSchema;
95
+ /** Invoked when the agent calls the tool; returns the agent-facing result. */
96
+ protected abstract executeTool(args: Record<string, unknown>): WebMCPToolResult | Promise<WebMCPToolResult>;
97
+ /**
98
+ * Property changes that alter the tool's *identity* (name/description) and so
99
+ * require re-registration. State read live inside {@link executeTool} does
100
+ * not belong here. Subclasses extend this with their own naming inputs.
101
+ */
102
+ protected get toolReactiveProps(): readonly string[];
103
+ connectedCallback(): void;
104
+ disconnectedCallback(): void;
105
+ updated(changed: Map<string, unknown>): void;
106
+ protected registerTool(): void;
107
+ }
108
+
60
109
  /**
61
110
  * Base class for form-associated, agent-operable controls.
62
111
  *
@@ -74,8 +123,15 @@ declare function isStandardSchema(value: unknown): value is StandardSchemaV1;
74
123
  * Text-field box appearance for the `.control` element. Used by input,
75
124
  * textarea, and select — the controls that render as a bordered field.
76
125
  */
77
- declare const textFieldStyles: lit.CSSResult;
78
- declare abstract class WmcpFormControl extends LitElement {
126
+ declare const textFieldStyles: CSSResult;
127
+ /**
128
+ * Shared base for every `<wmcp-*>` form control: form association via
129
+ * `ElementInternals`, Standard Schema validation, accessible error messaging,
130
+ * and opt-in WebMCP tool exposure. Each concrete element is a thin subclass
131
+ * that supplies its control markup and tool schema. Abstract — not registered
132
+ * on its own.
133
+ */
134
+ declare abstract class WmcpFormControl extends WmcpExposable {
79
135
  static formAssociated: boolean;
80
136
  static styles: CSSResultGroup;
81
137
  /** Visible label text. */
@@ -91,12 +147,6 @@ declare abstract class WmcpFormControl extends LitElement {
91
147
  helperText: string;
92
148
  /** Message shown when a `required` control is empty. */
93
149
  requiredMessage: string;
94
- /** Whether to expose this control as a WebMCP tool. */
95
- expose: boolean;
96
- /** Override the generated WebMCP tool name. */
97
- toolName: string;
98
- /** Override the generated WebMCP tool description. */
99
- toolDescription: string;
100
150
  /**
101
151
  * Standard Schema validator (Zod, Valibot, ArkType, …). Set as a property,
102
152
  * not an attribute. Validation runs on input and on form validation.
@@ -104,7 +154,6 @@ declare abstract class WmcpFormControl extends LitElement {
104
154
  schema?: StandardSchemaV1<unknown, unknown>;
105
155
  protected error: string;
106
156
  protected readonly internals: ElementInternals;
107
- private toolDisposer;
108
157
  /** Noun used in default tool names/descriptions when `name` is empty. */
109
158
  protected get controlNoun(): string;
110
159
  /** The rendered control element (`<input>` / `<textarea>` / `<select>`). */
@@ -134,9 +183,10 @@ declare abstract class WmcpFormControl extends LitElement {
134
183
  protected get requiredMessageDefault(): string;
135
184
  disconnectedCallback(): void;
136
185
  updated(changed: Map<string, unknown>): void;
137
- /** The resolved WebMCP tool name. */
138
186
  get resolvedToolName(): string;
139
- protected registerTool(): void;
187
+ protected get defaultToolDescription(): string;
188
+ protected get toolReactiveProps(): readonly string[];
189
+ protected executeTool(args: Record<string, unknown>): Promise<WebMCPToolResult>;
140
190
  /**
141
191
  * Apply the agent's tool arguments to component state. Defaults to treating
142
192
  * `args.value` as the new string value; controls with a different shape
@@ -167,10 +217,11 @@ declare abstract class WmcpFormControl extends LitElement {
167
217
  formResetCallback(): void;
168
218
  /** Subclasses render their control element here (id/class "control"). */
169
219
  protected abstract renderControl(): TemplateResult;
170
- protected renderMessage(): TemplateResult<1> | typeof nothing;
171
- render(): TemplateResult<1>;
220
+ protected renderMessage(): TemplateResult | typeof nothing;
221
+ render(): TemplateResult;
172
222
  }
173
223
 
224
+ /** The `type` variants `<wmcp-input>` supports (mirrors native input types). */
174
225
  type WmcpInputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' | 'date';
175
226
  /**
176
227
  * `<wmcp-input>` — a form-associated, agent-operable single-line text input.
@@ -182,12 +233,12 @@ type WmcpInputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' |
182
233
  */
183
234
  declare class WmcpInput extends WmcpFormControl {
184
235
  static readonly tagName = "wmcp-input";
185
- static styles: lit.CSSResultGroup[];
236
+ static styles: CSSResultGroup;
186
237
  /** HTML input type. */
187
238
  type: WmcpInputType;
188
239
  protected get controlNoun(): string;
189
240
  protected toolInputSchema(): JSONSchema;
190
- protected renderControl(): lit.TemplateResult<1>;
241
+ protected renderControl(): TemplateResult;
191
242
  }
192
243
 
193
244
  /**
@@ -201,22 +252,25 @@ declare class WmcpInput extends WmcpFormControl {
201
252
  */
202
253
  declare class WmcpTextarea extends WmcpFormControl {
203
254
  static readonly tagName = "wmcp-textarea";
204
- static styles: lit.CSSResultGroup[];
255
+ static styles: CSSResultGroup;
205
256
  /** Initial visible number of text lines. */
206
257
  rows: number;
207
258
  protected get controlNoun(): string;
208
- protected renderControl(): lit.TemplateResult<1>;
259
+ protected renderControl(): TemplateResult;
209
260
  }
210
261
 
262
+ /** A single selectable option in a `<wmcp-select>`. */
211
263
  interface WmcpSelectOption {
212
264
  value: string;
213
265
  label: string;
214
266
  disabled?: boolean;
215
267
  }
268
+ /** A labelled group of options (renders as an `<optgroup>`). */
216
269
  interface WmcpSelectOptionGroup {
217
270
  label: string;
218
271
  options: WmcpSelectOption[];
219
272
  }
273
+ /** An item in a `<wmcp-select>`'s `items` property — a plain option or a group. */
220
274
  type WmcpSelectItem = WmcpSelectOption | WmcpSelectOptionGroup;
221
275
  /**
222
276
  * `<wmcp-select>` — a form-associated, agent-operable single-select dropdown.
@@ -234,7 +288,7 @@ type WmcpSelectItem = WmcpSelectOption | WmcpSelectOptionGroup;
234
288
  */
235
289
  declare class WmcpSelect extends WmcpFormControl {
236
290
  static readonly tagName = "wmcp-select";
237
- static styles: lit.CSSResultGroup[];
291
+ static styles: CSSResultGroup;
238
292
  /**
239
293
  * Options as data. When non-empty, takes precedence over declarative
240
294
  * `<option>` children. Set as a property, not an attribute.
@@ -254,7 +308,7 @@ declare class WmcpSelect extends WmcpFormControl {
254
308
  flatOptions(): WmcpSelectOption[];
255
309
  protected toolInputSchema(): JSONSchema;
256
310
  private renderOption;
257
- protected renderControl(): lit.TemplateResult<1>;
311
+ protected renderControl(): TemplateResult;
258
312
  }
259
313
 
260
314
  /**
@@ -271,7 +325,7 @@ declare class WmcpSelect extends WmcpFormControl {
271
325
  */
272
326
  declare class WmcpCheckbox extends WmcpFormControl {
273
327
  static readonly tagName = "wmcp-checkbox";
274
- static styles: lit.CSSResultGroup[];
328
+ static styles: CSSResultGroup;
275
329
  /** Whether the box is checked. */
276
330
  checked: boolean;
277
331
  private defaultChecked;
@@ -287,10 +341,11 @@ declare class WmcpCheckbox extends WmcpFormControl {
287
341
  protected stateDescription(): string;
288
342
  formResetCallback(): void;
289
343
  private onToggle;
290
- protected renderControl(): lit.TemplateResult<1>;
291
- render(): lit.TemplateResult<1>;
344
+ protected renderControl(): TemplateResult;
345
+ render(): TemplateResult;
292
346
  }
293
347
 
348
+ /** One choice in a `<wmcp-radio-group>`, set declaratively via the `options` property. */
294
349
  interface WmcpRadioOption {
295
350
  value: string;
296
351
  label: string;
@@ -323,7 +378,7 @@ declare class WmcpRadio extends HTMLElement {
323
378
  */
324
379
  declare class WmcpRadioGroup extends WmcpFormControl {
325
380
  static readonly tagName = "wmcp-radio-group";
326
- static styles: lit.CSSResultGroup[];
381
+ static styles: CSSResultGroup;
327
382
  /** Options as data. When non-empty, takes precedence over `<wmcp-radio>`. */
328
383
  options: WmcpRadioOption[];
329
384
  private resolvedOptions;
@@ -339,8 +394,396 @@ declare class WmcpRadioGroup extends WmcpFormControl {
339
394
  private readDeclarativeOptions;
340
395
  protected toolInputSchema(): JSONSchema;
341
396
  private onSelect;
342
- protected renderControl(): lit.TemplateResult<1>;
343
- render(): lit.TemplateResult<1>;
397
+ protected renderControl(): TemplateResult;
398
+ render(): TemplateResult;
399
+ }
400
+
401
+ /**
402
+ * Base class for agent-operable *action* elements.
403
+ *
404
+ * Where {@link WmcpFormControl} exposes a *value* an agent can set, an action
405
+ * element exposes an *action* an agent can trigger — a click, an open, a
406
+ * dismissal. The WebMCP exposure mechanism (the `expose` surface, the tool
407
+ * lifecycle, the `exposeTool` call) lives in the shared {@link WmcpExposable}
408
+ * base; this layer adds the action-flavored *policy*: a verb-prefixed tool name
409
+ * (`click_save`, `open_booking`), an action-shaped default description, and a
410
+ * no-argument tool by default.
411
+ *
412
+ * A subclass supplies {@link actionVerb} and {@link executeTool}, and may
413
+ * override {@link actionNoun}, {@link defaultNameSuffix}, or
414
+ * {@link toolInputSchema} (e.g. a menu whose action takes which-item). Abstract
415
+ * — not registered on its own.
416
+ *
417
+ * Extracted when the second action element (dialog) landed alongside the first
418
+ * (button) — two data points reveal what's genuinely shared, the same rule
419
+ * that produced `WmcpFormControl`.
420
+ */
421
+ declare abstract class WmcpAction extends WmcpExposable {
422
+ /** Identifier used to build the default tool name. */
423
+ name: string;
424
+ /** Accessible name and the noun used in the default tool description. */
425
+ label: string;
426
+ /** Verb that prefixes the default tool name, e.g. `click` → `click_save`. */
427
+ protected abstract get actionVerb(): string;
428
+ /** Suffix for the default tool name when `name` is empty. */
429
+ protected get defaultNameSuffix(): string;
430
+ /** Human-readable noun for the thing being acted on. */
431
+ protected get actionNoun(): string;
432
+ get resolvedToolName(): string;
433
+ protected get defaultToolDescription(): string;
434
+ protected get toolReactiveProps(): readonly string[];
435
+ /**
436
+ * Perform the action and return the agent-facing result. Called when the
437
+ * agent invokes the tool; subclasses implement the actual effect.
438
+ */
439
+ protected abstract executeTool(args: Record<string, unknown>): WebMCPToolResult | Promise<WebMCPToolResult>;
440
+ }
441
+
442
+ /** Visual variants `<wmcp-button>` supports (shadcn-aligned). */
443
+ type WmcpButtonVariant = 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost';
444
+ /** Size variants `<wmcp-button>` supports. */
445
+ type WmcpButtonSize = 'sm' | 'md' | 'lg';
446
+ /** Native button behaviors `<wmcp-button>` mirrors. */
447
+ type WmcpButtonType = 'button' | 'submit' | 'reset';
448
+ /**
449
+ * `<wmcp-button>` — a themeable, agent-operable button. The first Phase 2
450
+ * interaction primitive.
451
+ *
452
+ * Where the form controls expose a *value* an agent can set, a button exposes
453
+ * an *action* an agent can trigger. When a WebMCP host is present and the
454
+ * button opts in (`expose`), it registers a tool that activates the button
455
+ * exactly as a human click would — running light-DOM `click` handlers and, for
456
+ * `type="submit"`/`"reset"`, driving the associated form. With no agent
457
+ * present (the common case today) it is simply a good, accessible button.
458
+ *
459
+ * Activation has a single path: both a real click and an agent tool call route
460
+ * through the inner native `<button>`, so behavior, focus, and form
461
+ * participation are identical for human and agent. A `disabled` button can be
462
+ * activated by neither.
463
+ *
464
+ * Form-associated, so `type="submit"` and `type="reset"` work from inside the
465
+ * shadow boundary (a native submit button there would not reach the outer
466
+ * form). Visible content is slotted; an explicit `label` is used for the
467
+ * accessible name and the default tool description when set.
468
+ *
469
+ * Not auto-registered — call `defineComponents()` (or load the CDN bundle).
470
+ */
471
+ declare class WmcpButton extends WmcpAction {
472
+ static readonly tagName = "wmcp-button";
473
+ static formAssociated: boolean;
474
+ static shadowRootOptions: ShadowRootInit;
475
+ static styles: CSSResultGroup;
476
+ /** Visual variant. */
477
+ variant: WmcpButtonVariant;
478
+ /** Size. */
479
+ size: WmcpButtonSize;
480
+ /** Native button behavior: a plain button, a form submit, or a form reset. */
481
+ type: WmcpButtonType;
482
+ /** Disables the button for both humans and agents. */
483
+ disabled: boolean;
484
+ private readonly internals;
485
+ /** The inner native `<button>` that owns activation, focus, and a11y. */
486
+ private get button();
487
+ protected get actionVerb(): string;
488
+ protected get defaultNameSuffix(): string;
489
+ protected get actionNoun(): string;
490
+ protected get defaultToolDescription(): string;
491
+ protected executeTool(): WebMCPToolResult;
492
+ /**
493
+ * Activate the button as if a human clicked it: routes through the inner
494
+ * native button so light-DOM `click` handlers fire and `type`-driven form
495
+ * submission/reset happens. A no-op when disabled.
496
+ */
497
+ activate(): void;
498
+ /**
499
+ * Inner-button click handler. The native click already bubbles (composed) to
500
+ * the host, so light-DOM listeners fire without help; this only adds the
501
+ * cross-shadow form behavior a native submit/reset button can't do from here.
502
+ */
503
+ private onInnerClick;
504
+ render(): TemplateResult;
505
+ }
506
+
507
+ /**
508
+ * `<wmcp-dialog>` — a modal dialog whose *action* is being opened. The second
509
+ * Phase 2 interaction primitive, and the one that motivated the shared
510
+ * {@link WmcpAction} base.
511
+ *
512
+ * It wraps the native `<dialog>` element, so it inherits the platform's focus
513
+ * trap, top-layer stacking, backdrop, and Escape-to-close for free. The
514
+ * exposed WebMCP action is **open** — the agent surfaces the dialog for the
515
+ * user to review; closing/confirming stays a deliberate human (or
516
+ * programmatic) step. That asymmetry is the consent gate: an agent can ask for
517
+ * attention, but the irreversible confirm is the person's to make.
518
+ *
519
+ * Drive it declaratively with the reflected `open` attribute or imperatively
520
+ * with {@link show} / {@link close}; either way it emits composed `open` and
521
+ * `close` events. With no agent present it is simply an accessible modal.
522
+ *
523
+ * Not auto-registered — call `defineComponents()` (or load the CDN bundle).
524
+ */
525
+ declare class WmcpDialog extends WmcpAction {
526
+ static readonly tagName = "wmcp-dialog";
527
+ static styles: CSSResultGroup;
528
+ /** Whether the dialog is open (reflected, so `[open]` styling works). */
529
+ open: boolean;
530
+ /** Open as a modal (focus-trapping, with backdrop). Set false for non-modal. */
531
+ modal: boolean;
532
+ /** Keep the dialog open when the backdrop is clicked (modal "static" mode). */
533
+ staticBackdrop: boolean;
534
+ /** Last `returnValue` the dialog closed with (mirrors native `<dialog>`). */
535
+ returnValue: string;
536
+ private get dialogEl();
537
+ protected get actionVerb(): string;
538
+ protected get defaultNameSuffix(): string;
539
+ protected get defaultToolDescription(): string;
540
+ protected executeTool(): WebMCPToolResult;
541
+ updated(changed: Map<string, unknown>): void;
542
+ /** Open the dialog (modal unless `modal` is false). */
543
+ show(): void;
544
+ /** Close the dialog, optionally recording a `returnValue`. */
545
+ close(returnValue?: string): void;
546
+ /** Reconcile our `open` state with the native dialog's imperative API. */
547
+ private syncNativeOpen;
548
+ /** Native `close` fires for Escape, backdrop, or our own `close()`. */
549
+ private onNativeClose;
550
+ /**
551
+ * Close on a backdrop click. A click whose target is the `<dialog>` itself
552
+ * is the backdrop — content clicks retarget to `.panel` or its children — so
553
+ * this never fires on the dialog's own frame or a text drag-select.
554
+ */
555
+ private onDialogClick;
556
+ render(): TemplateResult;
557
+ }
558
+
559
+ /** A single selectable item in a `<wmcp-menu>`. */
560
+ interface WmcpMenuItem {
561
+ value: string;
562
+ label: string;
563
+ disabled?: boolean;
564
+ }
565
+ /**
566
+ * `<wmcp-menu>` — a menu-button whose exposed action is *selecting an item*.
567
+ * The first **parameterized** interaction primitive: where button and dialog
568
+ * expose no-argument actions, the menu's tool takes *which item* — an `enum`
569
+ * of the item values — so it pressure-tests the {@link WmcpAction} base the
570
+ * way `<wmcp-select>` did for `WmcpFormControl`.
571
+ *
572
+ * The popup uses the native Popover API (top layer, light-dismiss, and Escape
573
+ * for free); items come from declarative `<option>` children (no build) or the
574
+ * `items` property. Selecting an item — by human click, keyboard, or agent
575
+ * tool call — fires a composed `select` event (`detail: { value, label }`) and
576
+ * closes the menu. A menu dispatches actions; it does not hold a value.
577
+ *
578
+ * Not auto-registered — call `defineComponents()` (or load the CDN bundle).
579
+ */
580
+ declare class WmcpMenu extends WmcpAction {
581
+ static readonly tagName = "wmcp-menu";
582
+ static styles: CSSResultGroup;
583
+ /** Trigger label. */
584
+ label: string;
585
+ /**
586
+ * Items as data. When non-empty, takes precedence over declarative
587
+ * `<option>` children. Set as a property, not an attribute.
588
+ */
589
+ items: WmcpMenuItem[];
590
+ /** Whether the popup is open (reflected). */
591
+ open: boolean;
592
+ /** The normalized item model actually rendered (property or declarative). */
593
+ private resolvedItems;
594
+ private itemObserver?;
595
+ private get menuEl();
596
+ private get itemButtons();
597
+ protected get actionVerb(): string;
598
+ protected get defaultNameSuffix(): string;
599
+ protected get actionNoun(): string;
600
+ protected get defaultToolDescription(): string;
601
+ protected get toolReactiveProps(): readonly string[];
602
+ protected toolInputSchema(): JSONSchema;
603
+ protected executeTool(args: Record<string, unknown>): WebMCPToolResult;
604
+ connectedCallback(): void;
605
+ disconnectedCallback(): void;
606
+ willUpdate(changed: Map<string, unknown>): void;
607
+ private syncItems;
608
+ private readDeclarativeItems;
609
+ /** Dispatch the selection and close the menu. */
610
+ private selectItem;
611
+ private onItemClick;
612
+ /** Sync `open`/`aria-expanded` and move focus into the menu when it opens. */
613
+ private onToggle;
614
+ /** Roving focus among items with the arrow / Home / End keys. */
615
+ private onMenuKeydown;
616
+ render(): TemplateResult;
617
+ }
618
+
619
+ /** A single tab derived from a `[tab]` panel child of `<wmcp-tabs>`. */
620
+ interface WmcpTabInfo {
621
+ value: string;
622
+ label: string;
623
+ disabled?: boolean;
624
+ }
625
+ /**
626
+ * `<wmcp-tabs>` — a tab set whose exposed action is *switching the active tab*.
627
+ * The first **stateful** interaction primitive: where button/dialog/menu are
628
+ * fire-and-forget dispatchers, a tab set holds a persistent `active` selection
629
+ * (reflected), and the agent's tool both reads and changes it.
630
+ *
631
+ * It confirms the {@link WmcpAction} base needs no "current value" concept — a
632
+ * stateful action element simply owns its own state (here `active`, like the
633
+ * dialog owns `open`) and its `executeTool` mutates it.
634
+ *
635
+ * Panels are declarative light-DOM children carrying a `tab` attribute (and an
636
+ * optional `tab-label`); the tablist is derived from them. Switching — by
637
+ * click, arrow keys, or agent — updates `active`, reveals the matching panel,
638
+ * and fires a composed `change` event (`detail: { value }`).
639
+ *
640
+ * Not auto-registered — call `defineComponents()` (or load the CDN bundle).
641
+ */
642
+ declare class WmcpTabs extends WmcpAction {
643
+ static readonly tagName = "wmcp-tabs";
644
+ static styles: CSSResultGroup;
645
+ /** The value of the active tab (reflected — this is the persistent state). */
646
+ active: string;
647
+ /** Accessible name for the tablist. */
648
+ label: string;
649
+ /** The tab model derived from the `[tab]` panel children. */
650
+ private tabs;
651
+ private panelObserver?;
652
+ protected get actionVerb(): string;
653
+ protected get defaultNameSuffix(): string;
654
+ protected get actionNoun(): string;
655
+ protected get defaultToolDescription(): string;
656
+ protected get toolReactiveProps(): readonly string[];
657
+ protected toolInputSchema(): JSONSchema;
658
+ protected executeTool(args: Record<string, unknown>): WebMCPToolResult;
659
+ connectedCallback(): void;
660
+ disconnectedCallback(): void;
661
+ updated(changed: Map<string, unknown>): void;
662
+ /** Light-DOM children that declare a tab via the `tab` attribute. */
663
+ private get panelEls();
664
+ private syncTabs;
665
+ /** Fall back to the first enabled tab when `active` is unset or invalid. */
666
+ private ensureActive;
667
+ /** Reflect the active tab onto the slotted panels (roles, labels, hidden). */
668
+ private applyPanels;
669
+ /** Switch the active tab, firing `change` when it actually moves. */
670
+ switchTo(value: string): void;
671
+ private get tabButtons();
672
+ /** Arrow / Home / End roving with automatic activation (ARIA tabs pattern). */
673
+ private onKeydown;
674
+ render(): TemplateResult;
675
+ }
676
+
677
+ /** Where the panel sits relative to its trigger. */
678
+ type WmcpPopoverPlacement = 'top' | 'bottom' | 'left' | 'right';
679
+ /** How the popover is opened: clicked (interactive) or hovered (tooltip). */
680
+ type WmcpPopoverTrigger = 'click' | 'hover';
681
+ /**
682
+ * `<wmcp-popover>` — a non-modal, anchored floating panel whose exposed action
683
+ * is being opened. The sibling of [dialog](./dialog.ts) (modal) and
684
+ * [menu](./menu.ts) (action list): same native-Popover-API + CSS-anchor
685
+ * machinery as the menu, but the content is arbitrary.
686
+ *
687
+ * `trigger="click"` (default) gives an interactive popover — click to toggle,
688
+ * with light-dismiss and Escape for free. `trigger="hover"` gives a tooltip —
689
+ * it opens on hover/focus, closes on leave/blur, and labels its trigger via
690
+ * `aria-describedby`. Either way the agent can `open` it; closing stays a
691
+ * human/light-dismiss step, the same consent posture as the dialog.
692
+ *
693
+ * Not auto-registered — call `defineComponents()` (or load the CDN bundle).
694
+ */
695
+ declare class WmcpPopover extends WmcpAction {
696
+ static readonly tagName = "wmcp-popover";
697
+ static styles: CSSResultGroup;
698
+ /** Whether the panel is open (reflected). */
699
+ open: boolean;
700
+ /** Trigger text, used when no `trigger` slot content is provided. */
701
+ label: string;
702
+ /** Panel placement relative to the trigger. */
703
+ placement: WmcpPopoverPlacement;
704
+ /** Open on click (interactive popover) or on hover/focus (tooltip). */
705
+ trigger: WmcpPopoverTrigger;
706
+ private get panelEl();
707
+ protected get actionVerb(): string;
708
+ protected get defaultNameSuffix(): string;
709
+ protected get defaultToolDescription(): string;
710
+ protected executeTool(): WebMCPToolResult;
711
+ updated(changed: Map<string, unknown>): void;
712
+ /** Open the popover. */
713
+ show(): void;
714
+ /** Close the popover. */
715
+ close(): void;
716
+ private syncNativeOpen;
717
+ /** Native toggle fires for clicks, light-dismiss, Escape, and our own calls. */
718
+ private onToggle;
719
+ private closeTimer?;
720
+ disconnectedCallback(): void;
721
+ /** Open on hover/focus of the trigger *or* the panel. */
722
+ private openOnHover;
723
+ /**
724
+ * Close on leave/blur — but on a short delay, so the pointer can cross the
725
+ * gap from the trigger to the panel (and reach interactive content inside it)
726
+ * without the popover vanishing. Re-entering either cancels the close.
727
+ */
728
+ private scheduleHoverClose;
729
+ private cancelScheduledClose;
730
+ render(): TemplateResult;
731
+ }
732
+
733
+ /** A toast's severity, used for styling and the agent-readable summary. */
734
+ type WmcpToastVariant = 'info' | 'success' | 'warning' | 'error';
735
+ /** Options accepted by {@link WmcpToast.show}. */
736
+ interface WmcpToastOptions {
737
+ title?: string;
738
+ message: string;
739
+ variant?: WmcpToastVariant;
740
+ /** Auto-dismiss after this many ms; `0` keeps it until dismissed. */
741
+ duration?: number;
742
+ }
743
+ /**
744
+ * `<wmcp-toast>` — a notification region, and the one component whose agent
745
+ * surface is *perceiving* rather than *actuating*.
746
+ *
747
+ * Page code throws toasts the way it always has — `el.show({ message })` — and
748
+ * they announce to screen readers via an `aria-live` region. When `expose` is
749
+ * set, the very same notifications become readable by an agent through a
750
+ * `read_<name>` tool: the machine-readable twin of the `aria-live`
751
+ * announcement. An agent acting on the user's behalf often has no other way to
752
+ * learn an outcome ("Payment declined", an async "Export ready"), so it reads
753
+ * the toasts rather than posting them.
754
+ *
755
+ * Extends {@link WmcpExposable} directly — not {@link WmcpAction} — because the
756
+ * tool reports state instead of triggering an action.
757
+ *
758
+ * Not auto-registered — call `defineComponents()` (or load the CDN bundle).
759
+ */
760
+ declare class WmcpToast extends WmcpExposable {
761
+ static readonly tagName = "wmcp-toast";
762
+ static styles: CSSResultGroup;
763
+ /** Identifier used for the default tool name (`read_<name>`). */
764
+ name: string;
765
+ /** Accessible name for the live region. */
766
+ label: string;
767
+ /** Corner the toasts stack in. */
768
+ placement: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
769
+ /** Default auto-dismiss in ms; `0` keeps toasts until dismissed. */
770
+ duration: number;
771
+ private toasts;
772
+ private recent;
773
+ private nextId;
774
+ private timers;
775
+ /** Show a toast. Returns its id (pass to {@link dismiss}). */
776
+ show(options: WmcpToastOptions): number;
777
+ /** Dismiss a toast by id. */
778
+ dismiss(id: number): void;
779
+ /** Dismiss all visible toasts. */
780
+ clear(): void;
781
+ disconnectedCallback(): void;
782
+ get resolvedToolName(): string;
783
+ protected get defaultToolDescription(): string;
784
+ protected get toolReactiveProps(): readonly string[];
785
+ protected executeTool(): WebMCPToolResult;
786
+ render(): TemplateResult;
344
787
  }
345
788
 
346
789
  /**
@@ -349,7 +792,7 @@ declare class WmcpRadioGroup extends WmcpFormControl {
349
792
  */
350
793
  declare function defineComponents(): void;
351
794
 
352
- export { JSONSchema, StandardSchemaV1, type ValidationOutcome, WmcpCheckbox, WmcpFormControl, WmcpInput, type WmcpInputType, WmcpRadio, WmcpRadioGroup, type WmcpRadioOption, WmcpSelect, type WmcpSelectItem, type WmcpSelectOption, type WmcpSelectOptionGroup, WmcpTextarea, defineComponents, isStandardSchema, textFieldStyles, validateStandard };
795
+ export { JSONSchema, StandardSchemaV1, type ValidationOutcome, WebMCPToolResult, WmcpAction, WmcpButton, type WmcpButtonSize, type WmcpButtonType, type WmcpButtonVariant, WmcpCheckbox, WmcpDialog, WmcpExposable, WmcpFormControl, WmcpInput, type WmcpInputType, WmcpMenu, type WmcpMenuItem, WmcpPopover, type WmcpPopoverPlacement, type WmcpPopoverTrigger, WmcpRadio, WmcpRadioGroup, type WmcpRadioOption, WmcpSelect, type WmcpSelectItem, type WmcpSelectOption, type WmcpSelectOptionGroup, type WmcpTabInfo, WmcpTabs, WmcpTextarea, WmcpToast, type WmcpToastOptions, type WmcpToastVariant, defineComponents, isStandardSchema, textFieldStyles, validateStandard };
353
796
 
354
797
  declare global {
355
798
  interface HTMLElementTagNameMap {
@@ -359,5 +802,11 @@ declare global {
359
802
  'wmcp-checkbox': import('./index.js').WmcpCheckbox;
360
803
  'wmcp-radio': import('./index.js').WmcpRadio;
361
804
  'wmcp-radio-group': import('./index.js').WmcpRadioGroup;
805
+ 'wmcp-button': import('./index.js').WmcpButton;
806
+ 'wmcp-dialog': import('./index.js').WmcpDialog;
807
+ 'wmcp-menu': import('./index.js').WmcpMenu;
808
+ 'wmcp-tabs': import('./index.js').WmcpTabs;
809
+ 'wmcp-popover': import('./index.js').WmcpPopover;
810
+ 'wmcp-toast': import('./index.js').WmcpToast;
362
811
  }
363
812
  }