@jini-ai/ui 0.4.7 → 0.4.8

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 (125) 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/providers/shadcn/button.d.ts +1 -1
  80. package/dist/features/mcp-ui/escape.js +2 -6
  81. package/dist/features/mcp-ui/surfaces/bridge.js +4 -2
  82. package/dist/features/mcp-ui/surfaces/document.d.ts +11 -4
  83. package/dist/features/mcp-ui/surfaces/document.js +25 -3
  84. package/dist/features/mcp-ui/surfaces/outcome.js +1 -1
  85. package/dist/features/media-providers/constants.d.ts +0 -7
  86. package/dist/features/media-providers/constants.js +7 -15
  87. package/dist/features/media-providers/react/components/MediaProvidersTab.js +3 -2
  88. package/dist/features/media-providers/react/hooks/useMediaProvidersTab.js +6 -3
  89. package/dist/features/memory/dependencies.d.ts +2 -0
  90. package/dist/features/memory/dependencies.js +9 -25
  91. package/dist/features/memory/index.d.ts +1 -0
  92. package/dist/features/memory/index.js +1 -0
  93. package/dist/features/memory/react/MemoryPorts.d.ts +17 -0
  94. package/dist/features/memory/react/MemoryPorts.js +15 -0
  95. package/dist/features/memory/react/hooks/useMemoryConfig.hooks.d.ts +2 -2
  96. package/dist/features/memory/react/hooks/useMemoryConfig.hooks.js +7 -7
  97. package/dist/features/memory/react/hooks/useMemoryConnectors.hooks.d.ts +2 -3
  98. package/dist/features/memory/react/hooks/useMemoryConnectors.hooks.js +4 -5
  99. package/dist/features/memory/react/hooks/useMemoryEntries.hooks.d.ts +2 -3
  100. package/dist/features/memory/react/hooks/useMemoryEntries.hooks.js +4 -5
  101. package/dist/features/memory/react/hooks/useMemoryExtractions.hooks.js +2 -2
  102. package/dist/features/panel-kit/fetch-query/adapter.react.d.ts +2 -2
  103. package/dist/features/panel-kit/fetch-query/adapter.react.js +2 -2
  104. package/dist/features/panel-kit/fetch-query/adapter.tanstack.d.ts +1 -1
  105. package/dist/features/panel-kit/fetch-query/adapter.tanstack.js +35 -13
  106. package/dist/features/panel-kit/fetch-query/binding.react.d.ts +1 -1
  107. package/dist/features/panel-kit/fetch-query/environment.browser.d.ts +1 -1
  108. package/dist/features/panel-kit/fetch-query/index.d.ts +4 -2
  109. package/dist/features/panel-kit/fetch-query/tanstack.d.ts +4 -2
  110. package/dist/features/panel-kit/helpers/standing-draft-recovery-message.d.ts +3 -1
  111. package/dist/features/panel-kit/helpers/standing-draft-recovery-message.js +9 -2
  112. package/dist/features/settings/dialog/styles/settings-dialog.css +169 -21
  113. package/dist/features/tabbed-dialog/styles/tabbed-dialog.css +91 -0
  114. package/dist/react/components/RemixIcon.d.ts +1 -41
  115. package/dist/react/components/RemixIcon.js +3 -176
  116. package/dist/react/components/RemixIcon.stylesheet.d.ts +84 -0
  117. package/dist/react/components/RemixIcon.stylesheet.js +208 -0
  118. package/dist/react/components/remixicon-font-recovery.d.ts +55 -0
  119. package/dist/react/components/remixicon-font-recovery.js +110 -0
  120. package/dist/styles/admin.css +8 -2
  121. package/package.json +12 -7
  122. package/dist/features/panel-kit/fetch-query/cache.d.ts +0 -125
  123. package/dist/features/panel-kit/fetch-query/cache.js +0 -232
  124. package/dist/features/panel-kit/fetch-query/types.d.ts +0 -93
  125. package/dist/features/panel-kit/fetch-query/types.js +0 -2
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_ES = {
7
7
  'About': 'Acerca de',
8
8
  'Accent color': 'Color de acento',
9
9
  'Account': 'Cuenta',
10
+ 'Advanced': 'Avanzado',
10
11
  'Advanced: proxy & custom paths': 'Avanzado: proxy y rutas personalizadas',
11
12
  'Agent check failed': 'Falló la comprobación del agente',
12
13
  'Agent is ready.': 'El agente está listo.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_ES = {
131
132
  'Not available for this daemon.': 'No disponible para este daemon.',
132
133
  'Not configured': 'No configurado',
133
134
  'Not installed': 'No instalado',
135
+ 'Show {count} not installed': 'Mostrar {count} no instalados',
136
+ 'Hide not installed': 'Ocultar no instalados',
137
+ 'Show not-installed CLIs': 'Mostrar CLIs no instalados',
134
138
  'Not sharing': 'No se comparte',
135
139
  'Nothing is shared unless you opt in.': 'No se comparte nada a menos que lo actives.',
136
140
  'Off': 'Desactivado',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_FA = {
7
7
  'About': 'درباره',
8
8
  'Accent color': 'رنگ تأکیدی',
9
9
  'Account': 'حساب کاربری',
10
+ 'Advanced': 'پیشرفته',
10
11
  'Advanced: proxy & custom paths': 'پیشرفته: پراکسی و مسیرهای سفارشی',
11
12
  'Agent check failed': 'بررسی عامل ناموفق بود',
12
13
  'Agent is ready.': 'عامل آماده است.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_FA = {
131
132
  'Not available for this daemon.': 'برای این دیمون در دسترس نیست.',
132
133
  'Not configured': 'پیکربندی‌نشده',
133
134
  'Not installed': 'نصب‌نشده',
135
+ 'Show {count} not installed': 'نمایش {count} مورد نصب‌نشده',
136
+ 'Hide not installed': 'پنهان کردن موارد نصب‌نشده',
137
+ 'Show not-installed CLIs': 'نمایش CLIهای نصب‌نشده',
134
138
  'Not sharing': 'اشتراک‌گذاری نمی‌شود',
135
139
  'Nothing is shared unless you opt in.': 'تا زمانی که خودتان فعال نکنید، چیزی به اشتراک گذاشته نمی‌شود.',
136
140
  'Off': 'خاموش',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_FR = {
7
7
  'About': 'À propos',
8
8
  'Accent color': 'Couleur d\'accent',
9
9
  'Account': 'Compte',
10
+ 'Advanced': 'Avancé',
10
11
  'Advanced: proxy & custom paths': 'Avancé : proxy et chemins personnalisés',
11
12
  'Agent check failed': 'Échec de la vérification de l\'agent',
12
13
  'Agent is ready.': 'L\'agent est prêt.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_FR = {
131
132
  'Not available for this daemon.': 'Non disponible pour ce daemon.',
132
133
  'Not configured': 'Non configuré',
133
134
  'Not installed': 'Non installé',
135
+ 'Show {count} not installed': 'Afficher {count} non installés',
136
+ 'Hide not installed': 'Masquer les non installés',
137
+ 'Show not-installed CLIs': 'Afficher les CLIs non installés',
134
138
  'Not sharing': 'Pas de partage',
135
139
  'Nothing is shared unless you opt in.': 'Rien n\'est partagé tant que vous ne l\'activez pas.',
136
140
  'Off': 'Désactivé',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_HI = {
7
7
  'About': 'परिचय',
8
8
  'Accent color': 'हाइलाइट रंग',
9
9
  'Account': 'खाता',
10
+ 'Advanced': 'उन्नत',
10
11
  'Advanced: proxy & custom paths': 'उन्नत: प्रॉक्सी और कस्टम पाथ',
11
12
  'Agent check failed': 'एजेंट जांच विफल रही',
12
13
  'Agent is ready.': 'एजेंट तैयार है।',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_HI = {
131
132
  'Not available for this daemon.': 'इस डेमन के लिए उपलब्ध नहीं है।',
132
133
  'Not configured': 'कॉन्फ़िगर नहीं किया गया',
133
134
  'Not installed': 'इंस्टॉल नहीं है',
135
+ 'Show {count} not installed': '{count} इंस्टॉल नहीं किए गए दिखाएँ',
136
+ 'Hide not installed': 'इंस्टॉल नहीं किए गए छिपाएँ',
137
+ 'Show not-installed CLIs': 'इंस्टॉल नहीं किए गए CLI दिखाएँ',
134
138
  'Not sharing': 'साझा नहीं किया जा रहा',
135
139
  'Nothing is shared unless you opt in.': 'जब तक आप इसे सक्रिय नहीं करते, तब तक कुछ भी साझा नहीं किया जाता।',
136
140
  'Off': 'बंद',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_HU = {
7
7
  'About': 'Névjegy',
8
8
  'Accent color': 'Kiemelőszín',
9
9
  'Account': 'Fiók',
10
+ 'Advanced': 'Speciális',
10
11
  'Advanced: proxy & custom paths': 'Speciális: proxy és egyéni útvonalak',
11
12
  'Agent check failed': 'Az ügynök ellenőrzése sikertelen',
12
13
  'Agent is ready.': 'Az ügynök készen áll.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_HU = {
131
132
  'Not available for this daemon.': 'Ehhez a démonhoz nem érhető el.',
132
133
  'Not configured': 'Nincs beállítva',
133
134
  'Not installed': 'Nincs telepítve',
135
+ 'Show {count} not installed': '{count} nem telepített megjelenítése',
136
+ 'Hide not installed': 'Nem telepítettek elrejtése',
137
+ 'Show not-installed CLIs': 'Nem telepített CLI-k megjelenítése',
134
138
  'Not sharing': 'Nincs megosztás',
135
139
  'Nothing is shared unless you opt in.': 'Semmi sem kerül megosztásra, amíg nem járulsz hozzá.',
136
140
  'Off': 'Ki',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_ID = {
7
7
  'About': 'Tentang',
8
8
  'Accent color': 'Warna aksen',
9
9
  'Account': 'Akun',
10
+ 'Advanced': 'Lanjutan',
10
11
  'Advanced: proxy & custom paths': 'Lanjutan: proxy & jalur kustom',
11
12
  'Agent check failed': 'Pemeriksaan agen gagal',
12
13
  'Agent is ready.': 'Agen sudah siap.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_ID = {
131
132
  'Not available for this daemon.': 'Tidak tersedia untuk daemon ini.',
132
133
  'Not configured': 'Belum dikonfigurasi',
133
134
  'Not installed': 'Belum terinstal',
135
+ 'Show {count} not installed': 'Tampilkan {count} yang belum terinstal',
136
+ 'Hide not installed': 'Sembunyikan yang belum terinstal',
137
+ 'Show not-installed CLIs': 'Tampilkan CLI yang belum terinstal',
134
138
  'Not sharing': 'Tidak dibagikan',
135
139
  'Nothing is shared unless you opt in.': 'Tidak ada yang dibagikan kecuali Anda memilih untuk mengikutinya.',
136
140
  'Off': 'Nonaktif',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_IT = {
7
7
  'About': 'Informazioni',
8
8
  'Accent color': 'Colore di accento',
9
9
  'Account': 'Account',
10
+ 'Advanced': 'Avanzate',
10
11
  'Advanced: proxy & custom paths': 'Avanzate: proxy e percorsi personalizzati',
11
12
  'Agent check failed': 'Verifica dell\'agente non riuscita',
12
13
  'Agent is ready.': 'L\'agente è pronto.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_IT = {
131
132
  'Not available for this daemon.': 'Non disponibile per questo daemon.',
132
133
  'Not configured': 'Non configurato',
133
134
  'Not installed': 'Non installato',
135
+ 'Show {count} not installed': 'Mostra {count} non installati',
136
+ 'Hide not installed': 'Nascondi non installati',
137
+ 'Show not-installed CLIs': 'Mostra CLI non installati',
134
138
  'Not sharing': 'Nessuna condivisione',
135
139
  'Nothing is shared unless you opt in.': 'Non viene condiviso nulla a meno che tu non lo attivi.',
136
140
  'Off': 'Disattivato',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_JA = {
7
7
  'About': '概要',
8
8
  'Accent color': 'アクセントカラー',
9
9
  'Account': 'アカウント',
10
+ 'Advanced': '詳細設定',
10
11
  'Advanced: proxy & custom paths': '詳細設定:プロキシとカスタムパス',
11
12
  'Agent check failed': 'エージェントの確認に失敗しました',
12
13
  'Agent is ready.': 'エージェントの準備ができました。',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_JA = {
131
132
  'Not available for this daemon.': 'このデーモンでは利用できません。',
132
133
  'Not configured': '未設定',
133
134
  'Not installed': '未インストール',
135
+ 'Show {count} not installed': '未インストールの {count} 件を表示',
136
+ 'Hide not installed': '未インストールを隠す',
137
+ 'Show not-installed CLIs': '未インストールの CLI を表示',
134
138
  'Not sharing': '共有していません',
135
139
  'Nothing is shared unless you opt in.': 'オプトインしない限り、何も共有されません。',
136
140
  'Off': 'オフ',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_KO = {
7
7
  'About': '정보',
8
8
  'Accent color': '강조 색상',
9
9
  'Account': '계정',
10
+ 'Advanced': '고급',
10
11
  'Advanced: proxy & custom paths': '고급: 프록시 및 사용자 지정 경로',
11
12
  'Agent check failed': '에이전트 확인 실패',
12
13
  'Agent is ready.': '에이전트가 준비되었습니다.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_KO = {
131
132
  'Not available for this daemon.': '이 데몬에서는 사용할 수 없습니다.',
132
133
  'Not configured': '구성되지 않음',
133
134
  'Not installed': '설치되지 않음',
135
+ 'Show {count} not installed': '설치되지 않은 {count}개 표시',
136
+ 'Hide not installed': '설치되지 않은 항목 숨기기',
137
+ 'Show not-installed CLIs': '설치되지 않은 CLI 표시',
134
138
  'Not sharing': '공유하지 않음',
135
139
  'Nothing is shared unless you opt in.': '직접 동의하지 않는 한 아무것도 공유되지 않습니다.',
136
140
  'Off': '끄기',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_PL = {
7
7
  'About': 'Informacje',
8
8
  'Accent color': 'Kolor akcentu',
9
9
  'Account': 'Konto',
10
+ 'Advanced': 'Zaawansowane',
10
11
  'Advanced: proxy & custom paths': 'Zaawansowane: proxy i niestandardowe ścieżki',
11
12
  'Agent check failed': 'Sprawdzenie agenta nie powiodło się',
12
13
  'Agent is ready.': 'Agent jest gotowy.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_PL = {
131
132
  'Not available for this daemon.': 'Niedostępne dla tego demona.',
132
133
  'Not configured': 'Nieskonfigurowane',
133
134
  'Not installed': 'Niezainstalowane',
135
+ 'Show {count} not installed': 'Pokaż niezainstalowane ({count})',
136
+ 'Hide not installed': 'Ukryj niezainstalowane',
137
+ 'Show not-installed CLIs': 'Pokaż niezainstalowane CLI',
134
138
  'Not sharing': 'Nieudostępniane',
135
139
  'Nothing is shared unless you opt in.': 'Nic nie jest udostępniane, dopóki się na to nie zgodzisz.',
136
140
  'Off': 'Wyłączone',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_PT_BR = {
7
7
  'About': 'Sobre',
8
8
  'Accent color': 'Cor de destaque',
9
9
  'Account': 'Conta',
10
+ 'Advanced': 'Avançado',
10
11
  'Advanced: proxy & custom paths': 'Avançado: proxy e caminhos personalizados',
11
12
  'Agent check failed': 'Falha na verificação do agente',
12
13
  'Agent is ready.': 'O agente está pronto.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_PT_BR = {
131
132
  'Not available for this daemon.': 'Não disponível para este daemon.',
132
133
  'Not configured': 'Não configurado',
133
134
  'Not installed': 'Não instalado',
135
+ 'Show {count} not installed': 'Mostrar {count} não instalados',
136
+ 'Hide not installed': 'Ocultar não instalados',
137
+ 'Show not-installed CLIs': 'Mostrar CLIs não instalados',
134
138
  'Not sharing': 'Não compartilhando',
135
139
  'Nothing is shared unless you opt in.': 'Nada é compartilhado a menos que você opte por isso.',
136
140
  'Off': 'Desativado',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_RU = {
7
7
  'About': 'О программе',
8
8
  'Accent color': 'Акцентный цвет',
9
9
  'Account': 'Аккаунт',
10
+ 'Advanced': 'Дополнительно',
10
11
  'Advanced: proxy & custom paths': 'Дополнительно: прокси и пользовательские пути',
11
12
  'Agent check failed': 'Проверка агента не удалась',
12
13
  'Agent is ready.': 'Агент готов.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_RU = {
131
132
  'Not available for this daemon.': 'Недоступно для этого демона.',
132
133
  'Not configured': 'Не настроено',
133
134
  'Not installed': 'Не установлено',
135
+ 'Show {count} not installed': 'Показать неустановленные ({count})',
136
+ 'Hide not installed': 'Скрыть неустановленные',
137
+ 'Show not-installed CLIs': 'Показать неустановленные CLI',
134
138
  'Not sharing': 'Не передаётся',
135
139
  'Nothing is shared unless you opt in.': 'Ничего не передаётся, пока вы не включите это.',
136
140
  'Off': 'Выкл.',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_TH = {
7
7
  'About': 'เกี่ยวกับ',
8
8
  'Accent color': 'สีเน้น',
9
9
  'Account': 'บัญชี',
10
+ 'Advanced': 'ขั้นสูง',
10
11
  'Advanced: proxy & custom paths': 'ขั้นสูง: พร็อกซีและพาธที่กำหนดเอง',
11
12
  'Agent check failed': 'ตรวจสอบเอเจนต์ไม่สำเร็จ',
12
13
  'Agent is ready.': 'เอเจนต์พร้อมใช้งานแล้ว',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_TH = {
131
132
  'Not available for this daemon.': 'ใช้ไม่ได้กับดีมอนนี้',
132
133
  'Not configured': 'ยังไม่ได้กำหนดค่า',
133
134
  'Not installed': 'ยังไม่ได้ติดตั้ง',
135
+ 'Show {count} not installed': 'แสดงที่ยังไม่ได้ติดตั้ง {count} รายการ',
136
+ 'Hide not installed': 'ซ่อนที่ยังไม่ได้ติดตั้ง',
137
+ 'Show not-installed CLIs': 'แสดง CLI ที่ยังไม่ได้ติดตั้ง',
134
138
  'Not sharing': 'ไม่ได้แชร์',
135
139
  'Nothing is shared unless you opt in.': 'จะไม่มีการแชร์สิ่งใดจนกว่าคุณจะเปิดใช้งานเอง',
136
140
  'Off': 'ปิด',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_TR = {
7
7
  'About': 'Hakkında',
8
8
  'Accent color': 'Vurgu rengi',
9
9
  'Account': 'Hesap',
10
+ 'Advanced': 'Gelişmiş',
10
11
  'Advanced: proxy & custom paths': 'Gelişmiş: proxy ve özel yollar',
11
12
  'Agent check failed': 'Aracı kontrolü başarısız oldu',
12
13
  'Agent is ready.': 'Aracı hazır.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_TR = {
131
132
  'Not available for this daemon.': 'Bu arka plan süreci için kullanılamaz.',
132
133
  'Not configured': 'Yapılandırılmadı',
133
134
  'Not installed': 'Yüklenmedi',
135
+ 'Show {count} not installed': 'Yüklü olmayan {count} öğeyi göster',
136
+ 'Hide not installed': 'Yüklü olmayanları gizle',
137
+ 'Show not-installed CLIs': 'Yüklü olmayan CLI\'ları göster',
134
138
  'Not sharing': 'Paylaşılmıyor',
135
139
  'Nothing is shared unless you opt in.': 'Siz etkinleştirmedikçe hiçbir şey paylaşılmaz.',
136
140
  'Off': 'Kapalı',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_UK = {
7
7
  'About': 'Про програму',
8
8
  'Accent color': 'Акцентний колір',
9
9
  'Account': 'Обліковий запис',
10
+ 'Advanced': 'Додатково',
10
11
  'Advanced: proxy & custom paths': 'Додатково: проксі та власні шляхи',
11
12
  'Agent check failed': 'Перевірку агента не пройдено',
12
13
  'Agent is ready.': 'Агент готовий.',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_UK = {
131
132
  'Not available for this daemon.': 'Недоступно для цього демона.',
132
133
  'Not configured': 'Не налаштовано',
133
134
  'Not installed': 'Не встановлено',
135
+ 'Show {count} not installed': 'Показати невстановлені ({count})',
136
+ 'Hide not installed': 'Сховати невстановлені',
137
+ 'Show not-installed CLIs': 'Показати невстановлені CLI',
134
138
  'Not sharing': 'Не поширюється',
135
139
  'Nothing is shared unless you opt in.': 'Нічого не поширюється, доки ви не увімкнете це самостійно.',
136
140
  'Off': 'Вимкнено',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_UR = {
7
7
  'About': 'تعارف',
8
8
  'Accent color': 'نمایاں رنگ',
9
9
  'Account': 'اکاؤنٹ',
10
+ 'Advanced': 'اعلیٰ درجے کی ترتیبات',
10
11
  'Advanced: proxy & custom paths': 'ایڈوانسڈ: پراکسی اور کسٹم پاتھز',
11
12
  'Agent check failed': 'ایجنٹ چیک ناکام ہو گیا',
12
13
  'Agent is ready.': 'ایجنٹ تیار ہے۔',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_UR = {
131
132
  'Not available for this daemon.': 'اس ڈیمن کے لیے دستیاب نہیں۔',
132
133
  'Not configured': 'کنفیگر نہیں ہے',
133
134
  'Not installed': 'انسٹال نہیں ہے',
135
+ 'Show {count} not installed': '{count} غیر انسٹال شدہ دکھائیں',
136
+ 'Hide not installed': 'غیر انسٹال شدہ چھپائیں',
137
+ 'Show not-installed CLIs': 'غیر انسٹال شدہ CLI دکھائیں',
134
138
  'Not sharing': 'شیئر نہیں کیا جا رہا',
135
139
  'Nothing is shared unless you opt in.': 'جب تک آپ خود شامل نہ ہوں، کچھ بھی شیئر نہیں کیا جاتا۔',
136
140
  'Off': 'بند',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_ZH_CN = {
7
7
  'About': '关于',
8
8
  'Accent color': '强调色',
9
9
  'Account': '账户',
10
+ 'Advanced': '高级',
10
11
  'Advanced: proxy & custom paths': '高级:代理与自定义路径',
11
12
  'Agent check failed': '智能体检查失败',
12
13
  'Agent is ready.': '智能体已就绪。',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_ZH_CN = {
131
132
  'Not available for this daemon.': '此守护进程不支持该功能。',
132
133
  'Not configured': '未配置',
133
134
  'Not installed': '未安装',
135
+ 'Show {count} not installed': '显示 {count} 个未安装',
136
+ 'Hide not installed': '隐藏未安装',
137
+ 'Show not-installed CLIs': '显示未安装的 CLI',
134
138
  'Not sharing': '未共享',
135
139
  'Nothing is shared unless you opt in.': '除非你主动选择,否则不会共享任何内容。',
136
140
  'Off': '关闭',
@@ -7,6 +7,7 @@ export const SETTINGS_DIALOG_ZH_TW = {
7
7
  'About': '關於',
8
8
  'Accent color': '強調色',
9
9
  'Account': '帳戶',
10
+ 'Advanced': '進階',
10
11
  'Advanced: proxy & custom paths': '進階:代理伺服器與自訂路徑',
11
12
  'Agent check failed': '代理程式檢查失敗',
12
13
  'Agent is ready.': '代理程式已就緒。',
@@ -131,6 +132,9 @@ export const SETTINGS_DIALOG_ZH_TW = {
131
132
  'Not available for this daemon.': '此背景程序不支援此功能。',
132
133
  'Not configured': '尚未設定',
133
134
  'Not installed': '尚未安裝',
135
+ 'Show {count} not installed': '顯示 {count} 個尚未安裝',
136
+ 'Hide not installed': '隱藏尚未安裝',
137
+ 'Show not-installed CLIs': '顯示尚未安裝的 CLI',
134
138
  'Not sharing': '未共享',
135
139
  'Nothing is shared unless you opt in.': '除非你主動選擇加入,否則不會共享任何內容。',
136
140
  'Off': '關閉',
@@ -8,7 +8,7 @@ import * as React from 'react';
8
8
  import { type VariantProps } from 'class-variance-authority';
9
9
  declare const buttonVariants: (props?: ({
10
10
  variant?: "link" | "default" | "outline" | "ghost" | "destructive" | "secondary" | null | undefined;
11
- size?: "default" | "sm" | "lg" | "icon" | null | undefined;
11
+ size?: "default" | "icon" | "sm" | "lg" | null | undefined;
12
12
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
13
13
  export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
14
14
  asChild?: boolean;
@@ -1,3 +1,4 @@
1
+ import { escapeHtml as sharedEscapeHtml } from "@jini-ai/core/text";
1
2
  /**
2
3
  * @module features/mcp-ui/escape
3
4
  *
@@ -21,12 +22,7 @@
21
22
  * @complexity O(n) in the value's length.
22
23
  */
23
24
  export function escapeHtml(value) {
24
- return value
25
- .replace(/&/g, '&amp;')
26
- .replace(/</g, '&lt;')
27
- .replace(/>/g, '&gt;')
28
- .replace(/"/g, '&quot;')
29
- .replace(/'/g, '&#39;');
25
+ return sharedEscapeHtml({ text: value });
30
26
  }
31
27
  /**
32
28
  * Serializes a value as a JS literal safe to embed in an inline `<script>`.
@@ -139,7 +139,9 @@ export function renderBridgeScript(spec) {
139
139
  // good (owner bug 2026-10-08: an ask-choice card stuck at 192px after a reload). Leaving width out
140
140
  // keeps the frame at the host's width: 100%, and the ResizeObserver below re-reports height on resize.
141
141
  function reportSize() {
142
- notify("ui/notifications/size-changed", { height: document.documentElement.scrollHeight });
142
+ // Root scrollHeight includes the iframe viewport, so a short card could never shrink.
143
+ // The body box includes the surface and its padding without that viewport floor.
144
+ notify("ui/notifications/size-changed", { height: Math.ceil(document.body.getBoundingClientRect().height) });
143
145
  }
144
146
 
145
147
  window.addEventListener("message", function (event) {
@@ -180,7 +182,7 @@ export function renderBridgeScript(spec) {
180
182
  readyHandlers = [];
181
183
  for (var i = 0; i < calls.length; i++) request(calls[i].method, calls[i].params).then(calls[i].resolve, calls[i].reject);
182
184
  for (var j = 0; j < handlers.length; j++) handlers[j]();
183
- if (typeof ResizeObserver === "function") new ResizeObserver(reportSize).observe(document.documentElement);
185
+ if (typeof ResizeObserver === "function") new ResizeObserver(reportSize).observe(document.body);
184
186
  }
185
187
 
186
188
  function onHandshakeFailed(error) {
@@ -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