@promptowl/contextnest-community 1.25.0 → 1.26.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 +68 -8
- package/CONFIGURATION.md +572 -116
- package/README.md +3 -2
- package/dist/{chunk-32SZCH36.js → chunk-2QOJE7A5.js} +4 -4
- package/dist/{chunk-2KHM5C7V.js → chunk-DGPTJXIV.js} +13 -15
- package/dist/chunk-I5EDEZBQ.js +523 -0
- package/dist/{chunk-TI7HMP64.js → chunk-IEAWRHMV.js} +2 -2
- package/dist/{chunk-DTLMBF4W.js → chunk-M6PGYMBD.js} +15 -8
- package/dist/{chunk-F66VCBLA.js → chunk-PICUHQEM.js} +51 -2
- package/dist/{chunk-KPGNZLZL.js → chunk-RPGFHESR.js} +1 -1
- package/dist/{chunk-7FROMOZM.js → chunk-SWA5M5XX.js} +68 -544
- package/dist/{chunk-JDAOA5KP.js → chunk-TRSGPS27.js} +39 -14
- package/dist/{engine-TER6FDBP.js → engine-QNMFDIBV.js} +3 -2
- package/dist/{external-edit-service-CAGENHDJ.js → external-edit-service-4MEGPT4D.js} +4 -3
- package/dist/{grants-service-2OTFS7EH.js → grants-service-24GLUBY4.js} +2 -2
- package/dist/index.js +911 -263
- package/dist/invited-user-AM6A3WGO.js +12 -0
- package/dist/{migrations.postgres-23VJJJJX.js → migrations.postgres-HGSQ7IA5.js} +4 -0
- package/dist/{review-service-4G2XUFS6.js → review-service-2EWN7WWO.js} +7 -6
- package/dist/{stewardship-service-S22V2JKG.js → stewardship-service-TDZUC2Q6.js} +4 -3
- package/dist/{version-service-X4FAG2OZ.js → version-service-C3JTZLJH.js} +4 -3
- package/dist/web3/assets/ActivityTracePage-DzwWIjjx.js +1 -0
- package/dist/web3/assets/{AgentDocsPage-Dkhgb1hk.js → AgentDocsPage-ixP2UdAE.js} +1 -1
- package/dist/web3/assets/CollaboratorManager-C9VAXZ0h.js +1 -0
- package/dist/web3/assets/CollaboratorsTab-tq4ZTexH.js +1 -0
- package/dist/web3/assets/DocumentEditor-C2CP2fiE.js +36 -0
- package/dist/web3/assets/DocumentsTab-Mh7KxUoB.js +6 -0
- package/dist/web3/assets/ExternalEditsTab-B_CWKXZ_.js +1 -0
- package/dist/web3/assets/{MarkdownEditor-Dfk5uIE5.js → MarkdownEditor-CKh4WSn-.js} +136 -131
- package/dist/web3/assets/MarkdownEditor-ndtIx5x0.css +1 -0
- package/dist/web3/assets/NestPageHeader-Cizo8nUi.js +1 -0
- package/dist/web3/assets/NestView-EW-sraEb.js +73 -0
- package/dist/web3/assets/OverviewTab-CjidsMX_.js +6 -0
- package/dist/web3/assets/PersonCombobox-BKI7dff4.js +1 -0
- package/dist/web3/assets/{ReviewActions-BXDTDPp1.js → ReviewActions-CS8JXgXF.js} +2 -2
- package/dist/web3/assets/ReviewTab-CwVrXzw5.js +1 -0
- package/dist/web3/assets/StewardsTab-C-iP6gnh.js +1 -0
- package/dist/web3/assets/SubmitForReviewModal-Biq3m79i.js +1 -0
- package/dist/web3/assets/{alert-dialog-4SiLKlz8.js → alert-dialog-BvF3NFr7.js} +2 -2
- package/dist/web3/assets/{arrow-left-BAgIocLn.js → arrow-left-CWIsv-sG.js} +1 -1
- package/dist/web3/assets/backlinks-Cqcn7n1J.js +19 -0
- package/dist/web3/assets/boxes-ClbgQqG2.js +6 -0
- package/dist/web3/assets/{chevron-left-XR4ReJ9Z.js → chevron-left-CK_ZPFm9.js} +1 -1
- package/dist/web3/assets/{circle-check-CSkZUEFK.js → circle-check-Bw_aTXiH.js} +1 -1
- package/dist/web3/assets/{circle-x-in2o3aHU.js → circle-x-DkIG68H7.js} +1 -1
- package/dist/web3/assets/{code-xml-pPQgdctI.js → code-xml-BlR7EN6l.js} +1 -1
- package/dist/web3/assets/{corner-down-right-CuxZWscX.js → corner-down-right-DSVxK3tf.js} +1 -1
- package/dist/web3/assets/count-skeleton-DToLM74B.js +1 -0
- package/dist/web3/assets/{earth-CXOcThqn.js → earth-BXhVPvCR.js} +1 -1
- package/dist/web3/assets/{file-exclamation-point-CSphs1VD.js → file-exclamation-point-BevGZgtj.js} +1 -1
- package/dist/web3/assets/{folder-input-BAwK9tFL.js → folder-input-m8UBV4fA.js} +1 -1
- package/dist/web3/assets/{index-A0_ymcqL.js → index-BOVYgMvj.js} +1 -1
- package/dist/web3/assets/index-DVnaYqj9.css +1 -0
- package/dist/web3/assets/index-WYDmEOfO.js +404 -0
- package/dist/web3/assets/page-B6pkc9cd.js +2 -0
- package/dist/web3/assets/page-BJrFCKXB.js +1 -0
- package/dist/web3/assets/page-Bgy9Ng9p.js +1 -0
- package/dist/web3/assets/page-C2zoxumw.js +1 -0
- package/dist/web3/assets/page-CJWO06dN.js +1 -0
- package/dist/web3/assets/page-CptuAPJc.js +6 -0
- package/dist/web3/assets/page-DPY01SOj.js +1 -0
- package/dist/web3/assets/page-Dea2SblF.js +9 -0
- package/dist/web3/assets/page-Deq6IKiN.js +6 -0
- package/dist/web3/assets/page-Dfjg8p7Z.js +1 -0
- package/dist/web3/assets/{page-xzYqkBUP.js → page-Dh57L0RG.js} +5 -5
- package/dist/web3/assets/page-Dwbp4Seu.js +6 -0
- package/dist/web3/assets/{page-CUjuSs5Q.js → page-DzKwP5Ds.js} +3 -3
- package/dist/web3/assets/page-YxjrE5b5.js +45 -0
- package/dist/web3/assets/{page-title-BkqlUA0j.js → page-title-DVq4qvMR.js} +1 -1
- package/dist/web3/assets/{play-B8xE9j5f.js → play-CXhS6Pgq.js} +1 -1
- package/dist/web3/assets/{send-CvAgOUPG.js → send-DdfwnIrj.js} +1 -1
- package/dist/web3/assets/{settings-EY4A_DYv.js → settings-DKX0Q4gO.js} +1 -1
- package/dist/web3/assets/{share-2-vGmZUl90.js → share-2-CxmXRt58.js} +1 -1
- package/dist/web3/assets/{tag-Br_y1f00.js → tag-DeYC_mRv.js} +1 -1
- package/dist/web3/assets/{trash-2-B4hRXo-p.js → trash-2-B0HyPTnI.js} +1 -1
- package/dist/web3/assets/{user-plus-4CTYEkd3.js → user-plus-Ckm_Isyc.js} +1 -1
- package/dist/web3/assets/{x-qxt1WrUi.js → x-mNtADYHc.js} +1 -1
- package/dist/web3/assets/{zap-BcsKR0ef.js → zap-D2ifcnYb.js} +1 -1
- package/dist/web3/index.html +2 -2
- package/package.json +3 -2
- package/dist/client-D44ZHDTJ.js +0 -11
- package/dist/keys-CTOGAG3W.js +0 -20
- package/dist/web3/assets/ActivityTracePage-D2iIbEph.js +0 -1
- package/dist/web3/assets/CollaboratorManager-Bo81D--Q.js +0 -1
- package/dist/web3/assets/CollaboratorsTab-DRCitQuX.js +0 -1
- package/dist/web3/assets/DocumentEditor-DV2WHYbj.js +0 -36
- package/dist/web3/assets/DocumentsTab-BUxBCN8o.js +0 -6
- package/dist/web3/assets/ExternalEditsTab-kIBimZyE.js +0 -1
- package/dist/web3/assets/MarkdownEditor-CsVusP2d.css +0 -1
- package/dist/web3/assets/NestPageHeader-yOK-OIYZ.js +0 -1
- package/dist/web3/assets/NestView-DwIagxwJ.js +0 -68
- package/dist/web3/assets/OverviewTab-DFOFMVyE.js +0 -1
- package/dist/web3/assets/PersonCombobox-D350WlrJ.js +0 -1
- package/dist/web3/assets/ReasonDialog-CN3ECAnQ.js +0 -1
- package/dist/web3/assets/ReviewTab-CZewAYiz.js +0 -1
- package/dist/web3/assets/StewardsTab-AagNWcWS.js +0 -1
- package/dist/web3/assets/SubmitForReviewModal-BOZJxwRN.js +0 -1
- package/dist/web3/assets/backlinks-Cb8Uf8mw.js +0 -24
- package/dist/web3/assets/card-UDyMRcps.js +0 -1
- package/dist/web3/assets/count-skeleton-DBWCDhRy.js +0 -1
- package/dist/web3/assets/dates-BCxbm4_q.js +0 -1
- package/dist/web3/assets/index-B5hLclEq.js +0 -389
- package/dist/web3/assets/index-DrUAtoQM.css +0 -1
- package/dist/web3/assets/page-BHD4beun.js +0 -1
- package/dist/web3/assets/page-BSYUXYmO.js +0 -11
- package/dist/web3/assets/page-BYc2DIux.js +0 -45
- package/dist/web3/assets/page-BfibLg8e.js +0 -1
- package/dist/web3/assets/page-CGe8MtUu.js +0 -9
- package/dist/web3/assets/page-CIgPJmG6.js +0 -2
- package/dist/web3/assets/page-Ck31nx9b.js +0 -1
- package/dist/web3/assets/page-Cpdj_11Y.js +0 -1
- package/dist/web3/assets/page-D0sN3GO6.js +0 -1
- package/dist/web3/assets/page-DEpH91X2.js +0 -1
- package/dist/web3/assets/page-l8-B7CGt.js +0 -1
- package/dist/web3/assets/page-mnSHmk6A.js +0 -6
- package/dist/web3/assets/refresh-cw-CsCtmWwX.js +0 -6
- package/dist/web3/assets/scroll-area-CbcH6yrZ.js +0 -1
- package/dist/web3/assets/scroll-area-dRWncRqa.css +0 -1
- package/dist/web3/assets/select-DrL0mpRN.js +0 -6
- package/dist/web3/assets/triangle-alert-CsYGyfGZ.js +0 -6
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import{c as gt,r,j as e,
|
|
1
|
+
import{c as gt,r,j as e,S as Kt,V as Bt,W as Ke,X as Be,b7 as ft,b8 as vt,b9 as Xe,ba as jt,bb as qt,bc as Je,I as te,B as S,R as st,L as J,bd as Qe,be as Ie,bf as bt,bg as yt,e as se,bh as Xt,a_ as oe,bi as Ut,bj as Gt,bk as mt,bl as Jt,Q as Yt,bm as Zt,bn as Nt,bo as Qt,bp as wt,bq as It,br as es,bs as ts,bt as ss,bu as ns,a6 as as,F as rs,bv as kt,bw as os,bx as _t,f as ls,aE as is,ah as St,ai as Ct,aj as Et,ak as Tt,al as et,by as qe,bz as cs,bA as ds,aP as us,aq as ms,b2 as xs}from"./index-WYDmEOfO.js";import{A as Ye,W as $t,T as hs,O as ps}from"./MarkdownEditor-CKh4WSn-.js";import{F as gs,N as We}from"./NestView-EW-sraEb.js";import{N as fs}from"./NestPageHeader-Cizo8nUi.js";import{P as At}from"./play-CXhS6Pgq.js";import{T as ze}from"./trash-2-B0HyPTnI.js";import{Z as Pt,F as vs}from"./zap-D2ifcnYb.js";import{C as nt}from"./corner-down-right-DSVxK3tf.js";import{X as Rt}from"./x-mNtADYHc.js";import{A as js}from"./arrow-left-CWIsv-sG.js";import"./index-BOVYgMvj.js";import"./chevron-left-CK_ZPFm9.js";import"./alert-dialog-BvF3NFr7.js";import"./count-skeleton-DToLM74B.js";import"./folder-input-m8UBV4fA.js";import"./PersonCombobox-BKI7dff4.js";import"./tag-DeYC_mRv.js";import"./user-plus-Ckm_Isyc.js";import"./ReviewActions-CS8JXgXF.js";import"./circle-check-Bw_aTXiH.js";import"./circle-x-DkIG68H7.js";import"./settings-DKX0Q4gO.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const
|
|
6
|
+
*/const bs=[["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"}]],ys=gt("bell",bs);/**
|
|
7
7
|
* @license lucide-react v0.577.0 - ISC
|
|
8
8
|
*
|
|
9
9
|
* This source code is licensed under the ISC license.
|
|
10
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 \\
|
|
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,b=g.length>xt?`${g.slice(0,xt-1).trimEnd()}…`:g;return{full:g,short:b,width:b.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(us,{className:"h-3.5 w-3.5"}):s==="branch"?e.jsx(Pt,{className:"h-3.5 w-3.5"}):s==="write"?e.jsx(ms,{className:"h-3.5 w-3.5"}):s==="notify"?e.jsx(ys,{className:"h-3.5 w-3.5"}):e.jsx("span",{className:"h-3.5 w-3.5"}),Ee=s=>ls(s)||s;function Ts({nestId:s,nestName:m,onBack:g}){const[b,C]=r.useState("canvas");return e.jsxs("div",{children:[e.jsx(fs,{nestName:m,onBack:g}),e.jsxs(Kt,{value:b,onValueChange:C,children:[e.jsxs(Bt,{children:[e.jsx(Ke,{value:"canvas",children:"Canvas"}),e.jsx(Ke,{value:"table",children:"Table"}),e.jsx(Ke,{value:"run",children:"Run"}),e.jsx(Ke,{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(Vs,{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($t,{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([]),[b,C]=r.useState([]),[y,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,X]=r.useState(""),[i,$]=r.useState(">"),[W,he]=r.useState(""),[ne,de]=r.useState(!1),[be,pe]=r.useState(!1),U=r.useCallback(async()=>{var n;j(!0);try{const[v,P,z]=await Promise.all([ft(s),vt(s),Xe(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(()=>{U()},[U]);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(""),X(""),he(""),B(""),await U()}catch(v){d(v instanceof Error?v.message:"Failed to add edge")}finally{de(!1)}},ye=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=b.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:()=>ye(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=>X(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:b.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 U(),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}),y?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:()=>ye(n),children:[e.jsx(oe,{className:"h-3.5 w-3.5 mr-1"})," Step"]})]}),ue(n,0,new Set([n]))]},n)),be||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:b,testId:C,disabledReason:y}){return e.jsxs(St,{value:s||void 0,onValueChange:m,children:[e.jsx(Ct,{className:"h-9 w-full","data-testid":C,disabled:!g.length,children:e.jsx(Et,{placeholder:g.length?b:"No runnable agents yet"})}),e.jsx(Tt,{children:g.map(j=>{const k=(y==null?void 0:y(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:b,runType:C,blockedReason:y}){const j="__none__",k=g.filter(d=>d.status==="running");return e.jsxs(St,{value:s||j,onValueChange:d=>m(d===j?"":d),children:[e.jsx(Ct,{className:"h-auto min-h-9 w-full","data-testid":"run-parent-lookup",children:e.jsx(Et,{})}),e.jsxs(Tt,{children:[e.jsx(et,{value:j,children:"— None (top-level run)"}),k.map(d=>{const h=y(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:b(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:b}=Yt(),C=g||Ps,y=b||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(""),[X,i]=r.useState(""),[$,W]=r.useState(""),[he,ne]=r.useState(""),[de,be]=r.useState(!1),[pe,U]=r.useState(null),[le,ye]=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),Xe(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 ds(a))}catch(p){x(p instanceof Error?p.message:"Failed to load run")}},G=async a=>{ye(a);try{await cs(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{ye(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()){be(!0),U(null);try{await Qe(s,$.trim(),Te(he),a),i(""),W(""),ne(""),await H()}catch(p){U(p instanceof Error?p.message:"Failed to spawn sub-agent")}finally{be(!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)>=y?`${y}/${y} 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:V=>{(V.key==="Enter"||V.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 V=[];return m&&(a.depth??0)<C&&P(a.id)<y&&V.push({label:X===a.id?"Close sub-agent form":"Spawn sub-agent",icon:oe,testId:"run-action-spawn",onSelect:()=>{i(X===a.id?"":a.id),W(""),ne(""),U(null)}}),V.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:V,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&&X===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:V=>z(a.id).has(V)?"already in this chain":null}),e.jsx("textarea",{value:he,onChange:V=>ne(V.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(""),U(null)},children:"Cancel"})]})]}),F.map(V=>Pe(V,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
12
|
-e CONTEXTNEST_SERVER=http://localhost:4040 \\
|
|
13
13
|
-e CONTEXTNEST_NEST=${s} \\
|
|
14
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};
|
|
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:b=d=>d,typeOf:C=()=>{},onOpen:y,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 ",b(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:()=>y==null?void 0:y(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 ",b(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:()=>y==null?void 0:y(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:b(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([]),[b,C]=r.useState([]),[y,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,X]=r.useState(""),[i,$]=r.useState(""),[W,he]=r.useState(">"),[ne,de]=r.useState(""),[be,pe]=r.useState(!1),[U,le]=r.useState(""),[ye,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),[V,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),Xe(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)=>{is(o).then(u=>{u&&($e(t),setTimeout(()=>$e(""),1500))})};r.useEffect(()=>{xe()},[xe]);const rt=new Map(y.map(t=>[t.id,t])),K=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(K(l)).localeCompare(K(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=y.map(t=>t.id).filter(t=>!ee.has(t)).filter(t=>!He||K(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)||K(t).localeCompare(K(o))}),Oe=lt+46,it=Math.max(Ot,V>0?Math.floor(V):920),Ue=Math.max(1,Math.floor((it-Se*2)/(_e+46)));Me.forEach((t,o)=>{ee.set(t,{id:t,x:Se+o%Ue*(_e+46),y:Oe+Math.floor(o/Ue)*(je+28)})});const ct=it,Lt=Me.length?Oe+Math.ceil(Me.length/Ue)*(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)}}),Ve=t=>{if(O(null),I(null),w(t.id),B(t.type.name),q(t.condition_mode||""),t.condition_mode==="nl")X(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(`${K(o.from_node)} → ${K(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=((_=b.find(l=>l.is_flow))==null?void 0:_.name)??((A=b[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(`${K(t)} → ${K(o)} is already connected with "${u}".`),Ve(f);return}try{const l=await kt(s,{from_node:t,to_node:o,type:u,condition_mode:null,condition:null});await xe(),Ve(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,Vt=[...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:Vt.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(),Ve(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:K(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(),Ve(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:[K(Le.from_node)," → ",K(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:b.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=>X(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:be,onClick:()=>void Ft(),children:be?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=ye.find(l=>l.agent_node===x),u=window.location.origin,f=`[[${K(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:K(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 bt(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 yt(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 Xt(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 Ut(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:U,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…"}),y.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:!U,onClick:()=>{ut(x,U),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([]),[b,C]=r.useState([]),[y,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),Xe(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(($=b.find(W=>W.id===i))==null?void 0:$.title)||i.replace(/^nodes\//,"")},D=i=>{var $;return($=b.find(W=>W.id===i))==null?void 0:$.type},q=b.filter(i=>i.type==="agent"||i.type==="skill"),Y=q.filter(i=>!m.some($=>$.agent_node===i.id)),X=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}),y?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 ",X(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:X($)},$)),![15,60,360,1440].includes(i.every_minutes)&&e.jsx("option",{value:i.every_minutes,children:X(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 bt(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 yt(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([]),[b,C]=r.useState(null),[y,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($t,{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."]}),b&&e.jsx("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive",children:b}),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:y,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(y)||!k,onClick:async()=>{E(!0);try{await wt(s,y,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 Vs({nestId:s}){const[m,g]=r.useState(null),[b,C]=r.useState(""),[y,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:b,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:y||!b.trim().startsWith("sk-"),onClick:async()=>{j(!0);try{await wt(s,"ANTHROPIC_API_KEY",b.trim()),C(""),g(!0),E(!0)}catch(N){d(N instanceof Error?N.message:"Save failed")}finally{j(!1)}},children:y?e.jsx(J,{className:"h-3.5 w-3.5 animate-spin"}):"Save key"})]})]})}const Ks=[["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([]),[b,C]=r.useState(null),[y,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."}),b&&e.jsx("div",{className:"rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive",children:b}),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:y,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:y,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"}),Ks.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 hn(){const s=xs();return e.jsx(Ts,{nestId:s.nestId,nestName:s.nestName,onBack:s.leaveNest})}export{hn as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{c,cY as l,j as e,aP as h,F as m,cZ as u,c_ as p,c$ as x,U as g,cG as j}from"./index-WYDmEOfO.js";import{P as y}from"./page-title-DVq4qvMR.js";import{B as w}from"./boxes-ClbgQqG2.js";import{U as b}from"./user-plus-Ckm_Isyc.js";import{S as f}from"./settings-DKX0Q4gO.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 v=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"10",r:"3",key:"ilqhr7"}],["path",{d:"M7 20.662V19a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v1.662",key:"154egf"}]],N=c("circle-user",v),k=[{id:"sso",title:"Single sign-on (OIDC)",where:"Admin → Server settings → Single sign-on",summary:"Let people sign in with your identity provider: Microsoft Entra ID, Google, Okta, Keycloak or any OpenID Connect issuer. It is one setup for the whole server, and only a server admin can change it.",steps:["Set Public base URL (Server settings → General) to the https address people use, e.g. https://nest.acme.com. The redirect URI is built from it: <Public base URL>/auth/oidc/callback. The Single sign-on tab shows it with a Copy button.","At your identity provider, register a web app (confidential client) with that exact redirect URI. Copy its client ID and client secret.","On the Single sign-on tab, pick Microsoft Entra ID or Google, or paste your issuer URL. Then paste the client ID and secret.","Optional: list your allowed email domains, and turn Auto-provision off if only invited people should get in.","Turn it on, Save, then test in a private window. The login page shows a Sign in with Microsoft / Google / SSO button."],notes:["People are matched by email. Someone who already has a password account with the same email signs into that account, and their password still works.","API keys (cnst_…) do not go through SSO. Disabling someone at your identity provider does not stop their keys or their open sessions. Remove them under Admin → Teammates to end both.","A failed sign-in comes back with a short error. Each code, what causes it and how to fix it are listed in CONFIGURATION.md → Single sign-on (OIDC) → Troubleshooting."]}];function r({title:t,icon:s,children:n}){return e.jsxs("section",{children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[s&&e.jsx("span",{className:"flex h-7 w-7 items-center justify-center rounded-md bg-primary/10 text-primary",children:e.jsx(s,{className:"h-4 w-4"})}),e.jsx("h2",{className:"text-base font-semibold tracking-tight",children:t})]}),n]})}function o({steps:t}){return e.jsx("ol",{className:"space-y-3",children:t.map((s,n)=>e.jsxs("li",{className:"flex gap-3",children:[e.jsx("span",{className:"mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-primary/10 text-xs font-semibold text-primary",children:n+1}),e.jsx("span",{className:"text-muted-foreground pt-0.5",children:s})]},n))})}function S({term:t,def:s}){return e.jsxs("div",{className:"rounded-lg border bg-card p-3 transition-colors hover:border-primary/40",children:[e.jsx("div",{className:"mb-1 text-sm font-semibold",children:t}),e.jsx("div",{className:"text-xs leading-relaxed text-muted-foreground",children:s})]})}function i({items:t}){return e.jsx("ul",{className:"space-y-2",children:t.map(([s,n])=>e.jsxs("li",{className:"text-muted-foreground",children:[e.jsx("b",{className:"text-foreground",children:s})," — ",n]},s))})}const a=({children:t})=>e.jsx("kbd",{className:"rounded border bg-muted px-1.5 py-0.5 text-xs",children:t}),A=[["Just me","Stewardship off. Saving publishes at once. Right for a personal nest."],["Me, with a paper trail","Stewardship on, self-approve allowed. Every change waits for review and you approve your own — a history without ceremony."],["A team","Stewards (viewer / editor / reviewer) per nest, tag or document. You cannot approve your own change; agents queue like everyone else."],["Prime documents","Mark a document or tag as prime and it always needs a second person, even where self-approve is on."]];function D(){const{manageKeys:t}=l();return e.jsxs("div",{className:"w-full",children:[e.jsx(y,{icon:h,title:"How it works",description:"A tour of the app, page by page. Agent setup (API, MCP, CLI) is on the Docs page in the header.",className:"mb-10"}),e.jsxs("div",{className:"space-y-10 text-sm leading-relaxed",children:[e.jsx(r,{title:"What this is",children:e.jsx("div",{className:"rounded-lg border-l-2 border-primary bg-muted/40 p-4",children:e.jsxs("p",{className:"text-muted-foreground",children:["A shared knowledge base for your team ",e.jsx("i",{children:"and"})," your AI agents. Documents live in"," ",e.jsx("b",{className:"text-foreground",children:"nests"}),". Every save is a version you can go back to. In a stewarded nest a change waits for a reviewer before agents can read it. People write here; agents read and write the same documents over the API, MCP or the ",e.jsx("code",{className:"rounded bg-muted px-1 py-0.5 text-xs",children:"ctx"})," CLI."]})})}),e.jsx(r,{title:"Nests",icon:w,children:e.jsx(i,{items:[["Create",e.jsxs(e.Fragment,{children:["From the Nests page — server admins only, unless an admin lets everyone create nests in Server settings. Have Markdown already? ",e.jsx("b",{children:"Import folder"})," brings a whole directory in."]})],["Organize",e.jsx(e.Fragment,{children:"Folders and subfolders in the sidebar; move a document from its folder picker. With many nests, the sidebar has a name filter."})],["Share",e.jsx(e.Fragment,{children:"The whole nest with a person or a team (viewer / editor / admin), or just one document or folder — the recipient sees only that slice."})],["Go public",e.jsxs(e.Fragment,{children:["A public nest gets a read-only ",e.jsx("b",{children:"Reader mode"})," with a home document. A single document can also be published to a link."]})],["Housekeeping",e.jsx(e.Fragment,{children:"Rename, pin, archive or delete a nest. Anyone can request a deletion; an owner honours or declines it."})]]})}),e.jsx(r,{title:"Inviting someone",icon:b,children:e.jsx(o,{steps:[e.jsxs(e.Fragment,{children:[e.jsx("b",{children:"Share a nest"})," with their email (the nest's Collaborators tab), or add them under ",e.jsx("b",{children:"Teammates"})," and pick a nest to share right there. Joining the server alone gives no nest access."]}),e.jsxs(e.Fragment,{children:["They get an ",e.jsx("b",{children:"invite email"})," naming the nest and who shared it. Adding a teammate also emails a temporary password."]}),e.jsxs(e.Fragment,{children:["The link opens sign-in with their email filled in. They ",e.jsx("b",{children:"Continue with PromptOwl"})," using that same email — creating a PromptOwl account there if they have none — or use the temporary password."]}),e.jsxs(e.Fragment,{children:["Signed in, they see ",e.jsx("b",{children:"Pending invites"})," on the Nests page. ",e.jsx("b",{children:"Accept"})," opens the nest; ",e.jsx("b",{children:"Decline"})," removes their access."]})]})}),e.jsx(r,{title:"Documents",icon:m,children:e.jsx(i,{items:[["Types",e.jsx(e.Fragment,{children:"Document (Markdown), Artifact (hosted HTML) and Table (CSV facts an agent can query row by row)."})],["Writing",e.jsxs(e.Fragment,{children:["Rich editor or raw Markdown. ",e.jsx("code",{className:"rounded bg-muted px-1 py-0.5 text-xs",children:"[[Title]]"})," links another document, ",e.jsx("code",{className:"rounded bg-muted px-1 py-0.5 text-xs",children:"@name"})," mentions a person, ",e.jsx("code",{className:"rounded bg-muted px-1 py-0.5 text-xs",children:"#"})," starts a heading."]})],["Tags",e.jsx(e.Fragment,{children:"Add them under the title. They stay local until you save."})],["Versions",e.jsx(e.Fragment,{children:"Every save is a version. Compare with an earlier one or revert to it from the history menu."})],["Comments",e.jsxs(e.Fragment,{children:["Switch to ",e.jsx("b",{children:"Comment"})," mode, select text, start a thread. Resolve or reopen it when done."]})],["People",e.jsxs(e.Fragment,{children:["Who created it and who else has edited it sit under the title; mention someone with ",e.jsx("code",{className:"rounded bg-muted px-1 py-0.5 text-xs",children:"@"})," to pull them in."]})],["Find anything",e.jsxs(e.Fragment,{children:[e.jsx(a,{children:"Ctrl"})," / ",e.jsx(a,{children:"⌘"})," ",e.jsx(a,{children:"K"})," searches every nest and document. ",e.jsx(a,{children:"?"})," lists all shortcuts."]})]]})}),e.jsxs(r,{title:"Review",icon:u,children:[e.jsx(o,{steps:[e.jsxs(e.Fragment,{children:["Write and save. With stewardship off that is it — the document is published. With it on, the save is a ",e.jsx("b",{children:"draft"}),"."]}),e.jsxs(e.Fragment,{children:[e.jsx("b",{children:"Submit for review"}),". Stewards are notified; you can withdraw until someone acts."]}),e.jsxs(e.Fragment,{children:["A reviewer ",e.jsx("b",{children:"approves"})," (published, visible to agents) or ",e.jsx("b",{children:"rejects"})," with a note (back to draft)."]})]}),e.jsx("div",{className:"mt-4 grid gap-3 sm:grid-cols-2",children:A.map(([s,n])=>e.jsx(S,{term:s,def:n},s))}),e.jsxs("p",{className:"mt-3 text-muted-foreground",children:[e.jsx("b",{className:"text-foreground",children:"My Work"})," is everything waiting on you across all nests."," ",e.jsx("b",{className:"text-foreground",children:"My Drafts"})," is what you wrote and never submitted."]})]}),e.jsx(r,{title:"Views inside a nest",icon:p,children:e.jsx(i,{items:[["Board",e.jsxs(e.Fragment,{children:["Documents as cards in columns — by folder, by status, or by a tag family like ",e.jsx("code",{className:"rounded bg-muted px-1 py-0.5 text-xs",children:"stage:*"}),". Drag to move or re-tag."]})],["Graph",e.jsx(e.Fragment,{children:"Documents, links, tags and stewards drawn as a graph."})],["Definitions",e.jsx(e.Fragment,{children:"The nest's glossary — terms stewards define so people and agents mean the same thing."})],["Workflows",e.jsxs(e.Fragment,{children:[e.jsx(x,{})," Agents are documents whose body is instructions. Wire one to a target document, run it by button, schedule or incoming hook; its output arrives as a pending review. Details on the Docs page."]})]]})}),e.jsx(r,{title:"Workspace",icon:g,children:e.jsx(i,{items:[["Teams",e.jsx(e.Fragment,{children:"Group people once, then share nests with the team. Signed in with PromptOwl? Its teams can be synced in."})],["API keys",e.jsxs(e.Fragment,{children:["What agents, the CLI and MCP clients use to sign in. A key sees every nest you can, or just one."," ",e.jsx("button",{type:"button",onClick:t,className:"underline underline-offset-2 text-foreground",children:"Manage keys"}),"."]})],["Connect",e.jsxs(e.Fragment,{children:["Bottom of the nest sidebar: the MCP URL and REST snippets for that nest. ",e.jsx("b",{children:"Add with AI"})," on the nest overview is a prompt that has an agent write context in."]})]]})}),e.jsx(r,{title:"Admin",icon:f,children:e.jsx(i,{items:[["Teammates",e.jsx(e.Fragment,{children:"Invite people, reset passwords, remove accounts, name other admins."})],["Server settings",e.jsx(e.Fragment,{children:"Public URL and logo, single sign-on, who can create nests, the Anthropic key, Slack / Teams / email notifications (email over SMTP or AWS SES), allowed content types, upload limit, telemetry."})],["Activity trace",e.jsx(e.Fragment,{children:"Every governance action on the server. Each nest has its own trace under Activity."})]]})}),k.map(s=>e.jsx(r,{title:s.title,icon:j,children:e.jsxs("div",{id:`help-${s.id}`,className:"space-y-3",children:[e.jsxs("p",{className:"text-muted-foreground",children:[e.jsx("span",{className:"text-xs uppercase tracking-wide",children:"For server admins"})," ","· ",e.jsx("b",{className:"text-foreground",children:s.where})]}),e.jsx("p",{className:"text-muted-foreground",children:s.summary}),e.jsx(o,{steps:s.steps}),e.jsx("ul",{className:"list-disc space-y-1 pl-5 text-muted-foreground",children:s.notes.map((n,d)=>e.jsx("li",{children:n},`${s.id}-note-${d}`))})]})},s.id)),e.jsx(r,{title:"Account",icon:N,children:e.jsx("p",{className:"text-muted-foreground",children:"Your name and password, from the menu in the top-right corner."})})]})]})}export{D as default};
|