@promptowl/contextnest-community 1.23.0 → 1.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +2195 -0
- package/CONFIGURATION.md +8 -2
- package/README.md +62 -10
- package/STEWARDSHIP.md +253 -0
- package/dist/{chunk-2YPY2HGZ.js → chunk-2KHM5C7V.js} +40 -5
- package/dist/{chunk-XYD6V2LH.js → chunk-32SZCH36.js} +28 -33
- package/dist/{chunk-QLXC6542.js → chunk-7FROMOZM.js} +69 -27
- package/dist/{chunk-MLQU4I5J.js → chunk-DTLMBF4W.js} +10 -8
- package/dist/{chunk-QWNXWRWO.js → chunk-JDAOA5KP.js} +67 -1
- package/dist/{chunk-UOMW7TT6.js → chunk-KPGNZLZL.js} +2 -2
- package/dist/{chunk-YVMSM7LS.js → chunk-LHWOJPFE.js} +7 -0
- package/dist/{chunk-5CVZMHHB.js → chunk-TI7HMP64.js} +99 -12
- package/dist/{client-LWDMNKX3.js → client-D44ZHDTJ.js} +1 -1
- package/dist/{engine-QFF2IA3G.js → engine-TER6FDBP.js} +3 -3
- package/dist/{external-edit-service-F7D3VSA2.js → external-edit-service-CAGENHDJ.js} +4 -4
- package/dist/{grants-service-TBGTCO5K.js → grants-service-2OTFS7EH.js} +3 -3
- package/dist/index.js +1120 -331
- package/dist/{migrations.postgres-APCVSYUE.js → migrations.postgres-23VJJJJX.js} +56 -5
- package/dist/{review-service-A7PNLWG5.js → review-service-4G2XUFS6.js} +7 -7
- package/dist/{stewardship-service-32UHIRQ5.js → stewardship-service-S22V2JKG.js} +6 -4
- package/dist/{version-service-RJ6CWZ3O.js → version-service-X4FAG2OZ.js} +4 -4
- package/dist/web3/assets/ActivityTracePage-D2iIbEph.js +1 -0
- package/dist/web3/assets/AgentDocsPage-Dkhgb1hk.js +1 -0
- package/dist/web3/assets/CollaboratorManager-Bo81D--Q.js +1 -0
- package/dist/web3/assets/CollaboratorsTab-DRCitQuX.js +1 -0
- package/dist/web3/assets/DocumentEditor-DV2WHYbj.js +36 -0
- package/dist/web3/assets/DocumentsTab-BUxBCN8o.js +6 -0
- package/dist/web3/assets/ExternalEditsTab-kIBimZyE.js +1 -0
- package/dist/web3/assets/MarkdownEditor-CsVusP2d.css +1 -0
- package/dist/web3/assets/MarkdownEditor-Dfk5uIE5.js +648 -0
- package/dist/web3/assets/NestPageHeader-yOK-OIYZ.js +1 -0
- package/dist/web3/assets/NestView-DwIagxwJ.js +68 -0
- package/dist/web3/assets/OverviewTab-DFOFMVyE.js +1 -0
- package/dist/web3/assets/PersonCombobox-D350WlrJ.js +1 -0
- package/dist/web3/assets/ReasonDialog-CN3ECAnQ.js +1 -0
- package/dist/web3/assets/ReviewActions-BXDTDPp1.js +6 -0
- package/dist/web3/assets/ReviewTab-CZewAYiz.js +1 -0
- package/dist/web3/assets/StewardsTab-AagNWcWS.js +1 -0
- package/dist/web3/assets/SubmitForReviewModal-BOZJxwRN.js +1 -0
- package/dist/web3/assets/alert-dialog-4SiLKlz8.js +7 -0
- package/dist/web3/assets/arrow-left-BAgIocLn.js +6 -0
- package/dist/web3/assets/backlinks-Cb8Uf8mw.js +24 -0
- package/dist/web3/assets/card-UDyMRcps.js +1 -0
- package/dist/web3/assets/chevron-left-XR4ReJ9Z.js +6 -0
- package/dist/web3/assets/circle-check-CSkZUEFK.js +6 -0
- package/dist/web3/assets/circle-x-in2o3aHU.js +6 -0
- package/dist/web3/assets/client-attribution-BraarYaP.js +1 -0
- package/dist/web3/assets/code-xml-pPQgdctI.js +6 -0
- package/dist/web3/assets/corner-down-right-CuxZWscX.js +6 -0
- package/dist/web3/assets/count-skeleton-DBWCDhRy.js +1 -0
- package/dist/web3/assets/dates-BCxbm4_q.js +1 -0
- package/dist/web3/assets/earth-CXOcThqn.js +6 -0
- package/dist/web3/assets/file-exclamation-point-CSphs1VD.js +6 -0
- package/dist/web3/assets/folder-input-BAwK9tFL.js +11 -0
- package/dist/web3/assets/folder-target-CUSWqImF.js +1 -0
- package/dist/web3/assets/index-A0_ymcqL.js +29 -0
- package/dist/web3/assets/index-B5hLclEq.js +389 -0
- package/dist/web3/assets/index-DrUAtoQM.css +1 -0
- package/dist/web3/assets/page-BHD4beun.js +1 -0
- package/dist/web3/assets/page-BSYUXYmO.js +11 -0
- package/dist/web3/assets/page-BYc2DIux.js +45 -0
- package/dist/web3/assets/page-BfibLg8e.js +1 -0
- package/dist/web3/assets/page-CGe8MtUu.js +9 -0
- package/dist/web3/assets/page-CIgPJmG6.js +2 -0
- package/dist/web3/assets/page-CUjuSs5Q.js +24 -0
- package/dist/web3/assets/page-Ck31nx9b.js +1 -0
- package/dist/web3/assets/page-Cpdj_11Y.js +1 -0
- package/dist/web3/assets/page-D0sN3GO6.js +1 -0
- package/dist/web3/assets/page-DEpH91X2.js +1 -0
- package/dist/web3/assets/page-l8-B7CGt.js +1 -0
- package/dist/web3/assets/page-mnSHmk6A.js +6 -0
- package/dist/web3/assets/page-title-BkqlUA0j.js +1 -0
- package/dist/web3/assets/page-xzYqkBUP.js +16 -0
- package/dist/web3/assets/play-B8xE9j5f.js +6 -0
- package/dist/web3/assets/refresh-cw-CsCtmWwX.js +6 -0
- package/dist/web3/assets/scroll-area-CbcH6yrZ.js +1 -0
- package/dist/web3/assets/scroll-area-dRWncRqa.css +1 -0
- package/dist/web3/assets/select-DrL0mpRN.js +6 -0
- package/dist/web3/assets/send-CvAgOUPG.js +6 -0
- package/dist/web3/assets/settings-EY4A_DYv.js +6 -0
- package/dist/web3/assets/share-2-vGmZUl90.js +6 -0
- package/dist/web3/assets/tag-Br_y1f00.js +11 -0
- package/dist/web3/assets/trash-2-B4hRXo-p.js +6 -0
- package/dist/web3/assets/triangle-alert-CsYGyfGZ.js +6 -0
- package/dist/web3/assets/user-plus-4CTYEkd3.js +6 -0
- package/dist/web3/assets/x-qxt1WrUi.js +6 -0
- package/dist/web3/assets/zap-BcsKR0ef.js +16 -0
- package/dist/web3/index.html +2 -2
- package/package.json +5 -3
- package/dist/web3/assets/index-BJ-LRNis.js +0 -1382
- package/dist/web3/assets/index-DPMEt-A_.css +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as n,u as G,i as z,f as l,aI as U,_ as V,j as e,B as C,L as M,ag as W,aP as J,aU as X,aV as Y,aT as Z}from"./index-B5hLclEq.js";import{N as I}from"./NestPageHeader-yOK-OIYZ.js";import{T as ee}from"./trash-2-B4hRXo-p.js";import{T as te}from"./triangle-alert-CsYGyfGZ.js";import"./arrow-left-BAgIocLn.js";function se({nestId:a,nestName:B,isArchived:T,onBack:H}){var K;const[h,Q]=n.useState([]),p=G(),[S,D]=n.useState(!0),[d,E]=n.useState(!1),[g,P]=n.useState(!1),[i,_]=n.useState(null),[o,j]=n.useState(""),[c,w]=n.useState(""),[A,b]=n.useState(""),x=n.useCallback(async()=>{D(!0);try{const{definitions:t}=await p.fetchQuery(z.definitions(a));Q(t)}catch(t){l.error((t==null?void 0:t.message)||"Failed to load definitions")}finally{D(!1)}},[a]);n.useEffect(()=>{let t=!1;return p.fetchQuery(z.nest(a)).then(s=>{if(t)return;const q=U({roles:(s==null?void 0:s.roles)??[],permission:(s==null?void 0:s.permission)??null,myStewards:(s==null?void 0:s.myStewards)??[],isOwner:(s==null?void 0:s.permission)==="owner",isAdmin:(s==null?void 0:s.permission)==="admin",isArchived:T||V(s==null?void 0:s.nest)});E(q.canManage||q.collabCanWrite)}).catch(()=>{t||E(!1)}),()=>{t=!0}},[a,p,T]),n.useEffect(()=>{x()},[x]);const N=()=>{_(null),j(""),w(""),b("")},y=t=>{var s;_(t.id),j(t.term),w(t.definition),b(((s=t.linked_tag)==null?void 0:s.replace(/^#/,""))??"")},L=o.trim().toLowerCase(),r=L?h.find(t=>t.term.toLowerCase()===L&&t.id!==i)??null:null,F=async()=>{if(!o.trim()||!c.trim())return l.error("Term and definition are both required."),!1;P(!0);try{const t=A.trim();return await X(a,{term:o.trim(),definition:c.trim(),...t||i?{linked_tag:t||null}:{},...i?{editing_id:i}:{}}),l.success(i?"Definition updated":r?`Replaced the definition of "${r.term}"`:"Term defined"),N(),await x(),!0}catch(t){return l.error((t==null?void 0:t.message)||"Save failed"),!1}finally{P(!1)}},O=async t=>{try{await Y(a,t.id),l.success(`Removed "${t.term}"`),await x()}catch(s){l.error((s==null?void 0:s.message)||"Delete failed")}},[u,m]=n.useState(!1),f=i??(u?"new":null),$=()=>{N(),m(!1)},v=t=>{t.key==="Escape"?(t.preventDefault(),$()):t.key==="Enter"&&(t.ctrlKey||t.metaKey||!(t.target instanceof HTMLTextAreaElement))&&(t.preventDefault(),F().then(s=>s&&m(!1)))},k="w-full rounded-md border border-input bg-background px-2 py-1 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",R=e.jsxs(e.Fragment,{children:[e.jsx("td",{className:"align-top",children:e.jsx("input",{autoFocus:!0,value:o,onChange:t=>j(t.target.value),onKeyDown:v,placeholder:"Term","aria-label":"Term",className:k,"data-testid":"definitions-term"})}),e.jsx("td",{className:"align-top",children:e.jsx("textarea",{value:c,onChange:t=>w(t.target.value),onKeyDown:v,placeholder:"What this term means here — formula or source if quantitative. Ctrl+Enter saves.","aria-label":"Definition",rows:Math.min(8,Math.max(2,c.split(`
|
|
2
|
+
`).length+1)),className:`${k} min-h-[2.25rem] resize-y`,"data-testid":"definitions-definition"})}),e.jsx("td",{className:"align-top",children:e.jsx("input",{value:A,onChange:t=>b(t.target.value),onKeyDown:v,placeholder:"tag","aria-label":"Linked tag",className:`${k} w-28`,"data-testid":"definitions-tag"})}),e.jsx("td",{className:"align-top text-xs text-muted-foreground whitespace-nowrap pt-2",children:i?(K=h.find(t=>t.id===i))==null?void 0:K.defined_by:"you"}),e.jsx("td",{className:"align-top whitespace-nowrap text-right",children:e.jsxs("div",{className:"flex items-center justify-end gap-1",children:[e.jsx(C,{variant:"ghost",size:"sm",className:"h-7",onClick:$,disabled:g,children:"Cancel"}),e.jsx(C,{size:"sm",className:"h-7",onClick:()=>void F().then(t=>t&&m(!1)),disabled:g||!o.trim()||!c.trim(),"data-testid":"definitions-save",children:g?e.jsx(M,{className:"h-3.5 w-3.5 animate-spin"}):r&&!i?"Replace":"Save"})]})})]});return e.jsxs("div",{className:"space-y-4",children:[e.jsx(I,{nestName:B,onBack:H,title:e.jsx("h1",{className:"min-w-0 truncate text-xl font-semibold",children:"Definitions"})}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"The nest's shared vocabulary — what each term means here, written down once so everyone (and every agent reading this nest) uses it the same way. Click a row to edit it."}),e.jsx("div",{className:"border border-border rounded-lg overflow-x-auto","data-testid":"definitions-table",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{className:"bg-muted/50 text-muted-foreground text-xs",children:e.jsxs("tr",{className:"[&>th]:px-3 [&>th]:py-2 [&>th]:text-left [&>th]:font-medium",children:[e.jsx("th",{className:"w-[18%]",children:"Term"}),e.jsx("th",{children:"Definition"}),e.jsx("th",{className:"w-28",children:"Tag"}),e.jsx("th",{className:"w-36",children:"Defined by"}),e.jsx("th",{className:"w-28"})]})}),e.jsxs("tbody",{children:[S&&e.jsx("tr",{children:e.jsxs("td",{colSpan:5,className:"px-3 py-8 text-center text-muted-foreground",children:[e.jsx(M,{className:"h-4 w-4 animate-spin inline mr-2"}),"Loading…"]})}),!S&&h.length===0&&!u&&e.jsx("tr",{children:e.jsx("td",{colSpan:5,className:"px-3 py-8 text-center text-muted-foreground",children:d?"No terms defined yet. Add the first one below.":"No terms defined yet."})}),h.map(t=>f===t.id?e.jsx("tr",{className:"border-t border-border bg-muted/20 [&>td]:px-2 [&>td]:py-1.5","data-testid":"definitions-row-editing",children:R},t.id):e.jsxs("tr",{onClick:d&&f===null?()=>y(t):void 0,className:`group border-t border-border align-top [&>td]:px-3 [&>td]:py-2${d&&f===null?" cursor-text hover:bg-muted/30":""}`,"data-testid":"definitions-row",children:[e.jsx("td",{className:"font-medium whitespace-nowrap",children:t.term}),e.jsx("td",{className:"max-w-[520px]",children:e.jsx("span",{className:"whitespace-pre-wrap",children:t.definition})}),e.jsx("td",{className:"whitespace-nowrap",children:t.linked_tag?e.jsx("span",{className:"rounded bg-amber-50 text-amber-700 px-1.5 py-0.5 text-xs",children:t.linked_tag}):e.jsx("span",{className:"text-muted-foreground",children:"—"})}),e.jsx("td",{className:"text-xs text-muted-foreground whitespace-nowrap",children:t.defined_by}),e.jsx("td",{className:"whitespace-nowrap text-right",children:d&&e.jsxs("span",{className:"opacity-0 group-hover:opacity-100 focus-within:opacity-100",children:[e.jsx("button",{type:"button","aria-label":`Edit ${t.term}`,onClick:s=>{s.stopPropagation(),y(t)},className:"p-1 rounded hover:bg-accent mr-1",children:e.jsx(W,{className:"h-3.5 w-3.5"})}),e.jsx("button",{type:"button","aria-label":`Delete ${t.term}`,onClick:s=>{s.stopPropagation(),O(t)},className:"p-1 rounded hover:bg-accent text-red-600",children:e.jsx(ee,{className:"h-3.5 w-3.5"})})]})})]},t.id)),f!==null&&r&&e.jsx("tr",{className:"bg-amber-50/60",children:e.jsx("td",{colSpan:5,className:"px-3 py-2 text-xs text-amber-800",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(te,{className:"h-3.5 w-3.5 shrink-0 mt-0.5"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("b",{children:r.term})," ",i?e.jsxs(e.Fragment,{children:["is already defined by another row (",r.defined_by,") — this rename will be rejected."]}):e.jsxs(e.Fragment,{children:["is already defined by ",r.defined_by,". Saving replaces that definition."]})]}),!i&&e.jsxs(C,{variant:"outline",size:"sm",className:"h-7 shrink-0",onClick:()=>{m(!1),y(r)},children:[e.jsx(W,{className:"h-3.5 w-3.5 mr-1"})," Edit it instead"]})]})})}),d&&u&&i===null&&e.jsx("tr",{className:"border-t border-border bg-muted/20 [&>td]:px-2 [&>td]:py-1.5","data-testid":"definitions-row-new",children:R}),d&&!u&&e.jsx("tr",{className:"border-t border-border",children:e.jsx("td",{colSpan:5,className:"p-0",children:e.jsxs("button",{type:"button",onClick:()=>{N(),m(!0)},className:"flex w-full items-center gap-1.5 px-3 py-2 text-left text-sm text-muted-foreground hover:bg-muted/40 hover:text-foreground","data-testid":"definitions-add",children:[e.jsx(J,{className:"h-3.5 w-3.5"})," New term"]})})})]})]})}),e.jsxs("details",{className:"rounded-md border bg-muted/30 px-3 py-2 text-xs",children:[e.jsx("summary",{className:"cursor-pointer font-medium text-muted-foreground",children:"For developers — fetch a definition over HTTP"}),e.jsxs("div",{className:"mt-2 space-y-1.5 text-muted-foreground",children:[e.jsx("p",{children:"Agents and analysis jobs read these live, so a definition edited here changes what they answer with on the next call."}),e.jsxs("pre",{className:"overflow-x-auto rounded border bg-background p-2 font-mono text-[10.5px] leading-relaxed",children:["GET /nests/",a,"/definitions?term=<term>"]}),e.jsx("p",{children:"Omit the query to get the whole glossary."})]})]})]})}function le(){const a=Z();return e.jsx(se,{nestId:a.nestId,nestName:a.nestName,isArchived:a.isArchived,onBack:a.leaveNest})}export{le as default};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import{c as ue,r as A,aW as Qe,j as u,U as Oe,B as Pe,L as Ue,aX as Ve,C as Je,ao as Ke,at as qe,aT as et}from"./index-B5hLclEq.js";import{N as tt}from"./NestPageHeader-yOK-OIYZ.js";import{L as nt,T as rt}from"./tag-Br_y1f00.js";import{T as st}from"./triangle-alert-CsYGyfGZ.js";import"./arrow-left-BAgIocLn.js";/**
|
|
2
|
+
* @license lucide-react v0.577.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const it=[["path",{d:"M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z",key:"hod4my"}],["path",{d:"M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z",key:"w4yl2u"}],["path",{d:"M3 5a2 2 0 0 0 2 2h3",key:"f2jnh7"}],["path",{d:"M3 3v13a2 2 0 0 0 2 2h3",key:"k8epm1"}]],ot=ue("folder-tree",it);/**
|
|
7
|
+
* @license lucide-react v0.577.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const at=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"m21 3-7 7",key:"1l2asr"}],["path",{d:"m3 21 7-7",key:"tjx5ai"}],["path",{d:"M9 21H3v-6",key:"wtvkvv"}]],lt=ue("maximize-2",at);/**
|
|
12
|
+
* @license lucide-react v0.577.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const ct=[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65",key:"13gj7c"}],["line",{x1:"11",x2:"11",y1:"8",y2:"14",key:"1vmskp"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11",key:"durymu"}]],ut=ue("zoom-in",ct);/**
|
|
17
|
+
* @license lucide-react v0.577.0 - ISC
|
|
18
|
+
*
|
|
19
|
+
* This source code is licensed under the ISC license.
|
|
20
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
21
|
+
*/const ft=[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65",key:"13gj7c"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11",key:"durymu"}]],ht=ue("zoom-out",ft);function dt(e,t){var n,s=1;e==null&&(e=0),t==null&&(t=0);function i(){var r,h=n.length,x,v=0,l=0;for(r=0;r<h;++r)x=n[r],v+=x.x,l+=x.y;for(v=(v/h-e)*s,l=(l/h-t)*s,r=0;r<h;++r)x=n[r],x.x-=v,x.y-=l}return i.initialize=function(r){n=r},i.x=function(r){return arguments.length?(e=+r,i):e},i.y=function(r){return arguments.length?(t=+r,i):t},i.strength=function(r){return arguments.length?(s=+r,i):s},i}function xt(e){const t=+this._x.call(null,e),n=+this._y.call(null,e);return Te(this.cover(t,n),t,n,e)}function Te(e,t,n,s){if(isNaN(t)||isNaN(n))return e;var i,r=e._root,h={data:s},x=e._x0,v=e._y0,l=e._x1,y=e._y1,_,p,c,k,f,o,d,m;if(!r)return e._root=h,e;for(;r.length;)if((f=t>=(_=(x+l)/2))?x=_:l=_,(o=n>=(p=(v+y)/2))?v=p:y=p,i=r,!(r=r[d=o<<1|f]))return i[d]=h,e;if(c=+e._x.call(null,r.data),k=+e._y.call(null,r.data),t===c&&n===k)return h.next=r,i?i[d]=h:e._root=h,e;do i=i?i[d]=new Array(4):e._root=new Array(4),(f=t>=(_=(x+l)/2))?x=_:l=_,(o=n>=(p=(v+y)/2))?v=p:y=p;while((d=o<<1|f)===(m=(k>=p)<<1|c>=_));return i[m]=r,i[d]=h,e}function gt(e){var t,n,s=e.length,i,r,h=new Array(s),x=new Array(s),v=1/0,l=1/0,y=-1/0,_=-1/0;for(n=0;n<s;++n)isNaN(i=+this._x.call(null,t=e[n]))||isNaN(r=+this._y.call(null,t))||(h[n]=i,x[n]=r,i<v&&(v=i),i>y&&(y=i),r<l&&(l=r),r>_&&(_=r));if(v>y||l>_)return this;for(this.cover(v,l).cover(y,_),n=0;n<s;++n)Te(this,h[n],x[n],e[n]);return this}function mt(e,t){if(isNaN(e=+e)||isNaN(t=+t))return this;var n=this._x0,s=this._y0,i=this._x1,r=this._y1;if(isNaN(n))i=(n=Math.floor(e))+1,r=(s=Math.floor(t))+1;else{for(var h=i-n||1,x=this._root,v,l;n>e||e>=i||s>t||t>=r;)switch(l=(t<s)<<1|e<n,v=new Array(4),v[l]=x,x=v,h*=2,l){case 0:i=n+h,r=s+h;break;case 1:n=i-h,r=s+h;break;case 2:i=n+h,s=r-h;break;case 3:n=i-h,s=r-h;break}this._root&&this._root.length&&(this._root=x)}return this._x0=n,this._y0=s,this._x1=i,this._y1=r,this}function pt(){var e=[];return this.visit(function(t){if(!t.length)do e.push(t.data);while(t=t.next)}),e}function yt(e){return arguments.length?this.cover(+e[0][0],+e[0][1]).cover(+e[1][0],+e[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]}function R(e,t,n,s,i){this.node=e,this.x0=t,this.y0=n,this.x1=s,this.y1=i}function vt(e,t,n){var s,i=this._x0,r=this._y0,h,x,v,l,y=this._x1,_=this._y1,p=[],c=this._root,k,f;for(c&&p.push(new R(c,i,r,y,_)),n==null?n=1/0:(i=e-n,r=t-n,y=e+n,_=t+n,n*=n);k=p.pop();)if(!(!(c=k.node)||(h=k.x0)>y||(x=k.y0)>_||(v=k.x1)<i||(l=k.y1)<r))if(c.length){var o=(h+v)/2,d=(x+l)/2;p.push(new R(c[3],o,d,v,l),new R(c[2],h,d,o,l),new R(c[1],o,x,v,d),new R(c[0],h,x,o,d)),(f=(t>=d)<<1|e>=o)&&(k=p[p.length-1],p[p.length-1]=p[p.length-1-f],p[p.length-1-f]=k)}else{var m=e-+this._x.call(null,c.data),j=t-+this._y.call(null,c.data),w=m*m+j*j;if(w<n){var $=Math.sqrt(n=w);i=e-$,r=t-$,y=e+$,_=t+$,s=c.data}}return s}function wt(e){if(isNaN(y=+this._x.call(null,e))||isNaN(_=+this._y.call(null,e)))return this;var t,n=this._root,s,i,r,h=this._x0,x=this._y0,v=this._x1,l=this._y1,y,_,p,c,k,f,o,d;if(!n)return this;if(n.length)for(;;){if((k=y>=(p=(h+v)/2))?h=p:v=p,(f=_>=(c=(x+l)/2))?x=c:l=c,t=n,!(n=n[o=f<<1|k]))return this;if(!n.length)break;(t[o+1&3]||t[o+2&3]||t[o+3&3])&&(s=t,d=o)}for(;n.data!==e;)if(i=n,!(n=n.next))return this;return(r=n.next)&&delete n.next,i?(r?i.next=r:delete i.next,this):t?(r?t[o]=r:delete t[o],(n=t[0]||t[1]||t[2]||t[3])&&n===(t[3]||t[2]||t[1]||t[0])&&!n.length&&(s?s[d]=n:this._root=n),this):(this._root=r,this)}function Nt(e){for(var t=0,n=e.length;t<n;++t)this.remove(e[t]);return this}function _t(){return this._root}function jt(){var e=0;return this.visit(function(t){if(!t.length)do++e;while(t=t.next)}),e}function bt(e){var t=[],n,s=this._root,i,r,h,x,v;for(s&&t.push(new R(s,this._x0,this._y0,this._x1,this._y1));n=t.pop();)if(!e(s=n.node,r=n.x0,h=n.y0,x=n.x1,v=n.y1)&&s.length){var l=(r+x)/2,y=(h+v)/2;(i=s[3])&&t.push(new R(i,l,y,x,v)),(i=s[2])&&t.push(new R(i,r,y,l,v)),(i=s[1])&&t.push(new R(i,l,h,x,y)),(i=s[0])&&t.push(new R(i,r,h,l,y))}return this}function kt(e){var t=[],n=[],s;for(this._root&&t.push(new R(this._root,this._x0,this._y0,this._x1,this._y1));s=t.pop();){var i=s.node;if(i.length){var r,h=s.x0,x=s.y0,v=s.x1,l=s.y1,y=(h+v)/2,_=(x+l)/2;(r=i[0])&&t.push(new R(r,h,x,y,_)),(r=i[1])&&t.push(new R(r,y,x,v,_)),(r=i[2])&&t.push(new R(r,h,_,y,l)),(r=i[3])&&t.push(new R(r,y,_,v,l))}n.push(s)}for(;s=n.pop();)e(s.node,s.x0,s.y0,s.x1,s.y1);return this}function Mt(e){return e[0]}function St(e){return arguments.length?(this._x=e,this):this._x}function $t(e){return e[1]}function Ct(e){return arguments.length?(this._y=e,this):this._y}function ve(e,t,n){var s=new we(t??Mt,n??$t,NaN,NaN,NaN,NaN);return e==null?s:s.addAll(e)}function we(e,t,n,s,i,r){this._x=e,this._y=t,this._x0=n,this._y0=s,this._x1=i,this._y1=r,this._root=void 0}function Me(e){for(var t={data:e.data},n=t;e=e.next;)n=n.next={data:e.data};return t}var L=ve.prototype=we.prototype;L.copy=function(){var e=new we(this._x,this._y,this._x0,this._y0,this._x1,this._y1),t=this._root,n,s;if(!t)return e;if(!t.length)return e._root=Me(t),e;for(n=[{source:t,target:e._root=new Array(4)}];t=n.pop();)for(var i=0;i<4;++i)(s=t.source[i])&&(s.length?n.push({source:s,target:t.target[i]=new Array(4)}):t.target[i]=Me(s));return e};L.add=xt;L.addAll=gt;L.cover=mt;L.data=pt;L.extent=yt;L.find=vt;L.remove=wt;L.removeAll=Nt;L.root=_t;L.size=jt;L.visit=bt;L.visitAfter=kt;L.x=St;L.y=Ct;function J(e){return function(){return e}}function U(e){return(e()-.5)*1e-6}function At(e){return e.x+e.vx}function zt(e){return e.y+e.vy}function It(e){var t,n,s,i=1,r=1;typeof e!="function"&&(e=J(e==null?1:+e));function h(){for(var l,y=t.length,_,p,c,k,f,o,d=0;d<r;++d)for(_=ve(t,At,zt).visitAfter(x),l=0;l<y;++l)p=t[l],f=n[p.index],o=f*f,c=p.x+p.vx,k=p.y+p.vy,_.visit(m);function m(j,w,$,P,z){var C=j.data,H=j.r,I=f+H;if(C){if(C.index>p.index){var B=c-C.x-C.vx,F=k-C.y-C.vy,X=B*B+F*F;X<I*I&&(B===0&&(B=U(s),X+=B*B),F===0&&(F=U(s),X+=F*F),X=(I-(X=Math.sqrt(X)))/X*i,p.vx+=(B*=X)*(I=(H*=H)/(o+H)),p.vy+=(F*=X)*I,C.vx-=B*(I=1-I),C.vy-=F*I)}return}return w>c+I||P<c-I||$>k+I||z<k-I}}function x(l){if(l.data)return l.r=n[l.data.index];for(var y=l.r=0;y<4;++y)l[y]&&l[y].r>l.r&&(l.r=l[y].r)}function v(){if(t){var l,y=t.length,_;for(n=new Array(y),l=0;l<y;++l)_=t[l],n[_.index]=+e(_,l,t)}}return h.initialize=function(l,y){t=l,s=y,v()},h.iterations=function(l){return arguments.length?(r=+l,h):r},h.strength=function(l){return arguments.length?(i=+l,h):i},h.radius=function(l){return arguments.length?(e=typeof l=="function"?l:J(+l),v(),h):e},h}function Et(e){return e.index}function Se(e,t){var n=e.get(t);if(!n)throw new Error("node not found: "+t);return n}function Pt(e){var t=Et,n=_,s,i=J(30),r,h,x,v,l,y=1;e==null&&(e=[]);function _(o){return 1/Math.min(x[o.source.index],x[o.target.index])}function p(o){for(var d=0,m=e.length;d<y;++d)for(var j=0,w,$,P,z,C,H,I;j<m;++j)w=e[j],$=w.source,P=w.target,z=P.x+P.vx-$.x-$.vx||U(l),C=P.y+P.vy-$.y-$.vy||U(l),H=Math.sqrt(z*z+C*C),H=(H-r[j])/H*o*s[j],z*=H,C*=H,P.vx-=z*(I=v[j]),P.vy-=C*I,$.vx+=z*(I=1-I),$.vy+=C*I}function c(){if(h){var o,d=h.length,m=e.length,j=new Map(h.map(($,P)=>[t($,P,h),$])),w;for(o=0,x=new Array(d);o<m;++o)w=e[o],w.index=o,typeof w.source!="object"&&(w.source=Se(j,w.source)),typeof w.target!="object"&&(w.target=Se(j,w.target)),x[w.source.index]=(x[w.source.index]||0)+1,x[w.target.index]=(x[w.target.index]||0)+1;for(o=0,v=new Array(m);o<m;++o)w=e[o],v[o]=x[w.source.index]/(x[w.source.index]+x[w.target.index]);s=new Array(m),k(),r=new Array(m),f()}}function k(){if(h)for(var o=0,d=e.length;o<d;++o)s[o]=+n(e[o],o,e)}function f(){if(h)for(var o=0,d=e.length;o<d;++o)r[o]=+i(e[o],o,e)}return p.initialize=function(o,d){h=o,l=d,c()},p.links=function(o){return arguments.length?(e=o,c(),p):e},p.id=function(o){return arguments.length?(t=o,p):t},p.iterations=function(o){return arguments.length?(y=+o,p):y},p.strength=function(o){return arguments.length?(n=typeof o=="function"?o:J(+o),k(),p):n},p.distance=function(o){return arguments.length?(i=typeof o=="function"?o:J(+o),f(),p):i},p}var Tt={value:()=>{}};function Re(){for(var e=0,t=arguments.length,n={},s;e<t;++e){if(!(s=arguments[e]+"")||s in n||/[\s.]/.test(s))throw new Error("illegal type: "+s);n[s]=[]}return new ae(n)}function ae(e){this._=e}function Rt(e,t){return e.trim().split(/^|\s+/).map(function(n){var s="",i=n.indexOf(".");if(i>=0&&(s=n.slice(i+1),n=n.slice(0,i)),n&&!t.hasOwnProperty(n))throw new Error("unknown type: "+n);return{type:n,name:s}})}ae.prototype=Re.prototype={constructor:ae,on:function(e,t){var n=this._,s=Rt(e+"",n),i,r=-1,h=s.length;if(arguments.length<2){for(;++r<h;)if((i=(e=s[r]).type)&&(i=Lt(n[i],e.name)))return i;return}if(t!=null&&typeof t!="function")throw new Error("invalid callback: "+t);for(;++r<h;)if(i=(e=s[r]).type)n[i]=$e(n[i],e.name,t);else if(t==null)for(i in n)n[i]=$e(n[i],e.name,null);return this},copy:function(){var e={},t=this._;for(var n in t)e[n]=t[n].slice();return new ae(e)},call:function(e,t){if((i=arguments.length-2)>0)for(var n=new Array(i),s=0,i,r;s<i;++s)n[s]=arguments[s+2];if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(r=this._[e],s=0,i=r.length;s<i;++s)r[s].value.apply(t,n)},apply:function(e,t,n){if(!this._.hasOwnProperty(e))throw new Error("unknown type: "+e);for(var s=this._[e],i=0,r=s.length;i<r;++i)s[i].value.apply(t,n)}};function Lt(e,t){for(var n=0,s=e.length,i;n<s;++n)if((i=e[n]).name===t)return i.value}function $e(e,t,n){for(var s=0,i=e.length;s<i;++s)if(e[s].name===t){e[s]=Tt,e=e.slice(0,s).concat(e.slice(s+1));break}return n!=null&&e.push({name:t,value:n}),e}var ee=0,re=0,ne=0,Le=1e3,le,se,ce=0,K=0,fe=0,ie=typeof performance=="object"&&performance.now?performance:Date,Be=typeof window=="object"&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(e){setTimeout(e,17)};function Fe(){return K||(Be(Bt),K=ie.now()+fe)}function Bt(){K=0}function pe(){this._call=this._time=this._next=null}pe.prototype=He.prototype={constructor:pe,restart:function(e,t,n){if(typeof e!="function")throw new TypeError("callback is not a function");n=(n==null?Fe():+n)+(t==null?0:+t),!this._next&&se!==this&&(se?se._next=this:le=this,se=this),this._call=e,this._time=n,ye()},stop:function(){this._call&&(this._call=null,this._time=1/0,ye())}};function He(e,t,n){var s=new pe;return s.restart(e,t,n),s}function Ft(){Fe(),++ee;for(var e=le,t;e;)(t=K-e._time)>=0&&e._call.call(void 0,t),e=e._next;--ee}function Ce(){K=(ce=ie.now())+fe,ee=re=0;try{Ft()}finally{ee=0,Xt(),K=0}}function Ht(){var e=ie.now(),t=e-ce;t>Le&&(fe-=t,ce=e)}function Xt(){for(var e,t=le,n,s=1/0;t;)t._call?(s>t._time&&(s=t._time),e=t,t=t._next):(n=t._next,t._next=null,t=e?e._next=n:le=n);se=e,ye(s)}function ye(e){if(!ee){re&&(re=clearTimeout(re));var t=e-K;t>24?(e<1/0&&(re=setTimeout(Ce,e-ie.now()-fe)),ne&&(ne=clearInterval(ne))):(ne||(ce=ie.now(),ne=setInterval(Ht,Le)),ee=1,Be(Ce))}}const Dt=1664525,Yt=1013904223,Ae=4294967296;function Zt(){let e=1;return()=>(e=(Dt*e+Yt)%Ae)/Ae}function Wt(e){return e.x}function Gt(e){return e.y}var Qt=10,Ot=Math.PI*(3-Math.sqrt(5));function Ut(e){var t,n=1,s=.001,i=1-Math.pow(s,1/300),r=0,h=.6,x=new Map,v=He(_),l=Re("tick","end"),y=Zt();e==null&&(e=[]);function _(){p(),l.call("tick",t),n<s&&(v.stop(),l.call("end",t))}function p(f){var o,d=e.length,m;f===void 0&&(f=1);for(var j=0;j<f;++j)for(n+=(r-n)*i,x.forEach(function(w){w(n)}),o=0;o<d;++o)m=e[o],m.fx==null?m.x+=m.vx*=h:(m.x=m.fx,m.vx=0),m.fy==null?m.y+=m.vy*=h:(m.y=m.fy,m.vy=0);return t}function c(){for(var f=0,o=e.length,d;f<o;++f){if(d=e[f],d.index=f,d.fx!=null&&(d.x=d.fx),d.fy!=null&&(d.y=d.fy),isNaN(d.x)||isNaN(d.y)){var m=Qt*Math.sqrt(.5+f),j=f*Ot;d.x=m*Math.cos(j),d.y=m*Math.sin(j)}(isNaN(d.vx)||isNaN(d.vy))&&(d.vx=d.vy=0)}}function k(f){return f.initialize&&f.initialize(e,y),f}return c(),t={tick:p,restart:function(){return v.restart(_),t},stop:function(){return v.stop(),t},nodes:function(f){return arguments.length?(e=f,c(),x.forEach(k),t):e},alpha:function(f){return arguments.length?(n=+f,t):n},alphaMin:function(f){return arguments.length?(s=+f,t):s},alphaDecay:function(f){return arguments.length?(i=+f,t):+i},alphaTarget:function(f){return arguments.length?(r=+f,t):r},velocityDecay:function(f){return arguments.length?(h=1-f,t):1-h},randomSource:function(f){return arguments.length?(y=f,x.forEach(k),t):y},force:function(f,o){return arguments.length>1?(o==null?x.delete(f):x.set(f,k(o)),t):x.get(f)},find:function(f,o,d){var m=0,j=e.length,w,$,P,z,C;for(d==null?d=1/0:d*=d,m=0;m<j;++m)z=e[m],w=f-z.x,$=o-z.y,P=w*w+$*$,P<d&&(C=z,d=P);return C},on:function(f,o){return arguments.length>1?(l.on(f,o),t):l.on(f)}}}function Vt(){var e,t,n,s,i=J(-30),r,h=1,x=1/0,v=.81;function l(c){var k,f=e.length,o=ve(e,Wt,Gt).visitAfter(_);for(s=c,k=0;k<f;++k)t=e[k],o.visit(p)}function y(){if(e){var c,k=e.length,f;for(r=new Array(k),c=0;c<k;++c)f=e[c],r[f.index]=+i(f,c,e)}}function _(c){var k=0,f,o,d=0,m,j,w;if(c.length){for(m=j=w=0;w<4;++w)(f=c[w])&&(o=Math.abs(f.value))&&(k+=f.value,d+=o,m+=o*f.x,j+=o*f.y);c.x=m/d,c.y=j/d}else{f=c,f.x=f.data.x,f.y=f.data.y;do k+=r[f.data.index];while(f=f.next)}c.value=k}function p(c,k,f,o){if(!c.value)return!0;var d=c.x-t.x,m=c.y-t.y,j=o-k,w=d*d+m*m;if(j*j/v<w)return w<x&&(d===0&&(d=U(n),w+=d*d),m===0&&(m=U(n),w+=m*m),w<h&&(w=Math.sqrt(h*w)),t.vx+=d*c.value*s/w,t.vy+=m*c.value*s/w),!0;if(c.length||w>=x)return;(c.data!==t||c.next)&&(d===0&&(d=U(n),w+=d*d),m===0&&(m=U(n),w+=m*m),w<h&&(w=Math.sqrt(h*w)));do c.data!==t&&(j=r[c.data.index]*s/w,t.vx+=d*j,t.vy+=m*j);while(c=c.next)}return l.initialize=function(c,k){e=c,n=k,y()},l.strength=function(c){return arguments.length?(i=typeof c=="function"?c:J(+c),y(),l):i},l.distanceMin=function(c){return arguments.length?(h=c*c,l):Math.sqrt(h)},l.distanceMax=function(c){return arguments.length?(x=c*c,l):Math.sqrt(x)},l.theta=function(c){return arguments.length?(v=c*c,l):Math.sqrt(v)},l}function Jt(e,t){return e>0?"Every category has a steward.":t>0?"No categories yet — tag documents to see steward coverage.":"No categories or stewards yet — tag documents and assign stewards to see coverage."}const G={doc:"#3b82f6",steward:"#16a34a",tag:"#f59e0b",root:"#64748b",folder:"#a855f7"};function Kt(e){return e==="steward"?"#16a34a66":e==="tag"?"#f59e0b66":e==="structure"?"#a855f766":"#94a3b8aa"}const ze=(e,t,n)=>Math.min(n,Math.max(t,e)),Ie=.15,qt=5;function Ee(e){return e.kind==="doc"?e.name.includes("]]")||e.name.includes("|")?null:`[[${e.name}]]`:e.kind==="tag"?`#${e.name.replace(/^#/,"")}`:null}function en(e){return`'${e.replace(/'/g,"'\\''")}'`}function tn({nestId:e,nestName:t,onOpenTag:n,onOpenDocument:s,onBack:i}){const[r,h]=A.useState(null),[x,v]=A.useState(!0),[l,y]=A.useState(null),[_,p]=A.useState({links:!0,stewardship:!0,categories:!0,structure:!0}),[c,k]=A.useState(null),[f,o]=A.useState(1),d=A.useRef(null),m=A.useRef(null),[j,w]=A.useState({w:800,h:560}),[$,P]=A.useState({nodes:[],links:[]}),[z,C]=A.useState({x:0,y:0,k:1}),[H,I]=A.useState(!1),B=A.useRef(null),F=A.useRef(!1),X=A.useRef({w:0,h:0}),Xe=(a,g)=>{const N=m.current.getBoundingClientRect();return{x:(a-N.left-z.x)/z.k,y:(g-N.top-z.y)/z.k}},Ne=(a,g,N)=>{const b=a.filter(Z=>Z.x!=null&&Z.y!=null);if(!b.length)return C({x:g/2,y:N/2,k:1});let M=1/0,S=1/0,T=-1/0,E=-1/0;for(const Z of b)M=Math.min(M,Z.x),S=Math.min(S,Z.y),T=Math.max(T,Z.x),E=Math.max(E,Z.y);const D=48,W=T-M||1,Q=E-S||1,V=ze(Math.min((g-2*D)/W,(N-2*D)/Q),Ie,1.5);C({x:g/2-(M+T)/2*V,y:N/2-(S+E)/2*V,k:V})},he=(a,g=j.w/2,N=j.h/2)=>{F.current=!0,C(b=>{const M=ze(b.k*a,Ie,qt),S=(g-b.x)/b.k,T=(N-b.y)/b.k;return{k:M,x:g-S*M,y:N-T*M}})};A.useEffect(()=>{const a=m.current;if(!a)return;const g=N=>{N.preventDefault();const b=a.getBoundingClientRect();he(N.deltaY<0?1.1:1/1.1,N.clientX-b.left,N.clientY-b.top)};return a.addEventListener("wheel",g,{passive:!1}),()=>a.removeEventListener("wheel",g)},[j.w,j.h,x,l]);const De=a=>{var g,N;(N=(g=m.current)==null?void 0:g.setPointerCapture)==null||N.call(g,a.pointerId),B.current={mode:"pan",px:a.clientX,py:a.clientY},I(!0)},Ye=(a,g)=>{var N,b;a.stopPropagation(),(b=(N=m.current)==null?void 0:N.setPointerCapture)==null||b.call(N,a.pointerId),B.current={mode:"node",node:g,moved:!1}},Ze=a=>{const g=B.current;if(g)if(g.mode==="pan"){const N=a.clientX-g.px,b=a.clientY-g.py;g.px=a.clientX,g.py=a.clientY,F.current=!0,C(M=>({...M,x:M.x+N,y:M.y+b}))}else{g.moved=!0;const N=Xe(a.clientX,a.clientY);g.node.x=N.x,g.node.y=N.y,P(b=>({...b,nodes:b.nodes.slice()}))}},_e=a=>{var N,b;const g=B.current;(b=(N=m.current)==null?void 0:N.releasePointerCapture)==null||b.call(N,a.pointerId),(g==null?void 0:g.mode)==="node"&&!g.moved&&k(M=>(M==null?void 0:M.id)===g.node.id?null:g.node),B.current=null,I(!1)};A.useEffect(()=>{let a=!1;return v(!0),Qe(e).then(g=>{a||(F.current=!1,h(g))}).catch(g=>!a&&y((g==null?void 0:g.message)||"Failed to load graph")).finally(()=>!a&&v(!1)),()=>{a=!0}},[e]),A.useEffect(()=>{if(!d.current)return;const a=d.current,g=()=>w({w:a.clientWidth,h:Math.max(420,a.clientHeight)});g();let N;const b=new ResizeObserver(()=>{clearTimeout(N),N=setTimeout(g,150)});return b.observe(a),()=>{clearTimeout(N),b.disconnect()}},[]);const Y=(r==null?void 0:r.signals)??null,oe=A.useMemo(()=>{if(!r)return{nodes:[],links:[]};const a=[],g=[],N=new Set(((Y==null?void 0:Y.orphans)||[]).map(S=>S.id));for(const S of r.nodes)a.push({id:S.id,name:S.title,kind:"doc",color:N.has(S.id)?"#ef4444":G.doc,val:2});if(_.links)for(const S of r.links)g.push({...S,kind:"link"});const b=()=>{a.some(S=>S.id==="root:nest")||a.push({id:"root:nest",name:t,kind:"root",color:G.root,val:4})};if(_.structure){b();const S=new Set,T=(D,W)=>{const Q=`${D}~>${W}`;S.has(Q)||(S.add(Q),g.push({source:D,target:W,kind:"structure"}))},E=new Set;for(const D of r.nodes){const W=D.id.split("/").filter(Boolean),Q=W[0]==="nodes"?W.slice(1,-1):W.slice(0,-1);let V="root:nest",Z="";for(const de of Q){Z=Z?`${Z}/${de}`:de;const te=`folder:${Z}`;E.has(te)||(E.add(te),a.push({id:te,name:de,kind:"folder",color:G.folder,val:2})),T(V,te),V=te}T(V,D.id)}}if(_.categories){for(const S of r.tags)a.push({id:`tag:${S.name}`,name:`#${S.name}`,kind:"tag",color:G.tag,val:1+Math.min(S.count,4)});for(const S of r.nodes)for(const T of S.tags)g.push({source:S.id,target:`tag:${T}`,kind:"tag"})}if(_.stewardship){const S=new Map(r.stewards.map(E=>[E.id,E.label]));for(const E of r.stewards)a.push({id:`steward:${E.id}`,name:E.label,kind:"steward",color:G.steward,val:3});let T=!1;for(const E of r.stewardEdges){const D=`steward:${E.steward}`;if(S.has(E.steward))if(E.scope==="tag")if(_.categories)g.push({source:D,target:E.target,kind:"steward"});else{const W=E.target.replace(/^tag:/,"");for(const Q of r.nodes)Q.tags.includes(W)&&g.push({source:D,target:Q.id,kind:"steward"})}else E.scope==="document"?g.push({source:D,target:E.target,kind:"steward"}):(T=!0,g.push({source:D,target:"root:nest",kind:"steward"}))}T&&b()}const M=new Set(a.map(S=>S.id));return{nodes:a,links:g.filter(S=>M.has(S.source)&&M.has(S.target))}},[r,_,Y,t]);A.useEffect(()=>{if(!oe.nodes.length){P({nodes:[],links:[]});return}const a=oe.nodes.map(M=>({...M})),g=oe.links.map(M=>({...M})),N=Ut(a).force("link",Pt(g).id(M=>M.id).distance(55).strength(.35)).force("charge",Vt().strength(-170)).force("center",dt(j.w/2,j.h/2)).force("collide",It(14)).stop();for(let M=0;M<300;M++)N.tick();P({nodes:a,links:g});const b=X.current.w!==j.w||X.current.h!==j.h;(!F.current||b)&&(Ne(a,j.w,j.h),X.current={w:j.w,h:j.h})},[oe,j.w,j.h]);const je=a=>3+a.val,O=A.useMemo(()=>{if(!c)return null;const a=new Map;for(const b of $.links){const M=typeof b.source=="string"?b.source:b.source.id,S=typeof b.target=="string"?b.target:b.target.id;(a.get(M)??a.set(M,[]).get(M)).push(S),(a.get(S)??a.set(S,[]).get(S)).push(M)}const g=new Set([c.id]);let N=[c.id];for(let b=0;b<f&&N.length;b++){const M=[];for(const S of N)for(const T of a.get(S)??[])g.has(T)||(g.add(T),M.push(T));N=M}return g},[c,f,$.links]),We=A.useMemo(()=>new Map($.nodes.map(a=>[a.id,a])),[$.nodes]),be=((r==null?void 0:r.stewards.length)??0)>0,ke=((r==null?void 0:r.tags.length)??0)>0,Ge=((r==null?void 0:r.links.length)??0)>0;return u.jsxs("div",{className:"space-y-4",children:[u.jsx(tt,{nestName:t,onBack:i,children:u.jsxs("div",{className:"flex items-center gap-3 text-sm",children:[[["structure","Structure",ot,!0],["links","Links",nt,Ge],["stewardship","Stewardship",Oe,be],["categories","Categories",rt,ke]].filter(([,,,a])=>a).map(([a,g,N])=>u.jsxs("label",{className:"flex items-center gap-1.5 cursor-pointer select-none",children:[u.jsx("input",{type:"checkbox",checked:_[a],onChange:b=>p(M=>({...M,[a]:b.target.checked}))}),u.jsx(N,{className:"h-3.5 w-3.5"}),g]},a)),u.jsx(Pe,{variant:"ghost",size:"sm",onClick:()=>{F.current=!1,C({x:0,y:0,k:1})},title:"Reset pan & zoom",children:"Reset view"})]})}),u.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[1fr_300px] gap-4",children:[u.jsxs("div",{ref:d,className:"border border-border rounded-lg bg-card overflow-hidden h-[560px] relative",children:[x&&u.jsxs("div",{className:"absolute inset-0 flex items-center justify-center text-muted-foreground",children:[u.jsx(Ue,{className:"h-5 w-5 animate-spin mr-2"})," Loading ontology…"]}),l&&u.jsx("div",{className:"absolute inset-0 flex items-center justify-center text-red-500 text-sm",children:l}),!x&&!l&&(r==null?void 0:r.truncated)&&u.jsxs("div",{className:"absolute top-2 left-2 z-10 rounded bg-amber-100 text-amber-800 text-xs px-2 py-1 border border-amber-300",children:["Showing ",r.nodes.length," of ",r.totalNodes," nodes (highest-connected). Gaps below cover all ",r.totalNodes,"."]}),!x&&!l&&u.jsxs(u.Fragment,{children:[u.jsx("svg",{ref:m,width:j.w,height:j.h,className:"block touch-none",style:{cursor:H?"grabbing":"grab"},onPointerDown:De,onPointerMove:Ze,onPointerUp:_e,onPointerLeave:_e,children:u.jsxs("g",{transform:`translate(${z.x},${z.y}) scale(${z.k})`,children:[u.jsx("g",{children:$.links.map((a,g)=>{const N=a.source,b=a.target;if((N==null?void 0:N.x)==null||(b==null?void 0:b.x)==null)return null;const M=!O||O.has(N.id)&&O.has(b.id);return u.jsx("line",{x1:N.x,y1:N.y,x2:b.x,y2:b.y,stroke:Kt(a.kind),strokeWidth:(M&&O?1.6:1)/z.k,opacity:M?1:.15},g)})}),u.jsx("g",{children:$.nodes.map(a=>{const g=!O||O.has(a.id);return u.jsxs("g",{transform:`translate(${a.x??0},${a.y??0})`,onPointerDown:N=>Ye(N,a),onDoubleClick:()=>{a.kind==="doc"&&(s==null||s(a.id))},style:{cursor:"grab"},opacity:g?1:.25,children:[a.kind==="doc"&&s&&u.jsx("title",{children:`Double-click to open "${a.name}"`}),u.jsx("circle",{r:je(a),fill:a.color,stroke:(c==null?void 0:c.id)===a.id?"#111827":g&&O?"#111827aa":"#ffffff",strokeWidth:(c==null?void 0:c.id)===a.id?2:1}),u.jsx("text",{x:je(a)+3,y:3,fontSize:9,fill:"#475569",children:a.name.length>24?a.name.slice(0,24)+"…":a.name})]},a.id)})})]})}),u.jsxs("div",{className:"absolute bottom-2 right-2 z-10 flex flex-col gap-1",children:[u.jsx(xe,{label:"Zoom in",onClick:()=>he(1.25),children:u.jsx(ut,{className:"h-4 w-4"})}),u.jsx(xe,{label:"Zoom out",onClick:()=>he(1/1.25),children:u.jsx(ht,{className:"h-4 w-4"})}),u.jsx(xe,{label:"Fit to view",onClick:()=>Ne($.nodes,j.w,j.h),children:u.jsx(lt,{className:"h-4 w-4"})})]})]})]}),u.jsxs("div",{className:"space-y-4",children:[u.jsxs("div",{className:"border border-border rounded-lg bg-card p-3",children:[u.jsxs("div",{className:"flex items-center gap-1.5 font-medium text-sm mb-2",children:[((r==null?void 0:r.nodes.length)??0)===0?u.jsx(Ve,{className:"h-4 w-4 text-muted-foreground"}):u.jsx(st,{className:"h-4 w-4 text-amber-500"})," ","Coverage gaps"]}),Y?((r==null?void 0:r.nodes.length)??0)===0?u.jsxs("p",{className:"text-xs text-muted-foreground",children:[u.jsx("span",{className:"font-medium text-foreground",children:"No documents yet"})," ","— add content to see governance coverage and connection gaps."]}):u.jsxs("div",{className:"space-y-3 text-sm",children:[u.jsx(me,{label:"Categories with no steward",items:Y.unstewardedTags.map(a=>`#${a.name} (${a.count})`),empty:Jt((r==null?void 0:r.tags.length)??0,(r==null?void 0:r.stewards.length)??0),onSelect:n&&(a=>n(Y.unstewardedTags[a].name)),selectTitle:a=>`Show #${Y.unstewardedTags[a].name} documents`}),u.jsx(me,{label:"Bottleneck stewards (≥50% of nodes)",items:Y.bottlenecks.map(a=>`${a.label} — ${a.share}%`),empty:"No single-owner concentration."}),u.jsx(me,{label:"Orphan nodes (no links)",items:Y.orphans.map(a=>a.title),empty:"No orphans — everything connects.",onSelect:s&&(a=>s(Y.orphans[a].id)),selectTitle:a=>`Open "${Y.orphans[a].title}"`})]}):u.jsx("p",{className:"text-xs text-muted-foreground",children:"—"})]}),c&&u.jsx(nn,{node:c,graph:r,nestId:e,hopDepth:f,onHopDepth:o,neighborhood:O,nodesById:We,onOpenTag:n,onOpenDocument:s}),u.jsxs("div",{className:"text-xs text-muted-foreground space-y-1",children:[u.jsx(q,{color:G.root,label:"Nest"}),u.jsx(q,{color:G.folder,label:"Folder"}),u.jsx(q,{color:G.doc,label:"Document"}),u.jsx(q,{color:"#ef4444",label:"Orphan document"}),ke&&u.jsx(q,{color:G.tag,label:"Category / tag"}),be&&u.jsx(q,{color:G.steward,label:"Steward"})]})]})]})]})}function xe({label:e,onClick:t,children:n}){return u.jsx("button",{type:"button","aria-label":e,title:e,onClick:t,className:"flex h-7 w-7 items-center justify-center rounded border border-border bg-card text-foreground shadow-sm hover:bg-accent",children:n})}function nn({node:e,graph:t,nestId:n,hopDepth:s,onHopDepth:i,neighborhood:r,nodesById:h,onOpenTag:x,onOpenDocument:v}){const l=e.kind==="doc"?t==null?void 0:t.nodes.find(o=>o.id===e.id):null,y=l&&t?t.links.filter(o=>o.source===l.id||o.target===l.id).length:0,_=Ee(e),p=r?[...r].map(o=>h.get(o)).filter(o=>!!o).map(Ee).filter(o=>!!o):[],c=p.join(" | "),k=typeof window<"u"?window.location.origin:"",f=_?`curl -X POST ${k}/nests/${n}/context \\
|
|
22
|
+
-H "Content-Type: application/json" \\
|
|
23
|
+
-H "Authorization: Bearer <api-key>" \\
|
|
24
|
+
-d ${en(JSON.stringify({selector:_,hops:s}))}`:null;return u.jsxs("div",{className:"border border-border rounded-lg bg-card p-3 text-sm space-y-2",children:[u.jsxs("div",{children:[u.jsx("div",{className:"font-medium mb-1 break-all",children:e.name}),u.jsx("div",{className:"text-xs text-muted-foreground capitalize",children:e.kind})]}),l&&v&&u.jsx(Pe,{size:"sm",variant:"outline",className:"w-full h-7 text-xs",onClick:()=>v(l.id),children:"Open document"}),l&&u.jsxs("div",{className:"space-y-1 text-xs",children:[l.tags.length>0&&u.jsx("div",{className:"flex flex-wrap gap-1",children:l.tags.map(o=>u.jsxs("button",{type:"button",onClick:()=>x==null?void 0:x(o),disabled:!x,className:"rounded bg-amber-50 text-amber-700 px-1.5 py-0.5 hover:bg-amber-100 disabled:hover:bg-amber-50 disabled:cursor-default",title:x?`Show #${o} documents`:`#${o}`,children:["#",o]},o))}),u.jsx("div",{className:"text-muted-foreground",children:y===0?"No wikilinks":`${y} wikilink${y===1?"":"s"}`})]}),u.jsxs("div",{className:"border-t pt-2 space-y-2",children:[u.jsxs("div",{className:"flex items-center justify-between gap-2",children:[u.jsx("span",{className:"text-xs font-medium",children:"Query this selection"}),u.jsxs("label",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:["hops",u.jsx("select",{className:"border border-border rounded bg-card px-1 py-0.5 text-xs",value:s,onChange:o=>i(Number(o.target.value)),children:[0,1,2,3].map(o=>u.jsx("option",{value:o,children:o},o))})]})]}),_&&u.jsx(ge,{label:"Selector",value:_}),f&&u.jsx(ge,{label:`API call (this node + ${s} hop${s===1?"":"s"})`,value:f}),p.length>1&&u.jsx(ge,{label:`Highlighted set (${p.length} nodes, exact — use hops: 0)`,value:c}),!_&&p.length===0&&u.jsx("p",{className:"text-xs text-muted-foreground",children:"No selector for this node kind — select a document or tag."})]})]})}function ge({label:e,value:t}){const[n,s]=A.useState(!1),i=async()=>{await qe(t)&&(s(!0),setTimeout(()=>s(!1),1500))};return u.jsxs("div",{className:"min-w-0",children:[u.jsxs("div",{className:"flex items-center justify-between gap-2 mb-0.5",children:[u.jsx("span",{className:"text-[11px] text-muted-foreground truncate",children:e}),u.jsx("button",{type:"button","aria-label":`Copy ${e}`,onClick:i,className:"flex h-5 w-5 items-center justify-center rounded hover:bg-accent shrink-0",children:n?u.jsx(Je,{className:"h-3 w-3 text-green-600"}):u.jsx(Ke,{className:"h-3 w-3"})})]}),u.jsx("pre",{className:"bg-muted rounded px-2 py-1.5 text-[10px] font-mono whitespace-pre-wrap break-all max-h-28 overflow-y-auto",children:t})]})}function me({label:e,items:t,empty:n,onSelect:s,selectTitle:i}){return u.jsxs("div",{children:[u.jsx("div",{className:"text-xs font-medium text-foreground",children:e}),t.length===0?u.jsx("div",{className:"text-xs text-muted-foreground",children:n}):u.jsxs("ul",{className:"mt-0.5 space-y-0.5",children:[t.slice(0,8).map((r,h)=>u.jsx("li",{className:"text-xs text-amber-700 break-all",children:s?u.jsx("button",{type:"button",onClick:()=>s(h),title:i==null?void 0:i(h),className:"text-left hover:underline",children:r}):r},h)),t.length>8&&u.jsxs("li",{className:"text-xs text-muted-foreground",children:["+",t.length-8," more"]})]})]})}function q({color:e,label:t}){return u.jsxs("div",{className:"flex items-center gap-1.5",children:[u.jsx("span",{className:"inline-block h-2.5 w-2.5 rounded-full",style:{background:e}}),t]})}function cn(){const e=et();return u.jsx(tn,{nestId:e.nestId,nestName:e.nestName,onOpenTag:t=>e.openNest({tags:[t]}),onOpenDocument:e.openDocument,onBack:e.leaveNest})}export{cn as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ck as he,O as ue,r as h,u as pe,i as U,co as F,j as t,cp as xe,cq as q,C as fe,f as x,s as ge,L as ve,B as u,bx as K,cr as be,cs as je,ct as ye,bO as ke,bP as Ne,as as _e,ax as we}from"./index-B5hLclEq.js";import{f as Ce,r as Q}from"./dates-BCxbm4_q.js";import{P as Re}from"./page-title-BkqlUA0j.js";import{A as Se,a as $e,R as Ae}from"./ReviewActions-BXDTDPp1.js";import{f as V}from"./scroll-area-CbcH6yrZ.js";import"./select-DrL0mpRN.js";import"./card-UDyMRcps.js";import{R as J}from"./ReasonDialog-CN3ECAnQ.js";import{C as We}from"./circle-check-CSkZUEFK.js";import{T as qe}from"./trash-2-B4hRXo-p.js";import{C as Te}from"./circle-x-in2o3aHU.js";import{C as De}from"./chevron-left-XR4ReJ9Z.js";const Y=8;function ze(f,j,g=Y){return j?f:f.slice(0,g)}function X(f,j){return f.filter(g=>g.id!==j)}function Je(){var I,E;const{openNest:f,openReview:j}=he(),{adminStatus:g}=ue(),G=((I=g==null?void 0:g.me)==null?void 0:I.email)??null,[n,m]=h.useState({items:[],waiting:[]}),[H,Z]=h.useState(!0),[T,D]=h.useState(!1),[l,S]=h.useState(null),[y,z]=h.useState("delete"),[d,v]=h.useState(new Set),[p,N]=h.useState(null),[$,ee]=h.useState(!1),M=pe(),w=async e=>{D(!0);try{const s=await M.fetchQuery(U.myWork({offset:e}));m(a=>({items:s.items,waiting:s.waiting,notifications:s.notifications??a.notifications,pagination:s.pagination}));const i=new Set(s.items.map(a=>`${a.nest_id}:${a.node_id}`));v(a=>new Set([...a].filter(k=>i.has(k))))}catch(s){console.error("[Dashboard] goToWorkPage failed",s)}finally{D(!1)}};h.useEffect(()=>{M.fetchQuery(U.myWork()).then(m).catch(()=>m({items:[],waiting:[],notifications:[]})).finally(()=>Z(!1))},[G]);const te=async(e,s)=>{await be(e.nest_id,e.node_id,s),R(e)},se=async(e,s)=>{await je(e.nest_id,e.node_id,s),R(e)},b=n.items.filter(e=>e.type==="review"),A=e=>`${e.nest_id}:${e.node_id}`,C=(()=>{const e=new Map;for(const i of b)d.has(A(i))&&e.set(i.nest_id,(e.get(i.nest_id)??0)+1);const s=Math.max(0,...e.values());return Math.max(0,s-F)})(),ie=async(e,s)=>{var B;const i=b.filter(o=>d.has(A(o)));if(i.length===0){x.info("Nothing selected on this page"),v(new Set),N(null);return}const a=new Map;for(const o of i)a.set(o.nest_id,[...a.get(o.nest_id)??[],o.node_id]);const k=await Promise.all([...a].map(([o,r])=>ye(o,e,r,s||void 0).then(_=>({nestId:o,..._})).catch(_=>({nestId:o,succeeded:0,failed:r.length,results:r.map(me=>({nodeId:me,ok:!1,error:(_==null?void 0:_.message)||"Request failed"}))})))),W=k.reduce((o,r)=>o+r.succeeded,0),L=k.reduce((o,r)=>o+r.failed,0),ce=new Set(k.flatMap(o=>o.results.filter(r=>!r.ok).map(r=>`${o.nestId}:${r.nodeId}`))),O=e==="approve"?"approved":"rejected";if(L===0)x.success(`${W} document${W===1?"":"s"} ${O}`);else{const o=[...new Set(k.flatMap(r=>r.results).filter(r=>!r.ok).map(r=>r.error||"Unknown reason"))];x.warning(`${W} ${O}, ${L} could not be`,{description:o.join(" "),duration:1e4})}v(ce),N(null),w(((B=n.pagination)==null?void 0:B.offset)??0)},c=e=>e.target_type==="nest_archive",ne=e=>e.type!=="deletion"?"Review":c(e)?"Archive":"Deletion",ae=async()=>{const e=l;await ke(e.nest_id,e.request_id),R(e)},oe=async e=>{const s=l;await Ne(s.nest_id,s.request_id,e),R(s)},re=async e=>{await _e(e.nest_id,e.request_id),m(s=>({...s,waiting:s.waiting.filter(i=>!(i.nest_id===e.nest_id&&i.node_id===e.node_id))}))},de=async e=>{await we(e.nest_id,e.node_id),m(s=>({...s,waiting:s.waiting.filter(i=>!(i.nest_id===e.nest_id&&i.node_id===e.node_id))}))},P=e=>{if(e.type==="deletion"&&e.target_type&&e.target_type!=="document"){f(e.nest_id,e.nest_name,!1,!1);return}j(e.nest_id,e.nest_name,e.node_id)},le=e=>{q([e.id]).catch(()=>{}),m(s=>({...s,notifications:X(s.notifications??[],e.id)})),e.node_id?j(e.nest_id,e.nest_name,e.node_id):f(e.nest_id,e.nest_name,!1,!1)},R=e=>{var s;m(i=>({...i,items:i.items.filter(a=>!(a.nest_id===e.nest_id&&a.node_id===e.node_id))})),v(i=>{const a=new Set(i);return a.delete(`${e.nest_id}:${e.node_id}`),a}),w(((s=n.pagination)==null?void 0:s.offset)??0)};return t.jsxs("div",{className:"space-y-4",children:[t.jsx(Re,{icon:xe,title:"My Work",description:"Reviews and requests waiting on you, and what you handed off.",className:"mb-0"}),t.jsx("div",{children:t.jsxs("div",{className:"space-y-5",children:[t.jsxs("div",{children:[(((E=n.notifications)==null?void 0:E.length)??0)>0&&t.jsxs("div",{className:"mb-3 rounded-lg border border-amber-300/50 bg-amber-500/5",children:[t.jsxs("div",{className:"px-4 py-2 flex items-center gap-2 text-sm font-medium",children:["🔔 Notifications",t.jsxs("span",{className:"text-xs text-muted-foreground",children:["(",n.notifications.length,")"]}),t.jsx("div",{className:"flex-1"}),t.jsx("button",{type:"button",className:"text-xs text-primary hover:underline",onClick:async()=>{await q("all"),m(e=>({...e,notifications:[]}))},children:"Mark all read"})]}),t.jsx("div",{className:ge("divide-y border-t",$&&"max-h-80 overflow-y-auto"),children:ze(n.notifications,$).map(e=>t.jsxs("div",{className:"flex items-center gap-2 px-4 py-2 text-xs hover:bg-amber-500/10",children:[t.jsxs("button",{type:"button",onClick:()=>le(e),className:"flex-1 flex items-center gap-2 text-left",children:[t.jsx("span",{className:"flex-1",children:e.message}),t.jsx("span",{className:"text-muted-foreground shrink-0",children:Ce(e.created_at)})]}),t.jsx("button",{type:"button",title:"Mark as read","aria-label":"Mark as read",className:"shrink-0 rounded p-1 text-muted-foreground hover:bg-amber-500/20 hover:text-foreground",onClick:async()=>{try{await q([e.id]),m(s=>({...s,notifications:X(s.notifications??[],e.id)}))}catch(s){x.error((s==null?void 0:s.message)||"Failed to mark as read")}},children:t.jsx(fe,{className:"h-3.5 w-3.5"})})]},e.id))}),n.notifications.length>Y&&t.jsx("div",{className:"border-t px-4 py-1.5 text-center",children:t.jsx("button",{type:"button",className:"text-xs text-primary hover:underline",onClick:()=>ee(e=>!e),children:$?"Show less":`Show all (${n.notifications.length})`})})]}),H?t.jsxs("div",{className:"rounded-lg border bg-muted/20 px-4 py-6 flex items-center justify-center gap-2 text-sm text-muted-foreground",children:[t.jsx(ve,{className:"h-4 w-4 animate-spin"}),"Loading your work…"]}):n.items.length===0?t.jsx("div",{className:"rounded-lg border bg-muted/20 px-4 py-6 text-center text-sm text-muted-foreground",children:"You're all caught up — nothing waiting on you."}):t.jsxs("div",{className:"rounded-lg border divide-y overflow-hidden",children:[b.length>1&&t.jsxs("div",{className:"flex flex-wrap items-center gap-2 bg-muted/40 px-4 py-2 text-sm",children:[t.jsx(V,{checked:d.size===0?!1:d.size===b.length?!0:"indeterminate",onCheckedChange:e=>v(e===!0?new Set(b.map(A)):new Set),"aria-label":"Select every review waiting on you","data-testid":"work-select-all"}),t.jsx("span",{className:"text-muted-foreground",children:d.size>0?`${d.size} selected`:`Select all ${b.length} reviews`}),C>0&&t.jsxs("span",{className:"text-destructive",children:["Up to ",F," per nest — deselect"," ",C,"."]}),d.size>0&&t.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[t.jsxs(u,{size:"sm",disabled:C>0,onClick:()=>N("approve"),"data-testid":"work-bulk-approve",children:["Approve ",d.size]}),t.jsxs(u,{size:"sm",variant:"outline",disabled:C>0,onClick:()=>N("reject"),"data-testid":"work-bulk-reject",children:["Reject ",d.size]}),t.jsx(u,{size:"sm",variant:"ghost",onClick:()=>v(new Set),children:"Clear"})]})]}),n.items.map(e=>{const s=`${e.nest_id}:${e.node_id}`;return t.jsxs("div",{className:"flex items-center gap-3 px-4 py-2.5 hover:bg-muted/40 group",children:[b.length>1&&t.jsx(V,{checked:d.has(s),disabled:e.type!=="review",onCheckedChange:()=>v(i=>{const a=new Set(i);return a.has(s)?a.delete(s):a.add(s),a}),"aria-label":`Select ${e.title}`,className:e.type==="review"?"":"invisible"}),t.jsx("span",{className:`rounded px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide shrink-0 ${e.type==="deletion"&&!c(e)?"bg-red-100 text-red-800 dark:bg-red-950/40 dark:text-red-300":"bg-amber-100 text-amber-800 dark:bg-amber-950/40 dark:text-amber-300"}`,children:ne(e)}),t.jsxs("button",{onClick:()=>P(e),className:"flex items-center gap-2 min-w-0 flex-1 text-left",children:[t.jsx("span",{className:"font-medium truncate",children:e.title}),t.jsxs("span",{className:"text-xs text-muted-foreground truncate",children:["in ",e.nest_name," · ",e.requested_by," · ",Q(e.requested_at),e.reason?` · "${e.reason}"`:""]})]}),t.jsx("div",{className:"flex items-center gap-2 shrink-0",children:e.type==="deletion"?t.jsxs(t.Fragment,{children:[t.jsxs(u,{variant:"outline",className:c(e)?Se:"text-destructive hover:text-destructive",onClick:()=>{z("delete"),S(e)},children:[c(e)?t.jsx(We,{className:"h-4 w-4 mr-2"}):t.jsx(qe,{className:"h-4 w-4 mr-2"}),c(e)?"Approve":"Delete"]}),t.jsxs(u,{variant:"outline",className:$e,onClick:()=>{z("decline"),S(e)},children:[t.jsx(Te,{className:"h-4 w-4 mr-2"})," Reject"]})]}):t.jsx(Ae,{documentTitle:e.title,version:1,onApprove:i=>te(e,i),onReject:i=>se(e,i)})})]},s)})]})]}),n.waiting.length>0&&t.jsxs("div",{children:[t.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[t.jsx("h3",{className:"text-sm font-semibold text-muted-foreground uppercase tracking-wide",children:"Waiting on others"}),t.jsx("span",{className:"rounded-full bg-muted text-muted-foreground text-xs font-semibold px-2 py-0.5",children:n.waiting.length})]}),t.jsx("div",{className:"rounded-lg border divide-y overflow-hidden",children:n.waiting.map(e=>t.jsxs("div",{className:"flex items-center gap-3 px-4 py-2 hover:bg-muted/40 group text-sm",children:[t.jsxs("button",{onClick:()=>P(e),className:"flex items-center gap-3 flex-1 min-w-0 text-left",children:[t.jsx("span",{className:"font-medium truncate",children:e.title}),t.jsxs("span",{className:"text-xs text-muted-foreground shrink-0",children:["in ",e.nest_name," ·"," ",e.type==="deletion"?"requested":"submitted"," ",Q(e.requested_at)]}),t.jsx("span",{className:"flex-1"}),t.jsx("span",{className:"text-xs text-muted-foreground",children:e.type!=="deletion"?"Pending Review":c(e)?"Archive Requested":"Deletion Requested"})]}),e.type==="deletion"&&e.request_id&&t.jsx(u,{size:"sm",variant:"ghost",className:"shrink-0 text-muted-foreground h-7 px-2",onClick:async s=>{s.stopPropagation();try{await re(e),x.success(c(e)?"Archive request withdrawn":"Deletion request withdrawn")}catch(i){x.error((i==null?void 0:i.message)||"Failed to withdraw deletion request")}},title:"Withdraw this deletion request",children:"Withdraw"}),e.type==="review"&&t.jsx(u,{size:"sm",variant:"ghost",className:"shrink-0 text-muted-foreground h-7 px-2",onClick:async s=>{s.stopPropagation();try{await de(e),x.success("Submission withdrawn — back to Draft")}catch(i){x.error((i==null?void 0:i.message)||"Failed to withdraw submission")}},title:"Withdraw this submission and return the document to Draft",children:"Withdraw"}),t.jsx(K,{className:"h-4 w-4 text-muted-foreground group-hover:translate-x-0.5 transition-transform shrink-0"})]},`${e.nest_id}:${e.node_id}`))})]}),n.pagination&&n.pagination.total>n.pagination.limit&&t.jsxs("div",{className:"flex items-center justify-center gap-3 pt-1 text-sm text-muted-foreground",children:[t.jsxs(u,{variant:"outline",size:"sm",disabled:T||n.pagination.offset===0,onClick:()=>w(Math.max(0,n.pagination.offset-n.pagination.limit)),children:[t.jsx(De,{className:"h-3.5 w-3.5 mr-1"}),"Prev"]}),t.jsxs("span",{children:["Page ",Math.floor(n.pagination.offset/n.pagination.limit)+1," of"," ",Math.max(1,Math.ceil(n.pagination.total/n.pagination.limit))]}),t.jsxs(u,{variant:"outline",size:"sm",disabled:T||!n.pagination.has_more,onClick:()=>w(n.pagination.offset+n.pagination.limit),children:["Next",t.jsx(K,{className:"h-3.5 w-3.5 ml-1"})]})]})]})}),p&&t.jsx(J,{open:!0,onOpenChange:e=>!e&&N(null),title:p==="approve"?`Approve ${d.size} document${d.size===1?"":"s"}?`:`Reject ${d.size} document${d.size===1?"":"s"}?`,description:p==="approve"?"Approving publishes each one. Anything that changed since this inbox loaded is reported back and left alone.":"Each author gets the same reason and the work goes back to them.",label:p==="reject"?"Why?":"Comment (optional)",optionalReason:p==="approve",placeholder:"Shared with every author in this batch",confirmLabel:p==="approve"?"Approve all":"Reject all",destructive:p==="reject",onConfirm:e=>ie(p,e)}),l&&t.jsx(J,{open:!0,onOpenChange:e=>!e&&S(null),title:y!=="delete"?`Reject this ${c(l)?"archive":"deletion"} request`:c(l)?`Archive "${l.title}"?`:`Delete "${l.title}"?`,description:`${l.requested_by} asked for this: "${l.reason??""}". ${y!=="delete"?c(l)?"The nest stays where it is; your note is the record, and the requester is notified.":"The document stays; your note is the record, and the requester is notified.":c(l)?"The nest goes read-only and leaves the dashboard; nothing is deleted and you can restore it.":"Deleting removes the document, its history, comments and annotations. It cannot be undone."}`,label:y==="decline"?"Why are you rejecting?":void 0,placeholder:"e.g. still referenced by onboarding",confirmLabel:y!=="delete"?"Reject":c(l)?"Archive nest":"Delete document",destructive:y==="delete"&&!c(l),onConfirm:y==="delete"?ae:oe})]})}export{Je as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ck as U,O as V,r as i,u as X,bX as G,j as e,ag as J,I as W,L as R,B as h,bA as Y,bx as Z,i as ee,aA as te,f as k,a5 as se}from"./index-B5hLclEq.js";import{r as ae}from"./dates-BCxbm4_q.js";import{P as re}from"./page-title-BkqlUA0j.js";import{f as T}from"./scroll-area-CbcH6yrZ.js";import"./select-DrL0mpRN.js";import"./card-UDyMRcps.js";import{S as ie}from"./SubmitForReviewModal-BOZJxwRN.js";import{A as ne,a as oe,b as le,c as de,d as ce,e as me,f as fe,g as ue}from"./alert-dialog-4SiLKlz8.js";import{C as E}from"./circle-check-CSkZUEFK.js";import{T as M}from"./trash-2-B4hRXo-p.js";import{C as he}from"./chevron-left-XR4ReJ9Z.js";import"./send-CvAgOUPG.js";function ke(){var z;const{openReview:F}=U(),{adminStatus:D}=V(),L=((z=D==null?void 0:D.me)==null?void 0:z.email)??null,[c,S]=i.useState([]),[a,P]=i.useState(null),[N,$]=i.useState(!0),[m,j]=i.useState(null),[C,B]=i.useState(""),[v,O]=i.useState(""),[b,Q]=i.useState("updated"),[l,x]=i.useState(new Set),[w,_]=i.useState(!1),[n,y]=i.useState(null),q=X(),u=async t=>{$(!0);try{const s=await q.fetchQuery(ee.myDrafts({offset:t,q:v||void 0,sort:b}));if(s.drafts.length===0&&t>0&&s.pagination.total>0)return void await u(0);S(s.drafts),P(s.pagination)}catch(s){console.error("[Dashboard] goToDraftsPage failed",s),S([])}finally{$(!1)}},I=async(t,s,f)=>{const r=[],d=[];for(const o of t)try{await te(o.nest_id,o.node_id,s,f),r.push(o)}catch(g){d.push(o),console.error("[Dashboard] submitForReview failed",o.node_id,g)}if(S(o=>o.filter(g=>!r.some(K=>p(K)===p(g)))),x(new Set),u((a==null?void 0:a.offset)??0),d.length){j(d);const o=r.length?`${r.length} submitted. `:"";throw new Error(`${o}Couldn't submit ${d.length}: ${d.map(g=>g.title).join(", ")}`)}r.length>1&&k.success(`${r.length} submitted for review`)},p=t=>`${t.nest_id}:${t.node_id}`;i.useEffect(()=>{const t=setTimeout(()=>O(C.trim()),250);return()=>clearTimeout(t)},[C]),i.useEffect(()=>{u(0)},[L]);const A=G.useRef(!1);i.useEffect(()=>{if(!A.current){A.current=!0;return}x(new Set),u(0)},[v,b]);const H=async t=>{if(t.length===0)return;y(null),_(!0);let s=0,f=0;const r=[];for(const d of t)try{(await se(d.nest_id,d.node_id)).deleted?f++:s++}catch(o){r.push(d.title),console.error("[Dashboard] discardDraft failed",d.node_id,o)}_(!1),x(new Set),(s||f)&&k.success([s?`${s} restored to the approved version`:"",f?`${f} deleted`:""].filter(Boolean).join(" · ")),r.length&&k.error(`Couldn't discard: ${r.join(", ")}`),u((a==null?void 0:a.offset)??0)};return e.jsxs("div",{className:"space-y-4",children:[e.jsx(re,{icon:J,title:"My Drafts",description:"Everything you started and never handed off.",className:"mb-0"}),e.jsx("div",{children:e.jsxs("div",{children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 mb-2",children:[e.jsx(W,{value:C,onChange:t=>B(t.target.value),placeholder:"Search drafts by title or nest…",className:"h-8 max-w-xs","aria-label":"Search your drafts","data-testid":"drafts-search"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-xs font-medium text-muted-foreground",children:"Sort:"}),e.jsx("div",{className:"inline-flex items-center rounded-md border bg-muted/40 p-0.5",role:"group","aria-label":"Sort drafts",children:[["updated","Recently edited"],["title","Title"]].map(([t,s])=>e.jsx("button",{type:"button","aria-pressed":b===t,onClick:()=>Q(t),className:`h-6 rounded px-2 text-xs transition-colors ${b===t?"bg-background font-medium text-foreground shadow-sm":"text-muted-foreground hover:text-foreground"}`,"data-testid":`drafts-sort-${t}`,children:s},t))})]})]}),N?e.jsxs("div",{className:"rounded-lg border bg-muted/20 px-4 py-6 flex items-center justify-center gap-2 text-sm text-muted-foreground",children:[e.jsx(R,{className:"h-4 w-4 animate-spin"}),"Loading your drafts…"]}):c.length===0?e.jsx("div",{className:"rounded-lg border bg-muted/20 px-4 py-6 text-center text-sm text-muted-foreground",children:v?`No drafts match "${v}".`:"No unsubmitted drafts — everything you've written is in review or approved."}):e.jsxs("div",{className:"rounded-lg border divide-y overflow-hidden",children:[c.length>1&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2 bg-muted/40 px-4 py-2 text-sm",children:[e.jsx(T,{checked:l.size===0?!1:l.size===c.length?!0:"indeterminate",onCheckedChange:t=>x(t===!0?new Set(c.map(p)):new Set),"aria-label":"Select every draft on this page","data-testid":"drafts-select-all"}),e.jsx("span",{className:"text-muted-foreground",children:l.size>0?`${l.size} selected`:`Select all ${c.length} on this page`}),l.size>0&&e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[e.jsxs(h,{size:"sm",variant:"outline",disabled:w,onClick:()=>j(c.filter(t=>l.has(p(t)))),"data-testid":"drafts-bulk-submit",children:[e.jsx(E,{className:"h-3.5 w-3.5 mr-1"}),"Submit ",l.size," for review"]}),e.jsxs(h,{size:"sm",variant:"outline",disabled:w,onClick:()=>y(c.filter(t=>l.has(p(t)))),"data-testid":"drafts-bulk-discard",children:[w?e.jsx(R,{className:"h-3.5 w-3.5 mr-1 animate-spin"}):e.jsx(M,{className:"h-3.5 w-3.5 mr-1"}),"Discard ",l.size]}),e.jsx(h,{size:"sm",variant:"ghost",onClick:()=>x(new Set),children:"Clear"})]})]}),c.map(t=>{const s=`${t.nest_id}:${t.node_id}`;return e.jsxs("div",{className:"flex items-center gap-3 px-4 py-2.5 hover:bg-muted/40 group",children:[c.length>1&&e.jsx(T,{checked:l.has(s),onCheckedChange:()=>x(f=>{const r=new Set(f);return r.has(s)?r.delete(s):r.add(s),r}),"aria-label":`Select ${t.title}`}),e.jsx("span",{className:`rounded px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide shrink-0 ${t.status==="rejected"?"bg-red-100 text-red-800 dark:bg-red-950/40 dark:text-red-300":"bg-muted text-muted-foreground"}`,children:t.status==="rejected"?"Rejected":"Draft"}),e.jsxs("button",{onClick:()=>F(t.nest_id,t.nest_name,t.node_id),className:"flex flex-col min-w-0 flex-1 text-left gap-0.5",children:[e.jsx("span",{className:"font-medium truncate",children:t.title}),e.jsxs("span",{className:"text-xs text-muted-foreground truncate",title:`${t.nest_name} / ${t.node_id}`,children:[e.jsx(Y,{className:"h-3 w-3 inline mr-1 -mt-0.5"}),t.nest_name,t.folder?` / ${t.folder}`:""," · edited"," ",ae(t.updated_at)]})]}),e.jsxs(h,{size:"sm",variant:"outline",className:"shrink-0",onClick:()=>j([t]),children:[e.jsx(E,{className:"h-3.5 w-3.5 mr-1"}),"Submit for review"]}),e.jsx(h,{size:"sm",variant:"ghost",disabled:w,className:"shrink-0 text-muted-foreground hover:text-destructive",title:"Discard this draft — back to the last approved version, or delete it if there isn't one",onClick:()=>y([t]),"data-testid":"draft-discard",children:e.jsx(M,{className:"h-3.5 w-3.5"})})]},s)})]}),a&&a.total>a.limit&&e.jsxs("div",{className:"flex items-center justify-center gap-3 pt-3 text-sm text-muted-foreground",children:[e.jsxs(h,{variant:"outline",size:"sm",disabled:N||a.offset===0,onClick:()=>u(Math.max(0,a.offset-a.limit)),children:[e.jsx(he,{className:"h-3.5 w-3.5 mr-1"}),"Prev"]}),e.jsxs("span",{children:["Page ",Math.floor(a.offset/a.limit)+1," of"," ",Math.max(1,Math.ceil(a.total/a.limit))]}),e.jsxs(h,{variant:"outline",size:"sm",disabled:N||!a.has_more,onClick:()=>u(a.offset+a.limit),children:["Next",e.jsx(Z,{className:"h-3.5 w-3.5 ml-1"})]})]})]})}),m&&m.length>0&&e.jsx(ie,{isOpen:!0,onClose:()=>j(null),documentTitle:m.length===1?m[0].title:`${m.length} drafts`,currentVersion:m.length===1?m[0].version:null,onSubmit:(t,s)=>I(m,t,s)}),e.jsx(ne,{open:!!n,onOpenChange:t=>!t&&y(null),children:e.jsxs(oe,{children:[e.jsxs(le,{children:[e.jsx(de,{children:(n==null?void 0:n.length)===1?`Discard "${n[0].title}"?`:`Discard ${(n==null?void 0:n.length)??0} drafts?`}),e.jsxs(ce,{children:[(n==null?void 0:n.length)===1?"The document goes":"Each document goes"," ","back to its last approved version. A document that was never approved is deleted instead. This can't be undone."]})]}),e.jsxs(me,{children:[e.jsx(fe,{children:"Cancel"}),e.jsx(ue,{onClick:()=>void H(n??[]),"data-testid":"drafts-discard-confirm",children:"Discard"})]})]})})]})}export{ke as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e,r as o,c_ as Ve,d3 as ze,dk as Ge,cP as ue,dl as Ue,c$ as Ye,cS as k,dm as xe,d2 as he,dn as qe,cX as Xe,dp as Ke,dq as Qe,dr as We,s as Je,u as pe,i as fe,ds as oe,A as L,K as J,a as I,L as _,B as C,dt as Ze,D as V,x as z,y as G,z as U,H as Y,C as je,e as M,bS as es,ab as ss,du as ts,f as E,O as ns,dv as rs,U as as,aP as os,T as ls,P as is,Q as le,R as ie,dw as cs,ag as ds,I as ge,dx as se,dy as ms,dz as ve,bB as us,dA as xs,dB as hs,dC as ps}from"./index-B5hLclEq.js";import{P as fs}from"./page-title-BkqlUA0j.js";import{P as js}from"./PersonCombobox-D350WlrJ.js";import{C as q,d as X,a as ye}from"./card-UDyMRcps.js";import{R as gs,S as we,a as Ne,b as Ce,c as be,d as Te}from"./select-DrL0mpRN.js";import{R as Pe}from"./refresh-cw-CsCtmWwX.js";import{T as vs}from"./triangle-alert-CsYGyfGZ.js";import{T as Ee}from"./trash-2-B4hRXo-p.js";import{C as Se}from"./circle-check-CSkZUEFK.js";import{C as Re}from"./circle-x-in2o3aHU.js";import{X as ys}from"./x-qxt1WrUi.js";import{U as ws}from"./user-plus-4CTYEkd3.js";var Ns=Symbol("radix.slottable");function Cs(s){const n=({children:t})=>e.jsx(e.Fragment,{children:t});return n.displayName=`${s}.Slottable`,n.__radixId=Ns,n}var[K]=Xe("Tooltip",[xe]),Q=xe(),ke="TooltipProvider",bs=700,Z="tooltip.open",[Ts,te]=K(ke),Oe=s=>{const{__scopeTooltip:n,delayDuration:t=bs,skipDelayDuration:a=300,disableHoverableContent:r=!1,children:m}=s,u=o.useRef(!0),p=o.useRef(!1),d=o.useRef(0);return o.useEffect(()=>{const f=d.current;return()=>window.clearTimeout(f)},[]),e.jsx(Ts,{scope:n,isOpenDelayedRef:u,delayDuration:t,onOpen:o.useCallback(()=>{window.clearTimeout(d.current),u.current=!1},[]),onClose:o.useCallback(()=>{window.clearTimeout(d.current),d.current=window.setTimeout(()=>u.current=!0,a)},[a]),isPointerInTransitRef:p,onPointerInTransitChange:o.useCallback(f=>{p.current=f},[]),disableHoverableContent:r,children:m})};Oe.displayName=ke;var H="Tooltip",[Ps,F]=K(H),Ae=s=>{const{__scopeTooltip:n,children:t,open:a,defaultOpen:r,onOpenChange:m,disableHoverableContent:u,delayDuration:p}=s,d=te(H,s.__scopeTooltip),f=Q(n),[l,h]=o.useState(null),i=Ve(),c=o.useRef(0),j=u??d.disableHoverableContent,g=p??d.delayDuration,v=o.useRef(!1),[y,w]=ze({prop:a,defaultProp:r??!1,onChange:b=>{b?(d.onOpen(),document.dispatchEvent(new CustomEvent(Z))):d.onClose(),m==null||m(b)},caller:H}),T=o.useMemo(()=>y?v.current?"delayed-open":"instant-open":"closed",[y]),P=o.useCallback(()=>{window.clearTimeout(c.current),c.current=0,v.current=!1,w(!0)},[w]),x=o.useCallback(()=>{window.clearTimeout(c.current),c.current=0,w(!1)},[w]),S=o.useCallback(()=>{window.clearTimeout(c.current),c.current=window.setTimeout(()=>{v.current=!0,w(!0),c.current=0},g)},[g,w]);return o.useEffect(()=>()=>{c.current&&(window.clearTimeout(c.current),c.current=0)},[]),e.jsx(Ge,{...f,children:e.jsx(Ps,{scope:n,contentId:i,open:y,stateAttribute:T,trigger:l,onTriggerChange:h,onTriggerEnter:o.useCallback(()=>{d.isOpenDelayedRef.current?S():P()},[d.isOpenDelayedRef,S,P]),onTriggerLeave:o.useCallback(()=>{j?x():(window.clearTimeout(c.current),c.current=0)},[x,j]),onOpen:P,onClose:x,disableHoverableContent:j,children:t})})};Ae.displayName=H;var ee="TooltipTrigger",_e=o.forwardRef((s,n)=>{const{__scopeTooltip:t,...a}=s,r=F(ee,t),m=te(ee,t),u=Q(t),p=o.useRef(null),d=ue(n,p,r.onTriggerChange),f=o.useRef(!1),l=o.useRef(!1),h=o.useCallback(()=>f.current=!1,[]);return o.useEffect(()=>()=>document.removeEventListener("pointerup",h),[h]),e.jsx(Ue,{asChild:!0,...u,children:e.jsx(Ye.button,{"aria-describedby":r.open?r.contentId:void 0,"data-state":r.stateAttribute,...a,ref:d,onPointerMove:k(s.onPointerMove,i=>{i.pointerType!=="touch"&&!l.current&&!m.isPointerInTransitRef.current&&(r.onTriggerEnter(),l.current=!0)}),onPointerLeave:k(s.onPointerLeave,()=>{r.onTriggerLeave(),l.current=!1}),onPointerDown:k(s.onPointerDown,()=>{r.open&&r.onClose(),f.current=!0,document.addEventListener("pointerup",h,{once:!0})}),onFocus:k(s.onFocus,()=>{f.current||r.onOpen()}),onBlur:k(s.onBlur,r.onClose),onClick:k(s.onClick,r.onClose)})})});_e.displayName=ee;var ne="TooltipPortal",[Es,Ss]=K(ne,{forceMount:void 0}),De=s=>{const{__scopeTooltip:n,forceMount:t,children:a,container:r}=s,m=F(ne,n);return e.jsx(Es,{scope:n,forceMount:t,children:e.jsx(he,{present:t||m.open,children:e.jsx(qe,{asChild:!0,container:r,children:a})})})};De.displayName=ne;var D="TooltipContent",Le=o.forwardRef((s,n)=>{const t=Ss(D,s.__scopeTooltip),{forceMount:a=t.forceMount,side:r="top",...m}=s,u=F(D,s.__scopeTooltip);return e.jsx(he,{present:a||u.open,children:u.disableHoverableContent?e.jsx(Ie,{side:r,...m,ref:n}):e.jsx(Rs,{side:r,...m,ref:n})})}),Rs=o.forwardRef((s,n)=>{const t=F(D,s.__scopeTooltip),a=te(D,s.__scopeTooltip),r=o.useRef(null),m=ue(n,r),[u,p]=o.useState(null),{trigger:d,onClose:f}=t,l=r.current,{onPointerInTransitChange:h}=a,i=o.useCallback(()=>{p(null),h(!1)},[h]),c=o.useCallback((j,g)=>{const v=j.currentTarget,y={x:j.clientX,y:j.clientY},w=Ds(y,v.getBoundingClientRect()),T=Ls(y,w),P=Is(g.getBoundingClientRect()),x=Hs([...T,...P]);p(x),h(!0)},[h]);return o.useEffect(()=>()=>i(),[i]),o.useEffect(()=>{if(d&&l){const j=v=>c(v,l),g=v=>c(v,d);return d.addEventListener("pointerleave",j),l.addEventListener("pointerleave",g),()=>{d.removeEventListener("pointerleave",j),l.removeEventListener("pointerleave",g)}}},[d,l,c,i]),o.useEffect(()=>{if(u){const j=g=>{const v=g.target,y={x:g.clientX,y:g.clientY},w=(d==null?void 0:d.contains(v))||(l==null?void 0:l.contains(v)),T=!Ms(y,u);w?i():T&&(i(),f())};return document.addEventListener("pointermove",j),()=>document.removeEventListener("pointermove",j)}},[d,l,u,f,i]),e.jsx(Ie,{...s,ref:m})}),[ks,Os]=K(H,{isInside:!1}),As=Cs("TooltipContent"),Ie=o.forwardRef((s,n)=>{const{__scopeTooltip:t,children:a,"aria-label":r,onEscapeKeyDown:m,onPointerDownOutside:u,...p}=s,d=F(D,t),f=Q(t),{onClose:l}=d;return o.useEffect(()=>(document.addEventListener(Z,l),()=>document.removeEventListener(Z,l)),[l]),o.useEffect(()=>{if(d.trigger){const h=i=>{const c=i.target;c!=null&&c.contains(d.trigger)&&l()};return window.addEventListener("scroll",h,{capture:!0}),()=>window.removeEventListener("scroll",h,{capture:!0})}},[d.trigger,l]),e.jsx(Ke,{asChild:!0,disableOutsidePointerEvents:!1,onEscapeKeyDown:m,onPointerDownOutside:u,onFocusOutside:h=>h.preventDefault(),onDismiss:l,children:e.jsxs(Qe,{"data-state":d.stateAttribute,...f,...p,ref:n,style:{...p.style,"--radix-tooltip-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-tooltip-content-available-width":"var(--radix-popper-available-width)","--radix-tooltip-content-available-height":"var(--radix-popper-available-height)","--radix-tooltip-trigger-width":"var(--radix-popper-anchor-width)","--radix-tooltip-trigger-height":"var(--radix-popper-anchor-height)"},children:[e.jsx(As,{children:a}),e.jsx(ks,{scope:t,isInside:!0,children:e.jsx(gs,{id:d.contentId,role:"tooltip",children:r||a})})]})})});Le.displayName=D;var Me="TooltipArrow",_s=o.forwardRef((s,n)=>{const{__scopeTooltip:t,...a}=s,r=Q(t);return Os(Me,t).isInside?null:e.jsx(We,{...r,...a,ref:n})});_s.displayName=Me;function Ds(s,n){const t=Math.abs(n.top-s.y),a=Math.abs(n.bottom-s.y),r=Math.abs(n.right-s.x),m=Math.abs(n.left-s.x);switch(Math.min(t,a,r,m)){case m:return"left";case r:return"right";case t:return"top";case a:return"bottom";default:throw new Error("unreachable")}}function Ls(s,n,t=5){const a=[];switch(n){case"top":a.push({x:s.x-t,y:s.y+t},{x:s.x+t,y:s.y+t});break;case"bottom":a.push({x:s.x-t,y:s.y-t},{x:s.x+t,y:s.y-t});break;case"left":a.push({x:s.x+t,y:s.y-t},{x:s.x+t,y:s.y+t});break;case"right":a.push({x:s.x-t,y:s.y-t},{x:s.x-t,y:s.y+t});break}return a}function Is(s){const{top:n,right:t,bottom:a,left:r}=s;return[{x:r,y:n},{x:t,y:n},{x:t,y:a},{x:r,y:a}]}function Ms(s,n){const{x:t,y:a}=s;let r=!1;for(let m=0,u=n.length-1;m<n.length;u=m++){const p=n[m],d=n[u],f=p.x,l=p.y,h=d.x,i=d.y;l>a!=i>a&&t<(h-f)*(a-l)/(i-l)+f&&(r=!r)}return r}function Hs(s){const n=s.slice();return n.sort((t,a)=>t.x<a.x?-1:t.x>a.x?1:t.y<a.y?-1:t.y>a.y?1:0),$s(n)}function $s(s){if(s.length<=1)return s.slice();const n=[];for(let a=0;a<s.length;a++){const r=s[a];for(;n.length>=2;){const m=n[n.length-1],u=n[n.length-2];if((m.x-u.x)*(r.y-u.y)>=(m.y-u.y)*(r.x-u.x))n.pop();else break}n.push(r)}n.pop();const t=[];for(let a=s.length-1;a>=0;a--){const r=s[a];for(;t.length>=2;){const m=t[t.length-1],u=t[t.length-2];if((m.x-u.x)*(r.y-u.y)>=(m.y-u.y)*(r.x-u.x))t.pop();else break}t.push(r)}return t.pop(),n.length===1&&t.length===1&&n[0].x===t[0].x&&n[0].y===t[0].y?n:n.concat(t)}var Fs=Oe,Bs=Ae,Vs=_e,zs=De,He=Le;const Gs=({children:s,delayDuration:n=0})=>e.jsx(Fs,{delayDuration:n,children:s}),O=Bs,A=Vs,R=o.forwardRef(({className:s,sideOffset:n=4,...t},a)=>e.jsx(zs,{children:e.jsx(He,{ref:a,sideOffset:n,className:Je("z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",s),...t})}));R.displayName=He.displayName;const Us={Owner:"Admin",Editor:"Editor",Viewer:"Viewer",User:"Viewer"},ce=s=>Us[s]??"Viewer";function Ys({localTeams:s,onImported:n}){const[t,a]=o.useState([]),r=pe(),[m,u]=o.useState(!0),[p,d]=o.useState(null),[f,l]=o.useState(!1),[h,i]=o.useState(null),[c,j]=o.useState(null),[g,v]=o.useState(null),y=new Map(s.filter(x=>x.source==="promptowl"&&x.external_id).map(x=>[x.external_id,x]));o.useEffect(()=>{w()},[]);const w=async()=>{u(!0),d(null);try{const x=await r.fetchQuery(fe.promptowlTeams());a(x.teams)}catch(x){oe(x)?l(!0):d((x==null?void 0:x.message)||"Could not reach PromptOwl")}finally{u(!1)}},T=async x=>{var S;i(x.id),d(null);try{const b=await ts([x.id]);v(b.results[0]??null),n(),E.success((S=b.results[0])!=null&&S.created?`Imported ${x.name}`:`Synced ${x.name}`)}catch(b){oe(b)?l(!0):d((b==null?void 0:b.message)||"Sync failed")}finally{i(null),j(null)}},P=x=>{y.has(x.id)?j(x):T(x)};return f?e.jsxs(L,{children:[e.jsx(J,{className:"h-4 w-4"}),e.jsx(I,{children:"Your PromptOwl session has ended. Sign out and sign back in with PromptOwl to import teams."})]}):m?e.jsx("div",{className:"flex justify-center py-12",children:e.jsx(_,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):e.jsxs("div",{className:"space-y-4",children:[p&&e.jsxs(L,{variant:"destructive",children:[e.jsx(J,{className:"h-4 w-4"}),e.jsx(I,{children:p})]}),e.jsxs("div",{className:"flex items-start gap-3",children:[e.jsx("p",{className:"text-sm text-muted-foreground flex-1",children:"Your PromptOwl teams. Syncing one copies it here with its members — people without an account are invited automatically. Teams you're view-only on can't be imported, since the copy would be yours to control."}),e.jsx(C,{size:"sm",variant:"ghost",onClick:w,"aria-label":"Refresh",children:e.jsx(Pe,{className:"h-4 w-4"})})]}),g&&e.jsx(Xs,{result:g}),t.length===0?e.jsx(q,{children:e.jsx(X,{className:"py-10 text-center text-sm text-muted-foreground",children:"You're not in any teams in PromptOwl."})}):e.jsx("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-3",children:t.map(x=>e.jsx(qs,{team:x,imported:y.has(x.id),syncing:h===x.id,canImport:Ze(x),onSync:()=>P(x)},x.id))}),e.jsx(V,{open:!!c,onOpenChange:x=>!x&&j(null),children:e.jsxs(z,{className:"sm:max-w-[460px]",children:[e.jsx(G,{children:e.jsxs(U,{children:['Sync "',c==null?void 0:c.name,'" from PromptOwl?']})}),e.jsxs(L,{children:[e.jsx(vs,{className:"h-4 w-4"}),e.jsx(I,{className:"text-xs",children:"PromptOwl is the source of truth. This team's roster here will be made to match PromptOwl exactly: roles are reset, and anyone you added by hand in ContextNest is removed."})]}),e.jsxs(Y,{children:[e.jsx(C,{variant:"outline",onClick:()=>j(null),children:"Cancel"}),e.jsxs(C,{disabled:!!h,onClick:()=>c&&T(c),children:[h&&e.jsx(_,{className:"h-4 w-4 mr-1 animate-spin"}),"Sync"]})]})]})})]})}function qs({team:s,imported:n,syncing:t,canImport:a,onSync:r}){return e.jsxs(q,{className:`flex flex-col${a?"":" opacity-70"}`,children:[e.jsx(ye,{className:"space-y-1 pb-3",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"font-semibold truncate",children:s.name}),e.jsx(M,{variant:"secondary",className:"shrink-0",children:s.members.length}),n&&e.jsxs(O,{children:[e.jsx(A,{asChild:!0,children:e.jsxs(M,{variant:"outline",className:"shrink-0 gap-1",children:[e.jsx(je,{className:"h-3 w-3"}),"Synced"]})}),e.jsx(R,{children:"Already imported. Syncing again updates it in place."})]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground truncate",children:["You're ",s.your_role," in PromptOwl",s.enterprise?` · ${s.enterprise.name}`:""]})]}),a?e.jsxs(C,{size:"sm",variant:n?"outline":"default",className:"shrink-0",disabled:t,onClick:r,children:[t?e.jsx(_,{className:"h-3.5 w-3.5 animate-spin"}):n?e.jsx(Pe,{className:"h-3.5 w-3.5"}):e.jsx(es,{className:"h-3.5 w-3.5"}),e.jsx("span",{className:"ml-1",children:n?"Sync":"Import"})]}):e.jsxs(O,{children:[e.jsx(A,{asChild:!0,children:e.jsxs("span",{className:"shrink-0 inline-flex items-center gap-1 text-xs text-muted-foreground border rounded-md px-2 py-1.5",children:[e.jsx(ss,{className:"h-3 w-3"}),"View-only"]})}),e.jsx(R,{className:"max-w-xs",children:"Importing a team makes you the owner of the copy here, which is more than you can do with this team in PromptOwl. Ask an owner or editor of it to import it."})]})]})}),e.jsx(X,{className:"space-y-1.5",children:s.members.length===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"No members."}):s.members.map(m=>e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{className:"flex-1 truncate",children:m.email}),e.jsxs(O,{children:[e.jsx(A,{asChild:!0,children:e.jsx("span",{className:"text-xs text-muted-foreground shrink-0",children:ce(m.role)})}),e.jsxs(R,{children:[m.role," in PromptOwl → ",ce(m.role)," here"]})]})]},m.email))})]})}function Xs({result:s}){const n=!s.added.length&&!s.updated.length&&!s.removed.length;return e.jsxs(L,{children:[e.jsx(je,{className:"h-4 w-4"}),e.jsxs(I,{className:"text-xs space-y-0.5",children:[e.jsxs("div",{className:"font-medium",children:[s.name," — ",s.created?"imported":"synced"]}),n?e.jsx("div",{children:"Already up to date."}):e.jsxs(e.Fragment,{children:[s.added.length>0&&e.jsxs("div",{children:["Added: ",s.added.join(", ")]}),s.updated.length>0&&e.jsxs("div",{children:["Role changed: ",s.updated.join(", ")]}),s.removed.length>0&&e.jsxs("div",{children:["Removed: ",s.removed.join(", ")]})]})]})]})}const de=5,W=s=>{var n;return((n=se.find(t=>t.value===s))==null?void 0:n.label)??s},$={viewer:1,editor:2,admin:3},B=4;function me(s,n,t){if(t||s.owner_email&&s.owner_email.toLowerCase()===n)return B;const a=s.members.find(r=>(r.email||"").toLowerCase()===n);return a?$[a.role]??0:0}function mt(){var re;const{adminStatus:s,isAdmin:n,promptowlTeamsEnabled:t}=ns(),a=(((re=s==null?void 0:s.me)==null?void 0:re.email)||"").toLowerCase(),[r]=o.useState(()=>rs()),m=t&&r,[u,p]=o.useState([]),[d,f]=o.useState(!0),l=pe(),[h,i]=o.useState(null),[c,j]=o.useState(!1),[g,v]=o.useState(null),[y,w]=o.useState(null),[T,P]=o.useState(!1),x=async()=>{i(null);try{const N=await l.fetchQuery(fe.teamList());p(N.teams),v(ae=>ae?N.teams.find(Be=>Be.id===ae.id)??null:null)}catch(N){i((N==null?void 0:N.message)||"Failed to load teams")}finally{f(!1)}};o.useEffect(()=>{x()},[]);const S=async()=>{if(y){P(!0);try{await cs(y.id),E.success("Team deleted"),w(null),await x()}catch(N){E.error((N==null?void 0:N.message)||"Failed to delete team")}finally{P(!1)}}},b=d?e.jsx("div",{className:"flex justify-center py-12",children:e.jsx(_,{className:"h-6 w-6 animate-spin text-muted-foreground"})}):u.length===0?e.jsx(q,{children:e.jsx(X,{className:"py-10 text-center text-sm text-muted-foreground",children:"No teams yet. Create one to share a nest with a whole group at once."})}):e.jsx("div",{className:"grid gap-4 sm:grid-cols-2 lg:grid-cols-3",children:u.map(N=>e.jsx(Qs,{team:N,rank:me(N,a,n),onEdit:()=>v(N),onDelete:()=>w(N)},N.id))});return e.jsxs(Gs,{delayDuration:150,children:[e.jsxs("div",{className:"w-full mx-auto space-y-4",children:[e.jsx(fs,{icon:as,title:"Teams",description:e.jsxs(e.Fragment,{children:["A team is a reusable group. Give each member a role, then share the team with a nest from its ",e.jsx("strong",{children:"Share"})," dialog — every member gets their role on that nest."]}),actions:e.jsxs(C,{size:"sm",onClick:()=>j(!0),children:[e.jsx(os,{className:"h-4 w-4 mr-1"}),"New Team"]})}),h&&e.jsxs(L,{variant:"destructive",children:[e.jsx(J,{className:"h-4 w-4"}),e.jsx(I,{children:h})]}),m?e.jsxs(ls,{defaultValue:"cn",children:[e.jsxs(is,{children:[e.jsx(le,{value:"cn",children:"ContextNest Teams"}),e.jsx(le,{value:"po",children:"PromptOwl Teams"})]}),e.jsx(ie,{value:"cn",className:"mt-4",children:b}),e.jsx(ie,{value:"po",className:"mt-4",children:e.jsx(Ys,{localTeams:u,onImported:x})})]}):b]}),c&&e.jsx(Ws,{onClose:()=>j(!1),onCreated:x}),g&&e.jsx(Js,{team:g,rank:me(g,a,n),onClose:()=>v(null),onChanged:x}),e.jsx(V,{open:!!y,onOpenChange:N=>!N&&w(null),children:e.jsxs(z,{className:"sm:max-w-[420px]",children:[e.jsx(G,{children:e.jsxs(U,{children:['Delete team "',y==null?void 0:y.name,'"?']})}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Members lose access to every nest this team is shared with. This can't be undone."}),e.jsxs(Y,{children:[e.jsx(C,{variant:"outline",onClick:()=>w(null),children:"Cancel"}),e.jsxs(C,{variant:"destructive",disabled:T,onClick:S,children:[T&&e.jsx(_,{className:"h-4 w-4 mr-1 animate-spin"}),"Delete"]})]})]})})]})}function $e({registered:s}){return e.jsxs(O,{children:[e.jsx(A,{asChild:!0,children:e.jsx("span",{className:"shrink-0 flex items-center",children:s?e.jsx(Se,{className:"h-3.5 w-3.5 text-green-600"}):e.jsx(Re,{className:"h-3.5 w-3.5 text-red-500"})})}),e.jsx(R,{children:s?"Registered account":"Invited — hasn't signed up yet"})]})}function Ks({member:s}){return e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx($e,{registered:s.registered}),e.jsx("span",{className:"flex-1 truncate",children:s.email}),e.jsx("span",{className:"text-xs text-muted-foreground shrink-0",children:W(s.role)})]})}function Qs({team:s,rank:n,onEdit:t,onDelete:a}){const r=s.members.slice(0,de),m=s.members.slice(de),u=n>=$.editor,p=n>=B;return e.jsxs(q,{className:"flex flex-col",children:[e.jsx(ye,{className:"space-y-1 pb-3",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"font-semibold truncate",children:s.name}),e.jsx(M,{variant:"secondary",className:"shrink-0",children:s.members.length}),s.source==="promptowl"&&e.jsxs(O,{children:[e.jsx(A,{asChild:!0,children:e.jsx(M,{variant:"outline",className:"shrink-0",children:"PromptOwl"})}),e.jsx(R,{children:"Imported from PromptOwl. Re-syncing makes this roster match PromptOwl exactly."})]})]}),s.owner_email&&e.jsxs("p",{className:"text-xs text-muted-foreground truncate",children:["Created by ",s.owner_email]})]}),e.jsxs("div",{className:"flex items-center gap-0.5 shrink-0",children:[u&&e.jsx(C,{size:"icon",variant:"ghost",className:"h-7 w-7",onClick:t,"aria-label":"Edit team",children:e.jsx(ds,{className:"h-3.5 w-3.5"})}),p&&e.jsx(C,{size:"icon",variant:"ghost",className:"h-7 w-7 text-destructive",onClick:a,"aria-label":"Delete team",children:e.jsx(Ee,{className:"h-3.5 w-3.5"})})]})]})}),e.jsx(X,{className:"space-y-1.5",children:s.members.length===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"No members yet."}):e.jsxs(e.Fragment,{children:[r.map(d=>e.jsx(Ks,{member:d},d.userId)),m.length>0&&e.jsxs(O,{children:[e.jsx(A,{asChild:!0,children:e.jsxs("button",{className:"text-xs text-muted-foreground hover:text-foreground text-left",children:["+",m.length," more member",m.length===1?"":"s"]})}),e.jsx(R,{className:"max-w-xs",children:e.jsx("div",{className:"space-y-1",children:m.map(d=>e.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[d.registered?e.jsx(Se,{className:"h-3 w-3 text-green-600 shrink-0"}):e.jsx(Re,{className:"h-3 w-3 text-red-500 shrink-0"}),e.jsx("span",{className:"truncate",children:d.email}),e.jsxs("span",{className:"opacity-70",children:["· ",W(d.role)]})]},d.userId))})})]})]})})]})}function Fe({onAdd:s,busy:n,maxRank:t=B,members:a=[]}){var i;const r=se.filter(c=>$[c.value]<=t),[m,u]=o.useState(""),[p,d]=o.useState(((i=r[0])==null?void 0:i.value)??"viewer"),[f,l]=o.useState(null),h=()=>{const c=m.trim();if(c){if(!us(c)){l("Enter a valid email address.");return}l(null),Promise.resolve(s(c,p)).then(()=>{var j;u(""),d(((j=r[0])==null?void 0:j.value)??"viewer")})}};return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex flex-col sm:flex-row items-stretch sm:items-center gap-2",children:[e.jsx(js,{value:m,onChange:c=>{u(c),f&&l(null)},onSubmit:h,placeholder:"person@company.com",exclude:a,className:"flex-1",testId:"team-member-input"}),e.jsxs(we,{value:p,onValueChange:c=>d(c),children:[e.jsx(Ne,{className:"w-full sm:w-[130px] h-8",children:e.jsx(Ce,{})}),e.jsx(be,{children:r.map(c=>e.jsx(Te,{value:c.value,children:c.label},c.value))})]}),e.jsxs(C,{size:"sm",onClick:h,disabled:n||!m.trim(),children:[e.jsx(ws,{className:"h-4 w-4 mr-1"}),"Add"]})]}),f&&e.jsx("p",{className:"text-xs text-destructive",children:f})]})}function Ws({onClose:s,onCreated:n}){const[t,a]=o.useState(""),[r,m]=o.useState([]),[u,p]=o.useState(!1),d=(l,h)=>{if(r.some(i=>i.email.toLowerCase()===l.toLowerCase())){E.error("Already added");return}m(i=>[...i,{email:l,role:h}])},f=async()=>{const l=t.trim();if(l){p(!0);try{const{team:h}=await ms(l);for(const i of r)try{await ve(h.id,{email:i.email,role:i.role})}catch(c){E.error(`${i.email}: ${(c==null?void 0:c.message)||"could not add"}`)}E.success(`Team "${l}" created`),n(),s()}catch(h){E.error((h==null?void 0:h.message)||"Failed to create team")}finally{p(!1)}}};return e.jsx(V,{open:!0,onOpenChange:l=>!l&&s(),children:e.jsxs(z,{className:"sm:max-w-[480px]",children:[e.jsx(G,{children:e.jsx(U,{children:"New team"})}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(ge,{autoFocus:!0,placeholder:"Team name (e.g. Platform)",value:t,onChange:l=>a(l.target.value)}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs font-medium text-muted-foreground",children:"Members (optional)"}),r.length>0&&e.jsx("div",{className:"space-y-1.5",children:r.map(l=>e.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[e.jsx("span",{className:"flex-1 truncate",children:l.email}),e.jsx("span",{className:"text-xs text-muted-foreground",children:W(l.role)}),e.jsx(C,{size:"icon",variant:"ghost",className:"h-6 w-6",onClick:()=>m(h=>h.filter(i=>i.email!==l.email)),"aria-label":`Remove ${l.email}`,children:e.jsx(ys,{className:"h-3.5 w-3.5"})})]},l.email))}),e.jsx(Fe,{onAdd:d,members:r.map(l=>l.email)})]})]}),e.jsxs(Y,{children:[e.jsx(C,{variant:"outline",onClick:s,children:"Cancel"}),e.jsxs(C,{onClick:f,disabled:u||!t.trim(),children:[u&&e.jsx(_,{className:"h-4 w-4 mr-1 animate-spin"}),"Create"]})]})]})})}function Js({team:s,rank:n,onClose:t,onChanged:a}){const r=n>=$.admin,m=n>=$.editor,[u,p]=o.useState(s.name),[d,f]=o.useState(!1),l=async(i,c)=>{f(!0);try{await i(),c&&E.success(c),a()}catch(j){E.error((j==null?void 0:j.message)||"Something went wrong")}finally{f(!1)}},h=async()=>{if(!r)return;const i=u.trim();!i||i===s.name||await l(()=>xs(s.id,i),"Team renamed")};return e.jsx(V,{open:!0,onOpenChange:i=>!i&&t(),children:e.jsxs(z,{className:"sm:max-w-[480px]",children:[e.jsx(G,{children:e.jsx(U,{children:"Edit team"})}),e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(ge,{value:u,onChange:i=>p(i.target.value),onBlur:h,onKeyDown:i=>i.key==="Enter"&&h(),className:"h-9",disabled:!r})}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs font-medium text-muted-foreground",children:"Members"}),s.members.length===0?e.jsx("p",{className:"text-xs text-muted-foreground",children:"No members yet."}):e.jsx("div",{className:"space-y-2",children:s.members.map(i=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx($e,{registered:i.registered}),e.jsx("span",{className:"text-sm flex-1 truncate",children:i.email}),r?e.jsxs(we,{value:i.role,onValueChange:c=>l(()=>hs(s.id,i.userId,c),"Role updated"),children:[e.jsx(Ne,{className:"w-[120px] h-8",children:e.jsx(Ce,{})}),e.jsx(be,{children:se.map(c=>e.jsx(Te,{value:c.value,children:c.label},c.value))})]}):e.jsx(M,{variant:"secondary",className:"text-[11px]",children:W(i.role)}),r&&e.jsx(C,{size:"icon",variant:"ghost",className:"h-8 w-8",disabled:d,onClick:()=>l(()=>ps(s.id,i.userId),"Member removed"),"aria-label":`Remove ${i.email}`,children:e.jsx(Ee,{className:"h-3.5 w-3.5"})})]},i.userId))}),m&&e.jsx("div",{className:"pt-1 border-t",children:e.jsx("div",{className:"pt-2",children:e.jsx(Fe,{busy:d,maxRank:n,members:s.members.map(i=>i.email),onAdd:(i,c)=>l(()=>ve(s.id,{email:i,role:c}),"Member added")})})})]})]}),e.jsx(Y,{children:e.jsx(C,{variant:"outline",onClick:t,children:"Done"})})]})})}export{mt as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as t}from"./index-B5hLclEq.js";import{ActivityTracePage as r}from"./ActivityTracePage-D2iIbEph.js";import"./page-title-BkqlUA0j.js";import"./select-DrL0mpRN.js";import"./dates-BCxbm4_q.js";import"./client-attribution-BraarYaP.js";import"./arrow-left-BAgIocLn.js";import"./refresh-cw-CsCtmWwX.js";import"./chevron-left-XR4ReJ9Z.js";function f(){return t.jsx(r,{})}export{f as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r,j as e,D as P,x as D,y as A,z as T,c8 as F,G as z,I as b,H as R,B as h,c9 as H,E as I,ca as B,f as k,O,cb as Y,cc as K,cd as U,e as G,bs as L,ce as W}from"./index-B5hLclEq.js";import{P as q}from"./page-title-BkqlUA0j.js";function S({shown:n,onToggle:c}){return e.jsx("button",{type:"button",onClick:c,tabIndex:-1,"aria-label":n?"Hide password":"Show password",title:n?"Hide password":"Show password",className:"absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",children:n?e.jsx(H,{className:"h-4 w-4"}):e.jsx(I,{className:"h-4 w-4"})})}function J({open:n,onClose:c}){const[u,l]=r.useState(""),[a,m]=r.useState(""),[t,x]=r.useState(""),[d,p]=r.useState(!1),[j,i]=r.useState(null),[N,v]=r.useState(!1),[w,g]=r.useState(!1),[f,o]=r.useState(!1),C=()=>{l(""),m(""),x(""),i(null),v(!1),g(!1),o(!1)},E=async()=>{if(i(null),a.trim().length===0){i("New password cannot be empty or only whitespace.");return}if(a.length<8){i("New password must be at least 8 characters.");return}if(a!==t){i("New passwords don't match.");return}if(a===u){i("New password must be different from the current password.");return}p(!0);try{await B(u,a),k.success("Password changed. Your other sessions were signed out."),C(),c()}catch(s){i((s==null?void 0:s.message)||"Could not change password.")}finally{p(!1)}};return e.jsx(P,{open:n,onOpenChange:s=>{!s&&!d&&(C(),c())},children:e.jsxs(D,{className:"sm:max-w-[400px]",children:[e.jsxs(A,{children:[e.jsxs(T,{className:"flex items-center gap-2",children:[e.jsx(F,{className:"h-4 w-4 text-muted-foreground"}),"Change password"]}),e.jsx(z,{children:"If an admin gave you a temporary password, set your own here. This signs out your other sessions."})]}),e.jsxs("div",{className:"space-y-3 py-1",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{htmlFor:"cp-current",className:"block text-sm font-medium",children:"Current password"}),e.jsxs("div",{className:"relative",children:[e.jsx(b,{id:"cp-current",type:N?"text":"password",placeholder:"Enter your current password",value:u,onChange:s=>l(s.target.value),autoComplete:"current-password",className:"pr-10"}),e.jsx(S,{shown:N,onToggle:()=>v(s=>!s)})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{htmlFor:"cp-next",className:"block text-sm font-medium",children:"New password"}),e.jsxs("div",{className:"relative",children:[e.jsx(b,{id:"cp-next",type:w?"text":"password",placeholder:"At least 8 characters",value:a,onChange:s=>m(s.target.value),autoComplete:"new-password",className:"pr-10"}),e.jsx(S,{shown:w,onToggle:()=>g(s=>!s)})]})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx("label",{htmlFor:"cp-confirm",className:"block text-sm font-medium",children:"Confirm new password"}),e.jsxs("div",{className:"relative",children:[e.jsx(b,{id:"cp-confirm",type:f?"text":"password",placeholder:"Re-enter your new password",value:t,onChange:s=>x(s.target.value),autoComplete:"new-password","aria-invalid":t.length>0&&t!==a,className:"pr-10"}),e.jsx(S,{shown:f,onToggle:()=>o(s=>!s)})]}),t.length>0&&t!==a&&e.jsx("p",{className:"text-sm text-destructive",children:"Passwords don't match."})]}),j&&e.jsx("p",{className:"text-sm text-destructive",children:j})]}),e.jsxs(R,{className:"gap-2",children:[e.jsx(h,{variant:"outline",onClick:()=>{C(),c()},disabled:d,children:"Cancel"}),e.jsx(h,{onClick:E,disabled:d||!u||!a||!t||a!==t,children:d?"Saving...":"Change password"})]})]})})}function V(){var g,f;const{adminStatus:n,isAdmin:c,refresh:u}=O(),l=(n==null?void 0:n.me)??null,[a,m]=r.useState(!1),[t,x]=r.useState(""),[d,p]=r.useState(!1),[j,i]=r.useState(!1);if(!l)return e.jsx("div",{className:"py-12 text-center text-muted-foreground",children:"Sign in to see your account."});const N=((g=l.name)==null?void 0:g.trim())||l.email,v=()=>{x(l.name??""),m(!0)},w=async()=>{p(!0);try{await W(t),await u(),k.success("Name updated."),m(!1)}catch(o){k.error((o==null?void 0:o.message)||"Could not update name.")}finally{p(!1)}};return e.jsxs("div",{"data-testid":"account-page",children:[e.jsx(q,{icon:Y,title:"Your Account",description:"Who you are on this server."}),e.jsx(y,{label:"Profile photo",children:e.jsx(K,{className:"h-20 w-20",children:e.jsx(U,{className:"text-3xl",children:N.charAt(0).toUpperCase()})})}),e.jsx(y,{label:"Name",action:a?null:e.jsx(h,{variant:"outline",size:"sm",onClick:v,"data-testid":"account-edit-name",children:"Edit"}),children:a?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(b,{value:t,"aria-label":"Name",maxLength:80,placeholder:"Your name",autoFocus:!0,onChange:o=>x(o.target.value),onKeyDown:o=>{o.key==="Enter"&&!d&&w(),o.key==="Escape"&&m(!1)},className:"max-w-xs","data-testid":"account-name-input"}),e.jsx(h,{size:"sm",onClick:w,disabled:d||t.trim()===(l.name??"").trim(),children:d?"Saving...":"Save"}),e.jsx(h,{size:"sm",variant:"ghost",onClick:()=>m(!1),disabled:d,children:"Cancel"})]}):e.jsx("span",{className:"text-muted-foreground",children:((f=l.name)==null?void 0:f.trim())||e.jsx("em",{children:"Not set — your email is shown instead"})})}),e.jsx(y,{label:"Email address",children:e.jsxs("span",{className:"flex items-center gap-2 text-muted-foreground",children:[l.email,c&&e.jsxs(G,{variant:"outline",className:"gap-1 border-blue-200 bg-blue-50 text-blue-700 text-[10px] px-1.5 py-0",children:[e.jsx(L,{className:"h-2.5 w-2.5"}),"Admin"]})]})}),e.jsx(y,{label:"Password",action:e.jsx(h,{variant:"outline",size:"sm",onClick:()=>i(!0),"data-testid":"account-change-password",children:"Change password"}),children:e.jsx("span",{className:"tracking-widest text-muted-foreground","aria-hidden":!0,children:"••••••••••••"})}),e.jsx(J,{open:j,onClose:()=>i(!1)})]})}function y({label:n,action:c,children:u}){return e.jsxs("div",{className:"flex items-start justify-between gap-4 border-b border-border py-5",children:[e.jsxs("div",{className:"min-w-0 space-y-2",children:[e.jsx("div",{className:"text-sm font-medium",children:n}),e.jsx("div",{className:"text-sm",children:u})]}),c]})}export{V as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as Ie,O as Re,r as a,u as De,j as e,U as ce,B as t,A as U,K as M,a as O,L as f,I as ve,cc as oe,cd as de,e as Q,bs as me,cl as Ee,df as _e,C as we,ao as ye,at as Ne,D as N,x as b,y as C,z as k,G as S,H as T,dg as Le,dh as Pe,di as Fe,i as he,J as be,dj as ze}from"./index-B5hLclEq.js";import{p as Ge}from"./dates-BCxbm4_q.js";import{P as Ue}from"./page-title-BkqlUA0j.js";import{C as xe,a as ue,c as pe,b as je,d as ge}from"./card-UDyMRcps.js";import{U as fe}from"./user-plus-4CTYEkd3.js";/**
|
|
2
|
+
* @license lucide-react v0.577.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const Me=[["path",{d:"m2 2 20 20",key:"1ooewy"}],["path",{d:"M5 5a1 1 0 0 0-1 1v7c0 5 3.5 7.5 7.67 8.94a1 1 0 0 0 .67.01c2.35-.82 4.48-1.97 5.9-3.71",key:"1jlk70"}],["path",{d:"M9.309 3.652A12.252 12.252 0 0 0 11.24 2.28a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1v7a9.784 9.784 0 0 1-.08 1.264",key:"18rp1v"}]],Oe=Ie("shield-off",Me);function Je(){var ie,le;const{adminStatus:o}=Re(),c=((le=(ie=o==null?void 0:o.me)==null?void 0:ie.email)==null?void 0:le.toLowerCase())??null,[d,l]=a.useState([]),m=De(),[h,A]=a.useState(""),[x,I]=a.useState("all"),[R,v]=a.useState([]),[w,Y]=a.useState(!0),[J,D]=a.useState(null),[Ce,E]=a.useState(!1),[ke,H]=a.useState(""),[K,W]=a.useState(null),[i,y]=a.useState(null),[Se,$]=a.useState(!1);a.useEffect(()=>$(!1),[i==null?void 0:i.password]);const[u,_]=a.useState(null),[L,V]=a.useState(!1),[p,P]=a.useState(null),[F,X]=a.useState(!1),[Z,ee]=a.useState(null),[j,z]=a.useState(null),[G,se]=a.useState(!1),[ae,te]=a.useState(null),[re,Te]=a.useState({}),g=async()=>{Y(!0);try{const[s,n]=await Promise.all([m.fetchQuery(he.teammates()),m.fetchQuery(he.superAdmins())]);l(s.teammates),v(s.pending_stewards||[]),Te(Object.fromEntries(n.super_admins.map(r=>[r.email.toLowerCase(),{source:r.source,self:r.self}]))),D(null)}catch(s){D(s.message)}finally{Y(!1)}};a.useEffect(()=>{g()},[]);const q=h.trim().toLowerCase(),ne=d.filter(s=>x==="admin"&&!s.is_admin||x==="normal"&&s.is_admin?!1:q?s.email.toLowerCase().includes(q)||(s.name||"").toLowerCase().includes(q):!0),Ae=s=>{const n=Ge(s);if(!n)return"Never";const r=Date.now()-n.getTime();return r<6e4?"Just now":r<36e5?`${Math.floor(r/6e4)}m ago`:r<864e5?`${Math.floor(r/36e5)}h ago`:r<6048e5?`${Math.floor(r/864e5)}d ago`:n.toLocaleDateString()};return e.jsxs("div",{children:[e.jsx(Ue,{icon:ce,title:"Teammates",description:"Add teammates and manage their access",actions:e.jsxs(t,{onClick:()=>E(!0),children:[e.jsx(fe,{className:"h-4 w-4 mr-2"}),"Invite Teammate"]})}),J&&e.jsxs(U,{variant:"destructive",className:"mb-4",children:[e.jsx(M,{className:"h-4 w-4"}),e.jsx(O,{children:J})]}),e.jsxs(xe,{children:[e.jsxs(ue,{children:[e.jsxs(pe,{className:"text-lg flex items-center gap-2",children:[e.jsx(ce,{className:"h-4 w-4"}),"All Users"]}),e.jsx(je,{children:"Everyone who has access to this community server"})]}),e.jsx(ge,{children:w?e.jsx("div",{className:"flex items-center justify-center py-8",children:e.jsx(f,{className:"h-5 w-5 animate-spin text-muted-foreground"})}):d.length===0?e.jsx("div",{className:"text-center py-8 text-sm text-muted-foreground",children:'No teammates yet. Click "Invite Teammate" to add one.'}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2 mb-3",children:[e.jsx(ve,{value:h,onChange:s=>A(s.target.value),placeholder:"Search by name or email…",className:"h-8 max-w-xs text-sm"}),e.jsx("div",{className:"flex items-center rounded-md border p-0.5 text-xs",children:[["all","All"],["admin","Superadmins"],["normal","Members"]].map(([s,n])=>e.jsx("button",{type:"button",onClick:()=>I(s),className:`px-2.5 py-1 rounded ${x===s?"bg-primary text-primary-foreground":"text-muted-foreground hover:text-foreground"}`,children:n},s))})]}),ne.length===0?e.jsx("div",{className:"text-center py-8 text-sm text-muted-foreground",children:"No users match your filters."}):e.jsx("div",{className:"space-y-2",children:ne.map(s=>{var n,r;return e.jsxs("div",{className:"flex items-center gap-3 p-3 rounded-lg border",children:[e.jsx(oe,{className:"h-9 w-9",children:e.jsx(de,{children:(s.email[0]||"?").toUpperCase()})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium truncate",children:s.name||s.email}),c&&s.email.toLowerCase()===c&&e.jsx(Q,{variant:"outline",className:"border-emerald-200 bg-emerald-50 text-emerald-700",children:"You"}),s.is_admin&&e.jsxs(Q,{variant:"outline",className:"gap-1 border-blue-200 bg-blue-50 text-blue-700",children:[e.jsx(me,{className:"h-3 w-3"}),"Admin"]}),!!s.is_invited&&e.jsx(Q,{variant:"outline",className:"border-amber-200 bg-amber-50 text-amber-700",title:"Added with a temporary password. They can sign in with their email + that password (use Reset password to re-issue one), then change it.",children:"Invited"})]}),e.jsxs("div",{className:"text-xs text-muted-foreground flex items-center gap-3",children:[e.jsx("span",{children:s.email}),e.jsx("span",{children:"·"}),e.jsxs("span",{children:[s.key_count," key",s.key_count!==1?"s":""]}),s.last_active&&e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"·"}),e.jsxs("span",{children:["last active ",Ae(s.last_active)]})]})]})]}),s.is_admin&&((n=re[s.email.toLowerCase()])==null?void 0:n.source)==="granted"&&!((r=re[s.email.toLowerCase()])!=null&&r.self)&&e.jsxs(t,{variant:"outline",size:"sm",className:"text-destructive hover:text-destructive hover:bg-destructive/10",onClick:()=>z(s),title:"Revoke this user's superadmin access",children:[e.jsx(Oe,{className:"h-4 w-4 mr-2"}),"Revoke superadmin"]}),!s.is_admin&&e.jsxs(e.Fragment,{children:[!s.is_invited&&e.jsxs(t,{variant:"outline",size:"sm",onClick:()=>P(s),title:"Grant this user superadmin access",children:[e.jsx(Ee,{className:"h-4 w-4 mr-2"}),"Grant superadmin"]}),e.jsx(t,{variant:"outline",size:"sm",disabled:!!i,onClick:async()=>{y({email:s.email,password:null});try{const B=await _e(s.id);y({email:s.email,password:B.temporary_password||""}),await g()}catch(B){y(null),D(B.message)}},title:"Generate a temporary password to share with this user (no email is sent)",children:"Reset password"}),e.jsx(t,{variant:"outline",size:"sm",className:"text-destructive hover:text-destructive hover:bg-destructive/10",onClick:()=>_(s),title:"Remove this user and revoke all access",children:"Remove"})]})]},s.id)})})]})})]}),R.length>0&&e.jsxs(xe,{className:"mt-4 border-amber-200 bg-amber-50/40",children:[e.jsxs(ue,{children:[e.jsxs(pe,{className:"text-lg flex items-center gap-2",children:[e.jsx(me,{className:"h-4 w-4 text-amber-700"}),"Stewards without server access"]}),e.jsx(je,{children:"These emails are assigned as stewards on one or more nests, but haven't registered to this server yet — they can't log in or approve anything until they claim an account."})]}),e.jsx(ge,{children:e.jsx("div",{className:"space-y-2",children:R.map(s=>e.jsxs("div",{className:"flex items-center gap-3 p-3 rounded-lg border bg-background",children:[e.jsx(oe,{className:"h-9 w-9",children:e.jsx(de,{className:"bg-amber-100 text-amber-800",children:(s[0]||"?").toUpperCase()})}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("span",{className:"font-medium text-sm truncate",children:s}),e.jsx("div",{className:"text-xs text-muted-foreground",children:"Assigned as steward · not registered yet"})]}),e.jsxs(t,{size:"sm",onClick:()=>{H(s),E(!0)},children:[e.jsx(fe,{className:"h-3.5 w-3.5 mr-1"}),"Invite"]})]},s))})})]}),Ce&&e.jsx(He,{seedEmail:ke,onClose:()=>{E(!1),H("")},onCreated:(s,n)=>{E(!1),H(""),W({email:s,password:n}),g()}}),K&&e.jsx(Ke,{email:K.email,password:K.password,onClose:()=>W(null)}),i&&e.jsx("div",{className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",onClick:()=>y(null),children:e.jsxs("div",{className:"w-full max-w-sm rounded-lg border bg-background p-5 shadow-lg",onClick:s=>s.stopPropagation(),children:[e.jsx("h3",{className:"font-semibold mb-1",children:"Temporary password"}),i.password===null?e.jsxs("div",{className:"flex flex-col items-center justify-center gap-3 py-8 text-center",children:[e.jsx(f,{className:"h-6 w-6 animate-spin text-muted-foreground"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:["Generating a temporary password for",e.jsx("br",{}),e.jsx("strong",{className:"text-foreground",children:i.email})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("p",{className:"text-xs text-muted-foreground mb-3",children:["Share this with ",e.jsx("strong",{children:i.email})," directly — no email is sent. They sign in with it, then change it from their account. It won't be shown again. Their existing API keys keep working; revoke a key separately if it may be compromised."]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"flex-1 bg-muted border rounded px-2 py-1.5 text-sm font-mono break-all",children:i.password}),e.jsx(t,{variant:"outline",size:"sm",onClick:async()=>{await Ne(i.password,"Temporary password copied")&&($(!0),setTimeout(()=>$(!1),1500))},children:Se?e.jsxs(e.Fragment,{children:[e.jsx(we,{className:"h-3.5 w-3.5 mr-1 text-green-600"}),"Copied"]}):e.jsxs(e.Fragment,{children:[e.jsx(ye,{className:"h-3.5 w-3.5 mr-1"}),"Copy"]})})]}),e.jsx("div",{className:"mt-4 text-right",children:e.jsx(t,{variant:"outline",size:"sm",onClick:()=>y(null),children:"Done"})})]})]})}),e.jsx(N,{open:!!u,onOpenChange:s=>!s&&!L&&_(null),children:e.jsxs(b,{className:"sm:max-w-[420px]",children:[e.jsxs(C,{children:[e.jsxs(k,{children:["Remove ",u==null?void 0:u.email,"?"]}),e.jsx(S,{children:"This revokes all their access (API keys, sessions, steward + collaborator roles) and deletes the account. This cannot be undone."})]}),e.jsxs(T,{children:[e.jsx(t,{variant:"outline",onClick:()=>_(null),disabled:L,children:"Cancel"}),e.jsx(t,{variant:"destructive",disabled:L,onClick:async()=>{if(u){V(!0);try{await Le(u.id),_(null),await g()}catch(s){D(s.message)}finally{V(!1)}}},children:L?e.jsx(f,{className:"h-4 w-4 animate-spin"}):"Remove"})]})]})}),e.jsx(N,{open:!!p,onOpenChange:s=>!s&&!F&&P(null),children:e.jsxs(b,{className:"sm:max-w-[420px]",children:[e.jsxs(C,{children:[e.jsxs(k,{children:["Grant superadmin to ",p==null?void 0:p.email,"?"]}),e.jsx(S,{children:"They immediately get server-admin access everywhere: every nest, teammate management, and the activity trace. You can revoke this later from this list."})]}),Z&&e.jsxs(U,{variant:"destructive",children:[e.jsx(M,{className:"h-4 w-4"}),e.jsx(O,{children:Z})]}),e.jsxs(T,{children:[e.jsx(t,{variant:"outline",onClick:()=>P(null),disabled:F,children:"Cancel"}),e.jsx(t,{disabled:F,onClick:async()=>{if(p){X(!0),ee(null);try{await Pe(p.email),P(null),await g()}catch(s){ee(s.message)}finally{X(!1)}}},children:F?e.jsx(f,{className:"h-4 w-4 animate-spin"}):"Grant"})]})]})}),e.jsx(N,{open:!!j,onOpenChange:s=>!s&&!G&&z(null),children:e.jsxs(b,{className:"sm:max-w-[420px]",children:[e.jsxs(C,{children:[e.jsxs(k,{children:["Revoke superadmin from ",j==null?void 0:j.email,"?"]}),e.jsx(S,{children:"They immediately lose server-admin access. They keep their account and any nest/collaborator roles granted separately. You can grant superadmin again later."})]}),ae&&e.jsxs(U,{variant:"destructive",children:[e.jsx(M,{className:"h-4 w-4"}),e.jsx(O,{children:ae})]}),e.jsxs(T,{children:[e.jsx(t,{variant:"outline",onClick:()=>z(null),disabled:G,children:"Cancel"}),e.jsx(t,{variant:"destructive",disabled:G,onClick:async()=>{if(j){se(!0),te(null);try{await Fe(j.email),z(null),await g()}catch(s){te(s.message)}finally{se(!1)}}},children:G?e.jsx(f,{className:"h-4 w-4 animate-spin"}):"Revoke"})]})]})})]})}function He({seedEmail:o,onClose:c,onCreated:d}){const[l,m]=a.useState(o||""),[h,A]=a.useState(!1),[x,I]=a.useState(null),R=async v=>{if(v.preventDefault(),!!l.trim()){A(!0),I(null);try{const w=await ze(l);d(l,w.temporary_password)}catch(w){I(w.message),A(!1)}}};return e.jsx(N,{open:!0,onOpenChange:c,children:e.jsxs(b,{className:"sm:max-w-[420px]",children:[e.jsxs(C,{children:[e.jsx(k,{children:"Add Teammate"}),e.jsx(S,{children:"Create a login for a teammate. They get a temporary password to sign in with, then can change it and create their own API key."})]}),e.jsxs("form",{onSubmit:R,className:"space-y-3",children:[x&&e.jsxs(U,{variant:"destructive",children:[e.jsx(M,{className:"h-4 w-4"}),e.jsx(O,{children:x})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsx(be,{children:"Email"}),e.jsx(ve,{type:"email",placeholder:"jane@acme.com",value:l,onChange:v=>m(v.target.value),required:!0,autoFocus:!0})]}),e.jsxs(T,{children:[e.jsx(t,{variant:"outline",type:"button",onClick:c,children:"Cancel"}),e.jsx(t,{type:"submit",disabled:h||!l.trim(),children:h?e.jsx(f,{className:"h-4 w-4 animate-spin"}):"Add teammate"})]})]})]})})}function Ke({email:o,password:c,onClose:d}){const[l,m]=a.useState(!1),h=async()=>{await Ne(c)&&(m(!0),setTimeout(()=>m(!1),1500))};return e.jsx(N,{open:!0,onOpenChange:d,children:e.jsxs(b,{className:"sm:max-w-[520px]",children:[e.jsxs(C,{children:[e.jsxs(k,{children:["Teammate added: ",o]}),e.jsxs(S,{children:["Send them this temporary password via Slack, email, or another secure channel. ",e.jsx("strong",{children:"It won't be shown again."})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(be,{className:"text-xs text-muted-foreground",children:"Temporary password"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("code",{className:"flex-1 bg-muted px-3 py-2 rounded text-xs font-mono break-all",children:c}),e.jsx(t,{size:"sm",variant:"outline",onClick:h,children:l?e.jsx(we,{className:"h-3.5 w-3.5 text-green-600"}):e.jsx(ye,{className:"h-3.5 w-3.5"})})]}),e.jsx("p",{className:"text-xs text-muted-foreground pt-2",children:"They sign in at this server with their email + this password, then can change it under their account and create their own API key for Hootie, Claude Desktop, or the CLI."})]}),e.jsx(T,{children:e.jsx(t,{onClick:d,children:"Done"})})]})})}export{Je as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e,s as l}from"./index-B5hLclEq.js";function x({icon:s,title:r,description:t,actions:a,className:i}){return e.jsxs("div",{className:l("mb-4",i),"data-testid":"page-title",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("h1",{className:"flex items-center gap-2 text-2xl font-semibold tracking-tight",children:[s&&e.jsx(s,{className:"h-6 w-6 shrink-0 text-muted-foreground"}),r]}),a&&e.jsx("div",{className:"ml-auto flex shrink-0 items-center gap-2",children:a})]}),t&&e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:t})]})}export{x as P};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import{c as gt,r,j as e,T as Vt,P as Bt,Q as Ve,R as Be,aY as ft,aZ as vt,a_ as Ue,a$ as jt,b0 as qt,b1 as Je,I as te,B as S,L as J,b2 as Qe,b3 as Ie,b4 as yt,b5 as bt,e as se,b6 as Ut,aP as oe,b7 as Xt,b8 as Gt,b9 as mt,ba as Jt,O as Yt,bb as Zt,bc as Nt,bd as Qt,be as wt,bf as It,bg as es,bh as ts,bi as ss,bj as ns,a2 as as,F as rs,bk as kt,bl as os,bm as _t,at as ls,bn as qe,bo as is,bp as cs,aE as ds,ag as us,aT as ms}from"./index-B5hLclEq.js";import{f as xs}from"./dates-BCxbm4_q.js";import{A as Ye,W as St,T as hs,O as ps}from"./MarkdownEditor-Dfk5uIE5.js";import{S as Ct,a as Et,b as Tt,c as $t,d as et}from"./select-DrL0mpRN.js";import{F as gs,N as We}from"./NestView-DwIagxwJ.js";import{N as fs}from"./NestPageHeader-yOK-OIYZ.js";import{R as st}from"./refresh-cw-CsCtmWwX.js";import{P as At}from"./play-B8xE9j5f.js";import{T as ze}from"./trash-2-B4hRXo-p.js";import{Z as Pt,F as vs}from"./zap-BcsKR0ef.js";import{C as nt}from"./corner-down-right-CuxZWscX.js";import{X as Rt}from"./x-qxt1WrUi.js";import{A as js}from"./arrow-left-BAgIocLn.js";import"./triangle-alert-CsYGyfGZ.js";import"./scroll-area-CbcH6yrZ.js";import"./index-A0_ymcqL.js";import"./chevron-left-XR4ReJ9Z.js";import"./alert-dialog-4SiLKlz8.js";import"./count-skeleton-DBWCDhRy.js";import"./folder-input-BAwK9tFL.js";import"./card-UDyMRcps.js";import"./PersonCombobox-D350WlrJ.js";import"./tag-Br_y1f00.js";import"./user-plus-4CTYEkd3.js";import"./ReviewActions-BXDTDPp1.js";import"./circle-check-CSkZUEFK.js";import"./circle-x-in2o3aHU.js";import"./ReasonDialog-CN3ECAnQ.js";import"./settings-EY4A_DYv.js";/**
|
|
2
|
+
* @license lucide-react v0.577.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const ys=[["path",{d:"M10.268 21a2 2 0 0 0 3.464 0",key:"vwvbt9"}],["path",{d:"M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326",key:"11g9vi"}]],bs=gt("bell",ys);/**
|
|
7
|
+
* @license lucide-react v0.577.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const Ns=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 6v6h4",key:"135r8i"}]],ws=gt("clock-3",Ns),ks=6,xt=46;function _s(s,m){const g=m?`${s} · ${m}`:s,y=g.length>xt?`${g.slice(0,xt-1).trimEnd()}…`:g;return{full:g,short:y,width:y.length*ks+8}}const tt=s=>s==="succeeded"?"default":s==="failed"||s==="cancelled"?"destructive":s==="queued"?"outline":"secondary",Ss=.85,Cs=6;function ht(s){return`${.75+Math.min(s,Cs)*Ss}rem`}const Ae=s=>qe(s)?"queued":s.status,Mt="Created — waiting for a runner to claim it",Es=s=>s==="read"?e.jsx(ds,{className:"h-3.5 w-3.5"}):s==="branch"?e.jsx(Pt,{className:"h-3.5 w-3.5"}):s==="write"?e.jsx(us,{className:"h-3.5 w-3.5"}):s==="notify"?e.jsx(bs,{className:"h-3.5 w-3.5"}):e.jsx("span",{className:"h-3.5 w-3.5"}),Ee=s=>xs(s)||s;function Ts({nestId:s,nestName:m,onBack:g}){const[y,C]=r.useState("canvas");return e.jsxs("div",{children:[e.jsx(fs,{nestName:m,onBack:g}),e.jsxs(Vt,{value:y,onValueChange:C,children:[e.jsxs(Bt,{children:[e.jsx(Ve,{value:"canvas",children:"Canvas"}),e.jsx(Ve,{value:"table",children:"Table"}),e.jsx(Ve,{value:"run",children:"Run"}),e.jsx(Ve,{value:"activity",children:"Activity"})]}),e.jsx(Be,{value:"canvas",className:"mt-4",children:e.jsx(Fs,{nestId:s})}),e.jsx(Be,{value:"table",className:"mt-4",children:e.jsx(As,{nestId:s})}),e.jsx(Be,{value:"run",className:"mt-4",children:e.jsx(Os,{nestId:s})}),e.jsxs(Be,{value:"activity",className:"mt-4 space-y-6",children:[e.jsx(Ks,{nestId:s}),e.jsx(Ds,{nestId:s}),e.jsx(Bs,{nestId:s}),e.jsx(Hs,{nestId:s})]})]})]})}function Ce({type:s}){return s==="agent"?e.jsx(as,{className:"h-3.5 w-3.5 text-violet-500 shrink-0"}):s==="skill"?e.jsx(Pt,{className:"h-3.5 w-3.5 text-blue-500 shrink-0"}):s==="artifact"?e.jsx(gs,{className:"h-3.5 w-3.5 text-amber-500 shrink-0"}):s==="tool"?e.jsx(St,{className:"h-3.5 w-3.5 text-teal-500 shrink-0"}):s==="table"?e.jsx(hs,{className:"h-3.5 w-3.5 text-cyan-500 shrink-0"}):s==="pdf"?e.jsx(vs,{className:"h-3.5 w-3.5 text-rose-500 shrink-0"}):e.jsx(rs,{className:"h-3.5 w-3.5 text-slate-400 shrink-0"})}function $s({edge:s}){if(!s.condition_mode||!s.condition)return e.jsx("span",{className:"rounded-full bg-muted px-2 py-0.5 text-[10px] text-muted-foreground",children:"always"});if(s.condition_mode==="nl")return e.jsxs("span",{className:"rounded-full bg-amber-500/10 text-amber-700 dark:text-amber-300 px-2 py-0.5 text-[10px] italic max-w-[260px] truncate inline-block align-middle",title:`AI judges: "${s.condition}"`,children:["if “",String(s.condition),"”"]});let m="";try{const g=typeof s.condition=="string"?JSON.parse(s.condition):s.condition;m=g&&g.term?`${g.term} ${g.op??""} ${g.value??""}`:JSON.stringify(g)}catch{m=String(s.condition)}return e.jsx("span",{className:"rounded-full bg-blue-500/10 text-blue-700 dark:text-blue-300 px-2 py-0.5 text-[10px] font-mono max-w-[260px] truncate inline-block align-middle",title:`Deterministic check: ${m}`,children:m})}function As({nestId:s}){var ke;const[m,g]=r.useState([]),[y,C]=r.useState([]),[b,j]=r.useState(!0),[k,d]=r.useState(null),[h,E]=r.useState([]),[N,w]=r.useState(""),[x,O]=r.useState(""),[c,L]=r.useState(""),[T,B]=r.useState(""),[D,q]=r.useState(""),[Y,U]=r.useState(""),[i,$]=r.useState(">"),[W,he]=r.useState(""),[ne,de]=r.useState(!1),[ye,pe]=r.useState(!1),X=r.useCallback(async()=>{var n;j(!0);try{const[v,P,z]=await Promise.all([ft(s),vt(s),Ue(s).then(R=>R.nodes).catch(()=>[])]);g(v),C(P),E(z),!c&&P.length&&L(((n=P.find(R=>R.is_flow))==null?void 0:n.name)??P[0].name),d(null)}catch(v){d(v instanceof Error?v.message:"Failed to load edges")}finally{j(!1)}},[s,c]);r.useEffect(()=>{X()},[X]);const le=async()=>{if(!N.trim()||!x.trim()||!c)return;const n=m.find(v=>v.from_node===N.trim()&&v.to_node===x.trim()&&v.type.name===c);if(n){d(`${H(n.from_node)} → ${H(n.to_node)} is already connected with "${c}".`);return}de(!0);try{const v=T==="structured"?{term:Y.trim(),op:i,value:isNaN(Number(W))?W.trim():Number(W)}:T==="nl"?D.trim():null;await kt(s,{from_node:N.trim(),to_node:x.trim(),type:c,condition_mode:T||null,condition:T?v:null}),O(""),q(""),U(""),he(""),B(""),await X()}catch(v){d(v instanceof Error?v.message:"Failed to add edge")}finally{de(!1)}},be=n=>{w(n),pe(!0)},Ne=async n=>{try{await _t(s,n),g(v=>v.filter(P=>P.id!==n))}catch(v){d(v instanceof Error?v.message:"Failed to delete edge")}},we=new Map(h.map(n=>[n.id,n])),H=n=>{var v;return((v=we.get(n))==null?void 0:v.title)||n.replace(/^nodes\//,"")},ae=n=>{var v;return(v=we.get(n))==null?void 0:v.type},re=m.filter(n=>n.type.is_flow),G=m.filter(n=>!n.type.is_flow),Te=(ke=y.find(n=>n.is_flow))==null?void 0:ke.name,Z=new Map;for(const n of re)Z.has(n.from_node)||Z.set(n.from_node,[]),Z.get(n.from_node).push(n);const $e=new Set(re.map(n=>n.to_node)),Q=[...Z.keys()].filter(n=>!$e.has(n)).sort(),I=[...h].sort((n,v)=>{const P=z=>z.type==="agent"?0:z.type==="skill"?1:2;return P(n)-P(v)||String(n.title||n.id).localeCompare(String(v.title||v.id))}),ue=(n,v,P)=>{const z=[];for(const R of Z.get(n)??[])z.push(e.jsxs("div",{className:"flex items-center gap-2 py-1 rounded px-1 -mx-1 hover:bg-muted/40 group",style:{marginLeft:`${v*1.5}rem`},children:[e.jsx(nt,{className:"h-3.5 w-3.5 text-muted-foreground/50 shrink-0"}),e.jsx($s,{edge:R}),e.jsx(Ye,{className:"h-3 w-3 text-muted-foreground/50 shrink-0"}),e.jsx(Ce,{type:ae(R.to_node)}),e.jsx("span",{className:"text-sm truncate",title:R.to_node,children:H(R.to_node)}),R.type.name!==Te&&e.jsxs("span",{className:"text-[10px] text-muted-foreground shrink-0",children:["(",R.type.name,")"]}),e.jsx("div",{className:"flex-1"}),e.jsx(S,{variant:"ghost",size:"icon",className:"h-6 w-6 opacity-0 group-hover:opacity-100 text-muted-foreground",onClick:()=>be(R.to_node),title:"Add a step after this document",children:e.jsx(oe,{className:"h-3.5 w-3.5"})}),e.jsx(S,{variant:"ghost",size:"icon",className:"h-6 w-6 opacity-0 group-hover:opacity-100 text-muted-foreground hover:text-destructive",onClick:()=>void Ne(R.id),title:"Remove this step",children:e.jsx(ze,{className:"h-3.5 w-3.5"})})]},R.id)),P.has(R.to_node)||(P.add(R.to_node),z.push(...ue(R.to_node,v+1,P)));return z},ie=e.jsxs("div",{className:"rounded-lg border bg-muted/20 p-3",id:"wf-composer",children:[e.jsx("div",{className:"text-xs font-medium mb-2",children:"Connect two documents"}),e.jsxs("div",{className:"flex items-center flex-wrap gap-2",children:[e.jsxs("select",{value:N,onChange:n=>w(n.target.value),className:"h-8 rounded-md border bg-background px-2 text-sm max-w-[220px]","data-testid":"wf-compose-from",children:[e.jsx("option",{value:"",children:"When this runs…"}),I.map(n=>e.jsxs("option",{value:n.id,children:[n.type==="agent"?"🤖 ":n.type==="skill"?"⚡ ":"",n.title||n.id]},n.id))]}),e.jsx(Ye,{className:"h-4 w-4 text-muted-foreground shrink-0"}),e.jsx("div",{className:"flex items-center rounded-md border h-8 text-xs overflow-hidden",children:[["","always"],["nl","if…"],["structured","metric"]].map(([n,v],P)=>e.jsx("button",{type:"button",className:`px-2.5 h-full ${P>0?"border-l":""} ${T===n?"bg-primary text-primary-foreground":"hover:bg-muted"}`,onClick:()=>B(n),children:v},n))}),T==="nl"&&e.jsx(te,{value:D,onChange:n=>q(n.target.value),placeholder:'e.g. "lost on price, not product"',className:"h-8 text-sm italic w-60",title:"An AI judges this plain-English rule against the run's context"}),T==="structured"&&e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(te,{value:Y,onChange:n=>U(n.target.value),placeholder:"CAC",className:"h-8 text-sm w-24 font-mono",title:"A term from your governed definitions"}),e.jsx("select",{value:i,onChange:n=>$(n.target.value),className:"h-8 rounded-md border bg-background px-1.5 text-sm font-mono",children:[">","<",">=","<=","=","!="].map(n=>e.jsx("option",{value:n,children:n},n))}),e.jsx(te,{value:W,onChange:n=>he(n.target.value),placeholder:"500",className:"h-8 text-sm w-20 font-mono"})]}),e.jsx(Ye,{className:"h-4 w-4 text-muted-foreground shrink-0"}),e.jsxs("select",{value:x,onChange:n=>O(n.target.value),className:"h-8 rounded-md border bg-background px-2 text-sm max-w-[220px]","data-testid":"wf-compose-to",children:[e.jsx("option",{value:"",children:"…continue to"}),I.map(n=>e.jsxs("option",{value:n.id,children:[n.type==="agent"?"🤖 ":n.type==="skill"?"⚡ ":"",n.title||n.id]},n.id))]}),e.jsxs(S,{size:"sm",className:"h-8",disabled:ne||!N||!x||T==="nl"&&!D.trim()||T==="structured"&&!Y.trim(),onClick:()=>void le(),children:[ne?e.jsx(J,{className:"h-3.5 w-3.5 animate-spin"}):e.jsx(oe,{className:"h-3.5 w-3.5 mr-1"}),"Add step"]}),e.jsx("select",{value:c,onChange:n=>L(n.target.value),className:"h-8 rounded-md border bg-background px-1.5 text-xs text-muted-foreground ml-auto",title:"Edge type — flow types (▶) are walked by the runner; others are reference links",children:y.map(n=>e.jsxs("option",{value:n.name,children:[n.is_flow?"▶ ":"",n.name]},n.id))})]})]});return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Each card is a flow the runner can walk, starting from its top node."}),e.jsx("div",{className:"flex-1"}),e.jsxs(S,{variant:"outline",size:"sm",onClick:()=>void X(),children:[e.jsx(st,{className:"h-3.5 w-3.5 mr-1"})," Refresh"]})]}),k&&e.jsx("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive whitespace-pre-line",children:k}),b?e.jsx("div",{className:"py-8 text-center text-muted-foreground",children:e.jsx(J,{className:"h-4 w-4 animate-spin inline"})}):Q.length===0?e.jsxs("div",{className:"rounded-lg border border-dashed p-6 text-center",children:[e.jsx("p",{className:"text-sm font-medium mb-1",children:"No flows yet"}),e.jsxs("p",{className:"text-xs text-muted-foreground max-w-md mx-auto",children:["A flow is a chain of steps: an ",e.jsx("b",{children:"agent"})," runs, and each connection says what happens next — always, when an AI judges a rule true, or when a metric crosses a threshold. Connect your first two documents below."]})]}):Q.map(n=>e.jsxs("div",{className:"rounded-lg border p-3",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(Ce,{type:ae(n)}),e.jsx("span",{className:"font-medium text-sm truncate",title:n,children:H(n)}),e.jsx(se,{variant:"secondary",className:"text-[10px]",children:ae(n)==="agent"?"agent · start":"start"}),e.jsx("div",{className:"flex-1"}),e.jsxs(S,{variant:"ghost",size:"sm",className:"h-7 text-xs text-muted-foreground",onClick:()=>be(n),children:[e.jsx(oe,{className:"h-3.5 w-3.5 mr-1"})," Step"]})]}),ue(n,0,new Set([n]))]},n)),ye||Q.length===0||G.length+re.length===0?ie:e.jsxs(S,{variant:"outline",size:"sm",onClick:()=>pe(!0),children:[e.jsx(oe,{className:"h-3.5 w-3.5 mr-1"})," Connect documents"]}),G.length>0&&e.jsxs("details",{className:"rounded-lg border px-3 py-2",children:[e.jsxs("summary",{className:"cursor-pointer text-xs font-medium text-muted-foreground select-none",children:["Reference links (",G.length,") — ontology edges the runner doesn't walk"]}),e.jsx("div",{className:"mt-2 space-y-1",children:G.map(n=>e.jsxs("div",{className:"flex items-center gap-2 text-sm group",children:[e.jsx(Ce,{type:ae(n.from_node)}),e.jsx("span",{className:"truncate",title:n.from_node,children:H(n.from_node)}),e.jsx("span",{className:"rounded-full px-2 py-0.5 text-[10px] text-muted-foreground border",style:{borderColor:n.type.color??void 0},children:n.type.name}),e.jsx(Ce,{type:ae(n.to_node)}),e.jsx("span",{className:"truncate",title:n.to_node,children:H(n.to_node)}),e.jsx("div",{className:"flex-1"}),e.jsx(S,{variant:"ghost",size:"icon",className:"h-6 w-6 opacity-0 group-hover:opacity-100 text-muted-foreground hover:text-destructive",onClick:()=>void Ne(n.id),title:"Delete link",children:e.jsx(ze,{className:"h-3.5 w-3.5"})})]},n.id))})]}),e.jsxs("p",{className:"text-[11px] text-muted-foreground",children:[e.jsx("b",{children:"always"})," = the step fires whenever the previous one runs ·"," ",e.jsx("b",{children:"if…"})," = an AI judges a plain-English rule against the run's context · ",e.jsx("b",{children:"metric"})," = a deterministic check like"," ",e.jsx("code",{children:"CAC > 500"}),", resolved from your governed terms."]})]})}const Ps=8,Rs=16;function pt({value:s,onValueChange:m,runnables:g,placeholder:y,testId:C,disabledReason:b}){return e.jsxs(Ct,{value:s||void 0,onValueChange:m,children:[e.jsx(Et,{className:"h-9 w-full","data-testid":C,disabled:!g.length,children:e.jsx(Tt,{placeholder:g.length?y:"No runnable agents yet"})}),e.jsx($t,{children:g.map(j=>{const k=(b==null?void 0:b(j.id))??null;return e.jsx(et,{value:j.id,disabled:!!k,children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(We,{type:j.type,className:"h-3.5 w-3.5"}),j.title||j.id,k&&e.jsxs("span",{className:"text-[10px] text-muted-foreground",children:["— ",k]})]})},j.id)})})]})}function Ms({value:s,onValueChange:m,runs:g,runLabel:y,runType:C,blockedReason:b}){const j="__none__",k=g.filter(d=>d.status==="running");return e.jsxs(Ct,{value:s||j,onValueChange:d=>m(d===j?"":d),children:[e.jsx(Et,{className:"h-auto min-h-9 w-full","data-testid":"run-parent-lookup",children:e.jsx(Tt,{})}),e.jsxs($t,{children:[e.jsx(et,{value:j,children:"— None (top-level run)"}),k.map(d=>{const h=b(d),E=d.depth??0;return e.jsx(et,{value:d.id,disabled:!!h,children:e.jsxs("span",{className:"flex flex-col gap-0.5 py-0.5",children:[e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(We,{type:C(d.agent_node),className:"h-3.5 w-3.5"}),e.jsx("span",{className:"font-medium",children:y(d.agent_node)}),e.jsx("span",{className:"font-mono text-[11px] text-muted-foreground",children:d.id.replace(/^run_/,"").slice(0,8)}),h&&e.jsx(se,{variant:"outline",className:"text-[10px]",children:h})]}),e.jsxs("span",{className:"text-[11px] text-muted-foreground",children:["depth ",E," → ",E+1," · ",Ee(d.started_at)]})]})},d.id)})]})]})}function Os({nestId:s}){const{subagentRunsEnabled:m,subagentMaxDepth:g,subagentMaxChildren:y}=Yt(),C=g||Ps,b=y||Rs,[j,k]=r.useState([]),[d,h]=r.useState(null),[E,N]=r.useState(!0),[w,x]=r.useState(null),[O,c]=r.useState(""),[L,T]=r.useState(!1),[B,D]=r.useState(""),[q,Y]=r.useState(""),[U,i]=r.useState(""),[$,W]=r.useState(""),[he,ne]=r.useState(""),[de,ye]=r.useState(!1),[pe,X]=r.useState(null),[le,be]=r.useState(null),[Ne,we]=r.useState([]),H=r.useCallback(async()=>{N(!0);try{const[a,p]=await Promise.all([Zt(s,void 0,500),Ue(s).then(F=>F.nodes).catch(()=>[])]);k(a),we(p),x(null)}catch(a){x(a instanceof Error?a.message:"Failed to load runs")}finally{N(!1)}},[s]),ae=Ne.filter(a=>a.type==="agent"||a.type==="skill");r.useEffect(()=>{H()},[H]);const re=async a=>{try{h(await cs(a))}catch(p){x(p instanceof Error?p.message:"Failed to load run")}},G=async a=>{be(a);try{await is(a),await H(),(d==null?void 0:d.id)===a&&await re(a)}catch(p){x(p instanceof Error?p.message:"Failed to cancel run")}finally{be(null)}},Te=a=>{const p=a.trim();if(p)try{const F=JSON.parse(p);return typeof F=="object"&&F!==null?F:{input:F}}catch{return{input:p}}},Z=async()=>{if(O.trim()){T(!0);try{await Qe(s,O.trim(),Te(B),q||void 0),c(""),D(""),Y(""),await H()}catch(a){x(a instanceof Error?a.message:"Failed to trigger run")}finally{T(!1)}}},$e=async a=>{if($.trim()){ye(!0),X(null);try{await Qe(s,$.trim(),Te(he),a),i(""),W(""),ne(""),await H()}catch(p){X(p instanceof Error?p.message:"Failed to spawn sub-agent")}finally{ye(!1)}}},Q=new Map(Ne.map(a=>[a.id,a])),I=a=>{var p;return((p=Q.get(a))==null?void 0:p.title)||a.replace(/^nodes\//,"")},ue=a=>{var p;return(p=Q.get(a))==null?void 0:p.type},ie=new Map,ke=new Set(j.map(a=>a.id)),n=[];for(const a of j)a.parent_run_id&&ke.has(a.parent_run_id)?(ie.has(a.parent_run_id)||ie.set(a.parent_run_id,[]),ie.get(a.parent_run_id).push(a)):n.push(a);const v=new Map(j.map(a=>[a.id,a])),P=a=>{var p;return((p=ie.get(a))==null?void 0:p.length)??0},z=a=>{const p=new Set;let F=a;for(let me=0;F&&me<=C+1;me++){const fe=v.get(F);if(!fe)break;p.add(fe.agent_node),F=fe.parent_run_id??null}return p},R=(a,p)=>(a.depth??0)>=C?"at max depth":P(a.id)>=b?`${b}/${b} full`:p&&z(a.id).has(p)?"would loop":null,Fe=q?v.get(q)??null:null,ge=Fe?R(Fe,O):null,Pe=(a,p)=>{var fe;const F=ie.get(a.id)??[],me=p?ht(p):void 0;return e.jsxs("div",{children:[e.jsxs("div",{role:"button",tabIndex:0,onClick:()=>void re(a.id),onKeyDown:K=>{(K.key==="Enter"||K.key===" ")&&re(a.id)},className:`group w-full overflow-hidden cursor-pointer px-3 py-2 hover:bg-muted/40 ${(d==null?void 0:d.id)===a.id?"bg-muted/60":""}`,style:{paddingLeft:me},children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[p>0&&e.jsx(nt,{className:"h-3 w-3 text-muted-foreground/50 shrink-0","aria-label":`Sub-agent at depth ${a.depth??p}`,children:e.jsx("title",{children:`Sub-agent at depth ${a.depth??p}`})}),e.jsx(We,{type:ue(a.agent_node),className:"h-3.5 w-3.5"}),e.jsx("span",{className:"font-mono text-xs truncate min-w-[6rem]",title:a.id,children:a.id.length>12?`${a.id.slice(0,12)}…`:a.id}),e.jsx(se,{variant:tt(Ae(a)),className:"text-[10px]",title:qe(a)?Mt:void 0,children:Ae(a)}),a.status==="running"&&(()=>{const K=[];return m&&(a.depth??0)<C&&P(a.id)<b&&K.push({label:U===a.id?"Close sub-agent form":"Spawn sub-agent",icon:oe,testId:"run-action-spawn",onSelect:()=>{i(U===a.id?"":a.id),W(""),ne(""),X(null)}}),K.push({label:le===a.id?"Cancelling…":"Cancel run",icon:le===a.id?J:Rt,iconClassName:le===a.id?"animate-spin":void 0,destructive:!0,disabled:le===a.id,separatorBefore:!0,testId:"run-action-cancel",onSelect:()=>void G(a.id)}),e.jsx("div",{className:"ml-auto shrink-0",children:e.jsx(ps,{actions:K,className:"h-6 w-6 text-muted-foreground",triggerTitle:"Run actions",testId:"run-actions"})})})()]}),e.jsxs("div",{className:"text-[11px] text-muted-foreground truncate",children:[I(a.agent_node)," · ",Ee(a.started_at),F.length>0&&` · ${F.length} child${F.length===1?"":"ren"}`]}),a.status==="failed"&&((fe=a.trace)==null?void 0:fe.error)&&e.jsx("div",{className:"text-[11px] text-destructive truncate mt-0.5",title:String(a.trace.error),children:String(a.trace.error).replace(/^\d+ /,"").slice(0,110)})]}),m&&U===a.id&&e.jsxs("div",{className:"border-t bg-muted/20 px-3 py-2.5 space-y-2",style:{paddingLeft:ht(p+1)},children:[e.jsxs("div",{className:"text-[11px] font-medium text-muted-foreground",children:["New sub-agent under"," ",e.jsx("span",{className:"font-mono",children:a.id.slice(0,12)})," —"," ",I(a.agent_node)," · depth ",a.depth??p," → child depth"," ",(a.depth??p)+1]}),e.jsx(pt,{value:$,onValueChange:W,runnables:ae,placeholder:"Choose an agent…",testId:"spawn-agent-lookup",disabledReason:K=>z(a.id).has(K)?"already in this chain":null}),e.jsx("textarea",{value:he,onChange:K=>ne(K.target.value),placeholder:"Inputs (optional) — plain text or JSON",className:"w-full rounded-md border bg-background px-2 py-1.5 text-xs font-mono min-h-[44px]"}),pe&&e.jsx("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 px-2.5 py-1.5 text-[11px] text-destructive",children:pe}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(S,{size:"sm",className:"h-7",disabled:de||!$.trim(),onClick:()=>void $e(a.id),children:[de?e.jsx(J,{className:"h-3.5 w-3.5 mr-1 animate-spin"}):e.jsx(oe,{className:"h-3.5 w-3.5 mr-1"}),"Create sub-agent"]}),e.jsx(S,{variant:"ghost",size:"sm",className:"h-7",onClick:()=>{i(""),X(null)},children:"Cancel"})]})]}),F.map(K=>Pe(K,p+1))]},a.id)};return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-lg border p-4 space-y-3",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-semibold",children:"Trigger a run"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"Creates a run record + bundle (inputs ride along). The server never executes — a runner (the contextnest-runner) walks the bundle and posts each step back into the trace below."})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[11px] font-medium text-muted-foreground mb-1",children:"Agent / skill node"}),e.jsx(pt,{value:O,onValueChange:c,runnables:ae,placeholder:"Choose an agent to run…",testId:"run-agent-lookup"})]}),m&&e.jsxs("div",{children:[e.jsx("label",{className:"block text-[11px] font-medium text-muted-foreground mb-1",children:"Parent run (optional — spawn as a sub-agent)"}),e.jsx(Ms,{value:q,onValueChange:Y,runs:j,runLabel:I,runType:ue,blockedReason:a=>R(a,O)}),ge&&e.jsxs("p",{className:"text-[11px] text-destructive mt-1",children:["This parent can't be used (",ge,") — pick another or change the agent."]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[11px] font-medium text-muted-foreground mb-1",children:"Inputs (optional — plain text or JSON)"}),e.jsx("textarea",{value:B,onChange:a=>D(a.target.value),placeholder:'e.g. {"account":"Foley"}',className:"w-full rounded-md border bg-background px-2 py-1.5 text-xs font-mono min-h-[64px]"})]}),w&&e.jsx("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive",children:w}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(S,{disabled:L||!O.trim()||!!ge,onClick:()=>void Z(),title:"Create a run (a runner executes it)",children:[L?e.jsx(J,{className:"h-3.5 w-3.5 mr-1.5 animate-spin"}):e.jsx(At,{className:"h-3.5 w-3.5 mr-1.5"}),"Create run"]}),e.jsxs(S,{variant:"outline",size:"sm",onClick:()=>void H(),children:[e.jsx(st,{className:"h-3.5 w-3.5 mr-1"})," Refresh"]})]}),e.jsxs("details",{className:"rounded-md border bg-muted/30 px-3 py-2 text-[11px]",children:[e.jsx("summary",{className:"cursor-pointer font-medium",children:"How do I run one? (the runner is a separate process)"}),e.jsxs("div",{className:"mt-2 space-y-1.5 text-muted-foreground",children:[e.jsxs("p",{children:["The ",e.jsx("b",{children:"trigger"})," button just records a run. The"," ",e.jsx("b",{children:"runner"})," is a small stateless container that actually walks it and calls the LLM. Point it at this nest:"]}),e.jsx("pre",{className:"overflow-x-auto rounded bg-background border p-2 font-mono text-[10.5px] leading-relaxed",children:`docker run -d --name cn-runner --network host \\
|
|
12
|
+
-e CONTEXTNEST_SERVER=http://localhost:4040 \\
|
|
13
|
+
-e CONTEXTNEST_NEST=${s} \\
|
|
14
|
+
-e CONTEXTNEST_KEY=cnst_localdev \\
|
|
15
|
+
contextnest-runner:local poll`}),e.jsxs("p",{children:[e.jsx("b",{children:"poll"})," claims every run this server creates (Schedule tab, Run buttons) and executes it — one standing container per nest. No Anthropic key flag needed: set"," ",e.jsx("code",{children:"ANTHROPIC_API_KEY"})," in Activity → Tool environment and the runner picks it up from the run bundle. Steps stream back into the trace below — refresh to watch."]})]})]})]}),e.jsxs("div",{className:`grid gap-4 items-start ${d?"lg:grid-cols-[minmax(0,24rem)_minmax(0,1fr)]":"grid-cols-1"}`,children:[e.jsx("div",{className:"rounded-lg border divide-y min-w-0",children:E?e.jsx("div",{className:"px-3 py-6 text-center text-muted-foreground",children:e.jsx(J,{className:"h-4 w-4 animate-spin inline"})}):j.length===0?e.jsx("div",{className:"px-3 py-6 text-center text-xs text-muted-foreground",children:"No runs yet. Trigger an agent above."}):n.map(a=>Pe(a,0))}),d&&e.jsx("div",{className:"rounded-lg border p-4 min-w-0 lg:sticky lg:top-20",children:e.jsx(Ls,{run:d,children:j.filter(a=>a.parent_run_id===d.id),parent:d.parent_run_id?j.find(a=>a.id===d.parent_run_id)??null:null,label:I,typeOf:ue,onOpen:a=>void re(a),onCancel:a=>void G(a),cancelling:le===d.id})})]})]})}function Ls({run:s,children:m=[],parent:g=null,label:y=d=>d,typeOf:C=()=>{},onOpen:b,onCancel:j,cancelling:k=!1}){var d;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(We,{type:C(s.agent_node),className:"h-4 w-4"}),e.jsx("span",{className:"font-mono text-sm",children:s.id}),e.jsx(se,{variant:tt(Ae(s)),title:qe(s)?Mt:void 0,children:Ae(s)}),(s.depth??0)>0&&e.jsxs(se,{variant:"outline",className:"text-[10px]",children:["sub-agent · depth ",s.depth]}),s.status==="running"&&j&&e.jsxs(S,{variant:"outline",size:"sm",className:"ml-auto h-7",disabled:k,onClick:()=>j(s.id),title:"Cancel this run",children:[k?e.jsx(J,{className:"h-3.5 w-3.5 mr-1 animate-spin"}):e.jsx(Rt,{className:"h-3.5 w-3.5 mr-1"}),"Cancel run"]})]}),e.jsxs("div",{className:"text-xs text-muted-foreground mb-4",children:["agent ",y(s.agent_node)," · started ",Ee(s.started_at),s.finished_at?` · finished ${Ee(s.finished_at)}`:""," · triggered by ",s.triggered_by]}),g&&e.jsxs("button",{type:"button",onClick:()=>b==null?void 0:b(g.id),className:"mb-3 inline-flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground",title:"Open the run that spawned this one",children:[e.jsx(js,{className:"h-3 w-3"})," Spawned by ",y(g.agent_node)," ",e.jsxs("span",{className:"font-mono",children:["(",g.id.slice(0,8),")"]})]}),m.length>0&&e.jsxs("div",{className:"mb-4 rounded-md border bg-muted/20 p-2.5",children:[e.jsxs("div",{className:"text-[10px] uppercase tracking-wide text-muted-foreground mb-1.5",children:["Sub-agents spawned (",m.length,")"]}),e.jsx("div",{className:"space-y-1",children:m.map(h=>e.jsxs("button",{type:"button",onClick:()=>b==null?void 0:b(h.id),className:"flex w-full items-center gap-2 rounded px-1.5 py-1 text-left text-xs hover:bg-muted/50",children:[e.jsx(nt,{className:"h-3 w-3 text-muted-foreground/50 shrink-0"}),e.jsx(We,{type:C(h.agent_node),className:"h-3.5 w-3.5"}),e.jsx("span",{className:"truncate",children:y(h.agent_node)}),e.jsx(se,{variant:tt(Ae(h)),className:"text-[10px] shrink-0",children:Ae(h)}),e.jsx("span",{className:"ml-auto font-mono text-[10px] text-muted-foreground shrink-0",children:h.id.slice(0,8)})]},h.id))})]}),((d=s.trace)==null?void 0:d.error)&&e.jsx("div",{className:"mb-3 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive font-mono break-all",children:s.trace.error}),e.jsx("div",{className:"space-y-0",children:s.steps.length===0?e.jsx("div",{className:"text-xs text-muted-foreground",children:qe(s)?"No steps yet — queued, waiting for a runner to claim it. Start a runner (see “How do I run one?” above) or cancel the run.":"No steps recorded."}):s.steps.map(h=>e.jsxs("div",{className:"grid grid-cols-[24px_1fr] gap-3 py-2 border-b border-dashed last:border-0",children:[e.jsx("div",{className:"text-muted-foreground pt-0.5",children:Es(h.action)}),e.jsxs("div",{children:[e.jsxs("div",{className:"text-xs",children:[e.jsxs("span",{className:"text-muted-foreground",children:[Ee(h.at)," ·"," "]}),e.jsx("span",{className:"font-medium",children:h.action}),h.node_id&&e.jsxs("span",{className:"font-mono text-muted-foreground",children:[" ",h.node_id]})]}),h.detail&&e.jsx("div",{className:"text-[11px] text-muted-foreground font-mono mt-0.5 break-all",children:typeof h.detail=="string"?h.detail:JSON.stringify(h.detail)})]})]},h.seq))})]})}const _e=168,je=56,Ws=260,zs=100,Se=30,Ze=70;function Fs({nestId:s}){const[m,g]=r.useState([]),[y,C]=r.useState([]),[b,j]=r.useState([]),[k,d]=r.useState(!0),[h,E]=r.useState(null),[N,w]=r.useState(null),[x,O]=r.useState(null),[c,L]=r.useState(null),[T,B]=r.useState(""),[D,q]=r.useState(""),[Y,U]=r.useState(""),[i,$]=r.useState(""),[W,he]=r.useState(">"),[ne,de]=r.useState(""),[ye,pe]=r.useState(!1),[X,le]=r.useState(""),[be,Ne]=r.useState([]),[we,H]=r.useState(60),[ae,re]=r.useState(""),[G,Te]=r.useState(1),[Z,$e]=r.useState(""),[Q,I]=r.useState(null),[ue,ie]=r.useState(!1),[ke,n]=r.useState(""),[v,P]=r.useState([]),[z,R]=r.useState(""),[Fe,ge]=r.useState([]),[Pe,a]=r.useState("slack"),[p,F]=r.useState({}),[me,fe]=r.useState(null),[K,at]=r.useState(0);r.useEffect(()=>{if(!me)return;const t=new ResizeObserver(o=>{var f;const u=((f=o[0])==null?void 0:f.contentRect.width)??0;u&&at(u)});return t.observe(me),at(me.clientWidth),()=>t.disconnect()},[me]);const xe=r.useCallback(async()=>{d(!0);try{const[t,o,u,f]=await Promise.all([ft(s),vt(s),Ue(s).then(_=>_.nodes).catch(()=>[]),jt(s).catch(()=>[])]);g(t),C(o),j(u),Ne(f),E(null)}catch(t){E(t instanceof Error?t.message:"Failed to load canvas")}finally{d(!1)}},[s]);r.useEffect(()=>{if(!x)return;let t=!1;return qt(s,x).then(o=>!t&&P(o.map(u=>u.user_email))).catch(()=>!t&&P([])),Je(s,x).then(o=>!t&&ge(o)).catch(()=>!t&&ge([])),()=>{t=!0}},[s,x]);const De=(t,o)=>{ls(o).then(u=>{u&&($e(t),setTimeout(()=>$e(""),1500))})};r.useEffect(()=>{xe()},[xe]);const rt=new Map(b.map(t=>[t.id,t])),V=t=>{var o;return((o=rt.get(t))==null?void 0:o.title)||t.replace(/^nodes\//,"")},Re=t=>{var o;return(o=rt.get(t))==null?void 0:o.type},ot=m.filter(t=>t.type.is_flow),ee=new Map;{const t=new Set;for(const A of m)t.add(A.from_node),t.add(A.to_node);const o=new Map,u=new Set(ot.map(A=>A.to_node)),f=[...t].filter(A=>!u.has(A)).sort();for(const A of f)o.set(A,0);for(let A=0;A<t.size;A++){let l=!1;for(const M of ot){const ce=(o.get(M.from_node)??0)+1;ce>(o.get(M.to_node)??0)&&(o.set(M.to_node,ce),l=!0)}if(!l)break}const _=new Map;for(const A of[...t].sort((l,M)=>String(V(l)).localeCompare(V(M)))){const l=o.get(A)??0;_.has(l)||_.set(l,[]),_.get(l).push(A)}for(const[A,l]of _)l.forEach((M,ce)=>{ee.set(M,{id:M,x:Se+A*Ws,y:Ze+ce*zs})})}const Ot=Se*2+(Math.max(0,...[...ee.values()].map(t=>t.x))+_e+60),lt=Math.max(300,Ze+(Math.max(-Ze+40,...[...ee.values()].map(t=>t.y))+je+40)),He=ke.trim().toLowerCase(),Me=b.map(t=>t.id).filter(t=>!ee.has(t)).filter(t=>!He||V(t).toLowerCase().includes(He)||t.toLowerCase().includes(He)).sort((t,o)=>{const u=f=>Re(f)==="agent"?0:Re(f)==="skill"?1:2;return u(t)-u(o)||V(t).localeCompare(V(o))}),Oe=lt+46,it=Math.max(Ot,K>0?Math.floor(K):920),Xe=Math.max(1,Math.floor((it-Se*2)/(_e+46)));Me.forEach((t,o)=>{ee.set(t,{id:t,x:Se+o%Xe*(_e+46),y:Oe+Math.floor(o/Xe)*(je+28)})});const ct=it,Lt=Me.length?Oe+Math.ceil(Me.length/Xe)*(je+28)+30:lt+20,ve=(t,o)=>{const u=ee.get(t);return u?{x:o==="out"?u.x+_e:u.x,y:u.y+je/2}:{x:0,y:0}},Wt=(t,o,u=0)=>{const f=ve(t,"out"),_=ve(o,"in"),A=Math.max(40,(_.x-f.x)/2),l=u*4/3;return`M${f.x},${f.y} C${f.x+A},${f.y+l} ${_.x-A},${_.y+l} ${_.x},${_.y}`},Ge=new Map;{const t=new Map;for(const o of m){const u=`${o.from_node}\0${o.to_node}`,f=t.get(u)??[];f.push(o),t.set(u,f)}for(const o of t.values())o.length<2||o.forEach((u,f)=>Ge.set(u.id,(f-(o.length-1)/2)*34))}const dt=t=>t.type.color||(t.type.is_flow?"#34a853":"#94a3b8"),zt=m.filter(t=>ee.has(t.from_node)&&ee.has(t.to_node)).map(t=>{let o="";if(t.condition_mode==="nl"&&t.condition)o=`“${t.condition}”`;else if(t.condition_mode==="structured"&&t.condition)try{const _=typeof t.condition=="string"?JSON.parse(t.condition):t.condition;o=_!=null&&_.term?`${_.term} ${_.op??""} ${_.value??""}`:""}catch{}const u=ve(t.from_node,"out"),f=ve(t.to_node,"in");return{edge:t,x:(u.x+f.x)/2,y:(u.y+f.y)/2+(Ge.get(t.id)??0)-je/2-6,..._s(t.type.name,o)}}),Ke=t=>{if(O(null),I(null),w(t.id),B(t.type.name),q(t.condition_mode||""),t.condition_mode==="nl")U(String(t.condition??""));else if(t.condition_mode==="structured"&&t.condition)try{const o=typeof t.condition=="string"?JSON.parse(t.condition):t.condition;$(String(o.term??"")),he(String(o.op??">")),de(String(o.value??""))}catch{$(""),de("")}},Ft=async()=>{if(!N)return;const t=m.find(u=>u.id===N),o=t&&m.find(u=>u.id!==N&&u.from_node===t.from_node&&u.to_node===t.to_node&&u.type.name===T);if(o){E(`${V(o.from_node)} → ${V(o.to_node)} is already connected with "${T}".`);return}pe(!0);try{await os(s,N,{type:T,condition_mode:D||null,condition:D==="nl"?Y.trim():D==="structured"?{term:i.trim(),op:W,value:isNaN(Number(ne))?ne.trim():Number(ne)}:null}),await xe()}catch(u){E(u instanceof Error?u.message:"Failed to save edge")}finally{pe(!1)}},Dt=async t=>{try{await _t(s,t),w(null),await xe()}catch(o){E(o instanceof Error?o.message:"Failed to delete edge")}},ut=async(t,o)=>{var _,A;if(t===o)return;const u=((_=y.find(l=>l.is_flow))==null?void 0:_.name)??((A=y[0])==null?void 0:A.name);if(!u)return;const f=m.find(l=>l.from_node===t&&l.to_node===o&&l.type.name===u);if(f){E(`${V(t)} → ${V(o)} is already connected with "${u}".`),Ke(f);return}try{const l=await kt(s,{from_node:t,to_node:o,type:u,condition_mode:null,condition:null});await xe(),Ke(l)}catch(l){E(l instanceof Error?l.message:"Failed to connect")}},Ht=t=>{const o=t.currentTarget.closest("svg").getBoundingClientRect();return{x:t.clientX-o.left,y:t.clientY-o.top}},Le=m.find(t=>t.id===N)??null,Kt=[...new Set(m.map(dt))];return e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[minmax(0,1fr)_300px] gap-4",children:[e.jsxs("div",{className:"rounded-lg border overflow-hidden bg-background",children:[e.jsxs("div",{className:"flex items-center gap-2 px-3 py-2 border-b text-xs text-muted-foreground",children:[e.jsxs("span",{className:"hidden md:inline",children:["Drag from a card's ",e.jsx("b",{children:"right port"})," onto another card to connect. Click a wire or card to edit it."]}),e.jsx("div",{className:"flex-1"}),e.jsx(te,{value:ke,onChange:t=>n(t.target.value),placeholder:"Find a document to wire in…",className:"h-7 w-56 text-xs","data-testid":"canvas-shelf-search"}),e.jsx(S,{variant:"outline",size:"sm",className:"h-7",onClick:()=>void xe(),children:e.jsx(st,{className:"h-3.5 w-3.5"})})]}),h&&e.jsx("div",{className:"mx-3 mt-2 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive whitespace-pre-line",children:h}),k?e.jsx("div",{className:"py-16 text-center text-muted-foreground",children:e.jsx(J,{className:"h-4 w-4 animate-spin inline"})}):ee.size===0?e.jsx("div",{className:"py-16 text-center text-sm text-muted-foreground",children:"No documents in this nest yet — create one from the Documents tab and it appears here, ready to wire up."}):e.jsx("div",{className:"overflow-auto max-h-[70vh]",ref:fe,children:e.jsxs("svg",{width:ct,height:Lt,ref:t=>{},style:{background:"radial-gradient(circle, hsl(var(--muted-foreground) / 0.18) 1px, transparent 1px)",backgroundSize:"20px 20px"},onMouseMove:t=>{if(!c)return;const o=t.currentTarget.getBoundingClientRect();L({...c,x:t.clientX-o.left,y:t.clientY-o.top})},onMouseUp:()=>L(null),onClick:()=>{w(null),O(null)},children:[e.jsx("defs",{children:Kt.map(t=>e.jsx("marker",{id:`ah-${t.replace(/[^a-z0-9]/gi,"")}`,markerWidth:"9",markerHeight:"9",refX:"7",refY:"3",orient:"auto",children:e.jsx("path",{d:"M0,0 L7,3 L0,6 z",fill:t})},t))}),m.map(t=>{if(!ee.has(t.from_node)||!ee.has(t.to_node))return null;const o=Ge.get(t.id)??0,u=Wt(t.from_node,t.to_node,o),f=dt(t);return e.jsxs("g",{children:[e.jsx("path",{d:u,fill:"none",stroke:f,strokeWidth:N===t.id?3:2,strokeDasharray:t.type.is_flow?void 0:"4 4",markerEnd:`url(#ah-${f.replace(/[^a-z0-9]/gi,"")})`,opacity:N&&N!==t.id?.45:1}),e.jsx("path",{d:u,fill:"none",stroke:"transparent",strokeWidth:14,style:{cursor:"pointer"},onClick:_=>{_.stopPropagation(),Ke(t)}})]},t.id)}),c&&e.jsx("path",{d:`M${ve(c.from,"out").x},${ve(c.from,"out").y} C${ve(c.from,"out").x+60},${ve(c.from,"out").y} ${c.x-60},${c.y} ${c.x},${c.y}`,fill:"none",stroke:"hsl(var(--primary))",strokeWidth:2,strokeDasharray:"5 4"}),Me.length>0&&e.jsxs("g",{children:[e.jsx("line",{x1:Se,y1:Oe-26,x2:ct-Se,y2:Oe-26,stroke:"hsl(var(--border))",strokeDasharray:"3 3"}),e.jsxs("text",{x:Se,y:Oe-32,style:{font:"10px sans-serif",fill:"hsl(var(--muted-foreground))"},children:["NOT WIRED IN YET (",Me.length,He?" matching":"",") — drag a right port onto any card to connect"]})]}),[...ee.values()].map(t=>{const o=Re(t.id),u=x===t.id;return e.jsxs("g",{children:[e.jsx("foreignObject",{x:t.x,y:t.y,width:_e,height:je+6,children:e.jsxs("div",{className:`rounded-lg border-2 bg-background px-2.5 py-1.5 shadow-sm cursor-pointer select-none ${u?"border-primary ring-2 ring-primary/20":"border-border"}`,style:{width:_e,height:je},onClick:f=>{f.stopPropagation(),w(null),I(null),O(t.id)},onMouseUp:()=>{c&&c.from!==t.id&&(ut(c.from,t.id),L(null))},title:t.id,children:[e.jsxs("div",{className:"flex items-center gap-1 text-[10px] uppercase tracking-wide text-muted-foreground",children:[e.jsx(Ce,{type:o}),o??"document"]}),e.jsx("div",{className:"text-xs font-semibold truncate mt-0.5",children:V(t.id)})]})}),e.jsx("circle",{cx:t.x+_e,cy:t.y+je/2,r:6,fill:"hsl(var(--background))",stroke:"hsl(var(--primary))",strokeWidth:1.5,style:{cursor:"crosshair"},onMouseDown:f=>{f.stopPropagation(),f.preventDefault();const _=Ht(f);L({from:t.id,x:_.x,y:_.y})}})]},t.id)}),zt.map(t=>e.jsxs("g",{style:{cursor:"pointer"},onClick:o=>{o.stopPropagation(),Ke(t.edge)},children:[e.jsx("title",{children:t.full}),e.jsx("rect",{x:t.x-t.width/2,y:t.y-9,width:t.width,height:13,rx:3,fill:"hsl(var(--background))",opacity:.92}),e.jsx("text",{x:t.x,y:t.y,textAnchor:"middle",style:{font:"10px ui-monospace, monospace",fill:"hsl(var(--muted-foreground))"},children:t.short})]},`label-${t.edge.id}`))]})})]}),e.jsx("div",{className:"rounded-lg border p-4 h-fit",children:Le?e.jsxs("div",{children:[e.jsxs("h3",{className:"text-sm font-semibold",children:["Edge · ",Le.type.name]}),e.jsxs("p",{className:"text-xs text-muted-foreground mb-3",children:[V(Le.from_node)," → ",V(Le.to_node)]}),e.jsx("label",{className:"block text-[10px] uppercase tracking-wide text-muted-foreground mb-1",children:"Type"}),e.jsx("select",{value:T,onChange:t=>B(t.target.value),className:"w-full h-8 rounded-md border bg-background px-2 text-sm mb-3",children:y.map(t=>e.jsxs("option",{value:t.name,children:[t.is_flow?"▶ ":"",t.name]},t.id))}),e.jsx("label",{className:"block text-[10px] uppercase tracking-wide text-muted-foreground mb-1",children:"Fires"}),e.jsx("div",{className:"flex items-center rounded-md border h-8 text-xs overflow-hidden w-fit mb-2",children:[["","always"],["nl","if…"],["structured","metric"]].map(([t,o],u)=>e.jsx("button",{type:"button",className:`px-2.5 h-full ${u>0?"border-l":""} ${D===t?"bg-primary text-primary-foreground":"hover:bg-muted"}`,onClick:()=>q(t),children:o},t))}),D==="nl"&&e.jsx(te,{value:Y,onChange:t=>U(t.target.value),placeholder:'e.g. "lost on price, not product"',className:"h-8 text-sm italic mb-2"}),D==="structured"&&e.jsxs("div",{className:"grid grid-cols-[1fr_58px_1fr] gap-1.5 mb-2",children:[e.jsx(te,{value:i,onChange:t=>$(t.target.value),placeholder:"CAC",className:"h-8 text-sm font-mono"}),e.jsx("select",{value:W,onChange:t=>he(t.target.value),className:"h-8 rounded-md border bg-background px-1 text-sm font-mono",children:[">","<",">=","<=","=","!="].map(t=>e.jsx("option",{value:t,children:t},t))}),e.jsx(te,{value:ne,onChange:t=>de(t.target.value),placeholder:"500",className:"h-8 text-sm font-mono"})]}),e.jsxs("div",{className:"flex gap-2 mt-4",children:[e.jsx(S,{size:"sm",className:"flex-1",disabled:ye,onClick:()=>void Ft(),children:ye?e.jsx(J,{className:"h-3.5 w-3.5 animate-spin"}):"Save"}),e.jsx(S,{size:"sm",variant:"outline",className:"text-destructive",onClick:()=>void Dt(Le.id),children:"Delete"})]})]}):x?(()=>{const t=["agent","skill"].includes(Re(x)??""),o=be.find(l=>l.agent_node===x),u=window.location.origin,f=`[[${V(x)}]]`,_=`curl -s -X POST ${u}/nests/${s}/context -H 'Content-Type: application/json' -d '{"selector":"${f}","hops":${G},"max_tokens":4000}'`,A=`curl -s -X PATCH ${u}/nests/${s}/nodes/${x} -H 'Content-Type: application/json' -d '{"append":"<your update>","changeNote":"via ctx"}'`;return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(Ce,{type:Re(x)}),e.jsx("h3",{className:"text-sm font-semibold truncate",children:V(x)})]}),e.jsx("p",{className:"text-xs text-muted-foreground font-mono truncate",children:x})]}),t&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs(S,{size:"sm",className:"w-full",onClick:async()=>{try{await Qe(s,x),re("Run created — a polling runner will pick it up"),setTimeout(()=>re(""),3e3)}catch(l){E(l instanceof Error?l.message:"Trigger failed")}},children:[e.jsx(At,{className:"h-3.5 w-3.5 mr-1.5"})," Run now"]}),ae&&e.jsx("p",{className:"text-[11px] text-emerald-600",children:ae}),e.jsx("label",{className:"block text-[10px] uppercase tracking-wide text-muted-foreground",children:"Schedule"}),o?e.jsxs("div",{className:"rounded-md border px-2.5 py-2 text-xs space-y-1.5",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{children:["every"," ",e.jsx("b",{children:o.every_minutes>=60?`${o.every_minutes/60}h`:`${o.every_minutes}m`}),o.enabled?"":" · paused"]}),e.jsx("div",{className:"flex-1"}),e.jsx("button",{type:"button",className:"text-primary hover:underline",onClick:async()=>{await Ie(s,o.id,{enabled:!o.enabled}),await xe()},children:o.enabled?"Pause":"Resume"}),e.jsx("button",{type:"button",className:"text-destructive hover:underline",onClick:async()=>{await yt(s,o.id),await xe()},children:"Remove"})]}),o.enabled&&o.next_due_at&&e.jsxs("div",{className:"text-muted-foreground",children:["next fire ~",Ee(o.next_due_at)]})]}):e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs("select",{value:we,onChange:l=>H(Number(l.target.value)),className:"h-8 rounded-md border bg-background px-2 text-sm flex-1",children:[e.jsx("option",{value:15,children:"every 15 minutes"}),e.jsx("option",{value:60,children:"every hour"}),e.jsx("option",{value:360,children:"every 6 hours"}),e.jsx("option",{value:1440,children:"every day"})]}),e.jsx(S,{size:"sm",className:"h-8",onClick:async()=>{try{await bt(s,{agent_node:x,every_minutes:we}),await xe()}catch(l){E(l instanceof Error?l.message:"Schedule failed")}},children:"Schedule"})]})]}),t&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"block text-[10px] uppercase tracking-wide text-muted-foreground",children:"Triggers — call this agent from outside"}),Fe.map(l=>e.jsxs("div",{className:"rounded-md border px-2 py-1.5 text-[11px] space-y-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(se,{variant:"secondary",className:"text-[10px]",children:l.preset}),e.jsxs("span",{className:"text-muted-foreground",children:["fired ",l.fire_count,"×"]}),e.jsx("div",{className:"flex-1"}),e.jsx("button",{type:"button",className:"text-destructive hover:underline",onClick:async()=>{await Ut(s,l.id),ge(await Je(s,x))},children:"Remove"})]}),l.url??p[l.id]?e.jsx("button",{type:"button",className:"w-full text-left font-mono break-all rounded bg-muted/40 px-1.5 py-1 hover:border-primary border border-transparent",title:"Copy the trigger URL — paste into a Slack slash command / Events API, Teams outgoing webhook, or any system that can POST",onClick:()=>De(`hook-${l.id}`,l.url??p[l.id]),children:Z===`hook-${l.id}`?"✓ copied":l.url??p[l.id]}):e.jsx("p",{className:"text-muted-foreground px-1.5",children:"URL was shown at creation only (like an API key). Remove + re-add to mint a fresh one."})]},l.id)),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs("select",{value:Pe,onChange:l=>a(l.target.value),className:"h-7 rounded-md border bg-background px-1.5 text-xs flex-1",children:[e.jsx("option",{value:"slack",children:"Slack (slash command / @mention)"}),e.jsx("option",{value:"teams",children:"Teams (outgoing webhook)"}),e.jsx("option",{value:"webhook",children:"Webhook (any system)"})]}),e.jsx(S,{size:"sm",variant:"outline",className:"h-7 px-2",onClick:async()=>{const l=await Xt(s,x,Pe);if(l.url){const M=`${l.id.slice(0,7)}…${l.id.slice(-4)}`;F(ce=>({...ce,[M]:l.url}))}ge(await Je(s,x))},children:e.jsx(oe,{className:"h-3.5 w-3.5"})})]}),e.jsx("p",{className:"text-[11px] text-muted-foreground",children:"Each trigger is a secret URL that queues a run — message text becomes the run's inputs. Add SLACK_SIGNING_SECRET to the Tool environment to verify Slack requests."})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"block text-[10px] uppercase tracking-wide text-muted-foreground",children:"Notify on output"}),v.length>0&&e.jsx("div",{className:"flex flex-wrap gap-1",children:v.map(l=>e.jsxs("span",{className:"inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[11px]",children:[l,e.jsx("button",{type:"button",className:"text-muted-foreground hover:text-destructive",title:"Stop notifying",onClick:async()=>{const M=await Gt(s,x,l);P(M.map(ce=>ce.user_email))},children:"✕"})]},l))}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(te,{value:z,onChange:l=>R(l.target.value),placeholder:"person@team.com",className:"h-7 text-xs flex-1",onKeyDown:async l=>{if(l.key==="Enter"&&z.includes("@")){const M=await mt(s,x,z.trim());P(M.map(ce=>ce.user_email)),R("")}}}),e.jsx(S,{size:"sm",variant:"outline",className:"h-7 px-2",disabled:!z.includes("@"),onClick:async()=>{const l=await mt(s,x,z.trim());P(l.map(M=>M.user_email)),R("")},children:e.jsx(oe,{className:"h-3.5 w-3.5"})})]}),e.jsx("p",{className:"text-[11px] text-muted-foreground",children:"Tagged people get an inbox notification when this node's output lands for review. (Slack/webhook delivery comes later — same table.)"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-[10px] uppercase tracking-wide text-muted-foreground mb-1",children:"Add a step after this"}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs("select",{value:X,onChange:l=>le(l.target.value),className:"h-8 rounded-md border bg-background px-2 text-sm flex-1 min-w-0",children:[e.jsx("option",{value:"",children:"Choose a document…"}),b.filter(l=>l.id!==x).map(l=>e.jsx("option",{value:l.id,children:l.title||l.id},l.id))]}),e.jsx(S,{size:"sm",className:"h-8",disabled:!X,onClick:()=>{ut(x,X),le("")},children:e.jsx(oe,{className:"h-3.5 w-3.5"})})]}),e.jsx("p",{className:"text-[11px] text-muted-foreground mt-1.5",children:"Or drag from the node's right port straight onto another card."})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-[10px] uppercase tracking-wide text-muted-foreground",children:"Use from CLI / agent"}),e.jsx("div",{className:"flex-1"}),e.jsx("select",{value:G,onChange:l=>Te(Number(l.target.value)),className:"h-6 rounded border bg-background px-1 text-[11px]",title:"How many hops of linked context to pull with it",children:[0,1,2,3].map(l=>e.jsxs("option",{value:l,children:[l," hop",l===1?"":"s"]},l))})]}),e.jsx("button",{type:"button",className:"w-full text-left rounded-md border bg-muted/40 px-2 py-1.5 text-[10.5px] font-mono break-all hover:border-primary",onClick:()=>De("sel",f),title:"Copy the selector",children:Z==="sel"?"✓ copied":f}),e.jsx("button",{type:"button",className:"w-full text-left rounded-md border bg-muted/40 px-2 py-1.5 text-[10.5px] font-mono break-all hover:border-primary",onClick:()=>De("read",_),title:"Copy — deterministic read: this node + linked context",children:Z==="read"?"✓ copied":`read → ${_.slice(0,64)}…`}),e.jsx("button",{type:"button",className:"w-full text-left rounded-md border bg-muted/40 px-2 py-1.5 text-[10.5px] font-mono break-all hover:border-primary",onClick:()=>De("write",A),title:"Copy — governed write: append to this node (lands as a new version / review request)",children:Z==="write"?"✓ copied":`write → ${A.slice(0,64)}…`}),e.jsx(S,{variant:"outline",size:"sm",className:"w-full h-7 text-xs",disabled:ue,onClick:async()=>{var l;ie(!0);try{const M=await Jt(s,f,G);I({text:M.context||"(empty context)",nodes:((l=M.trace)==null?void 0:l.nodes_traversed)??M.nodes_traversed??0})}catch(M){E(M instanceof Error?M.message:"Preview failed")}finally{ie(!1)}},children:ue?e.jsx(J,{className:"h-3.5 w-3.5 animate-spin"}):e.jsxs(e.Fragment,{children:["Test: preview what it reads (",G," hop",G===1?"":"s",")"]})}),Q&&e.jsxs("div",{className:"rounded-md border bg-muted/30 p-2",children:[e.jsxs("div",{className:"flex items-center text-[10px] text-muted-foreground mb-1",children:[e.jsxs("span",{children:[Q.nodes," node",Q.nodes===1?"":"s"," assembled — exactly what a run reads"]}),e.jsx("button",{type:"button",className:"ml-auto hover:text-foreground",onClick:()=>I(null),children:"✕"})]}),e.jsxs("pre",{className:"max-h-56 overflow-auto whitespace-pre-wrap text-[10.5px] leading-relaxed",children:[Q.text.slice(0,4e3),Q.text.length>4e3?`
|
|
16
|
+
…(truncated)`:""]})]})]})]})})():e.jsxs("div",{className:"text-sm text-muted-foreground",children:[e.jsx("p",{className:"font-medium text-foreground mb-1",children:"Nothing selected"}),e.jsxs("p",{className:"text-xs",children:["Click a ",e.jsx("b",{children:"wire"})," to change its type or condition, click a"," ",e.jsx("b",{children:"card"})," to add a next step, or drag from a card's right port onto another card to connect them."]})]})})]})}function Ds({nestId:s}){const[m,g]=r.useState([]),[y,C]=r.useState([]),[b,j]=r.useState(!0),[k,d]=r.useState(null),[h,E]=r.useState(""),[N,w]=r.useState(60),[x,O]=r.useState(""),[c,L]=r.useState(!1),T=r.useCallback(async()=>{j(!0);try{const[i,$]=await Promise.all([jt(s),Ue(s).then(W=>W.nodes).catch(()=>[])]);g(i),C($),d(null)}catch(i){d(i instanceof Error?i.message:"Failed to load schedules")}finally{j(!1)}},[s]);r.useEffect(()=>{T()},[T]);const B=i=>{var $;return(($=y.find(W=>W.id===i))==null?void 0:$.title)||i.replace(/^nodes\//,"")},D=i=>{var $;return($=y.find(W=>W.id===i))==null?void 0:$.type},q=y.filter(i=>i.type==="agent"||i.type==="skill"),Y=q.filter(i=>!m.some($=>$.agent_node===i.id)),U=i=>i>=1440?`${i/1440}d`:i>=60?`${i/60}h`:`${i}m`;return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("p",{className:"text-sm text-muted-foreground",children:["A schedule decides ",e.jsx("b",{children:"when a run starts"})," and its stop-after bound decides ",e.jsx("b",{children:"when it's done"}),". What happens ",e.jsx("em",{children:"inside"})," a run — which step fires, on what condition — lives on the wires in the Canvas (click a wire to set always / if… / metric). Scheduled output still lands as a review request; scheduling doesn't skip governance."]}),k&&e.jsx("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive",children:k}),b?e.jsx("div",{className:"py-8 text-center text-muted-foreground",children:e.jsx(J,{className:"h-4 w-4 animate-spin inline"})}):m.length===0?e.jsxs("div",{className:"rounded-lg border border-dashed p-6 text-center",children:[e.jsx(ws,{className:"h-6 w-6 text-muted-foreground/50 mx-auto mb-2"}),e.jsx("p",{className:"text-sm font-medium mb-1",children:"Nothing on the clock yet"}),e.jsx("p",{className:"text-xs text-muted-foreground",children:q.length?"Pick an agent below — every interval, the server files a run for it.":"This nest has no runnable agents yet. Create one from Documents → New → type Agent (its body is the instructions), then schedule it here."})]}):e.jsx("div",{className:"rounded-lg border divide-y",children:m.map(i=>e.jsxs("div",{className:"px-3 py-2.5 flex items-center gap-2 text-sm",children:[e.jsx(Ce,{type:D(i.agent_node)}),e.jsx("span",{className:"truncate font-medium",title:i.agent_node,children:B(i.agent_node)}),e.jsxs(se,{variant:"secondary",className:"text-[10px] shrink-0",children:["every ",U(i.every_minutes)]}),i.max_runs!==null&&e.jsxs(se,{variant:"outline",className:"text-[10px] shrink-0",title:"Stops automatically after this many runs",children:[i.runs_created,"/",i.max_runs," runs"]}),i.enabled?i.next_due_at&&e.jsxs("span",{className:"text-[11px] text-muted-foreground shrink-0",children:["next ~",Ee(i.next_due_at)]}):i.max_runs!==null&&i.runs_created>=i.max_runs?e.jsx(se,{className:"text-[10px] shrink-0 bg-emerald-600",children:"done"}):e.jsx(se,{variant:"outline",className:"text-[10px] shrink-0",children:"paused"}),e.jsx("div",{className:"flex-1"}),e.jsxs("select",{value:i.every_minutes,onChange:async $=>{await Ie(s,i.id,{every_minutes:Number($.target.value)}),await T()},className:"h-7 rounded-md border bg-background px-1.5 text-xs shrink-0",title:"Change the interval",children:[[15,60,360,1440].map($=>e.jsx("option",{value:$,children:U($)},$)),![15,60,360,1440].includes(i.every_minutes)&&e.jsx("option",{value:i.every_minutes,children:U(i.every_minutes)})]}),e.jsx(S,{variant:"outline",size:"sm",className:"h-7 text-xs shrink-0",onClick:async()=>{await Ie(s,i.id,{enabled:!i.enabled}),await T()},children:i.enabled?"Pause":"Resume"}),e.jsx(S,{variant:"ghost",size:"icon",className:"h-7 w-7 text-muted-foreground hover:text-destructive shrink-0",onClick:async()=>{await yt(s,i.id),await T()},title:"Remove schedule",children:e.jsx(ze,{className:"h-3.5 w-3.5"})})]},i.id))}),e.jsxs("div",{className:"rounded-lg border bg-muted/20 p-3",children:[e.jsx("div",{className:"text-xs font-medium mb-2",children:"Put an agent on the clock"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("select",{value:h,onChange:i=>E(i.target.value),className:"h-8 rounded-md border bg-background px-2 text-sm flex-1 min-w-0","data-testid":"schedule-agent-lookup",children:[e.jsx("option",{value:"",children:Y.length?"Choose an agent…":"Every runnable agent is scheduled"}),Y.map(i=>e.jsxs("option",{value:i.id,children:[i.type==="agent"?"🤖 ":"⚡ ",i.title||i.id]},i.id))]}),e.jsxs("select",{value:N,onChange:i=>w(Number(i.target.value)),className:"h-8 rounded-md border bg-background px-2 text-sm",children:[e.jsx("option",{value:15,children:"every 15 minutes"}),e.jsx("option",{value:60,children:"every hour"}),e.jsx("option",{value:360,children:"every 6 hours"}),e.jsx("option",{value:1440,children:"every day"})]}),e.jsxs("select",{value:x,onChange:i=>O(i.target.value===""?"":Number(i.target.value)),className:"h-8 rounded-md border bg-background px-2 text-sm",title:"The stop condition: pause automatically after this many runs",children:[e.jsx("option",{value:"",children:"until stopped"}),e.jsx("option",{value:1,children:"once"}),e.jsx("option",{value:5,children:"stop after 5"}),e.jsx("option",{value:10,children:"stop after 10"}),e.jsx("option",{value:25,children:"stop after 25"})]}),e.jsxs(S,{size:"sm",className:"h-8",disabled:c||!h,onClick:async()=>{L(!0);try{await bt(s,{agent_node:h,every_minutes:N,max_runs:x===""?null:x}),E(""),await T()}catch(i){d(i instanceof Error?i.message:"Schedule failed")}finally{L(!1)}},children:[e.jsx(oe,{className:"h-3.5 w-3.5 mr-1"})," Schedule"]})]})]})]})}function Hs({nestId:s}){const[m,g]=r.useState([]),[y,C]=r.useState(null),[b,j]=r.useState(""),[k,d]=r.useState(""),[h,E]=r.useState(!1),N=r.useCallback(async()=>{try{g(await Nt(s)),C(null)}catch(w){C(w instanceof Error?w.message:"Failed to load env")}},[s]);return r.useEffect(()=>{N()},[N]),e.jsxs("details",{className:"rounded-lg border px-4 py-3",children:[e.jsxs("summary",{className:"cursor-pointer select-none text-sm font-medium flex items-center gap-2",children:[e.jsx(St,{className:"h-4 w-4 text-teal-500 inline"})," Tool environment (",m.length," key",m.length===1?"":"s",")"]}),e.jsxs("div",{className:"mt-3 space-y-3",children:[e.jsxs("p",{className:"text-[11px] text-muted-foreground",children:["Credentials for ",e.jsx("b",{children:"tool"})," nodes. Values are write-only here and travel to the runner inside the run bundle. Stored alongside nest content, not encrypted — treat this box like the nest itself."]}),y&&e.jsx("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive",children:y}),m.length>0&&e.jsx("div",{className:"rounded-md border divide-y",children:m.map(w=>e.jsxs("div",{className:"px-3 py-1.5 flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"font-mono font-medium",children:w.key}),e.jsx("span",{className:"font-mono text-muted-foreground",children:w.value_masked}),e.jsx("div",{className:"flex-1"}),e.jsx("span",{className:"text-muted-foreground",children:w.updated_by}),e.jsx(S,{variant:"ghost",size:"icon",className:"h-6 w-6 text-muted-foreground hover:text-destructive",title:"Delete key",onClick:async()=>{await ns(s,w.key),await N()},children:e.jsx(ze,{className:"h-3.5 w-3.5"})})]},w.key))}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx(te,{value:b,onChange:w=>j(w.target.value.toUpperCase()),placeholder:"SLACK_TOKEN",className:"h-8 text-xs font-mono w-44"}),e.jsx(te,{value:k,onChange:w=>d(w.target.value),placeholder:"value (write-only)",type:"password",className:"h-8 text-xs font-mono flex-1"}),e.jsx(S,{size:"sm",className:"h-8",disabled:h||!/^[A-Z][A-Z0-9_]*$/.test(b)||!k,onClick:async()=>{E(!0);try{await wt(s,b,k),j(""),d(""),await N()}catch(w){C(w instanceof Error?w.message:"Save failed")}finally{E(!1)}},children:h?e.jsx(J,{className:"h-3.5 w-3.5 animate-spin"}):"Set"})]})]})]})}function Ks({nestId:s}){const[m,g]=r.useState(null),[y,C]=r.useState(""),[b,j]=r.useState(!1),[k,d]=r.useState(null),[h,E]=r.useState(!1);return r.useEffect(()=>{let N=!1;return Promise.all([Nt(s).catch(()=>null),Qt().catch(()=>null)]).then(([w,x])=>{if(!N){if(x!=null&&x.runner_key_configured)return g(!0);if(!w)return g(null);g(w.some(O=>O.key==="ANTHROPIC_API_KEY"))}}),()=>{N=!0}},[s]),m!==!1?h?e.jsx("div",{className:"rounded-lg border border-emerald-400/50 bg-emerald-500/5 px-4 py-3 text-sm",children:"✓ Key stored (masked from here on). Runners pick it up from the run bundle — start one in poll mode and your queued runs execute."}):null:e.jsxs("div",{className:"rounded-lg border border-amber-400/60 bg-amber-500/5 px-4 py-3",children:[e.jsx("div",{className:"text-sm font-medium mb-1",children:"🔑 Add your Anthropic API key to execute runs"}),e.jsx("p",{className:"text-xs text-muted-foreground mb-2",children:"Runs are created here, but a runner needs a key to call the model. Paste it once — it's stored write-only for this nest (masked everywhere, delivered to runners inside the run bundle). Get one at console.anthropic.com → Settings → API keys."}),k&&e.jsx("p",{className:"text-xs text-destructive mb-2",children:k}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(te,{type:"password",value:y,onChange:N=>C(N.target.value),placeholder:"sk-ant-…",className:"h-8 text-sm font-mono flex-1","data-testid":"runner-key-input"}),e.jsx(S,{size:"sm",className:"h-8",disabled:b||!y.trim().startsWith("sk-"),onClick:async()=>{j(!0);try{await wt(s,"ANTHROPIC_API_KEY",y.trim()),C(""),g(!0),E(!0)}catch(N){d(N instanceof Error?N.message:"Save failed")}finally{j(!1)}},children:b?e.jsx(J,{className:"h-3.5 w-3.5 animate-spin"}):"Save key"})]})]})}const Vs=[["review_requested","review requested"],["review_approved","approved"],["review_rejected","rejected"],["run_failed","run failed"],["mention","mentioned"]];function Bs({nestId:s}){const[m,g]=r.useState([]),[y,C]=r.useState(null),[b,j]=r.useState("slack"),[k,d]=r.useState(""),[h,E]=r.useState(["*"]),[N,w]=r.useState(!1),x=r.useCallback(async()=>{try{g(await It(s)),C(null)}catch(c){C(c instanceof Error?c.message:"Failed to load connectors")}},[s]);r.useEffect(()=>{x()},[x]);const O=c=>{E(L=>{if(c==="*")return["*"];const T=L.filter(B=>B!=="*"&&B!==c);return L.includes(c)?T.length?T:["*"]:[...T,c]})};return e.jsxs("details",{className:"rounded-lg border px-4 py-3",open:m.length>0,children:[e.jsxs("summary",{className:"cursor-pointer select-none text-sm font-medium",children:["📤 Connectors (",m.length,") — send events to Slack / Teams / webhooks"]}),e.jsxs("div",{className:"mt-3 space-y-3",children:[e.jsx("p",{className:"text-[11px] text-muted-foreground",children:"Governance + run events post to each matching channel. Fire-and-forget — a channel outage never blocks a review. The server-wide Slack webhook (super-admin Settings) always fires too."}),y&&e.jsx("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive",children:y}),m.length>0&&e.jsx("div",{className:"rounded-md border divide-y",children:m.map(c=>e.jsxs("div",{className:"px-3 py-2 flex items-center gap-2 text-xs",children:[e.jsx(se,{variant:"secondary",className:"text-[10px] shrink-0",children:c.channel}),e.jsx("span",{className:"font-mono truncate",children:c.url}),e.jsx("span",{className:"text-muted-foreground shrink-0",children:c.events.includes("*")?"all events":c.events.join(", ")}),e.jsx("div",{className:"flex-1"}),e.jsx(S,{variant:"outline",size:"sm",className:"h-6 text-[11px] px-2 shrink-0",onClick:async()=>{await es(s,c.id,{enabled:!c.enabled}),await x()},children:c.enabled?"Pause":"Resume"}),e.jsx(S,{variant:"ghost",size:"icon",className:"h-6 w-6 text-muted-foreground hover:text-destructive shrink-0",onClick:async()=>{await ts(s,c.id),await x()},title:"Delete connector",children:e.jsx(ze,{className:"h-3.5 w-3.5"})})]},c.id))}),e.jsxs("div",{className:"space-y-2 rounded-md border bg-muted/20 p-2.5",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs("select",{value:b,onChange:c=>j(c.target.value),className:"h-8 rounded-md border bg-background px-1.5 text-xs",children:[e.jsx("option",{value:"slack",children:"Slack"}),e.jsx("option",{value:"teams",children:"Teams"}),e.jsx("option",{value:"webhook",children:"Webhook (raw JSON)"})]}),e.jsx(te,{value:k,onChange:c=>d(c.target.value),placeholder:"https://hooks.slack.com/… or env:SLACK_WEBHOOK",className:"h-8 text-xs font-mono flex-1"}),e.jsx(S,{size:"sm",className:"h-8",disabled:N||!(k.startsWith("https://")||k.startsWith("env:")),onClick:async()=>{w(!0);try{await ss(s,{channel:b,url:k.trim(),events:h}),d(""),E(["*"]),await x()}catch(c){C(c instanceof Error?c.message:"Create failed")}finally{w(!1)}},children:e.jsx(oe,{className:"h-3.5 w-3.5"})})]}),e.jsxs("div",{className:"flex items-center flex-wrap gap-1 text-[11px]",children:[e.jsx("button",{type:"button",className:`rounded-full border px-2 py-0.5 ${h.includes("*")?"bg-primary text-primary-foreground border-primary":"hover:bg-muted"}`,onClick:()=>O("*"),children:"all events"}),Vs.map(([c,L])=>e.jsx("button",{type:"button",className:`rounded-full border px-2 py-0.5 ${h.includes(c)?"bg-primary text-primary-foreground border-primary":"hover:bg-muted"}`,onClick:()=>O(c),children:L},c))]})]})]})]})}function bn(){const s=ms();return e.jsx(Ts,{nestId:s.nestId,nestName:s.nestName,onBack:s.leaveNest})}export{bn as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as a}from"./index-B5hLclEq.js";/**
|
|
2
|
+
* @license lucide-react v0.577.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const o=[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]],e=a("play",o);export{e as P};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c as e}from"./index-B5hLclEq.js";/**
|
|
2
|
+
* @license lucide-react v0.577.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const c=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],a=e("refresh-cw",c);export{a as R};
|