PageSourceSearch

https://app.xlift.ai/assets/GuardrailsPage-BERpz0VU.js

js xlift.ai collected 2026-10-05 13:20:25 UTC 5,989 bytes, 1 lines download raw bytes

1import{ai as z,A as O,o as b,al as R,a4 as D,a5 as E,U as j,j as e,aM as K,C as l,G as r,aQ as B,$ as W,T as n,D as d,a0 as G,aa as M,K as A,E as F,X as L,a8 as T}from"./index-dE8a1mPK.js";import{E as N}from"./ErrorState-gVNyx0--.js";import{S as h}from"./Switch-Bm85N10X.js";import{C as P}from"./Code-YtMEZkZ5.js";import{N as Q}from"./NumberInput-EbCp_odp.js";import{S as w}from"./Select-DebRlW67.js";import"./IconCopy-B63sUmw8.js";import"./InputsGroupFieldset-C0syow2C.js";import"./OptionsDropdown-wonErrz5.js";import"./CheckIcon-DkMc45y2.js";const y={"send-dm":{label:"Send DM",sub:"Direct messages to a prospect"},follow:{label:"Follow",sub:"Following a prospect from one of your accounts"},reply:{label:"Reply / Quote",sub:"Public replies and quote-tweets to a prospect"},"post-mention":{label:"@-mention post",sub:"A standalone post that @-mentions the prospect"},like:{label:"Like",sub:"Liking a prospect's tweet (low-signal — usually safe across accounts)"},retweet:{label:"Retweet",sub:"Retweeting a prospect (low-signal — usually safe across accounts)"}};function Z(){const k=z(),{data:i,isLoading:v,error:p,refetch:C}=O({queryKey:["guardrails"],queryFn:()=>j.getGuardrails()}),[a,t]=b.useState(null);b.useEffect(()=>{i!=null&&i.settings&&!a&&t(structuredClone(i.settings))},[i,a]);const m=R({mutationFn:()=>j.putGuardrails(a),onSuccess:()=>{E("Guardrails saved"),k.invalidateQueries({queryKey:["guardrails"]})},onError:s=>D(s)});if(v)return e.jsx(K,{});if(p)return e.jsx(N,{error:p,onRetry:C});if(!a)return null;const S=i.allKinds||Object.keys(y),x=JSON.stringify(a)!==JSON.stringify(i.settings);function g(s,c){t(o=>({...o,claimKinds:{...o.claimKinds,[s]:{...o.claimKinds[s],...c}}}))}return e.jsxs(l,{gap:"md",children:[e.jsxs(r,{gap:"xs",align:"center",children:[e.jsx(B,{size:20}),e.jsx(W,{order:2,children:"Cross-account guardrails"})]}),e.jsx(n,{c:"dimmed",size:"sm",maw:760,children:"When you operate many X accounts under one Xlift user, the platform's #1 job is to make sure a single prospect isn't touched by all of them at once. Each setting below is a knob — keep the defaults and you're fine; turn them off only if you specifically want cross-account collisions to happen."}),e.jsx(d,{withBorder:!0,children:e.jsxs(l,{gap:"md",children:[e.jsxs(r,{justify:"space-between",align:"center",children:[e.jsxs("div",{children:[e.jsx(n,{fw:600,children:"Guardrails master switch"}),e.jsx(n,{size:"xs",c:"dimmed",children:"When OFF, no actions are claim-checked. Useful only for debugging."})]}),e.jsx(h,{size:"md",checked:a.enabled,onChange:s=>t({...a,enabled:s.currentTarget.checked})})]}),!a.enabled&&e.jsx(G,{color:"red",variant:"light",icon:e.jsx(M,{size:16}),children:"Guardrails are disabled. Prospects can be touched by every account in your pool with no cross-account check. Re-enable before running any real campaigns."})]})}),e.jsx(d,{withBorder:!0,children:e.jsxs(l,{gap:"sm",children:[e.jsx(n,{fw:600,children:"Per-action-kind claims"}),e.jsx(n,{size:"xs",c:"dimmed",children:'For each kind, decide whether to enforce the "one-account-at-a-time" rule and how long the claim sticks (the cooldown window after a successful action during which no other account in your pool may do the same kind of action to that prospect).'}),S.map(s=>{var f;const c=((f=a.claimKinds)==null?void 0:f[s])||{},o=y[s]||{label:s,sub:""};return e.jsx(d,{withBorder:!0,p:"sm",bg:"var(--xb-bg-soft)",children:e.jsxs(r,{justify:"space-between",align:"flex-start",wrap:"wrap",gap:"md",children:[e.jsxs(l,{gap:2,style:{flex:"1 1 280px",minWidth:0},children:[e.jsxs(r,{gap:"xs",children:[e.jsx(n,{fw:500,children:o.label}),e.jsx(P,{children:s})]}),e.jsx(n,{size:"xs",c:"dimmed",children:o.sub})]}),e.jsxs(r,{gap:"md",align:"center",children:[e.jsx(h,{label:"Enforce claim",checked:!!c.enabled,onChange:u=>g(s,{enabled:u.currentTarget.checked})}),e.jsx(Q,{size:"xs",label:"Cooldown (days)",value:c.ttlDays||0,onChange:u=>g(s,{ttlDays:Math.max(0,Math.min(365,Number(u)||0))}),min:0,max:365,w:150,disabled:!c.enabled})]})]})},s)})]})}),e.jsx(d,{withBorder:!0,children:e.jsxs(l,{gap:"md",children:[e.jsxs(r,{justify:"space-between",align:"center",children:[e.jsxs("div",{children:[e.jsx(n,{fw:600,children:"Release claim on reply"}),e.jsx(n,{size:"xs",c:"dimmed",children:"When the prospect replies back (via DM), every live claim across all action kinds is released so a different account can pick them up later if they go cold again."})]}),e.jsx(h,{size:"md",checked:a.releaseOnReply,onChange:s=>t({...a,releaseOnReply:s.currentTarget.checked})})]}),e.jsx(A,{}),e.jsxs(r,{justify:"space-between",align:"flex-start",wrap:"wrap",gap:"md",children:[e.jsxs(l,{gap:2,style:{flex:"1 1 280px",minWidth:0},children:[e.jsx(n,{fw:500,children:"Override on bulk actions"}),e.jsx(n,{size:"xs",c:"dimmed",children:"What happens when a bulk DM / enrollment includes prospects that are already claimed by another account."})]}),e.jsx(w,{size:"xs",w:220,value:a.bulkOverride,onChange:s=>t({...a,bulkOverride:s}),data:[{value:"block",label:"Block (hide claimed prospects)"},{value:"warn",label:"Warn (allow with confirmation)"},{value:"allow",label:"Allow (no check)"}]})]}),e.jsxs(r,{justify:"space-between",align:"flex-start",wrap:"wrap",gap:"md",children:[e.jsxs(l,{gap:2,style:{flex:"1 1 280px",minWidth:0},children:[e.jsx(n,{fw:500,children:"Override on single-action send"}),e.jsx(n,{size:"xs",c:"dimmed",children:"When you click Reply / DM / Quote on a single prospect that's already claimed."})]}),e.jsx(w,{size:"xs",w:220,value:a.perRowOverride,onChange:s=>t({...a,perRowOverride:s}),data:[{value:"confirm",label:"Confirm (ask, then allow)"},{value:"allow",label:"Allow (no check)"},{value:"block",label:"Block (refuse)"}]})]})]})}),e.jsxs(r,{justify:"flex-end",children:[x&&e.jsx(F,{color:"orange",variant:"light",children:"Unsaved changes"}),e.jsx(L,{leftSection:e.jsx(T,{size:14}),onClick:()=>m.mutate(),loading:m.isPending,disabled:!x,children:"Save guardrails"})]})]})}export{Z as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.