pith-ui 0.0.0-stage → 0.1.1

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 (134) hide show
  1. package/AI.md +75 -0
  2. package/API.md +3688 -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 +123 -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 +65 -0
  14. package/dist/content/conversation-view.d.ts.map +1 -0
  15. package/dist/content/conversation-view.js +140 -0
  16. package/dist/content/conversation-view.js.map +1 -0
  17. package/dist/content/image-viewer.d.ts +25 -0
  18. package/dist/content/image-viewer.d.ts.map +1 -0
  19. package/dist/content/image-viewer.js +114 -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 +108 -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 +54 -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 +100 -0
  46. package/dist/files/panels.d.ts.map +1 -0
  47. package/dist/files/panels.js +286 -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 +273 -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 +39 -0
  56. package/dist/forms/actions.js.map +1 -0
  57. package/dist/forms/custom-connection.d.ts +62 -0
  58. package/dist/forms/custom-connection.d.ts.map +1 -0
  59. package/dist/forms/custom-connection.js +72 -0
  60. package/dist/forms/custom-connection.js.map +1 -0
  61. package/dist/forms/dialog-frame.d.ts +41 -0
  62. package/dist/forms/dialog-frame.d.ts.map +1 -0
  63. package/dist/forms/dialog-frame.js +95 -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 +16 -0
  70. package/dist/forms/identity.d.ts.map +1 -0
  71. package/dist/forms/identity.js +53 -0
  72. package/dist/forms/identity.js.map +1 -0
  73. package/dist/forms/model-editor.d.ts +40 -0
  74. package/dist/forms/model-editor.d.ts.map +1 -0
  75. package/dist/forms/model-editor.js +89 -0
  76. package/dist/forms/model-editor.js.map +1 -0
  77. package/dist/forms/panels.d.ts +146 -0
  78. package/dist/forms/panels.d.ts.map +1 -0
  79. package/dist/forms/panels.js +339 -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 +116 -0
  84. package/dist/forms/provider-login.js.map +1 -0
  85. package/dist/forms/resource-editor.d.ts +27 -0
  86. package/dist/forms/resource-editor.d.ts.map +1 -0
  87. package/dist/forms/resource-editor.js +34 -0
  88. package/dist/forms/resource-editor.js.map +1 -0
  89. package/dist/foundations.d.ts +95 -0
  90. package/dist/foundations.d.ts.map +1 -0
  91. package/dist/foundations.js +315 -0
  92. package/dist/foundations.js.map +1 -0
  93. package/dist/index.d.ts +28 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +28 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/navigation/context-menu.d.ts +26 -0
  98. package/dist/navigation/context-menu.d.ts.map +1 -0
  99. package/dist/navigation/context-menu.js +81 -0
  100. package/dist/navigation/context-menu.js.map +1 -0
  101. package/dist/navigation/navigation.d.ts +92 -0
  102. package/dist/navigation/navigation.d.ts.map +1 -0
  103. package/dist/navigation/navigation.js +368 -0
  104. package/dist/navigation/navigation.js.map +1 -0
  105. package/dist/primitives.d.ts +310 -0
  106. package/dist/primitives.d.ts.map +1 -0
  107. package/dist/primitives.js +633 -0
  108. package/dist/primitives.js.map +1 -0
  109. package/dist/styles.css +853 -0
  110. package/dist/surface.d.ts +29 -0
  111. package/dist/surface.d.ts.map +1 -0
  112. package/dist/surface.js +154 -0
  113. package/dist/surface.js.map +1 -0
  114. package/dist/tasks/approval.d.ts +25 -0
  115. package/dist/tasks/approval.d.ts.map +1 -0
  116. package/dist/tasks/approval.js +64 -0
  117. package/dist/tasks/approval.js.map +1 -0
  118. package/dist/tasks/permission.d.ts +37 -0
  119. package/dist/tasks/permission.d.ts.map +1 -0
  120. package/dist/tasks/permission.js +73 -0
  121. package/dist/tasks/permission.js.map +1 -0
  122. package/dist/tasks/runtime.d.ts +31 -0
  123. package/dist/tasks/runtime.d.ts.map +1 -0
  124. package/dist/tasks/runtime.js +34 -0
  125. package/dist/tasks/runtime.js.map +1 -0
  126. package/dist/theme.d.ts +4 -0
  127. package/dist/theme.d.ts.map +1 -0
  128. package/dist/theme.js +6 -0
  129. package/dist/theme.js.map +1 -0
  130. package/dist/workspace.d.ts +92 -0
  131. package/dist/workspace.d.ts.map +1 -0
  132. package/dist/workspace.js +288 -0
  133. package/dist/workspace.js.map +1 -0
  134. package/package.json +27 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-connection.js","sourceRoot":"","sources":["../../src/forms/custom-connection.ts"],"names":[],"mappings":"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","sourcesContent":["import {scopeIds,localField,bindFormSubmission} from './identity.js';\nimport type {ActionResult,UIBlock} from '../core.js';\nimport { escape, uniqueId } from '../dom.js';\nimport {adoptProductParts} from '../foundations.js';\nexport interface CustomModelValue {id: string; name?: string; contextWindow?: number; maxTokens?: number; reasoning?: boolean; input?: readonly string[]; cost?: {input: number; output: number; cacheRead: number; cacheWrite: number}}\nexport interface CustomConnectionState {name: string; baseUrl: string; api: string; editing: boolean; models: readonly CustomModelValue[]; error?: string; disabled?: boolean}\nexport interface CustomModelDraft {sourceIndex: number; id: string; name: string; contextWindow: number; maxTokens: number; reasoning: boolean; images: boolean; prices: {input: string; output: string; cacheRead: string; cacheWrite: string}}\nexport interface CustomConnectionDraft {name: string; baseUrl: string; api: string; apiKey: string; models: CustomModelDraft[]}\nconst protocols = ['openai-completions', 'openai-responses', 'anthropic-messages', 'google-generative-ai', 'mistral-conversations'];\nfunction modelRowMarkup(model: CustomModelValue, index: number): string {return `<fieldset class=\"pui-custom-model\" data-model-index=\"${index}\"><legend>Model ${index + 1}</legend><label>Model ID<input name=\"id\" required value=\"${escape(model.id)}\" /></label><label>Display name<input name=\"name\" value=\"${escape(model.name || '')}\" /></label><div class=\"pui-sdk-grid\"><label>Context tokens<input name=\"contextWindow\" type=\"number\" min=\"1\" required value=\"${escape(model.contextWindow)}\" /></label><label>Max output tokens<input name=\"maxTokens\" type=\"number\" min=\"1\" required value=\"${escape(model.maxTokens)}\" /></label></div><div class=\"pui-sdk-grid\"><label class=\"pui-checkbox-field\"><input name=\"reasoning\" type=\"checkbox\" ${model.reasoning ? 'checked' : ''} />Thinking effort</label><label class=\"pui-checkbox-field\"><input name=\"images\" type=\"checkbox\" ${model.input?.includes('image') ? 'checked' : ''} />Images</label></div><details class=\"pui-provider-advanced\"><summary>Price estimate (optional)</summary><div class=\"pui-sdk-grid\">${(['input', 'output', 'cacheRead', 'cacheWrite'] as const).map((rate) => `<label>${({ input: \"Input\", output: \"Output\", cacheRead: \"Cache read\", cacheWrite: \"Cache write\" } as Record<string, string>)[rate]}<input name=\"price-${rate}\" type=\"number\" min=\"0\" step=\"any\" value=\"${escape(model.cost?.[rate] ?? '')}\" /></label>`).join('')}</div></details><button type=\"button\" class=\"pui-secondary-button pui-destructive-button\" data-remove-model>Remove model</button></fieldset>`;}\nexport interface CustomModelRowState extends CustomModelValue {disabled?: boolean; error?: string}\nexport function createCustomModelRow(model: CustomModelRowState, index = 0): UIBlock<CustomModelRowState> & {read(): CustomModelDraft; reset(model: CustomModelValue): void} {\n const element = document.createElement('div'); element.className = 'pui-custom-model-row'; element.innerHTML = modelRowMarkup(model,index);\n const field = element.querySelector<HTMLFieldSetElement>('fieldset')!; const error = document.createElement('p'); error.className = 'pui-form-error'; error.setAttribute('role','alert'); element.append(error); const parts = adoptProductParts(element); let destroyed = false;\n const input = (name: string) => field.querySelector<HTMLInputElement>(`[name=\"${name}\"]`)!;\n const reset = (value: CustomModelValue) => {\n if (destroyed) return;\n parts.control(input('id')).reset(value.id); parts.control(input('name')).reset(value.name || '');\n parts.control(input('contextWindow')).reset(value.contextWindow === undefined ? '' : String(value.contextWindow)); parts.control(input('maxTokens')).reset(value.maxTokens === undefined ? '' : String(value.maxTokens));\n parts.control(input('reasoning')).reset(!!value.reasoning); parts.control(input('images')).reset(!!value.input?.includes('image'));\n for (const rate of ['input','output','cacheRead','cacheWrite'] as const) parts.control(input('price-'+rate)).reset(value.cost?.[rate] === undefined ? '' : String(value.cost[rate]));\n };\n const value = (name:string) => parts.control(input(name)).getValue();\n const read = (): CustomModelDraft => ({sourceIndex:index,id:value('id').trim(),name:value('name').trim(),contextWindow:Number(value('contextWindow')),maxTokens:Number(value('maxTokens')),reasoning:parts.control(input('reasoning')).getChecked(),images:parts.control(input('images')).getChecked(),prices:{input:value('price-input'),output:value('price-output'),cacheRead:value('price-cacheRead'),cacheWrite:value('price-cacheWrite')}});\n const update = (state: Readonly<CustomModelRowState>) => {if (destroyed) return; if (state.disabled !== undefined) field.disabled = state.disabled; if (state.error !== undefined) parts.feedback(error).update({message:state.error,tone:'error'});};\n update(model); return {element,read,reset,update,destroy() {if (destroyed) return; destroyed = true; parts.destroy(); element.remove();}};\n}\nexport function createCustomConnectionEditor(state: CustomConnectionState, options: {idPrefix?: string; onSubmit?: (draft: CustomConnectionDraft) => ActionResult | Promise<ActionResult>} = {}): UIBlock<CustomConnectionState> & {read(): CustomConnectionDraft; readonly form: HTMLFormElement} {\n const element = document.createElement('div'); element.className = 'pui-custom-connection-editor'; element.innerHTML = `<p class=\"pui-modal-description\">Give this endpoint its own name. It can coexist with official providers and other compatible endpoints.</p><form id=\"custom-form\"><label class=\"pui-field-label\">Connection name<input id=\"custom-name\" required value=\"${escape(state.name)}\" /></label><label class=\"pui-field-label\">API base URL<input id=\"custom-url\" type=\"url\" required value=\"${escape(state.baseUrl)}\" placeholder=\"https://example.com/v1\" /></label><label class=\"pui-field-label\">API protocol<select id=\"custom-api\" class=\"pui-feature-select\">${protocols.map((p) => `<option ${state.api === p ? 'selected' : ''}>${p}</option>`).join('')}</select></label><label class=\"pui-field-label\">API key<input id=\"custom-key\" type=\"password\" autocomplete=\"new-password\" placeholder=\"${state.editing ? 'Leave blank to keep the key at the same endpoint' : 'API key (optional for local endpoints)'}\" /></label><div id=\"custom-models\"></div><button type=\"button\" class=\"pui-secondary-button\" id=\"add-custom-model\">Add model</button><p class=\"pui-field-hint\">Limits and capabilities are provided by you. Prices are USD per million tokens. Fill all four rates (0 for free/unused), or leave all four blank for unknown prices.</p><p class=\"pui-form-error\" data-custom-error role=\"alert\"></p><div class=\"pui-modal-footer\"><button type=\"button\" class=\"pui-secondary-button\" data-close=\"sdk-dialog\">Cancel</button><button class=\"pui-primary-button\" type=\"submit\">Save connection</button></div></form>`;\n const prefix = options.idPrefix ?? uniqueId('pui-custom') + '-'; scopeIds(element, prefix);\n const $ = <T extends HTMLElement = HTMLElement>(id: string) => localField<T>(element, prefix + id);\n const form = $<HTMLFormElement>('custom-form'); const parts = adoptProductParts(element), rows = new Map<number, ReturnType<typeof createCustomModelRow>>(); let nextIndex = 0, destroyed = false, pending = false; const abort = new AbortController(); let current = state;\n const add = (model: CustomModelValue) => {const index = nextIndex++; const row = createCustomModelRow(model,index); rows.set(index,row); $('custom-models').append(row.element); if (current.disabled || pending) for (const button of row.element.querySelectorAll<HTMLButtonElement>('button')) button.disabled = true;};\n state.models.forEach(add);\n $('add-custom-model').addEventListener('click', () => {if (!current.disabled && !pending) add({id:'',contextWindow:128000,maxTokens:8192});}, {signal:abort.signal});\n $('custom-models').addEventListener('click', event => {const target = (event.target as HTMLElement).closest<HTMLButtonElement>('[data-remove-model]'); if (!target || target.disabled || current.disabled || pending) return; const index = Number(target.closest<HTMLElement>('[data-model-index]')?.dataset.modelIndex); rows.get(index)?.destroy(); rows.delete(index);}, {signal:abort.signal});\n const read = (): CustomConnectionDraft => ({name:parts.control($<HTMLInputElement>('custom-name')).getValue(),baseUrl:parts.control($<HTMLInputElement>('custom-url')).getValue(),api:parts.control($<HTMLSelectElement>('custom-api')).getValue(),apiKey:parts.control($<HTMLInputElement>('custom-key')).getValue(),models:[...rows.values()].map(row => row.read())});\n const update = (next: Readonly<CustomConnectionState>) => {if (destroyed) return; current = next; if (next.error !== undefined) parts.feedback(element.querySelector<HTMLElement>('[data-custom-error]')!).update({message:next.error,tone:'error'}); parts.update(); for (const button of form.querySelectorAll<HTMLButtonElement>('button')) parts.action(button).update({disabled:next.disabled,pending:button.hasAttribute('data-close') ? false : pending});};\n const submission = bindFormSubmission(form,{read,unavailable:()=>!!current.disabled,onSubmit:options.onSubmit,onPending(value) {pending = value; update(current);},onError(error) {update({...current,error});}});\n update(state);\n return {element,form,read,update,destroy() {if (destroyed) return; destroyed = true; submission.destroy(); abort.abort(); for (const row of rows.values()) row.destroy(); rows.clear(); for (const input of element.querySelectorAll<HTMLInputElement>('input[type=\"password\"]')) parts.control(input).reset(''); parts.destroy(); element.remove();}};\n}\n"]}
@@ -0,0 +1,41 @@
1
+ import type { UIBlock } from '../core.js';
2
+ export interface DialogContent {
3
+ element: HTMLElement;
4
+ destroy(): void;
5
+ }
6
+ export interface FeatureDialogState {
7
+ title: string;
8
+ body: Node | DialogContent;
9
+ }
10
+ export interface FeatureDialogOptions {
11
+ dialog?: HTMLDialogElement;
12
+ content?: HTMLElement;
13
+ dialogId?: string;
14
+ titleId?: string;
15
+ errorId?: string;
16
+ eyebrow?: string;
17
+ onClose?: () => void;
18
+ }
19
+ export declare function createFeatureDialogFrame(options?: FeatureDialogOptions): UIBlock<FeatureDialogState> & {
20
+ open(state: FeatureDialogState): void;
21
+ close(): void;
22
+ fail(message: string): void;
23
+ isOpen(): boolean;
24
+ };
25
+ export declare function createFeatureStatus(state: {
26
+ message: string;
27
+ error?: boolean;
28
+ }): UIBlock<{
29
+ message: string;
30
+ error?: boolean;
31
+ }>;
32
+ export declare function createSDKDialogElements(options?: {
33
+ idPrefix?: string;
34
+ }): {
35
+ dialog: HTMLDialogElement;
36
+ content: HTMLElement;
37
+ oauthDialog: HTMLDialogElement;
38
+ oauthContent: HTMLElement;
39
+ destroy(): void;
40
+ };
41
+ //# sourceMappingURL=dialog-frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-frame.d.ts","sourceRoot":"","sources":["../../src/forms/dialog-frame.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAK1C,MAAM,WAAW,aAAa;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,OAAO,IAAI,IAAI,CAAA;CAAC;AACtE,MAAM,WAAW,kBAAkB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,GAAG,aAAa,CAAA;CAAC;AAC/E,MAAM,WAAW,oBAAoB;IAAE,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAC;AACxL,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,kBAAkB,CAAC,GAAG;IAAC,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAAC,KAAK,IAAI,IAAI,CAAC;IAAC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,IAAI,OAAO,CAAA;CAAC,CA8CjN;AACD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAC,GAAG,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAC,CAAC,CAK1H;AACD,wBAAgB,uBAAuB,CAAC,OAAO,GAAE;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAM,GAAG;IAAC,MAAM,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,WAAW,CAAC;IAAC,WAAW,EAAE,iBAAiB,CAAC;IAAC,YAAY,EAAE,WAAW,CAAC;IAAC,OAAO,IAAI,IAAI,CAAA;CAAC,CAOxM"}
@@ -0,0 +1,95 @@
1
+ import { scopeIds } from './identity.js';
2
+ import { dialogHeading, uniqueId } from '../dom.js';
3
+ import { installDialogLifecycle } from '../surface.js';
4
+ import { adoptFeedback } from '../foundations.js';
5
+ export function createFeatureDialogFrame(options = {}) {
6
+ const dialog = options.dialog || document.createElement('dialog');
7
+ const content = options.content || document.createElement('div');
8
+ const dialogId = options.dialogId || dialog.id || uniqueId('pui-feature-dialog');
9
+ const titleId = options.titleId || `${dialogId}-title`;
10
+ const errorId = options.errorId || `${dialogId}-error`;
11
+ dialog.id = dialogId;
12
+ if (!options.dialog)
13
+ dialog.className = 'pui-modal pui-feature-modal pui-feature-dialog';
14
+ dialog.setAttribute('aria-labelledby', titleId);
15
+ if (!dialog.contains(content))
16
+ dialog.append(content);
17
+ const template = document.createElement('template');
18
+ template.innerHTML = dialogHeading('', titleId, dialogId, options.eyebrow || '');
19
+ const heading = template.content.firstElementChild;
20
+ const title = heading.querySelector('h2');
21
+ const close = heading.querySelector('[data-close]');
22
+ const error = document.createElement('p');
23
+ error.id = errorId;
24
+ error.dataset.dialogError = '';
25
+ error.className = 'pui-form-error';
26
+ error.setAttribute('role', 'alert');
27
+ const feedback = adoptFeedback(error, { presentation: 'inline', autoHide: false });
28
+ let current = null;
29
+ let currentBody = null;
30
+ let destroyed = false;
31
+ const clear = () => { current?.destroy(); current = null; currentBody = null; content.replaceChildren(); content.onclick = null; };
32
+ const lifecycle = installDialogLifecycle(dialog, { onClose() { clear(); options.onClose?.(); } });
33
+ const update = (state) => {
34
+ if (destroyed)
35
+ return;
36
+ const active = document.activeElement;
37
+ const restoreFocus = dialog.open && !!active && (content.contains(active) || active === dialog || active === document.body);
38
+ const activeId = restoreFocus ? active?.id : '';
39
+ const body = state.body instanceof Node ? state.body : state.body.element;
40
+ const next = state.body instanceof Node ? null : state.body;
41
+ const changed = body !== currentBody;
42
+ if (current !== next)
43
+ current?.destroy();
44
+ current = next;
45
+ if (changed) {
46
+ currentBody?.parentNode?.removeChild(currentBody);
47
+ currentBody = body;
48
+ content.replaceChildren(heading, body, error);
49
+ content.onclick = null;
50
+ }
51
+ else if (heading.parentNode !== content)
52
+ content.replaceChildren(heading, body, error);
53
+ title.textContent = state.title;
54
+ close.setAttribute('aria-label', `Close ${state.title.toLowerCase()}`);
55
+ feedback.update({ message: '', tone: 'error' });
56
+ if (restoreFocus && changed) {
57
+ const previous = activeId ? Array.from(content.querySelectorAll('[id]')).find((node) => node.getAttribute('id') === activeId) : null;
58
+ const target = previous || content.querySelector('[data-close]');
59
+ target?.focus({ preventScroll: true });
60
+ }
61
+ };
62
+ return { element: dialog, update, open(state) { update(state); if (!destroyed)
63
+ lifecycle.open(); }, close: lifecycle.close, isOpen: lifecycle.isOpen, fail(message) { if (!destroyed)
64
+ feedback.update({ message, tone: 'error' }); }, destroy() { if (destroyed)
65
+ return; destroyed = true; lifecycle.close(); lifecycle.destroy(); clear(); feedback.destroy(); if (!options.dialog)
66
+ dialog.remove(); } };
67
+ }
68
+ export function createFeatureStatus(state) {
69
+ const element = document.createElement('p');
70
+ const feedback = adoptFeedback(element, { presentation: 'inline', autoHide: false });
71
+ const update = (state) => { element.className = state.error ? 'pui-form-error' : 'pui-feature-hint'; feedback.update({ message: state.message, tone: state.error ? 'error' : 'info' }); };
72
+ update(state);
73
+ return { element, update, destroy() { feedback.destroy(); element.remove(); } };
74
+ }
75
+ export function createSDKDialogElements(options = {}) {
76
+ const dialog = document.createElement('dialog');
77
+ dialog.id = 'sdk-dialog';
78
+ dialog.className = 'pui-modal pui-feature-modal';
79
+ dialog.setAttribute('aria-labelledby', 'sdk-title');
80
+ const content = document.createElement('div');
81
+ content.id = 'sdk-content';
82
+ dialog.append(content);
83
+ const oauthDialog = document.createElement('dialog');
84
+ oauthDialog.id = 'oauth-dialog';
85
+ oauthDialog.className = 'pui-modal';
86
+ oauthDialog.setAttribute('aria-labelledby', 'oauth-title');
87
+ const oauthContent = document.createElement('div');
88
+ oauthContent.id = 'oauth-content';
89
+ oauthDialog.append(oauthContent);
90
+ const prefix = options.idPrefix ?? uniqueId('pui-sdk') + '-';
91
+ scopeIds(dialog, prefix);
92
+ scopeIds(oauthDialog, prefix);
93
+ return { dialog, content, oauthDialog, oauthContent, destroy() { dialog.remove(); oauthDialog.remove(); } };
94
+ }
95
+ //# sourceMappingURL=dialog-frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-frame.js","sourceRoot":"","sources":["../../src/forms/dialog-frame.ts"],"names":[],"mappings":"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","sourcesContent":["import {scopeIds} from './identity.js';\nimport type { UIBlock } from '../core.js';\nimport { dialogHeading, uniqueId } from '../dom.js';\nimport { installDialogLifecycle } from '../surface.js';\nimport { adoptFeedback } from '../foundations.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; onClose?: () => void}\nexport function createFeatureDialogFrame(options: FeatureDialogOptions = {}): UIBlock<FeatureDialogState> & {open(state: FeatureDialogState): void; close(): void; fail(message: string): void; isOpen(): boolean} {\n const dialog = options.dialog || document.createElement('dialog');\n const content = options.content || document.createElement('div');\n const dialogId = options.dialogId || dialog.id || uniqueId('pui-feature-dialog');\n const titleId = options.titleId || `${dialogId}-title`;\n const errorId = options.errorId || `${dialogId}-error`;\n dialog.id = dialogId;\n if (!options.dialog) dialog.className = 'pui-modal pui-feature-modal pui-feature-dialog';\n dialog.setAttribute('aria-labelledby', titleId);\n if (!dialog.contains(content)) dialog.append(content);\n const template = document.createElement('template');\n template.innerHTML = dialogHeading('', titleId, dialogId, options.eyebrow || '');\n const heading = template.content.firstElementChild as HTMLElement;\n const title = heading.querySelector('h2')!;\n const close = heading.querySelector<HTMLButtonElement>('[data-close]')!;\n const error = document.createElement('p'); error.id = errorId; error.dataset.dialogError = ''; error.className = 'pui-form-error'; error.setAttribute('role', 'alert');\n const feedback = adoptFeedback(error, {presentation: 'inline', autoHide: false});\n let current: DialogContent | null = null; let currentBody: Node | null = null; let destroyed = false;\n const clear = () => {current?.destroy(); current = null; currentBody = null; content.replaceChildren(); content.onclick = null;};\n const lifecycle = installDialogLifecycle(dialog, {onClose() { clear(); options.onClose?.(); }});\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 const body = state.body instanceof Node ? state.body : state.body.element;\n const next = state.body instanceof Node ? null : state.body;\n const changed = body !== currentBody;\n if (current !== next) current?.destroy();\n current = next;\n if (changed) {\n currentBody?.parentNode?.removeChild(currentBody);\n currentBody = body;\n content.replaceChildren(heading, body, error);\n content.onclick = null;\n } else if (heading.parentNode !== content) content.replaceChildren(heading, body, error);\n title.textContent = state.title;\n close.setAttribute('aria-label', `Close ${state.title.toLowerCase()}`);\n feedback.update({message: '', tone: 'error'});\n if (restoreFocus && changed) {\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 return {element: dialog, update, open(state) {update(state); if (!destroyed) lifecycle.open();}, close: lifecycle.close, isOpen: lifecycle.isOpen, fail(message) {if (!destroyed) feedback.update({message, tone: 'error'});}, destroy() {if (destroyed) return; destroyed = true; lifecycle.close(); lifecycle.destroy(); clear(); feedback.destroy(); 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 feedback = adoptFeedback(element, {presentation: 'inline', autoHide: false});\n const update = (state: {message: string; error?: boolean}) => {element.className = state.error ? 'pui-form-error' : 'pui-feature-hint'; feedback.update({message: state.message, tone: state.error ? 'error' : 'info'});};\n update(state); return {element, update, destroy() {feedback.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,16 @@
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
+ import { type ActionResult } from '../core.js';
5
+ /** Shared form lifetime; business writes and target identity remain with the caller. */
6
+ export declare function bindFormSubmission<Value>(form: HTMLFormElement, options: {
7
+ read: () => Value;
8
+ unavailable: () => boolean;
9
+ onSubmit?: (value: Value) => ActionResult | Promise<ActionResult>;
10
+ onPending: (pending: boolean) => void;
11
+ onError: (error: string) => void;
12
+ }): {
13
+ invalidate(): void;
14
+ destroy(): void;
15
+ };
16
+ //# 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;AACD,OAAO,EAAY,KAAK,YAAY,EAAC,MAAM,YAAY,CAAC;AAGxD,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAC,eAAe,EAAC,OAAO,EAAC;IACrE,IAAI,EAAC,MAAI,KAAK,CAAC;IACf,WAAW,EAAC,MAAI,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAC,KAAK,KAAG,YAAY,GAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7D,SAAS,EAAC,CAAC,OAAO,EAAC,OAAO,KAAG,IAAI,CAAC;IAClC,OAAO,EAAC,CAAC,KAAK,EAAC,MAAM,KAAG,IAAI,CAAC;CAC9B,GAAE;IAAC,UAAU,IAAG,IAAI,CAAC;IAAA,OAAO,IAAG,IAAI,CAAA;CAAC,CAUpC"}
@@ -0,0 +1,53 @@
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
+ import { Generation } from '../core.js';
22
+ /** Shared form lifetime; business writes and target identity remain with the caller. */
23
+ export function bindFormSubmission(form, options) {
24
+ const generation = new Generation(), abort = new AbortController();
25
+ let pending = false;
26
+ if (options.onSubmit)
27
+ form.addEventListener('submit', async (event) => {
28
+ event.preventDefault();
29
+ if (pending || options.unavailable() || !form.reportValidity())
30
+ return;
31
+ const sequence = generation.next();
32
+ pending = true;
33
+ options.onError('');
34
+ options.onPending(true);
35
+ try {
36
+ const result = await options.onSubmit(options.read());
37
+ if (generation.current(sequence) && !result.ok)
38
+ options.onError(result.error);
39
+ }
40
+ catch (error) {
41
+ if (generation.current(sequence))
42
+ options.onError(error instanceof Error ? error.message : String(error));
43
+ }
44
+ finally {
45
+ if (generation.current(sequence)) {
46
+ pending = false;
47
+ options.onPending(false);
48
+ }
49
+ }
50
+ }, { signal: abort.signal });
51
+ return { invalidate() { generation.invalidate(); pending = false; options.onPending(false); }, destroy() { generation.destroy(); abort.abort(); } };
52
+ }
53
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/forms/identity.ts"],"names":[],"mappings":"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","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}\nimport {Generation,type ActionResult} from '../core.js';\n\n\n/** Shared form lifetime; business writes and target identity remain with the caller. */\nexport function bindFormSubmission<Value>(form:HTMLFormElement,options:{\n read:()=>Value;\n unavailable:()=>boolean;\n onSubmit?: (value:Value)=>ActionResult|Promise<ActionResult>;\n onPending:(pending:boolean)=>void;\n onError:(error:string)=>void;\n}):{invalidate():void;destroy():void} {\n const generation = new Generation(),abort = new AbortController(); let pending = false;\n if (options.onSubmit) form.addEventListener('submit',async event=>{\n event.preventDefault(); if (pending || options.unavailable() || !form.reportValidity()) return;\n const sequence = generation.next(); pending = true; options.onError(''); options.onPending(true);\n try {const result = await options.onSubmit!(options.read()); if (generation.current(sequence) && !result.ok) options.onError(result.error);}\n catch (error) {if (generation.current(sequence)) options.onError(error instanceof Error ? error.message : String(error));}\n finally {if (generation.current(sequence)) {pending = false; options.onPending(false);}}\n },{signal:abort.signal});\n return {invalidate() {generation.invalidate(); pending = false; options.onPending(false);},destroy() {generation.destroy(); abort.abort();}};\n}\n"]}
@@ -0,0 +1,40 @@
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
+ disabled?: boolean;
22
+ }
23
+ export interface ModelSelection {
24
+ provider: string;
25
+ model: string;
26
+ thinkingLevel: string;
27
+ }
28
+ export interface ModelEditorBlock extends UIBlock<ModelEditorState> {
29
+ read(): ModelSelection;
30
+ reset(selection: ModelSelection): void;
31
+ focus(): void;
32
+ }
33
+ export declare function thinkingLabel(level: string): string;
34
+ export declare function modelEditorMarkup(prefix: string): string;
35
+ export declare function createModelEditor(initial: ModelEditorState, options?: {
36
+ prefix?: string;
37
+ element?: HTMLElement;
38
+ onChange?: (selection: ModelSelection) => void;
39
+ }): ModelEditorBlock;
40
+ //# 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;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1C,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACrB;AACD,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,SAAS,mBAAmB,EAAE,GAAG,IAAI,CAAC;IACjD,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,CAAC;IACtC,SAAS,EAAE,cAAc,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AACD,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,gBAAiB,SAAQ,OAAO,CAAC,gBAAgB,CAAC;IAC/D,IAAI,IAAI,cAAc,CAAC;IACvB,KAAK,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC,KAAK,IAAI,IAAI,CAAC;CACjB;AACD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAuG;AAC3J,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAshC;AAC/kC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,GAAE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CAC7C,GAAG,gBAAgB,CAqExB"}
@@ -0,0 +1,89 @@
1
+ import { escape, uniqueId } from '../dom.js';
2
+ import { adoptProductParts, reconcileSelectOptions as optionsInto } from '../foundations.js';
3
+ export function thinkingLabel(level) { return level === 'off' ? 'Thinking off' : `Thinking: ${level === 'xhigh' ? 'extra high' : level}`; }
4
+ export function modelEditorMarkup(prefix) { prefix = escape(prefix); return `<label class="pui-field-label" for="${prefix}-provider">Provider</label><select class="pui-feature-select" id="${prefix}-provider" required disabled><option value="">Loading providers…</option></select><label class="pui-field-label" for="${prefix}-search">Model</label><input id="${prefix}-search" type="search" placeholder="Search by model name or ID" autocomplete="off" /><label class="pui-sr-only" for="${prefix}-model">Choose model</label><select id="${prefix}-model" class="pui-model-list" size="6" required disabled></select><p id="${prefix}-capabilities" class="pui-field-hint" aria-live="polite"></p><label class="pui-field-label" id="${prefix}-thinking-label" for="${prefix}-thinking">Thinking effort</label><select id="${prefix}-thinking" class="pui-feature-select" aria-describedby="${prefix}-capabilities" required></select><p class="pui-field-hint">Built-in models come from the Pith SDK catalog. Custom models use your saved definitions. Availability depends on your endpoint and account.</p>`; }
5
+ export function createModelEditor(initial, options = {}) {
6
+ const prefix = options.prefix || uniqueId('pui-model');
7
+ const element = options.element || document.createElement('div');
8
+ if (!options.element) {
9
+ element.className = 'pui-model-editor';
10
+ element.innerHTML = modelEditorMarkup(prefix);
11
+ }
12
+ const field = (id) => {
13
+ const result = Array.from(element.querySelectorAll('[id]')).find(node => node.id === prefix + '-' + id);
14
+ if (!result)
15
+ throw new Error(`Unknown model field: ${id}`);
16
+ return result;
17
+ };
18
+ const provider = field('provider'), model = field('model'), search = field('search'), effort = field('thinking');
19
+ const parts = adoptProductParts(element), abort = new AbortController();
20
+ let destroyed = false, initialized = false, signature = '', selected = '';
21
+ let state = initial;
22
+ const read = () => ({ provider: parts.control(provider).getValue(), model: parts.control(model).getValue(), thinkingLevel: parts.control(effort).getValue() });
23
+ const disabled = () => { parts.control(provider).update({ disabled: !!state.disabled || !state.providers?.length }); parts.control(model).update({ disabled: !!state.disabled || !model.options.length }); parts.control(effort).update({ disabled: !!state.disabled || effort.options.length < 2 }); parts.control(search).update({ disabled: !!state.disabled }); };
24
+ const capabilities = (preferred = effort.value) => {
25
+ selected = model.value;
26
+ const entry = (state.models || []).find(entry => entry.provider === provider.value && entry.id === selected);
27
+ const levels = entry?.thinkingLevels?.length ? entry.thinkingLevels : ['off'];
28
+ optionsInto(effort, levels.map(level => ({ value: level, label: thinkingLabel(level) })));
29
+ effort.value = levels.includes(preferred) ? preferred : levels.includes('high') ? 'high' : levels.includes('medium') ? 'medium' : levels[0];
30
+ effort.hidden = levels.length < 2;
31
+ field('thinking-label').hidden = effort.hidden;
32
+ field('capabilities').textContent = entry ? `${entry.supportsImages ? 'Text + images' : 'Text only'} · ${new Intl.NumberFormat('en').format(entry.contextWindow)} context tokens · ${new Intl.NumberFormat('en').format(entry.maxTokens)} max output tokens` : 'No matching models.';
33
+ disabled();
34
+ };
35
+ const renderModels = (preferred = effort.value) => {
36
+ const query = search.value.trim().toLowerCase();
37
+ const entries = (state.models || []).filter(entry => entry.provider === provider.value && (entry.id === selected || `${entry.name} ${entry.id}`.toLowerCase().includes(query)));
38
+ optionsInto(model, entries.map(entry => ({ value: entry.id, label: `${entry.name} — ${entry.id}` })));
39
+ model.value = entries.some(entry => entry.id === selected) ? selected : entries[0]?.id || '';
40
+ capabilities(preferred);
41
+ };
42
+ const chooseProvider = (selection) => {
43
+ const entry = state.providers?.find(entry => entry.id === provider.value);
44
+ search.value = '';
45
+ selected = selection && selection.provider === provider.value ? selection.model : entry?.model || '';
46
+ renderModels(selection && selection.provider === provider.value ? selection.thinkingLevel : entry?.thinkingLevel || 'high');
47
+ };
48
+ const reset = (selection) => {
49
+ if (destroyed)
50
+ return;
51
+ parts.control(provider).reset(state.providers?.some(entry => entry.id === selection.provider) ? selection.provider : state.providers?.[0]?.id || '');
52
+ chooseProvider(selection);
53
+ };
54
+ const update = (next) => {
55
+ if (destroyed)
56
+ return;
57
+ const draft = read();
58
+ state = next;
59
+ const nextSignature = JSON.stringify([next.providers, next.models]);
60
+ if (nextSignature !== signature) {
61
+ signature = nextSignature;
62
+ optionsInto(provider, (state.providers || []).map(entry => ({ value: entry.id, label: entry.name })));
63
+ if (!initialized || !draft.provider)
64
+ reset(next.selection);
65
+ else {
66
+ provider.value = state.providers?.some(entry => entry.id === draft.provider) ? draft.provider : state.providers?.[0]?.id || '';
67
+ selected = draft.model;
68
+ renderModels(draft.thinkingLevel);
69
+ }
70
+ initialized = true;
71
+ }
72
+ disabled();
73
+ };
74
+ provider.addEventListener('change', () => chooseProvider(), { signal: abort.signal });
75
+ model.addEventListener('change', () => capabilities(), { signal: abort.signal });
76
+ search.addEventListener('input', () => renderModels(), { signal: abort.signal });
77
+ element.addEventListener('change', () => options.onChange?.(read()), { signal: abort.signal });
78
+ update(initial);
79
+ return { element, update, read, reset, focus() { parts.control(search).focus(); }, destroy() {
80
+ if (destroyed)
81
+ return;
82
+ destroyed = true;
83
+ abort.abort();
84
+ parts.destroy();
85
+ if (!options.element)
86
+ element.remove();
87
+ } };
88
+ }
89
+ //# 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 {adoptProductParts,reconcileSelectOptions as optionsInto} from '../foundations.js';\nexport interface ModelProviderOption {\n id: string;\n name: string;\n model?: string;\n thinkingLevel?: string;\n}\nexport interface ModelOption {\n id: string;\n name: string;\n provider: string;\n thinkingLevels?: readonly string[] | null;\n supportsImages: boolean;\n contextWindow: number;\n maxTokens: number;\n}\nexport interface ModelEditorState {\n providers: readonly ModelProviderOption[] | null;\n models: readonly ModelOption[] | null;\n selection: ModelSelection;\n disabled?: boolean;\n}\nexport interface ModelSelection {\n provider: string;\n model: string;\n thinkingLevel: string;\n}\nexport interface ModelEditorBlock extends UIBlock<ModelEditorState> {\n read(): ModelSelection;\n reset(selection: ModelSelection): void;\n focus(): void;\n}\nexport function thinkingLabel(level: string): string { return level === 'off' ? 'Thinking off' : `Thinking: ${level === 'xhigh' ? 'extra high' : level}`; }\nexport function modelEditorMarkup(prefix: string): string { prefix = escape(prefix); return `<label class=\"pui-field-label\" for=\"${prefix}-provider\">Provider</label><select class=\"pui-feature-select\" id=\"${prefix}-provider\" required disabled><option value=\"\">Loading providers…</option></select><label class=\"pui-field-label\" for=\"${prefix}-search\">Model</label><input id=\"${prefix}-search\" type=\"search\" placeholder=\"Search by model name or ID\" autocomplete=\"off\" /><label class=\"pui-sr-only\" for=\"${prefix}-model\">Choose model</label><select id=\"${prefix}-model\" class=\"pui-model-list\" size=\"6\" required disabled></select><p id=\"${prefix}-capabilities\" class=\"pui-field-hint\" aria-live=\"polite\"></p><label class=\"pui-field-label\" id=\"${prefix}-thinking-label\" for=\"${prefix}-thinking\">Thinking effort</label><select id=\"${prefix}-thinking\" class=\"pui-feature-select\" aria-describedby=\"${prefix}-capabilities\" required></select><p class=\"pui-field-hint\">Built-in models come from the Pith SDK catalog. Custom models use your saved definitions. Availability depends on your endpoint and account.</p>`; }\nexport function createModelEditor(initial: ModelEditorState, options: {\n prefix?: string;\n element?: HTMLElement;\n onChange?: (selection: ModelSelection) => void;\n} = {}): ModelEditorBlock {\n const prefix = options.prefix || uniqueId('pui-model');\n const element = options.element || document.createElement('div');\n if (!options.element) {\n element.className = 'pui-model-editor';\n element.innerHTML = modelEditorMarkup(prefix);\n }\n const field = <T extends HTMLElement = HTMLElement>(id: string) => { const result = Array.from(element.querySelectorAll<HTMLElement>('[id]')).find(node => node.id === prefix + '-' + id); if (!result)\n throw new Error(`Unknown model field: ${id}`); return result as T; };\n const provider = field<HTMLSelectElement>('provider'), model = field<HTMLSelectElement>('model'), search = field<HTMLInputElement>('search'), effort = field<HTMLSelectElement>('thinking');\n const parts = adoptProductParts(element), abort = new AbortController();\n let destroyed = false, initialized = false, signature = '', selected = '';\n let state: Readonly<ModelEditorState> = initial;\n const read = (): ModelSelection => ({ provider: parts.control(provider).getValue(), model: parts.control(model).getValue(), thinkingLevel: parts.control(effort).getValue() });\n const disabled = () => { parts.control(provider).update({ disabled: !!state.disabled || !state.providers?.length }); parts.control(model).update({ disabled: !!state.disabled || !model.options.length }); parts.control(effort).update({ disabled: !!state.disabled || effort.options.length < 2 }); parts.control(search).update({disabled:!!state.disabled}); };\n const capabilities = (preferred = effort.value) => {\n selected = model.value;\n const entry = (state.models || []).find(entry => entry.provider === provider.value && entry.id === selected);\n const levels = entry?.thinkingLevels?.length ? entry.thinkingLevels : ['off'];\n optionsInto(effort, levels.map(level => ({ value: level, label: thinkingLabel(level) })));\n effort.value = levels.includes(preferred) ? preferred : levels.includes('high') ? 'high' : levels.includes('medium') ? 'medium' : levels[0];\n effort.hidden = levels.length < 2;\n field('thinking-label').hidden = effort.hidden;\n field('capabilities').textContent = entry ? `${entry.supportsImages ? 'Text + images' : 'Text only'} · ${new Intl.NumberFormat('en').format(entry.contextWindow)} context tokens · ${new Intl.NumberFormat('en').format(entry.maxTokens)} max output tokens` : 'No matching models.';\n disabled();\n };\n const renderModels = (preferred = effort.value) => {\n const query = search.value.trim().toLowerCase();\n const entries = (state.models || []).filter(entry => entry.provider === provider.value && (entry.id === selected || `${entry.name} ${entry.id}`.toLowerCase().includes(query)));\n optionsInto(model, entries.map(entry => ({ value: entry.id, label: `${entry.name} — ${entry.id}` })));\n model.value = entries.some(entry => entry.id === selected) ? selected : entries[0]?.id || '';\n capabilities(preferred);\n };\n const chooseProvider = (selection?: ModelSelection) => {\n const entry = state.providers?.find(entry => entry.id === provider.value);\n search.value = '';\n selected = selection && selection.provider === provider.value ? selection.model : entry?.model || '';\n renderModels(selection && selection.provider === provider.value ? selection.thinkingLevel : entry?.thinkingLevel || 'high');\n };\n const reset = (selection: ModelSelection) => { if (destroyed)\n return; parts.control(provider).reset(state.providers?.some(entry => entry.id === selection.provider) ? selection.provider : state.providers?.[0]?.id || ''); chooseProvider(selection); };\n const update = (next: Readonly<ModelEditorState>) => {\n if (destroyed)\n return;\n const draft = read();\n state = next;\n const nextSignature = JSON.stringify([next.providers, next.models]);\n if (nextSignature !== signature) {\n signature = nextSignature;\n optionsInto(provider, (state.providers || []).map(entry => ({ value: entry.id, label: entry.name })));\n if (!initialized || !draft.provider)\n reset(next.selection);\n else {\n provider.value = state.providers?.some(entry => entry.id === draft.provider) ? draft.provider : state.providers?.[0]?.id || '';\n selected = draft.model;\n renderModels(draft.thinkingLevel);\n }\n initialized = true;\n }\n disabled();\n };\n provider.addEventListener('change', () => chooseProvider(), { signal: abort.signal });\n model.addEventListener('change', () => capabilities(), { signal: abort.signal });\n search.addEventListener('input', () => renderModels(), { signal: abort.signal });\n element.addEventListener('change', () => options.onChange?.(read()), { signal: abort.signal });\n update(initial);\n return { element, update, read, reset, focus() { parts.control(search).focus(); }, destroy() { if (destroyed)\n return; destroyed = true; abort.abort(); parts.destroy(); if (!options.element)\n element.remove(); } };\n}\n"]}