@tai42/studio-sdk 9.3.0 → 11.0.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 (92) hide show
  1. package/README.md +45 -6
  2. package/SECURITY.md +10 -2
  3. package/dist/components/components.css +18 -0
  4. package/dist/components/dirty-guard.d.ts +23 -10
  5. package/dist/components/dirty-guard.d.ts.map +1 -1
  6. package/dist/components/dirty-guard.js +22 -12
  7. package/dist/components/dirty-guard.js.map +1 -1
  8. package/dist/components/field.d.ts.map +1 -1
  9. package/dist/components/field.js +1 -1
  10. package/dist/components/field.js.map +1 -1
  11. package/dist/components/fleet-report.d.ts +12 -3
  12. package/dist/components/fleet-report.d.ts.map +1 -1
  13. package/dist/components/fleet-report.js +28 -9
  14. package/dist/components/fleet-report.js.map +1 -1
  15. package/dist/components/icons.d.ts +4 -0
  16. package/dist/components/icons.d.ts.map +1 -1
  17. package/dist/components/icons.js +5 -0
  18. package/dist/components/icons.js.map +1 -1
  19. package/dist/hooks/useApi.d.ts +348 -2
  20. package/dist/hooks/useApi.d.ts.map +1 -1
  21. package/dist/host.d.ts +1 -1
  22. package/dist/host.d.ts.map +1 -1
  23. package/dist/index.d.ts +18 -7
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +23 -11
  26. package/dist/index.js.map +1 -1
  27. package/dist/navigation/context.d.ts +6 -2
  28. package/dist/navigation/context.d.ts.map +1 -1
  29. package/dist/navigation/context.js +10 -2
  30. package/dist/navigation/context.js.map +1 -1
  31. package/dist/navigation/types.d.ts +1 -0
  32. package/dist/navigation/types.d.ts.map +1 -1
  33. package/dist/plugin/host-state.d.ts +16 -0
  34. package/dist/plugin/host-state.d.ts.map +1 -1
  35. package/dist/plugin/host-state.js +1 -0
  36. package/dist/plugin/host-state.js.map +1 -1
  37. package/dist/plugin/types.d.ts +17 -7
  38. package/dist/plugin/types.d.ts.map +1 -1
  39. package/dist/schema-form/SchemaForm.d.ts +4 -3
  40. package/dist/schema-form/SchemaForm.d.ts.map +1 -1
  41. package/dist/schema-form/SchemaForm.js.map +1 -1
  42. package/dist/schema-form/SecretRefField.d.ts.map +1 -1
  43. package/dist/schema-form/SecretRefField.js +3 -2
  44. package/dist/schema-form/SecretRefField.js.map +1 -1
  45. package/dist/schema-form/context.d.ts +2 -2
  46. package/dist/schema-form/default-value.d.ts +12 -0
  47. package/dist/schema-form/default-value.d.ts.map +1 -1
  48. package/dist/schema-form/default-value.js +34 -3
  49. package/dist/schema-form/default-value.js.map +1 -1
  50. package/dist/schema-form/field-node.d.ts +7 -0
  51. package/dist/schema-form/field-node.d.ts.map +1 -1
  52. package/dist/schema-form/field-node.js +3 -2
  53. package/dist/schema-form/field-node.js.map +1 -1
  54. package/dist/schema-form/index.d.ts +11 -11
  55. package/dist/schema-form/index.js +11 -11
  56. package/dist/schema-form/object-fields.d.ts +3 -1
  57. package/dist/schema-form/object-fields.d.ts.map +1 -1
  58. package/dist/schema-form/object-fields.js +2 -2
  59. package/dist/schema-form/object-fields.js.map +1 -1
  60. package/dist/schema-form/string-field.d.ts +3 -2
  61. package/dist/schema-form/string-field.d.ts.map +1 -1
  62. package/dist/schema-form/string-field.js.map +1 -1
  63. package/dist/schema-form/union-field.d.ts +5 -2
  64. package/dist/schema-form/union-field.d.ts.map +1 -1
  65. package/dist/schema-form/union-field.js +68 -15
  66. package/dist/schema-form/union-field.js.map +1 -1
  67. package/package.json +3 -3
  68. package/src/components/components.css +18 -0
  69. package/src/components/dirty-guard.tsx +23 -13
  70. package/src/components/field.tsx +10 -5
  71. package/src/components/fleet-report.tsx +44 -13
  72. package/src/components/icons.tsx +19 -0
  73. package/src/host.ts +5 -1
  74. package/src/index.ts +24 -31
  75. package/src/navigation/context.tsx +16 -1
  76. package/src/navigation/types.ts +3 -0
  77. package/src/plugin/host-state.ts +18 -0
  78. package/src/plugin/types.ts +17 -7
  79. package/src/schema-form/SchemaForm.tsx +4 -3
  80. package/src/schema-form/SecretRefField.tsx +3 -2
  81. package/src/schema-form/context.ts +2 -2
  82. package/src/schema-form/default-value.ts +36 -3
  83. package/src/schema-form/field-node.tsx +21 -2
  84. package/src/schema-form/index.ts +11 -11
  85. package/src/schema-form/object-fields.tsx +4 -0
  86. package/src/schema-form/string-field.tsx +3 -2
  87. package/src/schema-form/union-field.tsx +85 -19
  88. package/dist/jq.d.ts +0 -31
  89. package/dist/jq.d.ts.map +0 -1
  90. package/dist/jq.js +0 -41
  91. package/dist/jq.js.map +0 -1
  92. package/src/jq.ts +0 -61
@@ -3,7 +3,7 @@ import { FieldNode } from './field-node';
3
3
  function isPlainObject(value) {
4
4
  return typeof value === 'object' && value !== null && !Array.isArray(value);
5
5
  }
6
- export function ObjectFields({ properties, requiredKeys, root, value, onChange, path, errors, idPrefix, skip, }) {
6
+ export function ObjectFields({ properties, requiredKeys, root, value, onChange, path, errors, idPrefix, skip, markRequired = false, }) {
7
7
  const obj = isPlainObject(value) ? value : {};
8
8
  return (_jsx(_Fragment, { children: properties.map(([name, propSchema]) => {
9
9
  if (skip !== undefined && name === skip)
@@ -11,7 +11,7 @@ export function ObjectFields({ properties, requiredKeys, root, value, onChange,
11
11
  const childPath = path === '' ? name : `${path}.${name}`;
12
12
  return (_jsx(FieldNode, { schema: propSchema, root: root, value: obj[name], onChange: (next) => {
13
13
  onChange(setKey(obj, name, next));
14
- }, path: childPath, label: name, required: requiredKeys.has(name), errors: errors, idPrefix: idPrefix }, name));
14
+ }, path: childPath, label: name, required: requiredKeys.has(name), markRequired: markRequired, errors: errors, idPrefix: idPrefix }, name));
15
15
  }) }));
16
16
  }
17
17
  function setKey(obj, name, next) {
@@ -1 +1 @@
1
- {"version":3,"file":"object-fields.js","sourceRoot":"","sources":["../../src/schema-form/object-fields.tsx"],"names":[],"mappings":";AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAC3B,UAAU,EACV,YAAY,EACZ,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,IAAI,GAWL;IACC,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9C,OAAO,CACL,4BACG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE;YACrC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YACrD,MAAM,SAAS,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;YACzD,OAAO,CACL,KAAC,SAAS,IAER,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,EAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;oBACjB,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;gBACpC,CAAC,EACD,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,IAXb,IAAI,CAYT,CACH,CAAC;QACJ,CAAC,CAAC,GACD,CACJ,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CACb,GAA4B,EAC5B,IAAY,EACZ,IAAa;IAEb,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"object-fields.js","sourceRoot":"","sources":["../../src/schema-form/object-fields.tsx"],"names":[],"mappings":";AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAC3B,UAAU,EACV,YAAY,EACZ,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,YAAY,GAAG,KAAK,GAarB;IACC,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9C,OAAO,CACL,4BACG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE;YACrC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YACrD,MAAM,SAAS,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;YACzD,OAAO,CACL,KAAC,SAAS,IAER,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,EAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;oBACjB,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;gBACpC,CAAC,EACD,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAChC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,IAZb,IAAI,CAaT,CACH,CAAC;QACJ,CAAC,CAAC,GACD,CACJ,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CACb,GAA4B,EAC5B,IAAY,EACZ,IAAa;IAEb,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC"}
@@ -6,8 +6,9 @@
6
6
  * control instead; and when the form supplies a completion provider, the input is
7
7
  * backed by argument autocomplete.
8
8
  *
9
- * NO JQ EDGE. This module — and every module under `schema-form` — names no jq
10
- * type and imports the SDK's `../jq` re-export neither statically NOR dynamically.
9
+ * NO JQ EDGE. This module — and every module under `schema-form`, and the package
10
+ * barrel above them — names no jq type and imports `@tai42/jq-studio` neither
11
+ * statically NOR dynamically.
11
12
  * The jq authoring door drags a heavy subgraph (the xyflow visual editor, a Web
12
13
  * Worker entry, and a multi-megabyte wasm engine), and a bundler EMITS that whole
13
14
  * subgraph for a dynamic import just as it does for a static one — `lazy` defers
@@ -1 +1 @@
1
- {"version":3,"file":"string-field.d.ts","sourceRoot":"","sources":["../../src/schema-form/string-field.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQvC,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAMpE,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,WAAW,EACX,KAAK,EACL,MAAM,EACN,KAAK,EACL,UAAU,EACV,OAAO,EACP,KAAK,EACL,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,UAAU,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC,GAAG,SAAS,CAqEZ"}
1
+ {"version":3,"file":"string-field.d.ts","sourceRoot":"","sources":["../../src/schema-form/string-field.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQvC,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAMpE,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,WAAW,EACX,KAAK,EACL,MAAM,EACN,KAAK,EACL,UAAU,EACV,OAAO,EACP,KAAK,EACL,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,UAAU,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC,GAAG,SAAS,CAqEZ"}
@@ -1 +1 @@
1
- {"version":3,"file":"string-field.js","sourceRoot":"","sources":["../../src/schema-form/string-field.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"string-field.js","sourceRoot":"","sources":["../../src/schema-form/string-field.tsx"],"names":[],"mappings":"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"}
@@ -1,8 +1,11 @@
1
1
  /**
2
2
  * The union field renderer: a variant picker plus the active variant's fields.
3
3
  * An object variant renders its properties inline (skipping the discriminator
4
- * tag, which the picker owns); a scalar/enum variant renders as a single nested
5
- * {@link FieldNode}. Selecting a variant seeds a concrete value for it.
4
+ * tag, which the picker owns), with the variant's required fields carrying the
5
+ * design system's required marker; a scalar/enum variant renders as a single
6
+ * nested {@link FieldNode}. Selecting a variant seeds a concrete value for it,
7
+ * preserving the fields the outgoing value shares with the new variant (see
8
+ * {@link switchVariantValue}).
6
9
  */
7
10
  import type { ReactNode } from 'react';
8
11
  import { type FieldModel } from './classify';
@@ -1 +1 @@
1
- {"version":3,"file":"union-field.d.ts","sourceRoot":"","sources":["../../src/schema-form/union-field.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAQ7D,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA0B5D,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,WAAW,EACX,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC9C,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,SAAS,CAuDZ"}
1
+ {"version":3,"file":"union-field.d.ts","sourceRoot":"","sources":["../../src/schema-form/union-field.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,EAAkB,KAAK,UAAU,EAAqB,MAAM,YAAY,CAAC;AAQhF,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAqF5D,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,WAAW,EACX,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC9C,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,SAAS,CA2DZ"}
@@ -2,21 +2,25 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Field } from '../components/field';
3
3
  import { Select } from '../components/select';
4
4
  import { classifySchema } from './classify';
5
- import { defaultValueForSchema } from './default-value';
5
+ import { skeletonValueForSchema } from './default-value';
6
6
  import { FieldGroup } from './field-group';
7
7
  import { FieldNode } from './field-node';
8
8
  import { ObjectFields } from './object-fields';
9
9
  import { resolveRef } from './resolve';
10
10
  import { groupClass } from './styles';
11
11
  import { activeVariantIndex } from './union';
12
+ function isPlainObject(value) {
13
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
14
+ }
12
15
  /**
13
- * A concrete seed for a chosen union variant. Object variants get their
14
- * required-field skeleton; a scalar/enum variant that has no explicit default
16
+ * A concrete seed for a chosen union variant. Object variants get their full
17
+ * skeleton (every required field minted, so the seed validates against the
18
+ * variant's own schema); a scalar/enum variant that has no explicit default
15
19
  * still needs a non-`undefined` value so the selection sticks (otherwise
16
20
  * `activeVariantIndex` reads it back as "no variant" and the picker snaps empty).
17
21
  */
18
22
  function seedVariantValue(schema, root) {
19
- const seeded = defaultValueForSchema(schema, root);
23
+ const seeded = skeletonValueForSchema(schema, root);
20
24
  if (seeded !== undefined)
21
25
  return seeded;
22
26
  const resolved = resolveRef(schema, root);
@@ -24,16 +28,65 @@ function seedVariantValue(schema, root) {
24
28
  return resolved.const;
25
29
  if (resolved.enum !== undefined && resolved.enum.length > 0)
26
30
  return resolved.enum[0];
27
- switch (classifySchema(schema, root).model.kind) {
28
- case 'string':
29
- return '';
30
- case 'number':
31
- return 0;
32
- case 'boolean':
33
- return false;
34
- default:
35
- return undefined;
31
+ return undefined;
32
+ }
33
+ /**
34
+ * The value committed when the user switches to `target`. Typed values SURVIVE
35
+ * the switch: the target's skeleton is minted first, then every top-level field
36
+ * of the current value whose NAME exists in the target variant's properties is
37
+ * carried over wholesale — the merge happens at the top level only, each carried
38
+ * field keeping its nested contents as-is — so fields both variants share are
39
+ * never silently discarded. Only fields absent from the current value keep
40
+ * their freshly minted seed. The discriminator tag is never carried: it always
41
+ * comes from the target's seed (the old tag would re-select the old variant).
42
+ * A non-object side (scalar variant, or a non-object current value) has no
43
+ * fields to carry, so it reseeds wholesale.
44
+ */
45
+ function switchVariantValue(current, target, discriminator, root) {
46
+ const seeded = seedVariantValue(target.schema, root);
47
+ if (!isPlainObject(current) || !isPlainObject(seeded))
48
+ return seeded;
49
+ const { model } = classifySchema(target.schema, root);
50
+ if (model.kind !== 'object')
51
+ return seeded;
52
+ const targetNames = new Set(model.properties.map(([name]) => name));
53
+ const merged = { ...seeded };
54
+ for (const [name, held] of Object.entries(current)) {
55
+ if (name === discriminator)
56
+ continue;
57
+ if (targetNames.has(name))
58
+ merged[name] = held;
59
+ }
60
+ return merged;
61
+ }
62
+ /** Title-case a property name: `kind` → "Kind", `content_type` → "Content Type". */
63
+ function titleCaseName(name) {
64
+ return name
65
+ .split(/[_\-\s]+/)
66
+ .filter((part) => part.length > 0)
67
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
68
+ .join(' ');
69
+ }
70
+ /**
71
+ * The variant picker's label. A discriminated union names the picker after the
72
+ * discriminator property it sets — the property's schema `title` when a variant
73
+ * declares one, else the property name title-cased — so the picker reads as the
74
+ * field it is ("Kind", "Format"). Only a union without a discriminator falls
75
+ * back to the generic "Variant".
76
+ */
77
+ function pickerLabel(discriminator, variants, root) {
78
+ if (discriminator === undefined)
79
+ return 'Variant';
80
+ for (const variant of variants) {
81
+ const property = resolveRef(variant.schema, root).properties?.[discriminator];
82
+ if (property === undefined)
83
+ continue;
84
+ const title = property.title ?? resolveRef(property, root).title;
85
+ if (typeof title === 'string' && title.length > 0)
86
+ return title;
36
87
  }
88
+ const cased = titleCaseName(discriminator);
89
+ return cased.length > 0 ? cased : 'Variant';
37
90
  }
38
91
  export function UnionField({ heading, description, error, model, root, value, onChange, path, errors, idPrefix, }) {
39
92
  const index = activeVariantIndex(value, model.variants, model.discriminator, root);
@@ -46,10 +99,10 @@ export function UnionField({ heading, description, error, model, root, value, on
46
99
  const variant = model.variants[position];
47
100
  if (variant === undefined)
48
101
  return;
49
- onChange(seedVariantValue(variant.schema, root));
102
+ onChange(switchVariantValue(value, variant, model.discriminator, root));
50
103
  };
51
104
  const active = index === -1 ? undefined : model.variants[index];
52
105
  const activeClassified = active === undefined ? undefined : classifySchema(active.schema, root);
53
- return (_jsxs(FieldGroup, { heading: heading, description: description, error: error, atRoot: false, children: [_jsx(Field, { label: "Variant", children: _jsx(Select, { options: options, value: index === -1 ? '' : String(index), placeholder: "Select a variant\u2026", onValueChange: selectVariant }) }), activeClassified?.model.kind === 'object' ? (_jsx("div", { className: groupClass, children: _jsx(ObjectFields, { properties: activeClassified.model.properties, requiredKeys: activeClassified.model.required, root: root, value: value, onChange: onChange, path: path, errors: errors, idPrefix: idPrefix, skip: model.discriminator }) })) : active !== undefined ? (_jsx(FieldNode, { schema: active.schema, root: root, value: value, onChange: onChange, path: path, label: active.label, required: true, errors: errors, idPrefix: idPrefix })) : null] }));
106
+ return (_jsxs(FieldGroup, { heading: heading, description: description, error: error, atRoot: path === '', children: [_jsx(Field, { label: pickerLabel(model.discriminator, model.variants, root), children: _jsx(Select, { options: options, value: index === -1 ? '' : String(index), placeholder: "Select a variant\u2026", onValueChange: selectVariant }) }), activeClassified?.model.kind === 'object' ? (_jsx("div", { className: groupClass, children: _jsx(ObjectFields, { properties: activeClassified.model.properties, requiredKeys: activeClassified.model.required, root: root, value: value, onChange: onChange, path: path, errors: errors, idPrefix: idPrefix, skip: model.discriminator, markRequired: true }) })) : active !== undefined ? (_jsx(FieldNode, { schema: active.schema, root: root, value: value, onChange: onChange, path: path, label: active.label, required: true, errors: errors, idPrefix: idPrefix })) : null] }));
54
107
  }
55
108
  //# sourceMappingURL=union-field.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"union-field.js","sourceRoot":"","sources":["../../src/schema-form/union-field.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"union-field.js","sourceRoot":"","sources":["../../src/schema-form/union-field.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tai42/studio-sdk",
3
- "version": "9.3.0",
3
+ "version": "11.0.0",
4
4
  "description": "The Studio plugin contract, shared UI components, and hooks that every feature builds on.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "tai42 <oss@tai42.ai>",
@@ -73,6 +73,7 @@
73
73
  },
74
74
  "devDependencies": {
75
75
  "@microsoft/api-extractor": "7.58.12",
76
+ "@tai42/jq-studio": "^0.1.3",
76
77
  "@testing-library/jest-dom": "^6.9.1",
77
78
  "@testing-library/react": "^16.3.2",
78
79
  "@testing-library/user-event": "^14.6.6",
@@ -94,8 +95,7 @@
94
95
  "@radix-ui/react-select": "^2.3.2",
95
96
  "@radix-ui/react-tabs": "^1.1.16",
96
97
  "@radix-ui/react-tooltip": "^1.2.11",
97
- "@tai42/jq-studio": "^0.1.3",
98
- "@tai42/api-client": "9.3.0"
98
+ "@tai42/api-client": "11.0.0"
99
99
  },
100
100
  "scripts": {
101
101
  "build": "tsc -b tsconfig.build.json && node scripts/copy-assets.mjs",
@@ -984,6 +984,24 @@
984
984
  background-image: linear-gradient(var(--tai-color-accent-tint), var(--tai-color-accent-tint));
985
985
  }
986
986
 
987
+ /* The HOST-APPLIED provenance mark on plugin-contributed nav (the shell renders
988
+ it; a plugin cannot suppress or restyle it). A small muted glyph that links to
989
+ the plugin's marketplace row and brightens on hover/focus. It sits beside a nav
990
+ row (per-entry, in a core section) or beside a self-named section header. */
991
+ .tai-plugin-badge {
992
+ display: inline-flex;
993
+ align-items: center;
994
+ justify-content: center;
995
+ flex: none;
996
+ color: var(--tai-color-text-muted);
997
+ border-radius: var(--tai-radius-sm);
998
+ }
999
+
1000
+ .tai-plugin-badge:hover,
1001
+ .tai-plugin-badge:focus-visible {
1002
+ color: var(--tai-color-text);
1003
+ }
1004
+
987
1005
  /* Skip-to-content: off-screen until focused, so a keyboard or screen-reader
988
1006
  user can bypass the sidebar nav and jump straight to the page content
989
1007
  (WCAG 2.4.1). It is the first focusable element in the shell. */
@@ -1,10 +1,11 @@
1
1
  /**
2
- * Unsaved-changes guard for tabbed editors. `Tabs` unmount inactive panels, so a
3
- * tab switch tears an editor down and drops its edits. One registry closes the gap:
4
- * editors report dirtiness via {@link useRegisterDirty}; {@link GuardedTabs} holds a
5
- * switch away from a dirty editor behind a confirm; the same registry arms
6
- * {@link useNavigationGuard}, so a route navigation confirms through the SAME dialog
7
- * and a full-page unload raises the native prompt. The dialog is one shared
2
+ * Unsaved-changes guard for editors that get torn down or navigated away from. One
3
+ * registry closes the gap: editors report dirtiness via {@link useRegisterDirty}; the
4
+ * enclosing {@link DirtyGuardBoundary} arms {@link useNavigationGuard} from that
5
+ * registry, so a route navigation confirms through a shared dialog and a full-page
6
+ * unload raises the native prompt. {@link GuardedTabs} adds a tab-switch confirm on
7
+ * top of the same boundary — `Tabs` unmount inactive panels, so a switch away from a
8
+ * dirty editor is held behind the confirm too. The dialog is one shared
8
9
  * {@link ConfirmDialog} driven by a pending-promise resolver, so the guard's
9
10
  * `Promise<boolean>` handler and the tab switch both settle against it.
10
11
  */
@@ -36,7 +37,16 @@ interface DirtyGuardValue {
36
37
 
37
38
  const DirtyGuardContext = createContext<DirtyGuardValue | null>(null);
38
39
 
39
- function DirtyGuardProvider({ children }: { readonly children: ReactNode }): ReactNode {
40
+ /**
41
+ * Boundary that guards navigation away from a region holding a dirty editor. Editors
42
+ * inside it arm the guard through {@link useRegisterDirty}; while any is dirty a route
43
+ * navigation (a route-token/plugin navigate, an {@link AppLink}, or a browser
44
+ * back/forward) confirms through the shared discard dialog, and a full-page unload
45
+ * raises the native prompt. Use this directly to guard a dirty editor that is a plain
46
+ * page section (no tabs); {@link GuardedTabs} wraps this same boundary to additionally
47
+ * guard tab switches.
48
+ */
49
+ export function DirtyGuardBoundary({ children }: { readonly children: ReactNode }): ReactNode {
40
50
  const dirtyIds = useRef<Set<string>>(new Set());
41
51
  // Mirror the registry's non-empty state into React so the navigation guard's
42
52
  // `when` re-arms as editors go dirty/clean.
@@ -96,9 +106,9 @@ function DirtyGuardProvider({ children }: { readonly children: ReactNode }): Rea
96
106
  }
97
107
 
98
108
  /**
99
- * Report an editor's dirty state to the enclosing {@link GuardedTabs}. A no-op
100
- * outside a provider (an editor rendered standalone, e.g. in isolation tests) so
101
- * the hook is always safe to call.
109
+ * Report an editor's dirty state to the enclosing {@link DirtyGuardBoundary} (which
110
+ * {@link GuardedTabs} also provides). A no-op outside a boundary (an editor rendered
111
+ * standalone, e.g. in isolation tests) so the hook is always safe to call.
102
112
  */
103
113
  export function useRegisterDirty(dirty: boolean): void {
104
114
  const ctx = useContext(DirtyGuardContext);
@@ -135,7 +145,7 @@ function GuardedTabsInner({
135
145
 
136
146
  /**
137
147
  * A drop-in replacement for {@link Tabs} that guards a switch away from a dirty
138
- * editor. Wraps the tabs in a {@link DirtyGuardProvider}, so an editor rendered in
148
+ * editor. Wraps the tabs in a {@link DirtyGuardBoundary}, so an editor rendered in
139
149
  * any panel can arm the guard through {@link useRegisterDirty}.
140
150
  */
141
151
  export function GuardedTabs({
@@ -146,8 +156,8 @@ export function GuardedTabs({
146
156
  readonly defaultValue?: string;
147
157
  }): ReactNode {
148
158
  return (
149
- <DirtyGuardProvider>
159
+ <DirtyGuardBoundary>
150
160
  <GuardedTabsInner items={items} defaultValue={defaultValue} />
151
- </DirtyGuardProvider>
161
+ </DirtyGuardBoundary>
152
162
  );
153
163
  }
@@ -155,6 +155,16 @@ export function Field({
155
155
  {label}
156
156
  </label>
157
157
  )}
158
+ {/* The description sits BETWEEN the label and the control, so it stays
159
+ adjacent to the label it glosses. After the control it drifts: a
160
+ group Field can wrap an arbitrarily tall surface (a whole schema
161
+ form), and a description below that surface reads as a footnote to
162
+ nothing. */}
163
+ {description !== undefined ? (
164
+ <p id={descriptionId} className="tai-field-hint" style={{ margin: 0 }}>
165
+ {description}
166
+ </p>
167
+ ) : null}
158
168
  {group ? (
159
169
  <div
160
170
  role="group"
@@ -167,11 +177,6 @@ export function Field({
167
177
  ) : (
168
178
  children
169
179
  )}
170
- {description !== undefined ? (
171
- <p id={descriptionId} className="tai-field-hint" style={{ margin: 0 }}>
172
- {description}
173
- </p>
174
- ) : null}
175
180
  {/* The icon carries the invalid state alongside the color, never the color
176
181
  alone — and it is the ERROR mark: a rejected value is a definite
177
182
  negative, not the warning the triangle states. */}
@@ -9,7 +9,10 @@
9
9
  * used by every config-mutation surface) reports a saved change that did not fully
10
10
  * propagate and points the operator at the System page to reload; `'reload'` (the
11
11
  * System page's own fleet-reload action) drops the "Change saved" framing — nothing
12
- * was saved, a reload was dispatched — and the self-referential System-page pointer.
12
+ * was saved, a reload was dispatched — and the self-referential System-page pointer;
13
+ * `'deregister'` and `'remove'` (detach fan-outs) likewise drop the "Change saved"
14
+ * framing and points the operator back at re-running the deregister, because a
15
+ * reload would re-attach the very server being detached — the wrong remediation.
13
16
  *
14
17
  * A `converged` summary (every worker applied, or a lone-worker local-only change)
15
18
  * renders NOTHING — the calling surface shows its own success. A `degraded` summary
@@ -73,26 +76,44 @@ const OUTCOME_STATUS: Record<FleetFailureOutcome, StatusTone> = {
73
76
  */
74
77
  export interface FleetReportProps {
75
78
  readonly summary: FleetReportSummary | null;
76
- /** Whose framing the copy takes: a saved config change, or a dispatched reload. */
77
- readonly action?: 'save' | 'reload';
79
+ /**
80
+ * Whose framing the copy takes: a saved config change (`'save'`), a dispatched
81
+ * reload (`'reload'`), a connector detach fan-out (`'deregister'`), or a live-registry
82
+ * tool removal (`'remove'`). All but `'save'` drop the "Change saved" framing;
83
+ * `'deregister'` and `'remove'` also point remediation back at re-running that
84
+ * same detach, since a reload would re-attach the detached server or tool.
85
+ */
86
+ readonly action?: 'save' | 'reload' | 'deregister' | 'remove';
78
87
  }
79
88
 
80
89
  export function FleetReport({ summary, action = 'save' }: FleetReportProps): ReactNode {
81
90
  if (summary === null || summary.status === 'converged') return null;
82
91
 
92
+ // Only a saved config change carries the "Change saved" framing; a reload or a
93
+ // deregister saved nothing.
94
+ const savedFraming = action === 'save';
95
+
83
96
  if (summary.status === 'unreachable') {
97
+ // Where to send the operator once the bus is back: re-run the same op, except a
98
+ // saved change reloads from the System page.
99
+ const unreachableRemediation =
100
+ action === 'deregister'
101
+ ? 'Re-run the deregister once the bus is back.'
102
+ : action === 'remove'
103
+ ? 'Re-run the remove once the bus is back.'
104
+ : action === 'reload'
105
+ ? 'Re-run the reload once the bus is back.'
106
+ : 'Re-run the reload from the System page once the bus is back.';
84
107
  return (
85
108
  <div role="alert" className="tai-error-state tai-stack tai-stack-2">
86
109
  <strong className="tai-status tai-status-err">
87
110
  <XCircleIcon />
88
- {action === 'reload'
89
- ? 'The worker fleet was not reached'
90
- : 'Change saved, but the worker fleet was not reached'}
111
+ {savedFraming
112
+ ? 'Change saved, but the worker fleet was not reached'
113
+ : 'The worker fleet was not reached'}
91
114
  </strong>
92
115
  <p>
93
- {action === 'reload'
94
- ? 'The worker bus was unreachable, so other workers may still be running the old config. Re-run the reload once the bus is back.'
95
- : 'The worker bus was unreachable, so other workers may still be running the old config. Re-run the reload from the System page once the bus is back.'}
116
+ {`The worker bus was unreachable, so other workers may still be running the old config. ${unreachableRemediation}`}
96
117
  </p>
97
118
  {/* The bus error is a message, not a listing: it wraps rather than scrolls. */}
98
119
  {summary.error !== null ? (
@@ -111,17 +132,27 @@ export function FleetReport({ summary, action = 'save' }: FleetReportProps): Rea
111
132
  // worker is the commonest degraded fleet there is.
112
133
  const count = summary.failures.length;
113
134
  const workers = `${String(count)} worker${count === 1 ? '' : 's'}`;
135
+ // How the operator converges the stranded workers: re-run the same op, except a
136
+ // saved change reloads the fleet from the System page.
137
+ const remediation =
138
+ action === 'deregister'
139
+ ? 're-run the deregister'
140
+ : action === 'remove'
141
+ ? 're-run the remove'
142
+ : action === 'reload'
143
+ ? 're-run the reload'
144
+ : 'reload the fleet from the System page';
114
145
  return (
115
146
  <div role="alert" className="tai-warn-state tai-stack tai-stack-2">
116
147
  <strong className="tai-status tai-status-warn">
117
148
  <AlertTriangleIcon />
118
- {action === 'reload'
119
- ? `${workers} did not converge`
120
- : `Change saved, but ${workers} did not converge`}
149
+ {savedFraming
150
+ ? `Change saved, but ${workers} did not converge`
151
+ : `${workers} did not converge`}
121
152
  </strong>
122
153
  <p>
123
154
  {`${count === 1 ? 'This worker' : 'These workers'} may still be running the old config — ` +
124
- (action === 'reload' ? 're-run the reload' : 'reload the fleet from the System page') +
155
+ remediation +
125
156
  ` to converge ${count === 1 ? 'it' : 'them'}.`}
126
157
  </p>
127
158
  <ul className="tai-stack tai-stack-2">
@@ -504,6 +504,24 @@ export const GridIcon: IconComponent = (props) => (
504
504
  </Icon>
505
505
  );
506
506
 
507
+ /** Served endpoints: a broadcast node radiating to the tools it serves. */
508
+ export const ServedEndpointsIcon: IconComponent = (props) => (
509
+ <Icon {...props}>
510
+ <circle cx="12" cy="12" r="2.5" />
511
+ <path d="M7.8 7.8a6 6 0 0 0 0 8.4" />
512
+ <path d="M16.2 7.8a6 6 0 0 1 0 8.4" />
513
+ <path d="M5 5a9 9 0 0 0 0 14" />
514
+ <path d="M19 5a9 9 0 0 1 0 14" />
515
+ </Icon>
516
+ );
517
+
518
+ /** Plugin: a puzzle piece — the host's provenance mark for plugin-contributed nav. */
519
+ export const PluginIcon: IconComponent = (props) => (
520
+ <Icon {...props}>
521
+ <path d="M10 4a2 2 0 0 1 4 0c0 .8.7 1.4 1.5 1.4H18a1 1 0 0 1 1 1v2.6c0 .8.6 1.5 1.4 1.5a2 2 0 0 1 0 4c-.8 0-1.4.7-1.4 1.5V19a1 1 0 0 1-1 1h-2.6c-.8 0-1.4-.6-1.4-1.4a2 2 0 0 0-4 0c0 .8-.6 1.4-1.4 1.4H6a1 1 0 0 1-1-1v-2.5C5 15.7 4.4 15 3.6 15a2 2 0 0 1 0-4c.8 0 1.4-.7 1.4-1.5V6a1 1 0 0 1 1-1h2.5C9.3 5 10 4.4 10 3.6z" />
522
+ </Icon>
523
+ );
524
+
507
525
  // -- Route mapping -----------------------------------------------------------
508
526
 
509
527
  /**
@@ -519,6 +537,7 @@ export const NAV_ICONS: Readonly<Record<Exclude<RouteToken, 'login'>, IconCompon
519
537
  extensions: ExtensionsIcon,
520
538
  templates: TemplatesIcon,
521
539
  connectors: ConnectorsIcon,
540
+ servedEndpoints: ServedEndpointsIcon,
522
541
  hooks: HooksIcon,
523
542
  storage: StorageIcon,
524
543
  scheduling: SchedulingIcon,
package/src/host.ts CHANGED
@@ -12,4 +12,8 @@ export {
12
12
  subscribePluginHost,
13
13
  usePluginContributions,
14
14
  } from './plugin/host-state';
15
- export type { PluginLoaderState, PluginContributionsSnapshot } from './plugin/host-state';
15
+ export type {
16
+ PluginLoaderState,
17
+ LoadedPlugin,
18
+ PluginContributionsSnapshot,
19
+ } from './plugin/host-state';
package/src/index.ts CHANGED
@@ -11,9 +11,22 @@
11
11
  * exported only from `@tai42/studio-sdk/host`, which the host bundle imports. See
12
12
  * SECURITY.md for the trust boundary.
13
13
  *
14
- * The three shared modules (react, react-dom, @tai42/studio-sdk) are singletons
15
- * across the plugin boundary; this package imports nothing internal at runtime
16
- * (the `ApiClient`/`Interaction` types are type-only imports).
14
+ * The shared modules (react, react-dom, @tai42/studio-sdk, @tai42/jq-studio) are
15
+ * singletons across the plugin boundary; this package imports nothing internal at
16
+ * runtime (the `ApiClient`/`Interaction` types are type-only imports).
17
+ *
18
+ * NO JQ. The visual jq editor is `@tai42/jq-studio`, a separately published,
19
+ * client-agnostic package, and this barrel does not re-export it — not even as a
20
+ * thin pass-through. A bundler emits a package's Web Worker file and wasm engine
21
+ * from the mere PRESENCE of the module in the graph (the assets are emitted while
22
+ * the module is transformed, before tree-shaking can drop an unused re-export), so
23
+ * a pass-through here would put ~2.9MB of jq runtime into every consumer that
24
+ * imports this barrel for a Button. Consumers that want the editor import
25
+ * `@tai42/jq-studio` directly; the import map resolves that bare specifier to the
26
+ * one served copy, so the whole deployment still shares a single jq instance, a
27
+ * single primitives injection, and a single worker. What the SDK keeps is the
28
+ * INJECTION POINT — `ExpressionFieldContext` / `SchemaForm`'s `expressionField`
29
+ * prop, plus the mirrored contract types — which holds no edge to jq at all.
17
30
  */
18
31
  // The design system, delivered by the BARREL so each host app loads it once and a
19
32
  // plugin never ships its own copy. These are bare side-effect imports, so they
@@ -48,29 +61,6 @@ export type {
48
61
  export { STUDIO_PLUGIN_API_VERSION, checkPluginApiVersion } from './plugin/version';
49
62
  export type { VersionGateResult } from './plugin/version';
50
63
 
51
- // -- jq fields (re-exported from @tai42/jq-studio; the platform owns no jq code) --
52
- export {
53
- JqField,
54
- JQEditorDialog,
55
- JqEditorDialog,
56
- preloadJq,
57
- installDefaultJqWorker,
58
- PrimitivesProvider,
59
- } from './jq';
60
- export type {
61
- JqFieldProps,
62
- JQEditorDialogProps,
63
- JqEditorDialogProps,
64
- ExpressionLanguage,
65
- JqInputKey,
66
- JqInputShapeDescriptor,
67
- SampleInputProvider,
68
- ServerValidationResult,
69
- ServerValidateHook,
70
- JqFieldDeclaration,
71
- Primitives,
72
- } from './jq';
73
-
74
64
  // -- Hooks -------------------------------------------------------------------
75
65
  export { ApiProvider, useApi } from './hooks/useApi';
76
66
  export type { ApiClient } from './hooks/useApi';
@@ -201,7 +191,7 @@ export { Dialog } from './components/dialog';
201
191
  export type { DialogProps } from './components/dialog';
202
192
  export { ConfirmDialog } from './components/confirm-dialog';
203
193
  export type { ConfirmDialogProps } from './components/confirm-dialog';
204
- export { GuardedTabs, useRegisterDirty } from './components/dirty-guard';
194
+ export { GuardedTabs, DirtyGuardBoundary, useRegisterDirty } from './components/dirty-guard';
205
195
  export { FormDialog } from './components/form-dialog';
206
196
  export type { FormDialogProps } from './components/form-dialog';
207
197
  export { Drawer } from './components/drawer';
@@ -328,6 +318,8 @@ export {
328
318
  ExtensionsIcon,
329
319
  TemplatesIcon,
330
320
  ConnectorsIcon,
321
+ ServedEndpointsIcon,
322
+ PluginIcon,
331
323
  HooksIcon,
332
324
  StorageIcon,
333
325
  SchedulingIcon,
@@ -373,10 +365,11 @@ export {
373
365
  SchemaForm,
374
366
  RecordEntryRendererContext,
375
367
  // The expression-door injection point: a host that wants `x-tai42-expression`
376
- // fields to author through the visual editor hands `JqField` to a form (the
377
- // `expressionField` prop) or mounts this context above its tree. A form with no
378
- // door renders those fields as plain string inputs and stays free of the jq
379
- // subgraph — the editor, its worker, and its wasm — entirely.
368
+ // fields to author through the visual editor imports `JqField` from
369
+ // `@tai42/jq-studio` and hands it to a form (the `expressionField` prop) or
370
+ // mounts this context above its tree. A form with no door renders those fields
371
+ // as plain string inputs and stays free of the jq subgraph — the editor, its
372
+ // worker, and its wasm — entirely.
380
373
  ExpressionFieldContext,
381
374
  SecretRefField,
382
375
  defaultValueForSchema,