pith-ui 0.1.0 → 0.1.4

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 (124) hide show
  1. package/AI.md +20 -1
  2. package/API.md +834 -272
  3. package/README.md +3 -1
  4. package/dist/composer.d.ts.map +1 -1
  5. package/dist/composer.js +48 -29
  6. package/dist/composer.js.map +1 -1
  7. package/dist/content/conversation-reader.d.ts.map +1 -1
  8. package/dist/content/conversation-reader.js +8 -1
  9. package/dist/content/conversation-reader.js.map +1 -1
  10. package/dist/content/conversation-view.d.ts +21 -4
  11. package/dist/content/conversation-view.d.ts.map +1 -1
  12. package/dist/content/conversation-view.js +72 -13
  13. package/dist/content/conversation-view.js.map +1 -1
  14. package/dist/content/image-viewer.d.ts +4 -2
  15. package/dist/content/image-viewer.d.ts.map +1 -1
  16. package/dist/content/image-viewer.js +36 -15
  17. package/dist/content/image-viewer.js.map +1 -1
  18. package/dist/content/paged-preview.d.ts +1 -1
  19. package/dist/content/paged-preview.d.ts.map +1 -1
  20. package/dist/content/paged-preview.js +10 -5
  21. package/dist/content/paged-preview.js.map +1 -1
  22. package/dist/content/views.d.ts +3 -0
  23. package/dist/content/views.d.ts.map +1 -1
  24. package/dist/content/views.js +110 -41
  25. package/dist/content/views.js.map +1 -1
  26. package/dist/content/welcome.d.ts.map +1 -1
  27. package/dist/content/welcome.js +19 -7
  28. package/dist/content/welcome.js.map +1 -1
  29. package/dist/dom.js +1 -1
  30. package/dist/dom.js.map +1 -1
  31. package/dist/files/panels.d.ts +8 -1
  32. package/dist/files/panels.d.ts.map +1 -1
  33. package/dist/files/panels.js +235 -120
  34. package/dist/files/panels.js.map +1 -1
  35. package/dist/files/systems.d.ts.map +1 -1
  36. package/dist/files/systems.js +81 -91
  37. package/dist/files/systems.js.map +1 -1
  38. package/dist/forms/actions.d.ts +28 -7
  39. package/dist/forms/actions.d.ts.map +1 -1
  40. package/dist/forms/actions.js +59 -11
  41. package/dist/forms/actions.js.map +1 -1
  42. package/dist/forms/custom-connection.d.ts +2 -1
  43. package/dist/forms/custom-connection.d.ts.map +1 -1
  44. package/dist/forms/custom-connection.js +36 -28
  45. package/dist/forms/custom-connection.js.map +1 -1
  46. package/dist/forms/dialog-frame.d.ts +2 -0
  47. package/dist/forms/dialog-frame.d.ts.map +1 -1
  48. package/dist/forms/dialog-frame.js +46 -26
  49. package/dist/forms/dialog-frame.js.map +1 -1
  50. package/dist/forms/history.d.ts +1 -1
  51. package/dist/forms/history.d.ts.map +1 -1
  52. package/dist/forms/history.js +78 -15
  53. package/dist/forms/history.js.map +1 -1
  54. package/dist/forms/identity.d.ts +12 -0
  55. package/dist/forms/identity.d.ts.map +1 -1
  56. package/dist/forms/identity.js +16 -0
  57. package/dist/forms/identity.js.map +1 -1
  58. package/dist/forms/model-editor.d.ts +8 -3
  59. package/dist/forms/model-editor.d.ts.map +1 -1
  60. package/dist/forms/model-editor.js +73 -62
  61. package/dist/forms/model-editor.js.map +1 -1
  62. package/dist/forms/panels.d.ts +103 -7
  63. package/dist/forms/panels.d.ts.map +1 -1
  64. package/dist/forms/panels.js +183 -77
  65. package/dist/forms/panels.js.map +1 -1
  66. package/dist/forms/provider-login.d.ts.map +1 -1
  67. package/dist/forms/provider-login.js +25 -39
  68. package/dist/forms/provider-login.js.map +1 -1
  69. package/dist/forms/resource-editor.d.ts +9 -5
  70. package/dist/forms/resource-editor.d.ts.map +1 -1
  71. package/dist/forms/resource-editor.js +20 -9
  72. package/dist/forms/resource-editor.js.map +1 -1
  73. package/dist/foundations.d.ts +95 -0
  74. package/dist/foundations.d.ts.map +1 -0
  75. package/dist/foundations.js +299 -0
  76. package/dist/foundations.js.map +1 -0
  77. package/dist/navigation/context-menu.d.ts +8 -1
  78. package/dist/navigation/context-menu.d.ts.map +1 -1
  79. package/dist/navigation/context-menu.js +67 -50
  80. package/dist/navigation/context-menu.js.map +1 -1
  81. package/dist/navigation/navigation.d.ts +55 -7
  82. package/dist/navigation/navigation.d.ts.map +1 -1
  83. package/dist/navigation/navigation.js +167 -18
  84. package/dist/navigation/navigation.js.map +1 -1
  85. package/dist/operation.d.ts +12 -0
  86. package/dist/operation.d.ts.map +1 -0
  87. package/dist/operation.js +49 -0
  88. package/dist/operation.js.map +1 -0
  89. package/dist/primitives.d.ts +11 -1
  90. package/dist/primitives.d.ts.map +1 -1
  91. package/dist/primitives.js +164 -301
  92. package/dist/primitives.js.map +1 -1
  93. package/dist/reconcile.d.ts +11 -0
  94. package/dist/reconcile.d.ts.map +1 -0
  95. package/dist/reconcile.js +36 -0
  96. package/dist/reconcile.js.map +1 -0
  97. package/dist/select.d.ts +14 -0
  98. package/dist/select.d.ts.map +1 -0
  99. package/dist/select.js +304 -0
  100. package/dist/select.js.map +1 -0
  101. package/dist/styles.css +452 -382
  102. package/dist/surface.d.ts +60 -0
  103. package/dist/surface.d.ts.map +1 -0
  104. package/dist/surface.js +344 -0
  105. package/dist/surface.js.map +1 -0
  106. package/dist/tasks/approval.d.ts.map +1 -1
  107. package/dist/tasks/approval.js +86 -45
  108. package/dist/tasks/approval.js.map +1 -1
  109. package/dist/tasks/permission-element.d.ts +3 -0
  110. package/dist/tasks/permission-element.d.ts.map +1 -0
  111. package/dist/tasks/permission-element.js +10 -0
  112. package/dist/tasks/permission-element.js.map +1 -0
  113. package/dist/tasks/permission.d.ts +5 -3
  114. package/dist/tasks/permission.d.ts.map +1 -1
  115. package/dist/tasks/permission.js +47 -22
  116. package/dist/tasks/permission.js.map +1 -1
  117. package/dist/tasks/runtime.d.ts.map +1 -1
  118. package/dist/tasks/runtime.js +30 -13
  119. package/dist/tasks/runtime.js.map +1 -1
  120. package/dist/workspace.d.ts +58 -4
  121. package/dist/workspace.d.ts.map +1 -1
  122. package/dist/workspace.js +202 -44
  123. package/dist/workspace.js.map +1 -1
  124. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"panels.js","sourceRoot":"","sources":["../../src/forms/panels.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAO3E,SAAS,SAAS,CAA6B,MAAc,EAAE,SAAiB,EAAE,OAAc,EAAE,MAAM,GAAG,EAAE;IAC3G,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACtD,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,MAAM,KAAK,GAAG,CAAsC,EAAU,EAAK,EAAE;QACnE,MAAM,MAAM,GAAG,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,MAAM,GAAG,EAAE,CAAC,CAAC;QACjI,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,EAAE,EAAE,CAAC,CAAC;QAC/D,OAAO,MAAW,CAAC;IACrB,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,CAAC,KAAsB,EAAE,EAAE;QACxC,IAAI,SAAS;YAAE,OAAO;QACtB,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,aAAa,CAAc,qBAAqB,CAAC,IAAI,OAAO,CAAC,aAAa,CAAc,+BAA+B,CAAC,CAAC;YAC/I,IAAI,KAAK;gBAAE,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC;QAC7C,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAoB,uBAAuB,CAAC,EAAE,CAAC;gBAC3F,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,cAAc,KAAK,MAAM,CAAC;YACjF,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,MAAM,CAAC,OAAO,CAAC,CAAC;IAChB,OAAO,EAAC,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,SAAS;YAAE,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC;AACrI,CAAC;AAGD,MAAM,UAAU,mBAAmB,CAAC,KAAyB,EAAE,UAAuB,EAAE;IACtF,OAAO,SAAS,CAAC;MACb,aAAa,CAAC,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6CA+BxC,IAAI,CAAC,OAAO,CAAC,kEAAkE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;;;;;2EAKtE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC,oBAAoB,iCAAiC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU;;;;;;;;;;;;;;;;YAgBhN,EAAE,oBAAoB,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;AAC3F,CAAC;AAGD,MAAM,UAAU,yBAAyB,CAAC,QAAsB,EAAE,EAAE,UAAuB,EAAE;IAC3F,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,aAAa,CAAC,aAAa,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,gBAAgB,CAAC,6jIAA6jI,EAAE,qBAAqB,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;IACjwI,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;IAAC,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;IAAC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACjF,MAAM,UAAU,GAAG,GAAG,EAAE,GAAE,IAAI,QAAQ;QAAE,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,CAAoB,UAAU,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAmB,SAAS,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAmB,aAAa,CAAC,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAA,CAAC,CAAC;IAChS,MAAM,IAAI,GAAG,CAAC,KAAsB,EAAE,EAAE;QACtC,IAAI,QAAQ;YAAE,OAAO;QACrB,CAAC,CAAkB,UAAU,CAAC,CAAC,KAAK,EAAE,CAAC;QACvC,CAAC,CAAsB,SAAS,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACnE,CAAC,CAAC,oBAAoB,CAAC,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,WAAW,GAAG,MAAM,CAAC;QAC5G,CAAC,CAAC,gBAAgB,CAAC,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAClF,CAAC,CAAmB,UAAU,CAAC,CAAC,KAAK,GAAG,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC;QAAC,CAAC,CAAmB,UAAU,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC;QAC9G,CAAC,CAAoB,UAAU,CAAC,CAAC,KAAK,GAAG,KAAK,EAAE,IAAI,IAAI,MAAM,CAAC;QAAC,CAAC,CAAmB,SAAS,CAAC,CAAC,KAAK,GAAG,KAAK,EAAE,GAAG,IAAI,EAAE,CAAC;QACxH,CAAC,CAAmB,WAAW,CAAC,CAAC,OAAO,GAAG,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC;QAAC,CAAC,CAAmB,kBAAkB,CAAC,CAAC,KAAK,GAAG,KAAK,EAAE,aAAa,IAAI,EAAE,CAAC;QAAC,CAAC,CAAmB,iBAAiB,CAAC,CAAC,KAAK,GAAG,KAAK,EAAE,UAAU,IAAI,EAAE,CAAC;QACrN,CAAC,CAAmB,aAAa,CAAC,CAAC,KAAK,GAAG,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;QAAC,CAAC,CAAsB,UAAU,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACvJ,CAAC,CAAmB,aAAa,CAAC,CAAC,OAAO,GAAG,KAAK,EAAE,OAAO,IAAI,IAAI,CAAC;QACpE,CAAC,CAAmB,WAAW,CAAC,CAAC,WAAW,GAAG,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC,gBAAgB,CAAC;QACjI,CAAC,CAAC,qBAAqB,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC;QAAC,MAAM,OAAO,GAAG,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;QAC/F,CAAC,CAAC,mBAAmB,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;QAAC,CAAC,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;QAAC,CAAC,CAAC,cAAc,CAAC,CAAC,WAAW,GAAG,2BAA2B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7K,CAAC,CAAC,gBAAgB,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC;QAAC,UAAU,EAAE,CAAC;QAAC,CAAC,CAAmB,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,CAAC;IAC3J,CAAC,CAAC;IACF,CAAC,CAAoB,UAAU,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAC,MAAM,EAAC,KAAK,CAAC,MAAM,EAAC,CAAC,CAAC;IAC/F,CAAC,CAAC,oBAAoB,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,GAAE,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAsB,SAAS,CAAC,CAAC,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA,CAAC,EAAE,EAAC,MAAM,EAAC,KAAK,CAAC,MAAM,EAAC,CAAC,CAAC;IAC1W,UAAU,EAAE,CAAC;IACb,OAAO,EAAC,GAAG,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,KAAI,IAAI,QAAQ;YAAE,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA,CAAC,EAAC,CAAC;AAC1H,CAAC;AACD,MAAM,UAAU,iBAAiB,CAAC,MAAc,IAAY,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,uCAAuC,MAAM,qEAAqE,MAAM,yHAAyH,MAAM,oCAAoC,MAAM,wHAAwH,MAAM,2CAA2C,MAAM,6EAA6E,MAAM,mGAAmG,MAAM,yBAAyB,MAAM,iDAAiD,MAAM,2DAA2D,MAAM,6MAA6M,CAAC,CAAC,CAAC;AAC/kC,MAAM,UAAU,iBAAiB,CAAC,QAAsB,EAAE,EAAE,UAAuB,EAAE;IACnF,OAAO,SAAS,CAAC,GAAG,aAAa,CAAC,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,oBAAoB,CAAC,yBAAyB,iBAAiB,CAAC,QAAQ,CAAC,oVAAoV,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC;AAC/jB,CAAC;AAOD,MAAM,UAAU,uBAAuB,CAAC,OAA+B;IACrE,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAAC,OAAO,CAAC,SAAS,GAAG,yBAAyB,CAAC;IAC7F,IAAI,SAAS,GAAG,KAAK,CAAC;IAAC,MAAM,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC3E,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAAC,KAAK,CAAC,SAAS,GAAG,kBAAkB,CAAC;IAAC,KAAK,CAAC,WAAW,GAAG,gJAAgJ,CAAC;IACtP,SAAS,WAAW;QAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAAC,IAAI,CAAC,SAAS,GAAG,qBAAqB,CAAC;QACvF,IAAI,CAAC,SAAS,GAAG,2RAA2R,CAAC;QAC7S,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAc,GAAG,CAAC,CAAC;QAAC,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAc,mBAAmB,CAAE,CAAC;QAClI,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,WAAW,GAAG,KAAK,EAAE,EAAE,GAAE,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,6CAA6C,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,OAAO,IAAI,CAAC,CAAA,CAAC,CAAC;QAC5Q,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAAC,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,WAAW,CAAC;QAAC,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;QAAC,OAAO,CAAC,OAAO,CAAC,GAAG,GAAG,YAAY,CAAC;QAC3I,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAAC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAAC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAC,IAAI,CAAC,CAAC;QACpG,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,EAAC,MAAM,CAAC,EAAE,CAAC;YAAA,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,EAAE,CAAC;YAAC,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,EAAE,CAAC;QAAA,CAAC;QACjG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAC,MAAM,EAAC,MAAM,CAAC,CAAC;QACnC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,IAAI,EAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAE,EAAC,OAAO,EAAC,UAAU,CAAC,CAAC,CAAC,EAAC,OAAO,EAAC,UAAU,CAAC,CAAC,CAAC,EAAC,MAAM,EAAC,UAAU,CAAC,CAAC,CAAC,EAAC,GAAG,EAAC,UAAU,CAAC,CAAC,CAAC,EAAC,KAAK,EAAC,UAAU,CAAC,CAAC,CAAC,EAAC,OAAO,EAAC,MAAM,EAAC,OAAO,EAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,CAAC;IAC5M,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,KAAuC,EAAE,EAAE;QACzD,IAAI,SAAS;YAAE,OAAO;QAAC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAAC,IAAI,MAAM,GAAmB,OAAO,CAAC,iBAAiB,CAAC;QACjH,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAC,IAAI,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBAAA,KAAK,GAAG,WAAW,EAAE,CAAC;gBAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAC,KAAK,CAAC,CAAC;YAAA,CAAC;YAC9H,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC;YAChF,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9G,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtH,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,EAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC;YAC/H,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,0BAA0B,GAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YACrL,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;YACnI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC;YAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;YAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC3L,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAAA,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,KAAK,KAAK,CAAC,OAAO;oBAAE,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAAA,CAAC;;gBAAM,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACpJ,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAAA,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,KAAK,KAAK,CAAC,OAAO;oBAAE,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAAA,CAAC;;gBAAM,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACxK,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAC,KAAK,CAAC,OAAO,EAAC,KAAK,CAAC,IAAI,EAAC,KAAK,CAAC,MAAM,EAAC,KAAK,CAAC,MAAM,CAAC;gBAAE,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC3H,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM;gBAAE,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,EAAC,MAAM,CAAC,CAAC;YAAC,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC;QACtH,CAAC;QACD,KAAK,MAAM,CAAC,GAAG,EAAC,KAAK,CAAC,IAAI,OAAO;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAA,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gBAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAAA,CAAC;QACxG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAAA,IAAI,KAAK,CAAC,aAAa,KAAK,OAAO;gBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAAA,CAAC;;YAAM,KAAK,CAAC,MAAM,EAAE,CAAC;IAC/G,CAAC,CAAC;IACF,MAAM,CAAC,OAAO,CAAC,CAAC;IAAC,OAAO,EAAC,OAAO,EAAC,MAAM,EAAC,OAAO,KAAI,IAAI,SAAS;YAAE,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA,CAAC,EAAC,CAAC;AACnI,CAAC","sourcesContent":["import type { UIBlock } from '../core.js';\nimport {scopeIds} from './identity.js';\nimport { dialogHeading, escape, icon, uniqueId, setText } from '../dom.js';\n\nexport interface FormFeedback { error?: string; disabled?: boolean }\nexport interface FormDOMBlock<State extends FormFeedback> extends UIBlock<State> {\n field<T extends HTMLElement = HTMLElement>(id: string): T;\n id(localId: string): string;\n}\nfunction formBlock<State extends FormFeedback>(markup: string, className: string, initial: State, prefix = ''): FormDOMBlock<State> {\n const element = document.createElement('div');\n element.className = className;\n element.innerHTML = markup; scopeIds(element, prefix);\n let destroyed = false;\n const field = <T extends HTMLElement = HTMLElement>(id: string): T => {\n const result = Array.from(element.querySelectorAll<HTMLElement>('[id]')).find((node) => node.getAttribute('id') === prefix + id);\n if (!result) throw new Error(`Unknown component field: ${id}`);\n return result as T;\n };\n const update = (state: Readonly<State>) => {\n if (destroyed) return;\n if (state.error !== undefined) {\n const error = element.querySelector<HTMLElement>('[data-dialog-error]') || element.querySelector<HTMLElement>('.pui-form-error[role=\"alert\"]');\n if (error) error.textContent = state.error;\n }\n if (state.disabled !== undefined) {\n for (const control of element.querySelectorAll<HTMLButtonElement>('button[type=\"submit\"]')) {\n control.disabled = state.disabled || control.dataset.controlPending === 'true';\n }\n }\n };\n update(initial);\n return {element, field, id: (id) => prefix + id, update, destroy() { if (destroyed) return; destroyed = true; element.remove(); }};\n}\nexport interface SettingsPanelState extends FormFeedback { baseUrl: string; hasApiKey: boolean }\nexport interface FormOptions { idPrefix?: string }\nexport function createSettingsPanel(state: SettingsPanelState, options: FormOptions = {}): FormDOMBlock<SettingsPanelState> {\n return formBlock(`\n ${dialogHeading('Settings', 'settings-title', 'settings-dialog', 'MAKE IT YOURS')}\n <section class=\"pui-settings-section pui-appearance-settings\" aria-labelledby=\"appearance-title\">\n <h3 id=\"appearance-title\">Appearance</h3>\n <p class=\"pui-appearance-hint\" id=\"appearance-hint\">A bright white workspace or a calm dark one, both with a blue accent. Follow system matches your computer.</p>\n <label class=\"pui-sr-only\" for=\"appearance-mode\">Appearance</label>\n <select id=\"appearance-mode\" class=\"pui-appearance-select\" aria-describedby=\"appearance-hint\"><option value=\"system\">Follow system</option><option value=\"light\">Light</option><option value=\"dark\">Dark</option></select>\n <div id=\"appearance-error\" class=\"pui-form-error\" role=\"alert\"></div>\n </section>\n <section id=\"update-settings\" class=\"pui-settings-section pui-update-settings\" aria-labelledby=\"update-title\">\n <h3 id=\"update-title\">Updates</h3>\n <div class=\"pui-settings-copy\">\n <p class=\"pui-field-hint\" data-update-version></p>\n <p class=\"pui-field-hint\" role=\"status\" aria-live=\"polite\" data-update-message>Loading update status…</p>\n </div>\n <progress max=\"100\" value=\"0\" aria-label=\"Update progress\" hidden></progress>\n <div class=\"pui-settings-actions\"><button class=\"pui-secondary-button\" type=\"button\" data-update-check disabled>Check for updates</button><button class=\"pui-primary-button\" type=\"button\" data-update-install hidden>Update and restart</button></div>\n </section>\n <form id=\"settings-form\">\n <section class=\"pui-settings-section\" aria-labelledby=\"provider-title\">\n <h3 id=\"provider-title\">Model providers</h3>\n <p class=\"pui-modal-description\">Connect your model providers here. Choose models and thinking effort beside the message box.</p>\n <div class=\"pui-settings-actions\"><button class=\"pui-secondary-button\" type=\"button\" data-sdk=\"custom\">Add independent model connection</button></div>\n <div class=\"pui-settings-field\">\n <label class=\"pui-field-label\" for=\"settings-provider\">Provider</label>\n <select id=\"settings-provider\" class=\"pui-feature-select\" required disabled><option value=\"\">Loading providers…</option></select>\n <div id=\"provider-actions\" hidden></div>\n <p id=\"provider-auth-hint\" class=\"pui-field-hint\" hidden></p>\n </div>\n <details id=\"provider-advanced\" class=\"pui-provider-advanced\">\n <summary>Advanced connection settings</summary>\n <label class=\"pui-field-label\" for=\"base-url\">API base URL</label>\n <div class=\"pui-input-with-icon\">${icon('globe')}<input id=\"base-url\" name=\"baseUrl\" type=\"url\" required value=\"${escape(state.baseUrl)}\" autocomplete=\"off\" /></div>\n <p class=\"pui-field-hint\">The provider’s endpoint is filled in automatically. Change it only for a proxy or custom service.</p>\n </details>\n <div id=\"provider-api-key\" class=\"pui-settings-field\">\n <label class=\"pui-field-label\" for=\"api-key\">API key <span id=\"key-status\" class=\"pui-configured-badge\"></span></label>\n <input id=\"api-key\" name=\"apiKey\" type=\"password\" placeholder=\"${state.hasApiKey ? 'Leave blank to keep your current key' : 'Paste your API key'}\" autocomplete=\"new-password\" ${state.hasApiKey ? '' : 'required'} />\n <p class=\"pui-field-hint\">The saved key is never returned to this page. Model requests go to your configured provider.</p>\n <button class=\"pui-secondary-button pui-destructive-button\" id=\"remove-key\" type=\"button\" hidden>Remove saved API key</button>\n </div>\n </section>\n <section class=\"pui-settings-section pui-connection-test\">\n <p class=\"pui-field-hint\">Uses this provider’s last selected model, or Pith’s default, to check streaming and tool calling. Does not save settings or access files.</p>\n <div class=\"pui-settings-actions\"><button type=\"button\" class=\"pui-secondary-button\" id=\"test-connection\" data-control-pending=\"true\" disabled data-global-idle data-idle-action>Test connection</button></div>\n <div id=\"connection-test-result\" role=\"status\" aria-live=\"polite\"></div>\n </section>\n <div id=\"settings-error\" data-dialog-error class=\"pui-form-error\" role=\"alert\"></div>\n <section class=\"pui-settings-section pui-diagnostics-setting\">\n <p class=\"pui-field-hint\">Version, usage and failure category only; no conversation, file contents, paths or credentials.</p>\n <div class=\"pui-settings-actions\"><button type=\"button\" class=\"pui-secondary-button\" data-action=\"diagnostics\">Save diagnostics</button></div>\n </section>\n <div class=\"pui-modal-footer\"><button class=\"pui-secondary-button\" type=\"button\" data-close=\"settings-dialog\">Cancel</button><button class=\"pui-primary-button\" id=\"save-settings\" data-control-pending=\"true\" disabled data-global-idle type=\"submit\">Save settings</button></div>\n </form>`, 'pui-settings-panel', state, options.idPrefix ?? uniqueId('pui-form') + '-');\n}\nexport interface MCPEditorValue {name: string; type: string; url?: string; oauth?: boolean; oauthClientId?: string; oauthScope?: string; command?: string; args?: readonly string[]; enabled?: boolean; hasBearerToken?: boolean; envKeys?: readonly string[]}\nexport interface MCPConnectionsPanel extends FormDOMBlock<FormFeedback> {renderType(): void; edit(value?: MCPEditorValue): void}\nexport function createMCPConnectionsPanel(state: FormFeedback = {}, options: FormOptions = {}): MCPConnectionsPanel {\n const block = formBlock(`${dialogHeading('Connections', 'connections-title', 'connections-dialog', 'EXTERNAL TOOLS')}<p class=\"pui-modal-description\">Add an MCP server to give Pith access to its tools. Enabled connections connect automatically when a task starts. Disable a connection to stop using it in tasks. External tools require approval unless this conversation has full access.</p><div class=\"pui-feature-toolbar\"><button class=\"pui-secondary-button\" data-action=\"refresh-mcp\">Refresh</button></div><div id=\"mcp-list\"><p class=\"pui-feature-hint\">Loading connections…</p></div><div id=\"mcp-error\" data-dialog-error class=\"pui-form-error\" role=\"alert\"></div><section class=\"pui-connection-editor\"><div class=\"pui-section-heading\"><span id=\"mcp-form-title\">Add connection</span><button type=\"button\" class=\"pui-secondary-button\" data-action=\"new-mcp\">New connection</button></div><form id=\"mcp-form\"><label class=\"pui-field-label\" for=\"mcp-name\">Name</label><input id=\"mcp-name\" name=\"name\" required autocomplete=\"off\" placeholder=\"my-tools\" /><label class=\"pui-field-label\" for=\"mcp-type\">Connection type</label><select id=\"mcp-type\" name=\"type\" class=\"pui-feature-select\"><option value=\"http\">HTTP</option><option value=\"stdio\">Local command (stdio)</option></select><div id=\"mcp-http-fields\"><label class=\"pui-field-label\" for=\"mcp-url\">Server URL</label><input id=\"mcp-url\" name=\"url\" type=\"url\" placeholder=\"https://example.com/mcp\" autocomplete=\"off\" /><label class=\"pui-checkbox-field\"><input id=\"mcp-oauth\" type=\"checkbox\" />Sign in with OAuth</label><details class=\"pui-provider-advanced\"><summary>OAuth settings (optional)</summary><label class=\"pui-field-label\">Registered client ID<input id=\"mcp-oauth-client\" /></label><label class=\"pui-field-label\">Scopes<input id=\"mcp-oauth-scope\" /></label><p class=\"pui-field-hint\">Uses the server’s OAuth discovery and PKCE. The temporary callback listens on 127.0.0.1:54819.</p></details><label class=\"pui-field-label\" for=\"mcp-token\">Bearer token (optional)</label><input id=\"mcp-token\" name=\"bearerToken\" type=\"password\" autocomplete=\"new-password\" placeholder=\"Optional token\" /><label class=\"pui-checkbox-field\" id=\"mcp-clear-token-row\" hidden><input id=\"mcp-clear-token\" type=\"checkbox\" />Remove saved bearer token</label><p class=\"pui-field-hint\">Saved tokens are never returned to this page. Leave this field blank to keep an existing token.</p></div><div id=\"mcp-stdio-fields\" hidden><label class=\"pui-field-label\" for=\"mcp-command\">Installed executable</label><input id=\"mcp-command\" name=\"command\" placeholder=\"/path/to/mcp-server\" autocomplete=\"off\" /><label class=\"pui-field-label\" for=\"mcp-args\">Arguments (JSON array)</label><textarea id=\"mcp-args\" name=\"args\" rows=\"3\" spellcheck=\"false\">[]</textarea><p class=\"pui-field-hint\">The executable and any runtime it needs must already be installed on your computer. Pith Desk does not bundle external runtimes or a marketplace.</p><div class=\"pui-secret-label\"><label class=\"pui-field-label\" for=\"mcp-env\">Environment overrides (JSON object, optional)</label><button class=\"pui-secondary-button\" type=\"button\" id=\"mcp-env-visibility\" data-action=\"toggle-env\" aria-controls=\"mcp-env\" aria-pressed=\"false\">Show</button></div><textarea id=\"mcp-env\" class=\"pui-secret-field\" name=\"env\" rows=\"3\" spellcheck=\"false\" autocomplete=\"off\" aria-describedby=\"mcp-env-hint\" placeholder='{\"API_KEY\":\"…\"}'></textarea><p id=\"mcp-env-hint\" class=\"pui-field-hint\">Values stay private. Leave blank to keep saved overrides. Add a JSON object of string keys and values to set or replace individual overrides.</p><p id=\"mcp-env-keys\" class=\"pui-field-hint\" hidden></p><label class=\"pui-checkbox-field\" id=\"mcp-clear-env-row\" hidden><input id=\"mcp-clear-env\" type=\"checkbox\" />Clear saved environment overrides</label></div><label class=\"pui-checkbox-field\"><input id=\"mcp-enabled\" name=\"enabled\" type=\"checkbox\" checked />Enable this connection</label><div id=\"mcp-form-error\" class=\"pui-form-error\" role=\"alert\"></div><div class=\"pui-modal-footer\"><button class=\"pui-secondary-button\" type=\"button\" data-close=\"connections-dialog\">Close</button><button class=\"pui-primary-button\" type=\"submit\" data-idle-action data-global-idle>Save connection</button></div></form></section>`, 'pui-mcp-connections', state, options.idPrefix ?? uniqueId('pui-form') + '-');\n const $ = block.field; const abort = new AbortController(); let disposed = false;\n const renderType = () => {if (disposed) return; const http = $<HTMLSelectElement>('mcp-type').value === 'http'; $('mcp-http-fields').hidden = !http; $('mcp-stdio-fields').hidden = http; $<HTMLInputElement>('mcp-url').required = http; $<HTMLInputElement>('mcp-command').required = !http;};\n const edit = (entry?: MCPEditorValue) => {\n if (disposed) return;\n $<HTMLFormElement>('mcp-form').reset();\n $<HTMLTextAreaElement>('mcp-env').classList.remove('pui-revealed');\n $('mcp-env-visibility').setAttribute('aria-pressed', 'false'); $('mcp-env-visibility').textContent = 'Show';\n $('mcp-form-title').textContent = entry ? `Edit ${entry.name}` : 'Add connection';\n $<HTMLInputElement>('mcp-name').value = entry?.name || ''; $<HTMLInputElement>('mcp-name').readOnly = !!entry;\n $<HTMLSelectElement>('mcp-type').value = entry?.type || 'http'; $<HTMLInputElement>('mcp-url').value = entry?.url || '';\n $<HTMLInputElement>('mcp-oauth').checked = entry?.oauth || false; $<HTMLInputElement>('mcp-oauth-client').value = entry?.oauthClientId || ''; $<HTMLInputElement>('mcp-oauth-scope').value = entry?.oauthScope || '';\n $<HTMLInputElement>('mcp-command').value = entry?.command || ''; $<HTMLTextAreaElement>('mcp-args').value = JSON.stringify(entry?.args || [], null, 2);\n $<HTMLInputElement>('mcp-enabled').checked = entry?.enabled ?? true;\n $<HTMLInputElement>('mcp-token').placeholder = entry?.hasBearerToken ? 'Leave blank to keep your saved token' : 'Optional token';\n $('mcp-clear-token-row').hidden = !entry?.hasBearerToken; const envKeys = entry?.envKeys || [];\n $('mcp-clear-env-row').hidden = !envKeys.length; $('mcp-env-keys').hidden = !envKeys.length; $('mcp-env-keys').textContent = `Saved environment keys: ${envKeys.join(', ')}`;\n $('mcp-form-error').textContent = ''; renderType(); $<HTMLInputElement>(entry ? entry.type === 'stdio' ? 'mcp-command' : 'mcp-url' : 'mcp-name').focus();\n };\n $<HTMLSelectElement>('mcp-type').addEventListener('change', renderType, {signal:abort.signal});\n $('mcp-env-visibility').addEventListener('click', (event) => {event.stopPropagation(); const field = $<HTMLTextAreaElement>('mcp-env'); const revealed = field.classList.toggle('pui-revealed'); const button = $('mcp-env-visibility'); button.setAttribute('aria-pressed', String(revealed)); button.textContent = revealed ? 'Hide' : 'Show';}, {signal:abort.signal});\n renderType();\n return {...block, renderType, edit, destroy() {if (disposed) return; disposed = true; abort.abort(); block.destroy();}};\n}\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 createModelPicker(state: FormFeedback = {}, options: FormOptions = {}): FormDOMBlock<FormFeedback> {\n return formBlock(`${dialogHeading('Choose a model', 'model-title', 'model-dialog', 'PITH MODEL CATALOG')}<form id=\"model-form\">${modelEditorMarkup('picker')}<div id=\"model-error\" class=\"pui-form-error\" role=\"alert\"></div><div class=\"pui-modal-footer\"><button type=\"button\" class=\"pui-secondary-button\" data-close=\"model-dialog\">Cancel</button><button type=\"submit\" class=\"pui-primary-button\" id=\"choose-model\" data-global-idle data-control-pending=\"true\" disabled>Use model</button></div></form>`, 'pui-model-picker', state, options.idPrefix ?? uniqueId('pui-form') + '-');\n}\nexport interface MCPConnectionItem {\n name: string; type: string; url?: string; command?: string; args?: readonly string[]; enabled: boolean;\n hasBearerToken?: boolean; status?: string; statusLabel: string; envKeys?: readonly string[]; error?: string; oauth?: boolean; signedIn?: boolean;\n}\nexport interface MCPConnectionListState extends FormFeedback { entries: readonly MCPConnectionItem[] }\ntype MCPConnectionDOM = {element: HTMLElement; name: HTMLElement; address: HTMLElement; enabled: HTMLElement; status: HTMLElement; env: HTMLElement; error: HTMLElement; actions: HTMLElement; signIn: HTMLButtonElement; signOut: HTMLButtonElement; edit: HTMLButtonElement; toggle: HTMLButtonElement; remove: HTMLButtonElement};\nexport function createMCPConnectionList(initial: MCPConnectionListState): UIBlock<MCPConnectionListState> {\n const element = document.createElement('div'); element.className = 'pui-mcp-connection-list';\n let destroyed = false; const entries = new Map<string, MCPConnectionDOM>();\n const empty = document.createElement('p'); empty.className = 'pui-feature-hint'; empty.textContent = 'No connections yet. Add an HTTP server or an installed local MCP command below. Tools are discovered on demand using tool search and Codemode.';\n function createEntry(): MCPConnectionDOM {\n const root = document.createElement('article'); root.className = 'pui-connection-card';\n root.innerHTML = '<div class=\"pui-connection-card-heading\"><strong></strong></div><p class=\"pui-file-path\"></p><p class=\"pui-feature-hint\"></p><p class=\"pui-connection-status\" role=\"status\"></p><p class=\"pui-feature-hint\" hidden></p><p class=\"pui-form-error\"></p><div class=\"pui-file-actions\"></div>';\n const paragraphs = root.querySelectorAll<HTMLElement>('p'); const actions = root.querySelector<HTMLElement>('.pui-file-actions')!;\n const button = (label: string, destructive = false) => {const node = document.createElement('button'); node.type = 'button'; node.className = destructive ? 'pui-secondary-button pui-destructive-button' : 'pui-secondary-button'; node.textContent = label; return node;};\n const signIn = button('Sign in'); signIn.dataset.sdk = 'mcp-login'; const signOut = button('Sign out'); signOut.dataset.sdk = 'mcp-logout';\n const edit = button('Edit'); const toggle = button('Disable'); const remove = button('Delete',true);\n for (const node of [toggle,remove]) {node.dataset.globalIdle = ''; node.dataset.idleAction = '';}\n actions.append(edit,toggle,remove);\n return {element:root,name:root.querySelector('strong')!,address:paragraphs[0],enabled:paragraphs[1],status:paragraphs[2],env:paragraphs[3],error:paragraphs[4],actions,signIn,signOut,edit,toggle,remove};\n }\n const update = (state: Readonly<MCPConnectionListState>) => {\n if (destroyed) return; const current = new Set<string>(); let cursor: Element | null = element.firstElementChild;\n for (const item of state.entries) {\n current.add(item.name); let entry = entries.get(item.name); if (!entry) {entry = createEntry(); entries.set(item.name,entry);}\n setText(entry.name, item.name); entry.element.dataset.connectionKey = item.name;\n setText(entry.address, item.type === 'http' ? item.url || '' : [item.command,...(item.args || [])].join(' '));\n setText(entry.enabled, `${item.enabled ? 'Enabled' : 'Disabled'}${item.hasBearerToken ? ' · Token configured' : ''}`);\n setText(entry.status, item.statusLabel); entry.status.classList.toggle('pui-is-error',item.enabled && item.status === 'error');\n entry.env.hidden = !item.envKeys?.length; setText(entry.env, item.envKeys?.length ? 'Saved environment keys: '+item.envKeys.join(', ') : ''); setText(entry.error, item.error || '');\n setText(entry.signIn, item.signedIn ? 'Sign in again' : 'Sign in'); entry.signIn.dataset.id = entry.signOut.dataset.id = item.name;\n entry.edit.dataset.mcpEdit = item.name; entry.toggle.dataset.mcpToggle = item.name; entry.remove.dataset.mcpRemove = item.name; setText(entry.toggle, item.enabled ? 'Disable' : 'Enable');\n if (item.oauth) {if (entry.signIn.parentElement !== entry.actions) entry.actions.insertBefore(entry.signIn,entry.edit);} else entry.signIn.remove();\n if (item.oauth && item.signedIn) {if (entry.signOut.parentElement !== entry.actions) entry.actions.insertBefore(entry.signOut,entry.edit);} else entry.signOut.remove();\n for (const button of [entry.signIn,entry.signOut,entry.edit,entry.toggle,entry.remove]) button.disabled = !!state.disabled;\n if (entry.element !== cursor) element.insertBefore(entry.element,cursor); cursor = entry.element.nextElementSibling;\n }\n for (const [key,entry] of entries) if (!current.has(key)) {entry.element.remove(); entries.delete(key);}\n if (!state.entries.length) {if (empty.parentElement !== element) element.append(empty);} else empty.remove();\n };\n update(initial); return {element,update,destroy() {if (destroyed) return; destroyed = true; entries.clear(); element.remove();}};\n}\n"]}
1
+ {"version":3,"file":"panels.js","sourceRoot":"","sources":["../../src/forms/panels.ts"],"names":[],"mappings":"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","sourcesContent":["import {type ActionResult, type UIBlock, type UIAction} from '../core.js';\nimport {scopeIds,bindFormSubmission} from './identity.js';\nimport { dialogHeading, escape, icon, uniqueId, setText } from '../dom.js';\nimport {createModelEditor, modelEditorMarkup, type ModelEditorState, type ModelSelection} from './model-editor.js';\nimport {adoptAction,adoptProductParts,reconcileSelectOptions,type ActionController} from '../foundations.js';\nimport {createOperation} from '../operation.js';\nimport {reconcileKeyed} from '../reconcile.js';\nexport {modelEditorMarkup} from './model-editor.js';\n\nexport interface FormFeedback { error?: string; disabled?: boolean }\nexport interface FormDOMBlock<State extends FormFeedback> extends UIBlock<State> {\n field<T extends HTMLElement = HTMLElement>(id: string): T;\n id(localId: string): string;\n}\nfunction formBlock<State extends FormFeedback>(markup: string, className: string, initial: State, prefix = ''): FormDOMBlock<State> & {parts: ReturnType<typeof adoptProductParts>} {\n const element = document.createElement('div');\n element.className = className;\n element.innerHTML = markup; scopeIds(element, prefix);\n const parts = adoptProductParts(element); let destroyed = false;\n const field = <T extends HTMLElement = HTMLElement>(id: string): T => {\n const result = Array.from(element.querySelectorAll<HTMLElement>('[id]')).find((node) => node.getAttribute('id') === prefix + id);\n if (!result) throw new Error(`Unknown component field: ${id}`);\n return result as T;\n };\n const update = (state: Readonly<State>) => {\n if (destroyed) return;\n if (state.error !== undefined) {\n const error = element.querySelector<HTMLElement>('[data-dialog-error]') || element.querySelector<HTMLElement>('.pui-form-error[role=\"alert\"]');\n if (error) parts.feedback(error).update({message:state.error,tone:'error'});\n }\n if (state.disabled !== undefined) {\n for (const control of element.querySelectorAll<HTMLButtonElement>('button[type=\"submit\"]')) {\n parts.action(control).update({disabled:state.disabled,pending:control.dataset.controlPending === 'true'});\n }\n }\n };\n update(initial);\n return {element,field,parts,id:(id) => prefix + id,update,destroy() {if (destroyed) return; destroyed = true; parts.destroy(); element.remove();}};\n}\nexport interface SettingsPanelState extends FormFeedback { baseUrl: string; hasApiKey: boolean; ready?: boolean; testing?: boolean; appearance?: {mode: 'light' | 'dark' | 'system'; disabled?: boolean; error?: string}; testResult?: {message: string; ok?: boolean} }\nexport interface FormOptions { idPrefix?: string }\nexport interface SettingsDraft {provider: string; baseUrl: string; apiKey: string}\nexport interface SettingsProviderOption {id: string; name: string; configured?: boolean; signedIn?: boolean}\nexport interface SettingsCredentialView {status: string; hidden: boolean; required: boolean; placeholder: string; removeVisible: boolean; hint?: string; actions?: Node}\nexport interface SettingsPanel extends FormDOMBlock<SettingsPanelState> {read(): SettingsDraft; setProviders(providers: readonly SettingsProviderOption[], selected?: string): void; resetProvider(value: {provider: string; baseUrl: string; clearKey?: boolean; collapseAdvanced?: boolean}): void; setCredential(view: SettingsCredentialView): void; clearSecrets(): void; readonly updates: HTMLElement}\nexport interface SettingsPanelOptions extends FormOptions {onAppearanceChange?: (mode: string) => void; onProviderChange?: (provider: string) => void; onDraftChange?: (draft: SettingsDraft) => void; onSubmit?: (draft: SettingsDraft) => ActionResult | Promise<ActionResult>; onTest?: (draft: SettingsDraft) => void; onRemoveKey?: (draft: SettingsDraft) => ActionResult | Promise<ActionResult>}\nexport function createSettingsPanel(state: SettingsPanelState, options: SettingsPanelOptions = {}): SettingsPanel {\n const block = formBlock(`\n ${dialogHeading('Settings', 'settings-title', 'settings-dialog', 'MAKE IT YOURS')}\n <section class=\"pui-settings-section pui-appearance-settings\" aria-labelledby=\"appearance-title\">\n <h3 id=\"appearance-title\">Appearance</h3>\n <p class=\"pui-appearance-hint\" id=\"appearance-hint\">A bright white workspace or a calm dark one, both with a blue accent. Follow system matches your computer.</p>\n <label class=\"pui-sr-only\" for=\"appearance-mode\">Appearance</label>\n <select id=\"appearance-mode\" class=\"pui-appearance-select\" aria-describedby=\"appearance-hint\"><option value=\"system\">Follow system</option><option value=\"light\">Light</option><option value=\"dark\">Dark</option></select>\n <div id=\"appearance-error\" class=\"pui-form-error\" role=\"alert\"></div>\n </section>\n <section id=\"update-settings\" class=\"pui-settings-section pui-update-settings\" aria-labelledby=\"update-title\">\n <h3 id=\"update-title\">Updates</h3>\n <div class=\"pui-settings-copy\">\n <p class=\"pui-field-hint\" data-update-version></p>\n <p class=\"pui-field-hint\" role=\"status\" aria-live=\"polite\" data-update-message>Loading update status…</p>\n </div>\n <progress max=\"100\" value=\"0\" aria-label=\"Update progress\" hidden></progress>\n <div class=\"pui-settings-actions\"><button class=\"pui-secondary-button\" type=\"button\" data-update-check disabled>Check for updates</button><button class=\"pui-primary-button\" type=\"button\" data-update-install hidden>Update and restart</button></div>\n </section>\n <form id=\"settings-form\">\n <section class=\"pui-settings-section\" aria-labelledby=\"provider-title\">\n <h3 id=\"provider-title\">Model providers</h3>\n <p class=\"pui-modal-description\">Connect your model providers here. Choose models and thinking effort beside the message box.</p>\n <div class=\"pui-settings-actions\"><button class=\"pui-secondary-button\" type=\"button\" data-sdk=\"custom\">Add independent model connection</button></div>\n <div class=\"pui-settings-field\">\n <label class=\"pui-field-label\" for=\"settings-provider\">Provider</label>\n <select id=\"settings-provider\" class=\"pui-feature-select\" required disabled><option value=\"\">Loading providers…</option></select>\n <div id=\"provider-actions\" hidden></div>\n <p id=\"provider-auth-hint\" class=\"pui-field-hint\" hidden></p>\n </div>\n <details id=\"provider-advanced\" class=\"pui-provider-advanced\">\n <summary>Advanced connection settings</summary>\n <label class=\"pui-field-label\" for=\"base-url\">API base URL</label>\n <div class=\"pui-input-with-icon\">${icon('globe')}<input id=\"base-url\" name=\"baseUrl\" type=\"url\" required value=\"${escape(state.baseUrl)}\" autocomplete=\"off\" /></div>\n <p class=\"pui-field-hint\">The provider’s endpoint is filled in automatically. Change it only for a proxy or custom service.</p>\n </details>\n <div id=\"provider-api-key\" class=\"pui-settings-field\">\n <label class=\"pui-field-label\" for=\"api-key\">API key <span id=\"key-status\" class=\"pui-configured-badge\"></span></label>\n <input id=\"api-key\" name=\"apiKey\" type=\"password\" placeholder=\"${state.hasApiKey ? 'Leave blank to keep your current key' : 'Paste your API key'}\" autocomplete=\"new-password\" ${state.hasApiKey ? '' : 'required'} />\n <p class=\"pui-field-hint\">The saved key is never returned to this page. Model requests go to your configured provider.</p>\n <button class=\"pui-secondary-button pui-destructive-button\" id=\"remove-key\" type=\"button\" hidden>Remove saved API key</button>\n </div>\n </section>\n <section class=\"pui-settings-section pui-connection-test\">\n <p class=\"pui-field-hint\">Uses this provider’s last selected model, or Pith’s default, to check streaming and tool calling. Does not save settings or access files.</p>\n <div class=\"pui-settings-actions\"><button type=\"button\" class=\"pui-secondary-button\" id=\"test-connection\" data-control-pending=\"true\" disabled data-global-idle data-idle-action>Test connection</button></div>\n <div id=\"connection-test-result\" role=\"status\" aria-live=\"polite\"></div>\n </section>\n <div id=\"settings-error\" data-dialog-error class=\"pui-form-error\" role=\"alert\"></div>\n <section class=\"pui-settings-section pui-diagnostics-setting\">\n <p class=\"pui-field-hint\">Version, usage and failure category only; no conversation, file contents, paths or credentials.</p>\n <div class=\"pui-settings-actions\"><button type=\"button\" class=\"pui-secondary-button\" data-action=\"diagnostics\">Save diagnostics</button></div>\n </section>\n <div class=\"pui-modal-footer\"><button class=\"pui-secondary-button\" type=\"button\" data-pui-close data-close=\"settings-dialog\">Cancel</button><button class=\"pui-primary-button\" id=\"save-settings\" data-control-pending=\"true\" disabled data-global-idle type=\"submit\">Save settings</button></div>\n </form>`, 'pui-settings-panel', state, options.idPrefix ?? uniqueId('pui-form') + '-');\n const $ = block.field, abort = new AbortController(); let current = state, pending = false, removing = false, destroyed = false, operationKind: 'submit' | 'remove' = 'submit';\n // These controls also exist before providers or appearance state have loaded.\n // Adopt them eagerly so the first rendered frame uses the shared selector.\n block.parts.control($<HTMLSelectElement>('appearance-mode'));\n block.parts.control($<HTMLSelectElement>('settings-provider'));\n const form = $<HTMLFormElement>('settings-form'), submit = $<HTMLButtonElement>('save-settings'), test = $<HTMLButtonElement>('test-connection'), remove = $<HTMLButtonElement>('remove-key');\n const read = (): SettingsDraft => {const key = $<HTMLInputElement>('api-key'); return {provider:block.parts.control($<HTMLSelectElement>('settings-provider')).getValue(),baseUrl:block.parts.control($<HTMLInputElement>('base-url')).getValue().trim(),apiKey:key.disabled ? '' : block.parts.control(key).getValue().trim()};};\n const update = (next: Readonly<SettingsPanelState>) => {\n if (destroyed) return; current = next; block.update(next);\n block.parts.action(submit).update({disabled:next.disabled,pending:pending || removing || !!next.testing || next.ready !== true});\n block.parts.action(test).update({label:next.testing ? 'Cancel test' : 'Test connection',disabled:!!next.disabled || pending || removing,pending:next.ready !== true});\n block.parts.action(remove).update({disabled:!!next.disabled || pending || !!next.testing || next.ready !== true,pending:removing});\n if (next.appearance) {const appearance = block.parts.control($<HTMLSelectElement>('appearance-mode')); appearance.reset(next.appearance.mode); appearance.update({disabled:!!next.appearance.disabled}); block.parts.feedback($('appearance-error')).update({message:next.appearance.error || '',tone:'error'});}\n if (next.testResult) {const result = $('connection-test-result'); result.textContent = next.testResult.message; result.className = next.testResult.ok === undefined ? '' : next.testResult.ok ? 'pui-test-success' : 'pui-form-error';}\n };\n const operation = createOperation({unavailable:() => !!current.disabled || !!current.testing || current.ready !== true,\n onPending(value) {pending = value && operationKind === 'submit'; removing = value && operationKind === 'remove'; update(current);},\n onError(error) {update({...current,error});}});\n const run = (action: SettingsPanelOptions['onSubmit'], kind: 'submit' | 'remove') => {\n if (!action || operation.pending || current.disabled || current.testing || current.ready !== true) return;\n if (kind === 'submit' && !form.reportValidity()) return;\n operationKind = kind;\n operation.run(() => {update({...current,error:''}); return action(read());}, result => {if (!result.ok) update({...current,error:result.error});});\n };\n form.addEventListener('submit',event => {if (options.onSubmit) {event.preventDefault(); void run(options.onSubmit,'submit');}}, {signal:abort.signal});\n remove.addEventListener('click',() => {void run(options.onRemoveKey,'remove');}, {signal:abort.signal});\n test.addEventListener('click',() => {if (!test.disabled && (current.testing || form.reportValidity())) options.onTest?.(read());}, {signal:abort.signal});\n $<HTMLSelectElement>('appearance-mode').addEventListener('change',() => options.onAppearanceChange?.($<HTMLSelectElement>('appearance-mode').value), {signal:abort.signal});\n $<HTMLSelectElement>('settings-provider').addEventListener('change',() => options.onProviderChange?.(read().provider), {signal:abort.signal});\n form.addEventListener('input',() => options.onDraftChange?.(read()), {signal:abort.signal});\n $<HTMLInputElement>('base-url').addEventListener('invalid',() => {$<HTMLDetailsElement>('provider-advanced').open = true;}, {signal:abort.signal});\n update(state);\n return {...block,read,update,updates:$('update-settings'),\n setProviders(providers, selected) {if (destroyed) return; const select = $<HTMLSelectElement>('settings-provider'),previous = selected ?? select.value; reconcileSelectOptions(select,providers.map(provider=>({value:provider.id,label:`${provider.name}${provider.signedIn ? ' · Signed in' : provider.configured ? ' · Configured' : ''}`})),providers.some(provider=>provider.id === previous) ? previous : providers[0]?.id || ''); block.parts.control(select).update({disabled:!providers.length});},\n resetProvider(value) {if (destroyed) return; operation.invalidate(); update({...current,error:''}); block.parts.control($<HTMLSelectElement>('settings-provider')).reset(value.provider); block.parts.control($<HTMLInputElement>('base-url')).reset(value.baseUrl); if (value.clearKey) block.parts.control($<HTMLInputElement>('api-key')).reset(''); if (value.collapseAdvanced) $<HTMLDetailsElement>('provider-advanced').open = false;},\n setCredential(view) {if (destroyed) return; $('key-status').textContent = view.status; $('provider-api-key').hidden = view.hidden; block.parts.control($<HTMLInputElement>('api-key')).update({disabled:view.hidden,required:view.required,placeholder:view.placeholder}); remove.hidden = !view.removeVisible; $('provider-auth-hint').hidden = !view.hint; $('provider-auth-hint').textContent = view.hint || ''; const actions = $('provider-actions'); actions.hidden = !view.actions; if (view.actions && actions.firstChild !== view.actions) actions.replaceChildren(view.actions); else if (!view.actions) actions.replaceChildren(); block.parts.update();},\n clearSecrets() {block.parts.control($<HTMLInputElement>('api-key')).reset('');},\n destroy() {if (destroyed) return; destroyed = true; operation.destroy(); abort.abort(); $<HTMLInputElement>('api-key').value = ''; block.destroy();}\n };\n}\nexport interface MCPEditorValue {name: string; type: string; url?: string; oauth?: boolean; oauthClientId?: string; oauthScope?: string; command?: string; args?: readonly string[]; enabled?: boolean; hasBearerToken?: boolean; envKeys?: readonly string[]}\nexport interface MCPConnectionDraft {name: string; type: 'http' | 'stdio'; url: string; oauth: boolean; oauthClientId: string; oauthScope: string; command: string; args: string; enabled: boolean; bearerToken: string; clearBearerToken: boolean; env: string; clearEnv: boolean}\nexport interface MCPConnectionsState extends FormFeedback {formError?: string}\nexport interface MCPConnectionsPanel extends FormDOMBlock<MCPConnectionsState> {renderType(): void; edit(value?: MCPEditorValue): void; read(): MCPConnectionDraft; clearBearerToken(): void; clearSecrets(): void; toggleEnvironment(): void; readonly list: HTMLElement}\nexport function createMCPConnectionsPanel(state: MCPConnectionsState = {}, options: FormOptions & {onSubmit?: (draft: MCPConnectionDraft) => ActionResult | Promise<ActionResult>} = {}): MCPConnectionsPanel {\n const block = formBlock(`${dialogHeading('Connections', 'connections-title', 'connections-dialog', 'EXTERNAL TOOLS')}<p class=\"pui-modal-description\">Add an MCP server to give Pith access to its tools. Enabled connections connect automatically when a task starts. Disable a connection to stop using it in tasks. External tools require approval unless this conversation has full access.</p><div class=\"pui-feature-toolbar\"><button type=\"button\" class=\"pui-secondary-button\" data-action=\"refresh-mcp\">Refresh</button></div><div id=\"mcp-list\"><p class=\"pui-feature-hint\">Loading connections…</p></div><div id=\"mcp-error\" data-dialog-error class=\"pui-form-error\" role=\"alert\"></div><section class=\"pui-connection-editor\"><div class=\"pui-section-heading\"><span id=\"mcp-form-title\">Add connection</span><button type=\"button\" class=\"pui-secondary-button\" data-action=\"new-mcp\">New connection</button></div><form id=\"mcp-form\"><label class=\"pui-field-label\" for=\"mcp-name\">Name</label><input id=\"mcp-name\" name=\"name\" required autocomplete=\"off\" placeholder=\"my-tools\" /><label class=\"pui-field-label\" for=\"mcp-type\">Connection type</label><select id=\"mcp-type\" name=\"type\" class=\"pui-feature-select\"><option value=\"http\">HTTP</option><option value=\"stdio\">Local command (stdio)</option></select><div id=\"mcp-http-fields\"><label class=\"pui-field-label\" for=\"mcp-url\">Server URL</label><input id=\"mcp-url\" name=\"url\" type=\"url\" placeholder=\"https://example.com/mcp\" autocomplete=\"off\" /><label class=\"pui-checkbox-field\"><input id=\"mcp-oauth\" type=\"checkbox\" />Sign in with OAuth</label><details class=\"pui-provider-advanced\"><summary>OAuth settings (optional)</summary><label class=\"pui-field-label\">Registered client ID<input id=\"mcp-oauth-client\" /></label><label class=\"pui-field-label\">Scopes<input id=\"mcp-oauth-scope\" /></label><p class=\"pui-field-hint\">Uses the server’s OAuth discovery and PKCE. The temporary callback listens on 127.0.0.1:54819.</p></details><label class=\"pui-field-label\" for=\"mcp-token\">Bearer token (optional)</label><input id=\"mcp-token\" name=\"bearerToken\" type=\"password\" autocomplete=\"new-password\" placeholder=\"Optional token\" /><label class=\"pui-checkbox-field\" id=\"mcp-clear-token-row\" hidden><input id=\"mcp-clear-token\" type=\"checkbox\" />Remove saved bearer token</label><p class=\"pui-field-hint\">Saved tokens are never returned to this page. Leave this field blank to keep an existing token.</p></div><div id=\"mcp-stdio-fields\" hidden><label class=\"pui-field-label\" for=\"mcp-command\">Installed executable</label><input id=\"mcp-command\" name=\"command\" placeholder=\"/path/to/mcp-server\" autocomplete=\"off\" /><label class=\"pui-field-label\" for=\"mcp-args\">Arguments (JSON array)</label><textarea id=\"mcp-args\" name=\"args\" rows=\"3\" spellcheck=\"false\">[]</textarea><p class=\"pui-field-hint\">The executable and any runtime it needs must already be installed on your computer. Pith Desk does not bundle external runtimes or a marketplace.</p><div class=\"pui-secret-label\"><label class=\"pui-field-label\" for=\"mcp-env\">Environment overrides (JSON object, optional)</label><button class=\"pui-secondary-button\" type=\"button\" id=\"mcp-env-visibility\" data-action=\"toggle-env\" aria-controls=\"mcp-env\" aria-pressed=\"false\">Show</button></div><textarea id=\"mcp-env\" class=\"pui-secret-field\" name=\"env\" rows=\"3\" spellcheck=\"false\" autocomplete=\"off\" aria-describedby=\"mcp-env-hint\" placeholder='{\"API_KEY\":\"…\"}'></textarea><p id=\"mcp-env-hint\" class=\"pui-field-hint\">Values stay private. Leave blank to keep saved overrides. Add a JSON object of string keys and values to set or replace individual overrides.</p><p id=\"mcp-env-keys\" class=\"pui-field-hint\" hidden></p><label class=\"pui-checkbox-field\" id=\"mcp-clear-env-row\" hidden><input id=\"mcp-clear-env\" type=\"checkbox\" />Clear saved environment overrides</label></div><label class=\"pui-checkbox-field\"><input id=\"mcp-enabled\" name=\"enabled\" type=\"checkbox\" checked />Enable this connection</label><div id=\"mcp-form-error\" class=\"pui-form-error\" role=\"alert\"></div><div class=\"pui-modal-footer\"><button class=\"pui-secondary-button\" type=\"button\" data-pui-close data-close=\"connections-dialog\">Close</button><button class=\"pui-primary-button\" type=\"submit\" data-idle-action data-global-idle>Save connection</button></div></form></section>`, 'pui-mcp-connections', state, options.idPrefix ?? uniqueId('pui-form') + '-');\n const $ = block.field; const abort = new AbortController(); let disposed = false, pending = false, current: MCPConnectionsState = state;\n const form = $<HTMLFormElement>('mcp-form'), submit = form.querySelector<HTMLButtonElement>('button[type=\"submit\"]')!;\n const control = (id:string) => block.parts.control($<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>(id));\n const read = (): MCPConnectionDraft => ({name:control('mcp-name').getValue().trim(),type:control('mcp-type').getValue() === 'stdio' ? 'stdio' : 'http',url:control('mcp-url').getValue().trim(),oauth:control('mcp-oauth').getChecked(),oauthClientId:control('mcp-oauth-client').getValue().trim(),oauthScope:control('mcp-oauth-scope').getValue().trim(),command:control('mcp-command').getValue().trim(),args:control('mcp-args').getValue(),enabled:control('mcp-enabled').getChecked(),bearerToken:control('mcp-token').getValue().trim(),clearBearerToken:control('mcp-clear-token').getChecked(),env:control('mcp-env').getValue(),clearEnv:control('mcp-clear-env').getChecked()});\n const update = (next: Readonly<MCPConnectionsState>) => {if (disposed) return; current = next; block.update(next); if (next.formError !== undefined) block.parts.feedback($('mcp-form-error')).update({message:next.formError,tone:'error'}); block.parts.action(submit).update({disabled:next.disabled,pending});};\n const renderType = () => {if (disposed) return; const http = control('mcp-type').getValue() === 'http'; for (const [id,active] of [['mcp-http-fields',http],['mcp-stdio-fields',!http]] as const) {const group = $(id); group.hidden = !active; for (const field of group.querySelectorAll<HTMLInputElement | HTMLTextAreaElement>('input,textarea')) block.parts.control(field).update({disabled:!active});} control('mcp-url').update({required:http}); control('mcp-command').update({required:!http});};\n const edit = (entry?: MCPEditorValue) => {\n if (disposed) return;\n submission.invalidate();\n $<HTMLFormElement>('mcp-form').reset();\n $<HTMLTextAreaElement>('mcp-env').classList.remove('pui-revealed');\n $('mcp-env-visibility').setAttribute('aria-pressed', 'false'); $('mcp-env-visibility').textContent = 'Show';\n $('mcp-form-title').textContent = entry ? `Edit ${entry.name}` : 'Add connection';\n control('mcp-name').reset(entry?.name || ''); control('mcp-name').update({readOnly:!!entry});\n control('mcp-type').reset(entry?.type || 'http'); control('mcp-url').reset(entry?.url || '');\n control('mcp-oauth').reset(entry?.oauth || false); control('mcp-oauth-client').reset(entry?.oauthClientId || ''); control('mcp-oauth-scope').reset(entry?.oauthScope || '');\n control('mcp-command').reset(entry?.command || ''); control('mcp-args').reset(JSON.stringify(entry?.args || [],null,2));\n control('mcp-enabled').reset(entry?.enabled ?? true);\n control('mcp-token').update({placeholder:entry?.hasBearerToken ? 'Leave blank to keep your saved token' : 'Optional token'});\n $('mcp-clear-token-row').hidden = !entry?.hasBearerToken; const envKeys = entry?.envKeys || [];\n $('mcp-clear-env-row').hidden = !envKeys.length; $('mcp-env-keys').hidden = !envKeys.length; $('mcp-env-keys').textContent = `Saved environment keys: ${envKeys.join(', ')}`;\n $('mcp-form-error').textContent = ''; current = {...current,formError:''}; update(current); renderType(); $<HTMLInputElement>(entry ? entry.type === 'stdio' ? 'mcp-command' : 'mcp-url' : 'mcp-name').focus();\n };\n $<HTMLSelectElement>('mcp-type').addEventListener('change', renderType, {signal:abort.signal});\n const toggleEnvironment = () => {if (disposed) return; const field = $<HTMLTextAreaElement>('mcp-env'); const revealed = field.classList.toggle('pui-revealed'); const button = $('mcp-env-visibility'); button.setAttribute('aria-pressed',String(revealed)); block.parts.action(button as HTMLButtonElement).update({label:revealed ? 'Hide' : 'Show'});};\n $('mcp-env-visibility').addEventListener('click',event => {event.stopPropagation(); toggleEnvironment();}, {signal:abort.signal});\n const submission = bindFormSubmission(form,{read,unavailable:()=>!!current.disabled,onSubmit:options.onSubmit,onPending(value) {pending = value; update(current);},onError(formError) {update({...current,formError});}});\n const clearBearerToken = () => {control('mcp-token').reset('');};\n const clearSecrets = () => {clearBearerToken(); control('mcp-env').reset('');};\n renderType(); update(state);\n return {...block,update,renderType,edit,read,clearBearerToken,clearSecrets,toggleEnvironment,list:$('mcp-list'),destroy() {if (disposed) return; disposed = true; submission.destroy(); abort.abort(); clearSecrets(); block.destroy();}};\n}\nexport interface ModelPickerState extends FormFeedback {editor?: ModelEditorState; loading?: boolean}\nexport interface ModelPicker extends FormDOMBlock<ModelPickerState> {read(): ModelSelection; reset(selection: ModelSelection): void; focus(): void}\nexport function createModelPicker(state: ModelPickerState = {}, options: FormOptions & {onSubmit?: (selection: ModelSelection) => ActionResult | Promise<ActionResult>} = {}): ModelPicker {\n const prefix = options.idPrefix ?? uniqueId('pui-form') + '-';\n const block = formBlock(`${dialogHeading('Choose a model', 'model-title', 'model-dialog', 'PITH MODEL CATALOG')}<form id=\"model-form\">${modelEditorMarkup('picker')}<div id=\"model-error\" class=\"pui-form-error\" role=\"alert\"></div><div class=\"pui-modal-footer\"><button type=\"button\" class=\"pui-secondary-button\" data-pui-close data-close=\"model-dialog\">Cancel</button><button type=\"submit\" class=\"pui-primary-button\" id=\"choose-model\" data-global-idle data-control-pending=\"true\" disabled>Use model</button></div></form>`, 'pui-model-picker', state, prefix);\n let editor: ReturnType<typeof createModelEditor> | undefined;\n let destroyed = false, pending = false, current = state;\n const form = block.field<HTMLFormElement>('model-form'), submit = block.field<HTMLButtonElement>('choose-model');\n const update = (next: Readonly<ModelPickerState>) => {if (destroyed) return; current = next; block.update(next); if (next.editor) {if (editor) editor.update(next.editor); else editor = createModelEditor(next.editor,{prefix:prefix + 'picker',element:block.element});} const loading = next.loading ?? !next.editor; block.parts.action(submit).update({disabled:next.disabled,pending:pending || loading});};\n const read = (): ModelSelection => editor?.read() || {provider:'',model:'',thinkingLevel:''};\n const submission = bindFormSubmission(form,{read,unavailable:()=>submit.disabled,onSubmit:options.onSubmit,onPending(value) {pending = value; update(current);},onError(error) {update({...current,error});}});\n update(state); return {...block,update,read,reset(selection) {submission.invalidate(); editor?.reset(selection);},focus() {editor?.focus();},destroy() {if (destroyed) return; destroyed = true; submission.destroy(); editor?.destroy(); block.destroy();}};\n}\nexport interface MCPConnectionItem {\n name: string; type: string; url?: string; command?: string; args?: readonly string[]; enabled: boolean;\n hasBearerToken?: boolean; status?: string; statusLabel: string; envKeys?: readonly string[]; error?: string; oauth?: boolean; signedIn?: boolean;\n}\nexport interface MCPConnectionListState extends FormFeedback { entries: readonly MCPConnectionItem[] }\nexport type MCPConnectionAction = 'mcp-login' | 'mcp-logout' | 'mcp-edit' | 'mcp-toggle' | 'mcp-remove';\nexport interface MCPConnectionTarget {readonly name: string}\nexport interface MCPConnectionListOptions {onAction?: (action: MCPConnectionAction, target: MCPConnectionTarget) => ReturnType<UIAction>}\ntype MCPConnectionDOM = {element: HTMLElement; name: HTMLElement; address: HTMLElement; enabled: HTMLElement; status: HTMLElement; env: HTMLElement; error: HTMLElement; actions: HTMLElement; signIn: HTMLButtonElement; signOut: HTMLButtonElement; edit: HTMLButtonElement; toggle: HTMLButtonElement; remove: HTMLButtonElement; handles: Map<HTMLButtonElement,ActionController>; abort: AbortController; localError: string};\nexport function createMCPConnectionList(initial: MCPConnectionListState, options: MCPConnectionListOptions = {}): UIBlock<MCPConnectionListState> {\n const element = document.createElement('div'); element.className = 'pui-mcp-connection-list';\n const parts = adoptProductParts(element); let destroyed = false; const entries = new Map<string, MCPConnectionDOM>();\n const empty = document.createElement('p'); empty.className = 'pui-feature-hint'; empty.textContent = 'No connections yet. Add an HTTP server or an installed local MCP command below. Tools are discovered on demand using tool search and Codemode.';\n function createEntry(item: MCPConnectionItem): MCPConnectionDOM {\n const root = document.createElement('article'); root.className = 'pui-connection-card';\n root.innerHTML = '<div class=\"pui-connection-card-heading\"><strong></strong></div><p class=\"pui-file-path\"></p><p class=\"pui-feature-hint\"></p><p class=\"pui-connection-status\" role=\"status\"></p><p class=\"pui-feature-hint\" hidden></p><p class=\"pui-form-error\"></p><div class=\"pui-file-actions\"></div>';\n const paragraphs = root.querySelectorAll<HTMLElement>('p'); const actions = root.querySelector<HTMLElement>('.pui-file-actions')!;\n const button = (label: string, destructive = false) => {const node = document.createElement('button'); node.type = 'button'; node.className = destructive ? 'pui-secondary-button pui-destructive-button' : 'pui-secondary-button'; node.textContent = label; return node;};\n const signIn = button('Sign in'); signIn.dataset.sdk = 'mcp-login'; const signOut = button('Sign out'); signOut.dataset.sdk = 'mcp-logout';\n const edit = button('Edit'); const toggle = button('Disable'); const remove = button('Delete',true);\n for (const node of [toggle,remove]) {node.dataset.globalIdle = ''; node.dataset.idleAction = '';}\n actions.append(edit,toggle,remove);\n const entry: MCPConnectionDOM = {element:root,name:root.querySelector('strong')!,address:paragraphs[0],enabled:paragraphs[1],status:paragraphs[2],env:paragraphs[3],error:paragraphs[4],actions,signIn,signOut,edit,toggle,remove,handles:new Map(),abort:new AbortController(),localError:''};\n const target = Object.freeze({name:item.name});\n for (const [node,action] of [[signIn,'mcp-login'],[signOut,'mcp-logout'],[edit,'mcp-edit'],[toggle,'mcp-toggle'],[remove,'mcp-remove']] as const) {\n if (options.onAction) node.addEventListener('click',event => event.stopPropagation(),{signal:entry.abort.signal});\n entry.handles.set(node,adoptAction(node,{onAction:options.onAction ? () => {entry.localError = ''; parts.feedback(entry.error).update({message:'',tone:'error'}); return options.onAction!(action,target);} : undefined,onError(message) {entry.localError = message; parts.feedback(entry.error).update({message,tone:'error'});}}));\n }\n return entry;\n }\n const release = (entry: MCPConnectionDOM) => {entry.abort.abort(); for (const handle of entry.handles.values()) handle.destroy();};\n const update = (state: Readonly<MCPConnectionListState>) => {\n if (destroyed) return;\n reconcileKeyed(element,entries,state.entries,{key:item=>item.name,element:entry=>entry.element,create:createEntry,update(entry,item) {\n setText(entry.name, item.name); entry.element.dataset.connectionKey = item.name;\n setText(entry.address, item.type === 'http' ? item.url || '' : [item.command,...(item.args || [])].join(' '));\n setText(entry.enabled, `${item.enabled ? 'Enabled' : 'Disabled'}${item.hasBearerToken ? ' · Token configured' : ''}`);\n setText(entry.status, item.statusLabel); entry.status.classList.toggle('pui-is-error',item.enabled && item.status === 'error');\n entry.env.hidden = !item.envKeys?.length; setText(entry.env, item.envKeys?.length ? 'Saved environment keys: '+item.envKeys.join(', ') : ''); parts.feedback(entry.error).update({message:item.error || entry.localError,tone:'error'});\n setText(entry.signIn, item.signedIn ? 'Sign in again' : 'Sign in'); entry.signIn.dataset.id = entry.signOut.dataset.id = item.name;\n entry.edit.dataset.mcpEdit = item.name; entry.toggle.dataset.mcpToggle = item.name; entry.remove.dataset.mcpRemove = item.name; setText(entry.toggle, item.enabled ? 'Disable' : 'Enable');\n if (item.oauth) {if (entry.signIn.parentElement !== entry.actions) entry.actions.insertBefore(entry.signIn,entry.edit);} else entry.signIn.remove();\n if (item.oauth && item.signedIn) {if (entry.signOut.parentElement !== entry.actions) entry.actions.insertBefore(entry.signOut,entry.edit);} else entry.signOut.remove();\n for (const [button,handle] of entry.handles) handle.update({disabled:!!state.disabled || (button === entry.signIn && !item.oauth) || (button === entry.signOut && (!item.oauth || !item.signedIn))});\n },destroy:release});\n if (!state.entries.length) {if (empty.parentElement !== element) element.append(empty);} else empty.remove(); parts.update();\n };\n update(initial); return {element,update,destroy() {if (destroyed) return; destroyed = true; for (const entry of entries.values()) release(entry); parts.destroy(); entries.clear(); element.remove();}};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"provider-login.d.ts","sourceRoot":"","sources":["../../src/forms/provider-login.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,YAAY,EAAE,KAAK,OAAO,EAAC,MAAM,YAAY,CAAC;AAEvE,MAAM,WAAW,kBAAkB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAC;AACpO,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,GAAE;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,YAAY,GAAG,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4CpQ"}
1
+ {"version":3,"file":"provider-login.d.ts","sourceRoot":"","sources":["../../src/forms/provider-login.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,KAAK,YAAY,EAAE,KAAK,OAAO,EAAC,MAAM,YAAY,CAAC;AAK3D,MAAM,WAAW,kBAAkB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAC;AACpO,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,GAAE;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,YAAY,GAAG,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4CpQ"}
@@ -1,18 +1,21 @@
1
1
  import { scopeIds, localField } from './identity.js';
2
- import { Generation } from '../core.js';
2
+ import {} from '../core.js';
3
3
  import { uniqueId } from '../dom.js';
4
+ import { adoptProductParts } from '../foundations.js';
5
+ import { createOperation } from '../operation.js';
6
+ import { bindContentClose } from '../surface.js';
4
7
  export function createProviderLoginPanel(initial, options = {}) {
5
8
  const element = document.createElement('div');
6
9
  element.className = 'pui-provider-login';
7
10
  const prefix = options.idPrefix ?? uniqueId('pui-login') + '-';
8
- element.innerHTML = `<p class="pui-provider-login-status" role="status"></p><p data-login-link hidden><a target="_blank" rel="noopener noreferrer">Open sign-in page in your browser ↗</a></p><p data-login-code hidden>Verification code: <strong></strong></p><form id="oauth-answer" hidden><label class="pui-field-label" for="oauth-value"></label><span data-login-input></span><button type="submit" class="pui-primary-button">Continue</button></form><div id="oauth-error" class="pui-form-error" role="alert"></div><div class="pui-modal-footer"><button type="button" class="pui-secondary-button" data-close="oauth-dialog" hidden>Close</button><button type="button" class="pui-secondary-button" data-sdk="cancel-login">Cancel sign-in</button></div>`;
11
+ element.innerHTML = `<p class="pui-provider-login-status" role="status"></p><p data-login-link hidden><a target="_blank" rel="noopener noreferrer">Open sign-in page in your browser ↗</a></p><p data-login-code hidden>Verification code: <strong></strong></p><form id="oauth-answer" hidden><label class="pui-field-label" for="oauth-value"></label><span data-login-input></span><button type="submit" class="pui-primary-button">Continue</button></form><div id="oauth-error" class="pui-form-error" role="alert"></div><div class="pui-modal-footer"><button type="button" class="pui-secondary-button" data-pui-close data-close="oauth-dialog" hidden>Close</button><button type="button" class="pui-secondary-button" data-sdk="cancel-login">Cancel sign-in</button></div>`;
9
12
  scopeIds(element, prefix);
10
13
  const field = (id) => localField(element, prefix + id);
11
14
  const form = field('oauth-answer'), status = element.querySelector('.pui-provider-login-status'), inputHost = element.querySelector('[data-login-input]'), submit = form.querySelector('button');
12
15
  const link = element.querySelector('a'), code = element.querySelector('[data-login-code]'), error = field('oauth-error');
13
- const generation = new Generation(), abort = new AbortController();
16
+ const abort = new AbortController(), parts = adoptProductParts(element);
14
17
  let signature = '', destroyed = false, pending = false, localError = '', state = initial;
15
- function renderDisabled() { submit.disabled = !!state.disabled || pending; }
18
+ function renderDisabled() { parts.action(submit).update({ disabled: state.disabled, pending }); }
16
19
  const update = (login) => {
17
20
  if (destroyed)
18
21
  return;
@@ -20,8 +23,7 @@ export function createProviderLoginPanel(initial, options = {}) {
20
23
  const next = JSON.stringify([login.phase, login.prompt, login.promptType, login.options]);
21
24
  if (next !== signature) {
22
25
  signature = next;
23
- generation.invalidate();
24
- pending = false;
26
+ operation.invalidate();
25
27
  localError = '';
26
28
  inputHost.replaceChildren();
27
29
  if (login.phase === 'prompt') {
@@ -44,9 +46,8 @@ export function createProviderLoginPanel(initial, options = {}) {
44
46
  inputHost.append(input);
45
47
  }
46
48
  }
47
- status.textContent = login.message;
49
+ parts.feedback(status).update({ message: login.message, tone: login.phase === 'error' ? 'error' : 'info' });
48
50
  status.classList.toggle('pui-form-error', login.phase === 'error');
49
- status.setAttribute('role', login.phase === 'error' ? 'alert' : 'status');
50
51
  let href = '';
51
52
  try {
52
53
  const url = new URL(login.url || '');
@@ -63,52 +64,37 @@ export function createProviderLoginPanel(initial, options = {}) {
63
64
  code.querySelector('strong').textContent = login.code || '';
64
65
  form.hidden = login.phase !== 'prompt';
65
66
  form.querySelector('label').textContent = login.prompt || '';
66
- error.textContent = login.error || localError;
67
+ const promptInput = inputHost.querySelector('input, select');
68
+ if (promptInput)
69
+ parts.control(promptInput);
70
+ parts.update();
71
+ parts.feedback(error).update({ message: login.error || localError, tone: 'error' });
67
72
  const complete = ['complete', 'error'].includes(login.phase);
68
73
  element.querySelector('[data-close]').hidden = !complete;
69
74
  element.querySelector('[data-sdk]').hidden = complete;
70
75
  renderDisabled();
71
76
  };
72
- element.addEventListener('submit', async (event) => {
77
+ const operation = createOperation({ unavailable: () => !!state.disabled || state.phase !== 'prompt', onPending(value) { pending = value; renderDisabled(); }, onError(message) { localError = message; parts.feedback(error).update({ message, tone: 'error' }); } });
78
+ element.addEventListener('submit', event => {
73
79
  event.preventDefault();
74
- if (pending || state.disabled || state.phase !== 'prompt' || !options.onAnswer)
80
+ if (operation.pending || state.disabled || state.phase !== 'prompt' || !options.onAnswer)
75
81
  return;
76
82
  const input = field('oauth-value');
77
83
  if (!input.checkValidity()) {
78
84
  input.reportValidity();
79
85
  return;
80
86
  }
81
- const seq = generation.next();
82
- pending = true;
83
- localError = '';
84
- error.textContent = '';
85
- renderDisabled();
86
- try {
87
- const result = await options.onAnswer(input.value);
88
- if (generation.current(seq) && result && !result.ok) {
89
- localError = result.error;
90
- error.textContent = localError;
91
- }
92
- }
93
- catch (reason) {
94
- if (generation.current(seq)) {
95
- localError = reason instanceof Error ? reason.message : String(reason);
96
- error.textContent = localError;
97
- }
98
- }
99
- finally {
100
- if (generation.current(seq)) {
101
- pending = false;
102
- renderDisabled();
103
- }
104
- }
87
+ operation.run(() => { localError = ''; parts.feedback(error).update({ message: '', tone: 'error' }); return options.onAnswer(parts.control(input).getValue()); }, result => { if (result && !result.ok) {
88
+ localError = result.error;
89
+ parts.feedback(error).update({ message: localError, tone: 'error' });
90
+ } });
105
91
  }, { signal: abort.signal });
92
+ const close = bindContentClose(element, { dialogId: prefix + 'oauth-dialog', onClose: options.onClose });
106
93
  element.addEventListener('click', event => { const target = event.target.closest('button'); if (target?.dataset.sdk === 'cancel-login')
107
- options.onCancel?.(); if (target?.dataset.close === prefix + 'oauth-dialog')
108
- options.onClose?.(); }, { signal: abort.signal });
94
+ options.onCancel?.(); }, { signal: abort.signal });
109
95
  update(initial);
110
96
  return { element, update, destroy() { if (destroyed)
111
- return; destroyed = true; generation.destroy(); abort.abort(); for (const input of element.querySelectorAll('input'))
112
- input.value = ''; element.remove(); } };
97
+ return; destroyed = true; operation.destroy(); close.destroy(); abort.abort(); for (const input of element.querySelectorAll('input'))
98
+ parts.control(input).reset(''); parts.destroy(); element.remove(); } };
113
99
  }
114
100
  //# sourceMappingURL=provider-login.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider-login.js","sourceRoot":"","sources":["../../src/forms/provider-login.ts"],"names":[],"mappings":"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","sourcesContent":["import {scopeIds, localField} from './identity.js';\nimport {Generation, type ActionResult, type UIBlock} from '../core.js';\nimport {uniqueId} from '../dom.js';\nexport interface ProviderLoginState {phase: string; message: string; url?: string; code?: string; prompt?: string; promptType?: string; options?: readonly {id: string; label: string}[] | null; error?: string; disabled?: boolean}\nexport function createProviderLoginPanel(initial: ProviderLoginState, options: {idPrefix?: string; onAnswer?: (answer: string) => void | ActionResult | Promise<void | ActionResult>; onCancel?: () => void; onClose?: () => void} = {}): UIBlock<ProviderLoginState> {\n const element = document.createElement('div'); element.className = 'pui-provider-login'; const prefix = options.idPrefix ?? uniqueId('pui-login') + '-';\n element.innerHTML = `<p class=\"pui-provider-login-status\" role=\"status\"></p><p data-login-link hidden><a target=\"_blank\" rel=\"noopener noreferrer\">Open sign-in page in your browser ↗</a></p><p data-login-code hidden>Verification code: <strong></strong></p><form id=\"oauth-answer\" hidden><label class=\"pui-field-label\" for=\"oauth-value\"></label><span data-login-input></span><button type=\"submit\" class=\"pui-primary-button\">Continue</button></form><div id=\"oauth-error\" class=\"pui-form-error\" role=\"alert\"></div><div class=\"pui-modal-footer\"><button type=\"button\" class=\"pui-secondary-button\" data-close=\"oauth-dialog\" hidden>Close</button><button type=\"button\" class=\"pui-secondary-button\" data-sdk=\"cancel-login\">Cancel sign-in</button></div>`;\n scopeIds(element, prefix);\n const field = <T extends HTMLElement = HTMLElement>(id: string): T => localField<T>(element, prefix + id);\n const form = field<HTMLFormElement>('oauth-answer'), status = element.querySelector<HTMLElement>('.pui-provider-login-status')!, inputHost = element.querySelector<HTMLElement>('[data-login-input]')!, submit = form.querySelector<HTMLButtonElement>('button')!;\n const link = element.querySelector<HTMLAnchorElement>('a')!, code = element.querySelector<HTMLElement>('[data-login-code]')!, error = field('oauth-error');\n const generation = new Generation(), abort = new AbortController();\n let signature = '', destroyed = false, pending = false, localError = '', state: Readonly<ProviderLoginState> = initial;\n function renderDisabled(): void { submit.disabled = !!state.disabled || pending; }\n const update = (login: Readonly<ProviderLoginState>) => {\n if (destroyed) return; state = login;\n const next = JSON.stringify([login.phase, login.prompt, login.promptType, login.options]);\n if (next !== signature) {\n signature = next; generation.invalidate(); pending = false; localError = '';\n inputHost.replaceChildren();\n if (login.phase === 'prompt') {\n const input = document.createElement(login.options?.length ? 'select' : 'input'); input.id = prefix + 'oauth-value';\n if (input instanceof HTMLInputElement) { input.type = login.promptType === 'secret' ? 'password' : 'text'; input.required = true; input.autocomplete = 'off'; }\n else { input.className = 'pui-feature-select'; for (const item of login.options || []) { const option = document.createElement('option'); option.value = item.id; option.textContent = item.label; input.append(option); } }\n inputHost.append(input);\n }\n }\n status.textContent = login.message; status.classList.toggle('pui-form-error', login.phase === 'error'); status.setAttribute('role', login.phase === 'error' ? 'alert' : 'status');\n let href = ''; try {const url = new URL(login.url || ''); if (url.protocol === 'https:' || url.protocol === 'http:') href = url.href;} catch {}\n link.parentElement!.hidden = !href; if (href) link.href = href; else link.removeAttribute('href');\n code.hidden = !login.code; code.querySelector('strong')!.textContent = login.code || '';\n form.hidden = login.phase !== 'prompt'; form.querySelector('label')!.textContent = login.prompt || '';\n error.textContent = login.error || localError;\n const complete = ['complete','error'].includes(login.phase);\n element.querySelector<HTMLButtonElement>('[data-close]')!.hidden = !complete;\n element.querySelector<HTMLButtonElement>('[data-sdk]')!.hidden = complete;\n renderDisabled();\n };\n element.addEventListener('submit', async event => {\n event.preventDefault(); if (pending || state.disabled || state.phase !== 'prompt' || !options.onAnswer) return;\n const input = field<HTMLInputElement | HTMLSelectElement>('oauth-value'); if (!input.checkValidity()) {input.reportValidity(); return;}\n const seq = generation.next(); pending = true; localError = ''; error.textContent = ''; renderDisabled();\n try { const result = await options.onAnswer(input.value); if (generation.current(seq) && result && !result.ok) {localError = result.error; error.textContent = localError;} }\n catch (reason) {if (generation.current(seq)) {localError = reason instanceof Error ? reason.message : String(reason); error.textContent = localError;}}\n finally {if (generation.current(seq)) {pending = false; renderDisabled();}}\n }, {signal:abort.signal});\n element.addEventListener('click', event => {const target = (event.target as HTMLElement).closest<HTMLButtonElement>('button'); if (target?.dataset.sdk === 'cancel-login') options.onCancel?.(); if (target?.dataset.close === prefix + 'oauth-dialog') options.onClose?.();}, {signal:abort.signal});\n update(initial); return {element, update, destroy() {if (destroyed) return; destroyed = true; generation.destroy(); abort.abort(); for (const input of element.querySelectorAll<HTMLInputElement>('input')) input.value = ''; element.remove();}};\n}\n"]}
1
+ {"version":3,"file":"provider-login.js","sourceRoot":"","sources":["../../src/forms/provider-login.ts"],"names":[],"mappings":"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","sourcesContent":["import {scopeIds, localField} from './identity.js';\nimport {type ActionResult, type UIBlock} from '../core.js';\nimport {uniqueId} from '../dom.js';\nimport {adoptProductParts} from '../foundations.js';\nimport {createOperation} from '../operation.js';\nimport {bindContentClose} from '../surface.js';\nexport interface ProviderLoginState {phase: string; message: string; url?: string; code?: string; prompt?: string; promptType?: string; options?: readonly {id: string; label: string}[] | null; error?: string; disabled?: boolean}\nexport function createProviderLoginPanel(initial: ProviderLoginState, options: {idPrefix?: string; onAnswer?: (answer: string) => void | ActionResult | Promise<void | ActionResult>; onCancel?: () => void; onClose?: () => void} = {}): UIBlock<ProviderLoginState> {\n const element = document.createElement('div'); element.className = 'pui-provider-login'; const prefix = options.idPrefix ?? uniqueId('pui-login') + '-';\n element.innerHTML = `<p class=\"pui-provider-login-status\" role=\"status\"></p><p data-login-link hidden><a target=\"_blank\" rel=\"noopener noreferrer\">Open sign-in page in your browser ↗</a></p><p data-login-code hidden>Verification code: <strong></strong></p><form id=\"oauth-answer\" hidden><label class=\"pui-field-label\" for=\"oauth-value\"></label><span data-login-input></span><button type=\"submit\" class=\"pui-primary-button\">Continue</button></form><div id=\"oauth-error\" class=\"pui-form-error\" role=\"alert\"></div><div class=\"pui-modal-footer\"><button type=\"button\" class=\"pui-secondary-button\" data-pui-close data-close=\"oauth-dialog\" hidden>Close</button><button type=\"button\" class=\"pui-secondary-button\" data-sdk=\"cancel-login\">Cancel sign-in</button></div>`;\n scopeIds(element, prefix);\n const field = <T extends HTMLElement = HTMLElement>(id: string): T => localField<T>(element, prefix + id);\n const form = field<HTMLFormElement>('oauth-answer'), status = element.querySelector<HTMLElement>('.pui-provider-login-status')!, inputHost = element.querySelector<HTMLElement>('[data-login-input]')!, submit = form.querySelector<HTMLButtonElement>('button')!;\n const link = element.querySelector<HTMLAnchorElement>('a')!, code = element.querySelector<HTMLElement>('[data-login-code]')!, error = field('oauth-error');\n const abort = new AbortController(), parts = adoptProductParts(element);\n let signature = '', destroyed = false, pending = false, localError = '', state: Readonly<ProviderLoginState> = initial;\n function renderDisabled(): void {parts.action(submit).update({disabled:state.disabled,pending});}\n const update = (login: Readonly<ProviderLoginState>) => {\n if (destroyed) return; state = login;\n const next = JSON.stringify([login.phase, login.prompt, login.promptType, login.options]);\n if (next !== signature) {\n signature = next; operation.invalidate(); localError = '';\n inputHost.replaceChildren();\n if (login.phase === 'prompt') {\n const input = document.createElement(login.options?.length ? 'select' : 'input'); input.id = prefix + 'oauth-value';\n if (input instanceof HTMLInputElement) { input.type = login.promptType === 'secret' ? 'password' : 'text'; input.required = true; input.autocomplete = 'off'; }\n else { input.className = 'pui-feature-select'; for (const item of login.options || []) { const option = document.createElement('option'); option.value = item.id; option.textContent = item.label; input.append(option); } }\n inputHost.append(input);\n }\n }\n parts.feedback(status).update({message:login.message,tone:login.phase === 'error' ? 'error' : 'info'}); status.classList.toggle('pui-form-error', login.phase === 'error');\n let href = ''; try {const url = new URL(login.url || ''); if (url.protocol === 'https:' || url.protocol === 'http:') href = url.href;} catch {}\n link.parentElement!.hidden = !href; if (href) link.href = href; else link.removeAttribute('href');\n code.hidden = !login.code; code.querySelector('strong')!.textContent = login.code || '';\n form.hidden = login.phase !== 'prompt'; form.querySelector('label')!.textContent = login.prompt || '';\n const promptInput = inputHost.querySelector<HTMLInputElement | HTMLSelectElement>('input, select'); if (promptInput) parts.control(promptInput);\n parts.update(); parts.feedback(error).update({message:login.error || localError,tone:'error'});\n const complete = ['complete','error'].includes(login.phase);\n element.querySelector<HTMLButtonElement>('[data-close]')!.hidden = !complete;\n element.querySelector<HTMLButtonElement>('[data-sdk]')!.hidden = complete;\n renderDisabled();\n };\n const operation = createOperation({unavailable:() => !!state.disabled || state.phase !== 'prompt',onPending(value) {pending = value; renderDisabled();},onError(message) {localError = message; parts.feedback(error).update({message,tone:'error'});}});\n element.addEventListener('submit', event => {\n event.preventDefault(); if (operation.pending || state.disabled || state.phase !== 'prompt' || !options.onAnswer) return;\n const input = field<HTMLInputElement | HTMLSelectElement>('oauth-value'); if (!input.checkValidity()) {input.reportValidity(); return;}\n operation.run(() => {localError = ''; parts.feedback(error).update({message:'',tone:'error'}); return options.onAnswer!(parts.control(input).getValue());}, result => {if (result && !result.ok) {localError = result.error; parts.feedback(error).update({message:localError,tone:'error'});}});\n }, {signal:abort.signal});\n const close = bindContentClose(element,{dialogId:prefix+'oauth-dialog',onClose:options.onClose});\n element.addEventListener('click', event => {const target = (event.target as HTMLElement).closest<HTMLButtonElement>('button'); if (target?.dataset.sdk === 'cancel-login') options.onCancel?.();}, {signal:abort.signal});\n update(initial); return {element, update, destroy() {if (destroyed) return; destroyed = true; operation.destroy(); close.destroy(); abort.abort(); for (const input of element.querySelectorAll<HTMLInputElement>('input')) parts.control(input).reset(''); parts.destroy(); element.remove();}};\n}\n"]}
@@ -1,22 +1,26 @@
1
- import type { UIBlock } from '../core.js';
1
+ import type { ActionResult, UIBlock } from '../core.js';
2
2
  export interface ResourceEditorState {
3
3
  workspaceId: string;
4
4
  workspacePath: string;
5
5
  path?: string;
6
6
  kind: string;
7
+ name?: string;
7
8
  content: string;
8
9
  editable: boolean;
9
10
  workspaceBusy: boolean;
10
11
  error?: string;
11
12
  disabled?: boolean;
12
13
  }
14
+ export interface ResourceDraft {
15
+ name: string;
16
+ content: string;
17
+ }
13
18
  export declare function createResourceEditor(state: ResourceEditorState, options?: {
14
19
  idPrefix?: string;
20
+ onSubmit?: (draft: ResourceDraft) => ActionResult | Promise<ActionResult>;
21
+ onDelete?: () => void;
15
22
  }): UIBlock<ResourceEditorState> & {
16
- read(): {
17
- name: string;
18
- content: string;
19
- };
23
+ read(): ResourceDraft;
20
24
  readonly form: HTMLFormElement;
21
25
  readonly removeButton: HTMLButtonElement | null;
22
26
  };
@@ -1 +1 @@
1
- {"version":3,"file":"resource-editor.d.ts","sourceRoot":"","sources":["../../src/forms/resource-editor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,mBAAmB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAC;AAC9M,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,EAAE,OAAO,GAAE;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,GAAG;IAAC,IAAI,IAAI;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,GAAG,IAAI,CAAA;CAAC,CAQ7P"}
1
+ {"version":3,"file":"resource-editor.d.ts","sourceRoot":"","sources":["../../src/forms/resource-editor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,YAAY,EAAC,OAAO,EAAC,MAAM,YAAY,CAAC;AAGrD,MAAM,WAAW,mBAAmB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAC;AAC7N,MAAM,WAAW,aAAa;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC;AAC9D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,EAAE,OAAO,GAAE;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,GAAG;IAAC,IAAI,IAAI,aAAa,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,GAAG,IAAI,CAAA;CAAC,CAc7U"}
@@ -1,24 +1,35 @@
1
- import { scopeIds } from './identity.js';
1
+ import { scopeIds, bindFormSubmission } from './identity.js';
2
2
  import { escape, uniqueId } from '../dom.js';
3
+ import { adoptProductParts } from '../foundations.js';
3
4
  export function createResourceEditor(state, options = {}) {
4
5
  const element = document.createElement('div');
5
6
  element.className = 'pui-resource-editor';
6
- element.innerHTML = `<p class="pui-file-path">${escape(state.path || state.workspacePath)}</p>${!state.editable ? `<p>${state.workspaceBusy ? 'Stop this workspace’s task before editing resources.' : 'Inherited instructions are read-only here. Add workspace instructions to specialize them.'}</p>` : ''}<form id="resource-form">${!state.path && state.kind !== 'instructions' ? '<label class="pui-field-label">Name<input id="resource-name" required pattern="[A-Za-z0-9]([A-Za-z0-9_]|-)*" placeholder="my-resource" /></label>' : ''}<label class="pui-field-label" for="resource-body">Markdown</label><textarea id="resource-body" class="pui-resource-editor" ${!state.editable ? 'readonly' : ''}>${escape(state.content)}</textarea><p class="pui-form-error" data-resource-error role="alert"></p><div class="pui-modal-footer">${state.path && state.editable ? '<button type="button" id="delete-resource" class="pui-secondary-button pui-destructive-button">Delete resource</button>' : ''}<button type="button" class="pui-secondary-button" data-close="sdk-dialog">${state.editable ? 'Cancel' : 'Close'}</button>${state.editable ? `<button type="submit" class="pui-primary-button" data-idle-action data-idle-workspace="${escape(state.workspaceId)}">Save</button>` : ''}</div></form>`;
7
+ element.innerHTML = `<p class="pui-file-path">${escape(state.path || state.workspacePath)}</p>${!state.editable ? `<p>${state.workspaceBusy ? 'Stop this workspace’s task before editing resources.' : 'Inherited instructions are read-only here. Add workspace instructions to specialize them.'}</p>` : ''}<form id="resource-form">${!state.path && state.kind !== 'instructions' ? '<label class="pui-field-label">Name<input id="resource-name" required pattern="[A-Za-z0-9]([A-Za-z0-9_]|-)*" placeholder="my-resource" /></label>' : ''}<label class="pui-field-label" for="resource-body">Markdown</label><textarea id="resource-body" class="pui-resource-editor" ${!state.editable ? 'readonly' : ''}>${escape(state.content)}</textarea><p class="pui-form-error" data-resource-error role="alert"></p><div class="pui-modal-footer">${state.path && state.editable ? '<button type="button" id="delete-resource" class="pui-secondary-button pui-destructive-button">Delete resource</button>' : ''}<button type="button" class="pui-secondary-button" data-pui-close data-close="sdk-dialog">${state.editable ? 'Cancel' : 'Close'}</button>${state.editable ? `<button type="submit" class="pui-primary-button" data-idle-action data-idle-workspace="${escape(state.workspaceId)}">Save</button>` : ''}</div></form>`;
7
8
  const initialError = element.querySelector('[data-resource-error]');
8
9
  initialError.textContent = state.error || '';
9
10
  const name = element.querySelector('#resource-name');
11
+ if (name)
12
+ name.value = state.name || '';
10
13
  const removeButton = element.querySelector('#delete-resource');
11
14
  if (removeButton)
12
15
  removeButton.dataset.resourceDelete = '';
13
16
  const form = element.querySelector('#resource-form');
14
17
  const body = element.querySelector('#resource-body');
15
- let destroyed = false;
18
+ let destroyed = false, pending = false;
16
19
  scopeIds(element, options.idPrefix ?? uniqueId('pui-resource') + '-');
17
- return { element, form, removeButton, read() { return { name: name?.value || '', content: body.value }; }, update(state) { if (destroyed)
18
- return; if (state.error !== undefined)
19
- element.querySelector('[data-resource-error]').textContent = state.error; if (state.disabled !== undefined)
20
- for (const button of form.querySelectorAll('button[type="submit"], [data-resource-delete]'))
21
- button.disabled = state.disabled; }, destroy() { if (destroyed)
22
- return; destroyed = true; element.remove(); } };
20
+ const parts = adoptProductParts(element), abort = new AbortController();
21
+ let current = state;
22
+ const read = () => ({ name: name ? parts.control(name).getValue() : '', content: parts.control(body).getValue() });
23
+ const update = (next) => { if (destroyed)
24
+ return; current = next; body.readOnly = !next.editable || next.workspaceBusy; if (name)
25
+ name.readOnly = body.readOnly; if (next.error !== undefined)
26
+ parts.feedback(initialError).update({ message: next.error, tone: 'error' }); for (const button of form.querySelectorAll('button[type="submit"], [data-resource-delete]'))
27
+ parts.action(button).update({ disabled: !!next.disabled || !next.editable || next.workspaceBusy, pending }); };
28
+ const submission = bindFormSubmission(form, { read, unavailable: () => !!current.disabled || !current.editable || current.workspaceBusy, onSubmit: options.onSubmit, onPending(value) { pending = value; update(current); }, onError(error) { update({ ...current, error }); } });
29
+ removeButton?.addEventListener('click', () => { if (!pending && !current.disabled && current.editable && !current.workspaceBusy)
30
+ options.onDelete?.(); }, { signal: abort.signal });
31
+ update(state);
32
+ return { element, form, removeButton, read, update, destroy() { if (destroyed)
33
+ return; destroyed = true; submission.destroy(); abort.abort(); parts.destroy(); element.remove(); } };
23
34
  }
24
35
  //# sourceMappingURL=resource-editor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resource-editor.js","sourceRoot":"","sources":["../../src/forms/resource-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import {scopeIds} from './identity.js';\nimport type { UIBlock } from '../core.js';\nimport { escape, uniqueId } from '../dom.js';\nexport interface ResourceEditorState {workspaceId: string; workspacePath: string; path?: string; kind: string; content: string; editable: boolean; workspaceBusy: boolean; error?: string; disabled?: boolean}\nexport function createResourceEditor(state: ResourceEditorState, options: {idPrefix?: string} = {}): UIBlock<ResourceEditorState> & {read(): {name: string; content: string}; readonly form: HTMLFormElement; readonly removeButton: HTMLButtonElement | null} {\n const element = document.createElement('div'); element.className = 'pui-resource-editor'; element.innerHTML = `<p class=\"pui-file-path\">${escape(state.path || state.workspacePath)}</p>${!state.editable ? `<p>${state.workspaceBusy ? 'Stop this workspace’s task before editing resources.' : 'Inherited instructions are read-only here. Add workspace instructions to specialize them.'}</p>` : ''}<form id=\"resource-form\">${!state.path && state.kind !== 'instructions' ? '<label class=\"pui-field-label\">Name<input id=\"resource-name\" required pattern=\"[A-Za-z0-9]([A-Za-z0-9_]|-)*\" placeholder=\"my-resource\" /></label>' : ''}<label class=\"pui-field-label\" for=\"resource-body\">Markdown</label><textarea id=\"resource-body\" class=\"pui-resource-editor\" ${!state.editable ? 'readonly' : ''}>${escape(state.content)}</textarea><p class=\"pui-form-error\" data-resource-error role=\"alert\"></p><div class=\"pui-modal-footer\">${state.path && state.editable ? '<button type=\"button\" id=\"delete-resource\" class=\"pui-secondary-button pui-destructive-button\">Delete resource</button>' : ''}<button type=\"button\" class=\"pui-secondary-button\" data-close=\"sdk-dialog\">${state.editable ? 'Cancel' : 'Close'}</button>${state.editable ? `<button type=\"submit\" class=\"pui-primary-button\" data-idle-action data-idle-workspace=\"${escape(state.workspaceId)}\">Save</button>` : ''}</div></form>`;\n const initialError = element.querySelector<HTMLElement>('[data-resource-error]')!; initialError.textContent = state.error || '';\n const name = element.querySelector<HTMLInputElement>('#resource-name');\n const removeButton = element.querySelector<HTMLButtonElement>('#delete-resource');\n if (removeButton) removeButton.dataset.resourceDelete = '';\n const form = element.querySelector<HTMLFormElement>('#resource-form')!; const body = element.querySelector<HTMLTextAreaElement>('#resource-body')!; let destroyed = false; scopeIds(element, options.idPrefix ?? uniqueId('pui-resource') + '-');\n return {element, form, removeButton, read() {return {name: name?.value || '', content: body.value};}, update(state) {if (destroyed) return; if (state.error !== undefined) element.querySelector<HTMLElement>('[data-resource-error]')!.textContent = state.error; if (state.disabled !== undefined) for (const button of form.querySelectorAll<HTMLButtonElement>('button[type=\"submit\"], [data-resource-delete]')) button.disabled = state.disabled;}, destroy() {if (destroyed) return; destroyed = true; element.remove();}};\n}\n"]}
1
+ {"version":3,"file":"resource-editor.js","sourceRoot":"","sources":["../../src/forms/resource-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import {scopeIds,bindFormSubmission} from './identity.js';\nimport type {ActionResult,UIBlock} from '../core.js';\nimport { escape, uniqueId } from '../dom.js';\nimport {adoptProductParts} from '../foundations.js';\nexport interface ResourceEditorState {workspaceId: string; workspacePath: string; path?: string; kind: string; name?: string; content: string; editable: boolean; workspaceBusy: boolean; error?: string; disabled?: boolean}\nexport interface ResourceDraft {name: string; content: string}\nexport function createResourceEditor(state: ResourceEditorState, options: {idPrefix?: string; onSubmit?: (draft: ResourceDraft) => ActionResult | Promise<ActionResult>; onDelete?: () => void} = {}): UIBlock<ResourceEditorState> & {read(): ResourceDraft; readonly form: HTMLFormElement; readonly removeButton: HTMLButtonElement | null} {\n const element = document.createElement('div'); element.className = 'pui-resource-editor'; element.innerHTML = `<p class=\"pui-file-path\">${escape(state.path || state.workspacePath)}</p>${!state.editable ? `<p>${state.workspaceBusy ? 'Stop this workspace’s task before editing resources.' : 'Inherited instructions are read-only here. Add workspace instructions to specialize them.'}</p>` : ''}<form id=\"resource-form\">${!state.path && state.kind !== 'instructions' ? '<label class=\"pui-field-label\">Name<input id=\"resource-name\" required pattern=\"[A-Za-z0-9]([A-Za-z0-9_]|-)*\" placeholder=\"my-resource\" /></label>' : ''}<label class=\"pui-field-label\" for=\"resource-body\">Markdown</label><textarea id=\"resource-body\" class=\"pui-resource-editor\" ${!state.editable ? 'readonly' : ''}>${escape(state.content)}</textarea><p class=\"pui-form-error\" data-resource-error role=\"alert\"></p><div class=\"pui-modal-footer\">${state.path && state.editable ? '<button type=\"button\" id=\"delete-resource\" class=\"pui-secondary-button pui-destructive-button\">Delete resource</button>' : ''}<button type=\"button\" class=\"pui-secondary-button\" data-pui-close data-close=\"sdk-dialog\">${state.editable ? 'Cancel' : 'Close'}</button>${state.editable ? `<button type=\"submit\" class=\"pui-primary-button\" data-idle-action data-idle-workspace=\"${escape(state.workspaceId)}\">Save</button>` : ''}</div></form>`;\n const initialError = element.querySelector<HTMLElement>('[data-resource-error]')!; initialError.textContent = state.error || '';\n const name = element.querySelector<HTMLInputElement>('#resource-name');\n if (name) name.value = state.name || '';\n const removeButton = element.querySelector<HTMLButtonElement>('#delete-resource');\n if (removeButton) removeButton.dataset.resourceDelete = '';\n const form = element.querySelector<HTMLFormElement>('#resource-form')!; const body = element.querySelector<HTMLTextAreaElement>('#resource-body')!; let destroyed = false, pending = false; scopeIds(element, options.idPrefix ?? uniqueId('pui-resource') + '-');\n const parts = adoptProductParts(element), abort = new AbortController(); let current = state;\n const read = (): ResourceDraft => ({name:name ? parts.control(name).getValue() : '',content:parts.control(body).getValue()});\n const update = (next: Readonly<ResourceEditorState>) => {if (destroyed) return; current = next; body.readOnly = !next.editable || next.workspaceBusy; if (name) name.readOnly = body.readOnly; if (next.error !== undefined) parts.feedback(initialError).update({message:next.error,tone:'error'}); for (const button of form.querySelectorAll<HTMLButtonElement>('button[type=\"submit\"], [data-resource-delete]')) parts.action(button).update({disabled:!!next.disabled || !next.editable || next.workspaceBusy,pending});};\n const submission = bindFormSubmission(form,{read,unavailable:()=>!!current.disabled || !current.editable || current.workspaceBusy,onSubmit:options.onSubmit,onPending(value) {pending = value; update(current);},onError(error) {update({...current,error});}});\n removeButton?.addEventListener('click',() => {if (!pending && !current.disabled && current.editable && !current.workspaceBusy) options.onDelete?.();}, {signal:abort.signal});\n update(state); return {element,form,removeButton,read,update,destroy() {if (destroyed) return; destroyed = true; submission.destroy(); abort.abort(); parts.destroy(); element.remove();}};\n}\n"]}