@runfusion/fusion 0.77.0-beta.4 → 0.77.0-beta.5

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 (161) hide show
  1. package/dist/bin.js +4051 -4144
  2. package/dist/child-process-worker.js +2681 -1719
  3. package/dist/client/.vite/manifest.json +261 -261
  4. package/dist/client/assets/{AgentDetailView-CH6GtXl9.js → AgentDetailView-CSK_Rnlk.js} +1 -1
  5. package/dist/client/assets/{AgentPermissionPolicyEditor-YTEpMhUx.js → AgentPermissionPolicyEditor-kG44Adcm.js} +1 -1
  6. package/dist/client/assets/{AgentsView-XOHHDo4a.js → AgentsView-ClKwKWnU.js} +3 -3
  7. package/dist/client/assets/ChatView-DoOqgkPX.js +13 -0
  8. package/dist/client/assets/{CommandCenter-BsH-R15f.js → CommandCenter-CJxvPbgn.js} +1 -1
  9. package/dist/client/assets/{DevServerView-CKOa-lkc.js → DevServerView-C4nyLONX.js} +1 -1
  10. package/dist/client/assets/{DirectoryPicker-DHUYTE-j.js → DirectoryPicker-BIvXWIB5.js} +1 -1
  11. package/dist/client/assets/{DocumentsView-BPzrxeP-.js → DocumentsView-DH_aZysM.js} +1 -1
  12. package/dist/client/assets/{EvalsView-DojCiv47.js → EvalsView-klRK-GJQ.js} +1 -1
  13. package/dist/client/assets/{ExperimentalAgentOnboardingModal-DuurZ8qe.js → ExperimentalAgentOnboardingModal-CgBmukIm.js} +1 -1
  14. package/dist/client/assets/{GoalsView-DDWPXcG1.js → GoalsView-ysh3X2x6.js} +1 -1
  15. package/dist/client/assets/{InsightsView-CgkMOD1A.js → InsightsView-BbMjCu7J.js} +1 -1
  16. package/dist/client/assets/{MemoryView-Cj49_z7O.js → MemoryView-B3IgA8Bx.js} +1 -1
  17. package/dist/client/assets/{PiExtensionsManager-B_rRJiOd.js → PiExtensionsManager-CZlIw7C3.js} +1 -1
  18. package/dist/client/assets/{PluginManager-Dxwi88oY.js → PluginManager-vy0YZ2Nx.js} +1 -1
  19. package/dist/client/assets/{PullRequestView-z-5v2hQT.js → PullRequestView-DhhsJV8I.js} +1 -1
  20. package/dist/client/assets/{ReportModal-DmOPEYWp.js → ReportModal-CQMn4i1y.js} +1 -1
  21. package/dist/client/assets/{ResearchView-D90Jbzbx.js → ResearchView-CVwfs4l3.js} +1 -1
  22. package/dist/client/assets/{SecretsView-CSyjZl5L.js → SecretsView-CrJfHle9.js} +1 -1
  23. package/dist/client/assets/{SessionTerminal-Bwb8nGmU.js → SessionTerminal-BRI8W1-G.js} +1 -1
  24. package/dist/client/assets/{SettingsModal-CJof1Ett.js → SettingsModal-B6U5Umru.js} +1 -1
  25. package/dist/client/assets/SettingsModal-h1A_aFqD.js +21 -0
  26. package/dist/client/assets/{SettingsTextareaRow-BYchnHfW.js → SettingsTextareaRow-O7-u9uMC.js} +1 -1
  27. package/dist/client/assets/{SetupWizardModal-NqV-erVf.js → SetupWizardModal-nXfJp8cA.js} +2 -2
  28. package/dist/client/assets/{SkillsView-BUrkIJ-p.js → SkillsView-CoWAjvWU.js} +1 -1
  29. package/dist/client/assets/{WorkflowNodeEditor-DcPk2A1Z.js → WorkflowNodeEditor-BFMM3RF_.js} +2 -2
  30. package/dist/client/assets/{agent-import-generation-X16OLfrL.js → agent-import-generation-BqDmtTur.js} +1 -1
  31. package/dist/client/assets/{agentsOrgChartLayout-BhPIXckU.js → agentsOrgChartLayout-C4cLqlV6.js} +1 -1
  32. package/dist/client/assets/app-BBSLJDbV.js +13 -0
  33. package/dist/client/assets/app-BKwOvuxE.js +5 -0
  34. package/dist/client/assets/app-Bvr57EZQ.js +5 -0
  35. package/dist/client/assets/app-C_PTWuI1.js +13 -0
  36. package/dist/client/assets/app-DKx18PHE.js +13 -0
  37. package/dist/client/assets/app-DRW5hIgr.js +13 -0
  38. package/dist/client/assets/app-DwvelD-n.js +13 -0
  39. package/dist/client/assets/{architectureDiagram-3BPJPVTR-WArMtdqy.js → architectureDiagram-3BPJPVTR-CdxcwdRe.js} +1 -1
  40. package/dist/client/assets/{blockDiagram-GPEHLZMM-emScogdV.js → blockDiagram-GPEHLZMM-CfQrRfHR.js} +1 -1
  41. package/dist/client/assets/{c4Diagram-AAUBKEIU-CBY7-E0T.js → c4Diagram-AAUBKEIU-Cx7-2SOm.js} +1 -1
  42. package/dist/client/assets/channel-B4WN1jC_.js +1 -0
  43. package/dist/client/assets/{chunk-2J33WTMH-Bcai1sOm.js → chunk-2J33WTMH-D8jvgP3M.js} +1 -1
  44. package/dist/client/assets/{chunk-4BX2VUAB-hjiKRusj.js → chunk-4BX2VUAB-B5tBx_s_.js} +1 -1
  45. package/dist/client/assets/{chunk-55IACEB6-DpO9nIb0.js → chunk-55IACEB6-C-F-HQ5Z.js} +1 -1
  46. package/dist/client/assets/{chunk-727SXJPM-B9JanA0o.js → chunk-727SXJPM-BP8Ln-8C.js} +1 -1
  47. package/dist/client/assets/{chunk-AQP2D5EJ-D6zdnEUE.js → chunk-AQP2D5EJ-DMnTmRmn.js} +1 -1
  48. package/dist/client/assets/{chunk-FMBD7UC4-CRkrJ51d.js → chunk-FMBD7UC4-D_YdfnNc.js} +1 -1
  49. package/dist/client/assets/{chunk-ND2GUHAM-BLQsKt7a.js → chunk-ND2GUHAM-CULXyuXq.js} +1 -1
  50. package/dist/client/assets/{chunk-QZHKN3VN-MCOlJ723.js → chunk-QZHKN3VN-CT1BWEJL.js} +1 -1
  51. package/dist/client/assets/classDiagram-4FO5ZUOK-CKE8RSOv.js +1 -0
  52. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CKE8RSOv.js +1 -0
  53. package/dist/client/assets/{cose-bilkent-S5V4N54A-Cv1XmKKG.js → cose-bilkent-S5V4N54A-M-3DXa6e.js} +1 -1
  54. package/dist/client/assets/{dagre-BM42HDAG-flnNS_RW.js → dagre-BM42HDAG-Bsiqvroz.js} +1 -1
  55. package/dist/client/assets/{dashboard-view-CrV-rL9Q.js → dashboard-view-BEBh_Ei5.js} +1 -1
  56. package/dist/client/assets/{dashboard-view-Dz7kqcJc.js → dashboard-view-Bo_gFjdO.js} +1 -1
  57. package/dist/client/assets/{dashboard-view-CC1aH-lp.js → dashboard-view-CnFFG3cW.js} +1 -1
  58. package/dist/client/assets/{dashboard-view-DEAYb_TZ.js → dashboard-view-DAHn20ph.js} +1 -1
  59. package/dist/client/assets/{diagram-2AECGRRQ-Z3S7b_6_.js → diagram-2AECGRRQ-CZiHoXo5.js} +1 -1
  60. package/dist/client/assets/{diagram-5GNKFQAL-BAZHdMFq.js → diagram-5GNKFQAL-BoJVz4Or.js} +1 -1
  61. package/dist/client/assets/{diagram-KO2AKTUF-C2y3S8F0.js → diagram-KO2AKTUF-DivGQuAL.js} +1 -1
  62. package/dist/client/assets/{diagram-LMA3HP47-Bfz0_IvT.js → diagram-LMA3HP47-DkMK7OJp.js} +1 -1
  63. package/dist/client/assets/{diagram-OG6HWLK6-BBmSQsTI.js → diagram-OG6HWLK6-DFFvRcpW.js} +1 -1
  64. package/dist/client/assets/{erDiagram-TEJ5UH35-DnpdQi66.js → erDiagram-TEJ5UH35--217vrom.js} +1 -1
  65. package/dist/client/assets/{flowDiagram-I6XJVG4X-IybTR_zf.js → flowDiagram-I6XJVG4X-CQgWO3xf.js} +1 -1
  66. package/dist/client/assets/{folder-open-Dntm63x4.js → folder-open-DR6cRcNR.js} +1 -1
  67. package/dist/client/assets/{ganttDiagram-6RSMTGT7-DEQOe2E9.js → ganttDiagram-6RSMTGT7-BjDMUrS3.js} +1 -1
  68. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-BOKc-h63.js → gitGraphDiagram-PVQCEYII-gKUcDnln.js} +1 -1
  69. package/dist/client/assets/index-Dki2LBAp.css +1 -0
  70. package/dist/client/assets/index-oxnX59eO.js +2774 -0
  71. package/dist/client/assets/{infoDiagram-5YYISTIA-LqaYIdbj.js → infoDiagram-5YYISTIA-BA91T8S5.js} +1 -1
  72. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-a8qd512s.js → ishikawaDiagram-YF4QCWOH-0BY5xe-c.js} +1 -1
  73. package/dist/client/assets/{journeyDiagram-JHISSGLW-BgoNyeiy.js → journeyDiagram-JHISSGLW-B_OwenbQ.js} +1 -1
  74. package/dist/client/assets/{kanban-definition-UN3LZRKU-Bqwow7D3.js → kanban-definition-UN3LZRKU-GLabUTKp.js} +1 -1
  75. package/dist/client/assets/{mermaid.core-B2zD934i.js → mermaid.core-BXo4rxYI.js} +4 -4
  76. package/dist/client/assets/{mindmap-definition-RKZ34NQL-CCTOigWu.js → mindmap-definition-RKZ34NQL-DZl6LPoE.js} +1 -1
  77. package/dist/client/assets/{pieDiagram-4H26LBE5-Bq5DtXKR.js → pieDiagram-4H26LBE5-DtHq-4py.js} +1 -1
  78. package/dist/client/assets/{puzzle-VhTPiCit.js → puzzle-OVm-I1L4.js} +1 -1
  79. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-CGMP3nUx.js → quadrantDiagram-W4KKPZXB-BdjXhd5d.js} +1 -1
  80. package/dist/client/assets/{requirementDiagram-4Y6WPE33-Ckeu_szu.js → requirementDiagram-4Y6WPE33-BoFVjELN.js} +1 -1
  81. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-SWbBDD4d.js → sankeyDiagram-5OEKKPKP-B0qyJh-P.js} +1 -1
  82. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-CiJrmL_G.js → sequenceDiagram-3UESZ5HK-ByY62Eqp.js} +1 -1
  83. package/dist/client/assets/{shield-alert-BBDlP6A5.js → shield-alert-CDy69fl7.js} +1 -1
  84. package/dist/client/assets/{standing-instructions-template-viu_kgDX.js → standing-instructions-template-BsnnRlwm.js} +1 -1
  85. package/dist/client/assets/{stateDiagram-AJRCARHV-DTCzK5Gt.js → stateDiagram-AJRCARHV-CwJ-_Phi.js} +1 -1
  86. package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-BIGAwFTT.js → stateDiagram-v2-BHNVJYJU-Cfvhq8mV.js} +1 -1
  87. package/dist/client/assets/{timeline-definition-PNZ67QCA-BQZEFEug.js → timeline-definition-PNZ67QCA-Co8VfGN9.js} +1 -1
  88. package/dist/client/assets/{upload-D5w3Ehwp.js → upload-CkqDbEeE.js} +1 -1
  89. package/dist/client/assets/{useDiscoveredSkillsCache-D6zMSIaS.js → useDiscoveredSkillsCache-BHUasRiZ.js} +1 -1
  90. package/dist/client/assets/{users-Bohihi_o.js → users-B8DkpbXD.js} +1 -1
  91. package/dist/client/assets/{vennDiagram-CIIHVFJN-DnHguEv8.js → vennDiagram-CIIHVFJN-XSJteQrL.js} +1 -1
  92. package/dist/client/assets/{wardley-L42UT6IY-BOqYltGN.js → wardley-L42UT6IY-Btc0FRfF.js} +1 -1
  93. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Re0Ery2M.js → wardleyDiagram-YWT4CUSO--IcDNmrf.js} +1 -1
  94. package/dist/client/assets/{xychartDiagram-2RQKCTM6-CnVq21b2.js → xychartDiagram-2RQKCTM6-CZW93G6X.js} +1 -1
  95. package/dist/client/index.html +2 -2
  96. package/dist/client/version.json +1 -1
  97. package/dist/droid-cli/package.json +1 -1
  98. package/dist/extension.js +3085 -2130
  99. package/dist/migrations/0000_initial.sql +3 -0
  100. package/dist/migrations/0061_fn_066_activity_log_task_id_index.sql +7 -0
  101. package/dist/migrations/0062_remove_task_subtask_splitting.sql +2 -0
  102. package/dist/migrations/0063_fn_090_ai_merge_review_reconciliation.sql +2 -0
  103. package/dist/migrations/0064_fn_094_task_repository_scope.sql +2 -0
  104. package/dist/pi-claude-cli/package.json +1 -1
  105. package/dist/plugin-sdk/index.d.ts +276 -186
  106. package/dist/plugin-sdk/index.js +35 -104
  107. package/dist/plugins/fusion-plugin-acp-runtime/bundled.js +35 -104
  108. package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
  109. package/dist/plugins/fusion-plugin-claude-runtime/bundled.js +35 -104
  110. package/dist/plugins/fusion-plugin-claude-runtime/package.json +1 -1
  111. package/dist/plugins/fusion-plugin-cli-printing-press/bundled.js +35 -104
  112. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  113. package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +35 -104
  114. package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
  115. package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +35 -104
  116. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  117. package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +35 -104
  118. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  119. package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +35 -104
  120. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  121. package/dist/plugins/fusion-plugin-grok-runtime/bundled.js +35 -104
  122. package/dist/plugins/fusion-plugin-grok-runtime/package.json +1 -1
  123. package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +35 -104
  124. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  125. package/dist/plugins/fusion-plugin-linear-import/bundled.js +35 -104
  126. package/dist/plugins/fusion-plugin-linear-import/package.json +1 -1
  127. package/dist/plugins/fusion-plugin-omp-runtime/bundled.js +35 -104
  128. package/dist/plugins/fusion-plugin-omp-runtime/package.json +1 -1
  129. package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +35 -104
  130. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  131. package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +35 -104
  132. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  133. package/dist/plugins/fusion-plugin-quality/bundled.js +35 -104
  134. package/dist/plugins/fusion-plugin-quality/package.json +1 -1
  135. package/dist/plugins/fusion-plugin-reports/bundled.js +35 -104
  136. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  137. package/dist/plugins/fusion-plugin-roadmap/bundled.js +35 -104
  138. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  139. package/dist/plugins/fusion-plugin-todos/bundled.js +35 -104
  140. package/dist/plugins/fusion-plugin-todos/package.json +1 -1
  141. package/dist/plugins/fusion-plugin-whatsapp-chat/bundled.js +35 -104
  142. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  143. package/package.json +1 -1
  144. package/skill/fusion/references/extension-tools.md +2 -1
  145. package/skill/fusion/references/fusion-capabilities.md +1 -1
  146. package/skill/fusion/references/task-structure.md +1 -1
  147. package/skill/fusion/workflows/specifications.md +2 -2
  148. package/dist/client/assets/ChatView-gH7QX3TI.js +0 -13
  149. package/dist/client/assets/SettingsModal-BAzmMjr9.js +0 -21
  150. package/dist/client/assets/app-B-TfWH9b.js +0 -5
  151. package/dist/client/assets/app-B2RDV_-t.js +0 -13
  152. package/dist/client/assets/app-CDo0mF2S.js +0 -5
  153. package/dist/client/assets/app-Cc18kAQS.js +0 -13
  154. package/dist/client/assets/app-DFF79EUn.js +0 -13
  155. package/dist/client/assets/app-DSeFHxgj.js +0 -13
  156. package/dist/client/assets/app-Ducr0y6r.js +0 -13
  157. package/dist/client/assets/channel-CP2ySYs0.js +0 -1
  158. package/dist/client/assets/classDiagram-4FO5ZUOK-DKkOBtzM.js +0 -1
  159. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DKkOBtzM.js +0 -1
  160. package/dist/client/assets/index-DXpztECA.css +0 -1
  161. package/dist/client/assets/index-I32FijPT.js +0 -2821
@@ -1,4 +1,4 @@
1
- import{r as l,j as e}from"./vendor-react-SZ_qB27O.js";import{c as V,ba as Y,bb as Z,bc as T,R as L,aK as D,aN as P,P as ee,C as se,k as ae,F as ie,aI as B,bd as ne,be as te,bf as I,X as re}from"./index-I32FijPT.js";import{u as le}from"./vendor-i18n-Duky4gdQ.js";import{P as $}from"./puzzle-VhTPiCit.js";import{B as A}from"./AgentPermissionPolicyEditor-YTEpMhUx.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";import"./vendor-xterm-BNq00GSj.js";/**
1
+ import{r as l,j as e}from"./vendor-react-SZ_qB27O.js";import{c as V,ba as Y,bb as Z,bc as T,R as L,aK as D,aN as P,P as ee,C as se,k as ae,F as ie,aI as B,bd as ne,be as te,bf as I,X as re}from"./index-oxnX59eO.js";import{u as le}from"./vendor-i18n-Duky4gdQ.js";import{P as $}from"./puzzle-OVm-I1L4.js";import{B as A}from"./AgentPermissionPolicyEditor-kG44Adcm.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";import"./vendor-xterm-BNq00GSj.js";/**
2
2
  * @license lucide-react v1.7.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as d,j as e}from"./vendor-react-SZ_qB27O.js";import{ag as ze,bg as He,bh as Ve,bi as ge,bj as Qe,X as me,aU as Ke,bk as Je,aK as he,P as be,b3 as ye,F as xe,R as fe,aN as Ye,a3 as Xe,bl as Ze,bm as es,bn as ss,bo as ns,bp as is,bq as ts,br as as,bs as Q,bt as ls,bu as rs}from"./index-I32FijPT.js";import{D as os}from"./DirectoryPicker-DHUYTE-j.js";import{u as Ce}from"./vendor-i18n-Duky4gdQ.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";import"./vendor-xterm-BNq00GSj.js";import"./folder-open-Dntm63x4.js";const us="/api/plugins/fusion-plugin-whatsapp-chat",cs=/^\d+$/;function K(r,c){const p=c?`?projectId=${encodeURIComponent(c)}`:"";return`${us}${r}${p}`}function ps({projectId:r,settings:c}){const{t:p}=Ce("app"),[n,x]=d.useState(null),[f,F]=d.useState(null),[L,_]=d.useState(()=>String(c?.pairingPhoneNumber??"")),[A,w]=d.useState(null),[P,k]=d.useState(null),v=d.useCallback(async()=>{try{const a=await fetch(K("/status",r)),y=await a.json();if(!a.ok)throw new Error(y.error??"WhatsApp pairing is unavailable. Enable the plugin and try again.");x(y),F(null)}catch(a){F(a instanceof Error?a.message:String(a))}},[r]);d.useEffect(()=>{v();const a=window.setInterval(()=>void v(),5e3);return()=>window.clearInterval(a)},[v]);const O=async()=>{const a=L.trim();if(!a||!cs.test(a)){w("Enter an E.164 phone number using digits only, without +.");return}k("code"),w(null);try{const y=await fetch(K("/pair-code",r),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({phoneNumber:a,...r?{projectId:r}:{}})}),m=await y.json();if(!y.ok)throw new Error(m.error??"Could not request a pairing code.");x(j=>({status:"awaiting-code",...j,pairingCode:m.pairingCode})),await v()}catch(y){w(y instanceof Error?y.message:String(y))}finally{k(null)}},U=async()=>{k("logout"),w(null);try{const a=await fetch(K("/logout",r),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r?{projectId:r}:{})});if(!a.ok){const y=await a.json();throw new Error(y.error??"Could not log out from WhatsApp.")}await v()}catch(a){w(a instanceof Error?a.message:String(a))}finally{k(null)}},B=c?.pairingMode==="code"?"code":"qr",R=n?.status??"starting";return e.jsxs("section",{className:"whatsapp-pairing-panel","aria-labelledby":"whatsapp-pairing-heading",children:[e.jsxs("div",{className:"whatsapp-pairing-heading-row",children:[e.jsxs("div",{children:[e.jsx("h5",{id:"whatsapp-pairing-heading",className:"plugin-detail-section-heading",children:p("whatsapp.pairing","WhatsApp pairing")}),e.jsx("p",{className:"whatsapp-pairing-description",children:p("whatsapp.description","Pair and monitor this project's WhatsApp connection here.")})]}),e.jsx("button",{className:"btn btn-secondary btn-sm",type:"button",onClick:()=>void v(),children:p("whatsapp.refreshStatus","Refresh status")})]}),e.jsxs("div",{className:`whatsapp-pairing-status whatsapp-pairing-status--${R}`,role:"status","data-testid":"whatsapp-pairing-status",children:[e.jsxs("strong",{children:[p("whatsapp.status","Status:")," ",R]}),n?.jid&&e.jsx("span",{children:p("whatsapp.connectedAs","Connected as {{jid}}",{jid:n.jid})}),(n?.lastError||f)&&e.jsx("span",{className:"field-error",children:n?.lastError??f})]}),R==="awaiting-qr"&&e.jsx("div",{className:"whatsapp-pairing-qr","data-testid":"whatsapp-pairing-qr",children:n?.qrDataUrl?e.jsx("img",{src:n.qrDataUrl,alt:p("whatsapp.qrCode","WhatsApp pairing QR code"),className:"whatsapp-pairing-qr-image"}):e.jsx("p",{className:"text-muted",children:p("whatsapp.waitingQr","Waiting for a fresh QR code. Keep this panel open and refresh if needed.")})}),(B==="code"||R==="awaiting-code")&&e.jsxs("div",{className:"whatsapp-pairing-code",children:[e.jsx("label",{htmlFor:"whatsapp-pairing-phone",children:p("whatsapp.phoneNumber","Phone number (E.164 digits without +)")}),e.jsxs("div",{className:"whatsapp-pairing-code-controls",children:[e.jsx("input",{id:"whatsapp-pairing-phone",className:"input",value:L,onChange:a=>_(a.target.value),inputMode:"numeric"}),e.jsx("button",{className:"btn btn-secondary",type:"button",onClick:()=>void O(),disabled:P!==null,children:P==="code"?p("whatsapp.requestingCode","Requesting code..."):p("whatsapp.requestPairingCode","Request pairing code")})]}),n?.pairingCode&&e.jsx("output",{className:"whatsapp-pairing-code-output",children:n.pairingCode})]}),R==="connected"&&e.jsx("p",{className:"whatsapp-pairing-success",children:p("whatsapp.connectedSuccess","WhatsApp is paired and ready to receive messages from allowed senders.")}),A&&e.jsx("p",{className:"field-error",children:A}),e.jsx("button",{className:"btn btn-danger",type:"button",onClick:()=>void U(),disabled:P!==null,"data-testid":"whatsapp-pairing-logout",children:P==="logout"?p("whatsapp.loggingOut","Logging out..."):p("whatsapp.logoutRepair","Logout and re-pair")}),e.jsxs("aside",{className:"whatsapp-pairing-instructions","aria-label":p("whatsapp.instructionsLabel","WhatsApp pairing instructions"),"data-testid":"whatsapp-pairing-instructions",children:[e.jsx("h6",{children:p("whatsapp.pairingConfiguration","Pairing and configuration")}),e.jsxs("ol",{children:[e.jsx("li",{children:p("whatsapp.installPlugin","Install and enable this plugin, then keep this settings panel open.")}),e.jsx("li",{children:p("whatsapp.allowedSenders","Set {{label}}; an empty list blocks all inbound messages.",{label:"Allowed WhatsApp Senders"})}),e.jsx("li",{children:p("whatsapp.choosePairingMethod","Choose {{qr}} to scan in WhatsApp Linked Devices, or {{code}} to enter a phone number and request a pairing code.",{qr:"QR",code:"code"})}),e.jsx("li",{children:p("whatsapp.waitConnected","Wait for the status above to become {{status}}.",{status:"connected"})}),e.jsx("li",{children:p("whatsapp.repairInstructions","Use Logout and re-pair to start over. If QR is still pending, wait briefly or refresh status for a new code.")})]})]})]})}const Pe="fusion-plugin-agent-browser",je={enabled:{type:"boolean",label:"Enable Agent Browser",group:"General"},installChannel:{type:"enum",label:"Install Channel",enumValues:["stable","beta","nightly"],defaultValue:"stable",group:"General"},commandTimeoutMs:{type:"number",label:"Command Timeout (ms)",defaultValue:12e4,group:"General"},headlessMode:{type:"boolean",label:"Headless Mode",defaultValue:!0,group:"Browser"},allowedDomains:{type:"array",label:"Allowed Domains",itemType:"string",group:"Browser"},promptExecutorSystem:{type:"string",label:"Executor System Prompt",multiline:!0,group:"Prompt Contributions"},promptExecutorTask:{type:"string",label:"Executor Task Prompt",multiline:!0,group:"Prompt Contributions"},promptTriage:{type:"string",label:"Triage Prompt",multiline:!0,group:"Prompt Contributions"},promptReviewer:{type:"string",label:"Reviewer Prompt",multiline:!0,group:"Prompt Contributions"},promptHeartbeat:{type:"string",label:"Heartbeat Prompt",multiline:!0,group:"Prompt Contributions"},skillExposure:{type:"enum",label:"Skill Exposure",enumValues:["none","selected","all"],defaultValue:"selected",group:"Skills"}},Ne={General:"plugins.agentBrowser.groupGeneral",Browser:"plugins.agentBrowser.groupBrowser","Prompt Contributions":"plugins.agentBrowser.groupPromptContributions",Skills:"plugins.agentBrowser.groupSkills"},Se={"Enable Agent Browser":"plugins.agentBrowser.labelEnabled","Install Channel":"plugins.agentBrowser.labelInstallChannel","Command Timeout (ms)":"plugins.agentBrowser.labelCommandTimeoutMs","Headless Mode":"plugins.agentBrowser.labelHeadlessMode","Allowed Domains":"plugins.agentBrowser.labelAllowedDomains","Executor System Prompt":"plugins.agentBrowser.labelPromptExecutorSystem","Executor Task Prompt":"plugins.agentBrowser.labelPromptExecutorTask","Triage Prompt":"plugins.agentBrowser.labelPromptTriage","Reviewer Prompt":"plugins.agentBrowser.labelPromptReviewer","Heartbeat Prompt":"plugins.agentBrowser.labelPromptHeartbeat","Skill Exposure":"plugins.agentBrowser.labelSkillExposure"},we=[{id:"fusion-plugin-hermes-runtime",name:"Hermes Runtime",description:"Runtime provider for Hermes CLI-backed execution.",category:"runtime",path:"./plugins/fusion-plugin-hermes-runtime",experimental:!0},{id:"fusion-plugin-paperclip-runtime",name:"Paperclip Runtime",description:"Runtime provider for Paperclip agent connections.",category:"runtime",path:"./plugins/fusion-plugin-paperclip-runtime"},{id:"fusion-plugin-openclaw-runtime",name:"OpenClaw Runtime",description:"Runtime provider for OpenClaw execution.",category:"runtime",path:"./plugins/fusion-plugin-openclaw-runtime",experimental:!0},{id:"fusion-plugin-droid-runtime",name:"Droid Runtime",description:"Runtime provider for Droid CLI execution.",category:"runtime",path:"./plugins/fusion-plugin-droid-runtime",experimental:!0},{id:"fusion-plugin-dependency-graph",name:"Dependency Graph",description:"Dashboard plugin for task dependency graph visualization.",category:"integration",path:"./plugins/fusion-plugin-dependency-graph"},{id:"fusion-plugin-reports",name:"Reports",description:"View report history, compare runs side-by-side, and export standalone HTML summaries.",category:"integration",path:"./plugins/fusion-plugin-reports"},{id:"fusion-plugin-whatsapp-chat",name:"WhatsApp Chat",description:"Pairs to WhatsApp Web (multi-device) with QR or pairing code, then bridges direct chats to a Fusion agent.",category:"integration",path:"./plugins/fusion-plugin-whatsapp-chat"},{id:"fusion-plugin-cli-printing-press",name:"CLI Printing Press",description:"Guided wizard for drafting external service CLI definitions.",category:"integration",path:"./plugins/fusion-plugin-cli-printing-press"},{id:"fusion-plugin-compound-engineering",name:"Compound Engineering",description:"A dedicated dashboard surface for compound-engineering artifacts and interactive ce-* sessions.",category:"integration",path:"./plugins/fusion-plugin-compound-engineering"},{id:"fusion-plugin-quality",name:"Quality",description:"Task QA tab and Quality hub: preview servers, test runs, reports, screenshots, and suggested cases.",category:"integration",path:"./plugins/fusion-plugin-quality"},{id:"fusion-plugin-linear-import",name:"Linear Import",description:"Browse Linear issues and import selected issues as Fusion triage tasks through plugin-owned settings.",category:"integration",path:"./plugins/fusion-plugin-linear-import"},{id:Pe,name:"Agent Browser",description:"Built-in integration metadata. Package install support lands in FN-3101.",category:"integration",hasSetup:!0}],T={started:"var(--color-success)",loaded:"var(--color-warning)",error:"var(--color-error)",stopped:"var(--color-muted)",installed:"var(--color-info)"};function ds(r){const c=r.settingsSchema,p=c&&Object.keys(c).length>0;return r.id!==Pe?p?c:void 0:p?{...je,...c}:je}function gs(r){const c=new Map,p=[];for(const[n,x]of Object.entries(r))if(x.group){const f=c.get(x.group)??[];f.push([n,x]),c.set(x.group,f)}else p.push([n,x]);return{grouped:c,ungrouped:p}}function ve(r,c="plugin-error-text"){return r.state!=="error"||!r.error?null:e.jsx("p",{className:c,title:r.error,children:r.error})}function ws({addToast:r,projectId:c,onPluginsChanged:p}){const{t:n}=Ce("app"),[x,f]=d.useState([]),[F,L]=d.useState(!0),[_,A]=d.useState(!1),[w,P]=d.useState(""),[k,v]=d.useState(!1),[O,U]=d.useState(!1),[B,R]=d.useState(null),[a,y]=d.useState(null),[m,j]=d.useState({}),[Re,J]=d.useState(!1),[Y,X]=d.useState(null),[Z,Ee]=d.useState([]),[Ie,ee]=d.useState(!0),[se,ne]=d.useState(null),[N,ke]=d.useState(""),[S,Be]=d.useState(""),[Ae,ie]=d.useState(null),q=d.useRef(null),[Fe,z]=d.useState({}),[Le,te]=d.useState(null),[$,ae]=d.useState(null),{confirm:qe}=ze(),b=d.useCallback(async(s=!1,i)=>{try{s||L(!0);const l=await He(c);f(i?l.some(o=>o.id===i.id)?l.map(o=>o.id===i.id?i:o):[...l,i]:l)}catch(l){r(n("plugins.loadFailed","Failed to load plugins: {{error}}",{error:l instanceof Error?l.message:String(l)}),"error")}finally{s||L(!1)}},[c,r]),E=d.useCallback(async(s=N,i=S)=>{try{ee(!0),ne(null);const l=await Ve(s,i||void 0,c);Ee(l)}catch(l){const o=l instanceof Error?l.message:String(l);ne(o)}finally{ee(!1)}},[c,S,N]);d.useEffect(()=>{b()},[b]),d.useEffect(()=>(q.current&&clearTimeout(q.current),q.current=setTimeout(()=>{E(N,S)},300),()=>{q.current&&clearTimeout(q.current)}),[E,S,N]),d.useEffect(()=>{const s=we.filter(l=>l.hasSetup&&x.some(o=>o.id===l.id));if(s.length===0)return;let i=!1;return Promise.all(s.map(async l=>{try{const o=await ge(l.id,c);if(i)return;z(g=>({...g,[l.id]:o}))}catch{if(i)return;z(o=>({...o,[l.id]:{hasSetup:!0,setupCheckDeferred:!0,deferredReason:"plugin-not-started",pluginState:"installed"}}))}})),()=>{i=!0}},[x,c]);const De=d.useRef([]);De.current=x,d.useEffect(()=>{const s=c?`?projectId=${encodeURIComponent(c)}`:"",i=l=>{try{const o=JSON.parse(l.data);if(o.scope==="project"&&(o.projectId??c)!==c)return;switch(o.transition){case"installing":case"enabled":case"disabled":case"settings-updated":E(N,S),f(g=>{const u=g.findIndex(t=>t.id===o.pluginId);if(u>=0){const t=[...g];return t[u]={...t[u],enabled:o.enabled,state:o.state,settings:o.settings,error:o.error},t}else return b(),g});break;case"state-changed":f(g=>{const u=g.findIndex(t=>t.id===o.pluginId);if(u>=0){const t=[...g];return t[u]={...t[u],state:o.state,error:o.error},t}return g});break;case"uninstalled":f(g=>g.filter(u=>u.id!==o.pluginId)),E(N,S);break;case"error":f(g=>{const u=g.findIndex(t=>t.id===o.pluginId);if(u>=0){const t=[...g];return t[u]={...t[u],state:o.state,error:o.error},t}return g});break}}catch{}};return Qe(`/api/events${s}`,{events:{"plugin:lifecycle":i},onReconnect:()=>{b(),E(N,S)}})},[c,b,E,S,N]);const le=async()=>{if(!w.trim()){r(n("plugins.installPathRequired","Please enter a plugin path"),"error");return}try{v(!0),await Q({path:w,...O?{aiScanOnLoad:!0}:{}},c),r(n("plugins.installedGlobally","Plugin installed globally"),"success"),A(!1),P(""),U(!1),await b(),p?.()}catch(s){r(n("plugins.installFailed","Failed to install plugin: {{error}}",{error:s instanceof Error?s.message:String(s)}),"error")}finally{v(!1)}},Ge=async s=>{if(!s.path){r(n("plugins.builtinNoPackage","{{name}} is built in and does not have an installable package yet",{name:s.name}),"warning");return}try{X(s.id),await Q({path:s.path},c),r(n("plugins.builtinInstalledGlobally","{{name}} installed globally",{name:s.name}),"success"),await b(),p?.()}catch(i){r(n("plugins.builtinInstallFailed","Failed to install {{name}}: {{error}}",{name:s.name,error:i instanceof Error?i.message:String(i)}),"error")}finally{X(null)}},Oe=async s=>{if(!s.path){r(n("plugins.registryNotInstallable","{{name}} is not available for one-click install yet",{name:s.name}),"warning");return}try{ie(s.id),await Q({path:s.path},c),r(n("plugins.registryInstalled","{{name}} installed and enabled",{name:s.name}),"success"),await b(),p?.(),await E(N,S)}catch(i){r(n("plugins.registryInstallFailed","Failed to install {{name}}: {{error}}",{name:s.name,error:i instanceof Error?i.message:String(i)}),"error")}finally{ie(null)}},re=async s=>{try{ae(s.id);const i=await rs(s.id,c);if(!i.success){r(n("plugins.setupInstallFailed","Failed to install {{name}} setup: {{error}}",{name:s.name,error:i.error??n("plugins.unknownError","unknown error")}),"error");return}r(n("plugins.setupInstalled","{{name}} setup installed",{name:s.name}),"success"),te(s.id);const l=await ge(s.id,c);z(o=>({...o,[s.id]:l}))}catch(i){r(n("plugins.setupInstallFailed","Failed to install {{name}} setup: {{error}}",{name:s.name,error:i instanceof Error?i.message:String(i)}),"error")}finally{ae(null),te(null)}},H=async s=>{try{const i=await ts(s.id,c);if(f(l=>l.map(o=>o.id===i.id?i:o)),i.state==="error"){r(n("plugins.enableFailed","Failed to enable {{name}}: {{error}}",{name:s.name,error:i.error??n("plugins.unknownError","unknown error")}),"error"),await b();return}r(n("plugins.enabledForProject","{{name}} enabled for this project",{name:s.name}),"success"),await b(!0,i),p?.()}catch(i){r(n("plugins.enablePluginFailed","Failed to enable plugin: {{error}}",{error:i instanceof Error?i.message:String(i)}),"error")}},V=async s=>{try{const i=await is(s.id,c);f(l=>l.map(o=>o.id===i.id?i:o)),r(n("plugins.disabledForProject","{{name}} disabled for this project",{name:s.name}),"success"),await b(!0,i),p?.()}catch(i){r(n("plugins.disablePluginFailed","Failed to disable plugin: {{error}}",{error:i instanceof Error?i.message:String(i)}),"error")}},Ue=async s=>{s.enabled?await V(s):await H(s)},oe=async s=>{try{R(s.id),await ns(s.id,c),r(n("plugins.reloaded","{{name}} reloaded",{name:s.name}),"success"),await b()}catch(i){r(n("plugins.reloadFailed","Failed to reload plugin: {{error}}",{error:i instanceof Error?i.message:String(i)}),"error")}finally{R(null)}},ue=async s=>{if(await qe({title:n("plugins.uninstallTitle","Uninstall Plugin Globally"),message:n("plugins.uninstallConfirm",'Are you sure you want to uninstall "{{name}}" globally (all projects)?',{name:s.name}),danger:!0}))try{await as(s.id,c),r(n("plugins.uninstalledGlobally","{{name}} uninstalled globally",{name:s.name}),"success"),await b(),p?.(),y(null)}catch(l){r(n("plugins.uninstallFailed","Failed to uninstall plugin: {{error}}",{error:l instanceof Error?l.message:String(l)}),"error")}},$e=async(s,i)=>{try{await Ze(s.id,{aiScanOnLoad:i},c),r(i?n("plugins.aiScanEnabled","AI scan on load enabled"):n("plugins.aiScanDisabled","AI scan on load disabled"),"success"),await b()}catch(l){r(n("plugins.updateFailed","Failed to update plugin: {{error}}",{error:l instanceof Error?l.message:String(l)}),"error")}},We=async s=>{try{await es(s.id,c),r(n("plugins.rescanned","{{name}} rescanned",{name:s.name}),"success"),await b()}catch(i){r(n("plugins.rescanFailed","Failed to rescan plugin: {{error}}",{error:i instanceof Error?i.message:String(i)}),"error")}},W=async s=>{y(s);try{J(!0);const i=await ls(s.id,c);j(i)}catch{j({})}finally{J(!1)}},Me=async()=>{if(a)try{await ss(a.id,m,c),r(n("plugins.settingsSaved","Settings saved"),"success")}catch(s){r(n("plugins.saveSettingsFailed","Failed to save settings: {{error}}",{error:s instanceof Error?s.message:String(s)}),"error")}};if(a)return e.jsxs("div",{className:"plugin-manager-detail","data-testid":"plugin-manager-detail",children:[e.jsxs("div",{className:"plugin-manager-detail-header",children:[e.jsx("button",{className:"btn-icon",onClick:()=>y(null),"aria-label":n("plugins.backToList","Back to plugin list"),children:e.jsx(me,{size:16})}),e.jsxs("div",{className:"plugin-detail-title",children:[e.jsxs("div",{className:"plugin-detail-title-copy",children:[e.jsx("h4",{className:"plugin-detail-name",children:a.name}),ve(a,"plugin-error-text plugin-error-text--detail")]}),e.jsx("span",{className:"plugin-state-badge",style:{color:T[a.state]||T.installed},children:a.state})]})]}),e.jsxs("div",{className:"plugin-detail-content",children:[e.jsxs("div",{className:"plugin-detail-card",children:[a.description&&e.jsx("p",{className:"plugin-description",children:a.description}),a.author&&e.jsxs("p",{className:"plugin-detail-meta-row",children:[e.jsx("span",{className:"text-muted",children:n("plugins.author","Author:")}),a.author]}),a.homepage&&e.jsxs("p",{className:"plugin-detail-meta-row plugin-homepage",children:[e.jsx("span",{className:"text-muted",children:n("plugins.homepage","Homepage:")}),e.jsxs("a",{href:a.homepage,target:"_blank",rel:"noopener noreferrer",children:[a.homepage,e.jsx(Ke,{size:12})]})]}),e.jsxs("p",{className:"plugin-detail-meta-row",children:[e.jsx("span",{className:"text-muted",children:n("plugins.version","Version:")}),a.version]})]}),e.jsxs("div",{className:"plugin-detail-card",children:[e.jsx("h5",{className:"plugin-detail-section-heading",children:n("plugins.securityScan","Security Scan")}),e.jsxs("div",{className:"plugin-security-row",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:!!a.aiScanOnLoad,onChange:s=>void $e(a,s.target.checked)}),n("plugins.enableAiScanBeforeLoad","Enable AI scan before load/reload")]}),e.jsxs("button",{className:"btn btn-secondary btn-sm",onClick:()=>void We(a),children:[e.jsx(Je,{size:14})," ",n("plugins.rescanAndReload","Rescan and Reload")]})]}),e.jsx("p",{className:"text-muted",children:n("plugins.aiScanHint","Turning this on only updates configuration. Use Rescan and Reload to run it now.")}),a.lastSecurityScan?e.jsxs("div",{className:"plugin-security-results",children:[e.jsxs("div",{className:"plugin-security-header",children:[e.jsx("span",{className:`plugin-state-badge plugin-security-badge plugin-security-badge--${a.lastSecurityScan.verdict}`,children:a.lastSecurityScan.verdict}),e.jsx("span",{className:"text-muted",children:a.lastSecurityScan.scannedAt})]}),e.jsx("p",{className:"plugin-security-summary",children:a.lastSecurityScan.summary}),e.jsxs("details",{children:[e.jsx("summary",{children:n("plugins.findings","Findings ({{count}})",{count:a.lastSecurityScan.findings.length})}),e.jsx("ul",{className:"plugin-security-findings",children:a.lastSecurityScan.findings.map((s,i)=>e.jsxs("li",{children:[e.jsx("strong",{children:s.severity})," ",s.category," — ",s.file,": ",s.reason]},`${s.file}-${i}`))})]})]}):e.jsx("p",{className:"text-muted",children:n("plugins.noSecurityScan","No security scan has been run yet.")})]}),e.jsxs("div",{className:"plugin-detail-card",children:[e.jsx("h5",{className:"plugin-detail-section-heading",children:n("plugins.settings","Settings")}),a.id==="fusion-plugin-whatsapp-chat"&&e.jsx(ps,{projectId:c,settings:m}),Re?e.jsx("p",{className:"text-muted",children:e.jsx(he,{label:n("plugins.loading","Loading...")})}):(()=>{const s=ds(a);return s&&Object.keys(s).length>0?e.jsxs("div",{className:"plugin-settings-form",children:[(()=>{const{grouped:i,ungrouped:l}=gs(s),o=[];l.length>0&&o.push({title:null,entries:l});for(const[g,u]of i.entries())o.push({title:g,entries:u});return o.map(g=>e.jsxs("div",{className:g.title?"plugin-settings-group":void 0,children:[g.title&&e.jsx("h6",{className:"plugin-settings-group-heading",children:Ne[g.title]?n(Ne[g.title],g.title):g.title}),g.entries.map(([u,t])=>{const I=`setting-${u}-help`,D=t.label?Se[t.label]?n(Se[t.label],t.label):t.label:u;return e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:`setting-${u}`,children:[D,t.required&&" *"]}),t.type==="string"&&!t.multiline&&e.jsx("input",{className:"input",type:"text",id:`setting-${u}`,value:m[u]??"",onChange:h=>j({...m,[u]:h.target.value}),placeholder:t.description,"aria-describedby":t.description&&!t.required?I:void 0}),t.type==="string"&&t.multiline&&e.jsx("textarea",{className:"input",id:`setting-${u}`,rows:4,value:m[u]??"",onChange:h=>j({...m,[u]:h.target.value}),placeholder:t.description,"aria-describedby":t.description&&!t.required?I:void 0}),t.type==="password"&&e.jsx("input",{className:"input",type:"password",id:`setting-${u}`,value:m[u]??"",onChange:h=>j({...m,[u]:h.target.value}),placeholder:t.description,"aria-describedby":t.description&&!t.required?I:void 0}),t.type==="number"&&e.jsx("input",{className:"input",type:"number",id:`setting-${u}`,value:m[u]??"",onChange:h=>j({...m,[u]:Number(h.target.value)}),"aria-describedby":t.description&&!t.required?I:void 0}),t.type==="boolean"&&e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:m[u]??!1,onChange:h=>j({...m,[u]:h.target.checked})}),t.description]}),t.type==="enum"&&e.jsxs("select",{className:"select",id:`setting-${u}`,value:m[u]??"",onChange:h=>j({...m,[u]:h.target.value}),"aria-describedby":t.description&&!t.required?I:void 0,children:[e.jsx("option",{value:"",children:n("plugins.selectOption","Select...")}),t.enumValues?.map(h=>e.jsx("option",{value:h,children:h},h))]}),t.type==="array"&&e.jsxs("div",{className:"plugin-settings-array",children:[m[u]?.map((h,C)=>e.jsxs("div",{className:"plugin-settings-array-item",children:[e.jsx("input",{className:"input",type:t.itemType==="number"?"number":"text",value:h??"",onChange:M=>{const G=M.target.value,de=[...m[u]||[]];de[C]=t.itemType==="number"?Number(G):G,j({...m,[u]:de})}}),e.jsx("button",{className:"btn-icon",onClick:()=>{const G=[...m[u]||[]];G.splice(C,1),j({...m,[u]:G})},"aria-label":n("plugins.removeItem","Remove item"),children:e.jsx(me,{size:14})})]},C)),e.jsxs("button",{className:"btn btn-secondary",onClick:()=>{const h=m[u]||[],C=t.itemType==="number"?0:"";j({...m,[u]:[...h,C]})},children:[e.jsx(be,{size:14})," ",n("plugins.addItem","Add Item")]})]}),t.description&&!t.required&&!t.multiline&&e.jsx("span",{id:I,className:"form-help",children:t.description})]},u)})]},g.title??"ungrouped"))})(),e.jsx("button",{className:"btn btn-primary",onClick:Me,children:n("plugins.saveSettings","Save Settings")})]}):e.jsx("p",{className:"text-muted",children:n("plugins.noConfigurableSettings","No configurable settings.")})})()]}),e.jsxs("div",{className:"plugin-detail-actions",children:[a.state==="started"&&e.jsxs("button",{className:"btn btn-secondary",onClick:()=>oe(a),disabled:B===a.id,children:[e.jsx(ye,{size:14,className:B===a.id?"spin":""}),B===a.id?n("plugins.reloading","Reloading..."):n("plugins.reload","Reload")]}),a.enabled?e.jsx("button",{className:"btn btn-secondary",onClick:()=>V(a),children:n("plugins.disableInProject","Disable in Project")}):e.jsx("button",{className:"btn btn-primary",onClick:()=>H(a),children:n("plugins.enableInProject","Enable in Project")}),e.jsxs("button",{className:"btn btn-danger",onClick:()=>ue(a),children:[e.jsx(xe,{size:14})," ",n("plugins.uninstallGlobally","Uninstall Globally")]})]})]})]});const ce=new Map(x.map(s=>[s.id,s])),pe=x,Te=()=>e.jsxs("section",{className:"plugin-registry-section","aria-label":n("plugins.browseRegistry","Browse Registry"),children:[e.jsxs("div",{className:"plugin-registry-header",children:[e.jsxs("div",{className:"plugin-registry-heading-copy",children:[e.jsx("h4",{className:"plugin-registry-heading",children:n("plugins.browseRegistry","Browse Registry")}),e.jsx("p",{className:"plugin-registry-description",children:n("plugins.registryDescription","Discover curated runtimes and integrations that can be added to this Fusion workspace.")})]}),e.jsxs("div",{className:"plugin-registry-controls",children:[e.jsxs("label",{className:"plugin-registry-category-label",children:[e.jsx("span",{className:"sr-only",children:n("plugins.registryCategory","Registry category")}),e.jsxs("select",{className:"select plugin-registry-category-select",value:S,onChange:s=>Be(s.target.value),"aria-label":n("plugins.registryCategory","Registry category"),children:[e.jsx("option",{value:"",children:n("plugins.registryCategoryAll","All Categories")}),e.jsx("option",{value:"runtime",children:n("plugins.registryCategoryRuntime","Runtime")}),e.jsx("option",{value:"integration",children:n("plugins.registryCategoryIntegration","Integration")})]})]}),e.jsxs("label",{className:"plugin-registry-search-label",children:[e.jsx("span",{className:"sr-only",children:n("plugins.searchRegistry","Search registry")}),e.jsx("input",{className:"input plugin-registry-search-input",type:"search",value:N,onChange:s=>ke(s.target.value),placeholder:n("plugins.searchRegistryPlaceholder","Search registry plugins")})]})]})]}),Ie?e.jsxs("div",{className:"plugin-registry-state",role:"status",children:[e.jsx(fe,{size:14,className:"spin"}),n("plugins.registryLoading","Loading registry...")]}):se?e.jsxs("div",{className:"plugin-registry-state plugin-registry-state--error",role:"alert",children:[e.jsx("span",{children:n("plugins.registryLoadFailed","Failed to load registry: {{error}}",{error:se})}),e.jsx("button",{className:"btn btn-secondary btn-sm plugin-registry-retry",onClick:()=>void E(N,S),children:n("plugins.retry","Retry")})]}):Z.length===0?e.jsx("div",{className:"plugin-registry-state",children:N.trim()?n("plugins.registryEmptySearch","No registry plugins match your search."):n("plugins.registryEmpty","No registry plugins are available.")}):e.jsx("div",{className:"plugin-registry-list","aria-label":n("plugins.registryPluginResults","Registry plugin results"),children:Z.map(s=>{const i=ce.get(s.id),l=Ae===s.id;return e.jsxs("div",{className:"plugin-registry-item",children:[e.jsxs("div",{className:"plugin-registry-meta",children:[e.jsxs("div",{className:"plugin-registry-title-row",children:[e.jsx("span",{className:"plugin-registry-name",children:s.name}),e.jsxs("span",{className:"plugin-registry-version",children:["v",s.version]}),e.jsx("span",{className:"plugin-registry-badge",children:s.category}),s.installed&&e.jsxs("span",{className:"plugin-registry-status plugin-registry-status--installed",children:[n("plugins.statusInstalled","Installed"),s.installedVersion&&s.installedVersion!==s.version?` · v${s.installedVersion}`:""]})]}),e.jsx("span",{className:"plugin-registry-description-text",children:s.description}),e.jsx("span",{className:"plugin-registry-author",children:n("plugins.registryByAuthor","By {{author}}",{author:s.author})})]}),e.jsx("div",{className:"plugin-registry-actions",children:s.installed?e.jsx("button",{className:"btn btn-secondary btn-sm plugin-registry-action",onClick:()=>{i?W(i):b()},children:n("plugins.manage","Manage")}):s.canInstall?e.jsx("button",{className:"btn btn-primary btn-sm plugin-registry-action",onClick:()=>void Oe(s),disabled:l,children:l?n("plugins.installing","Installing..."):n("plugins.installFromRegistry","Install")}):e.jsx("span",{className:"plugin-registry-coming-soon",children:n("plugins.registryComingSoon","Coming Soon")})})]},s.id)})})]}),_e=()=>e.jsxs("section",{className:"plugin-builtins-section","aria-label":n("plugins.builtinPlugins","Built-in Plugins"),children:[e.jsxs("div",{className:"plugin-builtins-header",children:[e.jsx("h4",{className:"plugin-builtins-heading",children:n("plugins.builtinPlugins","Built-in Plugins")}),e.jsx("p",{className:"plugin-builtins-description",children:n("plugins.builtinPluginsCatalog","Built-in plugin catalog for runtimes and integrations.")})]}),e.jsx("div",{className:"plugin-builtins-list","aria-label":n("plugins.builtinPluginRecommendations","Built-in plugin recommendations"),children:we.map(s=>{const i=ce.get(s.id),l=!!i,o=Fe[s.id],g=!!(o&&"setupCheckDeferred"in o&&o.setupCheckDeferred),u=o&&"status"in o?o.status:void 0,t=l&&s.hasSetup&&o?.hasSetup&&!g&&i?.state==="started"&&(u==="not-installed"||u==="error"),I=l&&o?.hasSetup&&u==="installed",D=Le===s.id,h=!s.path,C=s.category==="runtime",M=i?.enabled;return e.jsxs("div",{className:"plugin-builtins-item",children:[e.jsxs("div",{className:"plugin-builtins-meta",children:[e.jsx("span",{className:"plugin-builtins-name",children:s.name}),s.experimental&&e.jsx("span",{className:"plugin-builtins-runtime-badge",children:n("plugins.experimental","Experimental")}),e.jsx("span",{className:"plugin-builtins-runtime-badge",children:s.category}),e.jsx("span",{className:`plugin-builtins-status ${l?"plugin-builtins-status--installed":"plugin-builtins-status--available"}`,children:l?n("plugins.statusInstalled","Installed"):h?n("plugins.statusBuiltIn","Built in"):n("plugins.statusNotInstalled","Not installed")}),C&&M===!1&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--warning",children:n("plugins.builtinDisabled","Disabled")}),t&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--warning",children:n("plugins.setupRequired","Setup required")}),I&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--ready",children:n("plugins.setupReady","Setup ready")}),D&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--pending",children:n("plugins.checkingSetup","Checking setup...")}),g&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--deferred",children:n("plugins.startPluginToCheckSetup","Start plugin to check setup")}),e.jsx("span",{className:"plugin-builtins-description-text",children:s.description})]}),e.jsxs("div",{className:"plugin-builtins-actions",children:[C&&i&&e.jsxs("label",{className:"toggle-switch",children:[e.jsx("input",{type:"checkbox",checked:i.enabled,onChange:()=>void Ue(i),"aria-label":i.enabled?n("plugins.disablePlugin","Disable {{name}}",{name:s.name}):n("plugins.enablePlugin","Enable {{name}}",{name:s.name})}),e.jsx("span",{className:"toggle-slider"})]}),h?l&&t?e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>void re(s),disabled:$===s.id||D,children:$===s.id?n("plugins.settingUp","Setting up..."):n("plugins.installSetup","Install Setup")}):l&&i?e.jsx("button",{className:"btn btn-secondary btn-sm",onClick:()=>void W(i),children:n("plugins.manage","Manage")}):C?null:e.jsx("span",{className:"plugin-builtins-metadata-only",children:n("plugins.builtinMetadataOnly","Built-in metadata only")}):e.jsx("button",{className:`btn ${l&&!t?"btn-secondary":"btn-primary"} btn-sm`,onClick:()=>{if(!l){Ge(s);return}if(t){re(s);return}i&&W(i)},disabled:Y===s.id||$===s.id||D,children:l?t?$===s.id?n("plugins.settingUp","Setting up..."):n("plugins.installSetup","Install Setup"):n("plugins.manage","Manage"):Y===s.id?n("plugins.installing","Installing..."):n("plugins.installNamed","Install {{name}}",{name:s.name})})]})]},s.id)})})]});return e.jsxs("div",{className:"plugin-manager","data-testid":"plugin-manager",children:[e.jsxs("div",{className:"plugin-manager-header",children:[e.jsx("span",{className:"plugin-manager-header-title",children:n("plugins.installedPlugins","Installed Plugins")}),e.jsxs("div",{className:"plugin-manager-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:()=>void b(),title:n("plugins.refresh","Refresh"),"aria-label":n("plugins.refreshPluginList","Refresh plugin list"),children:[e.jsx(fe,{size:14,className:F?"spin":""}),n("plugins.refresh","Refresh")]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>A(!0),children:[e.jsx(be,{size:14})," ",n("plugins.install","Install")]})]})]}),_&&e.jsxs("div",{className:"plugin-install-form",children:[e.jsx("p",{className:"plugin-install-hint",children:n("plugins.installHint","Browse to a plugin package root (contains manifest.json) or a built dist directory.")}),e.jsx(os,{value:w,onChange:P,placeholder:n("plugins.installPathPlaceholder","Absolute path to plugin directory or dist folder"),onInputKeyDown:s=>{s.key==="Enter"&&(s.preventDefault(),le())}}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:O,onChange:s=>U(s.target.checked)}),n("plugins.enableAiSecurityScan","Enable AI security scan on load")]}),e.jsxs("div",{className:"plugin-install-actions",children:[e.jsx("button",{className:"btn btn-primary",onClick:le,disabled:k||!w.trim(),children:k?n("plugins.installing","Installing..."):n("plugins.installPluginGlobally","Install Plugin Globally")}),e.jsx("button",{className:"btn btn-secondary",onClick:()=>{A(!1),P("")},children:n("plugins.cancel","Cancel")})]})]}),F?e.jsx("div",{className:"settings-empty-state",children:e.jsx(he,{label:n("plugins.loadingPlugins","Loading plugins...")})}):e.jsxs(e.Fragment,{children:[pe.length===0?e.jsxs("div",{className:"settings-empty-state",children:[e.jsx(Ye,{size:32,className:"text-muted"}),e.jsx("p",{children:n("plugins.noPluginsInstalled","No plugins installed.")}),e.jsx("p",{className:"text-muted",children:n("plugins.noPluginsHint","Install a plugin to get started, or use the built-in catalog below.")})]}):e.jsx("div",{className:"plugin-list",children:pe.map(s=>e.jsxs("div",{className:"plugin-item",children:[e.jsx("div",{className:"plugin-info",children:e.jsxs("div",{className:"plugin-copy",children:[e.jsxs("div",{className:"plugin-copy-header",children:[e.jsx("span",{className:"plugin-name",children:s.name}),e.jsxs("span",{className:"plugin-version text-muted",children:["v",s.version]}),e.jsx("span",{className:"plugin-state-badge",style:{color:T[s.state]||T.installed},children:s.state})]}),ve(s)]})}),e.jsxs("div",{className:"plugin-actions",children:[s.state==="started"&&e.jsx("button",{className:"btn-icon",onClick:()=>oe(s),disabled:B===s.id,title:n("plugins.reload","Reload"),children:e.jsx(ye,{size:14,className:B===s.id?"spin":""})}),e.jsxs("label",{className:"toggle-switch",children:[e.jsx("input",{type:"checkbox",checked:s.enabled,onChange:()=>s.enabled?V(s):H(s),"aria-label":s.enabled?n("plugins.disablePlugin","Disable {{name}}",{name:s.name}):n("plugins.enablePlugin","Enable {{name}}",{name:s.name})}),e.jsx("span",{className:"toggle-slider"})]}),e.jsx("button",{className:"btn-icon",onClick:()=>W(s),title:n("plugins.settings","Settings"),children:e.jsx(Xe,{size:14})}),e.jsx("button",{className:"btn-icon",onClick:()=>ue(s),title:n("plugins.uninstallGloballyTitle","Uninstall globally"),children:e.jsx(xe,{size:14})})]})]},s.id))}),_e(),Te()]})]})}export{je as AGENT_BROWSER_SETTINGS_SCHEMA,Pe as BUILTIN_AGENT_BROWSER_PLUGIN_ID,we as BUILTIN_PLUGINS,ws as PluginManager,T as STATE_COLORS};
1
+ import{r as d,j as e}from"./vendor-react-SZ_qB27O.js";import{ag as ze,bg as He,bh as Ve,bi as ge,bj as Qe,X as me,aU as Ke,bk as Je,aK as he,P as be,b3 as ye,F as xe,R as fe,aN as Ye,a3 as Xe,bl as Ze,bm as es,bn as ss,bo as ns,bp as is,bq as ts,br as as,bs as Q,bt as ls,bu as rs}from"./index-oxnX59eO.js";import{D as os}from"./DirectoryPicker-BIvXWIB5.js";import{u as Ce}from"./vendor-i18n-Duky4gdQ.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";import"./vendor-xterm-BNq00GSj.js";import"./folder-open-DR6cRcNR.js";const us="/api/plugins/fusion-plugin-whatsapp-chat",cs=/^\d+$/;function K(r,c){const p=c?`?projectId=${encodeURIComponent(c)}`:"";return`${us}${r}${p}`}function ps({projectId:r,settings:c}){const{t:p}=Ce("app"),[n,x]=d.useState(null),[f,F]=d.useState(null),[L,_]=d.useState(()=>String(c?.pairingPhoneNumber??"")),[A,w]=d.useState(null),[P,k]=d.useState(null),v=d.useCallback(async()=>{try{const a=await fetch(K("/status",r)),y=await a.json();if(!a.ok)throw new Error(y.error??"WhatsApp pairing is unavailable. Enable the plugin and try again.");x(y),F(null)}catch(a){F(a instanceof Error?a.message:String(a))}},[r]);d.useEffect(()=>{v();const a=window.setInterval(()=>void v(),5e3);return()=>window.clearInterval(a)},[v]);const O=async()=>{const a=L.trim();if(!a||!cs.test(a)){w("Enter an E.164 phone number using digits only, without +.");return}k("code"),w(null);try{const y=await fetch(K("/pair-code",r),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({phoneNumber:a,...r?{projectId:r}:{}})}),m=await y.json();if(!y.ok)throw new Error(m.error??"Could not request a pairing code.");x(j=>({status:"awaiting-code",...j,pairingCode:m.pairingCode})),await v()}catch(y){w(y instanceof Error?y.message:String(y))}finally{k(null)}},U=async()=>{k("logout"),w(null);try{const a=await fetch(K("/logout",r),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r?{projectId:r}:{})});if(!a.ok){const y=await a.json();throw new Error(y.error??"Could not log out from WhatsApp.")}await v()}catch(a){w(a instanceof Error?a.message:String(a))}finally{k(null)}},B=c?.pairingMode==="code"?"code":"qr",R=n?.status??"starting";return e.jsxs("section",{className:"whatsapp-pairing-panel","aria-labelledby":"whatsapp-pairing-heading",children:[e.jsxs("div",{className:"whatsapp-pairing-heading-row",children:[e.jsxs("div",{children:[e.jsx("h5",{id:"whatsapp-pairing-heading",className:"plugin-detail-section-heading",children:p("whatsapp.pairing","WhatsApp pairing")}),e.jsx("p",{className:"whatsapp-pairing-description",children:p("whatsapp.description","Pair and monitor this project's WhatsApp connection here.")})]}),e.jsx("button",{className:"btn btn-secondary btn-sm",type:"button",onClick:()=>void v(),children:p("whatsapp.refreshStatus","Refresh status")})]}),e.jsxs("div",{className:`whatsapp-pairing-status whatsapp-pairing-status--${R}`,role:"status","data-testid":"whatsapp-pairing-status",children:[e.jsxs("strong",{children:[p("whatsapp.status","Status:")," ",R]}),n?.jid&&e.jsx("span",{children:p("whatsapp.connectedAs","Connected as {{jid}}",{jid:n.jid})}),(n?.lastError||f)&&e.jsx("span",{className:"field-error",children:n?.lastError??f})]}),R==="awaiting-qr"&&e.jsx("div",{className:"whatsapp-pairing-qr","data-testid":"whatsapp-pairing-qr",children:n?.qrDataUrl?e.jsx("img",{src:n.qrDataUrl,alt:p("whatsapp.qrCode","WhatsApp pairing QR code"),className:"whatsapp-pairing-qr-image"}):e.jsx("p",{className:"text-muted",children:p("whatsapp.waitingQr","Waiting for a fresh QR code. Keep this panel open and refresh if needed.")})}),(B==="code"||R==="awaiting-code")&&e.jsxs("div",{className:"whatsapp-pairing-code",children:[e.jsx("label",{htmlFor:"whatsapp-pairing-phone",children:p("whatsapp.phoneNumber","Phone number (E.164 digits without +)")}),e.jsxs("div",{className:"whatsapp-pairing-code-controls",children:[e.jsx("input",{id:"whatsapp-pairing-phone",className:"input",value:L,onChange:a=>_(a.target.value),inputMode:"numeric"}),e.jsx("button",{className:"btn btn-secondary",type:"button",onClick:()=>void O(),disabled:P!==null,children:P==="code"?p("whatsapp.requestingCode","Requesting code..."):p("whatsapp.requestPairingCode","Request pairing code")})]}),n?.pairingCode&&e.jsx("output",{className:"whatsapp-pairing-code-output",children:n.pairingCode})]}),R==="connected"&&e.jsx("p",{className:"whatsapp-pairing-success",children:p("whatsapp.connectedSuccess","WhatsApp is paired and ready to receive messages from allowed senders.")}),A&&e.jsx("p",{className:"field-error",children:A}),e.jsx("button",{className:"btn btn-danger",type:"button",onClick:()=>void U(),disabled:P!==null,"data-testid":"whatsapp-pairing-logout",children:P==="logout"?p("whatsapp.loggingOut","Logging out..."):p("whatsapp.logoutRepair","Logout and re-pair")}),e.jsxs("aside",{className:"whatsapp-pairing-instructions","aria-label":p("whatsapp.instructionsLabel","WhatsApp pairing instructions"),"data-testid":"whatsapp-pairing-instructions",children:[e.jsx("h6",{children:p("whatsapp.pairingConfiguration","Pairing and configuration")}),e.jsxs("ol",{children:[e.jsx("li",{children:p("whatsapp.installPlugin","Install and enable this plugin, then keep this settings panel open.")}),e.jsx("li",{children:p("whatsapp.allowedSenders","Set {{label}}; an empty list blocks all inbound messages.",{label:"Allowed WhatsApp Senders"})}),e.jsx("li",{children:p("whatsapp.choosePairingMethod","Choose {{qr}} to scan in WhatsApp Linked Devices, or {{code}} to enter a phone number and request a pairing code.",{qr:"QR",code:"code"})}),e.jsx("li",{children:p("whatsapp.waitConnected","Wait for the status above to become {{status}}.",{status:"connected"})}),e.jsx("li",{children:p("whatsapp.repairInstructions","Use Logout and re-pair to start over. If QR is still pending, wait briefly or refresh status for a new code.")})]})]})]})}const Pe="fusion-plugin-agent-browser",je={enabled:{type:"boolean",label:"Enable Agent Browser",group:"General"},installChannel:{type:"enum",label:"Install Channel",enumValues:["stable","beta","nightly"],defaultValue:"stable",group:"General"},commandTimeoutMs:{type:"number",label:"Command Timeout (ms)",defaultValue:12e4,group:"General"},headlessMode:{type:"boolean",label:"Headless Mode",defaultValue:!0,group:"Browser"},allowedDomains:{type:"array",label:"Allowed Domains",itemType:"string",group:"Browser"},promptExecutorSystem:{type:"string",label:"Executor System Prompt",multiline:!0,group:"Prompt Contributions"},promptExecutorTask:{type:"string",label:"Executor Task Prompt",multiline:!0,group:"Prompt Contributions"},promptTriage:{type:"string",label:"Triage Prompt",multiline:!0,group:"Prompt Contributions"},promptReviewer:{type:"string",label:"Reviewer Prompt",multiline:!0,group:"Prompt Contributions"},promptHeartbeat:{type:"string",label:"Heartbeat Prompt",multiline:!0,group:"Prompt Contributions"},skillExposure:{type:"enum",label:"Skill Exposure",enumValues:["none","selected","all"],defaultValue:"selected",group:"Skills"}},Ne={General:"plugins.agentBrowser.groupGeneral",Browser:"plugins.agentBrowser.groupBrowser","Prompt Contributions":"plugins.agentBrowser.groupPromptContributions",Skills:"plugins.agentBrowser.groupSkills"},Se={"Enable Agent Browser":"plugins.agentBrowser.labelEnabled","Install Channel":"plugins.agentBrowser.labelInstallChannel","Command Timeout (ms)":"plugins.agentBrowser.labelCommandTimeoutMs","Headless Mode":"plugins.agentBrowser.labelHeadlessMode","Allowed Domains":"plugins.agentBrowser.labelAllowedDomains","Executor System Prompt":"plugins.agentBrowser.labelPromptExecutorSystem","Executor Task Prompt":"plugins.agentBrowser.labelPromptExecutorTask","Triage Prompt":"plugins.agentBrowser.labelPromptTriage","Reviewer Prompt":"plugins.agentBrowser.labelPromptReviewer","Heartbeat Prompt":"plugins.agentBrowser.labelPromptHeartbeat","Skill Exposure":"plugins.agentBrowser.labelSkillExposure"},we=[{id:"fusion-plugin-hermes-runtime",name:"Hermes Runtime",description:"Runtime provider for Hermes CLI-backed execution.",category:"runtime",path:"./plugins/fusion-plugin-hermes-runtime",experimental:!0},{id:"fusion-plugin-paperclip-runtime",name:"Paperclip Runtime",description:"Runtime provider for Paperclip agent connections.",category:"runtime",path:"./plugins/fusion-plugin-paperclip-runtime"},{id:"fusion-plugin-openclaw-runtime",name:"OpenClaw Runtime",description:"Runtime provider for OpenClaw execution.",category:"runtime",path:"./plugins/fusion-plugin-openclaw-runtime",experimental:!0},{id:"fusion-plugin-droid-runtime",name:"Droid Runtime",description:"Runtime provider for Droid CLI execution.",category:"runtime",path:"./plugins/fusion-plugin-droid-runtime",experimental:!0},{id:"fusion-plugin-dependency-graph",name:"Dependency Graph",description:"Dashboard plugin for task dependency graph visualization.",category:"integration",path:"./plugins/fusion-plugin-dependency-graph"},{id:"fusion-plugin-reports",name:"Reports",description:"View report history, compare runs side-by-side, and export standalone HTML summaries.",category:"integration",path:"./plugins/fusion-plugin-reports"},{id:"fusion-plugin-whatsapp-chat",name:"WhatsApp Chat",description:"Pairs to WhatsApp Web (multi-device) with QR or pairing code, then bridges direct chats to a Fusion agent.",category:"integration",path:"./plugins/fusion-plugin-whatsapp-chat"},{id:"fusion-plugin-cli-printing-press",name:"CLI Printing Press",description:"Guided wizard for drafting external service CLI definitions.",category:"integration",path:"./plugins/fusion-plugin-cli-printing-press"},{id:"fusion-plugin-compound-engineering",name:"Compound Engineering",description:"A dedicated dashboard surface for compound-engineering artifacts and interactive ce-* sessions.",category:"integration",path:"./plugins/fusion-plugin-compound-engineering"},{id:"fusion-plugin-quality",name:"Quality",description:"Task QA tab and Quality hub: preview servers, test runs, reports, screenshots, and suggested cases.",category:"integration",path:"./plugins/fusion-plugin-quality"},{id:"fusion-plugin-linear-import",name:"Linear Import",description:"Browse Linear issues and import selected issues as Fusion triage tasks through plugin-owned settings.",category:"integration",path:"./plugins/fusion-plugin-linear-import"},{id:Pe,name:"Agent Browser",description:"Built-in integration metadata. Package install support lands in FN-3101.",category:"integration",hasSetup:!0}],T={started:"var(--color-success)",loaded:"var(--color-warning)",error:"var(--color-error)",stopped:"var(--color-muted)",installed:"var(--color-info)"};function ds(r){const c=r.settingsSchema,p=c&&Object.keys(c).length>0;return r.id!==Pe?p?c:void 0:p?{...je,...c}:je}function gs(r){const c=new Map,p=[];for(const[n,x]of Object.entries(r))if(x.group){const f=c.get(x.group)??[];f.push([n,x]),c.set(x.group,f)}else p.push([n,x]);return{grouped:c,ungrouped:p}}function ve(r,c="plugin-error-text"){return r.state!=="error"||!r.error?null:e.jsx("p",{className:c,title:r.error,children:r.error})}function ws({addToast:r,projectId:c,onPluginsChanged:p}){const{t:n}=Ce("app"),[x,f]=d.useState([]),[F,L]=d.useState(!0),[_,A]=d.useState(!1),[w,P]=d.useState(""),[k,v]=d.useState(!1),[O,U]=d.useState(!1),[B,R]=d.useState(null),[a,y]=d.useState(null),[m,j]=d.useState({}),[Re,J]=d.useState(!1),[Y,X]=d.useState(null),[Z,Ee]=d.useState([]),[Ie,ee]=d.useState(!0),[se,ne]=d.useState(null),[N,ke]=d.useState(""),[S,Be]=d.useState(""),[Ae,ie]=d.useState(null),q=d.useRef(null),[Fe,z]=d.useState({}),[Le,te]=d.useState(null),[$,ae]=d.useState(null),{confirm:qe}=ze(),b=d.useCallback(async(s=!1,i)=>{try{s||L(!0);const l=await He(c);f(i?l.some(o=>o.id===i.id)?l.map(o=>o.id===i.id?i:o):[...l,i]:l)}catch(l){r(n("plugins.loadFailed","Failed to load plugins: {{error}}",{error:l instanceof Error?l.message:String(l)}),"error")}finally{s||L(!1)}},[c,r]),E=d.useCallback(async(s=N,i=S)=>{try{ee(!0),ne(null);const l=await Ve(s,i||void 0,c);Ee(l)}catch(l){const o=l instanceof Error?l.message:String(l);ne(o)}finally{ee(!1)}},[c,S,N]);d.useEffect(()=>{b()},[b]),d.useEffect(()=>(q.current&&clearTimeout(q.current),q.current=setTimeout(()=>{E(N,S)},300),()=>{q.current&&clearTimeout(q.current)}),[E,S,N]),d.useEffect(()=>{const s=we.filter(l=>l.hasSetup&&x.some(o=>o.id===l.id));if(s.length===0)return;let i=!1;return Promise.all(s.map(async l=>{try{const o=await ge(l.id,c);if(i)return;z(g=>({...g,[l.id]:o}))}catch{if(i)return;z(o=>({...o,[l.id]:{hasSetup:!0,setupCheckDeferred:!0,deferredReason:"plugin-not-started",pluginState:"installed"}}))}})),()=>{i=!0}},[x,c]);const De=d.useRef([]);De.current=x,d.useEffect(()=>{const s=c?`?projectId=${encodeURIComponent(c)}`:"",i=l=>{try{const o=JSON.parse(l.data);if(o.scope==="project"&&(o.projectId??c)!==c)return;switch(o.transition){case"installing":case"enabled":case"disabled":case"settings-updated":E(N,S),f(g=>{const u=g.findIndex(t=>t.id===o.pluginId);if(u>=0){const t=[...g];return t[u]={...t[u],enabled:o.enabled,state:o.state,settings:o.settings,error:o.error},t}else return b(),g});break;case"state-changed":f(g=>{const u=g.findIndex(t=>t.id===o.pluginId);if(u>=0){const t=[...g];return t[u]={...t[u],state:o.state,error:o.error},t}return g});break;case"uninstalled":f(g=>g.filter(u=>u.id!==o.pluginId)),E(N,S);break;case"error":f(g=>{const u=g.findIndex(t=>t.id===o.pluginId);if(u>=0){const t=[...g];return t[u]={...t[u],state:o.state,error:o.error},t}return g});break}}catch{}};return Qe(`/api/events${s}`,{events:{"plugin:lifecycle":i},onReconnect:()=>{b(),E(N,S)}})},[c,b,E,S,N]);const le=async()=>{if(!w.trim()){r(n("plugins.installPathRequired","Please enter a plugin path"),"error");return}try{v(!0),await Q({path:w,...O?{aiScanOnLoad:!0}:{}},c),r(n("plugins.installedGlobally","Plugin installed globally"),"success"),A(!1),P(""),U(!1),await b(),p?.()}catch(s){r(n("plugins.installFailed","Failed to install plugin: {{error}}",{error:s instanceof Error?s.message:String(s)}),"error")}finally{v(!1)}},Ge=async s=>{if(!s.path){r(n("plugins.builtinNoPackage","{{name}} is built in and does not have an installable package yet",{name:s.name}),"warning");return}try{X(s.id),await Q({path:s.path},c),r(n("plugins.builtinInstalledGlobally","{{name}} installed globally",{name:s.name}),"success"),await b(),p?.()}catch(i){r(n("plugins.builtinInstallFailed","Failed to install {{name}}: {{error}}",{name:s.name,error:i instanceof Error?i.message:String(i)}),"error")}finally{X(null)}},Oe=async s=>{if(!s.path){r(n("plugins.registryNotInstallable","{{name}} is not available for one-click install yet",{name:s.name}),"warning");return}try{ie(s.id),await Q({path:s.path},c),r(n("plugins.registryInstalled","{{name}} installed and enabled",{name:s.name}),"success"),await b(),p?.(),await E(N,S)}catch(i){r(n("plugins.registryInstallFailed","Failed to install {{name}}: {{error}}",{name:s.name,error:i instanceof Error?i.message:String(i)}),"error")}finally{ie(null)}},re=async s=>{try{ae(s.id);const i=await rs(s.id,c);if(!i.success){r(n("plugins.setupInstallFailed","Failed to install {{name}} setup: {{error}}",{name:s.name,error:i.error??n("plugins.unknownError","unknown error")}),"error");return}r(n("plugins.setupInstalled","{{name}} setup installed",{name:s.name}),"success"),te(s.id);const l=await ge(s.id,c);z(o=>({...o,[s.id]:l}))}catch(i){r(n("plugins.setupInstallFailed","Failed to install {{name}} setup: {{error}}",{name:s.name,error:i instanceof Error?i.message:String(i)}),"error")}finally{ae(null),te(null)}},H=async s=>{try{const i=await ts(s.id,c);if(f(l=>l.map(o=>o.id===i.id?i:o)),i.state==="error"){r(n("plugins.enableFailed","Failed to enable {{name}}: {{error}}",{name:s.name,error:i.error??n("plugins.unknownError","unknown error")}),"error"),await b();return}r(n("plugins.enabledForProject","{{name}} enabled for this project",{name:s.name}),"success"),await b(!0,i),p?.()}catch(i){r(n("plugins.enablePluginFailed","Failed to enable plugin: {{error}}",{error:i instanceof Error?i.message:String(i)}),"error")}},V=async s=>{try{const i=await is(s.id,c);f(l=>l.map(o=>o.id===i.id?i:o)),r(n("plugins.disabledForProject","{{name}} disabled for this project",{name:s.name}),"success"),await b(!0,i),p?.()}catch(i){r(n("plugins.disablePluginFailed","Failed to disable plugin: {{error}}",{error:i instanceof Error?i.message:String(i)}),"error")}},Ue=async s=>{s.enabled?await V(s):await H(s)},oe=async s=>{try{R(s.id),await ns(s.id,c),r(n("plugins.reloaded","{{name}} reloaded",{name:s.name}),"success"),await b()}catch(i){r(n("plugins.reloadFailed","Failed to reload plugin: {{error}}",{error:i instanceof Error?i.message:String(i)}),"error")}finally{R(null)}},ue=async s=>{if(await qe({title:n("plugins.uninstallTitle","Uninstall Plugin Globally"),message:n("plugins.uninstallConfirm",'Are you sure you want to uninstall "{{name}}" globally (all projects)?',{name:s.name}),danger:!0}))try{await as(s.id,c),r(n("plugins.uninstalledGlobally","{{name}} uninstalled globally",{name:s.name}),"success"),await b(),p?.(),y(null)}catch(l){r(n("plugins.uninstallFailed","Failed to uninstall plugin: {{error}}",{error:l instanceof Error?l.message:String(l)}),"error")}},$e=async(s,i)=>{try{await Ze(s.id,{aiScanOnLoad:i},c),r(i?n("plugins.aiScanEnabled","AI scan on load enabled"):n("plugins.aiScanDisabled","AI scan on load disabled"),"success"),await b()}catch(l){r(n("plugins.updateFailed","Failed to update plugin: {{error}}",{error:l instanceof Error?l.message:String(l)}),"error")}},We=async s=>{try{await es(s.id,c),r(n("plugins.rescanned","{{name}} rescanned",{name:s.name}),"success"),await b()}catch(i){r(n("plugins.rescanFailed","Failed to rescan plugin: {{error}}",{error:i instanceof Error?i.message:String(i)}),"error")}},W=async s=>{y(s);try{J(!0);const i=await ls(s.id,c);j(i)}catch{j({})}finally{J(!1)}},Me=async()=>{if(a)try{await ss(a.id,m,c),r(n("plugins.settingsSaved","Settings saved"),"success")}catch(s){r(n("plugins.saveSettingsFailed","Failed to save settings: {{error}}",{error:s instanceof Error?s.message:String(s)}),"error")}};if(a)return e.jsxs("div",{className:"plugin-manager-detail","data-testid":"plugin-manager-detail",children:[e.jsxs("div",{className:"plugin-manager-detail-header",children:[e.jsx("button",{className:"btn-icon",onClick:()=>y(null),"aria-label":n("plugins.backToList","Back to plugin list"),children:e.jsx(me,{size:16})}),e.jsxs("div",{className:"plugin-detail-title",children:[e.jsxs("div",{className:"plugin-detail-title-copy",children:[e.jsx("h4",{className:"plugin-detail-name",children:a.name}),ve(a,"plugin-error-text plugin-error-text--detail")]}),e.jsx("span",{className:"plugin-state-badge",style:{color:T[a.state]||T.installed},children:a.state})]})]}),e.jsxs("div",{className:"plugin-detail-content",children:[e.jsxs("div",{className:"plugin-detail-card",children:[a.description&&e.jsx("p",{className:"plugin-description",children:a.description}),a.author&&e.jsxs("p",{className:"plugin-detail-meta-row",children:[e.jsx("span",{className:"text-muted",children:n("plugins.author","Author:")}),a.author]}),a.homepage&&e.jsxs("p",{className:"plugin-detail-meta-row plugin-homepage",children:[e.jsx("span",{className:"text-muted",children:n("plugins.homepage","Homepage:")}),e.jsxs("a",{href:a.homepage,target:"_blank",rel:"noopener noreferrer",children:[a.homepage,e.jsx(Ke,{size:12})]})]}),e.jsxs("p",{className:"plugin-detail-meta-row",children:[e.jsx("span",{className:"text-muted",children:n("plugins.version","Version:")}),a.version]})]}),e.jsxs("div",{className:"plugin-detail-card",children:[e.jsx("h5",{className:"plugin-detail-section-heading",children:n("plugins.securityScan","Security Scan")}),e.jsxs("div",{className:"plugin-security-row",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:!!a.aiScanOnLoad,onChange:s=>void $e(a,s.target.checked)}),n("plugins.enableAiScanBeforeLoad","Enable AI scan before load/reload")]}),e.jsxs("button",{className:"btn btn-secondary btn-sm",onClick:()=>void We(a),children:[e.jsx(Je,{size:14})," ",n("plugins.rescanAndReload","Rescan and Reload")]})]}),e.jsx("p",{className:"text-muted",children:n("plugins.aiScanHint","Turning this on only updates configuration. Use Rescan and Reload to run it now.")}),a.lastSecurityScan?e.jsxs("div",{className:"plugin-security-results",children:[e.jsxs("div",{className:"plugin-security-header",children:[e.jsx("span",{className:`plugin-state-badge plugin-security-badge plugin-security-badge--${a.lastSecurityScan.verdict}`,children:a.lastSecurityScan.verdict}),e.jsx("span",{className:"text-muted",children:a.lastSecurityScan.scannedAt})]}),e.jsx("p",{className:"plugin-security-summary",children:a.lastSecurityScan.summary}),e.jsxs("details",{children:[e.jsx("summary",{children:n("plugins.findings","Findings ({{count}})",{count:a.lastSecurityScan.findings.length})}),e.jsx("ul",{className:"plugin-security-findings",children:a.lastSecurityScan.findings.map((s,i)=>e.jsxs("li",{children:[e.jsx("strong",{children:s.severity})," ",s.category," — ",s.file,": ",s.reason]},`${s.file}-${i}`))})]})]}):e.jsx("p",{className:"text-muted",children:n("plugins.noSecurityScan","No security scan has been run yet.")})]}),e.jsxs("div",{className:"plugin-detail-card",children:[e.jsx("h5",{className:"plugin-detail-section-heading",children:n("plugins.settings","Settings")}),a.id==="fusion-plugin-whatsapp-chat"&&e.jsx(ps,{projectId:c,settings:m}),Re?e.jsx("p",{className:"text-muted",children:e.jsx(he,{label:n("plugins.loading","Loading...")})}):(()=>{const s=ds(a);return s&&Object.keys(s).length>0?e.jsxs("div",{className:"plugin-settings-form",children:[(()=>{const{grouped:i,ungrouped:l}=gs(s),o=[];l.length>0&&o.push({title:null,entries:l});for(const[g,u]of i.entries())o.push({title:g,entries:u});return o.map(g=>e.jsxs("div",{className:g.title?"plugin-settings-group":void 0,children:[g.title&&e.jsx("h6",{className:"plugin-settings-group-heading",children:Ne[g.title]?n(Ne[g.title],g.title):g.title}),g.entries.map(([u,t])=>{const I=`setting-${u}-help`,D=t.label?Se[t.label]?n(Se[t.label],t.label):t.label:u;return e.jsxs("div",{className:"form-group",children:[e.jsxs("label",{htmlFor:`setting-${u}`,children:[D,t.required&&" *"]}),t.type==="string"&&!t.multiline&&e.jsx("input",{className:"input",type:"text",id:`setting-${u}`,value:m[u]??"",onChange:h=>j({...m,[u]:h.target.value}),placeholder:t.description,"aria-describedby":t.description&&!t.required?I:void 0}),t.type==="string"&&t.multiline&&e.jsx("textarea",{className:"input",id:`setting-${u}`,rows:4,value:m[u]??"",onChange:h=>j({...m,[u]:h.target.value}),placeholder:t.description,"aria-describedby":t.description&&!t.required?I:void 0}),t.type==="password"&&e.jsx("input",{className:"input",type:"password",id:`setting-${u}`,value:m[u]??"",onChange:h=>j({...m,[u]:h.target.value}),placeholder:t.description,"aria-describedby":t.description&&!t.required?I:void 0}),t.type==="number"&&e.jsx("input",{className:"input",type:"number",id:`setting-${u}`,value:m[u]??"",onChange:h=>j({...m,[u]:Number(h.target.value)}),"aria-describedby":t.description&&!t.required?I:void 0}),t.type==="boolean"&&e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:m[u]??!1,onChange:h=>j({...m,[u]:h.target.checked})}),t.description]}),t.type==="enum"&&e.jsxs("select",{className:"select",id:`setting-${u}`,value:m[u]??"",onChange:h=>j({...m,[u]:h.target.value}),"aria-describedby":t.description&&!t.required?I:void 0,children:[e.jsx("option",{value:"",children:n("plugins.selectOption","Select...")}),t.enumValues?.map(h=>e.jsx("option",{value:h,children:h},h))]}),t.type==="array"&&e.jsxs("div",{className:"plugin-settings-array",children:[m[u]?.map((h,C)=>e.jsxs("div",{className:"plugin-settings-array-item",children:[e.jsx("input",{className:"input",type:t.itemType==="number"?"number":"text",value:h??"",onChange:M=>{const G=M.target.value,de=[...m[u]||[]];de[C]=t.itemType==="number"?Number(G):G,j({...m,[u]:de})}}),e.jsx("button",{className:"btn-icon",onClick:()=>{const G=[...m[u]||[]];G.splice(C,1),j({...m,[u]:G})},"aria-label":n("plugins.removeItem","Remove item"),children:e.jsx(me,{size:14})})]},C)),e.jsxs("button",{className:"btn btn-secondary",onClick:()=>{const h=m[u]||[],C=t.itemType==="number"?0:"";j({...m,[u]:[...h,C]})},children:[e.jsx(be,{size:14})," ",n("plugins.addItem","Add Item")]})]}),t.description&&!t.required&&!t.multiline&&e.jsx("span",{id:I,className:"form-help",children:t.description})]},u)})]},g.title??"ungrouped"))})(),e.jsx("button",{className:"btn btn-primary",onClick:Me,children:n("plugins.saveSettings","Save Settings")})]}):e.jsx("p",{className:"text-muted",children:n("plugins.noConfigurableSettings","No configurable settings.")})})()]}),e.jsxs("div",{className:"plugin-detail-actions",children:[a.state==="started"&&e.jsxs("button",{className:"btn btn-secondary",onClick:()=>oe(a),disabled:B===a.id,children:[e.jsx(ye,{size:14,className:B===a.id?"spin":""}),B===a.id?n("plugins.reloading","Reloading..."):n("plugins.reload","Reload")]}),a.enabled?e.jsx("button",{className:"btn btn-secondary",onClick:()=>V(a),children:n("plugins.disableInProject","Disable in Project")}):e.jsx("button",{className:"btn btn-primary",onClick:()=>H(a),children:n("plugins.enableInProject","Enable in Project")}),e.jsxs("button",{className:"btn btn-danger",onClick:()=>ue(a),children:[e.jsx(xe,{size:14})," ",n("plugins.uninstallGlobally","Uninstall Globally")]})]})]})]});const ce=new Map(x.map(s=>[s.id,s])),pe=x,Te=()=>e.jsxs("section",{className:"plugin-registry-section","aria-label":n("plugins.browseRegistry","Browse Registry"),children:[e.jsxs("div",{className:"plugin-registry-header",children:[e.jsxs("div",{className:"plugin-registry-heading-copy",children:[e.jsx("h4",{className:"plugin-registry-heading",children:n("plugins.browseRegistry","Browse Registry")}),e.jsx("p",{className:"plugin-registry-description",children:n("plugins.registryDescription","Discover curated runtimes and integrations that can be added to this Fusion workspace.")})]}),e.jsxs("div",{className:"plugin-registry-controls",children:[e.jsxs("label",{className:"plugin-registry-category-label",children:[e.jsx("span",{className:"sr-only",children:n("plugins.registryCategory","Registry category")}),e.jsxs("select",{className:"select plugin-registry-category-select",value:S,onChange:s=>Be(s.target.value),"aria-label":n("plugins.registryCategory","Registry category"),children:[e.jsx("option",{value:"",children:n("plugins.registryCategoryAll","All Categories")}),e.jsx("option",{value:"runtime",children:n("plugins.registryCategoryRuntime","Runtime")}),e.jsx("option",{value:"integration",children:n("plugins.registryCategoryIntegration","Integration")})]})]}),e.jsxs("label",{className:"plugin-registry-search-label",children:[e.jsx("span",{className:"sr-only",children:n("plugins.searchRegistry","Search registry")}),e.jsx("input",{className:"input plugin-registry-search-input",type:"search",value:N,onChange:s=>ke(s.target.value),placeholder:n("plugins.searchRegistryPlaceholder","Search registry plugins")})]})]})]}),Ie?e.jsxs("div",{className:"plugin-registry-state",role:"status",children:[e.jsx(fe,{size:14,className:"spin"}),n("plugins.registryLoading","Loading registry...")]}):se?e.jsxs("div",{className:"plugin-registry-state plugin-registry-state--error",role:"alert",children:[e.jsx("span",{children:n("plugins.registryLoadFailed","Failed to load registry: {{error}}",{error:se})}),e.jsx("button",{className:"btn btn-secondary btn-sm plugin-registry-retry",onClick:()=>void E(N,S),children:n("plugins.retry","Retry")})]}):Z.length===0?e.jsx("div",{className:"plugin-registry-state",children:N.trim()?n("plugins.registryEmptySearch","No registry plugins match your search."):n("plugins.registryEmpty","No registry plugins are available.")}):e.jsx("div",{className:"plugin-registry-list","aria-label":n("plugins.registryPluginResults","Registry plugin results"),children:Z.map(s=>{const i=ce.get(s.id),l=Ae===s.id;return e.jsxs("div",{className:"plugin-registry-item",children:[e.jsxs("div",{className:"plugin-registry-meta",children:[e.jsxs("div",{className:"plugin-registry-title-row",children:[e.jsx("span",{className:"plugin-registry-name",children:s.name}),e.jsxs("span",{className:"plugin-registry-version",children:["v",s.version]}),e.jsx("span",{className:"plugin-registry-badge",children:s.category}),s.installed&&e.jsxs("span",{className:"plugin-registry-status plugin-registry-status--installed",children:[n("plugins.statusInstalled","Installed"),s.installedVersion&&s.installedVersion!==s.version?` · v${s.installedVersion}`:""]})]}),e.jsx("span",{className:"plugin-registry-description-text",children:s.description}),e.jsx("span",{className:"plugin-registry-author",children:n("plugins.registryByAuthor","By {{author}}",{author:s.author})})]}),e.jsx("div",{className:"plugin-registry-actions",children:s.installed?e.jsx("button",{className:"btn btn-secondary btn-sm plugin-registry-action",onClick:()=>{i?W(i):b()},children:n("plugins.manage","Manage")}):s.canInstall?e.jsx("button",{className:"btn btn-primary btn-sm plugin-registry-action",onClick:()=>void Oe(s),disabled:l,children:l?n("plugins.installing","Installing..."):n("plugins.installFromRegistry","Install")}):e.jsx("span",{className:"plugin-registry-coming-soon",children:n("plugins.registryComingSoon","Coming Soon")})})]},s.id)})})]}),_e=()=>e.jsxs("section",{className:"plugin-builtins-section","aria-label":n("plugins.builtinPlugins","Built-in Plugins"),children:[e.jsxs("div",{className:"plugin-builtins-header",children:[e.jsx("h4",{className:"plugin-builtins-heading",children:n("plugins.builtinPlugins","Built-in Plugins")}),e.jsx("p",{className:"plugin-builtins-description",children:n("plugins.builtinPluginsCatalog","Built-in plugin catalog for runtimes and integrations.")})]}),e.jsx("div",{className:"plugin-builtins-list","aria-label":n("plugins.builtinPluginRecommendations","Built-in plugin recommendations"),children:we.map(s=>{const i=ce.get(s.id),l=!!i,o=Fe[s.id],g=!!(o&&"setupCheckDeferred"in o&&o.setupCheckDeferred),u=o&&"status"in o?o.status:void 0,t=l&&s.hasSetup&&o?.hasSetup&&!g&&i?.state==="started"&&(u==="not-installed"||u==="error"),I=l&&o?.hasSetup&&u==="installed",D=Le===s.id,h=!s.path,C=s.category==="runtime",M=i?.enabled;return e.jsxs("div",{className:"plugin-builtins-item",children:[e.jsxs("div",{className:"plugin-builtins-meta",children:[e.jsx("span",{className:"plugin-builtins-name",children:s.name}),s.experimental&&e.jsx("span",{className:"plugin-builtins-runtime-badge",children:n("plugins.experimental","Experimental")}),e.jsx("span",{className:"plugin-builtins-runtime-badge",children:s.category}),e.jsx("span",{className:`plugin-builtins-status ${l?"plugin-builtins-status--installed":"plugin-builtins-status--available"}`,children:l?n("plugins.statusInstalled","Installed"):h?n("plugins.statusBuiltIn","Built in"):n("plugins.statusNotInstalled","Not installed")}),C&&M===!1&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--warning",children:n("plugins.builtinDisabled","Disabled")}),t&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--warning",children:n("plugins.setupRequired","Setup required")}),I&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--ready",children:n("plugins.setupReady","Setup ready")}),D&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--pending",children:n("plugins.checkingSetup","Checking setup...")}),g&&e.jsx("span",{className:"plugin-builtins-setup-status plugin-builtins-setup-status--deferred",children:n("plugins.startPluginToCheckSetup","Start plugin to check setup")}),e.jsx("span",{className:"plugin-builtins-description-text",children:s.description})]}),e.jsxs("div",{className:"plugin-builtins-actions",children:[C&&i&&e.jsxs("label",{className:"toggle-switch",children:[e.jsx("input",{type:"checkbox",checked:i.enabled,onChange:()=>void Ue(i),"aria-label":i.enabled?n("plugins.disablePlugin","Disable {{name}}",{name:s.name}):n("plugins.enablePlugin","Enable {{name}}",{name:s.name})}),e.jsx("span",{className:"toggle-slider"})]}),h?l&&t?e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>void re(s),disabled:$===s.id||D,children:$===s.id?n("plugins.settingUp","Setting up..."):n("plugins.installSetup","Install Setup")}):l&&i?e.jsx("button",{className:"btn btn-secondary btn-sm",onClick:()=>void W(i),children:n("plugins.manage","Manage")}):C?null:e.jsx("span",{className:"plugin-builtins-metadata-only",children:n("plugins.builtinMetadataOnly","Built-in metadata only")}):e.jsx("button",{className:`btn ${l&&!t?"btn-secondary":"btn-primary"} btn-sm`,onClick:()=>{if(!l){Ge(s);return}if(t){re(s);return}i&&W(i)},disabled:Y===s.id||$===s.id||D,children:l?t?$===s.id?n("plugins.settingUp","Setting up..."):n("plugins.installSetup","Install Setup"):n("plugins.manage","Manage"):Y===s.id?n("plugins.installing","Installing..."):n("plugins.installNamed","Install {{name}}",{name:s.name})})]})]},s.id)})})]});return e.jsxs("div",{className:"plugin-manager","data-testid":"plugin-manager",children:[e.jsxs("div",{className:"plugin-manager-header",children:[e.jsx("span",{className:"plugin-manager-header-title",children:n("plugins.installedPlugins","Installed Plugins")}),e.jsxs("div",{className:"plugin-manager-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:()=>void b(),title:n("plugins.refresh","Refresh"),"aria-label":n("plugins.refreshPluginList","Refresh plugin list"),children:[e.jsx(fe,{size:14,className:F?"spin":""}),n("plugins.refresh","Refresh")]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>A(!0),children:[e.jsx(be,{size:14})," ",n("plugins.install","Install")]})]})]}),_&&e.jsxs("div",{className:"plugin-install-form",children:[e.jsx("p",{className:"plugin-install-hint",children:n("plugins.installHint","Browse to a plugin package root (contains manifest.json) or a built dist directory.")}),e.jsx(os,{value:w,onChange:P,placeholder:n("plugins.installPathPlaceholder","Absolute path to plugin directory or dist folder"),onInputKeyDown:s=>{s.key==="Enter"&&(s.preventDefault(),le())}}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:O,onChange:s=>U(s.target.checked)}),n("plugins.enableAiSecurityScan","Enable AI security scan on load")]}),e.jsxs("div",{className:"plugin-install-actions",children:[e.jsx("button",{className:"btn btn-primary",onClick:le,disabled:k||!w.trim(),children:k?n("plugins.installing","Installing..."):n("plugins.installPluginGlobally","Install Plugin Globally")}),e.jsx("button",{className:"btn btn-secondary",onClick:()=>{A(!1),P("")},children:n("plugins.cancel","Cancel")})]})]}),F?e.jsx("div",{className:"settings-empty-state",children:e.jsx(he,{label:n("plugins.loadingPlugins","Loading plugins...")})}):e.jsxs(e.Fragment,{children:[pe.length===0?e.jsxs("div",{className:"settings-empty-state",children:[e.jsx(Ye,{size:32,className:"text-muted"}),e.jsx("p",{children:n("plugins.noPluginsInstalled","No plugins installed.")}),e.jsx("p",{className:"text-muted",children:n("plugins.noPluginsHint","Install a plugin to get started, or use the built-in catalog below.")})]}):e.jsx("div",{className:"plugin-list",children:pe.map(s=>e.jsxs("div",{className:"plugin-item",children:[e.jsx("div",{className:"plugin-info",children:e.jsxs("div",{className:"plugin-copy",children:[e.jsxs("div",{className:"plugin-copy-header",children:[e.jsx("span",{className:"plugin-name",children:s.name}),e.jsxs("span",{className:"plugin-version text-muted",children:["v",s.version]}),e.jsx("span",{className:"plugin-state-badge",style:{color:T[s.state]||T.installed},children:s.state})]}),ve(s)]})}),e.jsxs("div",{className:"plugin-actions",children:[s.state==="started"&&e.jsx("button",{className:"btn-icon",onClick:()=>oe(s),disabled:B===s.id,title:n("plugins.reload","Reload"),children:e.jsx(ye,{size:14,className:B===s.id?"spin":""})}),e.jsxs("label",{className:"toggle-switch",children:[e.jsx("input",{type:"checkbox",checked:s.enabled,onChange:()=>s.enabled?V(s):H(s),"aria-label":s.enabled?n("plugins.disablePlugin","Disable {{name}}",{name:s.name}):n("plugins.enablePlugin","Enable {{name}}",{name:s.name})}),e.jsx("span",{className:"toggle-slider"})]}),e.jsx("button",{className:"btn-icon",onClick:()=>W(s),title:n("plugins.settings","Settings"),children:e.jsx(Xe,{size:14})}),e.jsx("button",{className:"btn-icon",onClick:()=>ue(s),title:n("plugins.uninstallGloballyTitle","Uninstall globally"),children:e.jsx(xe,{size:14})})]})]},s.id))}),_e(),Te()]})]})}export{je as AGENT_BROWSER_SETTINGS_SCHEMA,Pe as BUILTIN_AGENT_BROWSER_PLUGIN_ID,we as BUILTIN_PLUGINS,ws as PluginManager,T as STATE_COLORS};
@@ -1,4 +1,4 @@
1
- import{r as a,j as e}from"./vendor-react-SZ_qB27O.js";import{c as te,V as ie,b0 as k,b1 as N,b2 as C,b3 as F,b4 as M,b5 as ae,b6 as X,aU as Z,as as K,a as E}from"./index-I32FijPT.js";import{u as ne}from"./vendor-i18n-Duky4gdQ.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";import"./vendor-xterm-BNq00GSj.js";/**
1
+ import{r as a,j as e}from"./vendor-react-SZ_qB27O.js";import{c as te,V as ie,b0 as k,b1 as N,b2 as C,b3 as F,b4 as M,b5 as ae,b6 as X,aU as Z,as as K,a as E}from"./index-oxnX59eO.js";import{u as ne}from"./vendor-i18n-Duky4gdQ.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";import"./vendor-xterm-BNq00GSj.js";/**
2
2
  * @license lucide-react v1.7.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{r as n,j as e,b as se}from"./vendor-react-SZ_qB27O.js";import{c as z,dm as re,e9 as Q,af as le,C as X,ea as oe,eb as ne,z as ce,b5 as ie,bH as he,ec as A,ed as ue,ee as Y}from"./index-I32FijPT.js";import{u as _}from"./vendor-i18n-Duky4gdQ.js";/**
1
+ import{r as n,j as e,b as se}from"./vendor-react-SZ_qB27O.js";import{c as z,dm as re,e9 as Q,af as le,C as X,ea as oe,eb as ne,z as ce,b5 as ie,bH as he,ec as A,ed as ue,ee as Y}from"./index-oxnX59eO.js";import{u as _}from"./vendor-i18n-Duky4gdQ.js";/**
2
2
  * @license lucide-react v1.7.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,2 +1,2 @@
1
- import{r as c,j as e}from"./vendor-react-SZ_qB27O.js";import{r as Q,e as ue,S as he,cL as me,c_ as Se,b as ce,c$ as _e,bj as je,d0 as Y,aZ as we,d1 as ke,d2 as Ne,d3 as Ce,d4 as Ee,d5 as Ae,d6 as Te,d7 as Pe,cP as Le,d8 as Fe,d9 as Ie,da as Me,db as De,a_ as He,al as qe,V as Ue,aJ as pe,L as Oe,aK as Ve}from"./index-I32FijPT.js";import{u as fe}from"./vendor-i18n-Duky4gdQ.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";import"./vendor-xterm-BNq00GSj.js";const $e="builtin",X={pageFetch:!0,github:!1,localDocs:!0,llmSynthesis:!0};function ie(a){const n=a?.researchGlobalDefaults,l=a?.researchSettings;return{enabled:l?.enabled??a?.researchEnabled??a?.researchGlobalEnabled??!0,searchProvider:l?.searchProvider??n?.searchProvider??a?.researchGlobalWebSearchProvider??$e,synthesisProvider:l?.synthesisProvider??n?.synthesisProvider,synthesisModelId:l?.synthesisModelId??n?.synthesisModelId,enabledSources:{webSearch:!0,pageFetch:l?.enabledSources?.pageFetch??n?.enabledSources?.pageFetch??X.pageFetch,github:l?.enabledSources?.github??n?.enabledSources?.github??X.github,localDocs:l?.enabledSources?.localDocs??n?.enabledSources?.localDocs??X.localDocs,llmSynthesis:l?.enabledSources?.llmSynthesis??n?.enabledSources?.llmSynthesis??X.llmSynthesis},limits:{maxConcurrentRuns:l?.limits?.maxConcurrentRuns??a?.researchMaxConcurrentRuns??a?.researchGlobalMaxConcurrentRuns??3,maxSourcesPerRun:l?.limits?.maxSourcesPerRun??n?.maxSourcesPerRun??a?.researchMaxSourcesPerRun??a?.researchGlobalMaxSourcesPerRun??20,maxDurationMs:l?.limits?.maxDurationMs??a?.researchDefaultTimeout??a?.researchGlobalDefaultTimeout??3e5,requestTimeoutMs:l?.limits?.requestTimeoutMs??a?.researchGlobalFetchTimeoutMs??3e4},defaultExportFormat:n?.defaultExportFormat??"markdown"}}function be(a){const n=typeof a.id=="string"?a.id.trim():"";if(n)return n;const l=f=>f.trim().replace(/\s+/g," ").toLowerCase(),m=[l(a.heading??""),l(a.content??""),...[...a.sources??[]].map(l).filter(Boolean).sort()].join(`
1
+ import{r as c,j as e}from"./vendor-react-SZ_qB27O.js";import{r as Q,e as ue,S as he,cL as me,c_ as Se,b as ce,c$ as _e,bj as je,d0 as Y,aZ as we,d1 as ke,d2 as Ne,d3 as Ce,d4 as Ee,d5 as Ae,d6 as Te,d7 as Pe,cP as Le,d8 as Fe,d9 as Ie,da as Me,db as De,a_ as He,al as qe,V as Ue,aJ as pe,L as Oe,aK as Ve}from"./index-oxnX59eO.js";import{u as fe}from"./vendor-i18n-Duky4gdQ.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";import"./vendor-xterm-BNq00GSj.js";const $e="builtin",X={pageFetch:!0,github:!1,localDocs:!0,llmSynthesis:!0};function ie(a){const n=a?.researchGlobalDefaults,l=a?.researchSettings;return{enabled:l?.enabled??a?.researchEnabled??a?.researchGlobalEnabled??!0,searchProvider:l?.searchProvider??n?.searchProvider??a?.researchGlobalWebSearchProvider??$e,synthesisProvider:l?.synthesisProvider??n?.synthesisProvider,synthesisModelId:l?.synthesisModelId??n?.synthesisModelId,enabledSources:{webSearch:!0,pageFetch:l?.enabledSources?.pageFetch??n?.enabledSources?.pageFetch??X.pageFetch,github:l?.enabledSources?.github??n?.enabledSources?.github??X.github,localDocs:l?.enabledSources?.localDocs??n?.enabledSources?.localDocs??X.localDocs,llmSynthesis:l?.enabledSources?.llmSynthesis??n?.enabledSources?.llmSynthesis??X.llmSynthesis},limits:{maxConcurrentRuns:l?.limits?.maxConcurrentRuns??a?.researchMaxConcurrentRuns??a?.researchGlobalMaxConcurrentRuns??3,maxSourcesPerRun:l?.limits?.maxSourcesPerRun??n?.maxSourcesPerRun??a?.researchMaxSourcesPerRun??a?.researchGlobalMaxSourcesPerRun??20,maxDurationMs:l?.limits?.maxDurationMs??a?.researchDefaultTimeout??a?.researchGlobalDefaultTimeout??3e5,requestTimeoutMs:l?.limits?.requestTimeoutMs??a?.researchGlobalFetchTimeoutMs??3e4},defaultExportFormat:n?.defaultExportFormat??"markdown"}}function be(a){const n=typeof a.id=="string"?a.id.trim():"";if(n)return n;const l=f=>f.trim().replace(/\s+/g," ").toLowerCase(),m=[l(a.heading??""),l(a.content??""),...[...a.sources??[]].map(l).filter(Boolean).sort()].join(`
2
2
  `);let s=2166136261;for(let f=0;f<m.length;f+=1)s^=m.charCodeAt(f),s=Math.imul(s,16777619);return`finding-${(s>>>0).toString(16).padStart(8,"0")}`}const Ge=300,Be=4e3,We=["queued","running","cancelling","retry_waiting"];function le(a,n){if(a instanceof Le){const l=a;return{message:a.message,status:a.status,code:l.researchCode??"INTERNAL_ERROR",setupHint:l.setupHint,retryable:l.retryable}}return a instanceof Error?{message:a.message,code:"INTERNAL_ERROR"}:{message:n,code:"INTERNAL_ERROR"}}function ze(a){if(!a)return{cancelable:!1,retryable:!1,isTransitioning:!1,blockingReason:"No run selected"};const n=We.includes(a.status),l=a.status==="queued"||a.status==="running",m=a.lifecycle?.retryable,s=a.status==="failed"||a.status==="timed_out",f=!!(s&&m);let x;return!l&&n?x="Run is already transitioning":!l&&a.status==="completed"?x="Completed runs cannot be cancelled":!l&&a.status==="cancelled"?x="Run is already cancelled":!l&&a.status==="retry_exhausted"?x="Retry attempts exhausted":!l&&a.status==="failed"?x="Failed runs cannot be cancelled":!l&&a.status==="timed_out"&&(x="Timed out runs cannot be cancelled"),!f&&s&&m===!1&&(x=a.lifecycle?.errorCode==="RETRY_EXHAUSTED"?"Retry attempts exhausted":"Run is not retryable"),{cancelable:l,retryable:f,isTransitioning:n,blockingReason:x}}function Ke(a){const n=a?.projectId,l=n??"",m=`${he.RESEARCH_RUNS_PREFIX}${l}`,s=`${he.RESEARCH_SELECTED_ID_PREFIX}${l}`,f=Q(m,{maxAgeMs:ue}),x=Q(s,{maxAgeMs:me}),r=c.useRef(Array.isArray(f)&&f.length>0),[D,M]=c.useState(()=>Array.isArray(f)?f:[]),[h,A]=c.useState(x??null),[P,w]=c.useState(null),[O,H]=c.useState({available:!0}),[V,L]=c.useState(!(Array.isArray(f)&&f.length>0)),[G,q]=c.useState(null),[B,k]=c.useState(null),[N,F]=c.useState(""),_=c.useRef(0),R=c.useRef(0),C=c.useRef(n);c.useEffect(()=>{C.current!==n&&(C.current=n,R.current++);const o=Q(m,{maxAgeMs:ue}),d=Q(s,{maxAgeMs:me}),p=Array.isArray(o)&&o.length>0;M(Array.isArray(o)?o:[]),A(d??null),w(null),L(!p),r.current=p},[n,m,s]);const S=c.useCallback(async(o=N)=>{const d=++_.current,p=n;r.current||L(!0),q(null),k(null);try{const y=await Se({q:o||void 0,limit:100},p);if(d!==_.current||p!==n)return;M(y.runs),ce(m,y.runs,{maxBytes:5e5}),r.current=!0,H(y.availability),h&&!y.runs.some(g=>g.id===h)&&(A(null),ce(s,null,{maxBytes:5e5}),w(null))}catch(y){if(d!==_.current||p!==n)return;const g=le(y,"Failed to load research runs");q(g.message),k(g)}finally{d===_.current&&L(!1)}},[n,m,N,s,h]),i=c.useCallback(async o=>{const d=await _e(o,n);return w(d.run),H(d.availability),d.run},[n]);c.useEffect(()=>{r.current||L(!0);const o=window.setTimeout(()=>{S(N)},Ge);return()=>window.clearTimeout(o)},[S,N]),c.useEffect(()=>{if(!h){w(null);return}i(h)},[i,h]),c.useEffect(()=>{const o=R.current,d=()=>R.current!==o,p=n?`?projectId=${encodeURIComponent(n)}`:"";let y=!0;const g=()=>{!y||d()||(S(),h&&i(h))},j=`/api/events${p}`,$=je(j,{events:{"research:run:created":g,"research:run:updated":g,"research:run:completed":g,"research:run:failed":g,"research:run:cancelled":g},onReconnect:()=>{Y({view:"useResearch",trigger:"sse-reconnect",projectId:n,replayAttempted:!1,sseChannel:j}),g()}});return Y({view:"useResearch",trigger:"sse-open",projectId:n,replayAttempted:!1,sseChannel:j}),()=>{y=!1,$()}},[n,S,h,i]);const E=c.useCallback(()=>{S(),h&&i(h)},[S,h,i]);we(E,Be);const T=c.useCallback(o=>{A(o),ce(s,o,{maxBytes:5e5})},[s]);return{runs:D,selectedRun:P,selectedRunId:h,setSelectedRunId:T,availability:O,loading:V,error:G,searchQuery:N,setSearchQuery:F,refresh:S,createRun:o=>Pe(o,n),cancelRun:async o=>{try{k(null);const d=await Te(o,n);return h===o&&w(d.run),await S(),d}catch(d){const p=le(d,"Failed to cancel run");throw k(p),p}},retryRun:async o=>{try{k(null);const d=await Ae(o,n);return h===o&&w(d.run),await S(),d}catch(d){const p=le(d,"Failed to retry run");throw k(p),p}},exportRun:(o,d)=>Ee(o,d,n),createTaskFromRun:(o,d,p,y,g,j)=>Ce(o,{title:d,findingId:p,description:y,priority:g,attachExport:j},n),attachRunToTask:(o,d,p,y)=>Ne(o,{taskId:d,findingId:p,attachExport:y},n),promoteFinding:(o,d)=>ke(o,d,n),uiError:B,runActionState:ze(P),statusCounts:D.reduce((o,d)=>(o[d.status]+=1,o),{queued:0,running:0,cancelling:0,retry_waiting:0,completed:0,failed:0,cancelled:0,timed_out:0,retry_exhausted:0})}}function Qe({open:a,mode:n,run:l,finding:m,projectId:s,onClose:f,onConfirm:x}){const{t:r}=fe("app");Fe(a);const[D,M]=c.useState(!1),[h,A]=c.useState(""),[P,w]=c.useState(""),[O,H]=c.useState("normal"),[V,L]=c.useState(""),[G,q]=c.useState([]),[B,k]=c.useState(!1),[N,F]=c.useState(!1),{boardWorkflows:_}=Ie({projectId:s}),R=c.useMemo(()=>{const i=new Map;for(const E of _?.workflows??[])for(const T of E.columns)i.has(T.id)||i.set(T.id,T.flags);return E=>Me(i.get(E),E)},[_]),C=c.useMemo(()=>{const i=(m.content??"").split(/(?<=[.!?])\s+/)[0]??"";return`${m.heading||r("research.defaultFindingHeading","Research finding")} — ${i}`.trim()},[m.content,m.heading,r]);c.useEffect(()=>{a&&(M(!1),A(`Research: ${m.heading||l.title}`),w(C),H("normal"),L(""))},[a,n,m.heading,C,l.title]),c.useEffect(()=>{if(!a||n!=="enrich")return;let i=!1;return q([]),k(!0),De(50,0,s).then(E=>{i||q(E.filter(T=>!R(T.column)))}).finally(()=>{i||k(!1)}),()=>{i=!0}},[a,n,s,R]);const S=V.trim();return a?e.jsx("div",{className:"modal-overlay open",role:"presentation",onClick:f,children:e.jsxs("div",{className:"modal modal-lg research-task-action-modal",role:"dialog","aria-modal":"true",onClick:i=>i.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:n==="create"?r("research.createTaskTitle","Create task from finding"):r("research.enrichTaskTitle","Enrich existing task")}),e.jsx("button",{className:"modal-close",type:"button","aria-label":r("actions.close","Close"),onClick:f,children:"×"})]}),e.jsxs("div",{className:"research-task-action-modal__body",children:[e.jsxs("div",{className:"card research-task-action-modal__preview",children:[e.jsxs("p",{children:[e.jsxs("strong",{children:[r("research.runLabel","Run:")," "]})," ",l.id]}),e.jsxs("p",{children:[e.jsxs("strong",{children:[r("research.findingLabel","Finding:")," "]})," ",m.id,m.heading?` — ${m.heading}`:""]}),e.jsx("p",{children:C||r("research.noPreview","No preview available.")})]}),n==="create"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"research-task-action-modal__field",children:[r("research.titleLabel","Title"),e.jsx("input",{className:"input",value:h,onChange:i=>A(i.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:[r("research.descriptionLabel","Description"),e.jsx("textarea",{className:"input research-task-action-modal__textarea",value:P,onChange:i=>w(i.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:[r("research.priorityLabel","Priority"),e.jsxs("select",{className:"select",value:O,onChange:i=>H(i.target.value),children:[e.jsx("option",{value:"low",children:r("research.priorityLow","Low")}),e.jsx("option",{value:"normal",children:r("research.priorityNormal","Normal")}),e.jsx("option",{value:"high",children:r("research.priorityHigh","High")}),e.jsx("option",{value:"urgent",children:r("research.priorityUrgent","Urgent")})]})]})]}):e.jsxs("label",{className:"research-task-action-modal__field",children:[r("research.targetTaskLabel","Target task"),e.jsx("input",{className:"input",list:"research-task-action-task-list",value:V,placeholder:B?r("research.loadingTasks","Loading tasks…"):r("research.enterTaskId","Enter task ID"),onChange:i=>L(i.target.value)}),e.jsx("datalist",{id:"research-task-action-task-list",children:G.map(i=>e.jsx("option",{value:i.id,children:i.title},i.id))})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:D,onChange:i=>M(i.target.checked)}),e.jsx("span",{children:r("research.attachExport","Attach markdown export artifact")})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:f,children:r("actions.cancel","Cancel")}),e.jsx("button",{className:"btn btn-primary",type:"button",disabled:N||n==="enrich"&&!S,onClick:()=>{F(!0),x({taskId:n==="enrich"?S:void 0,title:n==="create"?h.trim():void 0,description:n==="create"?P.trim():void 0,priority:n==="create"?O:void 0,attachExport:D}).finally(()=>F(!1))},children:n==="create"?r("research.createTaskButton","Create Task"):r("research.enrichTaskButton","Enrich Task")})]})]})}):null}const Xe=["web-search","page-fetch","github","local-docs","llm-synthesis"],Ye={"web-search":"webSearch","page-fetch":"pageFetch",github:"github","local-docs":"localDocs","llm-synthesis":"llmSynthesis"};function Je(a){return{"web-search":a("research.providerWebSearch","Web Search"),"page-fetch":a("research.providerPageFetch","Page Fetch"),github:a("research.providerGitHub","GitHub"),"local-docs":a("research.providerLocalDocs","Local Docs"),"llm-synthesis":a("research.providerLlmSynthesis","LLM Synthesis")}}let oe=!1;function cs({projectId:a,addToast:n,onOpenSettings:l,readinessVersion:m=0}){const{t:s}=fe("app"),f=Je(s);c.useEffect(()=>(Y({view:"ResearchView",trigger:oe?"route-active":"remount",projectId:a,replayAttempted:!1}),oe=!1,()=>{oe=!0,Y({view:"ResearchView",trigger:"route-inactive",projectId:a,replayAttempted:!1})}),[a]);const{runs:x,selectedRun:r,selectedRunId:D,setSelectedRunId:M,availability:h,loading:A,error:P,searchQuery:w,setSearchQuery:O,createRun:H,cancelRun:V,retryRun:L,exportRun:G,createTaskFromRun:q,attachRunToTask:B,promoteFinding:k,statusCounts:N,refresh:F,uiError:_,runActionState:R}=Ke({projectId:a}),[C,S]=c.useState(""),[i,E]=c.useState(()=>ie(void 0)),[T,o]=c.useState([]),[d,p]=c.useState(!1),[y,g]=c.useState([]),[j,$]=c.useState(null),[U,K]=c.useState(null),[J,ve]=c.useState(""),Z=h.supportedProviders??Xe,ee=i.searchProvider,se=t=>t==="web-search"?!0:i.enabledSources[Ye[t]];c.useEffect(()=>{const t=Z.filter(u=>se(u));g(u=>{const b=u.filter(v=>t.includes(v));return b.length>0?b:t})},[i.enabledSources,Z]),c.useEffect(()=>{let t=!1;return Promise.all([He(a),qe().catch(()=>({providers:[]}))]).then(([u,b])=>{t||(E(ie(u)),o(b.providers.filter(v=>v.type==="api_key").map(v=>({id:v.id,authenticated:v.authenticated}))))}).catch(()=>{t||E(ie(void 0))}),()=>{t=!0}},[a,m]);const xe=c.useMemo(()=>r?r.status:s("research.noRunSelected","No run selected"),[r,s]),ye=c.useMemo(()=>r?r.status==="queued"||r.status==="retry_waiting"?"status-dot status-dot--pending":r.status==="running"?"status-dot status-dot--connecting":r.status==="completed"?"status-dot status-dot--online":r.status==="failed"||r.status==="cancelled"?"status-dot status-dot--error":"status-dot":"status-dot",[r]),re=h.supportedExportFormats??["markdown","json","html"],te=c.useMemo(()=>new Map(T.map(t=>[t.id,t.authenticated])),[T]),ae=c.useMemo(()=>{const t=new Set;return i.enabledSources.webSearch&&ee&&t.add(ee),i.enabledSources.llmSynthesis&&i.synthesisProvider&&t.add(i.synthesisProvider),[...t].filter(u=>te.has(u))},[i.enabledSources.llmSynthesis,i.enabledSources.webSearch,i.synthesisProvider,ee,te]).find(t=>te.get(t)!==!0),W=c.useMemo(()=>h.available?i.enabled?ae?{reason:s("research.missingApiKey","Missing API key for {{provider}}.",{provider:ae}),details:s("research.addCredentialsHint","Add provider credentials in Authentication settings."),settingsSection:"authentication"}:null:{reason:s("research.disabled","Research is disabled for this project."),details:s("research.enableResearchHint","Enable project research settings to create runs."),settingsSection:"research-project"}:{reason:h.reason??s("research.unavailable","Research is unavailable for this project."),details:h.setupInstructions,settingsSection:"research-project"},[h.available,h.reason,h.setupInstructions,i.enabled,ae,s]),z=async(t,u,b)=>{$(t);try{await u(),n?.(b,"success"),await F()}catch(v){n?.(v instanceof Error?v.message:s("research.actionFailed","Action failed"),"error")}finally{$(null)}},ne=async t=>{if(r){$(`export-${t}`);try{const u=await G(r.id,t),b=new Blob([u.content],{type:"text/plain;charset=utf-8"}),v=URL.createObjectURL(b),I=document.createElement("a");I.href=v,I.download=u.filename,document.body.appendChild(I),I.click(),I.remove(),URL.revokeObjectURL(v),n?.(s("research.exportedFile","Exported {{filename}}",{filename:u.filename}),"success")}catch(u){n?.(u instanceof Error?u.message:s("research.exportFailed","Export failed"),"error")}finally{$(null)}}},ge=async()=>{if(C.trim()){p(!0);try{const t=y.filter(b=>se(b));if(t.length===0){p(!1),n?.(s("research.noSourcesAvailable","No enabled research sources are available for this project."),"error");return}const u=await H({query:C.trim(),providers:t});M(u.run.id),S(""),n?.(s("research.runCreated","Research run created"),"success"),await F()}catch(t){n?.(t instanceof Error?t.message:s("research.createRunFailed","Failed to create run"),"error")}finally{p(!1)}}};return e.jsxs("section",{className:"research-view","aria-label":s("research.viewLabel","Research view"),children:[e.jsx(Ue,{icon:pe,title:s("research.title","Research"),actions:e.jsx("button",{className:"btn",type:"button",onClick:()=>void F(),children:s("actions.refresh","Refresh")})}),e.jsx("p",{className:"research-view__subtitle",children:s("research.subtitle","Cited search and synthesis runs: gather sources, fetch content, and synthesize findings.")}),W?e.jsxs("div",{className:"research-view__state research-view__state--error card","data-testid":"research-state-unavailable",children:[e.jsx("p",{children:W.reason}),W.details&&e.jsx("p",{children:W.details}),e.jsx("p",{children:s("research.currentDefaults","Current defaults: provider {{provider}}, max sources {{maxSources}}",{provider:i.searchProvider??s("research.notSet","(not set)"),maxSources:i.limits.maxSourcesPerRun})}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:()=>void F(),children:s("actions.refresh","Refresh")}),e.jsx("button",{className:"btn btn-primary",type:"button",onClick:()=>l?.(W.settingsSection),children:s("actions.openSettings","Open Settings")})]})]}):e.jsx(e.Fragment,{children:e.jsxs("div",{className:"research-view__layout",children:[e.jsx("aside",{className:"research-view__sidebar card",children:e.jsxs("div",{className:"research-view__sidebar-content",children:[e.jsxs("div",{className:"research-view__form",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-query",children:s("research.queryLabel","Query")}),e.jsx("textarea",{id:"research-query",className:"input research-view__textarea",value:C,onChange:t=>S(t.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:s("research.providersLabel","Providers")}),e.jsx("div",{className:"research-view__providers",children:Z.map(t=>{const u=se(t),b=t==="web-search";return e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:b||y.includes(t),disabled:b||!u,onChange:()=>{b||!u||g(v=>v.includes(t)?v.filter(I=>I!==t):[...v,t])}}),e.jsxs("span",{children:[f[t]??t,b?e.jsx("span",{className:"research-view__provider-lock",children:s("research.alwaysOn","Always on")}):null]})]},t)})})]}),e.jsxs("button",{className:"btn btn-primary",type:"button",disabled:!C.trim()||d,onClick:()=>void ge(),children:[d?e.jsx(Oe,{className:"animate-spin",size:14}):null,s("research.createRun","Create Run")]})]}),e.jsxs("div",{className:"research-view__history-header form-group",children:[e.jsx("label",{htmlFor:"research-run-search",children:s("actions.search","Search")}),e.jsxs("div",{className:"research-view__history-search-row",children:[e.jsx(pe,{size:14}),e.jsx("input",{id:"research-run-search",className:"input",placeholder:s("research.searchRunsPlaceholder","Search runs"),value:w,onChange:t=>O(t.target.value)})]})]}),e.jsx("div",{className:"research-view__history","data-testid":"research-state-running",children:x.map(t=>e.jsxs("button",{type:"button",className:`research-view__history-item card${D===t.id?" research-view__history-item--active":""}`,onClick:()=>M(t.id),children:[e.jsx("span",{className:"card-id",children:t.id}),e.jsx("span",{children:t.title})]},t.id))})]})}),e.jsxs("div",{className:"research-view__reader card",children:[A&&e.jsx("p",{"data-testid":"research-state-loading",children:e.jsx(Ve,{label:s("research.loadingRuns","Loading research runs…")})}),!A&&P&&e.jsx("p",{"data-testid":"research-state-error",children:P}),!A&&!P&&x.length===0&&e.jsx("p",{"data-testid":"research-state-empty",children:s("research.noRunsYet","No research runs yet")}),e.jsxs("div",{className:"research-view__reader-content",children:[r&&e.jsxs("div",{className:"research-view__run-detail",children:[e.jsxs("div",{className:"research-view__status-row",children:[e.jsx("span",{className:ye}),e.jsx("strong",{children:xe})]}),e.jsx("h3",{className:"research-view__run-title",children:r.title}),e.jsx("p",{className:"research-view__run-query",children:r.query}),e.jsx("p",{className:"research-view__run-summary","data-testid":"research-state-results",children:r.results?.summary??s("research.noSummaryYet","No summary yet.")}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",title:R.cancelable?void 0:R.blockingReason,disabled:j==="cancel"||j==="retry"||!R.cancelable,onClick:()=>void z("cancel",()=>V(r.id),s("research.runCancelled","Run cancelled")),children:s("actions.cancel","Cancel")}),e.jsx("button",{className:"btn",type:"button",title:R.retryable?void 0:R.blockingReason,disabled:j==="cancel"||j==="retry"||!R.retryable,onClick:()=>void z("retry",()=>L(r.id),s("research.runRetried","Run retried")),children:s("actions.retry","Retry")}),re.includes("markdown")&&e.jsx("button",{className:"btn",type:"button",disabled:j==="export-markdown",onClick:()=>void ne("markdown"),children:s("research.exportMd","Export MD")}),re.includes("json")&&e.jsx("button",{className:"btn",type:"button",disabled:j==="export-json",onClick:()=>void ne("json"),children:s("research.exportJson","Export JSON")}),re.includes("html")&&e.jsx("button",{className:"btn",type:"button",disabled:j==="export-html",onClick:()=>void ne("html"),children:s("research.exportHtml","Export HTML")})]}),r.error&&e.jsx("p",{className:"research-view__error",children:r.error}),_&&e.jsxs("div",{className:"form-error",role:"alert",children:[e.jsx("p",{children:_.message}),_.setupHint&&e.jsx("p",{children:_.setupHint}),_.code==="MISSING_CREDENTIALS"&&e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>l?.("authentication"),children:s("research.openAuthSettings","Open Authentication Settings")}),_.code==="FEATURE_DISABLED"&&e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>l?.("research-project"),children:s("research.openResearchSettings","Open Research Settings")})]}),R.blockingReason&&e.jsx("p",{className:"research-view__run-query",children:R.blockingReason}),Array.isArray(r.results?.findings)&&r.results.findings.length>0&&e.jsx("div",{className:"research-view__findings",children:r.results.findings.map(t=>{const u=be(t);return e.jsxs("article",{className:"research-view__finding card",children:[e.jsx("h4",{children:t.heading}),e.jsx("p",{children:t.content}),e.jsxs("div",{className:"research-view__actions research-view__finding-actions",children:[e.jsx("button",{className:"btn btn-primary btn-sm",type:"button",onClick:()=>K({mode:"create",findingId:u}),children:s("research.createTask","Create Task")}),e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>K({mode:"enrich",findingId:u}),children:s("research.enrichTask","Enrich Task")}),e.jsx("input",{className:"input","aria-label":s("research.destinationSlice","Destination slice ID"),value:J,onChange:b=>ve(b.target.value),placeholder:s("research.destinationSlice","Destination slice ID")}),e.jsx("button",{className:"btn btn-sm",type:"button",disabled:r.status!=="completed"||!J.trim()||j===`promote-${u}`,onClick:()=>void z(`promote-${u}`,()=>k(r.id,{findingId:u,sliceId:J.trim()}),s("research.findingPromoted","Finding promoted to roadmap")),children:s("research.promoteFinding","Promote to roadmap")})]})]},u)})}),Array.isArray(r.results?.citations)&&r.results.citations.length>0&&e.jsx("ul",{className:"research-view__citations",children:r.results.citations.map(t=>e.jsx("li",{children:e.jsx("a",{href:t,target:"_blank",rel:"noreferrer",children:t})},t))}),r.events.length>0&&e.jsxs("details",{children:[e.jsx("summary",{children:s("research.runHistory","Run history")}),e.jsx("ul",{className:"research-view__events",children:r.events.map(t=>e.jsx("li",{children:t.message},t.id))})]})]}),!r&&x.length>0&&e.jsx("p",{children:s("research.selectRunToViewDetails","Select a run to view details.")}),e.jsxs("div",{className:"research-view__stats",children:[e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:s("research.statRunning","Running")}),e.jsx("div",{className:"research-view__stat-value",children:N.running})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:s("research.statCompleted","Completed")}),e.jsx("div",{className:"research-view__stat-value",children:N.completed})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:s("research.statFailed","Failed")}),e.jsx("div",{className:"research-view__stat-value",children:N.failed})]})]})]})]})]})}),r&&U&&(()=>{const t=r.results?.findings?.findIndex(b=>be(b)===U.findingId)??-1,u=t>=0?r.results.findings[t]:null;return u?e.jsx(Qe,{open:!0,mode:U.mode,run:r,finding:{id:U.findingId,heading:u.heading,content:u.content},projectId:a,onClose:()=>K(null),onConfirm:async({taskId:b,title:v,description:I,priority:Re,attachExport:de})=>{U.mode==="create"?await z("create-task",()=>q(r.id,v,U.findingId,I,Re,de),s("research.taskCreatedFromResearch","Task created from research")):b&&await z("attach-task",()=>B(r.id,b,U.findingId,de),s("research.taskEnrichedFromResearch","Task enriched from research")),K(null)}}):null})()]})}export{cs as ResearchView};
@@ -1 +1 @@
1
- import{r as t,j as e}from"./vendor-react-SZ_qB27O.js";import{w as A,V as we,x as ke,R as ce,P as Re,E as ne,y as le,z as Le,B as Te,D as Ae,F as Me,C as De,k as Ve,G as qe}from"./index-I32FijPT.js";import{u as Ke}from"./vendor-i18n-Duky4gdQ.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";import"./vendor-xterm-BNq00GSj.js";const Oe="__sync_passphrase__",G={key:"",value:"",description:"",scope:"project",accessPolicy:"prompt",envExportable:!1,envExportKey:""},d={className:"secrets-action-icon","aria-hidden":!0,style:{width:"1em",height:"1em"}},Fe={...d,className:"secrets-action-icon spin"},Ge=({addToast:p,projectId:l})=>{const{t:a}=Ke("app"),[J,Y]=t.useState([]),[oe,U]=t.useState(),[Q,W]=t.useState(!0),[X,M]=t.useState(null),[ie,D]=t.useState(),[Z,b]=t.useState(null),[h,V]=t.useState(null),[de,x]=t.useState(!1),[ue,C]=t.useState(null),[c,i]=t.useState(G),[q,E]=t.useState(!1),[ee,f]=t.useState({}),[pe,K]=t.useState(null),[m,se]=t.useState(!1),[he,ae]=t.useState(),[me,O]=t.useState(!1),[w,F]=t.useState(""),[B,_]=t.useState(""),[ye,$]=t.useState(!1),[H,xe]=t.useState(!1),v=t.useRef(new Map),I=t.useRef(new Map),j=t.useRef(0),k=t.useRef(0),o=t.useRef(l);o.current!==l&&(o.current=l,j.current+=1,k.current+=1);const y=t.useCallback(s=>A(s,l),[l]),u=t.useCallback(async(s,r)=>{const n=await fetch(s,{...r,headers:{"Content-Type":"application/json",...r?.headers??{}}});if(!n.ok){const g=await n.json().catch(()=>({error:"Request failed"}));throw new Error(String(g?.error??"Request failed"))}if(n.status!==204)return n.json()},[]),S=t.useCallback(async()=>{const s=l;if(o.current!==s)return;const r=++j.current;W(!0),M(null),D(void 0);try{const n=await u(y("/api/secrets"));r===j.current&&o.current===s&&(Y(n.secrets),U(s))}catch(n){r===j.current&&o.current===s&&(M(n instanceof Error?n.message:String(n)),D(s))}finally{r===j.current&&o.current===s&&W(!1)}},[l,y,u]),R=t.useCallback(async()=>{const s=l;if(o.current!==s)return;const r=++k.current;try{const n=await u(y("/api/secrets/sync-passphrase"));r===k.current&&o.current===s&&(se(!!n.configured),ae(s))}catch(n){r===k.current&&o.current===s&&p?.(a("secrets.errorLoadSyncStatus","Failed to load sync passphrase status: {{error}}",{error:n instanceof Error?n.message:String(n)}),"error")}},[p,l,y,u,a]);t.useEffect(()=>(Y([]),U(void 0),f({}),K(null),se(!1),ae(void 0),M(null),D(void 0),b(null),V(null),x(!1),E(!1),C(null),O(!1),F(""),_(""),$(!1),S(),R(),()=>{v.current.forEach(s=>clearTimeout(s)),I.current.forEach(s=>clearTimeout(s))}),[S,R,l]);const z=()=>{O(!1),F(""),_("")},ve=async(s,r)=>{await u(A("/api/secrets/sync-passphrase",r),{method:"PUT",body:JSON.stringify({passphrase:s})})},be=async()=>{const s=l;$(!0);try{if(await ve(w,s),o.current!==s)return;p?.(m?a("secrets.syncPassphraseRotated","Sync passphrase rotated"):a("secrets.syncPassphraseSet","Sync passphrase set"),"success"),z(),await R()}catch(r){o.current===s&&p?.(a("secrets.errorSaveSyncPassphrase","Failed to save sync passphrase: {{error}}",{error:r instanceof Error?r.message:String(r)}),"error")}finally{o.current===s&&$(!1)}},fe=async()=>{if(!window.confirm(a("secrets.confirmClearSyncPassphrase","Clear the cross-node sync passphrase? Existing sync pairs will stop working until you set a new passphrase.")))return;const r=l;try{if(await u(A("/api/secrets/sync-passphrase",r),{method:"DELETE"}),o.current!==r)return;p?.(a("secrets.syncPassphraseCleared","Sync passphrase cleared"),"success"),await R()}catch(n){o.current===r&&p?.(a("secrets.errorClearSyncPassphrase","Failed to clear sync passphrase: {{error}}",{error:n instanceof Error?n.message:String(n)}),"error")}},je=()=>{V(null),i(G),x(!0),E(!1),b(null)},Se=s=>{V(s),i({key:s.key,value:"",description:s.description??"",scope:s.scope,accessPolicy:s.accessPolicy,envExportable:s.envExportable,envExportKey:s.envExportKey??""}),x(!0),E(!1),b(null)},ge=async()=>{const s=l;b(null);try{if(h){const r={key:c.key,description:c.description||null,accessPolicy:c.accessPolicy,envExportable:c.envExportable,envExportKey:c.envExportable&&c.envExportKey||null};c.value&&(r.value=c.value),await u(y(`/api/secrets/${h.scope}/${h.id}`),{method:"PATCH",body:JSON.stringify(r)})}else await u(y("/api/secrets"),{method:"POST",body:JSON.stringify({scope:c.scope,key:c.key,value:c.value,description:c.description||null,accessPolicy:c.accessPolicy,envExportable:c.envExportable,envExportKey:c.envExportable&&c.envExportKey||null})});if(o.current!==s)return;x(!1),i(G),await S()}catch(r){o.current===s&&b(r instanceof Error?r.message:String(r))}},Ne=s=>{const r=v.current.get(s.id);r&&(clearTimeout(r),v.current.delete(s.id)),f(n=>({...n,[s.id]:null}))},Pe=async s=>{const r=l,n=await u(y(`/api/secrets/${s.scope}/${s.id}/reveal`),{method:"POST"});if(o.current!==r)return;f(P=>({...P,[s.id]:n.value})),p?.(a("secrets.revealed","Revealed"),"success");const g=setTimeout(()=>{f(P=>({...P,[s.id]:null})),v.current.delete(s.id)},3e4),N=v.current.get(s.id);N&&clearTimeout(N),v.current.set(s.id,g)},Ce=async s=>{const r=ee[s.id];if(!r)return;if(!await qe(r)){p?.(a("secrets.copyFailed","Failed to copy secret"),"error");return}K(s.id),p?.(a("secrets.copied","Copied"),"success");const g=setTimeout(()=>{K(null),f(P=>({...P,[s.id]:null}))},1500),N=I.current.get(s.id);N&&clearTimeout(N),I.current.set(s.id,g)},Ee=async s=>{const r=l;await u(A(`/api/secrets/${s.scope}/${s.id}`,r),{method:"DELETE"}),o.current===r&&(C(null),await S())},L=oe===l,T=he===l,re=t.useMemo(()=>[...L?J:[]].filter(s=>!(s.scope==="global"&&s.key===Oe)).sort((s,r)=>s.key.localeCompare(r.key)),[J,L]),te=w.length>0&&w===B;return e.jsxs("section",{className:"secrets-view",children:[e.jsx(we,{icon:ke,title:a("secrets.title","Secrets"),actions:e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn-sm",onClick:()=>void S(),children:[e.jsx(ce,{...d})," ",a("secrets.refresh","Refresh")]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:je,children:[e.jsx(Re,{...d})," ",a("secrets.addSecret","Add Secret")]})]})}),X&&ie===l?e.jsx("div",{className:"form-error",children:X}):null,Q||!L?e.jsxs("div",{className:"secrets-loading",children:[e.jsx(ce,{...Fe})," ",a("secrets.loading","Loading…")]}):null,!Q&&L&&re.length===0?e.jsx("div",{className:"secrets-empty",children:a("secrets.empty","No secrets found.")}):null,e.jsx("div",{className:"secrets-list",children:re.map(s=>{const r=ee[s.id];return e.jsxs("article",{className:"card secrets-row",children:[e.jsxs("div",{className:"secrets-row-main",children:[e.jsx("div",{className:"secrets-row-key",children:s.key}),e.jsxs("div",{className:"secrets-row-meta",children:[e.jsx("span",{className:"secrets-chip",children:s.scope}),e.jsx("span",{className:"secrets-chip",children:s.accessPolicy}),s.envExportable?e.jsx("span",{className:"secrets-chip",children:a("secrets.envExportableChip","env exportable")}):null]}),r?e.jsx("pre",{className:"secrets-revealed",children:r}):null]}),e.jsxs("div",{className:"secrets-row-side",children:[e.jsx("span",{className:"secrets-row-read",children:s.lastReadAt?new Date(s.lastReadAt).toLocaleString():a("secrets.neverRead","Never read")}),e.jsxs("div",{className:"secrets-row-actions",children:[e.jsx("button",{type:"button",className:"btn btn-icon secrets-visibility-toggle",onClick:()=>{if(r){Ne(s);return}Pe(s)},"aria-label":r?a("secrets.hideAriaLabel","Hide"):a("secrets.revealAriaLabel","Reveal"),children:r?e.jsx(ne,{...d}):e.jsx(le,{...d})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>void Ce(s),"aria-label":a("secrets.copyAriaLabel","Copy"),disabled:!r,children:pe===s.id?e.jsx(Le,{...d}):e.jsx(Te,{...d})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>Se(s),"aria-label":a("secrets.editAriaLabel","Edit"),children:e.jsx(Ae,{...d})}),e.jsx("button",{className:"btn btn-icon btn-danger",onClick:()=>C(s.id),"aria-label":a("secrets.deleteAriaLabel","Delete"),children:e.jsx(Me,{...d})})]}),ue===s.id?e.jsxs("div",{className:"secrets-confirm",children:[e.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void Ee(s),children:a("secrets.confirmDelete","Confirm")}),e.jsx("button",{className:"btn btn-sm",onClick:()=>C(null),children:a("secrets.cancelDelete","Cancel")})]}):null]})]},s.id)})}),e.jsxs("article",{className:"card secrets-sync-card secrets-sync-disclosure",children:[e.jsxs("button",{type:"button",className:"secrets-sync-disclosure-toggle","data-testid":"secrets-passphrase-disclosure","aria-expanded":H,"aria-controls":"secrets-sync-disclosure-panel",onClick:()=>xe(s=>!s),children:[H?e.jsx(De,{size:16,"aria-hidden":"true"}):e.jsx(Ve,{size:16,"aria-hidden":"true"}),e.jsx("span",{children:a("secrets.syncPassphraseTitle","Cross-Node Sync Passphrase")})]}),H?e.jsxs("div",{id:"secrets-sync-disclosure-panel",className:"secrets-sync-disclosure-panel",children:[e.jsxs("div",{className:"secrets-sync-header",children:[e.jsxs("p",{className:"secrets-sync-status",children:[e.jsx("span",{className:`status-dot ${T&&m?"status-dot--online":"status-dot--pending"}`,"aria-hidden":"true"})," ",T&&m?a("secrets.syncConfigured","Configured"):a("secrets.syncNotConfigured","Not configured")]}),e.jsxs("div",{className:"secrets-sync-actions",children:[e.jsx("button",{className:"btn",onClick:()=>O(!0),children:T&&m?a("secrets.rotateSyncPassphrase","Rotate"):a("secrets.setPassphrase","Set passphrase")}),T&&m?e.jsx("button",{className:"btn btn-danger",onClick:()=>void fe(),children:a("secrets.clearSyncPassphrase","Clear")}):null]})]}),e.jsx("p",{className:"secrets-sync-copy",children:a("secrets.syncPassphraseDescription","Shared passphrase used to wrap cross-node secret bundles. Both nodes in a sync pair must share the same value. Stored locally only; never transmitted.")})]}):null]}),me?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":m?a("secrets.rotateSyncPassphraseModalTitle","Rotate sync passphrase"):a("secrets.setSyncPassphraseModalTitle","Set sync passphrase"),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:m?a("secrets.rotateSyncPassphraseModalTitle","Rotate sync passphrase"):a("secrets.setSyncPassphraseModalTitle","Set sync passphrase")}),e.jsx("button",{className:"modal-close",onClick:z,"aria-label":a("secrets.closeAriaLabel","Close"),children:"×"})]}),e.jsxs("div",{className:"secrets-modal-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.passphraseLabel","Passphrase")}),e.jsx("input",{"aria-label":a("secrets.passphraseLabel","Passphrase"),className:"input",type:"password",autoComplete:"new-password",value:w,onChange:s=>F(s.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.confirmPassphraseLabel","Confirm passphrase")}),e.jsx("input",{"aria-label":a("secrets.confirmPassphraseLabel","Confirm passphrase"),className:"input",type:"password",autoComplete:"new-password",value:B,onChange:s=>_(s.target.value)})]}),!te&&B.length>0?e.jsx("div",{className:"form-error",children:a("secrets.passphraseMustMatch","Passphrases must match.")}):null]}),e.jsx("div",{className:"modal-actions",children:e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn",onClick:z,children:a("secrets.cancelBtn","Cancel")}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void be(),disabled:!te||ye,children:m?a("secrets.rotateSyncPassphrase","Rotate"):a("secrets.setPassphrase","Set passphrase")})]})})]})}):null,de?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":h?a("secrets.editSecretModalTitle","Edit secret"):a("secrets.addSecretModalTitle","Add secret"),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:h?a("secrets.editSecretModalTitle","Edit secret"):a("secrets.addSecretModalTitle","Add secret")}),e.jsx("button",{className:"modal-close",onClick:()=>x(!1),"aria-label":a("secrets.closeAriaLabel","Close"),children:"×"})]}),e.jsxs("div",{className:"secrets-modal-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.keyLabel","Key")}),e.jsx("input",{className:"input",value:c.key,onChange:s=>i(r=>({...r,key:s.target.value}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.valueLabel","Value")}),e.jsxs("div",{className:"secrets-value-row",children:[e.jsx("input",{className:"input",type:q?"text":"password",autoComplete:"off",spellCheck:!1,value:c.value,onChange:s=>i(r=>({...r,value:s.target.value}))}),e.jsx("button",{type:"button",className:"btn btn-icon secrets-visibility-toggle",onClick:()=>E(s=>!s),"aria-label":q?a("secrets.hideValueAriaLabel","Hide value"):a("secrets.showValueAriaLabel","Show value"),children:q?e.jsx(ne,{...d}):e.jsx(le,{...d})})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.descriptionLabel","Description")}),e.jsx("textarea",{className:"input",value:c.description,onChange:s=>i(r=>({...r,description:s.target.value}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.scopeLabel","Scope")}),e.jsxs("div",{className:"secrets-radio-row",children:[e.jsxs("label",{children:[e.jsx("input",{type:"radio",checked:c.scope==="project",onChange:()=>i(s=>({...s,scope:"project"})),disabled:!!h})," ",a("secrets.scopeProject","Project")]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",checked:c.scope==="global",onChange:()=>i(s=>({...s,scope:"global"})),disabled:!!h})," ",a("secrets.scopeGlobal","Global")]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.accessPolicyLabel","Access policy")}),e.jsxs("select",{className:"select",value:c.accessPolicy,onChange:s=>i(r=>({...r,accessPolicy:s.target.value})),children:[e.jsx("option",{value:"auto",children:a("secrets.accessPolicyAuto","auto")}),e.jsx("option",{value:"prompt",children:a("secrets.accessPolicyPrompt","prompt")}),e.jsx("option",{value:"deny",children:a("secrets.accessPolicyDeny","deny")})]})]}),e.jsx("div",{className:"form-group",children:e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:c.envExportable,onChange:s=>i(r=>({...r,envExportable:s.target.checked}))})," ",a("secrets.exportToEnvLabel","Export to env")]})}),c.envExportable?e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.envKeyLabel","Env key")}),e.jsx("input",{className:"input",value:c.envExportKey,onChange:s=>i(r=>({...r,envExportKey:s.target.value}))})]}):null,Z?e.jsx("div",{className:"form-error",children:Z}):null]}),e.jsx("div",{className:"modal-actions",children:e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn",onClick:()=>x(!1),children:a("secrets.cancelBtn","Cancel")}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void ge(),children:h?a("secrets.saveBtn","Save"):a("secrets.createBtn","Create")})]})})]})}):null]})};export{Ge as SecretsView};
1
+ import{r as t,j as e}from"./vendor-react-SZ_qB27O.js";import{w as A,V as we,x as ke,R as ce,P as Re,E as ne,y as le,z as Le,B as Te,D as Ae,F as Me,C as De,k as Ve,G as qe}from"./index-oxnX59eO.js";import{u as Ke}from"./vendor-i18n-Duky4gdQ.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";import"./vendor-xterm-BNq00GSj.js";const Oe="__sync_passphrase__",G={key:"",value:"",description:"",scope:"project",accessPolicy:"prompt",envExportable:!1,envExportKey:""},d={className:"secrets-action-icon","aria-hidden":!0,style:{width:"1em",height:"1em"}},Fe={...d,className:"secrets-action-icon spin"},Ge=({addToast:p,projectId:l})=>{const{t:a}=Ke("app"),[J,Y]=t.useState([]),[oe,U]=t.useState(),[Q,W]=t.useState(!0),[X,M]=t.useState(null),[ie,D]=t.useState(),[Z,b]=t.useState(null),[h,V]=t.useState(null),[de,x]=t.useState(!1),[ue,C]=t.useState(null),[c,i]=t.useState(G),[q,E]=t.useState(!1),[ee,f]=t.useState({}),[pe,K]=t.useState(null),[m,se]=t.useState(!1),[he,ae]=t.useState(),[me,O]=t.useState(!1),[w,F]=t.useState(""),[B,_]=t.useState(""),[ye,$]=t.useState(!1),[H,xe]=t.useState(!1),v=t.useRef(new Map),I=t.useRef(new Map),j=t.useRef(0),k=t.useRef(0),o=t.useRef(l);o.current!==l&&(o.current=l,j.current+=1,k.current+=1);const y=t.useCallback(s=>A(s,l),[l]),u=t.useCallback(async(s,r)=>{const n=await fetch(s,{...r,headers:{"Content-Type":"application/json",...r?.headers??{}}});if(!n.ok){const g=await n.json().catch(()=>({error:"Request failed"}));throw new Error(String(g?.error??"Request failed"))}if(n.status!==204)return n.json()},[]),S=t.useCallback(async()=>{const s=l;if(o.current!==s)return;const r=++j.current;W(!0),M(null),D(void 0);try{const n=await u(y("/api/secrets"));r===j.current&&o.current===s&&(Y(n.secrets),U(s))}catch(n){r===j.current&&o.current===s&&(M(n instanceof Error?n.message:String(n)),D(s))}finally{r===j.current&&o.current===s&&W(!1)}},[l,y,u]),R=t.useCallback(async()=>{const s=l;if(o.current!==s)return;const r=++k.current;try{const n=await u(y("/api/secrets/sync-passphrase"));r===k.current&&o.current===s&&(se(!!n.configured),ae(s))}catch(n){r===k.current&&o.current===s&&p?.(a("secrets.errorLoadSyncStatus","Failed to load sync passphrase status: {{error}}",{error:n instanceof Error?n.message:String(n)}),"error")}},[p,l,y,u,a]);t.useEffect(()=>(Y([]),U(void 0),f({}),K(null),se(!1),ae(void 0),M(null),D(void 0),b(null),V(null),x(!1),E(!1),C(null),O(!1),F(""),_(""),$(!1),S(),R(),()=>{v.current.forEach(s=>clearTimeout(s)),I.current.forEach(s=>clearTimeout(s))}),[S,R,l]);const z=()=>{O(!1),F(""),_("")},ve=async(s,r)=>{await u(A("/api/secrets/sync-passphrase",r),{method:"PUT",body:JSON.stringify({passphrase:s})})},be=async()=>{const s=l;$(!0);try{if(await ve(w,s),o.current!==s)return;p?.(m?a("secrets.syncPassphraseRotated","Sync passphrase rotated"):a("secrets.syncPassphraseSet","Sync passphrase set"),"success"),z(),await R()}catch(r){o.current===s&&p?.(a("secrets.errorSaveSyncPassphrase","Failed to save sync passphrase: {{error}}",{error:r instanceof Error?r.message:String(r)}),"error")}finally{o.current===s&&$(!1)}},fe=async()=>{if(!window.confirm(a("secrets.confirmClearSyncPassphrase","Clear the cross-node sync passphrase? Existing sync pairs will stop working until you set a new passphrase.")))return;const r=l;try{if(await u(A("/api/secrets/sync-passphrase",r),{method:"DELETE"}),o.current!==r)return;p?.(a("secrets.syncPassphraseCleared","Sync passphrase cleared"),"success"),await R()}catch(n){o.current===r&&p?.(a("secrets.errorClearSyncPassphrase","Failed to clear sync passphrase: {{error}}",{error:n instanceof Error?n.message:String(n)}),"error")}},je=()=>{V(null),i(G),x(!0),E(!1),b(null)},Se=s=>{V(s),i({key:s.key,value:"",description:s.description??"",scope:s.scope,accessPolicy:s.accessPolicy,envExportable:s.envExportable,envExportKey:s.envExportKey??""}),x(!0),E(!1),b(null)},ge=async()=>{const s=l;b(null);try{if(h){const r={key:c.key,description:c.description||null,accessPolicy:c.accessPolicy,envExportable:c.envExportable,envExportKey:c.envExportable&&c.envExportKey||null};c.value&&(r.value=c.value),await u(y(`/api/secrets/${h.scope}/${h.id}`),{method:"PATCH",body:JSON.stringify(r)})}else await u(y("/api/secrets"),{method:"POST",body:JSON.stringify({scope:c.scope,key:c.key,value:c.value,description:c.description||null,accessPolicy:c.accessPolicy,envExportable:c.envExportable,envExportKey:c.envExportable&&c.envExportKey||null})});if(o.current!==s)return;x(!1),i(G),await S()}catch(r){o.current===s&&b(r instanceof Error?r.message:String(r))}},Ne=s=>{const r=v.current.get(s.id);r&&(clearTimeout(r),v.current.delete(s.id)),f(n=>({...n,[s.id]:null}))},Pe=async s=>{const r=l,n=await u(y(`/api/secrets/${s.scope}/${s.id}/reveal`),{method:"POST"});if(o.current!==r)return;f(P=>({...P,[s.id]:n.value})),p?.(a("secrets.revealed","Revealed"),"success");const g=setTimeout(()=>{f(P=>({...P,[s.id]:null})),v.current.delete(s.id)},3e4),N=v.current.get(s.id);N&&clearTimeout(N),v.current.set(s.id,g)},Ce=async s=>{const r=ee[s.id];if(!r)return;if(!await qe(r)){p?.(a("secrets.copyFailed","Failed to copy secret"),"error");return}K(s.id),p?.(a("secrets.copied","Copied"),"success");const g=setTimeout(()=>{K(null),f(P=>({...P,[s.id]:null}))},1500),N=I.current.get(s.id);N&&clearTimeout(N),I.current.set(s.id,g)},Ee=async s=>{const r=l;await u(A(`/api/secrets/${s.scope}/${s.id}`,r),{method:"DELETE"}),o.current===r&&(C(null),await S())},L=oe===l,T=he===l,re=t.useMemo(()=>[...L?J:[]].filter(s=>!(s.scope==="global"&&s.key===Oe)).sort((s,r)=>s.key.localeCompare(r.key)),[J,L]),te=w.length>0&&w===B;return e.jsxs("section",{className:"secrets-view",children:[e.jsx(we,{icon:ke,title:a("secrets.title","Secrets"),actions:e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn-sm",onClick:()=>void S(),children:[e.jsx(ce,{...d})," ",a("secrets.refresh","Refresh")]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:je,children:[e.jsx(Re,{...d})," ",a("secrets.addSecret","Add Secret")]})]})}),X&&ie===l?e.jsx("div",{className:"form-error",children:X}):null,Q||!L?e.jsxs("div",{className:"secrets-loading",children:[e.jsx(ce,{...Fe})," ",a("secrets.loading","Loading…")]}):null,!Q&&L&&re.length===0?e.jsx("div",{className:"secrets-empty",children:a("secrets.empty","No secrets found.")}):null,e.jsx("div",{className:"secrets-list",children:re.map(s=>{const r=ee[s.id];return e.jsxs("article",{className:"card secrets-row",children:[e.jsxs("div",{className:"secrets-row-main",children:[e.jsx("div",{className:"secrets-row-key",children:s.key}),e.jsxs("div",{className:"secrets-row-meta",children:[e.jsx("span",{className:"secrets-chip",children:s.scope}),e.jsx("span",{className:"secrets-chip",children:s.accessPolicy}),s.envExportable?e.jsx("span",{className:"secrets-chip",children:a("secrets.envExportableChip","env exportable")}):null]}),r?e.jsx("pre",{className:"secrets-revealed",children:r}):null]}),e.jsxs("div",{className:"secrets-row-side",children:[e.jsx("span",{className:"secrets-row-read",children:s.lastReadAt?new Date(s.lastReadAt).toLocaleString():a("secrets.neverRead","Never read")}),e.jsxs("div",{className:"secrets-row-actions",children:[e.jsx("button",{type:"button",className:"btn btn-icon secrets-visibility-toggle",onClick:()=>{if(r){Ne(s);return}Pe(s)},"aria-label":r?a("secrets.hideAriaLabel","Hide"):a("secrets.revealAriaLabel","Reveal"),children:r?e.jsx(ne,{...d}):e.jsx(le,{...d})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>void Ce(s),"aria-label":a("secrets.copyAriaLabel","Copy"),disabled:!r,children:pe===s.id?e.jsx(Le,{...d}):e.jsx(Te,{...d})}),e.jsx("button",{className:"btn btn-icon",onClick:()=>Se(s),"aria-label":a("secrets.editAriaLabel","Edit"),children:e.jsx(Ae,{...d})}),e.jsx("button",{className:"btn btn-icon btn-danger",onClick:()=>C(s.id),"aria-label":a("secrets.deleteAriaLabel","Delete"),children:e.jsx(Me,{...d})})]}),ue===s.id?e.jsxs("div",{className:"secrets-confirm",children:[e.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void Ee(s),children:a("secrets.confirmDelete","Confirm")}),e.jsx("button",{className:"btn btn-sm",onClick:()=>C(null),children:a("secrets.cancelDelete","Cancel")})]}):null]})]},s.id)})}),e.jsxs("article",{className:"card secrets-sync-card secrets-sync-disclosure",children:[e.jsxs("button",{type:"button",className:"secrets-sync-disclosure-toggle","data-testid":"secrets-passphrase-disclosure","aria-expanded":H,"aria-controls":"secrets-sync-disclosure-panel",onClick:()=>xe(s=>!s),children:[H?e.jsx(De,{size:16,"aria-hidden":"true"}):e.jsx(Ve,{size:16,"aria-hidden":"true"}),e.jsx("span",{children:a("secrets.syncPassphraseTitle","Cross-Node Sync Passphrase")})]}),H?e.jsxs("div",{id:"secrets-sync-disclosure-panel",className:"secrets-sync-disclosure-panel",children:[e.jsxs("div",{className:"secrets-sync-header",children:[e.jsxs("p",{className:"secrets-sync-status",children:[e.jsx("span",{className:`status-dot ${T&&m?"status-dot--online":"status-dot--pending"}`,"aria-hidden":"true"})," ",T&&m?a("secrets.syncConfigured","Configured"):a("secrets.syncNotConfigured","Not configured")]}),e.jsxs("div",{className:"secrets-sync-actions",children:[e.jsx("button",{className:"btn",onClick:()=>O(!0),children:T&&m?a("secrets.rotateSyncPassphrase","Rotate"):a("secrets.setPassphrase","Set passphrase")}),T&&m?e.jsx("button",{className:"btn btn-danger",onClick:()=>void fe(),children:a("secrets.clearSyncPassphrase","Clear")}):null]})]}),e.jsx("p",{className:"secrets-sync-copy",children:a("secrets.syncPassphraseDescription","Shared passphrase used to wrap cross-node secret bundles. Both nodes in a sync pair must share the same value. Stored locally only; never transmitted.")})]}):null]}),me?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":m?a("secrets.rotateSyncPassphraseModalTitle","Rotate sync passphrase"):a("secrets.setSyncPassphraseModalTitle","Set sync passphrase"),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:m?a("secrets.rotateSyncPassphraseModalTitle","Rotate sync passphrase"):a("secrets.setSyncPassphraseModalTitle","Set sync passphrase")}),e.jsx("button",{className:"modal-close",onClick:z,"aria-label":a("secrets.closeAriaLabel","Close"),children:"×"})]}),e.jsxs("div",{className:"secrets-modal-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.passphraseLabel","Passphrase")}),e.jsx("input",{"aria-label":a("secrets.passphraseLabel","Passphrase"),className:"input",type:"password",autoComplete:"new-password",value:w,onChange:s=>F(s.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.confirmPassphraseLabel","Confirm passphrase")}),e.jsx("input",{"aria-label":a("secrets.confirmPassphraseLabel","Confirm passphrase"),className:"input",type:"password",autoComplete:"new-password",value:B,onChange:s=>_(s.target.value)})]}),!te&&B.length>0?e.jsx("div",{className:"form-error",children:a("secrets.passphraseMustMatch","Passphrases must match.")}):null]}),e.jsx("div",{className:"modal-actions",children:e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn",onClick:z,children:a("secrets.cancelBtn","Cancel")}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void be(),disabled:!te||ye,children:m?a("secrets.rotateSyncPassphrase","Rotate"):a("secrets.setPassphrase","Set passphrase")})]})})]})}):null,de?e.jsx("div",{className:"modal-overlay open",role:"presentation",children:e.jsxs("div",{className:"modal",role:"dialog","aria-modal":"true","aria-label":h?a("secrets.editSecretModalTitle","Edit secret"):a("secrets.addSecretModalTitle","Add secret"),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:h?a("secrets.editSecretModalTitle","Edit secret"):a("secrets.addSecretModalTitle","Add secret")}),e.jsx("button",{className:"modal-close",onClick:()=>x(!1),"aria-label":a("secrets.closeAriaLabel","Close"),children:"×"})]}),e.jsxs("div",{className:"secrets-modal-body",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.keyLabel","Key")}),e.jsx("input",{className:"input",value:c.key,onChange:s=>i(r=>({...r,key:s.target.value}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.valueLabel","Value")}),e.jsxs("div",{className:"secrets-value-row",children:[e.jsx("input",{className:"input",type:q?"text":"password",autoComplete:"off",spellCheck:!1,value:c.value,onChange:s=>i(r=>({...r,value:s.target.value}))}),e.jsx("button",{type:"button",className:"btn btn-icon secrets-visibility-toggle",onClick:()=>E(s=>!s),"aria-label":q?a("secrets.hideValueAriaLabel","Hide value"):a("secrets.showValueAriaLabel","Show value"),children:q?e.jsx(ne,{...d}):e.jsx(le,{...d})})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.descriptionLabel","Description")}),e.jsx("textarea",{className:"input",value:c.description,onChange:s=>i(r=>({...r,description:s.target.value}))})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.scopeLabel","Scope")}),e.jsxs("div",{className:"secrets-radio-row",children:[e.jsxs("label",{children:[e.jsx("input",{type:"radio",checked:c.scope==="project",onChange:()=>i(s=>({...s,scope:"project"})),disabled:!!h})," ",a("secrets.scopeProject","Project")]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",checked:c.scope==="global",onChange:()=>i(s=>({...s,scope:"global"})),disabled:!!h})," ",a("secrets.scopeGlobal","Global")]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.accessPolicyLabel","Access policy")}),e.jsxs("select",{className:"select",value:c.accessPolicy,onChange:s=>i(r=>({...r,accessPolicy:s.target.value})),children:[e.jsx("option",{value:"auto",children:a("secrets.accessPolicyAuto","auto")}),e.jsx("option",{value:"prompt",children:a("secrets.accessPolicyPrompt","prompt")}),e.jsx("option",{value:"deny",children:a("secrets.accessPolicyDeny","deny")})]})]}),e.jsx("div",{className:"form-group",children:e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:c.envExportable,onChange:s=>i(r=>({...r,envExportable:s.target.checked}))})," ",a("secrets.exportToEnvLabel","Export to env")]})}),c.envExportable?e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:a("secrets.envKeyLabel","Env key")}),e.jsx("input",{className:"input",value:c.envExportKey,onChange:s=>i(r=>({...r,envExportKey:s.target.value}))})]}):null,Z?e.jsx("div",{className:"form-error",children:Z}):null]}),e.jsx("div",{className:"modal-actions",children:e.jsxs("div",{className:"modal-actions-right",children:[e.jsx("button",{className:"btn",onClick:()=>x(!1),children:a("secrets.cancelBtn","Cancel")}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void ge(),children:h?a("secrets.saveBtn","Save"):a("secrets.createBtn","Create")})]})})]})}):null]})};export{Ge as SecretsView};
@@ -1,2 +1,2 @@
1
1
  const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor-xterm-BNq00GSj.js","assets/vendor-react-SZ_qB27O.js","assets/vendor-xterm-LZoznX6r.css","assets/addon-fit-C1WQXRvu.js","assets/addon-webgl-uLc0RKcC.js"])))=>i.map(i=>d[i]);
2
- import{W as je,Y as z,_ as ue,$ as J,a0 as me,a1 as F,a2 as Me,a3 as Le,y as De,a4 as Oe,a5 as Y,a6 as Ae,a7 as ze,a as Fe,a8 as K,a9 as Be,aa as Ie}from"./index-I32FijPT.js";import{r as i,j as t}from"./vendor-react-SZ_qB27O.js";import"./vendor-xterm-BNq00GSj.js";import{u as Ke}from"./vendor-i18n-Duky4gdQ.js";import{S as We}from"./shield-alert-BBDlP6A5.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";const $e=32*1024,Ue=1e4,Qe=100,Ve="\x1B",Je=" ",Ye="",Ge="\x1B[A",He="\x1B[B",qe="\x1B[C",Ze="\x1B[D",W={ctrl:"Ctrl",escape:"Esc",tab:"Tab",ctrlC:"^C"};function fe(m){if(m.length!==1)return null;const o=m.toUpperCase().charCodeAt(0);return o>=64&&o<=95?String.fromCharCode(o&31):null}function Xe(){const[m,f]=i.useState(()=>Y());return i.useEffect(()=>{if(typeof window>"u"||typeof window.matchMedia!="function")return;const o=window.matchMedia(Ae),a=window.visualViewport,y=()=>f(Y());return y(),typeof a?.addEventListener=="function"&&a.addEventListener("resize",y),typeof o.addEventListener=="function"?(o.addEventListener("change",y),()=>{o.removeEventListener("change",y),typeof a?.removeEventListener=="function"&&a.removeEventListener("resize",y)}):(o.addListener(y),()=>{o.removeListener(y),typeof a?.removeEventListener=="function"&&a.removeEventListener("resize",y)})},[]),m}function et(m,f){if(typeof window>"u")return"";const a=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/api/cli-sessions/ws?sessionId=${encodeURIComponent(m)}&ticket=${encodeURIComponent(f)}`;return Ie(a)}function tt(){return/Mac|iPhone|iPad|iPod/i.test(navigator.platform)}function pe(m){if(typeof window<"u"&&typeof window.atob=="function"){const f=window.atob(m),o=new Uint8Array(f.length);for(let a=0;a<f.length;a++)o[a]=f.charCodeAt(a);return new TextDecoder("utf-8").decode(o)}return Buffer.from(m,"base64").toString("utf8")}function ut({sessionId:m,readOnly:f=!1,posture:o,mode:a="live",projectId:y,onConfirmAdvance:g,showConfirmAdvance:$=!1,onOpenAdapterSettings:G,active:H=!0}){const{t:r}=Ke("app"),x=i.useRef(null),C=i.useRef(null),N=i.useRef(null),R=i.useRef(null),w=i.useRef(null),[q,Z]=i.useState(!1),[ye,U]=i.useState(!1),[X,ee]=i.useState(!1),P=Xe(),{keyboardOpen:B,keyboardOverlap:be}=je({enabled:P}),he=i.useRef(null),[v,te]=i.useState(""),[j,D]=i.useState(!1),[we,Se]=i.useState(()=>z().customShortcuts),[ne,ie]=i.useState(null),se=f||ne===!0,O=!f&&ne===!1&&a==="live",b=i.useCallback(e=>{if(!e||!O)return;const n=w.current;n?.readyState===WebSocket.OPEN&&n.send(JSON.stringify({type:"input",data:e}))},[O]),M=i.useCallback(e=>{if(j){const n=fe(e);if(D(!1),n){b(n);return}}b(e)},[j,b]),c=i.useCallback(e=>{e.preventDefault()},[]),_e=i.useCallback(e=>{e?.preventDefault?.(),v&&b(v),b("\r"),te("")},[v,b]),ke=i.useCallback(e=>{if(j&&e.length>v.length){const n=e.slice(v.length,v.length+1),l=fe(n);if(D(!1),l){b(l);return}}te(e)},[j,v,b]);i.useEffect(()=>{$&&U(!1)},[$,m]);const T=i.useCallback((e,n)=>{const l=w.current;l?.readyState===WebSocket.OPEN&&l.send(JSON.stringify({type:"resize",cols:e,rows:n}))},[]),oe=i.useCallback(()=>{const e=C.current;if(!e)return;const n=z(),l=ue(n.fontFamily);e.options.fontFamily=l,x.current?.style.setProperty("--terminal-glyph-font-family",J(n.fontFamily)),e.options.fontSize=n.fontSize,e.options.cursorStyle=n.cursorStyle,e.options.cursorBlink=n.cursorBlink&&O;try{N.current?.fit?.(),T(e.cols,e.rows)}catch{}me(n.fontSize,l).then(E=>{if(!(!E||C.current!==e||e.options.fontSize!==n.fontSize||e.options.fontFamily!==l)){F(e,l),e.options.fontSize=n.fontSize;try{N.current?.fit?.(),T(e.cols,e.rows),F(e,l),e.refresh(0,Math.max(0,e.rows-1))}catch{}}},()=>{})},[O,T]);i.useEffect(()=>{if(typeof window>"u")return;const e=n=>{n.key===ze&&(oe(),Se(z().customShortcuts))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)},[oe]);const[ve,Ee]=i.useState(0);i.useEffect(()=>{if(!H)return;const e=C.current,n=N.current;if(e&&n?.fit)try{n.fit(),T(e.cols,e.rows),F(e,String(e.options.fontFamily??"")),e.refresh(0,Math.max(0,e.rows-1))}catch{}const l=w.current;l&&l.readyState!==WebSocket.OPEN&&l.readyState!==WebSocket.CONNECTING&&Ee(E=>E+1)},[H,T]),i.useEffect(()=>{if(!m||typeof window>"u")return;let e=!1,n=null,l=null,E=0;ie(null);const Q=T,le=p=>{if(E+=p,E<$e)return;const S=w.current;S?.readyState===WebSocket.OPEN&&S.send(JSON.stringify({type:"ack",bytes:E})),E=0};return(async()=>{let p;try{p=await Fe(`/cli-sessions/${encodeURIComponent(m)}/attach-ticket`,{method:"POST",body:JSON.stringify(y?{projectId:y}:{})})}catch{return}if(e)return;ie(p.readOnly);const S=!f&&!p.readOnly&&a==="live",[{Terminal:xe},{FitAddon:Ne},{Unicode11Addon:Re}]=await Promise.all([K(()=>import("./vendor-xterm-BNq00GSj.js").then(d=>d.x),__vite__mapDeps([0,1,2])),K(()=>import("./addon-fit-C1WQXRvu.js").then(d=>d.a),__vite__mapDeps([3,1])),K(()=>import("./addon-unicode11-D3Fsv-Po.js"),[])]);if(e||!x.current)return;const _=z(),A=ue(_.fontFamily);x.current.style.setProperty("--terminal-glyph-font-family",J(_.fontFamily));const s=new xe({convertEol:!1,cursorBlink:_.cursorBlink&&S,cursorStyle:_.cursorStyle,disableStdin:!S,scrollback:Ue,fontFamily:A,fontSize:_.fontSize}),L=new Ne;s.loadAddon(L);const Pe=new Re;if(s.loadAddon(Pe),s.unicode.activeVersion="11",Be(()=>{s.open(x.current)}),C.current=s,N.current=L,_.renderer==="auto"&&!Y())try{const{WebglAddon:d}=await K(async()=>{const{WebglAddon:u}=await import("./addon-webgl-uLc0RKcC.js").then(h=>h.a);return{WebglAddon:u}},__vite__mapDeps([4,1]));if(!e){const u=new d;u.onContextLoss(()=>{try{u.dispose()}catch{}R.current===u&&(R.current=null)}),s.loadAddon(u),R.current=u}}catch{}try{L.fit()}catch{}(async()=>{if(!(!await me(_.fontSize,A)||e||C.current!==s||N.current!==L||s.options.fontSize!==_.fontSize||s.options.fontFamily!==A))try{F(s,A),s.options.fontSize=_.fontSize,L.fit(),Q(s.cols,s.rows),F(s,A),s.refresh(0,Math.max(0,s.rows-1))}catch{}})(),S&&(s.onData(d=>{const u=w.current;u?.readyState===WebSocket.OPEN&&u.send(JSON.stringify({type:"input",data:d}))}),s.attachCustomKeyEventHandler(d=>{if(d.type!=="keydown"||!(tt()?d.metaKey:d.ctrlKey)||d.altKey||d.shiftKey)return!0;const h=d.key.toLowerCase();if(h==="c"){const k=s.hasSelection()?s.getSelection():"";return k?(navigator.clipboard?.writeText(k).catch(()=>{}),!1):!0}if(h==="v"){const k=navigator.clipboard?.readText;return k&&k.call(navigator.clipboard).then(ce=>{if(!ce)return;const de=w.current;de?.readyState===WebSocket.OPEN&&de.send(JSON.stringify({type:"input",data:ce}))}).catch(()=>{}),!1}return!0})),n=new ResizeObserver(()=>{l&&clearTimeout(l),l=setTimeout(()=>{try{L.fit(),Q(s.cols,s.rows),s.refresh(0,Math.max(0,s.rows-1))}catch{}},Qe)}),n.observe(x.current);const V=new WebSocket(et(m,p.ticket));w.current=V,V.onopen=()=>{Q(s.cols,s.rows)},V.onmessage=d=>{let u;try{u=JSON.parse(typeof d.data=="string"?d.data:"")}catch{return}switch(u.type){case"scrollback":{if(typeof u.data!="string")return;s.reset();const h=pe(u.data),k=h.length;s.write(h,()=>le(k));break}case"data":{if(typeof u.data!="string")return;const h=pe(u.data),k=h.length;s.write(h,()=>le(k));break}}}})(),()=>{e=!0,l&&clearTimeout(l),n&&n.disconnect();const p=w.current;if(p){p.onopen=null,p.onmessage=null,p.onclose=null,p.onerror=null;try{p.close()}catch{}w.current=null}if(R.current){try{R.current.dispose()}catch{}R.current=null}const S=C.current;if(S){try{S.dispose()}catch{}C.current=null}N.current=null}},[m,f,a,y,T,ve]);const ae=i.useMemo(()=>a==="idle"?r("cliTerminal.replayIdle","Session idle"):a==="ended"?r("cliTerminal.replayEnded","Session ended"):null,[a,r]),Ce=i.useCallback(async()=>{if(g){ee(!0);try{await g("advance"),U(!0)}finally{ee(!1)}}},[g]),Te=i.useCallback(async()=>{g&&await g("not-yet"),U(!0)},[g]),I=!!o?.elevated,re=o?.elevatedFlags?.join(", "),ge={"--terminal-glyph-font-family":J(z().fontFamily)};return t.jsxs("div",{className:`cli-session-terminal${P?" cli-session-terminal--mobile":""}${P&&B?" cli-session-terminal--keyboard-open":""}`,"data-mode":a,"data-read-only":se,"data-mobile":P,"data-keyboard-open":P&&B,children:[t.jsxs("header",{className:"cli-session-terminal__header",children:[o&&t.jsxs("div",{className:"cli-session-terminal__posture-wrap",children:[t.jsxs("button",{type:"button",className:`cli-posture-chip${I?" cli-posture-chip--elevated":""}`,"data-elevated":I,"aria-expanded":q,onClick:()=>Z(e=>!e),children:[I?t.jsx(We,{size:13,"aria-hidden":"true"}):t.jsx(Me,{size:13,"aria-hidden":"true"}),t.jsx("span",{className:"cli-posture-chip__name",children:o.adapterName}),o.mode&&t.jsx("span",{className:"cli-posture-chip__mode",children:o.mode}),I&&re&&t.jsx("span",{className:"cli-posture-chip__flag",children:re})]}),q&&t.jsxs("div",{className:"cli-posture-tooltip",role:"tooltip",children:[t.jsx("p",{className:"cli-posture-tooltip__title",children:r("cliTerminal.postureResolved","Resolved posture")}),t.jsxs("ul",{className:"cli-posture-tooltip__list",children:[(o.resolved??[]).map((e,n)=>t.jsx("li",{children:e},n)),(o.resolved??[]).length===0&&t.jsx("li",{children:o.mode??r("cliTerminal.postureBaseline","Baseline")})]}),G&&t.jsxs("button",{type:"button",className:"cli-posture-tooltip__settings",onClick:()=>{Z(!1),G()},children:[t.jsx(Le,{size:12,"aria-hidden":"true"}),r("cliTerminal.adapterSettings","Adapter settings")]})]})]}),se&&t.jsxs("span",{className:"cli-session-terminal__readonly-badge",children:[t.jsx(De,{size:12,"aria-hidden":"true"}),r("cliTerminal.readOnly","Read-only")]}),ae&&t.jsx("span",{className:"cli-session-terminal__replay-badge","data-replay-mode":a,children:ae})]}),t.jsx("div",{className:"cli-session-terminal__viewport-shell",children:t.jsx("div",{className:"cli-session-terminal__viewport",ref:x,"data-testid":"cli-terminal-viewport",style:ge})}),$&&!ye&&t.jsxs("div",{className:"cli-session-terminal__advance-strip",role:"region",children:[t.jsx("span",{className:"cli-session-terminal__advance-copy",children:r("cliTerminal.advancePrompt","This session looks idle — advance to review?")}),t.jsxs("div",{className:"cli-session-terminal__advance-actions",children:[t.jsx("button",{type:"button",className:"cli-session-terminal__advance-btn",disabled:X,onClick:Ce,children:r("cliTerminal.advance","Advance")}),t.jsx("button",{type:"button",className:"cli-session-terminal__advance-btn cli-session-terminal__advance-btn--secondary",disabled:X,onClick:Te,children:r("cliTerminal.notYet","Not yet")})]})]}),P&&O&&t.jsxs("div",{className:`cli-session-terminal__mobile-bar${B?" cli-session-terminal__mobile-bar--keyboard-open":""}`,"data-testid":"cli-terminal-mobile-bar",style:B?{bottom:`${be}px`}:void 0,children:[t.jsxs("div",{className:"cli-session-terminal__key-row","data-testid":"cli-terminal-key-bar",children:[t.jsx("button",{type:"button",className:`cli-terminal-key cli-terminal-key--ctrl${j?" cli-terminal-key--active":""}`,"data-testid":"cli-key-ctrl","aria-label":r("cliTerminal.mobileKeyCtrl","Sticky Ctrl modifier"),"aria-pressed":j,onPointerDown:c,onMouseDown:c,onClick:()=>D(e=>!e),children:W.ctrl}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-esc","aria-label":r("cliTerminal.mobileKeyEsc","Send Escape"),onPointerDown:c,onMouseDown:c,onClick:()=>M(Ve),children:W.escape}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-tab","aria-label":r("cliTerminal.mobileKeyTab","Send Tab"),onPointerDown:c,onMouseDown:c,onClick:()=>M(Je),children:W.tab}),t.jsx("button",{type:"button",className:"cli-terminal-key cli-terminal-key--ctrlc","data-testid":"cli-key-ctrl-c","aria-label":r("cliTerminal.mobileKeyCtrlC","Send Ctrl-C"),onPointerDown:c,onMouseDown:c,onClick:()=>{D(!1),b(Ye)},children:W.ctrlC}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-up","aria-label":r("cliTerminal.mobileKeyArrowUp","Cursor up"),onPointerDown:c,onMouseDown:c,onClick:()=>M(Ge),children:"↑"}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-down","aria-label":r("cliTerminal.mobileKeyArrowDown","Cursor down"),onPointerDown:c,onMouseDown:c,onClick:()=>M(He),children:"↓"}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-left","aria-label":r("cliTerminal.mobileKeyArrowLeft","Cursor left"),onPointerDown:c,onMouseDown:c,onClick:()=>M(Ze),children:"←"}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-right","aria-label":r("cliTerminal.mobileKeyArrowRight","Cursor right"),onPointerDown:c,onMouseDown:c,onClick:()=>M(qe),children:"→"}),we.map(e=>t.jsx("button",{type:"button",className:"cli-terminal-key cli-terminal-key--custom","data-testid":`cli-terminal-custom-shortcut-${e.id}`,title:e.label,"aria-label":e.label,onPointerDown:c,onMouseDown:c,onClick:()=>{D(!1),b(Oe(e.value))},children:e.label},e.id))]}),t.jsxs("form",{className:"cli-session-terminal__input-row",onSubmit:_e,children:[t.jsx("input",{ref:he,type:"text",className:"cli-session-terminal__mobile-input","data-testid":"cli-terminal-mobile-input",value:v,placeholder:r("cliTerminal.mobileInputPlaceholder","Type to send to the session…"),autoCapitalize:"off",autoCorrect:"off",autoComplete:"off",spellCheck:!1,onChange:e=>ke(e.target.value)}),t.jsx("button",{type:"submit",className:"cli-session-terminal__mobile-send","data-testid":"cli-terminal-mobile-send","aria-label":r("cliTerminal.mobileSend","Send"),onPointerDown:c,onMouseDown:c,children:r("cliTerminal.mobileSend","Send")})]})]})]})}export{ut as SessionTerminal};
2
+ import{W as je,Y as z,_ as ue,$ as J,a0 as me,a1 as F,a2 as Me,a3 as Le,y as De,a4 as Oe,a5 as Y,a6 as Ae,a7 as ze,a as Fe,a8 as K,a9 as Be,aa as Ie}from"./index-oxnX59eO.js";import{r as i,j as t}from"./vendor-react-SZ_qB27O.js";import"./vendor-xterm-BNq00GSj.js";import{u as Ke}from"./vendor-i18n-Duky4gdQ.js";import{S as We}from"./shield-alert-CDy69fl7.js";import"./vendor-codemirror-CcrtqoCy.js";import"./vendor-reactflow-BlIeoTu4.js";const $e=32*1024,Ue=1e4,Qe=100,Ve="\x1B",Je=" ",Ye="",Ge="\x1B[A",He="\x1B[B",qe="\x1B[C",Ze="\x1B[D",W={ctrl:"Ctrl",escape:"Esc",tab:"Tab",ctrlC:"^C"};function fe(m){if(m.length!==1)return null;const o=m.toUpperCase().charCodeAt(0);return o>=64&&o<=95?String.fromCharCode(o&31):null}function Xe(){const[m,f]=i.useState(()=>Y());return i.useEffect(()=>{if(typeof window>"u"||typeof window.matchMedia!="function")return;const o=window.matchMedia(Ae),a=window.visualViewport,y=()=>f(Y());return y(),typeof a?.addEventListener=="function"&&a.addEventListener("resize",y),typeof o.addEventListener=="function"?(o.addEventListener("change",y),()=>{o.removeEventListener("change",y),typeof a?.removeEventListener=="function"&&a.removeEventListener("resize",y)}):(o.addListener(y),()=>{o.removeListener(y),typeof a?.removeEventListener=="function"&&a.removeEventListener("resize",y)})},[]),m}function et(m,f){if(typeof window>"u")return"";const a=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/api/cli-sessions/ws?sessionId=${encodeURIComponent(m)}&ticket=${encodeURIComponent(f)}`;return Ie(a)}function tt(){return/Mac|iPhone|iPad|iPod/i.test(navigator.platform)}function pe(m){if(typeof window<"u"&&typeof window.atob=="function"){const f=window.atob(m),o=new Uint8Array(f.length);for(let a=0;a<f.length;a++)o[a]=f.charCodeAt(a);return new TextDecoder("utf-8").decode(o)}return Buffer.from(m,"base64").toString("utf8")}function ut({sessionId:m,readOnly:f=!1,posture:o,mode:a="live",projectId:y,onConfirmAdvance:g,showConfirmAdvance:$=!1,onOpenAdapterSettings:G,active:H=!0}){const{t:r}=Ke("app"),x=i.useRef(null),C=i.useRef(null),N=i.useRef(null),R=i.useRef(null),w=i.useRef(null),[q,Z]=i.useState(!1),[ye,U]=i.useState(!1),[X,ee]=i.useState(!1),P=Xe(),{keyboardOpen:B,keyboardOverlap:be}=je({enabled:P}),he=i.useRef(null),[v,te]=i.useState(""),[j,D]=i.useState(!1),[we,Se]=i.useState(()=>z().customShortcuts),[ne,ie]=i.useState(null),se=f||ne===!0,O=!f&&ne===!1&&a==="live",b=i.useCallback(e=>{if(!e||!O)return;const n=w.current;n?.readyState===WebSocket.OPEN&&n.send(JSON.stringify({type:"input",data:e}))},[O]),M=i.useCallback(e=>{if(j){const n=fe(e);if(D(!1),n){b(n);return}}b(e)},[j,b]),c=i.useCallback(e=>{e.preventDefault()},[]),_e=i.useCallback(e=>{e?.preventDefault?.(),v&&b(v),b("\r"),te("")},[v,b]),ke=i.useCallback(e=>{if(j&&e.length>v.length){const n=e.slice(v.length,v.length+1),l=fe(n);if(D(!1),l){b(l);return}}te(e)},[j,v,b]);i.useEffect(()=>{$&&U(!1)},[$,m]);const T=i.useCallback((e,n)=>{const l=w.current;l?.readyState===WebSocket.OPEN&&l.send(JSON.stringify({type:"resize",cols:e,rows:n}))},[]),oe=i.useCallback(()=>{const e=C.current;if(!e)return;const n=z(),l=ue(n.fontFamily);e.options.fontFamily=l,x.current?.style.setProperty("--terminal-glyph-font-family",J(n.fontFamily)),e.options.fontSize=n.fontSize,e.options.cursorStyle=n.cursorStyle,e.options.cursorBlink=n.cursorBlink&&O;try{N.current?.fit?.(),T(e.cols,e.rows)}catch{}me(n.fontSize,l).then(E=>{if(!(!E||C.current!==e||e.options.fontSize!==n.fontSize||e.options.fontFamily!==l)){F(e,l),e.options.fontSize=n.fontSize;try{N.current?.fit?.(),T(e.cols,e.rows),F(e,l),e.refresh(0,Math.max(0,e.rows-1))}catch{}}},()=>{})},[O,T]);i.useEffect(()=>{if(typeof window>"u")return;const e=n=>{n.key===ze&&(oe(),Se(z().customShortcuts))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)},[oe]);const[ve,Ee]=i.useState(0);i.useEffect(()=>{if(!H)return;const e=C.current,n=N.current;if(e&&n?.fit)try{n.fit(),T(e.cols,e.rows),F(e,String(e.options.fontFamily??"")),e.refresh(0,Math.max(0,e.rows-1))}catch{}const l=w.current;l&&l.readyState!==WebSocket.OPEN&&l.readyState!==WebSocket.CONNECTING&&Ee(E=>E+1)},[H,T]),i.useEffect(()=>{if(!m||typeof window>"u")return;let e=!1,n=null,l=null,E=0;ie(null);const Q=T,le=p=>{if(E+=p,E<$e)return;const S=w.current;S?.readyState===WebSocket.OPEN&&S.send(JSON.stringify({type:"ack",bytes:E})),E=0};return(async()=>{let p;try{p=await Fe(`/cli-sessions/${encodeURIComponent(m)}/attach-ticket`,{method:"POST",body:JSON.stringify(y?{projectId:y}:{})})}catch{return}if(e)return;ie(p.readOnly);const S=!f&&!p.readOnly&&a==="live",[{Terminal:xe},{FitAddon:Ne},{Unicode11Addon:Re}]=await Promise.all([K(()=>import("./vendor-xterm-BNq00GSj.js").then(d=>d.x),__vite__mapDeps([0,1,2])),K(()=>import("./addon-fit-C1WQXRvu.js").then(d=>d.a),__vite__mapDeps([3,1])),K(()=>import("./addon-unicode11-D3Fsv-Po.js"),[])]);if(e||!x.current)return;const _=z(),A=ue(_.fontFamily);x.current.style.setProperty("--terminal-glyph-font-family",J(_.fontFamily));const s=new xe({convertEol:!1,cursorBlink:_.cursorBlink&&S,cursorStyle:_.cursorStyle,disableStdin:!S,scrollback:Ue,fontFamily:A,fontSize:_.fontSize}),L=new Ne;s.loadAddon(L);const Pe=new Re;if(s.loadAddon(Pe),s.unicode.activeVersion="11",Be(()=>{s.open(x.current)}),C.current=s,N.current=L,_.renderer==="auto"&&!Y())try{const{WebglAddon:d}=await K(async()=>{const{WebglAddon:u}=await import("./addon-webgl-uLc0RKcC.js").then(h=>h.a);return{WebglAddon:u}},__vite__mapDeps([4,1]));if(!e){const u=new d;u.onContextLoss(()=>{try{u.dispose()}catch{}R.current===u&&(R.current=null)}),s.loadAddon(u),R.current=u}}catch{}try{L.fit()}catch{}(async()=>{if(!(!await me(_.fontSize,A)||e||C.current!==s||N.current!==L||s.options.fontSize!==_.fontSize||s.options.fontFamily!==A))try{F(s,A),s.options.fontSize=_.fontSize,L.fit(),Q(s.cols,s.rows),F(s,A),s.refresh(0,Math.max(0,s.rows-1))}catch{}})(),S&&(s.onData(d=>{const u=w.current;u?.readyState===WebSocket.OPEN&&u.send(JSON.stringify({type:"input",data:d}))}),s.attachCustomKeyEventHandler(d=>{if(d.type!=="keydown"||!(tt()?d.metaKey:d.ctrlKey)||d.altKey||d.shiftKey)return!0;const h=d.key.toLowerCase();if(h==="c"){const k=s.hasSelection()?s.getSelection():"";return k?(navigator.clipboard?.writeText(k).catch(()=>{}),!1):!0}if(h==="v"){const k=navigator.clipboard?.readText;return k&&k.call(navigator.clipboard).then(ce=>{if(!ce)return;const de=w.current;de?.readyState===WebSocket.OPEN&&de.send(JSON.stringify({type:"input",data:ce}))}).catch(()=>{}),!1}return!0})),n=new ResizeObserver(()=>{l&&clearTimeout(l),l=setTimeout(()=>{try{L.fit(),Q(s.cols,s.rows),s.refresh(0,Math.max(0,s.rows-1))}catch{}},Qe)}),n.observe(x.current);const V=new WebSocket(et(m,p.ticket));w.current=V,V.onopen=()=>{Q(s.cols,s.rows)},V.onmessage=d=>{let u;try{u=JSON.parse(typeof d.data=="string"?d.data:"")}catch{return}switch(u.type){case"scrollback":{if(typeof u.data!="string")return;s.reset();const h=pe(u.data),k=h.length;s.write(h,()=>le(k));break}case"data":{if(typeof u.data!="string")return;const h=pe(u.data),k=h.length;s.write(h,()=>le(k));break}}}})(),()=>{e=!0,l&&clearTimeout(l),n&&n.disconnect();const p=w.current;if(p){p.onopen=null,p.onmessage=null,p.onclose=null,p.onerror=null;try{p.close()}catch{}w.current=null}if(R.current){try{R.current.dispose()}catch{}R.current=null}const S=C.current;if(S){try{S.dispose()}catch{}C.current=null}N.current=null}},[m,f,a,y,T,ve]);const ae=i.useMemo(()=>a==="idle"?r("cliTerminal.replayIdle","Session idle"):a==="ended"?r("cliTerminal.replayEnded","Session ended"):null,[a,r]),Ce=i.useCallback(async()=>{if(g){ee(!0);try{await g("advance"),U(!0)}finally{ee(!1)}}},[g]),Te=i.useCallback(async()=>{g&&await g("not-yet"),U(!0)},[g]),I=!!o?.elevated,re=o?.elevatedFlags?.join(", "),ge={"--terminal-glyph-font-family":J(z().fontFamily)};return t.jsxs("div",{className:`cli-session-terminal${P?" cli-session-terminal--mobile":""}${P&&B?" cli-session-terminal--keyboard-open":""}`,"data-mode":a,"data-read-only":se,"data-mobile":P,"data-keyboard-open":P&&B,children:[t.jsxs("header",{className:"cli-session-terminal__header",children:[o&&t.jsxs("div",{className:"cli-session-terminal__posture-wrap",children:[t.jsxs("button",{type:"button",className:`cli-posture-chip${I?" cli-posture-chip--elevated":""}`,"data-elevated":I,"aria-expanded":q,onClick:()=>Z(e=>!e),children:[I?t.jsx(We,{size:13,"aria-hidden":"true"}):t.jsx(Me,{size:13,"aria-hidden":"true"}),t.jsx("span",{className:"cli-posture-chip__name",children:o.adapterName}),o.mode&&t.jsx("span",{className:"cli-posture-chip__mode",children:o.mode}),I&&re&&t.jsx("span",{className:"cli-posture-chip__flag",children:re})]}),q&&t.jsxs("div",{className:"cli-posture-tooltip",role:"tooltip",children:[t.jsx("p",{className:"cli-posture-tooltip__title",children:r("cliTerminal.postureResolved","Resolved posture")}),t.jsxs("ul",{className:"cli-posture-tooltip__list",children:[(o.resolved??[]).map((e,n)=>t.jsx("li",{children:e},n)),(o.resolved??[]).length===0&&t.jsx("li",{children:o.mode??r("cliTerminal.postureBaseline","Baseline")})]}),G&&t.jsxs("button",{type:"button",className:"cli-posture-tooltip__settings",onClick:()=>{Z(!1),G()},children:[t.jsx(Le,{size:12,"aria-hidden":"true"}),r("cliTerminal.adapterSettings","Adapter settings")]})]})]}),se&&t.jsxs("span",{className:"cli-session-terminal__readonly-badge",children:[t.jsx(De,{size:12,"aria-hidden":"true"}),r("cliTerminal.readOnly","Read-only")]}),ae&&t.jsx("span",{className:"cli-session-terminal__replay-badge","data-replay-mode":a,children:ae})]}),t.jsx("div",{className:"cli-session-terminal__viewport-shell",children:t.jsx("div",{className:"cli-session-terminal__viewport",ref:x,"data-testid":"cli-terminal-viewport",style:ge})}),$&&!ye&&t.jsxs("div",{className:"cli-session-terminal__advance-strip",role:"region",children:[t.jsx("span",{className:"cli-session-terminal__advance-copy",children:r("cliTerminal.advancePrompt","This session looks idle — advance to review?")}),t.jsxs("div",{className:"cli-session-terminal__advance-actions",children:[t.jsx("button",{type:"button",className:"cli-session-terminal__advance-btn",disabled:X,onClick:Ce,children:r("cliTerminal.advance","Advance")}),t.jsx("button",{type:"button",className:"cli-session-terminal__advance-btn cli-session-terminal__advance-btn--secondary",disabled:X,onClick:Te,children:r("cliTerminal.notYet","Not yet")})]})]}),P&&O&&t.jsxs("div",{className:`cli-session-terminal__mobile-bar${B?" cli-session-terminal__mobile-bar--keyboard-open":""}`,"data-testid":"cli-terminal-mobile-bar",style:B?{bottom:`${be}px`}:void 0,children:[t.jsxs("div",{className:"cli-session-terminal__key-row","data-testid":"cli-terminal-key-bar",children:[t.jsx("button",{type:"button",className:`cli-terminal-key cli-terminal-key--ctrl${j?" cli-terminal-key--active":""}`,"data-testid":"cli-key-ctrl","aria-label":r("cliTerminal.mobileKeyCtrl","Sticky Ctrl modifier"),"aria-pressed":j,onPointerDown:c,onMouseDown:c,onClick:()=>D(e=>!e),children:W.ctrl}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-esc","aria-label":r("cliTerminal.mobileKeyEsc","Send Escape"),onPointerDown:c,onMouseDown:c,onClick:()=>M(Ve),children:W.escape}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-tab","aria-label":r("cliTerminal.mobileKeyTab","Send Tab"),onPointerDown:c,onMouseDown:c,onClick:()=>M(Je),children:W.tab}),t.jsx("button",{type:"button",className:"cli-terminal-key cli-terminal-key--ctrlc","data-testid":"cli-key-ctrl-c","aria-label":r("cliTerminal.mobileKeyCtrlC","Send Ctrl-C"),onPointerDown:c,onMouseDown:c,onClick:()=>{D(!1),b(Ye)},children:W.ctrlC}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-up","aria-label":r("cliTerminal.mobileKeyArrowUp","Cursor up"),onPointerDown:c,onMouseDown:c,onClick:()=>M(Ge),children:"↑"}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-down","aria-label":r("cliTerminal.mobileKeyArrowDown","Cursor down"),onPointerDown:c,onMouseDown:c,onClick:()=>M(He),children:"↓"}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-left","aria-label":r("cliTerminal.mobileKeyArrowLeft","Cursor left"),onPointerDown:c,onMouseDown:c,onClick:()=>M(Ze),children:"←"}),t.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-right","aria-label":r("cliTerminal.mobileKeyArrowRight","Cursor right"),onPointerDown:c,onMouseDown:c,onClick:()=>M(qe),children:"→"}),we.map(e=>t.jsx("button",{type:"button",className:"cli-terminal-key cli-terminal-key--custom","data-testid":`cli-terminal-custom-shortcut-${e.id}`,title:e.label,"aria-label":e.label,onPointerDown:c,onMouseDown:c,onClick:()=>{D(!1),b(Oe(e.value))},children:e.label},e.id))]}),t.jsxs("form",{className:"cli-session-terminal__input-row",onSubmit:_e,children:[t.jsx("input",{ref:he,type:"text",className:"cli-session-terminal__mobile-input","data-testid":"cli-terminal-mobile-input",value:v,placeholder:r("cliTerminal.mobileInputPlaceholder","Type to send to the session…"),autoCapitalize:"off",autoCorrect:"off",autoComplete:"off",spellCheck:!1,onChange:e=>ke(e.target.value)}),t.jsx("button",{type:"submit",className:"cli-session-terminal__mobile-send","data-testid":"cli-terminal-mobile-send","aria-label":r("cliTerminal.mobileSend","Send"),onPointerDown:c,onMouseDown:c,children:r("cliTerminal.mobileSend","Send")})]})]})]})}export{ut as SessionTerminal};
@@ -1 +1 @@
1
- import{r}from"./vendor-react-SZ_qB27O.js";import{a as n,w as s}from"./index-I32FijPT.js";function x(e){return n(s("/memory/files",e))}function C(e,t){const c=`path=${encodeURIComponent(e)}`;return n(s(`/memory/file?${c}`,t))}function F(e,t,c){return n(s("/memory/file",c),{method:"PUT",body:JSON.stringify({path:e,content:t})})}function J(e,t){return n(s("/memory/compact",t),{method:"POST",body:JSON.stringify(e?{path:e}:{})})}function N(e){return n(s("/memory/dream",e),{method:"POST"})}function W(e){return n(s("/memory/insights",e))}function j(e,t){return n(s("/memory/insights",t),{method:"PUT",body:JSON.stringify({content:e})})}function q(e){return n(s("/memory/extract",e),{method:"POST"})}function D(e){return n(s("/memory/audit",e))}function B(e){return n(s("/memory/backend",e))}function L(e){return n(s("/memory/install-qmd",e),{method:"POST"})}function $(e,t){return n(s("/memory/test",t),{method:"POST",body:JSON.stringify({query:e})})}function Q(e={}){const{projectId:t,pollInterval:c=6e4,autoRefresh:p=!1,enabled:a=!0}=e,[S,y]=r.useState(null),[g,m]=r.useState(a),[M,d]=r.useState(null),[k,v]=r.useState(null),o=r.useRef(null),u=r.useRef(null),l=r.useRef(!0),i=r.useCallback(async()=>{if(!a){m(!1),d(null),y(null);return}o.current&&o.current.abort(),o.current=new AbortController,m(!0),d(null),y(null);try{const f=await B(t);if(!l.current)return;y(f),d(null),v(new Date),m(!1)}catch(f){if(f instanceof Error&&f.name==="AbortError"||!l.current)return;const w=f instanceof Error?f.message:"Failed to fetch memory backend status";d(w),m(!1)}},[a,t]);r.useEffect(()=>(l.current=!0,a?(i(),()=>{l.current=!1}):(o.current&&o.current.abort(),y(null),d(null),m(!1),()=>{l.current=!1})),[a,i]),r.useEffect(()=>{if(!(!a||!p))return u.current=setInterval(()=>{i()},c),()=>{u.current&&(clearInterval(u.current),u.current=null)}},[a,p,c,i]),r.useEffect(()=>()=>{l.current=!1,o.current&&o.current.abort(),u.current&&(clearInterval(u.current),u.current=null)},[]);const I=r.useCallback(()=>i(),[i]),b=g?null:S,R=b?.currentBackend??null,h=b?.capabilities??null,E=b?.availableBackends??[],O=h?.readable??!1,P=h?.writable??!1,T=h?.supportsAtomicWrite??!1;return{status:b,currentBackend:R,capabilities:h,availableBackends:E,isReadable:O,isWritable:P,supportsAtomicWrite:T,loading:g,error:M,lastUpdated:k,refresh:I}}export{x as a,D as b,W as c,j as d,q as e,C as f,N as g,J as h,L as i,F as s,$ as t,Q as u};
1
+ import{r}from"./vendor-react-SZ_qB27O.js";import{a as n,w as s}from"./index-oxnX59eO.js";function x(e){return n(s("/memory/files",e))}function C(e,t){const c=`path=${encodeURIComponent(e)}`;return n(s(`/memory/file?${c}`,t))}function F(e,t,c){return n(s("/memory/file",c),{method:"PUT",body:JSON.stringify({path:e,content:t})})}function J(e,t){return n(s("/memory/compact",t),{method:"POST",body:JSON.stringify(e?{path:e}:{})})}function N(e){return n(s("/memory/dream",e),{method:"POST"})}function W(e){return n(s("/memory/insights",e))}function j(e,t){return n(s("/memory/insights",t),{method:"PUT",body:JSON.stringify({content:e})})}function q(e){return n(s("/memory/extract",e),{method:"POST"})}function D(e){return n(s("/memory/audit",e))}function B(e){return n(s("/memory/backend",e))}function L(e){return n(s("/memory/install-qmd",e),{method:"POST"})}function $(e,t){return n(s("/memory/test",t),{method:"POST",body:JSON.stringify({query:e})})}function Q(e={}){const{projectId:t,pollInterval:c=6e4,autoRefresh:p=!1,enabled:a=!0}=e,[S,y]=r.useState(null),[g,m]=r.useState(a),[M,d]=r.useState(null),[k,v]=r.useState(null),o=r.useRef(null),u=r.useRef(null),l=r.useRef(!0),i=r.useCallback(async()=>{if(!a){m(!1),d(null),y(null);return}o.current&&o.current.abort(),o.current=new AbortController,m(!0),d(null),y(null);try{const f=await B(t);if(!l.current)return;y(f),d(null),v(new Date),m(!1)}catch(f){if(f instanceof Error&&f.name==="AbortError"||!l.current)return;const w=f instanceof Error?f.message:"Failed to fetch memory backend status";d(w),m(!1)}},[a,t]);r.useEffect(()=>(l.current=!0,a?(i(),()=>{l.current=!1}):(o.current&&o.current.abort(),y(null),d(null),m(!1),()=>{l.current=!1})),[a,i]),r.useEffect(()=>{if(!(!a||!p))return u.current=setInterval(()=>{i()},c),()=>{u.current&&(clearInterval(u.current),u.current=null)}},[a,p,c,i]),r.useEffect(()=>()=>{l.current=!1,o.current&&o.current.abort(),u.current&&(clearInterval(u.current),u.current=null)},[]);const I=r.useCallback(()=>i(),[i]),b=g?null:S,R=b?.currentBackend??null,h=b?.capabilities??null,E=b?.availableBackends??[],O=h?.readable??!1,P=h?.writable??!1,T=h?.supportsAtomicWrite??!1;return{status:b,currentBackend:R,capabilities:h,availableBackends:E,isReadable:O,isWritable:P,supportsAtomicWrite:T,loading:g,error:M,lastUpdated:k,refresh:I}}export{x as a,D as b,W as c,j as d,q as e,C as f,N as g,J as h,L as i,F as s,$ as t,Q as u};