@tai42/studio-sdk 6.2.0 → 7.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.
Files changed (69) hide show
  1. package/dist/components/field.d.ts +14 -1
  2. package/dist/components/field.d.ts.map +1 -1
  3. package/dist/components/field.js +5 -2
  4. package/dist/components/field.js.map +1 -1
  5. package/dist/expression/ExpressionField.d.ts +140 -0
  6. package/dist/expression/ExpressionField.d.ts.map +1 -0
  7. package/dist/expression/ExpressionField.js +88 -0
  8. package/dist/expression/ExpressionField.js.map +1 -0
  9. package/dist/expression/context.d.ts +50 -0
  10. package/dist/expression/context.d.ts.map +1 -0
  11. package/dist/expression/context.js +53 -0
  12. package/dist/expression/context.js.map +1 -0
  13. package/dist/expression/types.d.ts +157 -0
  14. package/dist/expression/types.d.ts.map +1 -0
  15. package/dist/expression/types.js +11 -0
  16. package/dist/expression/types.js.map +1 -0
  17. package/dist/hooks/useApi.d.ts +8 -0
  18. package/dist/hooks/useApi.d.ts.map +1 -1
  19. package/dist/index.d.ts +6 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +4 -0
  22. package/dist/index.js.map +1 -1
  23. package/dist/plugin/registry.d.ts.map +1 -1
  24. package/dist/plugin/registry.js +39 -1
  25. package/dist/plugin/registry.js.map +1 -1
  26. package/dist/plugin/types.d.ts +31 -0
  27. package/dist/plugin/types.d.ts.map +1 -1
  28. package/dist/schema-editor/SchemaEditor.d.ts.map +1 -1
  29. package/dist/schema-editor/SchemaEditor.js +8 -4
  30. package/dist/schema-editor/SchemaEditor.js.map +1 -1
  31. package/dist/schema-form/classify.d.ts +5 -3
  32. package/dist/schema-form/classify.d.ts.map +1 -1
  33. package/dist/schema-form/classify.js +42 -16
  34. package/dist/schema-form/classify.js.map +1 -1
  35. package/dist/schema-form/default-value.d.ts.map +1 -1
  36. package/dist/schema-form/default-value.js +4 -1
  37. package/dist/schema-form/default-value.js.map +1 -1
  38. package/dist/schema-form/field-node.d.ts.map +1 -1
  39. package/dist/schema-form/field-node.js +3 -3
  40. package/dist/schema-form/field-node.js.map +1 -1
  41. package/dist/schema-form/json-field.d.ts +14 -0
  42. package/dist/schema-form/json-field.d.ts.map +1 -0
  43. package/dist/schema-form/json-field.js +104 -0
  44. package/dist/schema-form/json-field.js.map +1 -0
  45. package/dist/schema-form/types.d.ts +2 -2
  46. package/dist/schema-form/types.js +2 -2
  47. package/dist/schema-form/validate.d.ts.map +1 -1
  48. package/dist/schema-form/validate.js +11 -4
  49. package/dist/schema-form/validate.js.map +1 -1
  50. package/package.json +2 -2
  51. package/src/components/field.tsx +20 -2
  52. package/src/expression/ExpressionField.tsx +330 -0
  53. package/src/expression/context.tsx +83 -0
  54. package/src/expression/types.ts +164 -0
  55. package/src/index.ts +22 -0
  56. package/src/plugin/registry.ts +50 -1
  57. package/src/plugin/types.ts +32 -0
  58. package/src/schema-editor/SchemaEditor.tsx +8 -4
  59. package/src/schema-form/classify.ts +103 -18
  60. package/src/schema-form/default-value.ts +4 -1
  61. package/src/schema-form/field-node.tsx +7 -4
  62. package/src/schema-form/json-field.tsx +143 -0
  63. package/src/schema-form/types.ts +2 -2
  64. package/src/schema-form/validate.ts +10 -4
  65. package/dist/schema-form/unsupported-notice.d.ts +0 -18
  66. package/dist/schema-form/unsupported-notice.d.ts.map +0 -1
  67. package/dist/schema-form/unsupported-notice.js +0 -8
  68. package/dist/schema-form/unsupported-notice.js.map +0 -1
  69. package/src/schema-form/unsupported-notice.tsx +0 -39
@@ -59,6 +59,19 @@ export interface FieldProps {
59
59
  * `group`.
60
60
  */
61
61
  readonly group?: boolean;
62
+ /**
63
+ * Render the label for ASSISTIVE TECH ONLY — visually hidden, but still the
64
+ * control's accessible name through the very same `<label for>` (or, in a group,
65
+ * the same `aria-labelledby`). The label element stays in the DOM behind
66
+ * `tai-visually-hidden`, so nothing about the accessible name changes; only its
67
+ * paint is dropped. It is the standard idiom for a dense grid of otherwise
68
+ * identical fields, where each row needs a UNIQUE, addressable name (a
69
+ * voice-control user can only say a name that exists) but there is no room for a
70
+ * visible label on every row — the same trade `RadioGroup`'s `visuallyHiddenLabel`
71
+ * and `ViewToggle` make. The label text still governs WCAG 2.5.3 (Label in Name),
72
+ * so a caller passes the real per-row name as `label`, not a decoration.
73
+ */
74
+ readonly hideLabel?: boolean;
62
75
  }
63
- export declare function Field({ label, description, error, children, style, className, group, }: FieldProps): import("react").JSX.Element;
76
+ export declare function Field({ label, description, error, children, style, className, group, hideLabel, }: FieldProps): import("react").JSX.Element;
64
77
  //# sourceMappingURL=field.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/components/field.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAYtD,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,cAAc,EAAE,IAAI,GAAG,SAAS,CAAC;CAC3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,IAAI,iBAAiB,CAUnD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,sFAAsF;IACtF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,KAAK,EACL,SAAS,EACT,KAAa,GACd,EAAE,UAAU,+BAiEZ"}
1
+ {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../src/components/field.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAYtD,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,cAAc,EAAE,IAAI,GAAG,SAAS,CAAC;CAC3C;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,IAAI,iBAAiB,CAUnD;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,sFAAsF;IACtF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,KAAK,EACL,SAAS,EACT,KAAa,EACb,SAAiB,GAClB,EAAE,UAAU,+BAqEZ"}
@@ -31,7 +31,7 @@ export function useFieldControl() {
31
31
  'aria-invalid': ctx.invalid ? true : undefined,
32
32
  };
33
33
  }
34
- export function Field({ label, description, error, children, style, className, group = false, }) {
34
+ export function Field({ label, description, error, children, style, className, group = false, hideLabel = false, }) {
35
35
  const controlId = useId();
36
36
  const labelId = `${controlId}-label`;
37
37
  const descriptionId = `${controlId}-desc`;
@@ -51,6 +51,9 @@ export function Field({ label, description, error, children, style, className, g
51
51
  const value = group
52
52
  ? { controlId: undefined, describedBy: undefined, invalid: error !== undefined }
53
53
  : { controlId, describedBy, invalid: error !== undefined };
54
- return (_jsx(FieldContext.Provider, { value: value, children: _jsxs("div", { className: className === undefined ? 'tai-field' : `tai-field ${className}`, style: style, children: [group ? (_jsx("span", { id: labelId, className: "tai-field-label", children: label })) : (_jsx("label", { id: labelId, htmlFor: controlId, className: "tai-field-label", children: label })), group ? (_jsx("div", { role: "group", "aria-labelledby": labelId, "aria-describedby": describedBy, className: "tai-field-group", children: children })) : (children), description !== undefined ? (_jsx("p", { id: descriptionId, className: "tai-field-hint", style: { margin: 0 }, children: description })) : null, error !== undefined ? (_jsxs("p", { id: errorId, role: "alert", className: "tai-field-error", style: { margin: 0 }, children: [_jsx(XCircleIcon, {}), error] })) : null] }) }));
54
+ // The label keeps its `htmlFor`/`id` wiring either way — `hideLabel` only drops
55
+ // its PAINT, so the accessible name it gives the control is unchanged.
56
+ const labelClassName = hideLabel ? 'tai-field-label tai-visually-hidden' : 'tai-field-label';
57
+ return (_jsx(FieldContext.Provider, { value: value, children: _jsxs("div", { className: className === undefined ? 'tai-field' : `tai-field ${className}`, style: style, children: [group ? (_jsx("span", { id: labelId, className: labelClassName, children: label })) : (_jsx("label", { id: labelId, htmlFor: controlId, className: labelClassName, children: label })), group ? (_jsx("div", { role: "group", "aria-labelledby": labelId, "aria-describedby": describedBy, className: "tai-field-group", children: children })) : (children), description !== undefined ? (_jsx("p", { id: descriptionId, className: "tai-field-hint", style: { margin: 0 }, children: description })) : null, error !== undefined ? (_jsxs("p", { id: errorId, role: "alert", className: "tai-field-error", style: { margin: 0 }, children: [_jsx(XCircleIcon, {}), error] })) : null] }) }));
55
58
  }
56
59
  //# sourceMappingURL=field.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"field.js","sourceRoot":"","sources":["../../src/components/field.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"field.js","sourceRoot":"","sources":["../../src/components/field.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * `ExpressionField` — the SDK's expression-authoring control. It is a plain SDK
3
+ * text field (a `Field` wrapping a `Textarea`, or a `TextInput` when
4
+ * `multiline={false}`) that GROWS a "visual editor" affordance only when a plugin
5
+ * has contributed an editor for the field's language. With no editor registered —
6
+ * or no {@link ExpressionEditorsProvider} mounted above it — it stays exactly a
7
+ * text field, so a consumer adopts it with no dependency on any editor being
8
+ * installed (graceful absence).
9
+ *
10
+ * The launcher half — the button that lazily loads the editor behind `Suspense`,
11
+ * warms its chunk on open-intent, and turns a `load()` rejection into a loud
12
+ * inline error — is the standalone {@link ExpressionEditorLauncher}, exported so a
13
+ * dense grid can compose its OWN input + an icon-only door in one row and reuse
14
+ * this exact mount semantics rather than reimplementing them. `ExpressionField`
15
+ * consumes that same component internally, so there is one source of truth for how
16
+ * an editor is mounted.
17
+ *
18
+ * The interaction is ported from babelfish's `jq-editor-button.tsx` but styled
19
+ * with SDK primitives and generalised to any {@link ExpressionLanguage}: the
20
+ * whole {@link ExpressionFieldDeclaration} threads onto the editor, so its context
21
+ * chip, Test seeding, and server-validate hook all read from one object, and each
22
+ * degrades on its own when absent.
23
+ */
24
+ import { type InputHTMLAttributes, type ReactElement, type TextareaHTMLAttributes } from 'react';
25
+ import type { ExpressionFieldDeclaration } from './types';
26
+ /**
27
+ * The native attributes {@link ExpressionField} FORWARDS to its underlying control
28
+ * (`Textarea` or, single-line, `TextInput`), minus the ones the field owns itself.
29
+ * Intersecting both attribute sets keeps the pass-through valid whichever element
30
+ * `multiline` selects, and omitting the owned keys keeps a caller from
31
+ * accidentally severing the value/edit wiring or the monospace class. This is the
32
+ * `inputs.tsx` pass-through doctrine (a caller's native attribute reaches the
33
+ * element) narrowed to what a field can safely surrender — `name`, `onBlur`,
34
+ * `maxLength`, `style`, `data-*`, and the like.
35
+ */
36
+ export type ExpressionControlProps = Omit<TextareaHTMLAttributes<HTMLTextAreaElement> & InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'disabled' | 'rows' | 'placeholder' | 'className' | 'spellCheck' | 'children'>;
37
+ export interface ExpressionEditorLauncherProps {
38
+ /** What language the field authors, what its input is, and how to sample/validate it. */
39
+ readonly declaration: ExpressionFieldDeclaration;
40
+ /** The field's current expression ('' when unset), the editor seeds itself with. */
41
+ readonly value: string;
42
+ /** Called with the authored expression when the user saves in the editor. */
43
+ readonly onSave: (expression: string) => void;
44
+ /** The label the editor titles itself with; also enriches the launcher's name. */
45
+ readonly fieldLabel: string;
46
+ /** Icon-only launcher for narrow rows; the full name rides `aria-label`. */
47
+ readonly compact?: boolean;
48
+ /**
49
+ * Open the editor READ-ONLY (no Save). This is the launcher's ONLY blocking knob:
50
+ * a launcher has no inline textarea to disable, so — unlike {@link ExpressionField}'s
51
+ * `disabled`, which conflates textarea-disabled with editor-read-only — the door
52
+ * expresses author-blocking solely here. {@link ExpressionField} maps its own
53
+ * `disabled` onto this by default, and its `editorReadOnly` overrides that.
54
+ */
55
+ readonly editorReadOnly?: boolean;
56
+ /**
57
+ * Override the launcher's hover `title` (e.g. a rerun/side-effect hint). Absent,
58
+ * the title is derived from the declaration's shape ("Visual editor · input: …").
59
+ */
60
+ readonly title?: string;
61
+ }
62
+ /**
63
+ * The launcher + lazily-loaded editor for one expression field, standalone so a
64
+ * compact grid can drop it beside its own input. It resolves the contributed
65
+ * editor for `declaration.language` itself and renders NOTHING when none is
66
+ * registered (or no {@link ExpressionEditorsProvider} is mounted) — the same
67
+ * graceful absence {@link ExpressionField} degrades to a plain text field on.
68
+ */
69
+ export declare function ExpressionEditorLauncher({ declaration, value, onSave, fieldLabel, compact, editorReadOnly, title, }: ExpressionEditorLauncherProps): ReactElement | null;
70
+ export interface ExpressionFieldProps {
71
+ /** The `Field` label; also the editor's title unless {@link fieldLabel} overrides it. */
72
+ readonly label: string;
73
+ /**
74
+ * Render the label for assistive tech only (visually hidden) — for a dense grid
75
+ * of otherwise-identical expression rows that each need a unique, addressable
76
+ * name but have no room for a visible label. The `label` text is still the
77
+ * accessible name (see {@link Field.hideLabel}).
78
+ */
79
+ readonly hideLabel?: boolean;
80
+ /** Optional field description rendered under the control. */
81
+ readonly description?: string;
82
+ /** Optional error rendered under the control (also flags the field invalid). */
83
+ readonly error?: string;
84
+ /** What language the field authors, what its input is, and how to sample/validate it. */
85
+ readonly declaration: ExpressionFieldDeclaration;
86
+ /** The field's current expression ('' when unset). */
87
+ readonly value: string;
88
+ /** Called with the new expression on both textarea edits and an editor save. */
89
+ readonly onChange: (expression: string) => void;
90
+ /**
91
+ * Disables INLINE editing (the textarea/input is `disabled`). By default it also
92
+ * opens the editor read-only, so a blocked value can still be inspected; pass
93
+ * {@link editorReadOnly} to decouple the two.
94
+ */
95
+ readonly disabled?: boolean;
96
+ /**
97
+ * Whether the visual editor opens READ-ONLY, independent of {@link disabled}.
98
+ * Defaults to `disabled` — the historical coupling — so a caller that never sets
99
+ * it keeps today's behaviour. Set it `false` to let the editor author a value
100
+ * whose textarea is disabled, or `true` to lock the editor while the textarea
101
+ * stays editable.
102
+ */
103
+ readonly editorReadOnly?: boolean;
104
+ /** Icon-only launcher for narrow rows; the full name rides `aria-label`. */
105
+ readonly compact?: boolean;
106
+ /** The label the editor titles itself with; defaults to {@link label}. */
107
+ readonly fieldLabel?: string;
108
+ /**
109
+ * Author the field on a SINGLE line — a `TextInput` instead of a `Textarea` —
110
+ * for a per-argument grid row. Defaults to `true` (multiline). The visual-editor
111
+ * launcher is unaffected.
112
+ */
113
+ readonly multiline?: boolean;
114
+ /**
115
+ * Render the expression content in the design system's monospace face. Defaults
116
+ * to TRUE: an expression is code, and code reads in a mono font (jq filters,
117
+ * paths, and operators align and disambiguate `l`/`1`/`I` there) — the same face
118
+ * every jq surface in the ecosystem paints. A prose-ish field can opt out with
119
+ * `false`.
120
+ */
121
+ readonly monospace?: boolean;
122
+ /**
123
+ * Override the launcher button's hover `title` (e.g. a rerun/side-effect hint),
124
+ * threaded to {@link ExpressionEditorLauncher.title}.
125
+ */
126
+ readonly launcherTitle?: string;
127
+ /** Textarea row count (defaults to the SDK `Textarea` default); ignored when single-line. */
128
+ readonly rows?: number;
129
+ /** Textarea/input placeholder. */
130
+ readonly placeholder?: string;
131
+ /**
132
+ * Narrow native-attribute pass-through to the underlying control — `name`,
133
+ * `onBlur`, `maxLength`, `style`, `data-*`, and the like. The field owns
134
+ * value/onChange/disabled/rows/placeholder/spellCheck and the monospace class, so
135
+ * those are not forwardable (see {@link ExpressionControlProps}).
136
+ */
137
+ readonly textareaProps?: ExpressionControlProps;
138
+ }
139
+ export declare function ExpressionField({ label, hideLabel, description, error, declaration, value, onChange, disabled, editorReadOnly, compact, fieldLabel, multiline, monospace, launcherTitle, rows, placeholder, textareaProps, }: ExpressionFieldProps): ReactElement;
140
+ //# sourceMappingURL=ExpressionField.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpressionField.d.ts","sourceRoot":"","sources":["../../src/expression/ExpressionField.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * `ExpressionField` — the SDK's expression-authoring control. It is a plain SDK
4
+ * text field (a `Field` wrapping a `Textarea`, or a `TextInput` when
5
+ * `multiline={false}`) that GROWS a "visual editor" affordance only when a plugin
6
+ * has contributed an editor for the field's language. With no editor registered —
7
+ * or no {@link ExpressionEditorsProvider} mounted above it — it stays exactly a
8
+ * text field, so a consumer adopts it with no dependency on any editor being
9
+ * installed (graceful absence).
10
+ *
11
+ * The launcher half — the button that lazily loads the editor behind `Suspense`,
12
+ * warms its chunk on open-intent, and turns a `load()` rejection into a loud
13
+ * inline error — is the standalone {@link ExpressionEditorLauncher}, exported so a
14
+ * dense grid can compose its OWN input + an icon-only door in one row and reuse
15
+ * this exact mount semantics rather than reimplementing them. `ExpressionField`
16
+ * consumes that same component internally, so there is one source of truth for how
17
+ * an editor is mounted.
18
+ *
19
+ * The interaction is ported from babelfish's `jq-editor-button.tsx` but styled
20
+ * with SDK primitives and generalised to any {@link ExpressionLanguage}: the
21
+ * whole {@link ExpressionFieldDeclaration} threads onto the editor, so its context
22
+ * chip, Test seeding, and server-validate hook all read from one object, and each
23
+ * degrades on its own when absent.
24
+ */
25
+ import { Suspense, lazy, useMemo, useState, } from 'react';
26
+ import { Button, Spinner } from '../components/primitives';
27
+ import { ErrorBoundary } from '../components/error-boundary';
28
+ import { Field } from '../components/field';
29
+ import { TextInput, Textarea } from '../components/inputs';
30
+ import { GridIcon } from '../components/icons';
31
+ import { useExpressionEditor } from './context';
32
+ /**
33
+ * The launcher + lazily-loaded editor for one expression field, standalone so a
34
+ * compact grid can drop it beside its own input. It resolves the contributed
35
+ * editor for `declaration.language` itself and renders NOTHING when none is
36
+ * registered (or no {@link ExpressionEditorsProvider} is mounted) — the same
37
+ * graceful absence {@link ExpressionField} degrades to a plain text field on.
38
+ */
39
+ export function ExpressionEditorLauncher({ declaration, value, onSave, fieldLabel, compact = false, editorReadOnly = false, title, }) {
40
+ const contribution = useExpressionEditor(declaration.language);
41
+ const [open, setOpen] = useState(false);
42
+ // A fresh lazy wrapper per contribution: the module resolves once and React
43
+ // caches it, so re-opening the editor does not re-fetch the chunk.
44
+ const LazyEditor = useMemo(() => contribution === null
45
+ ? null
46
+ : lazy(() => contribution.load().then((module) => ({ default: module.Editor }))), [contribution]);
47
+ if (contribution === null || LazyEditor === null)
48
+ return null;
49
+ // Warm the chunk on OPEN-INTENT (hover/focus) and again on click, both
50
+ // best-effort: a preload that throws must never block opening the editor, whose
51
+ // own lazy import stays the loud path if the module genuinely cannot load.
52
+ const warm = () => {
53
+ contribution.preload?.();
54
+ };
55
+ const shapeLabel = declaration.shape?.label;
56
+ const openLabel = shapeLabel
57
+ ? `Open the visual editor for ${fieldLabel} (input: ${shapeLabel})`
58
+ : `Open the visual editor for ${fieldLabel}`;
59
+ const resolvedTitle = title ?? (shapeLabel ? `Visual editor · input: ${shapeLabel}` : 'Visual editor');
60
+ return (_jsxs(_Fragment, { children: [_jsxs(Button, { type: "button", variant: "secondary", onClick: () => {
61
+ warm();
62
+ setOpen(true);
63
+ }, onMouseEnter: warm, onFocus: warm, "aria-label": openLabel, title: resolvedTitle, children: [_jsx(GridIcon, { "aria-hidden": true }), compact ? null : ' Visual editor'] }), open ? (_jsx(ErrorBoundary, { label: "Visual editor", children: _jsx(Suspense, { fallback: _jsx(Spinner, { label: "Loading the visual editor" }), children: _jsx(LazyEditor, { declaration: declaration, open: true, initialExpression: value, fieldLabel: fieldLabel, readOnly: editorReadOnly, onSave: (expression) => {
64
+ onSave(expression);
65
+ setOpen(false);
66
+ }, onClose: () => {
67
+ setOpen(false);
68
+ } }) }) })) : null] }));
69
+ }
70
+ export function ExpressionField({ label, hideLabel = false, description, error, declaration, value, onChange, disabled = false, editorReadOnly, compact = false, fieldLabel, multiline = true, monospace = true, launcherTitle, rows, placeholder, textareaProps, }) {
71
+ const contribution = useExpressionEditor(declaration.language);
72
+ const monoClassName = monospace
73
+ ? multiline
74
+ ? 'tai-textarea-mono'
75
+ : 'tai-input-mono'
76
+ : undefined;
77
+ // The editor's read-only state is INDEPENDENT of the textarea's disabled state,
78
+ // but defaults to it so the historical coupling holds for a caller that never
79
+ // asks for the two to differ.
80
+ const resolvedEditorReadOnly = editorReadOnly ?? disabled;
81
+ const control = multiline ? (_jsx(Textarea, { ...textareaProps, value: value, onChange: (event) => {
82
+ onChange(event.target.value);
83
+ }, disabled: disabled, spellCheck: false, rows: rows, placeholder: placeholder, className: monoClassName })) : (_jsx(TextInput, { ...textareaProps, value: value, onChange: (event) => {
84
+ onChange(event.target.value);
85
+ }, disabled: disabled, spellCheck: false, placeholder: placeholder, className: monoClassName }));
86
+ return (_jsxs(Field, { label: label, hideLabel: hideLabel, description: description, error: error, children: [control, contribution !== null ? (_jsx("div", { style: { display: 'flex', justifyContent: 'flex-end', marginTop: 'var(--tai-space-2)' }, children: _jsx(ExpressionEditorLauncher, { declaration: declaration, value: value, onSave: onChange, fieldLabel: fieldLabel ?? label, compact: compact, editorReadOnly: resolvedEditorReadOnly, title: launcherTitle }) })) : null] }));
87
+ }
88
+ //# sourceMappingURL=ExpressionField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpressionField.js","sourceRoot":"","sources":["../../src/expression/ExpressionField.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The consumption bridge for contributed expression editors: the SHELL reads the
3
+ * committed contributions from `@tai42/studio-sdk/host` and mounts
4
+ * {@link ExpressionEditorsProvider} high in the tree, so both host features and
5
+ * plugin pages resolve an editor for a language through {@link useExpressionEditor}.
6
+ *
7
+ * WHY A CONTEXT AND NOT A DIRECT REGISTRY READ: the contribution registry lives in
8
+ * the host-only `@tai42/studio-sdk/host` module, which the plugin surface
9
+ * deliberately cannot import — a served plugin bundle must not be able to forge,
10
+ * wipe, or ENUMERATE the registry. React itself is the one import-map singleton
11
+ * both bundles share (the shell externalises `react` and `@tai42/studio-sdk`), so a
12
+ * context provided by the host reaches a plugin page's render. The provider carries
13
+ * the editors as a private context value the plugin surface never exports, and the
14
+ * only door through it is {@link useExpressionEditor}, which resolves ONE language
15
+ * to ONE contribution. A plugin can look up the editor for its own field and no
16
+ * more: it cannot list the languages, count the editors, or mutate the set.
17
+ *
18
+ * ABSENT PROVIDER IS A FIRST-CLASS STATE: a field rendered with no provider above
19
+ * it (a host that never wired the bridge, a test that mounts a field bare) resolves
20
+ * `null` and degrades to a plain text field. That is the graceful-absence contract
21
+ * {@link ExpressionField} relies on, so the hook returns `null` rather than throwing.
22
+ */
23
+ import { type ReactNode } from 'react';
24
+ import type { ExpressionEditorContribution, ExpressionLanguage } from './types';
25
+ export interface ExpressionEditorsProviderProps {
26
+ /**
27
+ * The committed editor contributions, keyed by language — exactly the shell's
28
+ * `getContributions().expressionEditors`. Passed as the read-only map it already
29
+ * is; the provider never mutates or re-exposes it, and wraps it in a lookup so a
30
+ * consumer can only resolve, never enumerate.
31
+ */
32
+ readonly editors: ReadonlyMap<string, ExpressionEditorContribution>;
33
+ readonly children: ReactNode;
34
+ }
35
+ /**
36
+ * Publishes the contributed editors to the subtree as a lookup. The shell mounts
37
+ * this once, above both the host feature routes and the plugin pages, with the
38
+ * host registry's `expressionEditors` map. Re-rendering with a new `editors` map
39
+ * (the load pass completing) updates every consumer.
40
+ */
41
+ export declare function ExpressionEditorsProvider({ editors, children, }: ExpressionEditorsProviderProps): ReactNode;
42
+ /**
43
+ * Resolve the contributed editor for one expression language, or `null` when none
44
+ * is registered OR no {@link ExpressionEditorsProvider} is mounted above the caller.
45
+ * This is the ONLY way a plugin surface reaches a contributed editor: it cannot
46
+ * enumerate or mutate the registry, only ask for one language. `null` is the
47
+ * graceful-absence signal {@link ExpressionField} renders a plain text field on.
48
+ */
49
+ export declare function useExpressionEditor(language: ExpressionLanguage): ExpressionEditorContribution | null;
50
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/expression/context.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1F,OAAO,KAAK,EAAE,4BAA4B,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAYhF,MAAM,WAAW,8BAA8B;IAC7C;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC;IACpE,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,OAAO,EACP,QAAQ,GACT,EAAE,8BAA8B,GAAG,SAAS,CAW5C;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,kBAAkB,GAC3B,4BAA4B,GAAG,IAAI,CAIrC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * The consumption bridge for contributed expression editors: the SHELL reads the
3
+ * committed contributions from `@tai42/studio-sdk/host` and mounts
4
+ * {@link ExpressionEditorsProvider} high in the tree, so both host features and
5
+ * plugin pages resolve an editor for a language through {@link useExpressionEditor}.
6
+ *
7
+ * WHY A CONTEXT AND NOT A DIRECT REGISTRY READ: the contribution registry lives in
8
+ * the host-only `@tai42/studio-sdk/host` module, which the plugin surface
9
+ * deliberately cannot import — a served plugin bundle must not be able to forge,
10
+ * wipe, or ENUMERATE the registry. React itself is the one import-map singleton
11
+ * both bundles share (the shell externalises `react` and `@tai42/studio-sdk`), so a
12
+ * context provided by the host reaches a plugin page's render. The provider carries
13
+ * the editors as a private context value the plugin surface never exports, and the
14
+ * only door through it is {@link useExpressionEditor}, which resolves ONE language
15
+ * to ONE contribution. A plugin can look up the editor for its own field and no
16
+ * more: it cannot list the languages, count the editors, or mutate the set.
17
+ *
18
+ * ABSENT PROVIDER IS A FIRST-CLASS STATE: a field rendered with no provider above
19
+ * it (a host that never wired the bridge, a test that mounts a field bare) resolves
20
+ * `null` and degrades to a plain text field. That is the graceful-absence contract
21
+ * {@link ExpressionField} relies on, so the hook returns `null` rather than throwing.
22
+ */
23
+ import { createContext, createElement, useContext, useMemo } from 'react';
24
+ const ExpressionEditorsContext = createContext(null);
25
+ /**
26
+ * Publishes the contributed editors to the subtree as a lookup. The shell mounts
27
+ * this once, above both the host feature routes and the plugin pages, with the
28
+ * host registry's `expressionEditors` map. Re-rendering with a new `editors` map
29
+ * (the load pass completing) updates every consumer.
30
+ */
31
+ export function ExpressionEditorsProvider({ editors, children, }) {
32
+ // Memoised on the `editors` map so the context value keeps a STABLE identity
33
+ // across re-renders that do not change the map — a new closure every render would
34
+ // re-notify every consumer that reads the context (every mounted field) for
35
+ // nothing. The identity turns over exactly when the map does (the load pass
36
+ // committing a new editor), which is the one time consumers must re-resolve.
37
+ const lookup = useMemo(() => (language) => editors.get(language) ?? null, [editors]);
38
+ return createElement(ExpressionEditorsContext.Provider, { value: lookup }, children);
39
+ }
40
+ /**
41
+ * Resolve the contributed editor for one expression language, or `null` when none
42
+ * is registered OR no {@link ExpressionEditorsProvider} is mounted above the caller.
43
+ * This is the ONLY way a plugin surface reaches a contributed editor: it cannot
44
+ * enumerate or mutate the registry, only ask for one language. `null` is the
45
+ * graceful-absence signal {@link ExpressionField} renders a plain text field on.
46
+ */
47
+ export function useExpressionEditor(language) {
48
+ const lookup = useContext(ExpressionEditorsContext);
49
+ if (lookup === null)
50
+ return null;
51
+ return lookup(language);
52
+ }
53
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/expression/context.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAC;AAY1F,MAAM,wBAAwB,GAAG,aAAa,CAAsB,IAAI,CAAC,CAAC;AAa1E;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,EACxC,OAAO,EACP,QAAQ,GACuB;IAC/B,6EAA6E;IAC7E,kFAAkF;IAClF,4EAA4E;IAC5E,4EAA4E;IAC5E,6EAA6E;IAC7E,MAAM,MAAM,GAAG,OAAO,CACpB,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,EACjD,CAAC,OAAO,CAAC,CACV,CAAC;IACF,OAAO,aAAa,CAAC,wBAAwB,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,CAAC;AACvF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAA4B;IAE5B,MAAM,MAAM,GAAG,UAAU,CAAC,wBAAwB,CAAC,CAAC;IACpD,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * The SDK's AGNOSTIC expression-field vocabulary: the language-neutral graduation
3
+ * of babelfish jq-studio's field-declaration surface into the platform SDK, so any
4
+ * Studio consumer (a flow product, a tai42 feature, a third-party plugin) can
5
+ * declare an expression field the SAME way and any plugin can contribute the
6
+ * editor that authors it.
7
+ *
8
+ * A host declares an expression field through these generic types — a language
9
+ * tag, a DESCRIPTOR of what the expression's input document IS (not an enum of
10
+ * shapes the editor hard-codes), a sample-input provider, and a pluggable
11
+ * server-validate hook. Nothing here names anything product-specific, so the same
12
+ * SDK serves flows' node/tool-result envelopes and tai42's webhook-body /
13
+ * auth-context / tool-result shapes without a type change. babelfish's flows
14
+ * adapter retypes its own envelopes onto these; the descriptor fields are kept
15
+ * isomorphic to jq-studio's `JqInputShapeDescriptor` so that mapping is a rename,
16
+ * not a reshape.
17
+ *
18
+ * The editor itself is NOT in the SDK — it is a plugin CONTRIBUTION
19
+ * ({@link ExpressionEditorContribution}), lazily loaded across the plugin
20
+ * boundary. This module is the shared contract both sides retype against.
21
+ */
22
+ import type { ComponentType } from 'react';
23
+ /**
24
+ * The expression language an expression field authors. `'jq'` is the only language
25
+ * that exists today; the tag is an OPEN string union so a host (or a later plugin)
26
+ * can name another pipeline language without a change to this type. The literal
27
+ * keeps `'jq'` on the autocomplete list while `string` keeps the union open.
28
+ */
29
+ export type ExpressionLanguage = 'jq' | (string & {});
30
+ /**
31
+ * One top-level key of the expression's input document, with a one-line gloss the
32
+ * editor may surface (a context chip, an input-node body, path suggestions).
33
+ * Graduated from jq-studio's `JqInputKey`.
34
+ */
35
+ export interface ExpressionInputKey {
36
+ readonly name: string;
37
+ readonly gloss: string;
38
+ }
39
+ /**
40
+ * A descriptor of what the expression's input document IS for a field — the shape
41
+ * the expression receives as its root. Deliberately open: a host builds these from
42
+ * its own domain, so ANY envelope is expressible, including ones the editor has
43
+ * never heard of. The `id` is an opaque, host-namespaced string used only for
44
+ * memoisation/telemetry. Graduated from jq-studio's `JqInputShapeDescriptor` with
45
+ * every field isomorphic, so the flows adapter maps its `JQType` onto this without
46
+ * reshaping.
47
+ */
48
+ export interface ExpressionShapeDescriptor {
49
+ /** Stable, host-namespaced id (opaque to the editor). */
50
+ readonly id: string;
51
+ /** Short chip label — what the input is here, e.g. "node envelope". */
52
+ readonly label: string;
53
+ /** One sentence: what the input document is in this field. */
54
+ readonly blurb: string;
55
+ /** The top-level keys of the input document, each with a one-liner. */
56
+ readonly keys: readonly ExpressionInputKey[];
57
+ /** What the expression must RETURN, e.g. "true or false" | "an object". */
58
+ readonly returns: string;
59
+ /** Per-field caveats (e.g. ".iterate.item is always null in a while condition"). */
60
+ readonly caveats?: readonly string[];
61
+ /** A static skeleton of the input document — the cheap, honest default a Test
62
+ * panel seeds its input with. A host may override it dynamically through the
63
+ * declaration's {@link ExpressionSampleInputProvider}. */
64
+ readonly sample?: unknown;
65
+ }
66
+ /** A provider of a concrete sample input for the editor's Test panel. A function
67
+ * (not a value) so a host can supply a static skeleton now and a live sample
68
+ * later without changing this API. Graduated from jq-studio's
69
+ * `SampleInputProvider`. */
70
+ export type ExpressionSampleInputProvider = () => unknown;
71
+ /** The answer a pluggable validator gives for an expression against its declared
72
+ * shape. Mirrors babelfish `validate_jq`'s result WITHOUT importing its types, so
73
+ * the hook stays host-agnostic. */
74
+ export interface ExpressionValidationResult {
75
+ readonly ok: boolean;
76
+ readonly compiles?: boolean;
77
+ readonly singleEmit?: boolean;
78
+ readonly message?: string;
79
+ }
80
+ /** A pluggable server-validate hook. The editor calls it with the current
81
+ * expression and the sample input; the host routes it to its own validator (flows
82
+ * wires babelfish's `validate_jq` endpoint here). Absent = no server validation
83
+ * (a local runtime may still power the Test panel). Graduated from jq-studio's
84
+ * `ServerValidateHook`. */
85
+ export type ExpressionServerValidate = (args: {
86
+ readonly expression: string;
87
+ readonly sampleInput: unknown;
88
+ }) => Promise<ExpressionValidationResult>;
89
+ /**
90
+ * The declaration a host attaches to an expression field: the language, what the
91
+ * input document is (descriptor), how to sample it, and how to server-validate it.
92
+ * Every property beyond `language` is optional so adoption is incremental — an
93
+ * undeclared-but-for-language field behaves exactly as a plain text field. No
94
+ * property names anything host-specific. Graduated from jq-studio's
95
+ * `JqFieldDeclaration`.
96
+ */
97
+ export interface ExpressionFieldDeclaration {
98
+ readonly language: ExpressionLanguage;
99
+ readonly shape?: ExpressionShapeDescriptor;
100
+ readonly sampleInput?: ExpressionSampleInputProvider;
101
+ readonly serverValidate?: ExpressionServerValidate;
102
+ }
103
+ /**
104
+ * The props a contributed editor component receives when the field opens it. The
105
+ * WHOLE {@link ExpressionFieldDeclaration} crosses (not just `shape` /
106
+ * `serverValidate`), so the editor reads the input descriptor for its context
107
+ * chip, the sample provider for Test seeding, and the validate hook for its
108
+ * Validate action from one object. `onSave` writes the authored expression back
109
+ * through the field; `onClose` dismisses without saving.
110
+ */
111
+ export interface ExpressionEditorProps {
112
+ /** What the field feeds and how to sample/validate it (see the type). */
113
+ readonly declaration: ExpressionFieldDeclaration;
114
+ /** Whether the editor is open — the field mounts it only while true. */
115
+ readonly open: boolean;
116
+ /** The field's current expression ('' when unset), the editor seeds itself with. */
117
+ readonly initialExpression: string;
118
+ /** The field label the editor titles itself with. */
119
+ readonly fieldLabel?: string;
120
+ /** Author-blocking: the editor renders read-only (no Save) when true. */
121
+ readonly readOnly?: boolean;
122
+ /** Called with the authored expression when the user saves. */
123
+ readonly onSave: (expression: string) => void;
124
+ /** Called when the user dismisses the editor without saving. */
125
+ readonly onClose: () => void;
126
+ }
127
+ /**
128
+ * The contract version an {@link ExpressionEditorContribution} must target. Bumped
129
+ * only on a BREAKING change to {@link ExpressionEditorProps} or the contribution
130
+ * shape; the registry rejects a contribution whose `contractVersion` is not
131
+ * exactly this, so a host never mounts an editor built against an incompatible
132
+ * props contract. It is distinct from `STUDIO_PLUGIN_API_VERSION`: the plugin API
133
+ * gains this whole extension point ADDITIVELY (that version does not move), and
134
+ * this narrower number then versions the editor props independently.
135
+ */
136
+ export declare const EXPRESSION_EDITOR_CONTRACT_VERSION = 1;
137
+ /**
138
+ * A plugin's contribution of the editor for one expression language. The editor
139
+ * rides a SEPARATE chunk (a visual canvas, converters, a language runtime), so it
140
+ * is fetched lazily: `load` resolves the module exposing the `Editor` component,
141
+ * and the optional `preload` warms that chunk on open-intent (hover/focus) so the
142
+ * editor is ready by the time the user opens it. `contractVersion` must equal
143
+ * {@link EXPRESSION_EDITOR_CONTRACT_VERSION} or the registry rejects it loudly.
144
+ */
145
+ export interface ExpressionEditorContribution {
146
+ /** The language this editor authors; the lookup key a field resolves by. */
147
+ readonly language: ExpressionLanguage;
148
+ /** The {@link ExpressionEditorProps} contract this editor was built against. */
149
+ readonly contractVersion: number;
150
+ /** Best-effort warm of the editor's chunk on open-intent; never awaited by the field. */
151
+ readonly preload?: () => void;
152
+ /** Resolve the editor component's chunk; rejection surfaces as the field's loud error. */
153
+ readonly load: () => Promise<{
154
+ readonly Editor: ComponentType<ExpressionEditorProps>;
155
+ }>;
156
+ }
157
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/expression/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The contract version an {@link ExpressionEditorContribution} must target. Bumped
3
+ * only on a BREAKING change to {@link ExpressionEditorProps} or the contribution
4
+ * shape; the registry rejects a contribution whose `contractVersion` is not
5
+ * exactly this, so a host never mounts an editor built against an incompatible
6
+ * props contract. It is distinct from `STUDIO_PLUGIN_API_VERSION`: the plugin API
7
+ * gains this whole extension point ADDITIVELY (that version does not move), and
8
+ * this narrower number then versions the editor props independently.
9
+ */
10
+ export const EXPRESSION_EDITOR_CONTRACT_VERSION = 1;
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/expression/types.ts"],"names":[],"mappings":"AAuIA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,CAAC"}
@@ -1000,6 +1000,14 @@ export declare const ApiProvider: import("react").Provider<{
1000
1000
  created_at: string;
1001
1001
  id: string;
1002
1002
  recipient: string | null;
1003
+ options?: string[] | null | undefined;
1004
+ template?: {
1005
+ name: string;
1006
+ language: string;
1007
+ parameters: string[];
1008
+ } | null | undefined;
1009
+ audience?: string | null | undefined;
1010
+ media?: unknown[] | null | undefined;
1003
1011
  }[];
1004
1012
  }>;
1005
1013
  readonly listAgents: (signal?: AbortSignal) => Promise<{