@jini-ai/ui 0.4.7 → 0.4.9

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 (128) hide show
  1. package/README.md +2 -0
  2. package/dist/features/admin-widgets/components/InfoTip.d.ts +23 -2
  3. package/dist/features/admin-widgets/components/InfoTip.hooks.d.ts +22 -2
  4. package/dist/features/admin-widgets/components/InfoTip.hooks.js +75 -28
  5. package/dist/features/admin-widgets/components/InfoTip.js +12 -4
  6. package/dist/features/admin-widgets/components/InfoTip.rules.d.ts +72 -0
  7. package/dist/features/admin-widgets/components/InfoTip.rules.js +68 -0
  8. package/dist/features/admin-widgets/components/SuggestInput/SuggestInput.d.ts +36 -0
  9. package/dist/features/admin-widgets/components/SuggestInput/SuggestInput.hooks.d.ts +58 -0
  10. package/dist/features/admin-widgets/components/SuggestInput/SuggestInput.hooks.js +66 -0
  11. package/dist/features/admin-widgets/components/SuggestInput/SuggestInput.js +24 -0
  12. package/dist/features/admin-widgets/components/useDebouncedHtmlPreview.hooks.d.ts +23 -0
  13. package/dist/features/admin-widgets/components/useDebouncedHtmlPreview.hooks.js +28 -0
  14. package/dist/features/admin-widgets/index.d.ts +9 -0
  15. package/dist/features/admin-widgets/index.js +5 -0
  16. package/dist/features/execution/constants.js +11 -10
  17. package/dist/features/execution/http-adapter.d.ts +3 -1
  18. package/dist/features/execution/http-adapter.js +9 -4
  19. package/dist/features/execution/index.d.ts +1 -1
  20. package/dist/features/execution/index.js +1 -1
  21. package/dist/features/execution/react/components/ByokProviderForm.d.ts +18 -1
  22. package/dist/features/execution/react/components/ByokProviderForm.js +14 -16
  23. package/dist/features/execution/react/components/LocalCliAgentCard.d.ts +5 -1
  24. package/dist/features/execution/react/components/LocalCliAgentCard.js +12 -87
  25. package/dist/features/execution/react/components/LocalCliAgentList.d.ts +4 -1
  26. package/dist/features/execution/react/components/LocalCliAgentList.js +13 -4
  27. package/dist/features/execution/react/components/LocalCliAgentSettings.d.ts +20 -0
  28. package/dist/features/execution/react/components/LocalCliAgentSettings.js +20 -0
  29. package/dist/features/execution/react/hooks/use-byok-field-validation.hooks.d.ts +24 -0
  30. package/dist/features/execution/react/hooks/use-byok-field-validation.hooks.js +27 -0
  31. package/dist/features/execution/react/hooks/useExecutionTab.js +10 -1
  32. package/dist/features/execution/react/hooks/useLocalCliAgentCard.d.ts +48 -0
  33. package/dist/features/execution/react/hooks/useLocalCliAgentCard.js +110 -0
  34. package/dist/features/execution/react/hooks/useLocalCliAgentList.d.ts +19 -0
  35. package/dist/features/execution/react/hooks/useLocalCliAgentList.js +13 -0
  36. package/dist/features/execution/rules.d.ts +13 -0
  37. package/dist/features/execution/rules.js +14 -0
  38. package/dist/features/execution/types.d.ts +2 -0
  39. package/dist/features/html-editor/canvas-embed-placeholders.d.ts +13 -1
  40. package/dist/features/html-editor/canvas-embed-placeholders.js +61 -12
  41. package/dist/features/html-editor/dom.d.ts +5 -0
  42. package/dist/features/html-editor/dom.js +10 -0
  43. package/dist/features/html-editor/editor-blocks.d.ts +71 -0
  44. package/dist/features/html-editor/editor-blocks.js +185 -0
  45. package/dist/features/html-editor/editor-serialization.d.ts +24 -0
  46. package/dist/features/html-editor/editor-serialization.js +110 -0
  47. package/dist/features/html-editor/index.d.ts +5 -0
  48. package/dist/features/html-editor/index.js +3 -0
  49. package/dist/features/html-editor/protected-elements.d.ts +64 -0
  50. package/dist/features/html-editor/protected-elements.js +189 -0
  51. package/dist/features/html-editor/react/components/InteractiveHtmlEditor.d.ts +6 -4
  52. package/dist/features/html-editor/react/components/InteractiveHtmlEditor.js +3 -3
  53. package/dist/features/html-editor/react/hooks/useInteractiveHtmlEditor.d.ts +9 -1
  54. package/dist/features/html-editor/react/hooks/useInteractiveHtmlEditor.js +107 -196
  55. package/dist/features/html-editor/source-splice.d.ts +23 -0
  56. package/dist/features/html-editor/source-splice.js +45 -0
  57. package/dist/features/i18n/dictionaries/settings-dialog.ar.js +4 -0
  58. package/dist/features/i18n/dictionaries/settings-dialog.bn.js +4 -0
  59. package/dist/features/i18n/dictionaries/settings-dialog.de.js +4 -0
  60. package/dist/features/i18n/dictionaries/settings-dialog.en.js +4 -0
  61. package/dist/features/i18n/dictionaries/settings-dialog.es.js +4 -0
  62. package/dist/features/i18n/dictionaries/settings-dialog.fa.js +4 -0
  63. package/dist/features/i18n/dictionaries/settings-dialog.fr.js +4 -0
  64. package/dist/features/i18n/dictionaries/settings-dialog.hi.js +4 -0
  65. package/dist/features/i18n/dictionaries/settings-dialog.hu.js +4 -0
  66. package/dist/features/i18n/dictionaries/settings-dialog.id.js +4 -0
  67. package/dist/features/i18n/dictionaries/settings-dialog.it.js +4 -0
  68. package/dist/features/i18n/dictionaries/settings-dialog.ja.js +4 -0
  69. package/dist/features/i18n/dictionaries/settings-dialog.ko.js +4 -0
  70. package/dist/features/i18n/dictionaries/settings-dialog.pl.js +4 -0
  71. package/dist/features/i18n/dictionaries/settings-dialog.pt-BR.js +4 -0
  72. package/dist/features/i18n/dictionaries/settings-dialog.ru.js +4 -0
  73. package/dist/features/i18n/dictionaries/settings-dialog.th.js +4 -0
  74. package/dist/features/i18n/dictionaries/settings-dialog.tr.js +4 -0
  75. package/dist/features/i18n/dictionaries/settings-dialog.uk.js +4 -0
  76. package/dist/features/i18n/dictionaries/settings-dialog.ur.js +4 -0
  77. package/dist/features/i18n/dictionaries/settings-dialog.zh-CN.js +4 -0
  78. package/dist/features/i18n/dictionaries/settings-dialog.zh-TW.js +4 -0
  79. package/dist/features/interactive-ui/interactive-ui.css +1 -1
  80. package/dist/features/interactive-ui/providers/recharts/bar-chart.js +1 -1
  81. package/dist/features/interactive-ui/providers/recharts/line-chart.js +1 -1
  82. package/dist/features/interactive-ui/providers/shadcn/button.d.ts +1 -1
  83. package/dist/features/mcp-ui/escape.js +2 -6
  84. package/dist/features/mcp-ui/surfaces/bridge.js +4 -2
  85. package/dist/features/mcp-ui/surfaces/document.d.ts +11 -4
  86. package/dist/features/mcp-ui/surfaces/document.js +25 -3
  87. package/dist/features/mcp-ui/surfaces/outcome.js +1 -1
  88. package/dist/features/media-providers/constants.d.ts +0 -7
  89. package/dist/features/media-providers/constants.js +7 -15
  90. package/dist/features/media-providers/react/components/MediaProvidersTab.js +3 -2
  91. package/dist/features/media-providers/react/hooks/useMediaProvidersTab.js +6 -3
  92. package/dist/features/memory/dependencies.d.ts +2 -0
  93. package/dist/features/memory/dependencies.js +9 -25
  94. package/dist/features/memory/index.d.ts +1 -0
  95. package/dist/features/memory/index.js +1 -0
  96. package/dist/features/memory/react/MemoryPorts.d.ts +17 -0
  97. package/dist/features/memory/react/MemoryPorts.js +15 -0
  98. package/dist/features/memory/react/hooks/useMemoryConfig.hooks.d.ts +2 -2
  99. package/dist/features/memory/react/hooks/useMemoryConfig.hooks.js +7 -7
  100. package/dist/features/memory/react/hooks/useMemoryConnectors.hooks.d.ts +2 -3
  101. package/dist/features/memory/react/hooks/useMemoryConnectors.hooks.js +4 -5
  102. package/dist/features/memory/react/hooks/useMemoryEntries.hooks.d.ts +2 -3
  103. package/dist/features/memory/react/hooks/useMemoryEntries.hooks.js +4 -5
  104. package/dist/features/memory/react/hooks/useMemoryExtractions.hooks.js +2 -2
  105. package/dist/features/panel-kit/fetch-query/adapter.react.d.ts +2 -2
  106. package/dist/features/panel-kit/fetch-query/adapter.react.js +2 -2
  107. package/dist/features/panel-kit/fetch-query/adapter.tanstack.d.ts +1 -1
  108. package/dist/features/panel-kit/fetch-query/adapter.tanstack.js +35 -13
  109. package/dist/features/panel-kit/fetch-query/binding.react.d.ts +1 -1
  110. package/dist/features/panel-kit/fetch-query/environment.browser.d.ts +1 -1
  111. package/dist/features/panel-kit/fetch-query/index.d.ts +4 -2
  112. package/dist/features/panel-kit/fetch-query/tanstack.d.ts +4 -2
  113. package/dist/features/panel-kit/helpers/standing-draft-recovery-message.d.ts +3 -1
  114. package/dist/features/panel-kit/helpers/standing-draft-recovery-message.js +9 -2
  115. package/dist/features/settings/dialog/styles/settings-dialog.css +169 -21
  116. package/dist/features/tabbed-dialog/styles/tabbed-dialog.css +91 -0
  117. package/dist/react/components/RemixIcon.d.ts +1 -41
  118. package/dist/react/components/RemixIcon.js +3 -176
  119. package/dist/react/components/RemixIcon.stylesheet.d.ts +84 -0
  120. package/dist/react/components/RemixIcon.stylesheet.js +208 -0
  121. package/dist/react/components/remixicon-font-recovery.d.ts +55 -0
  122. package/dist/react/components/remixicon-font-recovery.js +110 -0
  123. package/dist/styles/admin.css +8 -2
  124. package/package.json +12 -7
  125. package/dist/features/panel-kit/fetch-query/cache.d.ts +0 -125
  126. package/dist/features/panel-kit/fetch-query/cache.js +0 -232
  127. package/dist/features/panel-kit/fetch-query/types.d.ts +0 -93
  128. package/dist/features/panel-kit/fetch-query/types.js +0 -2
@@ -8,7 +8,7 @@ import { type SurfaceTokenName } from './tokens.js';
8
8
  * be a color no caller could reskin. `var(--x, fallback)` appears only where a value is genuinely
9
9
  * optional.
10
10
  */
11
- export declare const SURFACE_BASE_CSS = "*, *::before, *::after { box-sizing: border-box; }\nhtml, body { margin: 0; padding: 0; }\nbody {\n /* Transparent, not var(--jini-mcpui-bg): this document has no page of its own to paint. It is an\n allow-scripts-only sandboxed iframe embedded directly in a host's chat transcript, and html's\n background is left at its (also transparent) initial value, so the host's own pane shows\n straight through to .mcpui-surface below rather than through a second, unrelated rectangle of\n fill color sitting between the two. --jini-mcpui-bg stays declared for a caller styling\n something else via extraCss -- nothing in this stylesheet reads it anymore. */\n background: transparent;\n color: var(--jini-mcpui-text);\n font-family: var(--jini-mcpui-font);\n font-size: 14px;\n line-height: 1.5;\n padding: 16px;\n -webkit-font-smoothing: antialiased;\n}\n.mcpui-surface {\n background: linear-gradient(135deg,\n color-mix(in srgb, var(--jini-mcpui-accent) 5%, var(--jini-mcpui-panel)) 0%,\n var(--jini-mcpui-panel) 60%);\n border: 1px solid color-mix(in srgb, var(--jini-mcpui-accent) 18%, var(--jini-mcpui-border));\n border-radius: var(--jini-mcpui-radius-md);\n box-shadow: var(--jini-mcpui-surface-shadow);\n padding: 18px 20px 16px;\n max-width: 640px;\n margin: 0 auto;\n}\n.mcpui-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--jini-mcpui-text-strong);\n}\n.mcpui-description { margin: 6px 0 0; color: var(--jini-mcpui-text-muted); }\n.mcpui-details {\n display: grid;\n grid-template-columns: max-content minmax(0, 1fr);\n gap: 4px 14px;\n margin: 14px 0 0;\n}\n.mcpui-details dt { color: var(--jini-mcpui-text-soft); font-weight: 500; }\n.mcpui-details dd { margin: 0; overflow-wrap: anywhere; color: var(--jini-mcpui-text); }\n.mcpui-code {\n margin: 0;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n max-height: 16em;\n overflow: auto;\n font-family: var(--jini-mcpui-font-mono);\n font-size: 12.5px;\n line-height: 1.45;\n padding: 6px 8px;\n border: 1px solid var(--jini-mcpui-border);\n border-radius: var(--jini-mcpui-radius-sm);\n background: var(--jini-mcpui-bg);\n}\n.mcpui-warning {\n margin: 14px 0 0;\n padding: 9px 11px;\n border-radius: var(--jini-mcpui-radius-md);\n border: 1px solid var(--jini-mcpui-danger);\n background: var(--jini-mcpui-danger-tint);\n color: var(--jini-mcpui-text-strong);\n}\n.mcpui-fields { display: flex; flex-direction: column; gap: 12px; margin: 16px 0 0; border: 0; padding: 0; }\n.mcpui-field { display: flex; flex-direction: column; gap: 4px; }\n.mcpui-field-inline { flex-direction: row; align-items: flex-start; gap: 8px; }\n.mcpui-label { font-weight: 500; color: var(--jini-mcpui-text-strong); }\n.mcpui-required { color: var(--jini-mcpui-accent); margin-left: 2px; }\n.mcpui-hint { color: var(--jini-mcpui-text-soft); font-size: 13px; }\n.mcpui-input, .mcpui-select, .mcpui-textarea {\n font: inherit;\n color: var(--jini-mcpui-text);\n background: var(--jini-mcpui-panel);\n border: 1px solid color-mix(in srgb, var(--jini-mcpui-accent) 14%, var(--jini-mcpui-border-strong));\n border-radius: var(--jini-mcpui-radius-sm);\n padding: 7px 9px;\n width: 100%;\n min-width: 0;\n}\n.mcpui-textarea { resize: vertical; min-height: 72px; font-family: var(--jini-mcpui-font); }\n.mcpui-checkbox { margin: 3px 0 0; accent-color: var(--jini-mcpui-accent); }\n.mcpui-choice-group { border: 0; padding: 0; margin: 0; min-width: 0; }\n.mcpui-choice { display: flex; flex-direction: row; align-items: flex-start; gap: 8px; margin: 6px 0 0; }\n.mcpui-choice-label { color: var(--jini-mcpui-text); font-weight: 400; }\n.mcpui-input:focus-visible, .mcpui-select:focus-visible, .mcpui-textarea:focus-visible,\n.mcpui-checkbox:focus-visible, .mcpui-button:focus-visible {\n outline: 2px solid var(--jini-mcpui-accent-ring);\n outline-offset: 1px;\n border-color: var(--jini-mcpui-accent);\n}\n.mcpui-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 18px 0 0; }\n.mcpui-button {\n font: inherit;\n font-weight: 500;\n padding: 7px 15px;\n border-radius: var(--jini-mcpui-radius-pill);\n border: 1px solid color-mix(in srgb, var(--jini-mcpui-accent) 14%, var(--jini-mcpui-border-strong));\n background: var(--jini-mcpui-panel);\n color: var(--jini-mcpui-text);\n cursor: pointer;\n}\n.mcpui-button:hover:not([disabled]) { background: var(--jini-mcpui-accent-tint); }\n.mcpui-button-primary {\n background: var(--jini-mcpui-accent);\n border-color: var(--jini-mcpui-accent);\n color: var(--jini-mcpui-panel);\n}\n.mcpui-button-primary:hover:not([disabled]) { background: var(--jini-mcpui-accent-hover); border-color: var(--jini-mcpui-accent-hover); }\n.mcpui-button-danger {\n background: var(--jini-mcpui-danger);\n border-color: var(--jini-mcpui-danger);\n color: var(--jini-mcpui-panel);\n}\n.mcpui-button-danger:hover:not([disabled]) { background: var(--jini-mcpui-danger-hover); border-color: var(--jini-mcpui-danger-hover); }\n.mcpui-button[disabled] { opacity: 0.55; cursor: default; }\n.mcpui-status { margin: 12px 0 0; min-height: 1.4em; color: var(--jini-mcpui-text-muted); }\n.mcpui-status[data-state=\"failed\"], .mcpui-status[data-state=\"invalid\"], .mcpui-status[data-state=\"expired\"] { color: var(--jini-mcpui-danger); }\n.mcpui-status[data-state=\"done\"] { color: var(--jini-mcpui-text-strong); }\n/* Neither a plain success nor a failure \u2014 e.g. an outcome surface reporting \"uploaded, not yet\n reachable\" (outcome.ts's own state: partial). Distinct from both --jini-mcpui-danger (would\n wrongly read as \"this failed\") and --jini-mcpui-text-strong (would wrongly read as \"this is\n fully done\"); the accent token reads as \"worth a second look\" without asserting either. */\n.mcpui-status[data-state=\"partial\"] { color: var(--jini-mcpui-accent); }\n.mcpui-code { font-family: var(--jini-mcpui-font-mono); font-size: 13px; color: var(--jini-mcpui-text-faint); }";
11
+ export declare const SURFACE_BASE_CSS = "*, *::before, *::after { box-sizing: border-box; }\nhtml, body { margin: 0; padding: 0; }\nbody {\n /* Transparent, not var(--jini-mcpui-bg): this document has no page of its own to paint. It is an\n allow-scripts-only sandboxed iframe embedded directly in a host's chat transcript, and html's\n background is left at its (also transparent) initial value, so the host's own pane shows\n straight through to .mcpui-surface below rather than through a second, unrelated rectangle of\n fill color sitting between the two. --jini-mcpui-bg stays declared for a caller styling\n something else via extraCss -- nothing in this stylesheet reads it anymore. */\n background: transparent;\n color: var(--jini-mcpui-text);\n font-family: var(--jini-mcpui-font);\n font-size: 14px;\n line-height: 1.5;\n padding: 16px;\n -webkit-font-smoothing: antialiased;\n}\n.mcpui-surface {\n background: linear-gradient(135deg,\n color-mix(in srgb, var(--jini-mcpui-accent) 5%, var(--jini-mcpui-panel)) 0%,\n var(--jini-mcpui-panel) 60%);\n border: 1px solid color-mix(in srgb, var(--jini-mcpui-accent) 18%, var(--jini-mcpui-border));\n border-radius: var(--jini-mcpui-radius-md);\n box-shadow: var(--jini-mcpui-surface-shadow);\n padding: 18px 20px 16px;\n max-width: 640px;\n margin: 0 auto;\n}\n.mcpui-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n letter-spacing: -0.01em;\n color: var(--jini-mcpui-text-strong);\n}\n.mcpui-description { margin: 6px 0 0; color: var(--jini-mcpui-text-muted); }\n.mcpui-details {\n display: grid;\n grid-template-columns: max-content minmax(0, 1fr);\n gap: 4px 14px;\n margin: 14px 0 0;\n}\n.mcpui-details dt { color: var(--jini-mcpui-text-soft); font-weight: 500; }\n.mcpui-details dd { margin: 0; overflow-wrap: anywhere; color: var(--jini-mcpui-text); }\n.mcpui-details-outcome { display: flex; flex-direction: column; gap: 8px; }\n.mcpui-outcome-row { display: flex; align-items: flex-start; gap: 14px; }\n.mcpui-outcome-row dt { flex: 1; min-width: 0; overflow-wrap: anywhere; }\n.mcpui-outcome-row dt .mcpui-hint { display: block; font-weight: 400; }\n.mcpui-outcome-row dd { flex: 1; min-width: 0; }\n/* Capped so a long status cannot squeeze the label back to one character per line; the full text\n stays in the cell's title. */\n.mcpui-outcome-row dd.mcpui-detail-status {\n flex: 0 1 auto; max-width: 60%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n}\n/* The iframe has 16px body padding on each side: 352px viewport = 320px card. Stacked, the value\n has the full width, so it wraps between words instead of truncating. */\n@media (max-width: 352px) {\n .mcpui-outcome-row { flex-direction: column; gap: 2px; }\n .mcpui-outcome-row dd.mcpui-detail-status { max-width: 100%; white-space: normal; overflow-wrap: normal; }\n}\n.mcpui-code {\n margin: 0;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n max-height: 16em;\n overflow: auto;\n font-family: var(--jini-mcpui-font-mono);\n font-size: 12.5px;\n line-height: 1.45;\n padding: 6px 8px;\n border: 1px solid var(--jini-mcpui-border);\n border-radius: var(--jini-mcpui-radius-sm);\n background: var(--jini-mcpui-bg);\n}\n.mcpui-warning {\n margin: 14px 0 0;\n padding: 9px 11px;\n border-radius: var(--jini-mcpui-radius-md);\n border: 1px solid var(--jini-mcpui-danger);\n background: var(--jini-mcpui-danger-tint);\n color: var(--jini-mcpui-text-strong);\n}\n.mcpui-fields { display: flex; flex-direction: column; gap: 12px; margin: 16px 0 0; border: 0; padding: 0; }\n.mcpui-field { display: flex; flex-direction: column; gap: 4px; }\n.mcpui-field-inline { flex-direction: row; align-items: flex-start; gap: 8px; }\n.mcpui-label { font-weight: 500; color: var(--jini-mcpui-text-strong); }\n.mcpui-required { color: var(--jini-mcpui-accent); margin-left: 2px; }\n.mcpui-hint { color: var(--jini-mcpui-text-soft); font-size: 13px; }\n.mcpui-input, .mcpui-select, .mcpui-textarea {\n font: inherit;\n color: var(--jini-mcpui-text);\n background: var(--jini-mcpui-panel);\n border: 1px solid color-mix(in srgb, var(--jini-mcpui-accent) 14%, var(--jini-mcpui-border-strong));\n border-radius: var(--jini-mcpui-radius-sm);\n padding: 7px 9px;\n width: 100%;\n min-width: 0;\n}\n.mcpui-textarea { resize: vertical; min-height: 72px; font-family: var(--jini-mcpui-font); }\n.mcpui-checkbox { margin: 3px 0 0; accent-color: var(--jini-mcpui-accent); }\n.mcpui-choice-group { border: 0; padding: 0; margin: 0; min-width: 0; }\n.mcpui-choice { display: flex; flex-direction: row; align-items: flex-start; gap: 8px; margin: 6px 0 0; }\n.mcpui-choice-label { color: var(--jini-mcpui-text); font-weight: 400; }\n.mcpui-input:focus-visible, .mcpui-select:focus-visible, .mcpui-textarea:focus-visible,\n.mcpui-checkbox:focus-visible, .mcpui-button:focus-visible {\n outline: 2px solid var(--jini-mcpui-accent-ring);\n outline-offset: 1px;\n border-color: var(--jini-mcpui-accent);\n}\n.mcpui-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 18px 0 0; }\n.mcpui-button {\n font: inherit;\n font-weight: 500;\n padding: 7px 15px;\n border-radius: var(--jini-mcpui-radius-pill);\n border: 1px solid color-mix(in srgb, var(--jini-mcpui-accent) 14%, var(--jini-mcpui-border-strong));\n background: var(--jini-mcpui-panel);\n color: var(--jini-mcpui-text);\n cursor: pointer;\n}\n.mcpui-button:hover:not([disabled]) { background: var(--jini-mcpui-accent-tint); }\n.mcpui-button-primary {\n background: var(--jini-mcpui-accent);\n border-color: var(--jini-mcpui-accent);\n color: var(--jini-mcpui-panel);\n}\n.mcpui-button-primary:hover:not([disabled]) { background: var(--jini-mcpui-accent-hover); border-color: var(--jini-mcpui-accent-hover); }\n.mcpui-button-danger {\n background: var(--jini-mcpui-danger);\n border-color: var(--jini-mcpui-danger);\n color: var(--jini-mcpui-panel);\n}\n.mcpui-button-danger:hover:not([disabled]) { background: var(--jini-mcpui-danger-hover); border-color: var(--jini-mcpui-danger-hover); }\n.mcpui-button[disabled] { opacity: 0.55; cursor: default; }\n.mcpui-status { margin: 12px 0 0; min-height: 1.4em; color: var(--jini-mcpui-text-muted); }\n.mcpui-status[data-state=\"failed\"], .mcpui-status[data-state=\"invalid\"], .mcpui-status[data-state=\"expired\"] { color: var(--jini-mcpui-danger); }\n.mcpui-status[data-state=\"done\"] { color: var(--jini-mcpui-text-strong); }\n/* Neither a plain success nor a failure \u2014 e.g. an outcome surface reporting \"uploaded, not yet\n reachable\" (outcome.ts's own state: partial). Distinct from both --jini-mcpui-danger (would\n wrongly read as \"this failed\") and --jini-mcpui-text-strong (would wrongly read as \"this is\n fully done\"); the accent token reads as \"worth a second look\" without asserting either. */\n.mcpui-status[data-state=\"partial\"] { color: var(--jini-mcpui-accent); }\n.mcpui-code { font-family: var(--jini-mcpui-font-mono); font-size: 13px; color: var(--jini-mcpui-text-faint); }";
12
12
  /**
13
13
  * The Content-Security-Policy every generated surface declares in its own `<head>`.
14
14
  *
@@ -66,20 +66,27 @@ export declare function renderSurfaceHeader(spec: {
66
66
  export interface SurfaceDetail {
67
67
  readonly label: string;
68
68
  readonly value: string;
69
+ /** Optional secondary context beneath the label, using the shared muted hint style. */
70
+ readonly description?: string;
69
71
  /**
70
72
  * `code` renders the value in a monospace `<pre>` that keeps its line breaks and scrolls inside
71
73
  * its own box past a fixed height, so a long SQL statement or JSON argument stays readable without
72
- * stretching the dialog past its frame. Omitted (or `text`) keeps the plain inline value.
74
+ * stretching the dialog past its frame. `status` reserves one line for a short outcome value.
75
+ * Omitted (or `text`) keeps the plain inline value.
73
76
  */
74
- readonly format?: 'text' | 'code';
77
+ readonly format?: 'text' | 'code' | 'status';
75
78
  }
76
79
  /**
77
80
  * Renders a `label: value` description list.
78
81
  *
82
+ * @param options.layout - Outcome rows size independently and stack in narrow cards.
79
83
  * @returns The `<dl>`, or `''` for an empty list — an empty `<dl>` is announced by screen readers
80
84
  * as a list with no items, which is worse than no list.
85
+ * @complexity O(n) in the rendered length; no effects or input mutation.
81
86
  */
82
- export declare function renderDetailList(details: readonly SurfaceDetail[]): string;
87
+ export declare function renderDetailList(details: readonly SurfaceDetail[], options?: {
88
+ layout?: 'outcome';
89
+ }): string;
83
90
  /** Renders the polite live region every surface reports outcomes through. Its id is fixed so surface scripts can find it. */
84
91
  export declare function renderStatusRegion(): string;
85
92
  /**
@@ -67,6 +67,22 @@ body {
67
67
  }
68
68
  .mcpui-details dt { color: var(--jini-mcpui-text-soft); font-weight: 500; }
69
69
  .mcpui-details dd { margin: 0; overflow-wrap: anywhere; color: var(--jini-mcpui-text); }
70
+ .mcpui-details-outcome { display: flex; flex-direction: column; gap: 8px; }
71
+ .mcpui-outcome-row { display: flex; align-items: flex-start; gap: 14px; }
72
+ .mcpui-outcome-row dt { flex: 1; min-width: 0; overflow-wrap: anywhere; }
73
+ .mcpui-outcome-row dt .mcpui-hint { display: block; font-weight: 400; }
74
+ .mcpui-outcome-row dd { flex: 1; min-width: 0; }
75
+ /* Capped so a long status cannot squeeze the label back to one character per line; the full text
76
+ stays in the cell's title. */
77
+ .mcpui-outcome-row dd.mcpui-detail-status {
78
+ flex: 0 1 auto; max-width: 60%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
79
+ }
80
+ /* The iframe has 16px body padding on each side: 352px viewport = 320px card. Stacked, the value
81
+ has the full width, so it wraps between words instead of truncating. */
82
+ @media (max-width: 352px) {
83
+ .mcpui-outcome-row { flex-direction: column; gap: 2px; }
84
+ .mcpui-outcome-row dd.mcpui-detail-status { max-width: 100%; white-space: normal; overflow-wrap: normal; }
85
+ }
70
86
  .mcpui-code {
71
87
  margin: 0;
72
88
  white-space: pre-wrap;
@@ -216,20 +232,26 @@ export function renderSurfaceHeader(spec) {
216
232
  /**
217
233
  * Renders a `label: value` description list.
218
234
  *
235
+ * @param options.layout - Outcome rows size independently and stack in narrow cards.
219
236
  * @returns The `<dl>`, or `''` for an empty list — an empty `<dl>` is announced by screen readers
220
237
  * as a list with no items, which is worse than no list.
238
+ * @complexity O(n) in the rendered length; no effects or input mutation.
221
239
  */
222
- export function renderDetailList(details) {
240
+ export function renderDetailList(details, options = {}) {
223
241
  if (details.length === 0)
224
242
  return '';
243
+ const outcome = options.layout === 'outcome';
225
244
  const rows = details
226
245
  .map((detail) => {
227
246
  const value = escapeHtml(detail.value);
228
247
  const body = detail.format === 'code' ? `<pre class="mcpui-code">${value}</pre>` : value;
229
- return ` <dt>${escapeHtml(detail.label)}</dt><dd>${body}</dd>`;
248
+ const description = detail.description === undefined ? '' : `<span class="mcpui-hint">${escapeHtml(detail.description)}</span>`;
249
+ const valueClass = detail.format === 'status' ? ` class="mcpui-detail-status" title="${value}"` : '';
250
+ const pair = `<dt>${escapeHtml(detail.label)}${description}</dt><dd${valueClass}>${body}</dd>`;
251
+ return outcome ? ` <div class="mcpui-outcome-row">${pair}</div>` : ` ${pair}`;
230
252
  })
231
253
  .join('\n');
232
- return `<dl class="mcpui-details">\n${rows}\n</dl>`;
254
+ return `<dl class="mcpui-details${outcome ? ' mcpui-details-outcome' : ''}">\n${rows}\n</dl>`;
233
255
  }
234
256
  /** Renders the polite live region every surface reports outcomes through. Its id is fixed so surface scripts can find it. */
235
257
  export function renderStatusRegion() {
@@ -68,7 +68,7 @@ export function renderOutcomeDocument(spec) {
68
68
  : '';
69
69
  const bodyHtml = [
70
70
  renderSurfaceHeader(spec.description === undefined ? { title: spec.title } : { title: spec.title, description: spec.description }),
71
- renderDetailList(spec.details ?? []),
71
+ renderDetailList(spec.details ?? [], { layout: 'outcome' }),
72
72
  statusHtml,
73
73
  actionsHtml,
74
74
  ]
@@ -1,10 +1,3 @@
1
1
  import type { MediaProviderOption } from './types.js';
2
- /**
3
- * A small, vendor-shaped starting catalog — same convention as `execution/constants.ts`'s
4
- * `DEFAULT_PROVIDER_PRESETS`. Sourced by driving Open Design's own Settings → Media providers
5
- * panel directly (Playwright) and transcribing its real provider list, base URLs, and default
6
- * models. Pass your own `catalog` to `MediaProvidersTab` to replace this wholesale; Zana or any
7
- * other host is expected to do so once it has its own provider roster.
8
- */
9
2
  export declare const DEFAULT_MEDIA_PROVIDER_CATALOG: readonly MediaProviderOption[];
10
3
  //# sourceMappingURL=constants.d.ts.map
@@ -1,3 +1,4 @@
1
+ import { findProvider, canonicalMediaProviderId } from '@jini-ai/integrations/media-providers/catalog';
1
2
  /**
2
3
  * A small, vendor-shaped starting catalog — same convention as `execution/constants.ts`'s
3
4
  * `DEFAULT_PROVIDER_PRESETS`. Sourced by driving Open Design's own Settings → Media providers
@@ -5,17 +6,15 @@
5
6
  * models. Pass your own `catalog` to `MediaProvidersTab` to replace this wholesale; Zana or any
6
7
  * other host is expected to do so once it has its own provider roster.
7
8
  */
8
- export const DEFAULT_MEDIA_PROVIDER_CATALOG = [
9
+ const starterCatalog = [
9
10
  {
10
11
  id: 'nano-banana',
11
12
  label: 'Nano Banana',
12
- defaultBaseUrl: 'https://generativelanguage.googleapis.com',
13
13
  models: ['gemini-3.1-flash-image-preview'],
14
14
  },
15
15
  {
16
16
  id: 'aihubmix',
17
17
  label: 'AIHubMix',
18
- defaultBaseUrl: 'https://aihubmix.com/v1',
19
18
  models: ['gemini-3.1-flash-image-preview'],
20
19
  },
21
20
  {
@@ -26,65 +25,58 @@ export const DEFAULT_MEDIA_PROVIDER_CATALOG = [
26
25
  {
27
26
  id: 'elevenlabs',
28
27
  label: 'ElevenLabs',
29
- defaultBaseUrl: 'https://api.elevenlabs.io',
30
28
  },
31
29
  {
32
30
  id: 'fal-ai',
33
31
  label: 'Fal.ai',
34
- defaultBaseUrl: 'https://fal.run',
35
32
  models: ['gemini-3.1-flash-image-preview'],
36
33
  },
37
34
  {
38
35
  id: 'fishaudio',
39
36
  label: 'FishAudio',
40
- defaultBaseUrl: 'https://api.fish.audio',
41
37
  },
42
38
  {
43
39
  id: 'imagerouter',
44
40
  label: 'ImageRouter',
45
- defaultBaseUrl: 'https://api.imagerouter.io/v1/openai',
46
41
  models: ['gemini-3.1-flash-image-preview'],
47
42
  },
48
43
  {
49
44
  id: 'leonardo-ai',
50
45
  label: 'Leonardo.ai',
51
- defaultBaseUrl: 'https://cloud.leonardo.ai/api/rest/v1',
52
46
  },
53
47
  {
54
48
  id: 'minimax',
55
49
  label: 'MiniMax',
56
- defaultBaseUrl: 'https://api.minimaxi.chat/v1',
57
50
  },
58
51
  {
59
52
  id: 'openai',
60
53
  label: 'OpenAI',
61
- defaultBaseUrl: 'https://api.openai.com/v1',
62
54
  models: ['gpt-image-2', 'dall-e-3'],
63
55
  },
64
56
  {
65
57
  id: 'openrouter',
66
58
  label: 'OpenRouter',
67
- defaultBaseUrl: 'https://openrouter.ai/api/v1',
68
59
  },
69
60
  {
70
61
  id: 'senseaudio',
71
62
  label: 'SenseAudio',
72
- defaultBaseUrl: 'https://api.senseaudio.cn',
73
63
  },
74
64
  {
75
65
  id: 'tavily-search',
76
66
  label: 'Tavily Search',
77
- defaultBaseUrl: 'https://api.tavily.com',
78
67
  },
79
68
  {
80
69
  id: 'volcengine-ark',
81
70
  label: 'Volcengine Ark (Doubao)',
82
- defaultBaseUrl: 'https://ark.cn-beijing.volces.com/api/v3',
83
71
  },
84
72
  {
85
73
  id: 'xai-grok-imagine',
86
74
  label: 'xAI Grok Imagine',
87
- defaultBaseUrl: 'https://api.x.ai/v1',
88
75
  },
89
76
  ];
77
+ export const DEFAULT_MEDIA_PROVIDER_CATALOG = starterCatalog.map((entry) => {
78
+ const id = canonicalMediaProviderId({ id: entry.id });
79
+ const provider = findProvider({ id });
80
+ return { ...entry, id, label: provider.label, ...(provider.defaultBaseUrl ? { defaultBaseUrl: provider.defaultBaseUrl } : {}) };
81
+ });
90
82
  //# sourceMappingURL=constants.js.map
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { canonicalMediaProviderId } from '@jini-ai/integrations/media-providers/catalog';
2
3
  import { Fragment, useState } from 'react';
3
4
  import { agentHandleProps, buildAgentListHandles } from '@jini-ai/agentic';
4
5
  import { useT } from '../../../i18n/index.js';
@@ -55,7 +56,7 @@ export function MediaProvidersTab({ port, catalog = DEFAULT_MEDIA_PROVIDER_CATAL
55
56
  return next;
56
57
  });
57
58
  };
58
- const orderedCatalog = sortProvidersByConfigured(catalog, providers, pinnedProviderIds);
59
+ const orderedCatalog = sortProvidersByConfigured(catalog.map((entry) => ({ ...entry, id: canonicalMediaProviderId({ id: entry.id }) })), providers, pinnedProviderIds?.map((id) => canonicalMediaProviderId({ id })));
59
60
  const providerHandles = agentHandle
60
61
  ? buildAgentListHandles({ prefix: agentHandle, ids: orderedCatalog.map((option) => option.id) })
61
62
  : undefined;
@@ -63,7 +64,7 @@ export function MediaProvidersTab({ port, catalog = DEFAULT_MEDIA_PROVIDER_CATAL
63
64
  // pinned id absent from `catalog` never appears in `orderedCatalog` either (see
64
65
  // `sortProvidersByConfigured`'s own "silently skipped" doc), so this stays correct without
65
66
  // re-deriving which pinned ids actually resolved to a real card.
66
- const pinnedIdSet = new Set(pinnedProviderIds ?? []);
67
+ const pinnedIdSet = new Set(pinnedProviderIds?.map((id) => canonicalMediaProviderId({ id })) ?? []);
67
68
  const hasPendingChanges = pendingProviderIds.size > 0;
68
69
  // Save writes every provider at once, so ONE unacceptable endpoint blocks the
69
70
  // whole button rather than being silently persisted alongside the good ones.
@@ -1,3 +1,4 @@
1
+ import { normalizeMediaProviderMap, canonicalMediaProviderId } from '@jini-ai/integrations/media-providers/catalog';
1
2
  import { useCallback, useEffect, useRef, useState } from 'react';
2
3
  import { hasAnyConfiguredProvider, isEntryEmpty, mergeDaemonProviders, shouldSyncLocalProvidersToDaemon, } from '../../rules.js';
3
4
  /**
@@ -18,7 +19,7 @@ import { hasAnyConfiguredProvider, isEntryEmpty, mergeDaemonProviders, shouldSyn
18
19
  * server manages nothing" and silently wipe local edits.
19
20
  */
20
21
  export function useMediaProvidersTab({ port, initialProviders }) {
21
- const [providers, setProviders] = useState(() => ({ ...(initialProviders ?? {}) }));
22
+ const [providers, setProviders] = useState(() => normalizeMediaProviderMap({ providers: initialProviders ?? {} }));
22
23
  const [pendingProviderIds, setPendingProviderIds] = useState(() => new Set());
23
24
  const [load, setLoad] = useState({ status: 'loading' });
24
25
  const [save, setSave] = useState({ status: 'idle' });
@@ -113,7 +114,7 @@ export function useMediaProvidersTab({ port, initialProviders }) {
113
114
  if (!touched.has(providerId))
114
115
  clearedProviderIds.current.delete(providerId);
115
116
  }
116
- const next = { ...saved };
117
+ const next = normalizeMediaProviderMap({ providers: saved });
117
118
  for (const providerId of touched) {
118
119
  const local = providersRef.current[providerId];
119
120
  if (local === undefined)
@@ -205,7 +206,7 @@ export function useMediaProvidersTab({ port, initialProviders }) {
205
206
  setLoad({ status: 'unreachable' });
206
207
  return;
207
208
  }
208
- const merged = mergeDaemonProviders(providersRef.current, daemonResult, {
209
+ const merged = mergeDaemonProviders(providersRef.current, normalizeMediaProviderMap({ providers: daemonResult }), {
209
210
  preserveLocalProviderIds: pendingRef.current,
210
211
  dropProviderIds: clearedProviderIds.current,
211
212
  });
@@ -226,6 +227,7 @@ export function useMediaProvidersTab({ port, initialProviders }) {
226
227
  fetchAndReconcile(false);
227
228
  }, [fetchAndReconcile]);
228
229
  const updateProvider = useCallback((providerId, patch) => {
230
+ providerId = canonicalMediaProviderId({ id: providerId });
229
231
  const current = providersRef.current;
230
232
  const nextEntry = { ...(current[providerId] ?? {}), ...patch };
231
233
  const nextMap = { ...current };
@@ -242,6 +244,7 @@ export function useMediaProvidersTab({ port, initialProviders }) {
242
244
  mutatedSinceSend.current.add(providerId);
243
245
  }, [applyProviders, applyPending]);
244
246
  const clearProvider = useCallback((providerId) => {
247
+ providerId = canonicalMediaProviderId({ id: providerId });
245
248
  void (async () => {
246
249
  const previousEntry = providersRef.current[providerId];
247
250
  const next = { ...providersRef.current };
@@ -9,6 +9,7 @@ export declare function createMemoryHttpPorts(_required: Record<string, never>,
9
9
  entries: MemoryEntriesPort;
10
10
  extractions: MemoryExtractionsPort;
11
11
  };
12
+ /** @deprecated Explicit legacy REST binding. Host UI composition must use MemoryPortsProvider. */
12
13
  export declare const memoryConfigPort: MemoryConfigPort, memoryEntriesPort: MemoryEntriesPort, memoryExtractionsPort: MemoryExtractionsPort;
13
14
  /** Standalone default read shares the entries port's validated REST implementation. */
14
15
  export declare const fetchMemoryList: () => Promise<MemoryListResponse>;
@@ -25,5 +26,6 @@ export interface FakeMemoryConnectorsPortOptions {
25
26
  * above — only the connector catalogue/status/suggest transport is faked.
26
27
  */
27
28
  export declare function createFakeMemoryConnectorsPort(options?: FakeMemoryConnectorsPortOptions): MemoryConnectorsPort;
29
+ /** @deprecated Demo catalogue; hosts supply their own connectors port through MemoryPortsProvider. */
28
30
  export declare const memoryConnectorsPort: MemoryConnectorsPort;
29
31
  //# sourceMappingURL=dependencies.d.ts.map
@@ -1,29 +1,11 @@
1
1
  /**
2
- * The only file in this feature allowed to touch a concrete transport
3
- * adapter. Everything else in the slice depends on `ports.ts`.
4
- *
5
- * Split, deliberately, into two different defaults:
6
- *
7
- * - `memoryConfigPort`/`memoryEntriesPort`/`memoryExtractionsPort` bind REAL
8
- * `fetch`-based adapters against a plain `/api/memory*` REST surface (list/
9
- * tree/entry CRUD, config PATCH, extraction history CRUD). Unlike
10
- * `features/connectors`' data port — which fakes its transport by design,
11
- * because the real one is a specific third-party OAuth-catalog vendor's
12
- * API shape — this is a generic JSON/REST contract with no vendor coupling,
13
- * and the pinned source's one open bug (`fetchMemoryList()` trusting an
14
- * under-validated response — see the fix below and
15
- * `packages/ui/archived provenance ledger`) only exists to fix in a real, testable
16
- * adapter. A host is still free to supply its own binding; this default
17
- * just isn't a fake.
18
- * - `memoryConnectorsPort` binds a fake/in-memory connector catalogue (same
19
- * reasoning as `features/connectors`' own fake — the real catalogue is a
20
- * vendor-specific OAuth discovery transport this package doesn't assume),
21
- * plus REAL browser-only bridges for the two pieces that touch only
22
- * generic browser APIs: pending-authorization persistence (sessionStorage)
23
- * and the cross-tab "connectors changed" signal (a `CustomEvent`).
24
- * `saveMemoryEntry` on this port is the same real HTTP adapter the entries
25
- * cluster uses — saving a connector suggestion is an ordinary memory write,
26
- * not a connector-transport concern.
2
+ * Explicit legacy/test transport bindings; Memory's wired hooks never select them implicitly.
3
+ * Production hosts supply MemoryPortsProvider with authorized config/entries/extractions and
4
+ * connector ports. createMemoryHttpPorts binds a host-selected REST contract; exported singletons
5
+ * retain the old /api/memory* paths for compatibility only. memoryConnectorsPort is a demo catalogue
6
+ * with sessionStorage/CustomEvent bridges and real REST memory writes, not production discovery.
7
+ * Removal plan: migrate singleton consumers to host factories/providers, then remove deprecated
8
+ * defaults in an owner-approved breaking release. Do not silently turn a demo into a live port.
27
9
  */
28
10
  import { requestWithTimeout } from '../../utils/browser-request.js';
29
11
  import { DEFAULT_CONNECTOR_PROVIDER, MEMORY_CONNECTOR_PENDING_AUTH_STORAGE_KEY, } from './constants.js';
@@ -163,6 +145,7 @@ export function createMemoryHttpPorts(_required, { fetch } = {}) {
163
145
  };
164
146
  return { config: memoryConfigPort, entries: memoryEntriesPort, extractions: memoryExtractionsPort };
165
147
  }
148
+ /** @deprecated Explicit legacy REST binding. Host UI composition must use MemoryPortsProvider. */
166
149
  export const { config: memoryConfigPort, entries: memoryEntriesPort, extractions: memoryExtractionsPort } = createMemoryHttpPorts({});
167
150
  /** Standalone default read shares the entries port's validated REST implementation. */
168
151
  export const fetchMemoryList = memoryEntriesPort.fetchMemoryList;
@@ -251,5 +234,6 @@ function notifyConnectorsChanged() {
251
234
  return;
252
235
  window.dispatchEvent(new CustomEvent(CONNECTORS_CHANGED_EVENT));
253
236
  }
237
+ /** @deprecated Demo catalogue; hosts supply their own connectors port through MemoryPortsProvider. */
254
238
  export const memoryConnectorsPort = createFakeMemoryConnectorsPort();
255
239
  //# sourceMappingURL=dependencies.js.map
@@ -1,3 +1,4 @@
1
+ export { MemoryPortsProvider, useMemoryPorts, type MemoryPorts } from './react/MemoryPorts.js';
1
2
  export { FIELD_LABEL_STYLE } from './react/styles.js';
2
3
  export { type AsyncCommitGuard, createAsyncCommitGuard } from './async-commit-guard.js';
3
4
  export { CONNECTOR_CALLBACK_MESSAGE_TYPE, connectorAppLabel, DEFAULT_CONNECTOR_PROVIDER, EMPTY_DRAFT, MEMORY_CONNECTOR_APP_IDS, MEMORY_CONNECTOR_APP_LABELS, MEMORY_CONNECTOR_PENDING_AUTH_STORAGE_KEY, STARTERS, TYPES, } from './constants.js';
@@ -1,3 +1,4 @@
1
+ export { MemoryPortsProvider, useMemoryPorts } from './react/MemoryPorts.js';
1
2
  export { FIELD_LABEL_STYLE } from './react/styles.js';
2
3
  export { createAsyncCommitGuard } from './async-commit-guard.js';
3
4
  export { CONNECTOR_CALLBACK_MESSAGE_TYPE, connectorAppLabel, DEFAULT_CONNECTOR_PROVIDER, EMPTY_DRAFT, MEMORY_CONNECTOR_APP_IDS, MEMORY_CONNECTOR_APP_LABELS, MEMORY_CONNECTOR_PENDING_AUTH_STORAGE_KEY, STARTERS, TYPES, } from './constants.js';
@@ -0,0 +1,17 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { MemoryConfigPort, MemoryConnectorsPort, MemoryEntriesPort, MemoryExtractionsPort } from '../ports.js';
3
+ /** Hosts own authentication, endpoint paths and connector discovery; memory UI owns no transport. */
4
+ export interface MemoryPorts {
5
+ config: MemoryConfigPort;
6
+ entries: MemoryEntriesPort;
7
+ extractions: MemoryExtractionsPort;
8
+ connectors: MemoryConnectorsPort;
9
+ }
10
+ /** Bind one host's memory services to its subtree. Independent hosts never share these ports. */
11
+ export declare function MemoryPortsProvider({ ports, children }: {
12
+ ports: MemoryPorts;
13
+ children: ReactNode;
14
+ }): import("react").JSX.Element;
15
+ /** Fail at composition when no host was bound, before a hook can attempt network I/O. */
16
+ export declare function useMemoryPorts(_required?: Record<string, never>, _optional?: Record<string, never>): MemoryPorts;
17
+ //# sourceMappingURL=MemoryPorts.d.ts.map
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from 'react';
3
+ const MemoryPortsContext = createContext(null);
4
+ /** Bind one host's memory services to its subtree. Independent hosts never share these ports. */
5
+ export function MemoryPortsProvider({ ports, children }) {
6
+ return _jsx(MemoryPortsContext.Provider, { value: ports, children: children });
7
+ }
8
+ /** Fail at composition when no host was bound, before a hook can attempt network I/O. */
9
+ export function useMemoryPorts(_required = {}, _optional = {}) {
10
+ const ports = useContext(MemoryPortsContext);
11
+ if (!ports)
12
+ throw new Error('Memory hooks require MemoryPortsProvider');
13
+ return ports;
14
+ }
15
+ //# sourceMappingURL=MemoryPorts.js.map
@@ -22,8 +22,8 @@ export interface MemoryConfigController {
22
22
  }
23
23
  export declare function useMemoryConfig(port: MemoryConfigPort): MemoryConfigController;
24
24
  /**
25
- * Wirer: binds the real provider port and returns a ready-to-call hook. This is
26
- * the default a host injects; swap it via the component prop in tests.
25
+ * Reads the host-injected config port from MemoryPortsProvider (required).
26
+ * Hosts own authorization/transport; tests may inject a fake into useMemoryConfig.
27
27
  */
28
28
  export declare function useWiredMemoryConfig(): MemoryConfigController;
29
29
  //# sourceMappingURL=useMemoryConfig.hooks.d.ts.map
@@ -8,13 +8,13 @@
8
8
  // mocks, no global `fetch` stub.
9
9
  // - business logic (the pure `rules`) is imported directly; only the
10
10
  // side-effecting transport is injected.
11
- // - `useWiredMemoryConfig()` (the wirer, bottom of file) binds the real
12
- // provider port and is the default a host injects, so production callers
13
- // pass nothing while tests swap the whole hook.
11
+ // - useWiredMemoryConfig() (below) reads the host-injected config port from
12
+ // MemoryPortsProvider. Production hosts must mount that provider; tests inject
13
+ // a fake port directly or swap the hook. There is no implicit REST fallback.
14
14
  import { useCallback, useMemo, useRef, useState } from 'react';
15
15
  import { createAsyncCommitGuard } from '../../async-commit-guard.js';
16
16
  import { enabledPatch, singleFlagPatch } from '../../rules.js';
17
- import { memoryConfigPort } from '../../dependencies.js';
17
+ import { useMemoryPorts } from '../MemoryPorts.js';
18
18
  const CONFIG_SAVE_ERROR_MESSAGE = "Memory settings couldn't be saved. Try again shortly.";
19
19
  function newConfigWriteQueue() {
20
20
  return { inFlight: false, pending: null };
@@ -210,10 +210,10 @@ export function useMemoryConfig(port) {
210
210
  };
211
211
  }
212
212
  /**
213
- * Wirer: binds the real provider port and returns a ready-to-call hook. This is
214
- * the default a host injects; swap it via the component prop in tests.
213
+ * Reads the host-injected config port from MemoryPortsProvider (required).
214
+ * Hosts own authorization/transport; tests may inject a fake into useMemoryConfig.
215
215
  */
216
216
  export function useWiredMemoryConfig() {
217
- return useMemoryConfig(memoryConfigPort);
217
+ return useMemoryConfig(useMemoryPorts().config);
218
218
  }
219
219
  //# sourceMappingURL=useMemoryConfig.hooks.js.map
@@ -91,9 +91,8 @@ export declare function applyMemoryConnectorConnectResult({ connectorId, result,
91
91
  }): boolean;
92
92
  export declare function useMemoryConnectors(port: MemoryConnectorsPort, coord: MemoryConnectorsCoordination): MemoryConnectorsController;
93
93
  /**
94
- * Wirer: binds the real connectors transport + OAuth bridges and returns a
95
- * hook that still takes a host's runtime coordination. The default a host
96
- * injects; swap it via the component prop in tests.
94
+ * Reads the host-injected connector catalogue/OAuth bridges from MemoryPortsProvider
95
+ * (required), retaining runtime coordination. The deprecated demo catalogue is never a fallback.
97
96
  */
98
97
  export declare function useWiredMemoryConnectors(coord: MemoryConnectorsCoordination): MemoryConnectorsController;
99
98
  //# sourceMappingURL=useMemoryConnectors.hooks.d.ts.map
@@ -38,7 +38,7 @@ import { createAsyncCommitGuard } from '../../async-commit-guard.js';
38
38
  import { DEFAULT_CONNECTOR_PROVIDER, MEMORY_CONNECTOR_APP_IDS, MEMORY_CONNECTOR_APP_LABELS, } from '../../constants.js';
39
39
  import { describeExtractionFailure } from '../../formatters.js';
40
40
  import { applyMemoryConnectorStatus, connectorWithPendingAuthorization, memoryEntryIdForConnectorSuggestion, upsertMemoryConnector, } from '../../rules.js';
41
- import { memoryConnectorsPort } from '../../dependencies.js';
41
+ import { useMemoryPorts } from '../MemoryPorts.js';
42
42
  import { describeConnectorSuggestionOutcome, describeConnectorSuggestionsSaveOutcome, isRecentFailedConnectorExtraction, withoutKey, withoutSetMember, } from './useMemoryConnectors.rules.js';
43
43
  /** `onSaveConnectorSuggestions`'s save loop, isolated: writes each selected
44
44
  * suggestion as a memory entry in order, collecting which ones landed and
@@ -507,11 +507,10 @@ export function useMemoryConnectors(port, coord) {
507
507
  };
508
508
  }
509
509
  /**
510
- * Wirer: binds the real connectors transport + OAuth bridges and returns a
511
- * hook that still takes a host's runtime coordination. The default a host
512
- * injects; swap it via the component prop in tests.
510
+ * Reads the host-injected connector catalogue/OAuth bridges from MemoryPortsProvider
511
+ * (required), retaining runtime coordination. The deprecated demo catalogue is never a fallback.
513
512
  */
514
513
  export function useWiredMemoryConnectors(coord) {
515
- return useMemoryConnectors(memoryConnectorsPort, coord);
514
+ return useMemoryConnectors(useMemoryPorts().connectors, coord);
516
515
  }
517
516
  //# sourceMappingURL=useMemoryConnectors.hooks.js.map
@@ -44,9 +44,8 @@ export interface MemoryEntriesController {
44
44
  }
45
45
  export declare function useMemoryEntries(port: MemoryEntriesPort, coord: MemoryEntriesCoordination): MemoryEntriesController;
46
46
  /**
47
- * Wirer: binds the real entries transport and returns a hook that still takes
48
- * a host's runtime coordination. The default a host injects; swap it via the
49
- * component prop in tests.
47
+ * Reads the host-injected entries port from MemoryPortsProvider (required),
48
+ * retaining the host's runtime coordination. No /api/memory* transport is chosen implicitly.
50
49
  */
51
50
  export declare function useWiredMemoryEntries(coord: MemoryEntriesCoordination): MemoryEntriesController;
52
51
  //# sourceMappingURL=useMemoryEntries.hooks.d.ts.map
@@ -10,7 +10,7 @@ import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
10
10
  import { copyToClipboard } from '../../../../utils/copy-to-clipboard.js';
11
11
  import { createAsyncCommitGuard } from '../../async-commit-guard.js';
12
12
  import { EMPTY_DRAFT } from '../../constants.js';
13
- import { memoryEntriesPort } from '../../dependencies.js';
13
+ import { useMemoryPorts } from '../MemoryPorts.js';
14
14
  const LOAD_ERROR_MESSAGE = "Memory data couldn't be loaded. Try again shortly.";
15
15
  const MUTATION_ERROR_MESSAGE = "Memory changes couldn't be saved. Try again shortly.";
16
16
  export function useMemoryEntries(port, coord) {
@@ -331,11 +331,10 @@ export function useMemoryEntries(port, coord) {
331
331
  };
332
332
  }
333
333
  /**
334
- * Wirer: binds the real entries transport and returns a hook that still takes
335
- * a host's runtime coordination. The default a host injects; swap it via the
336
- * component prop in tests.
334
+ * Reads the host-injected entries port from MemoryPortsProvider (required),
335
+ * retaining the host's runtime coordination. No /api/memory* transport is chosen implicitly.
337
336
  */
338
337
  export function useWiredMemoryEntries(coord) {
339
- return useMemoryEntries(memoryEntriesPort, coord);
338
+ return useMemoryEntries(useMemoryPorts().entries, coord);
340
339
  }
341
340
  //# sourceMappingURL=useMemoryEntries.hooks.js.map
@@ -13,7 +13,7 @@
13
13
  // store's synchronous transitions to React state.
14
14
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
15
15
  import { createAsyncCommitGuard } from '../../async-commit-guard.js';
16
- import { memoryExtractionsPort } from '../../dependencies.js';
16
+ import { useMemoryPorts } from '../MemoryPorts.js';
17
17
  import { createExtractionHistoryStore } from './useMemoryExtractions.store.js';
18
18
  const LOAD_ERROR_MESSAGE = "Memory extraction history couldn't be loaded. Try again shortly.";
19
19
  const MUTATION_ERROR_MESSAGE = "Memory extraction history couldn't be updated. Try again shortly.";
@@ -176,6 +176,6 @@ export function useMemoryExtractions(port) {
176
176
  };
177
177
  }
178
178
  export function useWiredMemoryExtractions() {
179
- return useMemoryExtractions(memoryExtractionsPort);
179
+ return useMemoryExtractions(useMemoryPorts().extractions);
180
180
  }
181
181
  //# sourceMappingURL=useMemoryExtractions.hooks.js.map
@@ -1,6 +1,6 @@
1
1
  import { type ReactNode } from 'react';
2
- import { type FetchQueryEnvironmentPort } from './cache.js';
3
- import type { CachedLoader, CachedLoaderOptions, FetchMutationOptions, FetchQueryOptions, MutationResult, QueryKey, QueryResult } from './types.js';
2
+ import { type FetchQueryEnvironmentPort } from '@jini-ai/core/fetch';
3
+ import type { CachedLoader, CachedLoaderOptions, FetchMutationOptions, FetchQueryOptions, MutationResult, QueryKey, QueryResult } from '@jini-ai/core/fetch';
4
4
  /** Isolated cache scope; no external provider or query-library singleton is needed. */
5
5
  export declare function FetchQueryProvider({ children, environment }: {
6
6
  children: ReactNode;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';
3
- import { DEFAULT_STALE_TIME, FetchQueryCache, toQueryError } from './cache.js';
3
+ import { DEFAULT_STALE_TIME, FetchQueryCache, toQueryError } from '@jini-ai/core/fetch';
4
4
  import { browserFetchQueryEnvironment } from './environment.browser.js';
5
5
  import { FetchQueryBinding } from './binding.react.js';
6
6
  const CacheContext = createContext(null);
@@ -109,7 +109,7 @@ export function useCachedLoader({ key, fetch }, { staleTime = DEFAULT_STALE_TIME
109
109
  const cache = useCache();
110
110
  return useMemo(() => ({
111
111
  peek: () => cache.entry({ key: key }, { staleTime: staleTime }).state.data,
112
- load: () => cache.load({ entry: cache.entry({ key: key }, { staleTime: staleTime }), fetch: fetch, staleTime: staleTime }),
112
+ load: (required = { key, fetch }) => cache.load({ entry: cache.entry({ key: required.key }, { staleTime }), fetch: required.fetch, staleTime }),
113
113
  replace: ({ value }) => cache.replace({ entry: cache.entry({ key: key }, { staleTime: staleTime }), data: value }),
114
114
  }), [cache, key, fetch, staleTime]);
115
115
  }
@@ -1,6 +1,6 @@
1
1
  /** Optional TanStack translation layer. No library types escape the fetch-query contract. */
2
2
  import { type ReactNode } from 'react';
3
- import { type FetchQueryEnvironmentPort } from './cache.js';
3
+ import { type FetchQueryEnvironmentPort } from '@jini-ai/core/fetch';
4
4
  /** Provider-owned TanStack cache and binding, compatible with hooks from the default entry.
5
5
  * @example <FetchQueryProvider><ResourceScreen /></FetchQueryProvider>
6
6
  * @param props Children and optional host connectivity/focus port. */