pith-ui 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/AI.md +67 -0
  2. package/API.md +3281 -0
  3. package/LICENSE +661 -0
  4. package/README.md +80 -2
  5. package/dist/composer.d.ts +38 -0
  6. package/dist/composer.d.ts.map +1 -0
  7. package/dist/composer.js +114 -0
  8. package/dist/composer.js.map +1 -0
  9. package/dist/content/conversation-reader.d.ts +19 -0
  10. package/dist/content/conversation-reader.d.ts.map +1 -0
  11. package/dist/content/conversation-reader.js +280 -0
  12. package/dist/content/conversation-reader.js.map +1 -0
  13. package/dist/content/conversation-view.d.ts +48 -0
  14. package/dist/content/conversation-view.d.ts.map +1 -0
  15. package/dist/content/conversation-view.js +107 -0
  16. package/dist/content/conversation-view.js.map +1 -0
  17. package/dist/content/image-viewer.d.ts +23 -0
  18. package/dist/content/image-viewer.d.ts.map +1 -0
  19. package/dist/content/image-viewer.js +101 -0
  20. package/dist/content/image-viewer.js.map +1 -0
  21. package/dist/content/markdown.d.ts +12 -0
  22. package/dist/content/markdown.d.ts.map +1 -0
  23. package/dist/content/markdown.js +68 -0
  24. package/dist/content/markdown.js.map +1 -0
  25. package/dist/content/paged-preview.d.ts +15 -0
  26. package/dist/content/paged-preview.d.ts.map +1 -0
  27. package/dist/content/paged-preview.js +105 -0
  28. package/dist/content/paged-preview.js.map +1 -0
  29. package/dist/content/views.d.ts +9 -0
  30. package/dist/content/views.d.ts.map +1 -0
  31. package/dist/content/views.js +53 -0
  32. package/dist/content/views.js.map +1 -0
  33. package/dist/content/welcome.d.ts +18 -0
  34. package/dist/content/welcome.d.ts.map +1 -0
  35. package/dist/content/welcome.js +45 -0
  36. package/dist/content/welcome.js.map +1 -0
  37. package/dist/core.d.ts +36 -0
  38. package/dist/core.d.ts.map +1 -0
  39. package/dist/core.js +44 -0
  40. package/dist/core.js.map +1 -0
  41. package/dist/dom.d.ts +14 -0
  42. package/dist/dom.d.ts.map +1 -0
  43. package/dist/dom.js +69 -0
  44. package/dist/dom.js.map +1 -0
  45. package/dist/files/panels.d.ts +95 -0
  46. package/dist/files/panels.d.ts.map +1 -0
  47. package/dist/files/panels.js +245 -0
  48. package/dist/files/panels.js.map +1 -0
  49. package/dist/files/systems.d.ts +91 -0
  50. package/dist/files/systems.d.ts.map +1 -0
  51. package/dist/files/systems.js +256 -0
  52. package/dist/files/systems.js.map +1 -0
  53. package/dist/forms/actions.d.ts +27 -0
  54. package/dist/forms/actions.d.ts.map +1 -0
  55. package/dist/forms/actions.js +19 -0
  56. package/dist/forms/actions.js.map +1 -0
  57. package/dist/forms/custom-connection.d.ts +61 -0
  58. package/dist/forms/custom-connection.d.ts.map +1 -0
  59. package/dist/forms/custom-connection.js +65 -0
  60. package/dist/forms/custom-connection.js.map +1 -0
  61. package/dist/forms/dialog-frame.d.ts +39 -0
  62. package/dist/forms/dialog-frame.d.ts.map +1 -0
  63. package/dist/forms/dialog-frame.js +75 -0
  64. package/dist/forms/dialog-frame.js.map +1 -0
  65. package/dist/forms/history.d.ts +16 -0
  66. package/dist/forms/history.d.ts.map +1 -0
  67. package/dist/forms/history.js +21 -0
  68. package/dist/forms/history.js.map +1 -0
  69. package/dist/forms/identity.d.ts +4 -0
  70. package/dist/forms/identity.d.ts.map +1 -0
  71. package/dist/forms/identity.js +21 -0
  72. package/dist/forms/identity.js.map +1 -0
  73. package/dist/forms/model-editor.d.ts +35 -0
  74. package/dist/forms/model-editor.d.ts.map +1 -0
  75. package/dist/forms/model-editor.js +78 -0
  76. package/dist/forms/model-editor.js.map +1 -0
  77. package/dist/forms/panels.d.ts +57 -0
  78. package/dist/forms/panels.d.ts.map +1 -0
  79. package/dist/forms/panels.js +224 -0
  80. package/dist/forms/panels.js.map +1 -0
  81. package/dist/forms/provider-login.d.ts +22 -0
  82. package/dist/forms/provider-login.d.ts.map +1 -0
  83. package/dist/forms/provider-login.js +114 -0
  84. package/dist/forms/provider-login.js.map +1 -0
  85. package/dist/forms/resource-editor.d.ts +23 -0
  86. package/dist/forms/resource-editor.d.ts.map +1 -0
  87. package/dist/forms/resource-editor.js +24 -0
  88. package/dist/forms/resource-editor.js.map +1 -0
  89. package/dist/index.d.ts +28 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +28 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/navigation/context-menu.d.ts +25 -0
  94. package/dist/navigation/context-menu.d.ts.map +1 -0
  95. package/dist/navigation/context-menu.js +67 -0
  96. package/dist/navigation/context-menu.js.map +1 -0
  97. package/dist/navigation/navigation.d.ts +57 -0
  98. package/dist/navigation/navigation.d.ts.map +1 -0
  99. package/dist/navigation/navigation.js +185 -0
  100. package/dist/navigation/navigation.js.map +1 -0
  101. package/dist/primitives.d.ts +307 -0
  102. package/dist/primitives.d.ts.map +1 -0
  103. package/dist/primitives.js +741 -0
  104. package/dist/primitives.js.map +1 -0
  105. package/dist/styles.css +849 -0
  106. package/dist/tasks/approval.d.ts +25 -0
  107. package/dist/tasks/approval.d.ts.map +1 -0
  108. package/dist/tasks/approval.js +61 -0
  109. package/dist/tasks/approval.js.map +1 -0
  110. package/dist/tasks/permission.d.ts +35 -0
  111. package/dist/tasks/permission.d.ts.map +1 -0
  112. package/dist/tasks/permission.js +67 -0
  113. package/dist/tasks/permission.js.map +1 -0
  114. package/dist/tasks/runtime.d.ts +31 -0
  115. package/dist/tasks/runtime.d.ts.map +1 -0
  116. package/dist/tasks/runtime.js +34 -0
  117. package/dist/tasks/runtime.js.map +1 -0
  118. package/dist/theme.d.ts +4 -0
  119. package/dist/theme.d.ts.map +1 -0
  120. package/dist/theme.js +6 -0
  121. package/dist/theme.js.map +1 -0
  122. package/dist/workspace.d.ts +38 -0
  123. package/dist/workspace.d.ts.map +1 -0
  124. package/dist/workspace.js +183 -0
  125. package/dist/workspace.js.map +1 -0
  126. package/package.json +27 -4
@@ -0,0 +1,75 @@
1
+ import { scopeIds } from './identity.js';
2
+ import { dialogHeading, escape, showDialogError, uniqueId } from '../dom.js';
3
+ export function createFeatureDialogFrame(options = {}) {
4
+ const dialog = options.dialog || document.createElement('dialog');
5
+ const content = options.content || document.createElement('div');
6
+ const dialogId = options.dialogId || uniqueId('pui-feature-dialog');
7
+ const titleId = options.titleId || `${dialogId}-title`;
8
+ const errorId = options.errorId || `${dialogId}-error`;
9
+ if (!options.dialog) {
10
+ dialog.id = dialogId;
11
+ dialog.className = 'pui-modal pui-feature-modal pui-feature-dialog';
12
+ dialog.setAttribute('aria-labelledby', titleId);
13
+ dialog.append(content);
14
+ }
15
+ let current = null;
16
+ let destroyed = false;
17
+ const clear = (keep) => { if (current !== keep)
18
+ current?.destroy(); current = null; content.replaceChildren(); content.onclick = null; };
19
+ const update = (state) => {
20
+ if (destroyed)
21
+ return;
22
+ const active = document.activeElement;
23
+ const restoreFocus = dialog.open && !!active && (content.contains(active) || active === dialog || active === document.body);
24
+ const activeId = restoreFocus ? active?.id : '';
25
+ clear(state.body instanceof Node ? undefined : state.body);
26
+ content.innerHTML = dialogHeading(state.title, titleId, dialogId, options.eyebrow || '') + `<p id="${escape(errorId)}" data-dialog-error class="pui-form-error" role="alert"></p>`;
27
+ const body = state.body instanceof Node ? state.body : state.body.element;
28
+ content.insertBefore(body, content.querySelector('[data-dialog-error]'));
29
+ if (!(state.body instanceof Node))
30
+ current = state.body;
31
+ if (restoreFocus) {
32
+ const previous = activeId ? Array.from(content.querySelectorAll('[id]')).find((node) => node.getAttribute('id') === activeId) : null;
33
+ const target = previous || content.querySelector('[data-close]');
34
+ target?.focus({ preventScroll: true });
35
+ }
36
+ };
37
+ const onClose = () => { if (!dialog.open)
38
+ clear(); };
39
+ const onClick = (event) => { const button = event.target.closest('[data-close]'); if (button?.dataset.close === dialogId && dialog.open)
40
+ dialog.close(); };
41
+ dialog.addEventListener('close', onClose);
42
+ dialog.addEventListener('click', onClick);
43
+ return { element: dialog, update, open(state) { update(state); if (!destroyed && !dialog.open)
44
+ dialog.showModal(); }, close() { if (dialog.open)
45
+ dialog.close(); }, fail(message) { showDialogError(content, message); }, destroy() { if (destroyed)
46
+ return; destroyed = true; dialog.removeEventListener('close', onClose); dialog.removeEventListener('click', onClick); clear(); if (!options.dialog)
47
+ dialog.remove(); } };
48
+ }
49
+ export function createFeatureStatus(state) {
50
+ const element = document.createElement('p');
51
+ const update = (state) => { element.textContent = state.message; element.className = state.error ? 'pui-form-error' : 'pui-feature-hint'; element.setAttribute('role', state.error ? 'alert' : 'status'); };
52
+ update(state);
53
+ return { element, update, destroy() { element.remove(); } };
54
+ }
55
+ export function createSDKDialogElements(options = {}) {
56
+ const dialog = document.createElement('dialog');
57
+ dialog.id = 'sdk-dialog';
58
+ dialog.className = 'pui-modal pui-feature-modal';
59
+ dialog.setAttribute('aria-labelledby', 'sdk-title');
60
+ const content = document.createElement('div');
61
+ content.id = 'sdk-content';
62
+ dialog.append(content);
63
+ const oauthDialog = document.createElement('dialog');
64
+ oauthDialog.id = 'oauth-dialog';
65
+ oauthDialog.className = 'pui-modal';
66
+ oauthDialog.setAttribute('aria-labelledby', 'oauth-title');
67
+ const oauthContent = document.createElement('div');
68
+ oauthContent.id = 'oauth-content';
69
+ oauthDialog.append(oauthContent);
70
+ const prefix = options.idPrefix ?? uniqueId('pui-sdk') + '-';
71
+ scopeIds(dialog, prefix);
72
+ scopeIds(oauthDialog, prefix);
73
+ return { dialog, content, oauthDialog, oauthContent, destroy() { dialog.remove(); oauthDialog.remove(); } };
74
+ }
75
+ //# sourceMappingURL=dialog-frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-frame.js","sourceRoot":"","sources":["../../src/forms/dialog-frame.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAK7E,MAAM,UAAU,wBAAwB,CAAC,UAAgC,EAAE;IACzE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAClE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,GAAG,QAAQ,QAAQ,CAAC;IACvD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,GAAG,QAAQ,QAAQ,CAAC;IACvD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QAAA,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAC;QAAC,MAAM,CAAC,SAAS,GAAG,gDAAgD,CAAC;QAAC,MAAM,CAAC,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;QAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAAA,CAAC;IAC1L,IAAI,OAAO,GAAyB,IAAI,CAAC;IAAC,IAAI,SAAS,GAAG,KAAK,CAAC;IAChE,MAAM,KAAK,GAAG,CAAC,IAAoB,EAAE,EAAE,GAAE,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA,CAAC,CAAC;IACvJ,MAAM,MAAM,GAAG,CAAC,KAAmC,EAAE,EAAE;QACrD,IAAI,SAAS;YAAE,OAAO;QACtB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC;QACtC,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5H,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,KAAK,CAAC,KAAK,CAAC,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3D,OAAO,CAAC,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,GAAG,UAAU,MAAM,CAAC,OAAO,CAAC,8DAA8D,CAAC;QACnL,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;QAC1E,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,YAAY,IAAI,CAAC;YAAE,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;QACxD,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAc,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAClJ,MAAM,MAAM,GAAG,QAAQ,IAAI,OAAO,CAAC,aAAa,CAAc,cAAc,CAAC,CAAC;YAC9E,MAAM,EAAE,KAAK,CAAC,EAAC,aAAa,EAAE,IAAI,EAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,GAAG,EAAE,GAAE,IAAI,CAAC,MAAM,CAAC,IAAI;QAAE,KAAK,EAAE,CAAC,CAAA,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,CAAC,KAAY,EAAE,EAAE,GAAE,MAAM,MAAM,GAAI,KAAK,CAAC,MAAsB,CAAC,OAAO,CAAc,cAAc,CAAC,CAAC,CAAC,IAAI,MAAM,EAAE,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI;QAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA,CAAC,CAAC;IAC9L,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACrF,OAAO,EAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,IAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA,CAAC,EAAE,KAAK,KAAI,IAAI,MAAM,CAAC,IAAI;YAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA,CAAC,EAAE,IAAI,CAAC,OAAO,IAAG,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA,CAAC,EAAE,OAAO,KAAI,IAAI,SAAS;YAAE,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA,CAAC,EAAC,CAAC;AACtZ,CAAC;AACD,MAAM,UAAU,mBAAmB,CAAC,KAAyC;IAC3E,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,CAAC,KAAyC,EAAE,EAAE,GAAE,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA,CAAC,CAAC;IAC9O,MAAM,CAAC,KAAK,CAAC,CAAC;IAAC,OAAO,EAAC,OAAO,EAAE,MAAM,EAAE,OAAO,KAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA,CAAC,EAAC,CAAC;AACzE,CAAC;AACD,MAAM,UAAU,uBAAuB,CAAC,UAA+B,EAAE;IACvE,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,YAAY,CAAC;IAAC,MAAM,CAAC,SAAS,GAAG,6BAA6B,CAAC;IAAC,MAAM,CAAC,YAAY,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;IACjL,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,GAAG,aAAa,CAAC;IAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClG,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAAC,WAAW,CAAC,EAAE,GAAG,cAAc,CAAC;IAAC,WAAW,CAAC,SAAS,GAAG,WAAW,CAAC;IAAC,WAAW,CAAC,YAAY,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;IACvL,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAAC,YAAY,CAAC,EAAE,GAAG,eAAe,CAAC;IAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACxH,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACtH,OAAO,EAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,KAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAA,CAAC,EAAC,CAAC;AAC1G,CAAC","sourcesContent":["import {scopeIds} from './identity.js';\nimport type { UIBlock } from '../core.js';\nimport { dialogHeading, escape, showDialogError, uniqueId } from '../dom.js';\n\nexport interface DialogContent {element: HTMLElement; destroy(): void}\nexport interface FeatureDialogState {title: string; body: Node | DialogContent}\nexport interface FeatureDialogOptions {dialog?: HTMLDialogElement; content?: HTMLElement; dialogId?: string; titleId?: string; errorId?: string; eyebrow?: string}\nexport function createFeatureDialogFrame(options: FeatureDialogOptions = {}): UIBlock<FeatureDialogState> & {open(state: FeatureDialogState): void; close(): void; fail(message: string): void} {\n const dialog = options.dialog || document.createElement('dialog');\n const content = options.content || document.createElement('div');\n const dialogId = options.dialogId || uniqueId('pui-feature-dialog');\n const titleId = options.titleId || `${dialogId}-title`;\n const errorId = options.errorId || `${dialogId}-error`;\n if (!options.dialog) {dialog.id = dialogId; dialog.className = 'pui-modal pui-feature-modal pui-feature-dialog'; dialog.setAttribute('aria-labelledby', titleId); dialog.append(content);}\n let current: DialogContent | null = null; let destroyed = false;\n const clear = (keep?: DialogContent) => {if (current !== keep) current?.destroy(); current = null; content.replaceChildren(); content.onclick = null;};\n const update = (state: Readonly<FeatureDialogState>) => {\n if (destroyed) return;\n const active = document.activeElement;\n const restoreFocus = dialog.open && !!active && (content.contains(active) || active === dialog || active === document.body);\n const activeId = restoreFocus ? active?.id : '';\n clear(state.body instanceof Node ? undefined : state.body);\n content.innerHTML = dialogHeading(state.title, titleId, dialogId, options.eyebrow || '') + `<p id=\"${escape(errorId)}\" data-dialog-error class=\"pui-form-error\" role=\"alert\"></p>`;\n const body = state.body instanceof Node ? state.body : state.body.element;\n content.insertBefore(body, content.querySelector('[data-dialog-error]'));\n if (!(state.body instanceof Node)) current = state.body;\n if (restoreFocus) {\n const previous = activeId ? Array.from(content.querySelectorAll<HTMLElement>('[id]')).find((node) => node.getAttribute('id') === activeId) : null;\n const target = previous || content.querySelector<HTMLElement>('[data-close]');\n target?.focus({preventScroll: true});\n }\n };\n const onClose = () => {if (!dialog.open) clear();};\n const onClick = (event: Event) => {const button = (event.target as HTMLElement).closest<HTMLElement>('[data-close]'); if (button?.dataset.close === dialogId && dialog.open) dialog.close();};\n dialog.addEventListener('close', onClose); dialog.addEventListener('click', onClick);\n return {element: dialog, update, open(state) {update(state); if (!destroyed && !dialog.open) dialog.showModal();}, close() {if (dialog.open) dialog.close();}, fail(message) {showDialogError(content, message);}, destroy() {if (destroyed) return; destroyed = true; dialog.removeEventListener('close', onClose); dialog.removeEventListener('click', onClick); clear(); if (!options.dialog) dialog.remove();}};\n}\nexport function createFeatureStatus(state: {message: string; error?: boolean}): UIBlock<{message: string; error?: boolean}> {\n const element = document.createElement('p');\n const update = (state: {message: string; error?: boolean}) => {element.textContent = state.message; element.className = state.error ? 'pui-form-error' : 'pui-feature-hint'; element.setAttribute('role', state.error ? 'alert' : 'status');};\n update(state); return {element, update, destroy() {element.remove();}};\n}\nexport function createSDKDialogElements(options: {idPrefix?: string} = {}): {dialog: HTMLDialogElement; content: HTMLElement; oauthDialog: HTMLDialogElement; oauthContent: HTMLElement; destroy(): void} {\n const dialog = document.createElement('dialog'); dialog.id = 'sdk-dialog'; dialog.className = 'pui-modal pui-feature-modal'; dialog.setAttribute('aria-labelledby', 'sdk-title');\n const content = document.createElement('div'); content.id = 'sdk-content'; dialog.append(content);\n const oauthDialog = document.createElement('dialog'); oauthDialog.id = 'oauth-dialog'; oauthDialog.className = 'pui-modal'; oauthDialog.setAttribute('aria-labelledby', 'oauth-title');\n const oauthContent = document.createElement('div'); oauthContent.id = 'oauth-content'; oauthDialog.append(oauthContent);\n const prefix = options.idPrefix ?? uniqueId('pui-sdk') + '-'; scopeIds(dialog, prefix); scopeIds(oauthDialog, prefix);\n return {dialog, content, oauthDialog, oauthContent, destroy() {dialog.remove(); oauthDialog.remove();}};\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import type { UIBlock } from '../core.js';
2
+ export interface BranchHistoryNode {
3
+ id: string;
4
+ role: string;
5
+ text: string;
6
+ active: boolean;
7
+ }
8
+ export interface BranchHistoryState {
9
+ nodes: readonly BranchHistoryNode[] | null;
10
+ error?: string;
11
+ loading?: boolean;
12
+ }
13
+ export declare function createBranchHistory(state: BranchHistoryState, options?: {
14
+ onContinue?: (id: string) => void | Promise<void>;
15
+ }): UIBlock<BranchHistoryState>;
16
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/forms/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,iBAAiB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC;AAC5F,MAAM,WAAW,kBAAkB;IAAE,KAAK,EAAE,SAAS,iBAAiB,EAAE,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAC;AACnH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,EAAE,OAAO,GAAE;IAAC,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAK7J"}
@@ -0,0 +1,21 @@
1
+ import { escape } from '../dom.js';
2
+ export function createBranchHistory(state, options = {}) {
3
+ const element = document.createElement('div');
4
+ element.className = 'pui-branch-history';
5
+ const abort = new AbortController();
6
+ let destroyed = false;
7
+ const update = (state) => { if (destroyed)
8
+ return; if (state.loading) {
9
+ element.textContent = 'Loading history…';
10
+ return;
11
+ } if (state.error) {
12
+ element.textContent = state.error;
13
+ return;
14
+ } element.innerHTML = `<p class="pui-modal-description">Continue from any saved message. Other branches remain available here; files and external actions are not undone.</p><div class="pui-branch-list">${(state.nodes || []).map((node) => `<article class="pui-branch-node ${node.active ? 'pui-current-branch' : ''}"><div class="pui-connection-card-heading"><strong>${escape(node.role)}${node.active ? ' · current branch' : ''}</strong><button class="pui-secondary-button" data-branch="${escape(node.id)}">Continue here</button></div><p>${escape(node.text.slice(0, 360) || '(Image or empty reply)')}</p></article>`).join('') || '<p>No history yet.</p>'}</div>`; };
15
+ element.addEventListener('click', (event) => { const target = event.target.closest('[data-branch]'); if (target && options.onContinue)
16
+ void options.onContinue(target.dataset.branch); }, { signal: abort.signal });
17
+ update(state);
18
+ return { element, update, destroy() { if (destroyed)
19
+ return; destroyed = true; abort.abort(); element.remove(); } };
20
+ }
21
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/forms/history.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGnC,MAAM,UAAU,mBAAmB,CAAC,KAAyB,EAAE,UAA+D,EAAE;IAC/H,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAAC,OAAO,CAAC,SAAS,GAAG,oBAAoB,CAAC;IAAC,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;IAAC,IAAI,SAAS,GAAG,KAAK,CAAC;IACpJ,MAAM,MAAM,GAAG,CAAC,KAAmC,EAAE,EAAE,GAAE,IAAI,SAAS;QAAE,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAAA,OAAO,CAAC,WAAW,GAAG,kBAAkB,CAAC;QAAC,OAAO;IAAA,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAAA,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC;QAAC,OAAO;IAAA,CAAC,CAAC,OAAO,CAAC,SAAS,GAAG,sLAAsL,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,mCAAmC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,sDAAsD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,8DAA8D,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,oCAAoC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,wBAAwB,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,wBAAwB,QAAQ,CAAC,CAAA,CAAC,CAAC;IACx2B,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,GAAE,MAAM,MAAM,GAAI,KAAK,CAAC,MAAsB,CAAC,OAAO,CAAoB,eAAe,CAAC,CAAC,CAAC,IAAI,MAAM,IAAI,OAAO,CAAC,UAAU;QAAE,KAAK,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,MAAO,CAAC,CAAC,CAAA,CAAC,EAAE,EAAC,MAAM,EAAE,KAAK,CAAC,MAAM,EAAC,CAAC,CAAC;IACrP,MAAM,CAAC,KAAK,CAAC,CAAC;IAAC,OAAO,EAAC,OAAO,EAAE,MAAM,EAAE,OAAO,KAAI,IAAI,SAAS;YAAE,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA,CAAC,EAAC,CAAC;AAChI,CAAC","sourcesContent":["import type { UIBlock } from '../core.js';\nimport { escape } from '../dom.js';\nexport interface BranchHistoryNode {id: string; role: string; text: string; active: boolean}\nexport interface BranchHistoryState {nodes: readonly BranchHistoryNode[] | null; error?: string; loading?: boolean}\nexport function createBranchHistory(state: BranchHistoryState, options: {onContinue?: (id: string) => void | Promise<void>} = {}): UIBlock<BranchHistoryState> {\n const element = document.createElement('div'); element.className = 'pui-branch-history'; const abort = new AbortController(); let destroyed = false;\n const update = (state: Readonly<BranchHistoryState>) => {if (destroyed) return; if (state.loading) {element.textContent = 'Loading history…'; return;} if (state.error) {element.textContent = state.error; return;} element.innerHTML = `<p class=\"pui-modal-description\">Continue from any saved message. Other branches remain available here; files and external actions are not undone.</p><div class=\"pui-branch-list\">${(state.nodes || []).map((node) => `<article class=\"pui-branch-node ${node.active ? 'pui-current-branch' : ''}\"><div class=\"pui-connection-card-heading\"><strong>${escape(node.role)}${node.active ? ' · current branch' : ''}</strong><button class=\"pui-secondary-button\" data-branch=\"${escape(node.id)}\">Continue here</button></div><p>${escape(node.text.slice(0, 360) || '(Image or empty reply)')}</p></article>`).join('') || '<p>No history yet.</p>'}</div>`;};\n element.addEventListener('click', (event) => {const target = (event.target as HTMLElement).closest<HTMLButtonElement>('[data-branch]'); if (target && options.onContinue) void options.onContinue(target.dataset.branch!);}, {signal: abort.signal});\n update(state); return {element, update, destroy() {if (destroyed) return; destroyed = true; abort.abort(); element.remove();}};\n}\n"]}
@@ -0,0 +1,4 @@
1
+ /** Scope DOM IDs and their references without relying on document-level lookup. */
2
+ export declare function scopeIds(root: HTMLElement, prefix: string): void;
3
+ export declare function localField<T extends HTMLElement = HTMLElement>(root: HTMLElement, id: string): T;
4
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/forms/identity.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAQhE;AACD,wBAAgB,UAAU,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,CAIhG"}
@@ -0,0 +1,21 @@
1
+ /** Scope DOM IDs and their references without relying on document-level lookup. */
2
+ export function scopeIds(root, prefix) {
3
+ for (const control of root.querySelectorAll('input:not([type="checkbox"]):not([type="file"]), textarea, select'))
4
+ control.classList.add('pui-control');
5
+ if (!prefix)
6
+ return;
7
+ const attributes = ['id', 'for', 'aria-labelledby', 'aria-describedby', 'aria-controls', 'data-close'];
8
+ for (const node of [root, ...root.querySelectorAll('*')])
9
+ for (const attribute of attributes) {
10
+ const value = node.getAttribute(attribute);
11
+ if (value)
12
+ node.setAttribute(attribute, value.split(' ').map(id => prefix + id).join(' '));
13
+ }
14
+ }
15
+ export function localField(root, id) {
16
+ const found = [...root.querySelectorAll('[id]')].find(node => node.getAttribute('id') === id);
17
+ if (!found)
18
+ throw new Error(`Unknown component field: ${id}`);
19
+ return found;
20
+ }
21
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/forms/identity.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,MAAM,UAAU,QAAQ,CAAC,IAAiB,EAAE,MAAc;IACxD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,gBAAgB,CAAc,mEAAmE,CAAC;QAAE,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACpK,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC;IACvG,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAc,GAAG,CAAC,CAAC;QAAE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YAC1G,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAC3C,IAAI,KAAK;gBAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7F,CAAC;AACH,CAAC;AACD,MAAM,UAAU,UAAU,CAAsC,IAAiB,EAAE,EAAU;IAC3F,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAc,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC3G,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,EAAE,EAAE,CAAC,CAAC;IAC9D,OAAO,KAAU,CAAC;AACpB,CAAC","sourcesContent":["/** Scope DOM IDs and their references without relying on document-level lookup. */\nexport function scopeIds(root: HTMLElement, prefix: string): void {\n for (const control of root.querySelectorAll<HTMLElement>('input:not([type=\"checkbox\"]):not([type=\"file\"]), textarea, select')) control.classList.add('pui-control');\n if (!prefix) return;\n const attributes = ['id', 'for', 'aria-labelledby', 'aria-describedby', 'aria-controls', 'data-close'];\n for (const node of [root, ...root.querySelectorAll<HTMLElement>('*')]) for (const attribute of attributes) {\n const value = node.getAttribute(attribute);\n if (value) node.setAttribute(attribute, value.split(' ').map(id => prefix + id).join(' '));\n }\n}\nexport function localField<T extends HTMLElement = HTMLElement>(root: HTMLElement, id: string): T {\n const found = [...root.querySelectorAll<HTMLElement>('[id]')].find(node => node.getAttribute('id') === id);\n if (!found) throw new Error(`Unknown component field: ${id}`);\n return found as T;\n}\n"]}
@@ -0,0 +1,35 @@
1
+ import type { UIBlock } from '../core.js';
2
+ export interface ModelProviderOption {
3
+ id: string;
4
+ name: string;
5
+ model?: string;
6
+ thinkingLevel?: string;
7
+ }
8
+ export interface ModelOption {
9
+ id: string;
10
+ name: string;
11
+ provider: string;
12
+ thinkingLevels?: readonly string[] | null;
13
+ supportsImages: boolean;
14
+ contextWindow: number;
15
+ maxTokens: number;
16
+ }
17
+ export interface ModelEditorState {
18
+ providers: readonly ModelProviderOption[] | null;
19
+ models: readonly ModelOption[] | null;
20
+ selection: ModelSelection;
21
+ }
22
+ export interface ModelSelection {
23
+ provider: string;
24
+ model: string;
25
+ thinkingLevel: string;
26
+ }
27
+ export declare function thinkingLabel(level: string): string;
28
+ export declare function createModelEditor(initial: ModelEditorState, options?: {
29
+ prefix?: string;
30
+ element?: HTMLElement;
31
+ onChange?: (selection: ModelSelection) => void;
32
+ }): UIBlock<ModelEditorState> & {
33
+ read(): ModelSelection;
34
+ };
35
+ //# sourceMappingURL=model-editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-editor.d.ts","sourceRoot":"","sources":["../../src/forms/model-editor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,MAAM,WAAW,mBAAmB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAC;AACvG,MAAM,WAAW,WAAW;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAAC,cAAc,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC;AACvL,MAAM,WAAW,gBAAgB;IAAE,SAAS,EAAE,SAAS,mBAAmB,EAAE,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAC;AACtJ,MAAM,WAAW,cAAc;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAC;AACxF,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAuG;AAC3J,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,GAAE;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAA;CAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,GAAG;IAAC,IAAI,IAAI,cAAc,CAAA;CAAC,CA2DzN"}
@@ -0,0 +1,78 @@
1
+ import { escape, uniqueId } from '../dom.js';
2
+ import { modelEditorMarkup } from './panels.js';
3
+ export function thinkingLabel(level) { return level === 'off' ? 'Thinking off' : `Thinking: ${level === 'xhigh' ? 'extra high' : level}`; }
4
+ export function createModelEditor(initial, options = {}) {
5
+ const prefix = options.prefix || uniqueId('pui-model');
6
+ const element = options.element || document.createElement('div');
7
+ if (!options.element) {
8
+ element.className = 'pui-model-editor';
9
+ element.innerHTML = modelEditorMarkup(prefix);
10
+ }
11
+ const $ = (id) => { const field = Array.from(element.querySelectorAll('[id]')).find((node) => node.getAttribute('id') === id); if (!field)
12
+ throw new Error(`Unknown model field: ${id}`); return field; };
13
+ let binding = new AbortController();
14
+ let destroyed = false;
15
+ let signature = '';
16
+ const read = () => ({ provider: $(`${prefix}-provider`).value, model: $(`${prefix}-model`).value, thinkingLevel: $(`${prefix}-thinking`).value });
17
+ const update = (state) => {
18
+ if (destroyed)
19
+ return;
20
+ const next = JSON.stringify(state);
21
+ if (next === signature)
22
+ return;
23
+ signature = next;
24
+ binding.abort();
25
+ binding = new AbortController();
26
+ const catalog = state;
27
+ const selection = state.selection;
28
+ const providers = catalog.providers || [];
29
+ const providerSelect = $(`${prefix}-provider`);
30
+ const modelSelect = $(`${prefix}-model`);
31
+ const search = $(`${prefix}-search`);
32
+ const effort = $(`${prefix}-thinking`);
33
+ providerSelect.innerHTML = providers.map((entry) => `<option value="${escape(entry.id)}">${escape(entry.name)}</option>`).join('');
34
+ providerSelect.disabled = providers.length === 0;
35
+ providerSelect.value = providers.some((entry) => entry.id === selection.provider) ? selection.provider : providers[0]?.id || '';
36
+ let selected = '';
37
+ const capabilities = () => {
38
+ selected = modelSelect.value;
39
+ const model = (catalog.models || []).find((entry) => entry.provider === providerSelect.value && entry.id === selected);
40
+ const previous = effort.value;
41
+ const levels = model?.thinkingLevels || ['off'];
42
+ effort.innerHTML = levels.map((level) => `<option value="${escape(level)}">${escape(thinkingLabel(level))}</option>`).join('');
43
+ effort.value = levels.includes(previous) ? previous : levels.includes('high') ? 'high' : levels.includes('medium') ? 'medium' : levels[0];
44
+ effort.disabled = levels.length < 2;
45
+ effort.hidden = levels.length < 2;
46
+ $(`${prefix}-thinking-label`).hidden = levels.length < 2;
47
+ $(`${prefix}-capabilities`).textContent = model ? `${model.supportsImages ? 'Text + images' : 'Text only'} · ${new Intl.NumberFormat('en').format(model.contextWindow)} context tokens · ${new Intl.NumberFormat('en').format(model.maxTokens)} max output tokens` : 'No matching models.';
48
+ };
49
+ const renderModels = () => {
50
+ const query = search.value.trim().toLowerCase();
51
+ const models = (catalog.models || []).filter((entry) => entry.provider === providerSelect.value && (entry.id === selected || `${entry.name} ${entry.id}`.toLowerCase().includes(query)));
52
+ modelSelect.innerHTML = models.map((entry) => `<option value="${escape(entry.id)}">${escape(entry.name)} — ${escape(entry.id)}</option>`).join('');
53
+ modelSelect.disabled = models.length === 0;
54
+ modelSelect.value = models.some((entry) => entry.id === selected) ? selected : models[0]?.id || '';
55
+ capabilities();
56
+ };
57
+ const chooseProvider = () => {
58
+ const provider = providers.find((entry) => entry.id === providerSelect.value);
59
+ if (!provider)
60
+ return;
61
+ search.value = '';
62
+ selected = provider.model || (provider.id === selection.provider ? selection.model : '');
63
+ effort.innerHTML = `<option value="${escape(provider.thinkingLevel || selection.thinkingLevel || 'high')}"></option>`;
64
+ renderModels();
65
+ };
66
+ providerSelect.addEventListener('change', chooseProvider, { signal: binding.signal });
67
+ modelSelect.addEventListener('change', capabilities, { signal: binding.signal });
68
+ search.addEventListener('input', renderModels, { signal: binding.signal });
69
+ chooseProvider();
70
+ if (options.onChange)
71
+ element.addEventListener('change', () => options.onChange(read()), { signal: binding.signal });
72
+ };
73
+ update(initial);
74
+ return { element, update, read, destroy() { if (destroyed)
75
+ return; destroyed = true; binding.abort(); if (!options.element)
76
+ element.remove(); } };
77
+ }
78
+ //# sourceMappingURL=model-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-editor.js","sourceRoot":"","sources":["../../src/forms/model-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import type { UIBlock } from '../core.js';\nimport { escape, uniqueId } from '../dom.js';\nimport { modelEditorMarkup } from './panels.js';\nexport interface ModelProviderOption {id: string; name: string; model?: string; thinkingLevel?: string}\nexport interface ModelOption {id: string; name: string; provider: string; thinkingLevels?: readonly string[] | null; supportsImages: boolean; contextWindow: number; maxTokens: number}\nexport interface ModelEditorState {providers: readonly ModelProviderOption[] | null; models: readonly ModelOption[] | null; selection: ModelSelection}\nexport interface ModelSelection {provider: string; model: string; thinkingLevel: string}\nexport function thinkingLabel(level: string): string { return level === 'off' ? 'Thinking off' : `Thinking: ${level === 'xhigh' ? 'extra high' : level}`; }\nexport function createModelEditor(initial: ModelEditorState, options: {prefix?: string; element?: HTMLElement; onChange?: (selection: ModelSelection) => void} = {}): UIBlock<ModelEditorState> & {read(): ModelSelection} {\n const prefix = options.prefix || uniqueId('pui-model');\n const element = options.element || document.createElement('div');\n if (!options.element) {element.className = 'pui-model-editor'; element.innerHTML = modelEditorMarkup(prefix);}\n const $ = <T extends HTMLElement = HTMLElement>(id: string) => {const field = Array.from(element.querySelectorAll<HTMLElement>('[id]')).find((node) => node.getAttribute('id') === id); if (!field) throw new Error(`Unknown model field: ${id}`); return field as T;};\n let binding = new AbortController(); let destroyed = false; let signature = '';\n const read = (): ModelSelection => ({provider: $<HTMLSelectElement>(`${prefix}-provider`).value, model: $<HTMLSelectElement>(`${prefix}-model`).value, thinkingLevel: $<HTMLSelectElement>(`${prefix}-thinking`).value});\n const update = (state: Readonly<ModelEditorState>) => {\n if (destroyed) return;\n const next = JSON.stringify(state); if (next === signature) return; signature = next;\n binding.abort(); binding = new AbortController();\n const catalog = state; const selection = state.selection;\n const providers = catalog.providers || [];\n const providerSelect = $<HTMLSelectElement>(`${prefix}-provider`);\n const modelSelect = $<HTMLSelectElement>(`${prefix}-model`);\n const search = $<HTMLInputElement>(`${prefix}-search`);\n const effort = $<HTMLSelectElement>(`${prefix}-thinking`);\n providerSelect.innerHTML = providers.map((entry) => `<option value=\"${escape(entry.id)}\">${escape(entry.name)}</option>`).join('');\n providerSelect.disabled = providers.length === 0;\n providerSelect.value = providers.some((entry) => entry.id === selection.provider) ? selection.provider! : providers[0]?.id || '';\n let selected = '';\n const capabilities = () => {\n selected = modelSelect.value;\n const model = (catalog.models || []).find((entry) => entry.provider === providerSelect.value && entry.id === selected);\n const previous = effort.value;\n const levels = model?.thinkingLevels || ['off'];\n effort.innerHTML = levels.map((level) => `<option value=\"${escape(level)}\">${escape(thinkingLabel(level))}</option>`).join('');\n effort.value = levels.includes(previous) ? previous : levels.includes('high') ? 'high' : levels.includes('medium') ? 'medium' : levels[0];\n effort.disabled = levels.length < 2;\n effort.hidden = levels.length < 2;\n $(`${prefix}-thinking-label`).hidden = levels.length < 2;\n $(`${prefix}-capabilities`).textContent = model ? `${model.supportsImages ? 'Text + images' : 'Text only'} · ${new Intl.NumberFormat('en').format(model.contextWindow)} context tokens · ${new Intl.NumberFormat('en').format(model.maxTokens)} max output tokens` : 'No matching models.';\n };\n const renderModels = () => {\n const query = search.value.trim().toLowerCase();\n const models = (catalog.models || []).filter((entry) => entry.provider === providerSelect.value && (entry.id === selected || `${entry.name} ${entry.id}`.toLowerCase().includes(query)));\n modelSelect.innerHTML = models.map((entry) => `<option value=\"${escape(entry.id)}\">${escape(entry.name)} — ${escape(entry.id)}</option>`).join('');\n modelSelect.disabled = models.length === 0;\n modelSelect.value = models.some((entry) => entry.id === selected) ? selected : models[0]?.id || '';\n capabilities();\n };\n const chooseProvider = () => {\n const provider = providers.find((entry) => entry.id === providerSelect.value);\n if (!provider)\n return;\n search.value = '';\n selected = provider.model || (provider.id === selection.provider ? selection.model : '');\n effort.innerHTML = `<option value=\"${escape(provider.thinkingLevel || selection.thinkingLevel || 'high')}\"></option>`;\n renderModels();\n };\n providerSelect.addEventListener('change', chooseProvider, {signal: binding.signal});\n modelSelect.addEventListener('change', capabilities, {signal: binding.signal});\n search.addEventListener('input', renderModels, {signal: binding.signal});\n chooseProvider();\n\n if (options.onChange) element.addEventListener('change', () => options.onChange!(read()), {signal: binding.signal});\n };\n update(initial);\n return {element, update, read, destroy() {if (destroyed) return; destroyed = true; binding.abort(); if (!options.element) element.remove();}};\n}\n"]}
@@ -0,0 +1,57 @@
1
+ import type { UIBlock } from '../core.js';
2
+ export interface FormFeedback {
3
+ error?: string;
4
+ disabled?: boolean;
5
+ }
6
+ export interface FormDOMBlock<State extends FormFeedback> extends UIBlock<State> {
7
+ field<T extends HTMLElement = HTMLElement>(id: string): T;
8
+ id(localId: string): string;
9
+ }
10
+ export interface SettingsPanelState extends FormFeedback {
11
+ baseUrl: string;
12
+ hasApiKey: boolean;
13
+ }
14
+ export interface FormOptions {
15
+ idPrefix?: string;
16
+ }
17
+ export declare function createSettingsPanel(state: SettingsPanelState, options?: FormOptions): FormDOMBlock<SettingsPanelState>;
18
+ export interface MCPEditorValue {
19
+ name: string;
20
+ type: string;
21
+ url?: string;
22
+ oauth?: boolean;
23
+ oauthClientId?: string;
24
+ oauthScope?: string;
25
+ command?: string;
26
+ args?: readonly string[];
27
+ enabled?: boolean;
28
+ hasBearerToken?: boolean;
29
+ envKeys?: readonly string[];
30
+ }
31
+ export interface MCPConnectionsPanel extends FormDOMBlock<FormFeedback> {
32
+ renderType(): void;
33
+ edit(value?: MCPEditorValue): void;
34
+ }
35
+ export declare function createMCPConnectionsPanel(state?: FormFeedback, options?: FormOptions): MCPConnectionsPanel;
36
+ export declare function modelEditorMarkup(prefix: string): string;
37
+ export declare function createModelPicker(state?: FormFeedback, options?: FormOptions): FormDOMBlock<FormFeedback>;
38
+ export interface MCPConnectionItem {
39
+ name: string;
40
+ type: string;
41
+ url?: string;
42
+ command?: string;
43
+ args?: readonly string[];
44
+ enabled: boolean;
45
+ hasBearerToken?: boolean;
46
+ status?: string;
47
+ statusLabel: string;
48
+ envKeys?: readonly string[];
49
+ error?: string;
50
+ oauth?: boolean;
51
+ signedIn?: boolean;
52
+ }
53
+ export interface MCPConnectionListState extends FormFeedback {
54
+ entries: readonly MCPConnectionItem[];
55
+ }
56
+ export declare function createMCPConnectionList(initial: MCPConnectionListState): UIBlock<MCPConnectionListState>;
57
+ //# sourceMappingURL=panels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panels.d.ts","sourceRoot":"","sources":["../../src/forms/panels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1C,MAAM,WAAW,YAAY;IAAG,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE;AACpE,MAAM,WAAW,YAAY,CAAC,KAAK,SAAS,YAAY,CAAE,SAAQ,OAAO,CAAC,KAAK,CAAC;IAC9E,KAAK,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;IAC1D,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B;AA0BD,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE;AAChG,MAAM,WAAW,WAAW;IAAG,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE;AAClD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,EAAE,OAAO,GAAE,WAAgB,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAuD1H;AACD,MAAM,WAAW,cAAc;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAC;AAC9P,MAAM,WAAW,mBAAoB,SAAQ,YAAY,CAAC,YAAY,CAAC;IAAE,UAAU,IAAI,IAAI,CAAC;IAAC,IAAI,CAAC,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;CAAC;AAChI,wBAAgB,yBAAyB,CAAC,KAAK,GAAE,YAAiB,EAAE,OAAO,GAAE,WAAgB,GAAG,mBAAmB,CAwBlH;AACD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAshC;AAC/kC,wBAAgB,iBAAiB,CAAC,KAAK,GAAE,YAAiB,EAAE,OAAO,GAAE,WAAgB,GAAG,YAAY,CAAC,YAAY,CAAC,CAEjH;AACD,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IACvG,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACjJ;AACD,MAAM,WAAW,sBAAuB,SAAQ,YAAY;IAAG,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAAE;AAEtG,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAmCxG"}