@bikdotai/bik-component-library 0.0.850 → 0.0.851

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.
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),ee=require("../../../assets/icons/chevronRight.svg.js"),te=require("../../../assets/icons/searchIcon.svg.js"),ne=require("../../../icons/Arrows/Normal arrows/ArrowLeft.js"),s=require("react"),oe=require("styled-components"),N=require("../../TypographyStyle.js"),l=require("../../../constants/Theme.js"),g=require("../constants/tools.js"),G=require("../utils/mentionSerialization.js"),v=require("../utils/sourceIcons.js"),Y=require("../../../icons/Informational/Common UI/Shield.js"),re=i=>i&&typeof i=="object"&&"default"in i?i:{default:i},p=re(oe),k=i=>i.meta,C=i=>k(i)?.plainLabel??i.label,ie="__bik_create_subagent__",le=({items:i,onSelect:L,registerKeyHandler:j,onClose:O,onCreateSubAgent:R,initialSource:U,toolActions:S,integrationStatus:F,onConnectIntegration:J})=>{const[Z,E]=s.useState(null),[u,q]=s.useState(U??null),[w,M]=s.useState(null),[A,m]=s.useState(-1),[I,Q]=s.useState(""),y=s.useMemo(()=>i.filter(e=>k(e)?.kind==="tool"),[i]),_=s.useMemo(()=>i.filter(e=>k(e)?.kind==="subagent"),[i]),P=s.useMemo(()=>{const e=[];return y.forEach(r=>{const x=k(r)?.source??"other";e.includes(x)||e.push(x)}),e},[y]),z=s.useMemo(()=>new Map((S??[]).map(e=>[e.source,e])),[S]),$=s.useMemo(()=>g.CATEGORIES.filter(e=>e.key==="tool"?y.length>0||(S?.length??0)>0:_.length>0||!!R),[y.length,_.length,R,S?.length]),D=$.length===1?$[0].key:null,d=Z??D,f=d?d==="subagent"?{title:"Sub-agent",onBack:D?void 0:()=>E(null)}:u?{title:G.toolSourceLabel(u),onBack:U?void 0:()=>q(null),icon:v.sourceIcon(u)}:w==="integrations"?{title:"Integrations",onBack:()=>M(null)}:{title:"Tools",onBack:D?void 0:()=>E(null)}:null,c=s.useMemo(()=>{if(!d)return $.map(n=>({id:n.key,label:n.label,drillsIn:!0,onActivate:()=>{E(n.key),q(null),M(null)}}));if(d==="subagent"){const n=I.trim().toLowerCase(),h=_.filter(b=>!n||C(b).toLowerCase().includes(n)).map(b=>({id:String(b.id),label:C(b),drillsIn:!1,onActivate:()=>L(b)}));return R&&h.push({id:ie,label:"Create new",drillsIn:!1,isCreate:!0,onActivate:()=>{O?.(),R()}}),h}if(!u){const n=(S??[]).map(t=>t.source).filter(t=>!P.includes(t)),h=[...P,...n],b=t=>{const a=z.get(t);if((a!==void 0?a.connected:F?.[t])===!1)return{id:t,label:G.toolSourceLabel(t),drillsIn:!1,icon:v.sourceIcon(t)??a?.icon,rightLabel:"Connect",onActivate:()=>{O?.(),a?.onConnect?a.onConnect():J?.(t)}};const X=y.filter(T=>(k(T)?.source??"other")===t);if(X.length+(a?1:0)===1){const T=v.sourceIcon(t)??a?.icon;if(a)return{id:t,label:a.label,drillsIn:!1,icon:T,onActivate:()=>{O?.(),a.onSelect()}};const B=X[0];return{id:String(B.id),label:C(B),drillsIn:!1,icon:T,authRequired:k(B)?.authRequired,onActivate:()=>L(B)}}return{id:t,label:G.toolSourceLabel(t),drillsIn:!0,icon:v.sourceIcon(t)??a?.icon,onActivate:()=>q(t)}};if(w==="integrations")return h.filter(g.isIntegrationSource).sort((t,a)=>g.toolSourceRank(t)-g.toolSourceRank(a)).map(b);const W=h.filter(t=>!g.isIntegrationSource(t)).map(t=>({rank:g.toolSourceRank(t),row:b(t)}));return h.some(g.isIntegrationSource)&&W.push({rank:g.INTEGRATIONS_RANK,row:{id:"__integrations__",label:"Integrations",drillsIn:!0,onActivate:()=>{M("integrations"),q(null)}}}),W.sort((t,a)=>t.rank-a.rank).map(t=>t.row)}const e=I.trim().toLowerCase(),r=y.filter(n=>(k(n)?.source??"other")===u).filter(n=>!e||C(n).toLowerCase().includes(e)).map(n=>({id:String(n.id),label:C(n),drillsIn:!1,authRequired:k(n)?.authRequired,onActivate:()=>L(n)})),x=z.get(u);if(x){const n=u in g.CONFIG_TOOL_SOURCES;r.push({id:`create:${u}`,label:x.label,drillsIn:!1,isCreate:!n,onActivate:()=>{O?.(),x.onSelect()}})}return r},[d,$,u,w,I,y,_,P,L,O,R,S,z,F,J]);s.useEffect(()=>m(-1),[d,u,w,I,i]),s.useEffect(()=>Q(""),[d,u,w]);const V=s.useRef({rows:c,activeIndex:A,header:f});V.current={rows:c,activeIndex:A,header:f},s.useEffect(()=>{if(j)return j(e=>{const{rows:r,activeIndex:x,header:n}=V.current;switch(e.key){case"ArrowDown":return r.length&&m(h=>(h+1)%r.length),!0;case"ArrowUp":return r.length&&m(h=>(h+r.length-1)%r.length),!0;case"ArrowRight":case"Enter":return(r[x]??r[0])?.onActivate(),!0;case"ArrowLeft":return n?.onBack?(n.onBack(),!0):!1;default:return!1}}),()=>j(null)},[j]);const K=d?c.length&&!c[0].drillsIn?"items":"sources":"categories",H=d==="tool"&&!!u||d==="subagent";return o.jsxs(ae,{className:`bik-mention-picker bik-mention-picker--${K}`,children:[f&&o.jsxs(ge,{type:"button",onClick:f.onBack,disabled:!f.onBack,style:{background:l.COLORS.surface.subdued,cursor:f.onBack?"pointer":"default"},children:[f.onBack&&o.jsx(ne.default,{width:20,height:20,color:l.COLORS.content.primary}),f.icon&&v.renderSourceIcon(f.icon),o.jsxs(N.TitleSmall,{children:[" ",f.title]})]}),H&&o.jsxs(se,{children:[o.jsx(te.default,{width:20,height:20,color:l.COLORS.content.placeholder}),o.jsx(ce,{autoFocus:!0,value:I,placeholder:"Search","data-test":"mention-picker-search",onChange:e=>Q(e.target.value),onKeyDown:e=>{c.length&&(e.key==="ArrowDown"?(e.preventDefault(),m(r=>(r+1)%c.length)):e.key==="ArrowUp"?(e.preventDefault(),m(r=>(r+c.length-1)%c.length)):e.key==="Enter"&&(e.preventDefault(),(c[A]??c[0])?.onActivate()))}})]}),c.length===0?o.jsx(xe,{children:d==="subagent"?null:"No tools available"}):c.map((e,r)=>o.jsx(ue,{type:"button",$active:r===A,onMouseEnter:()=>m(r),onMouseLeave:()=>m(-1),onClick:e.onActivate,children:e.isCreate?o.jsx(pe,{children:e.label}):o.jsxs(o.Fragment,{children:[o.jsxs(de,{children:[v.renderSourceIcon(e.icon),o.jsx(N.BodySecondary,{color:l.COLORS.content.primary,children:e.label}),e.authRequired&&o.jsx(Y.default,{size:16,"aria-label":"This tool requires customer verification"})]}),e.rightLabel?o.jsx(he,{children:e.rightLabel}):e.drillsIn&&o.jsx(ee.default,{width:12,height:12})]})},e.id)),c.some(e=>e.authRequired)&&o.jsxs(fe,{children:[o.jsx(Y.default,{size:16}),o.jsx(N.BodyCaption,{color:l.COLORS.content.secondary,children:"This tool requires customer verification"})]})]})},ae=p.default.div`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),Z=require("../../../assets/icons/chevronRight.svg.js"),K=require("../../../assets/icons/searchIcon.svg.js"),H=require("../../../icons/Arrows/Normal arrows/ArrowLeft.js"),c=require("react"),ee=require("styled-components"),z=require("../../TypographyStyle.js"),l=require("../../../constants/Theme.js"),w=require("../constants/tools.js"),D=require("../utils/mentionSerialization.js"),v=require("../utils/sourceIcons.js"),V=require("../../../icons/Informational/Common UI/Shield.js"),te=i=>i&&typeof i=="object"&&"default"in i?i:{default:i},h=te(ee),x=i=>i.meta,L=i=>x(i)?.plainLabel??i.label,ne="__bik_create_subagent__",oe=({items:i,onSelect:C,registerKeyHandler:I,onClose:S,onCreateSubAgent:O,initialSource:N,toolActions:y,integrationStatus:U,onConnectIntegration:F})=>{const[W,B]=c.useState(null),[u,E]=c.useState(N??null),[j,b]=c.useState(-1),[R,G]=c.useState(""),k=c.useMemo(()=>i.filter(e=>x(e)?.kind==="tool"),[i]),q=c.useMemo(()=>i.filter(e=>x(e)?.kind==="subagent"),[i]),M=c.useMemo(()=>{const e=[];return k.forEach(r=>{const p=x(r)?.source??"other";e.includes(p)||e.push(p)}),e},[k]),_=c.useMemo(()=>new Map((y??[]).map(e=>[e.source,e])),[y]),$=c.useMemo(()=>w.CATEGORIES.filter(e=>e.key==="tool"?k.length>0||(y?.length??0)>0:q.length>0||!!O),[k.length,q.length,O,y?.length]),P=$.length===1?$[0].key:null,d=W??P,f=d?d==="subagent"?{title:"Sub-agent",onBack:P?void 0:()=>B(null)}:u?{title:D.toolSourceLabel(u),onBack:N?void 0:()=>E(null),icon:v.sourceIcon(u)}:{title:"Tools",onBack:P?void 0:()=>B(null)}:null,s=c.useMemo(()=>{if(!d)return $.map(t=>({id:t.key,label:t.label,drillsIn:!0,onActivate:()=>{B(t.key),E(null)}}));if(d==="subagent"){const t=R.trim().toLowerCase(),g=q.filter(m=>!t||L(m).toLowerCase().includes(t)).map(m=>({id:String(m.id),label:L(m),drillsIn:!1,onActivate:()=>C(m)}));return O&&g.push({id:ne,label:"Create new",drillsIn:!1,isCreate:!0,onActivate:()=>{S?.(),O()}}),g}if(!u){const t=(y??[]).map(n=>n.source).filter(n=>!M.includes(n)),g=[...M,...t],m=n=>{const a=_.get(n);if((a!==void 0?a.connected:U?.[n])===!1)return{id:n,label:D.toolSourceLabel(n),drillsIn:!1,icon:v.sourceIcon(n)??a?.icon,rightLabel:"Connect",onActivate:()=>{S?.(),a?.onConnect?a.onConnect():F?.(n)}};const Q=k.filter(A=>(x(A)?.source??"other")===n);if(Q.length+(a?1:0)===1&&!(a===void 0&&w.isIntegrationSource(n))){const A=v.sourceIcon(n)??a?.icon;if(a)return{id:n,label:a.label,drillsIn:!1,icon:A,onActivate:()=>{S?.(),a.onSelect()}};const T=Q[0];return{id:String(T.id),label:L(T),drillsIn:!1,icon:A,authRequired:x(T)?.authRequired,onActivate:()=>C(T)}}return{id:n,label:D.toolSourceLabel(n),drillsIn:!0,icon:v.sourceIcon(n)??a?.icon,onActivate:()=>E(n)}};return g.sort((n,a)=>w.toolSourceRank(n)-w.toolSourceRank(a)).map(m)}const e=R.trim().toLowerCase(),r=k.filter(t=>(x(t)?.source??"other")===u).filter(t=>!e||L(t).toLowerCase().includes(e)).map(t=>({id:String(t.id),label:L(t),drillsIn:!1,authRequired:x(t)?.authRequired,onActivate:()=>C(t)})),p=_.get(u);if(p){const t=u in w.CONFIG_TOOL_SOURCES;r.push({id:`create:${u}`,label:p.label,drillsIn:!1,isCreate:!t,onActivate:()=>{S?.(),p.onSelect()}})}return r},[d,$,u,R,k,q,M,C,S,O,y,_,U,F]);c.useEffect(()=>b(-1),[d,u,R,i]),c.useEffect(()=>G(""),[d,u]);const J=c.useRef({rows:s,activeIndex:j,header:f});J.current={rows:s,activeIndex:j,header:f},c.useEffect(()=>{if(I)return I(e=>{const{rows:r,activeIndex:p,header:t}=J.current;switch(e.key){case"ArrowDown":return r.length&&b(g=>(g+1)%r.length),!0;case"ArrowUp":return r.length&&b(g=>(g+r.length-1)%r.length),!0;case"ArrowRight":case"Enter":return(r[p]??r[0])?.onActivate(),!0;case"ArrowLeft":return t?.onBack?(t.onBack(),!0):!1;default:return!1}}),()=>I(null)},[I]);const X=d?s.length&&!s[0].drillsIn?"items":"sources":"categories",Y=d==="tool"&&!!u||d==="subagent";return o.jsxs(re,{className:`bik-mention-picker bik-mention-picker--${X}`,children:[f&&o.jsxs(fe,{type:"button",onClick:f.onBack,disabled:!f.onBack,style:{background:l.COLORS.surface.subdued,cursor:f.onBack?"pointer":"default"},children:[f.onBack&&o.jsx(H.default,{width:20,height:20,color:l.COLORS.content.primary}),f.icon&&v.renderSourceIcon(f.icon),o.jsxs(z.TitleSmall,{children:[" ",f.title]})]}),Y&&o.jsxs(ie,{children:[o.jsx(K.default,{width:20,height:20,color:l.COLORS.content.placeholder}),o.jsx(le,{autoFocus:!0,value:R,placeholder:"Search","data-test":"mention-picker-search",onChange:e=>G(e.target.value),onKeyDown:e=>{s.length&&(e.key==="ArrowDown"?(e.preventDefault(),b(r=>(r+1)%s.length)):e.key==="ArrowUp"?(e.preventDefault(),b(r=>(r+s.length-1)%s.length)):e.key==="Enter"&&(e.preventDefault(),(s[j]??s[0])?.onActivate()))}})]}),s.length===0?o.jsx(he,{children:d==="subagent"?null:"No tools available"}):s.map((e,r)=>o.jsx(ae,{type:"button",$active:r===j,onMouseEnter:()=>b(r),onMouseLeave:()=>b(-1),onClick:e.onActivate,children:e.isCreate?o.jsx(de,{children:e.label}):o.jsxs(o.Fragment,{children:[o.jsxs(ce,{children:[v.renderSourceIcon(e.icon),o.jsx(z.BodySecondary,{color:l.COLORS.content.primary,children:e.label}),e.authRequired&&o.jsx(V.default,{size:16,"aria-label":"This tool requires customer verification"})]}),e.rightLabel?o.jsx(ue,{children:e.rightLabel}):e.drillsIn&&o.jsx(Z.default,{width:12,height:12})]})},e.id)),s.some(e=>e.authRequired)&&o.jsxs(se,{children:[o.jsx(V.default,{size:16}),o.jsx(z.BodyCaption,{color:l.COLORS.content.secondary,children:"This tool requires customer verification"})]})]})},re=h.default.div`
2
2
  display: flex;
3
3
  flex-direction: column;
4
4
  min-width: 240px;
@@ -8,14 +8,14 @@
8
8
  border: 1px solid ${l.COLORS.stroke.primary};
9
9
  border-radius: 4px;
10
10
  box-shadow: 0px -2px 8px 0px #0000001f;
11
- `,se=p.default.div`
11
+ `,ie=h.default.div`
12
12
  display: flex;
13
13
  align-items: center;
14
14
  gap: 8px;
15
15
  padding: 10px 12px;
16
16
  flex-shrink: 0;
17
17
  border-bottom: 1px solid ${l.COLORS.stroke.primary};
18
- `,ce=p.default.input`
18
+ `,le=h.default.input`
19
19
  flex: 1;
20
20
  min-width: 0;
21
21
  border: none;
@@ -28,7 +28,7 @@
28
28
  &::placeholder {
29
29
  color: ${l.COLORS.content.placeholder};
30
30
  }
31
- `,ue=p.default.button`
31
+ `,ae=h.default.button`
32
32
  display: flex;
33
33
  justify-content: space-between;
34
34
  align-items: center;
@@ -50,32 +50,32 @@
50
50
  &:hover {
51
51
  background: ${l.COLORS.surface.hovered};
52
52
  }
53
- `,de=p.default.div`
53
+ `,ce=h.default.div`
54
54
  display: flex;
55
55
  align-items: center;
56
56
  gap: 12px;
57
57
  min-width: 0;
58
- `,fe=p.default.div`
58
+ `,se=h.default.div`
59
59
  display: flex;
60
60
  align-items: center;
61
61
  gap: 6px;
62
62
  padding: 8px 12px;
63
63
  border-top: 1px solid ${l.COLORS.stroke.primary};
64
- `,he=p.default.span`
64
+ `,ue=h.default.span`
65
65
  flex-shrink: 0;
66
66
  color: ${l.COLORS.content.brand};
67
67
  font-family: Inter;
68
68
  font-size: 14px;
69
69
  font-weight: 600;
70
70
  white-space: nowrap;
71
- `,pe=p.default.div`
71
+ `,de=h.default.div`
72
72
  width: 100%;
73
73
  text-align: center;
74
74
  color: ${l.COLORS.content.brand};
75
75
  font-family: Inter;
76
76
  font-size: 14px;
77
77
  font-weight: 600;
78
- `,ge=p.default.button`
78
+ `,fe=h.default.button`
79
79
  display: flex;
80
80
  align-items: center;
81
81
  padding: 12px 16px;
@@ -90,10 +90,10 @@
90
90
  box-sizing: border-box;
91
91
  flex-shrink: 0;
92
92
  gap: 4px;
93
- `,xe=p.default.div`
93
+ `,he=h.default.div`
94
94
  padding: 12px 10px;
95
95
  font-family: Inter;
96
96
  font-size: 13px;
97
97
  color: ${l.COLORS.content.secondary};
98
- `;exports.MentionPicker=le;
98
+ `;exports.MentionPicker=oe;
99
99
  //# sourceMappingURL=MentionPicker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MentionPicker.js","sources":["../../../../../src/components/agent-builder/components/MentionPicker.tsx"],"sourcesContent":["// import ChevronLeft from '@src/assets/icons/chevronLeft.svg';\nimport ChevronRight from '@src/assets/icons/chevronRight.svg';\nimport SearchIcon from '@src/assets/icons/searchIcon.svg';\nimport type { MentionDropdownRenderProps, MentionItem } from '@src/editor';\nimport { Shield } from '@src/icons';\nimport SvgArrowLeft from '@src/icons/Arrows/Normal arrows/ArrowLeft';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport {\n\tBodyCaption,\n\tBodySecondary,\n\tTitleSmall,\n} from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tCATEGORIES,\n\tCONFIG_TOOL_SOURCES,\n\tINTEGRATIONS_RANK,\n\tisIntegrationSource,\n\ttoolSourceRank,\n} from '../constants/tools';\nimport type { Category, ToolAction, ToolSource } from '../constants/tools';\nimport {\n\tMentionKindMeta,\n\ttoolSourceLabel,\n} from '../utils/mentionSerialization';\nimport { renderSourceIcon, sourceIcon, SourceIcon } from '../utils/sourceIcons';\n\nconst metaOf = (item: MentionItem): MentionKindMeta | undefined =>\n\titem.meta as unknown as MentionKindMeta | undefined;\n\nconst rowLabel = (item: MentionItem): string =>\n\tmetaOf(item)?.plainLabel ?? item.label;\n\n/** One navigable row in the picker's current view. */\ntype PickerRowModel = {\n\tid: string;\n\tlabel: string;\n\t/** Drill-in rows show a chevron; leaf (selectable) rows do not. */\n\tdrillsIn: boolean;\n\t/** Leading brand glyph (source rows only). */\n\ticon?: SourceIcon;\n\t/** Brand-coloured \"Create new\" action row (not a selectable item). */\n\tisCreate?: boolean;\n\t/**\n\t * Brand-coloured right-aligned action text (e.g. \"Connect\") shown in place of\n\t * the drill-in chevron — used for an unconnected integration source.\n\t */\n\trightLabel?: string;\n\t/** Tool leaf touches customer-private data → shows a shield glyph. */\n\tauthRequired?: boolean;\n\tonActivate: () => void;\n};\n\n/** Sentinel id for the sub-agent \"Create new\" row. */\nconst CREATE_SUBAGENT_ID = '__bik_create_subagent__';\n\ntype MentionPickerProps = MentionDropdownRenderProps & {\n\t/** Opens the create-sub-agent drawer (shows a \"Create new\" row in the Sub-agent view). */\n\tonCreateSubAgent?: () => void;\n\t/**\n\t * Open already drilled into this tool source (e.g. `'shopify'`) — its tool list\n\t * is shown immediately. */\n\tinitialSource?: string;\n\t/**\n\t * Built-in tool actions (Rest API / Handover to email) shown in the Tools view.\n\t * Picking one opens its config drawer (via `onSelect`) and dismisses the picker\n\t * — it never inserts a mention into the text.\n\t */\n\ttoolActions?: ToolAction[];\n\t/**\n\t * Per-source integration connection state. A source whose value is `false`\n\t * renders a \"Connect\" row (like an unconnected action) instead of drilling in —\n\t * so native source groups (Shopify / BigCommerce / ShipStation) show \"Connect\"\n\t * consistently with the config actions (Slack).\n\t */\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\t/** Open the connect flow for an unconnected source (used by the Connect row). */\n\tonConnectIntegration?: (source: ToolSource) => void;\n};\n\n/**\n * `@` reference picker. Drills:\n * root → Tools → <source> (Manifest / Shopify / …) → tool\n * → Sub-agent → sub-agent\n * (\"Add condition\" and \"Variables\" are intentionally not shown yet.)\n *\n * Owns keyboard navigation (↑/↓ move, →/Enter activate, ← go back) over the\n * CURRENTLY visible rows — registered with the editor via `registerKeyHandler`.\n */\nexport const MentionPicker: React.FC<MentionPickerProps> = ({\n\titems,\n\tonSelect,\n\tregisterKeyHandler,\n\tonClose,\n\tonCreateSubAgent,\n\tinitialSource,\n\ttoolActions,\n\tintegrationStatus,\n\tonConnectIntegration,\n}) => {\n\tconst [category, setCategory] = useState<Category | null>(null);\n\tconst [source, setSource] = useState<string | null>(initialSource ?? null);\n\t// Non-null when drilled into the consolidated \"Integrations\" group (its member\n\t// sources are shown; picking one drills into that source's tools as usual).\n\tconst [group, setGroup] = useState<'integrations' | null>(null);\n\t// -1 = nothing highlighted; rows highlight only on hover / arrow keys\n\t// (a default highlight reads as a stuck hover state).\n\tconst [activeIndex, setActiveIndex] = useState(-1);\n\t// Search box shown inside a source's tool list (Manifest / Shopify); filters\n\t// that source's tools by name.\n\tconst [search, setSearch] = useState('');\n\n\tconst tools = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'tool'),\n\t\t[items],\n\t);\n\tconst subAgents = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'subagent'),\n\t\t[items],\n\t);\n\tconst sources = useMemo(() => {\n\t\tconst acc: string[] = [];\n\t\ttools.forEach((t) => {\n\t\t\tconst s = metaOf(t)?.source ?? 'other';\n\t\t\tif (!acc.includes(s)) {\n\t\t\t\tacc.push(s);\n\t\t\t}\n\t\t});\n\t\treturn acc;\n\t}, [tools]);\n\t// The built-in \"create\" action per source (Rest API / email / Slack). A source\n\t// with an action drills into [its instances + a \"Create new\" row] — like the\n\t// Sub-agent category — instead of showing a duplicate flat \"create\" row.\n\tconst actionBySource = useMemo(\n\t\t() =>\n\t\t\tnew Map<string, ToolAction>(\n\t\t\t\t(toolActions ?? []).map((a) => [a.source, a]),\n\t\t\t),\n\t\t[toolActions],\n\t);\n\n\t// Show a category when it has items — and ALWAYS show Sub-agent when creating\n\t// one is possible, so an agent with no sub-agents yet still gets the root\n\t// \"Tools / Sub-agent\" choice (with a \"Create new\" inside). When only one is\n\t// available (e.g. the sub-agent drawer offers tools only) the selector is skipped.\n\tconst availableCategories = useMemo(\n\t\t() =>\n\t\t\tCATEGORIES.filter((c) =>\n\t\t\t\tc.key === 'tool'\n\t\t\t\t\t? tools.length > 0 || (toolActions?.length ?? 0) > 0\n\t\t\t\t\t: subAgents.length > 0 || !!onCreateSubAgent,\n\t\t\t),\n\t\t[tools.length, subAgents.length, onCreateSubAgent, toolActions?.length],\n\t);\n\tconst soleCategory =\n\t\tavailableCategories.length === 1 ? availableCategories[0].key : null;\n\tconst activeCategory = category ?? soleCategory;\n\n\t// Title shown above the current view. `onBack` is omitted at a root level (a\n\t// sole category has nowhere to go back to) — the header then shows as a plain\n\t// title. When `onBack` is set the header leads with a back arrow, followed by\n\t// the source icon in a source detail view: `[← back][icon][title]`.\n\tconst header: {\n\t\ttitle: string;\n\t\tonBack?: () => void;\n\t\ticon?: SourceIcon;\n\t} | null = !activeCategory\n\t\t? null\n\t\t: activeCategory === 'subagent'\n\t\t? // Always titled — with a back arrow only when the category chooser is above.\n\t\t {\n\t\t\t\ttitle: 'Sub-agent',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t }\n\t\t: source\n\t\t? {\n\t\t\t\ttitle: toolSourceLabel(source),\n\t\t\t\t// Deep-linked to a source (opened from a right-panel source button):\n\t\t\t\t// that source IS the root, so no back arrow. Otherwise back clears the\n\t\t\t\t// source — returning to the Integrations group if we came via it (its\n\t\t\t\t// `group` state is untouched), else to the source chooser.\n\t\t\t\tonBack: initialSource ? undefined : () => setSource(null),\n\t\t\t\ticon: sourceIcon(source),\n\t\t }\n\t\t: group === 'integrations'\n\t\t? { title: 'Integrations', onBack: () => setGroup(null) }\n\t\t: // Always titled — matches the Sub-agent header; back arrow only when the\n\t\t // category chooser is above (i.e. not the sole category).\n\t\t {\n\t\t\t\ttitle: 'Tools',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t };\n\n\t// Build the navigable rows for the current view.\n\tconst rows: PickerRowModel[] = useMemo(() => {\n\t\tif (!activeCategory) {\n\t\t\treturn availableCategories.map((c) => ({\n\t\t\t\tid: c.key,\n\t\t\t\tlabel: c.label,\n\t\t\t\tdrillsIn: true,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tsetCategory(c.key);\n\t\t\t\t\tsetSource(null);\n\t\t\t\t\tsetGroup(null);\n\t\t\t\t},\n\t\t\t}));\n\t\t}\n\t\tif (activeCategory === 'subagent') {\n\t\t\tconst sq = search.trim().toLowerCase();\n\t\t\tconst leaves: PickerRowModel[] = subAgents\n\t\t\t\t.filter((item) => !sq || rowLabel(item).toLowerCase().includes(sq))\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tid: String(item.id),\n\t\t\t\t\tlabel: rowLabel(item),\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t\t}));\n\t\t\t// \"Create new\" opens the drawer — first dismiss the menu (strips the \"@\").\n\t\t\tif (onCreateSubAgent) {\n\t\t\t\tleaves.push({\n\t\t\t\t\tid: CREATE_SUBAGENT_ID,\n\t\t\t\t\tlabel: 'Create new',\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tisCreate: true,\n\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\tonCreateSubAgent();\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn leaves;\n\t\t}\n\t\tif (!source) {\n\t\t\t// The real sources (from instances) plus any action source (Rest API /\n\t\t\t// email / Slack) with no instances yet, so it still appears for first-time\n\t\t\t// creation. Deduped — no more twin rows.\n\t\t\tconst actionOnly = (toolActions ?? [])\n\t\t\t\t.map((a) => a.source)\n\t\t\t\t.filter((s) => !sources.includes(s));\n\t\t\tconst combined = [...sources, ...actionOnly];\n\n\t\t\t// One drill-in row per source: Connect (unconnected) / a single collapsed\n\t\t\t// leaf / a drill-in. Reused at the top level AND inside the Integrations\n\t\t\t// group so both behave identically.\n\t\t\tconst buildSourceRow = (s: string): PickerRowModel => {\n\t\t\t\tconst action = actionBySource.get(s);\n\t\t\t\t// Not connected → a \"Connect\" row (no drill-in / no instances / no\n\t\t\t\t// \"Create new\"); clicking dismisses the picker and runs the connect\n\t\t\t\t// flow. Applies to config actions (their own `connected`) AND native\n\t\t\t\t// source groups (via `integrationStatus`), so both look consistent.\n\t\t\t\tconst connected =\n\t\t\t\t\taction !== undefined\n\t\t\t\t\t\t? action.connected\n\t\t\t\t\t\t: integrationStatus?.[s as ToolSource];\n\t\t\t\tif (connected === false) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: s,\n\t\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\t\trightLabel: 'Connect',\n\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\tif (action?.onConnect) {\n\t\t\t\t\t\t\t\taction.onConnect();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tonConnectIntegration?.(s as ToolSource);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// A source whose drill-in view would hold exactly one leaf is pointless\n\t\t\t\t// to drill into — surface that single leaf right here (its function name\n\t\t\t\t// + the same source icon). Covers \"no Rest API added yet\" (→ open the\n\t\t\t\t// create modal directly) and a config tool's single capability (Slack →\n\t\t\t\t// \"Send Slack message\", email → \"Send email\").\n\t\t\t\tconst instances = tools.filter(\n\t\t\t\t\t(t) => (metaOf(t)?.source ?? 'other') === s,\n\t\t\t\t);\n\t\t\t\tif (instances.length + (action ? 1 : 0) === 1) {\n\t\t\t\t\tconst icon = sourceIcon(s) ?? action?.icon;\n\t\t\t\t\tif (action) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: s,\n\t\t\t\t\t\t\tlabel: action.label,\n\t\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\t\ticon,\n\t\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\t\taction.onSelect();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tconst only = instances[0];\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: String(only.id),\n\t\t\t\t\t\tlabel: rowLabel(only),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon,\n\t\t\t\t\t\tauthRequired: metaOf(only)?.authRequired,\n\t\t\t\t\t\tonActivate: () => onSelect(only),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tid: s,\n\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\tdrillsIn: true,\n\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\tonActivate: () => setSource(s),\n\t\t\t\t};\n\t\t\t};\n\n\t\t\t// Inside the Integrations group: just its member sources, ranked.\n\t\t\tif (group === 'integrations') {\n\t\t\t\treturn combined\n\t\t\t\t\t.filter(isIntegrationSource)\n\t\t\t\t\t.sort((a, b) => toolSourceRank(a) - toolSourceRank(b))\n\t\t\t\t\t.map(buildSourceRow);\n\t\t\t}\n\n\t\t\t// Top level: non-integration sources as their own rows, plus ONE\n\t\t\t// \"Integrations\" drill-in row (only when a member exists). Fixed rank order\n\t\t\t// so adding/updating a tool never reshuffles the picker rows.\n\t\t\tconst topRows = combined\n\t\t\t\t.filter((s) => !isIntegrationSource(s))\n\t\t\t\t.map((s) => ({ rank: toolSourceRank(s), row: buildSourceRow(s) }));\n\t\t\tif (combined.some(isIntegrationSource)) {\n\t\t\t\ttopRows.push({\n\t\t\t\t\trank: INTEGRATIONS_RANK,\n\t\t\t\t\trow: {\n\t\t\t\t\t\tid: '__integrations__',\n\t\t\t\t\t\tlabel: 'Integrations',\n\t\t\t\t\t\tdrillsIn: true,\n\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\tsetGroup('integrations');\n\t\t\t\t\t\t\tsetSource(null);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn topRows.sort((a, b) => a.rank - b.rank).map((x) => x.row);\n\t\t}\n\t\tconst q = search.trim().toLowerCase();\n\t\tconst leaves: PickerRowModel[] = tools\n\t\t\t.filter((t) => (metaOf(t)?.source ?? 'other') === source)\n\t\t\t.filter((t) => !q || rowLabel(t).toLowerCase().includes(q))\n\t\t\t.map((item) => ({\n\t\t\t\tid: String(item.id),\n\t\t\t\tlabel: rowLabel(item),\n\t\t\t\tdrillsIn: false,\n\t\t\t\tauthRequired: metaOf(item)?.authRequired,\n\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t}));\n\t\t// A configurable source's add row, below any existing instances, opening\n\t\t// its drawer. Config tools (Slack / email) are a single fixed capability →\n\t\t// render like a normal tool leaf (label only, no icon — matching the tool\n\t\t// rows). Rest API instances are user-created, so its \"add\" stays a\n\t\t// brand-coloured create row.\n\t\tconst action = actionBySource.get(source);\n\t\tif (action) {\n\t\t\tconst isConfigTool = source in CONFIG_TOOL_SOURCES;\n\t\t\tleaves.push({\n\t\t\t\tid: `create:${source}`,\n\t\t\t\tlabel: action.label,\n\t\t\t\tdrillsIn: false,\n\t\t\t\tisCreate: !isConfigTool,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tonClose?.();\n\t\t\t\t\taction.onSelect();\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn leaves;\n\t}, [\n\t\tactiveCategory,\n\t\tavailableCategories,\n\t\tsource,\n\t\tgroup,\n\t\tsearch,\n\t\ttools,\n\t\tsubAgents,\n\t\tsources,\n\t\tonSelect,\n\t\tonClose,\n\t\tonCreateSubAgent,\n\t\ttoolActions,\n\t\tactionBySource,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\n\t]);\n\n\t// Reset highlight whenever the view (or filtered result set) changes.\n\tuseEffect(\n\t\t() => setActiveIndex(-1),\n\t\t[activeCategory, source, group, search, items],\n\t);\n\t// Clear the search box when leaving a source view.\n\tuseEffect(() => setSearch(''), [activeCategory, source, group]);\n\n\t// Keep the latest rows/index reachable from the stable key handler.\n\tconst navRef = useRef({ rows, activeIndex, header });\n\tnavRef.current = { rows, activeIndex, header };\n\n\tuseEffect(() => {\n\t\tif (!registerKeyHandler) {\n\t\t\treturn;\n\t\t}\n\t\tregisterKeyHandler((event) => {\n\t\t\tconst { rows: r, activeIndex: i, header: h } = navRef.current;\n\t\t\tswitch (event.key) {\n\t\t\t\tcase 'ArrowDown':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowUp':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + r.length - 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowRight':\n\t\t\t\tcase 'Enter':\n\t\t\t\t\t// Nothing highlighted yet → treat the first row as the target so\n\t\t\t\t\t// the editor's @-flow (type, then Enter) still works.\n\t\t\t\t\t(r[i] ?? r[0])?.onActivate();\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowLeft':\n\t\t\t\t\tif (h?.onBack) {\n\t\t\t\t\t\th.onBack();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\treturn () => registerKeyHandler(null);\n\t}, [registerKeyHandler]);\n\n\tconst variant = !activeCategory\n\t\t? 'categories'\n\t\t: rows.length && !rows[0].drillsIn\n\t\t? 'items'\n\t\t: 'sources';\n\n\t// Search lives inside a source's tool list (Manifest / Shopify) and in the\n\t// sub-agent list.\n\tconst showSearch =\n\t\t(activeCategory === 'tool' && !!source) || activeCategory === 'subagent';\n\n\treturn (\n\t\t<PickerCard className={`bik-mention-picker bik-mention-picker--${variant}`}>\n\t\t\t{header && (\n\t\t\t\t<PickerBack\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={header.onBack}\n\t\t\t\t\tdisabled={!header.onBack}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackground: COLORS.surface.subdued,\n\t\t\t\t\t\tcursor: header.onBack ? 'pointer' : 'default',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{header.onBack && (\n\t\t\t\t\t\t<SvgArrowLeft\n\t\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\t\theight={20}\n\t\t\t\t\t\t\tcolor={COLORS.content.primary}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{header.icon && renderSourceIcon(header.icon)}\n\t\t\t\t\t<TitleSmall> {header.title}</TitleSmall>\n\t\t\t\t</PickerBack>\n\t\t\t)}\n\t\t\t{showSearch && (\n\t\t\t\t<PickerSearchRow>\n\t\t\t\t\t<SearchIcon\n\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\theight={20}\n\t\t\t\t\t\tcolor={COLORS.content.placeholder}\n\t\t\t\t\t/>\n\t\t\t\t\t<PickerSearchInput\n\t\t\t\t\t\t// Focus on open so the user can type immediately (appears only\n\t\t\t\t\t\t// after they drill into a source).\n\t\t\t\t\t\t// eslint-disable-next-line jsx-a11y/no-autofocus\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tplaceholder=\"Search\"\n\t\t\t\t\t\tdata-test=\"mention-picker-search\"\n\t\t\t\t\t\tonChange={(e) => setSearch(e.target.value)}\n\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\tif (!rows.length) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (e.key === 'ArrowDown') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'ArrowUp') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + rows.length - 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'Enter') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t(rows[activeIndex] ?? rows[0])?.onActivate();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</PickerSearchRow>\n\t\t\t)}\n\t\t\t{rows.length === 0 ? (\n\t\t\t\t<PickerEmpty>\n\t\t\t\t\t{activeCategory === 'subagent' ? null : 'No tools available'}\n\t\t\t\t</PickerEmpty>\n\t\t\t) : (\n\t\t\t\trows.map((row, i) => (\n\t\t\t\t\t<PickerRow\n\t\t\t\t\t\tkey={row.id}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t$active={i === activeIndex}\n\t\t\t\t\t\tonMouseEnter={() => setActiveIndex(i)}\n\t\t\t\t\t\tonMouseLeave={() => setActiveIndex(-1)}\n\t\t\t\t\t\tonClick={row.onActivate}\n\t\t\t\t\t>\n\t\t\t\t\t\t{row.isCreate ? (\n\t\t\t\t\t\t\t<CreateRowText>{row.label}</CreateRowText>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<PickerRowMain>\n\t\t\t\t\t\t\t\t\t{renderSourceIcon(row.icon)}\n\t\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t\t{row.label}\n\t\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t\t{row.authRequired && (\n\t\t\t\t\t\t\t\t\t\t<Shield\n\t\t\t\t\t\t\t\t\t\t\tsize={16}\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"This tool requires customer verification\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</PickerRowMain>\n\t\t\t\t\t\t\t\t{row.rightLabel ? (\n\t\t\t\t\t\t\t\t\t<RightActionText>{row.rightLabel}</RightActionText>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\trow.drillsIn && <ChevronRight width={12} height={12} />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</PickerRow>\n\t\t\t\t))\n\t\t\t)}\n\t\t\t{rows.some((row) => row.authRequired) && (\n\t\t\t\t<PickerLegend>\n\t\t\t\t\t<Shield size={16} />\n\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\tThis tool requires customer verification\n\t\t\t\t\t</BodyCaption>\n\t\t\t\t</PickerLegend>\n\t\t\t)}\n\t\t</PickerCard>\n\t);\n};\n\nconst PickerCard = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tmin-width: 240px;\n\tmax-height: 301px;\n\toverflow-y: auto;\n\tbackground: ${COLORS.surface.standard};\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tbox-shadow: 0px -2px 8px 0px #0000001f;\n`;\n\n// Search box at the top of a source's tool list (Manifest / Shopify).\nconst PickerSearchRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 10px 12px;\n\tflex-shrink: 0;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n`;\n\nconst PickerSearchInput = styled.input`\n\tflex: 1;\n\tmin-width: 0;\n\tborder: none;\n\toutline: none;\n\tbackground: transparent;\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tcolor: ${COLORS.content.primary};\n\n\t&::placeholder {\n\t\tcolor: ${COLORS.content.placeholder};\n\t}\n`;\n\nconst PickerRow = styled.button<{ $active?: boolean }>`\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n\tgap: 2px;\n\twidth: 100%;\n\tpadding: 8px 10px;\n\theight: 48px;\n\t/* The card is a flex column with a max-height; without these a long list\n\t compresses its rows below 48px (why only the short first step looked right)\n\t instead of scrolling. Pin the row so the card scrolls instead. */\n\tbox-sizing: border-box;\n\tflex-shrink: 0;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: ${(p) => (p.$active ? COLORS.surface.subdued : 'transparent')};\n\tcursor: pointer;\n\ttext-align: left;\n\n\t&:hover {\n\t\tbackground: ${COLORS.surface.hovered};\n\t}\n`;\n\n// Left cluster: leading source glyph + label (chevron stays right via PickerRow).\nconst PickerRowMain = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tmin-width: 0;\n`;\n\n// Footer legend, shown when the list holds any auth-required tool.\nconst PickerLegend = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 8px 12px;\n\tborder-top: 1px solid ${COLORS.stroke.primary};\n`;\n\n// Right-aligned brand action text (e.g. \"Connect\") in place of the chevron.\nconst RightActionText = styled.span`\n\tflex-shrink: 0;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n`;\n\n// \"Create new\" — centered brand text, no icon (matches the side-panel dropdown).\nconst CreateRowText = styled.div`\n\twidth: 100%;\n\ttext-align: center;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n`;\n\nconst PickerBack = styled.button`\n\tdisplay: flex;\n\talign-items: center;\n\tpadding: 12px 16px;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: transparent;\n\tcursor: pointer;\n\tfont-family: Inter;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\theight: 48px;\n\tbox-sizing: border-box;\n\tflex-shrink: 0;\n\tgap: 4px;\n`;\n\nconst PickerEmpty = styled.div`\n\tpadding: 12px 10px;\n\tfont-family: Inter;\n\tfont-size: 13px;\n\tcolor: ${COLORS.content.secondary};\n`;\n"],"names":["metaOf","item","rowLabel","CREATE_SUBAGENT_ID","MentionPicker","items","onSelect","registerKeyHandler","onClose","onCreateSubAgent","initialSource","toolActions","integrationStatus","onConnectIntegration","category","setCategory","useState","source","setSource","group","setGroup","activeIndex","setActiveIndex","search","setSearch","tools","useMemo","i","subAgents","sources","acc","t","s","actionBySource","a","availableCategories","CATEGORIES","c","soleCategory","activeCategory","header","toolSourceLabel","sourceIcon","rows","sq","leaves","actionOnly","combined","buildSourceRow","action","instances","icon","only","isIntegrationSource","b","toolSourceRank","topRows","INTEGRATIONS_RANK","x","q","isConfigTool","CONFIG_TOOL_SOURCES","useEffect","navRef","useRef","event","h","p","variant","showSearch","jsxs","PickerCard","PickerBack","COLORS","jsx","SvgArrowLeft","renderSourceIcon","TitleSmall","PickerSearchRow","SearchIcon","PickerSearchInput","PickerEmpty","row","PickerRow","CreateRowText","Fragment","PickerRowMain","BodySecondary","Shield","RightActionText","ChevronRight","PickerLegend","BodyCaption","styled"],"mappings":"0pBA4BMA,EAAUC,GACfA,EAAK,KAEAC,EAAYD,GACjBD,EAAOC,CAAI,GAAG,YAAcA,EAAK,MAuB5BE,GAAqB,0BAmCdC,GAA8C,CAAC,CAC3D,MAAAC,EACA,SAAAC,EACA,mBAAAC,EACA,QAAAC,EACA,iBAAAC,EACA,cAAAC,EACA,YAAAC,EACA,kBAAAC,EACA,qBAAAC,CACD,IAAM,CACL,KAAM,CAACC,EAAUC,CAAW,EAAIC,EAAAA,SAA0B,IAAI,EACxD,CAACC,EAAQC,CAAS,EAAIF,EAAAA,SAAwBN,GAAiB,IAAI,EAGnE,CAACS,EAAOC,CAAQ,EAAIJ,EAAAA,SAAgC,IAAI,EAGxD,CAACK,EAAaC,CAAc,EAAIN,EAAAA,SAAS,EAAE,EAG3C,CAACO,EAAQC,CAAS,EAAIR,EAAAA,SAAS,EAAE,EAEjCS,EAAQC,EAAAA,QACb,IAAMrB,EAAM,OAAQsB,GAAM3B,EAAO2B,CAAC,GAAG,OAAS,MAAM,EACpD,CAACtB,CAAK,CAAA,EAEDuB,EAAYF,EAAAA,QACjB,IAAMrB,EAAM,OAAQsB,GAAM3B,EAAO2B,CAAC,GAAG,OAAS,UAAU,EACxD,CAACtB,CAAK,CAAA,EAEDwB,EAAUH,EAAAA,QAAQ,IAAM,CAC7B,MAAMI,EAAgB,CAAA,EACtBL,OAAAA,EAAM,QAASM,GAAM,CACpB,MAAMC,EAAIhC,EAAO+B,CAAC,GAAG,QAAU,QAC1BD,EAAI,SAASE,CAAC,GAClBF,EAAI,KAAKE,CAAC,CAEZ,CAAC,EACMF,CACR,EAAG,CAACL,CAAK,CAAC,EAIJQ,EAAiBP,EAAAA,QACtB,IACC,IAAI,KACFf,GAAe,CAAA,GAAI,IAAKuB,GAAM,CAACA,EAAE,OAAQA,CAAC,CAAC,CAAA,EAE9C,CAACvB,CAAW,CAAA,EAOPwB,EAAsBT,EAAAA,QAC3B,IACCU,EAAAA,WAAW,OAAQC,GAClBA,EAAE,MAAQ,OACPZ,EAAM,OAAS,IAAMd,GAAa,QAAU,GAAK,EACjDiB,EAAU,OAAS,GAAK,CAAC,CAACnB,CAAA,EAE/B,CAACgB,EAAM,OAAQG,EAAU,OAAQnB,EAAkBE,GAAa,MAAM,CAAA,EAEjE2B,EACLH,EAAoB,SAAW,EAAIA,EAAoB,CAAC,EAAE,IAAM,KAC3DI,EAAiBzB,GAAYwB,EAM7BE,EAIMD,EAETA,IAAmB,WAEnB,CACA,MAAO,YACP,OAAQD,EAAe,OAAY,IAAMvB,EAAY,IAAI,CAAA,EAEzDE,EACA,CACA,MAAOwB,EAAAA,gBAAgBxB,CAAM,EAK7B,OAAQP,EAAgB,OAAY,IAAMQ,EAAU,IAAI,EACxD,KAAMwB,EAAAA,WAAWzB,CAAM,CAAA,EAEvBE,IAAU,eACV,CAAE,MAAO,eAAgB,OAAQ,IAAMC,EAAS,IAAI,CAAA,EAGpD,CACA,MAAO,QACP,OAAQkB,EAAe,OAAY,IAAMvB,EAAY,IAAI,CAAA,EAvBzD,KA2BG4B,EAAyBjB,EAAAA,QAAQ,IAAM,CAC5C,GAAI,CAACa,EACJ,OAAOJ,EAAoB,IAAKE,IAAO,CACtC,GAAIA,EAAE,IACN,MAAOA,EAAE,MACT,SAAU,GACV,WAAY,IAAM,CACjBtB,EAAYsB,EAAE,GAAG,EACjBnB,EAAU,IAAI,EACdE,EAAS,IAAI,CACd,CAAA,EACC,EAEH,GAAImB,IAAmB,WAAY,CAClC,MAAMK,EAAKrB,EAAO,KAAA,EAAO,YAAA,EACnBsB,EAA2BjB,EAC/B,OAAQ3B,GAAS,CAAC2C,GAAM1C,EAASD,CAAI,EAAE,YAAA,EAAc,SAAS2C,CAAE,CAAC,EACjE,IAAK3C,IAAU,CACf,GAAI,OAAOA,EAAK,EAAE,EAClB,MAAOC,EAASD,CAAI,EACpB,SAAU,GACV,WAAY,IAAMK,EAASL,CAAI,CAAA,EAC9B,EAEH,OAAIQ,GACHoC,EAAO,KAAK,CACX,GAAI1C,GACJ,MAAO,aACP,SAAU,GACV,SAAU,GACV,WAAY,IAAM,CACjBK,IAAA,EACAC,EAAA,CACD,CAAA,CACA,EAEKoC,CACR,CACA,GAAI,CAAC5B,EAAQ,CAIZ,MAAM6B,GAAcnC,GAAe,CAAA,GACjC,IAAKuB,GAAMA,EAAE,MAAM,EACnB,OAAQF,GAAM,CAACH,EAAQ,SAASG,CAAC,CAAC,EAC9Be,EAAW,CAAC,GAAGlB,EAAS,GAAGiB,CAAU,EAKrCE,EAAkBhB,GAA8B,CACrD,MAAMiB,EAAShB,EAAe,IAAID,CAAC,EASnC,IAHCiB,IAAW,OACRA,EAAO,UACPrC,IAAoBoB,CAAe,KACrB,GACjB,MAAO,CACN,GAAIA,EACJ,MAAOS,EAAAA,gBAAgBT,CAAC,EACxB,SAAU,GACV,KAAMU,EAAAA,WAAWV,CAAC,GAAKiB,GAAQ,KAC/B,WAAY,UACZ,WAAY,IAAM,CACjBzC,IAAA,EACIyC,GAAQ,UACXA,EAAO,UAAA,EAEPpC,IAAuBmB,CAAe,CAExC,CAAA,EAQF,MAAMkB,EAAYzB,EAAM,OACtBM,IAAO/B,EAAO+B,CAAC,GAAG,QAAU,WAAaC,CAAA,EAE3C,GAAIkB,EAAU,QAAUD,EAAS,EAAI,KAAO,EAAG,CAC9C,MAAME,EAAOT,EAAAA,WAAWV,CAAC,GAAKiB,GAAQ,KACtC,GAAIA,EACH,MAAO,CACN,GAAIjB,EACJ,MAAOiB,EAAO,MACd,SAAU,GACV,KAAAE,EACA,WAAY,IAAM,CACjB3C,IAAA,EACAyC,EAAO,SAAA,CACR,CAAA,EAGF,MAAMG,EAAOF,EAAU,CAAC,EACxB,MAAO,CACN,GAAI,OAAOE,EAAK,EAAE,EAClB,MAAOlD,EAASkD,CAAI,EACpB,SAAU,GACV,KAAAD,EACA,aAAcnD,EAAOoD,CAAI,GAAG,aAC5B,WAAY,IAAM9C,EAAS8C,CAAI,CAAA,CAEjC,CACA,MAAO,CACN,GAAIpB,EACJ,MAAOS,EAAAA,gBAAgBT,CAAC,EACxB,SAAU,GACV,KAAMU,EAAAA,WAAWV,CAAC,GAAKiB,GAAQ,KAC/B,WAAY,IAAM/B,EAAUc,CAAC,CAAA,CAE/B,EAGA,GAAIb,IAAU,eACb,OAAO4B,EACL,OAAOM,EAAAA,mBAAmB,EAC1B,KAAK,CAACnB,EAAGoB,IAAMC,EAAAA,eAAerB,CAAC,EAAIqB,EAAAA,eAAeD,CAAC,CAAC,EACpD,IAAIN,CAAc,EAMrB,MAAMQ,EAAUT,EACd,OAAQf,GAAM,CAACqB,EAAAA,oBAAoBrB,CAAC,CAAC,EACrC,IAAKA,IAAO,CAAE,KAAMuB,EAAAA,eAAevB,CAAC,EAAG,IAAKgB,EAAehB,CAAC,CAAA,EAAI,EAClE,OAAIe,EAAS,KAAKM,EAAAA,mBAAmB,GACpCG,EAAQ,KAAK,CACZ,KAAMC,EAAAA,kBACN,IAAK,CACJ,GAAI,mBACJ,MAAO,eACP,SAAU,GACV,WAAY,IAAM,CACjBrC,EAAS,cAAc,EACvBF,EAAU,IAAI,CACf,CAAA,CACD,CACA,EAEKsC,EAAQ,KAAK,CAACtB,EAAGoB,IAAMpB,EAAE,KAAOoB,EAAE,IAAI,EAAE,IAAKI,GAAMA,EAAE,GAAG,CAChE,CACA,MAAMC,EAAIpC,EAAO,KAAA,EAAO,YAAA,EAClBsB,EAA2BpB,EAC/B,OAAQM,IAAO/B,EAAO+B,CAAC,GAAG,QAAU,WAAad,CAAM,EACvD,OAAQc,GAAM,CAAC4B,GAAKzD,EAAS6B,CAAC,EAAE,cAAc,SAAS4B,CAAC,CAAC,EACzD,IAAK1D,IAAU,CACf,GAAI,OAAOA,EAAK,EAAE,EAClB,MAAOC,EAASD,CAAI,EACpB,SAAU,GACV,aAAcD,EAAOC,CAAI,GAAG,aAC5B,WAAY,IAAMK,EAASL,CAAI,CAAA,EAC9B,EAMGgD,EAAShB,EAAe,IAAIhB,CAAM,EACxC,GAAIgC,EAAQ,CACX,MAAMW,EAAe3C,KAAU4C,EAAAA,oBAC/BhB,EAAO,KAAK,CACX,GAAI,UAAU5B,CAAM,GACpB,MAAOgC,EAAO,MACd,SAAU,GACV,SAAU,CAACW,EACX,WAAY,IAAM,CACjBpD,IAAA,EACAyC,EAAO,SAAA,CACR,CAAA,CACA,CACF,CACA,OAAOJ,CACR,EAAG,CACFN,EACAJ,EACAlB,EACAE,EACAI,EACAE,EACAG,EACAC,EACAvB,EACAE,EACAC,EACAE,EACAsB,EACArB,EACAC,CAAA,CACA,EAGDiD,EAAAA,UACC,IAAMxC,EAAe,EAAE,EACvB,CAACiB,EAAgBtB,EAAQE,EAAOI,EAAQlB,CAAK,CAAA,EAG9CyD,EAAAA,UAAU,IAAMtC,EAAU,EAAE,EAAG,CAACe,EAAgBtB,EAAQE,CAAK,CAAC,EAG9D,MAAM4C,EAASC,EAAAA,OAAO,CAAE,KAAArB,EAAM,YAAAtB,EAAa,OAAAmB,EAAQ,EACnDuB,EAAO,QAAU,CAAE,KAAApB,EAAM,YAAAtB,EAAa,OAAAmB,CAAA,EAEtCsB,EAAAA,UAAU,IAAM,CACf,GAAKvD,EAGL,OAAAA,EAAoB0D,GAAU,CAC7B,KAAM,CAAE,KAAM,EAAG,YAAatC,EAAG,OAAQuC,GAAMH,EAAO,QACtD,OAAQE,EAAM,IAAA,CACb,IAAK,YACJ,OAAI,EAAE,QAAQ3C,EAAgB6C,IAAOA,EAAI,GAAK,EAAE,MAAM,EAC/C,GACR,IAAK,UACJ,OAAI,EAAE,QAAQ7C,EAAgB6C,IAAOA,EAAI,EAAE,OAAS,GAAK,EAAE,MAAM,EAC1D,GACR,IAAK,aACL,IAAK,QAGJ,OAAC,EAAExC,CAAC,GAAK,EAAE,CAAC,IAAI,WAAA,EACT,GACR,IAAK,YACJ,OAAIuC,GAAG,QACNA,EAAE,OAAA,EACK,IAED,GACR,QACC,MAAO,EAAA,CAEV,CAAC,EACM,IAAM3D,EAAmB,IAAI,CACrC,EAAG,CAACA,CAAkB,CAAC,EAEvB,MAAM6D,EAAW7B,EAEdI,EAAK,QAAU,CAACA,EAAK,CAAC,EAAE,SACxB,QACA,UAHA,aAOG0B,EACJ9B,IAAmB,QAAU,CAAC,CAACtB,GAAWsB,IAAmB,WAE/D,OACC+B,EAAAA,KAACC,GAAA,CAAW,UAAW,0CAA0CH,CAAO,GACtE,SAAA,CAAA5B,GACA8B,EAAAA,KAACE,GAAA,CACA,KAAK,SACL,QAAShC,EAAO,OAChB,SAAU,CAACA,EAAO,OAClB,MAAO,CACN,WAAYiC,EAAAA,OAAO,QAAQ,QAC3B,OAAQjC,EAAO,OAAS,UAAY,SAAA,EAGpC,SAAA,CAAAA,EAAO,QACPkC,EAAAA,IAACC,GAAAA,QAAA,CACA,MAAO,GACP,OAAQ,GACR,MAAOF,EAAAA,OAAO,QAAQ,OAAA,CAAA,EAGvBjC,EAAO,MAAQoC,mBAAiBpC,EAAO,IAAI,SAC3CqC,EAAAA,WAAA,CAAW,SAAA,CAAA,IAAErC,EAAO,KAAA,CAAA,CAAM,CAAA,CAAA,CAAA,EAG5B6B,UACCS,GAAA,CACA,SAAA,CAAAJ,EAAAA,IAACK,GAAAA,QAAA,CACA,MAAO,GACP,OAAQ,GACR,MAAON,EAAAA,OAAO,QAAQ,WAAA,CAAA,EAEvBC,EAAAA,IAACM,GAAA,CAIA,UAAS,GACT,MAAOzD,EACP,YAAY,SACZ,YAAU,wBACV,SAAW,GAAMC,EAAU,EAAE,OAAO,KAAK,EACzC,UAAY,GAAM,CACZmB,EAAK,SAGN,EAAE,MAAQ,aACb,EAAE,eAAA,EACFrB,EAAgB6C,IAAOA,EAAI,GAAKxB,EAAK,MAAM,GACjC,EAAE,MAAQ,WACpB,EAAE,eAAA,EACFrB,EAAgB6C,IAAOA,EAAIxB,EAAK,OAAS,GAAKA,EAAK,MAAM,GAC/C,EAAE,MAAQ,UACpB,EAAE,eAAA,GACDA,EAAKtB,CAAW,GAAKsB,EAAK,CAAC,IAAI,WAAA,GAElC,CAAA,CAAA,CACD,EACD,EAEAA,EAAK,SAAW,EAChB+B,EAAAA,IAACO,IACC,SAAA1C,IAAmB,WAAa,KAAO,oBAAA,CACzC,EAEAI,EAAK,IAAI,CAACuC,EAAKvD,IACd+C,EAAAA,IAACS,GAAA,CAEA,KAAK,SACL,QAASxD,IAAMN,EACf,aAAc,IAAMC,EAAeK,CAAC,EACpC,aAAc,IAAML,EAAe,EAAE,EACrC,QAAS4D,EAAI,WAEZ,WAAI,SACJR,EAAAA,IAACU,IAAe,SAAAF,EAAI,KAAA,CAAM,EAE1BZ,EAAAA,KAAAe,EAAAA,SAAA,CACC,SAAA,CAAAf,OAACgB,GAAA,CACC,SAAA,CAAAV,EAAAA,iBAAiBM,EAAI,IAAI,QACzBK,EAAAA,cAAA,CAAc,MAAOd,EAAAA,OAAO,QAAQ,QACnC,WAAI,MACN,EACCS,EAAI,cACJR,EAAAA,IAACc,EAAAA,QAAA,CACA,KAAM,GACN,aAAW,0CAAA,CAAA,CACZ,EAEF,EACCN,EAAI,WACJR,MAACe,GAAA,CAAiB,WAAI,UAAA,CAAW,EAEjCP,EAAI,UAAYR,EAAAA,IAACgB,GAAAA,QAAA,CAAa,MAAO,GAAI,OAAQ,EAAA,CAAI,CAAA,CAAA,CAEvD,CAAA,EA5BIR,EAAI,EAAA,CA+BV,EAEDvC,EAAK,KAAMuC,GAAQA,EAAI,YAAY,UAClCS,GAAA,CACA,SAAA,CAAAjB,EAAAA,IAACc,EAAAA,QAAA,CAAO,KAAM,EAAA,CAAI,QACjBI,EAAAA,YAAA,CAAY,MAAOnB,EAAAA,OAAO,QAAQ,UAAW,SAAA,0CAAA,CAE9C,CAAA,CAAA,CACD,CAAA,EAEF,CAEF,EAEMF,GAAasB,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAMXpB,EAAAA,OAAO,QAAQ,QAAQ;AAAA,qBACjBA,EAAAA,OAAO,OAAO,OAAO;AAAA;AAAA;AAAA,EAMpCK,GAAkBe,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAMHpB,EAAAA,OAAO,OAAO,OAAO;AAAA,EAG3CO,GAAoBa,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAQvBpB,EAAAA,OAAO,QAAQ,OAAO;AAAA;AAAA;AAAA,WAGrBA,EAAAA,OAAO,QAAQ,WAAW;AAAA;AAAA,EAI/BU,GAAYU,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAcGpB,EAAAA,OAAO,OAAO,OAAO;AAAA,eACjCN,GAAOA,EAAE,QAAUM,EAAAA,OAAO,QAAQ,QAAU,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA,gBAK1DA,EAAAA,OAAO,QAAQ,OAAO;AAAA;AAAA,EAKhCa,GAAgBO,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAQvBF,GAAeE,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,yBAKHpB,EAAAA,OAAO,OAAO,OAAO;AAAA,EAIxCgB,GAAkBI,EAAAA,QAAO;AAAA;AAAA,UAErBpB,EAAAA,OAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAQxBW,GAAgBS,EAAAA,QAAO;AAAA;AAAA;AAAA,UAGnBpB,EAAAA,OAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA,EAMxBD,GAAaqB,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,4BAKEpB,EAAAA,OAAO,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAY3CQ,GAAcY,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA,UAIjBpB,EAAAA,OAAO,QAAQ,SAAS;AAAA"}
1
+ {"version":3,"file":"MentionPicker.js","sources":["../../../../../src/components/agent-builder/components/MentionPicker.tsx"],"sourcesContent":["// import ChevronLeft from '@src/assets/icons/chevronLeft.svg';\nimport ChevronRight from '@src/assets/icons/chevronRight.svg';\nimport SearchIcon from '@src/assets/icons/searchIcon.svg';\nimport type { MentionDropdownRenderProps, MentionItem } from '@src/editor';\nimport { Shield } from '@src/icons';\nimport SvgArrowLeft from '@src/icons/Arrows/Normal arrows/ArrowLeft';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport {\n\tBodyCaption,\n\tBodySecondary,\n\tTitleSmall,\n} from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tCATEGORIES,\n\tCONFIG_TOOL_SOURCES,\n\tisIntegrationSource,\n\ttoolSourceRank,\n} from '../constants/tools';\nimport type { Category, ToolAction, ToolSource } from '../constants/tools';\nimport {\n\tMentionKindMeta,\n\ttoolSourceLabel,\n} from '../utils/mentionSerialization';\nimport { renderSourceIcon, sourceIcon, SourceIcon } from '../utils/sourceIcons';\n\nconst metaOf = (item: MentionItem): MentionKindMeta | undefined =>\n\titem.meta as unknown as MentionKindMeta | undefined;\n\nconst rowLabel = (item: MentionItem): string =>\n\tmetaOf(item)?.plainLabel ?? item.label;\n\n/** One navigable row in the picker's current view. */\ntype PickerRowModel = {\n\tid: string;\n\tlabel: string;\n\t/** Drill-in rows show a chevron; leaf (selectable) rows do not. */\n\tdrillsIn: boolean;\n\t/** Leading brand glyph (source rows only). */\n\ticon?: SourceIcon;\n\t/** Brand-coloured \"Create new\" action row (not a selectable item). */\n\tisCreate?: boolean;\n\t/**\n\t * Brand-coloured right-aligned action text (e.g. \"Connect\") shown in place of\n\t * the drill-in chevron — used for an unconnected integration source.\n\t */\n\trightLabel?: string;\n\t/** Tool leaf touches customer-private data → shows a shield glyph. */\n\tauthRequired?: boolean;\n\tonActivate: () => void;\n};\n\n/** Sentinel id for the sub-agent \"Create new\" row. */\nconst CREATE_SUBAGENT_ID = '__bik_create_subagent__';\n\ntype MentionPickerProps = MentionDropdownRenderProps & {\n\t/** Opens the create-sub-agent drawer (shows a \"Create new\" row in the Sub-agent view). */\n\tonCreateSubAgent?: () => void;\n\t/**\n\t * Open already drilled into this tool source (e.g. `'shopify'`) — its tool list\n\t * is shown immediately. */\n\tinitialSource?: string;\n\t/**\n\t * Built-in tool actions (Rest API / Handover to email) shown in the Tools view.\n\t * Picking one opens its config drawer (via `onSelect`) and dismisses the picker\n\t * — it never inserts a mention into the text.\n\t */\n\ttoolActions?: ToolAction[];\n\t/**\n\t * Per-source integration connection state. A source whose value is `false`\n\t * renders a \"Connect\" row (like an unconnected action) instead of drilling in —\n\t * so native source groups (Shopify / BigCommerce / ShipStation) show \"Connect\"\n\t * consistently with the config actions (Slack).\n\t */\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\t/** Open the connect flow for an unconnected source (used by the Connect row). */\n\tonConnectIntegration?: (source: ToolSource) => void;\n};\n\n/**\n * `@` reference picker. Drills:\n * root → Tools → <source> (Manifest / Shopify / …) → tool\n * → Sub-agent → sub-agent\n * (\"Add condition\" and \"Variables\" are intentionally not shown yet.)\n *\n * Owns keyboard navigation (↑/↓ move, →/Enter activate, ← go back) over the\n * CURRENTLY visible rows — registered with the editor via `registerKeyHandler`.\n */\nexport const MentionPicker: React.FC<MentionPickerProps> = ({\n\titems,\n\tonSelect,\n\tregisterKeyHandler,\n\tonClose,\n\tonCreateSubAgent,\n\tinitialSource,\n\ttoolActions,\n\tintegrationStatus,\n\tonConnectIntegration,\n}) => {\n\tconst [category, setCategory] = useState<Category | null>(null);\n\tconst [source, setSource] = useState<string | null>(initialSource ?? null);\n\t// -1 = nothing highlighted; rows highlight only on hover / arrow keys\n\t// (a default highlight reads as a stuck hover state).\n\tconst [activeIndex, setActiveIndex] = useState(-1);\n\t// Search box shown inside a source's tool list (Manifest / Shopify); filters\n\t// that source's tools by name.\n\tconst [search, setSearch] = useState('');\n\n\tconst tools = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'tool'),\n\t\t[items],\n\t);\n\tconst subAgents = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'subagent'),\n\t\t[items],\n\t);\n\tconst sources = useMemo(() => {\n\t\tconst acc: string[] = [];\n\t\ttools.forEach((t) => {\n\t\t\tconst s = metaOf(t)?.source ?? 'other';\n\t\t\tif (!acc.includes(s)) {\n\t\t\t\tacc.push(s);\n\t\t\t}\n\t\t});\n\t\treturn acc;\n\t}, [tools]);\n\t// The built-in \"create\" action per source (Rest API / email / Slack). A source\n\t// with an action drills into [its instances + a \"Create new\" row] — like the\n\t// Sub-agent category — instead of showing a duplicate flat \"create\" row.\n\tconst actionBySource = useMemo(\n\t\t() =>\n\t\t\tnew Map<string, ToolAction>(\n\t\t\t\t(toolActions ?? []).map((a) => [a.source, a]),\n\t\t\t),\n\t\t[toolActions],\n\t);\n\n\t// Show a category when it has items — and ALWAYS show Sub-agent when creating\n\t// one is possible, so an agent with no sub-agents yet still gets the root\n\t// \"Tools / Sub-agent\" choice (with a \"Create new\" inside). When only one is\n\t// available (e.g. the sub-agent drawer offers tools only) the selector is skipped.\n\tconst availableCategories = useMemo(\n\t\t() =>\n\t\t\tCATEGORIES.filter((c) =>\n\t\t\t\tc.key === 'tool'\n\t\t\t\t\t? tools.length > 0 || (toolActions?.length ?? 0) > 0\n\t\t\t\t\t: subAgents.length > 0 || !!onCreateSubAgent,\n\t\t\t),\n\t\t[tools.length, subAgents.length, onCreateSubAgent, toolActions?.length],\n\t);\n\tconst soleCategory =\n\t\tavailableCategories.length === 1 ? availableCategories[0].key : null;\n\tconst activeCategory = category ?? soleCategory;\n\n\t// Title shown above the current view. `onBack` is omitted at a root level (a\n\t// sole category has nowhere to go back to) — the header then shows as a plain\n\t// title. When `onBack` is set the header leads with a back arrow, followed by\n\t// the source icon in a source detail view: `[← back][icon][title]`.\n\tconst header: {\n\t\ttitle: string;\n\t\tonBack?: () => void;\n\t\ticon?: SourceIcon;\n\t} | null = !activeCategory\n\t\t? null\n\t\t: activeCategory === 'subagent'\n\t\t? // Always titled — with a back arrow only when the category chooser is above.\n\t\t {\n\t\t\t\ttitle: 'Sub-agent',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t }\n\t\t: source\n\t\t? {\n\t\t\t\ttitle: toolSourceLabel(source),\n\t\t\t\t// Deep-linked to a source (opened from a right-panel source button):\n\t\t\t\t// that source IS the root, so no back arrow. Otherwise back clears the\n\t\t\t\t// source — returning to the source chooser.\n\t\t\t\tonBack: initialSource ? undefined : () => setSource(null),\n\t\t\t\ticon: sourceIcon(source),\n\t\t }\n\t\t: // Always titled — matches the Sub-agent header; back arrow only when the\n\t\t // category chooser is above (i.e. not the sole category).\n\t\t {\n\t\t\t\ttitle: 'Tools',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t };\n\n\t// Build the navigable rows for the current view.\n\tconst rows: PickerRowModel[] = useMemo(() => {\n\t\tif (!activeCategory) {\n\t\t\treturn availableCategories.map((c) => ({\n\t\t\t\tid: c.key,\n\t\t\t\tlabel: c.label,\n\t\t\t\tdrillsIn: true,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tsetCategory(c.key);\n\t\t\t\t\tsetSource(null);\n\t\t\t\t},\n\t\t\t}));\n\t\t}\n\t\tif (activeCategory === 'subagent') {\n\t\t\tconst sq = search.trim().toLowerCase();\n\t\t\tconst leaves: PickerRowModel[] = subAgents\n\t\t\t\t.filter((item) => !sq || rowLabel(item).toLowerCase().includes(sq))\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tid: String(item.id),\n\t\t\t\t\tlabel: rowLabel(item),\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t\t}));\n\t\t\t// \"Create new\" opens the drawer — first dismiss the menu (strips the \"@\").\n\t\t\tif (onCreateSubAgent) {\n\t\t\t\tleaves.push({\n\t\t\t\t\tid: CREATE_SUBAGENT_ID,\n\t\t\t\t\tlabel: 'Create new',\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tisCreate: true,\n\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\tonCreateSubAgent();\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn leaves;\n\t\t}\n\t\tif (!source) {\n\t\t\t// The real sources (from instances) plus any action source (Rest API /\n\t\t\t// email / Slack) with no instances yet, so it still appears for first-time\n\t\t\t// creation. Deduped — no more twin rows.\n\t\t\tconst actionOnly = (toolActions ?? [])\n\t\t\t\t.map((a) => a.source)\n\t\t\t\t.filter((s) => !sources.includes(s));\n\t\t\tconst combined = [...sources, ...actionOnly];\n\n\t\t\t// One row per source: Connect (unconnected) / a single collapsed leaf\n\t\t\t// (action sources) / a drill-in group (integrations + multi-tool sources).\n\t\t\tconst buildSourceRow = (s: string): PickerRowModel => {\n\t\t\t\tconst action = actionBySource.get(s);\n\t\t\t\t// Not connected → a \"Connect\" row (no drill-in / no instances / no\n\t\t\t\t// \"Create new\"); clicking dismisses the picker and runs the connect\n\t\t\t\t// flow. Applies to config actions (their own `connected`) AND native\n\t\t\t\t// source groups (via `integrationStatus`), so both look consistent.\n\t\t\t\tconst connected =\n\t\t\t\t\taction !== undefined\n\t\t\t\t\t\t? action.connected\n\t\t\t\t\t\t: integrationStatus?.[s as ToolSource];\n\t\t\t\tif (connected === false) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: s,\n\t\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\t\trightLabel: 'Connect',\n\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\tif (action?.onConnect) {\n\t\t\t\t\t\t\t\taction.onConnect();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tonConnectIntegration?.(s as ToolSource);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// A source whose drill-in view would hold exactly one leaf is normally\n\t\t\t\t// surfaced as that single leaf right here (its function name + the same\n\t\t\t\t// source icon). Covers \"no Rest API added yet\" (→ open the create modal\n\t\t\t\t// directly) and a config tool's single capability (Slack → \"Send Slack\n\t\t\t\t// message\", email → \"Send email\"). EXCEPTION: external integrations\n\t\t\t\t// (Shopify / BigCommerce / ShipStation / Skio / Gorgias) always stay a\n\t\t\t\t// drill-in group even with a single tool, so the vendor reads as its own\n\t\t\t\t// discoverable, connectable unit.\n\t\t\t\tconst instances = tools.filter(\n\t\t\t\t\t(t) => (metaOf(t)?.source ?? 'other') === s,\n\t\t\t\t);\n\t\t\t\tconst collapseSingleLeaf =\n\t\t\t\t\tinstances.length + (action ? 1 : 0) === 1 &&\n\t\t\t\t\t!(action === undefined && isIntegrationSource(s));\n\t\t\t\tif (collapseSingleLeaf) {\n\t\t\t\t\tconst icon = sourceIcon(s) ?? action?.icon;\n\t\t\t\t\tif (action) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: s,\n\t\t\t\t\t\t\tlabel: action.label,\n\t\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\t\ticon,\n\t\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\t\taction.onSelect();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tconst only = instances[0];\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: String(only.id),\n\t\t\t\t\t\tlabel: rowLabel(only),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon,\n\t\t\t\t\t\tauthRequired: metaOf(only)?.authRequired,\n\t\t\t\t\t\tonActivate: () => onSelect(only),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tid: s,\n\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\tdrillsIn: true,\n\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\tonActivate: () => setSource(s),\n\t\t\t\t};\n\t\t\t};\n\n\t\t\t// Every source is its own top-level row (Manifest / Shopify / each\n\t\t\t// integration / the action sources), in fixed rank order so adding or\n\t\t\t// updating a tool never reshuffles the picker.\n\t\t\treturn combined\n\t\t\t\t.sort((a, b) => toolSourceRank(a) - toolSourceRank(b))\n\t\t\t\t.map(buildSourceRow);\n\t\t}\n\t\tconst q = search.trim().toLowerCase();\n\t\tconst leaves: PickerRowModel[] = tools\n\t\t\t.filter((t) => (metaOf(t)?.source ?? 'other') === source)\n\t\t\t.filter((t) => !q || rowLabel(t).toLowerCase().includes(q))\n\t\t\t.map((item) => ({\n\t\t\t\tid: String(item.id),\n\t\t\t\tlabel: rowLabel(item),\n\t\t\t\tdrillsIn: false,\n\t\t\t\tauthRequired: metaOf(item)?.authRequired,\n\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t}));\n\t\t// A configurable source's add row, below any existing instances, opening\n\t\t// its drawer. Config tools (Slack / email) are a single fixed capability →\n\t\t// render like a normal tool leaf (label only, no icon — matching the tool\n\t\t// rows). Rest API instances are user-created, so its \"add\" stays a\n\t\t// brand-coloured create row.\n\t\tconst action = actionBySource.get(source);\n\t\tif (action) {\n\t\t\tconst isConfigTool = source in CONFIG_TOOL_SOURCES;\n\t\t\tleaves.push({\n\t\t\t\tid: `create:${source}`,\n\t\t\t\tlabel: action.label,\n\t\t\t\tdrillsIn: false,\n\t\t\t\tisCreate: !isConfigTool,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tonClose?.();\n\t\t\t\t\taction.onSelect();\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn leaves;\n\t}, [\n\t\tactiveCategory,\n\t\tavailableCategories,\n\t\tsource,\n\t\tsearch,\n\t\ttools,\n\t\tsubAgents,\n\t\tsources,\n\t\tonSelect,\n\t\tonClose,\n\t\tonCreateSubAgent,\n\t\ttoolActions,\n\t\tactionBySource,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\n\t]);\n\n\t// Reset highlight whenever the view (or filtered result set) changes.\n\tuseEffect(() => setActiveIndex(-1), [activeCategory, source, search, items]);\n\t// Clear the search box when leaving a source view.\n\tuseEffect(() => setSearch(''), [activeCategory, source]);\n\n\t// Keep the latest rows/index reachable from the stable key handler.\n\tconst navRef = useRef({ rows, activeIndex, header });\n\tnavRef.current = { rows, activeIndex, header };\n\n\tuseEffect(() => {\n\t\tif (!registerKeyHandler) {\n\t\t\treturn;\n\t\t}\n\t\tregisterKeyHandler((event) => {\n\t\t\tconst { rows: r, activeIndex: i, header: h } = navRef.current;\n\t\t\tswitch (event.key) {\n\t\t\t\tcase 'ArrowDown':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowUp':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + r.length - 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowRight':\n\t\t\t\tcase 'Enter':\n\t\t\t\t\t// Nothing highlighted yet → treat the first row as the target so\n\t\t\t\t\t// the editor's @-flow (type, then Enter) still works.\n\t\t\t\t\t(r[i] ?? r[0])?.onActivate();\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowLeft':\n\t\t\t\t\tif (h?.onBack) {\n\t\t\t\t\t\th.onBack();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\treturn () => registerKeyHandler(null);\n\t}, [registerKeyHandler]);\n\n\tconst variant = !activeCategory\n\t\t? 'categories'\n\t\t: rows.length && !rows[0].drillsIn\n\t\t? 'items'\n\t\t: 'sources';\n\n\t// Search lives inside a source's tool list (Manifest / Shopify) and in the\n\t// sub-agent list.\n\tconst showSearch =\n\t\t(activeCategory === 'tool' && !!source) || activeCategory === 'subagent';\n\n\treturn (\n\t\t<PickerCard className={`bik-mention-picker bik-mention-picker--${variant}`}>\n\t\t\t{header && (\n\t\t\t\t<PickerBack\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={header.onBack}\n\t\t\t\t\tdisabled={!header.onBack}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackground: COLORS.surface.subdued,\n\t\t\t\t\t\tcursor: header.onBack ? 'pointer' : 'default',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{header.onBack && (\n\t\t\t\t\t\t<SvgArrowLeft\n\t\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\t\theight={20}\n\t\t\t\t\t\t\tcolor={COLORS.content.primary}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{header.icon && renderSourceIcon(header.icon)}\n\t\t\t\t\t<TitleSmall> {header.title}</TitleSmall>\n\t\t\t\t</PickerBack>\n\t\t\t)}\n\t\t\t{showSearch && (\n\t\t\t\t<PickerSearchRow>\n\t\t\t\t\t<SearchIcon\n\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\theight={20}\n\t\t\t\t\t\tcolor={COLORS.content.placeholder}\n\t\t\t\t\t/>\n\t\t\t\t\t<PickerSearchInput\n\t\t\t\t\t\t// Focus on open so the user can type immediately (appears only\n\t\t\t\t\t\t// after they drill into a source).\n\t\t\t\t\t\t// eslint-disable-next-line jsx-a11y/no-autofocus\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tplaceholder=\"Search\"\n\t\t\t\t\t\tdata-test=\"mention-picker-search\"\n\t\t\t\t\t\tonChange={(e) => setSearch(e.target.value)}\n\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\tif (!rows.length) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (e.key === 'ArrowDown') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'ArrowUp') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + rows.length - 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'Enter') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t(rows[activeIndex] ?? rows[0])?.onActivate();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</PickerSearchRow>\n\t\t\t)}\n\t\t\t{rows.length === 0 ? (\n\t\t\t\t<PickerEmpty>\n\t\t\t\t\t{activeCategory === 'subagent' ? null : 'No tools available'}\n\t\t\t\t</PickerEmpty>\n\t\t\t) : (\n\t\t\t\trows.map((row, i) => (\n\t\t\t\t\t<PickerRow\n\t\t\t\t\t\tkey={row.id}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t$active={i === activeIndex}\n\t\t\t\t\t\tonMouseEnter={() => setActiveIndex(i)}\n\t\t\t\t\t\tonMouseLeave={() => setActiveIndex(-1)}\n\t\t\t\t\t\tonClick={row.onActivate}\n\t\t\t\t\t>\n\t\t\t\t\t\t{row.isCreate ? (\n\t\t\t\t\t\t\t<CreateRowText>{row.label}</CreateRowText>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<PickerRowMain>\n\t\t\t\t\t\t\t\t\t{renderSourceIcon(row.icon)}\n\t\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t\t{row.label}\n\t\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t\t{row.authRequired && (\n\t\t\t\t\t\t\t\t\t\t<Shield\n\t\t\t\t\t\t\t\t\t\t\tsize={16}\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"This tool requires customer verification\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</PickerRowMain>\n\t\t\t\t\t\t\t\t{row.rightLabel ? (\n\t\t\t\t\t\t\t\t\t<RightActionText>{row.rightLabel}</RightActionText>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\trow.drillsIn && <ChevronRight width={12} height={12} />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</PickerRow>\n\t\t\t\t))\n\t\t\t)}\n\t\t\t{rows.some((row) => row.authRequired) && (\n\t\t\t\t<PickerLegend>\n\t\t\t\t\t<Shield size={16} />\n\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\tThis tool requires customer verification\n\t\t\t\t\t</BodyCaption>\n\t\t\t\t</PickerLegend>\n\t\t\t)}\n\t\t</PickerCard>\n\t);\n};\n\nconst PickerCard = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tmin-width: 240px;\n\tmax-height: 301px;\n\toverflow-y: auto;\n\tbackground: ${COLORS.surface.standard};\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tbox-shadow: 0px -2px 8px 0px #0000001f;\n`;\n\n// Search box at the top of a source's tool list (Manifest / Shopify).\nconst PickerSearchRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 10px 12px;\n\tflex-shrink: 0;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n`;\n\nconst PickerSearchInput = styled.input`\n\tflex: 1;\n\tmin-width: 0;\n\tborder: none;\n\toutline: none;\n\tbackground: transparent;\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tcolor: ${COLORS.content.primary};\n\n\t&::placeholder {\n\t\tcolor: ${COLORS.content.placeholder};\n\t}\n`;\n\nconst PickerRow = styled.button<{ $active?: boolean }>`\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n\tgap: 2px;\n\twidth: 100%;\n\tpadding: 8px 10px;\n\theight: 48px;\n\t/* The card is a flex column with a max-height; without these a long list\n\t compresses its rows below 48px (why only the short first step looked right)\n\t instead of scrolling. Pin the row so the card scrolls instead. */\n\tbox-sizing: border-box;\n\tflex-shrink: 0;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: ${(p) => (p.$active ? COLORS.surface.subdued : 'transparent')};\n\tcursor: pointer;\n\ttext-align: left;\n\n\t&:hover {\n\t\tbackground: ${COLORS.surface.hovered};\n\t}\n`;\n\n// Left cluster: leading source glyph + label (chevron stays right via PickerRow).\nconst PickerRowMain = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tmin-width: 0;\n`;\n\n// Footer legend, shown when the list holds any auth-required tool.\nconst PickerLegend = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 8px 12px;\n\tborder-top: 1px solid ${COLORS.stroke.primary};\n`;\n\n// Right-aligned brand action text (e.g. \"Connect\") in place of the chevron.\nconst RightActionText = styled.span`\n\tflex-shrink: 0;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n`;\n\n// \"Create new\" — centered brand text, no icon (matches the side-panel dropdown).\nconst CreateRowText = styled.div`\n\twidth: 100%;\n\ttext-align: center;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n`;\n\nconst PickerBack = styled.button`\n\tdisplay: flex;\n\talign-items: center;\n\tpadding: 12px 16px;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: transparent;\n\tcursor: pointer;\n\tfont-family: Inter;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\theight: 48px;\n\tbox-sizing: border-box;\n\tflex-shrink: 0;\n\tgap: 4px;\n`;\n\nconst PickerEmpty = styled.div`\n\tpadding: 12px 10px;\n\tfont-family: Inter;\n\tfont-size: 13px;\n\tcolor: ${COLORS.content.secondary};\n`;\n"],"names":["metaOf","item","rowLabel","CREATE_SUBAGENT_ID","MentionPicker","items","onSelect","registerKeyHandler","onClose","onCreateSubAgent","initialSource","toolActions","integrationStatus","onConnectIntegration","category","setCategory","useState","source","setSource","activeIndex","setActiveIndex","search","setSearch","tools","useMemo","i","subAgents","sources","acc","t","s","actionBySource","a","availableCategories","CATEGORIES","c","soleCategory","activeCategory","header","toolSourceLabel","sourceIcon","rows","sq","leaves","actionOnly","combined","buildSourceRow","action","instances","isIntegrationSource","icon","only","b","toolSourceRank","q","isConfigTool","CONFIG_TOOL_SOURCES","useEffect","navRef","useRef","event","h","p","variant","showSearch","jsxs","PickerCard","PickerBack","COLORS","jsx","SvgArrowLeft","renderSourceIcon","TitleSmall","PickerSearchRow","SearchIcon","PickerSearchInput","PickerEmpty","row","PickerRow","CreateRowText","Fragment","PickerRowMain","BodySecondary","Shield","RightActionText","ChevronRight","PickerLegend","BodyCaption","styled"],"mappings":"upBA2BMA,EAAUC,GACfA,EAAK,KAEAC,EAAYD,GACjBD,EAAOC,CAAI,GAAG,YAAcA,EAAK,MAuB5BE,GAAqB,0BAmCdC,GAA8C,CAAC,CAC3D,MAAAC,EACA,SAAAC,EACA,mBAAAC,EACA,QAAAC,EACA,iBAAAC,EACA,cAAAC,EACA,YAAAC,EACA,kBAAAC,EACA,qBAAAC,CACD,IAAM,CACL,KAAM,CAACC,EAAUC,CAAW,EAAIC,EAAAA,SAA0B,IAAI,EACxD,CAACC,EAAQC,CAAS,EAAIF,EAAAA,SAAwBN,GAAiB,IAAI,EAGnE,CAACS,EAAaC,CAAc,EAAIJ,EAAAA,SAAS,EAAE,EAG3C,CAACK,EAAQC,CAAS,EAAIN,EAAAA,SAAS,EAAE,EAEjCO,EAAQC,EAAAA,QACb,IAAMnB,EAAM,OAAQoB,GAAMzB,EAAOyB,CAAC,GAAG,OAAS,MAAM,EACpD,CAACpB,CAAK,CAAA,EAEDqB,EAAYF,EAAAA,QACjB,IAAMnB,EAAM,OAAQoB,GAAMzB,EAAOyB,CAAC,GAAG,OAAS,UAAU,EACxD,CAACpB,CAAK,CAAA,EAEDsB,EAAUH,EAAAA,QAAQ,IAAM,CAC7B,MAAMI,EAAgB,CAAA,EACtBL,OAAAA,EAAM,QAASM,GAAM,CACpB,MAAMC,EAAI9B,EAAO6B,CAAC,GAAG,QAAU,QAC1BD,EAAI,SAASE,CAAC,GAClBF,EAAI,KAAKE,CAAC,CAEZ,CAAC,EACMF,CACR,EAAG,CAACL,CAAK,CAAC,EAIJQ,EAAiBP,EAAAA,QACtB,IACC,IAAI,KACFb,GAAe,CAAA,GAAI,IAAKqB,GAAM,CAACA,EAAE,OAAQA,CAAC,CAAC,CAAA,EAE9C,CAACrB,CAAW,CAAA,EAOPsB,EAAsBT,EAAAA,QAC3B,IACCU,EAAAA,WAAW,OAAQC,GAClBA,EAAE,MAAQ,OACPZ,EAAM,OAAS,IAAMZ,GAAa,QAAU,GAAK,EACjDe,EAAU,OAAS,GAAK,CAAC,CAACjB,CAAA,EAE/B,CAACc,EAAM,OAAQG,EAAU,OAAQjB,EAAkBE,GAAa,MAAM,CAAA,EAEjEyB,EACLH,EAAoB,SAAW,EAAIA,EAAoB,CAAC,EAAE,IAAM,KAC3DI,EAAiBvB,GAAYsB,EAM7BE,EAIMD,EAETA,IAAmB,WAEnB,CACA,MAAO,YACP,OAAQD,EAAe,OAAY,IAAMrB,EAAY,IAAI,CAAA,EAEzDE,EACA,CACA,MAAOsB,EAAAA,gBAAgBtB,CAAM,EAI7B,OAAQP,EAAgB,OAAY,IAAMQ,EAAU,IAAI,EACxD,KAAMsB,EAAAA,WAAWvB,CAAM,CAAA,EAIvB,CACA,MAAO,QACP,OAAQmB,EAAe,OAAY,IAAMrB,EAAY,IAAI,CAAA,EApBzD,KAwBG0B,EAAyBjB,EAAAA,QAAQ,IAAM,CAC5C,GAAI,CAACa,EACJ,OAAOJ,EAAoB,IAAKE,IAAO,CACtC,GAAIA,EAAE,IACN,MAAOA,EAAE,MACT,SAAU,GACV,WAAY,IAAM,CACjBpB,EAAYoB,EAAE,GAAG,EACjBjB,EAAU,IAAI,CACf,CAAA,EACC,EAEH,GAAImB,IAAmB,WAAY,CAClC,MAAMK,EAAKrB,EAAO,KAAA,EAAO,YAAA,EACnBsB,EAA2BjB,EAC/B,OAAQzB,GAAS,CAACyC,GAAMxC,EAASD,CAAI,EAAE,YAAA,EAAc,SAASyC,CAAE,CAAC,EACjE,IAAKzC,IAAU,CACf,GAAI,OAAOA,EAAK,EAAE,EAClB,MAAOC,EAASD,CAAI,EACpB,SAAU,GACV,WAAY,IAAMK,EAASL,CAAI,CAAA,EAC9B,EAEH,OAAIQ,GACHkC,EAAO,KAAK,CACX,GAAIxC,GACJ,MAAO,aACP,SAAU,GACV,SAAU,GACV,WAAY,IAAM,CACjBK,IAAA,EACAC,EAAA,CACD,CAAA,CACA,EAEKkC,CACR,CACA,GAAI,CAAC1B,EAAQ,CAIZ,MAAM2B,GAAcjC,GAAe,CAAA,GACjC,IAAKqB,GAAMA,EAAE,MAAM,EACnB,OAAQF,GAAM,CAACH,EAAQ,SAASG,CAAC,CAAC,EAC9Be,EAAW,CAAC,GAAGlB,EAAS,GAAGiB,CAAU,EAIrCE,EAAkBhB,GAA8B,CACrD,MAAMiB,EAAShB,EAAe,IAAID,CAAC,EASnC,IAHCiB,IAAW,OACRA,EAAO,UACPnC,IAAoBkB,CAAe,KACrB,GACjB,MAAO,CACN,GAAIA,EACJ,MAAOS,EAAAA,gBAAgBT,CAAC,EACxB,SAAU,GACV,KAAMU,EAAAA,WAAWV,CAAC,GAAKiB,GAAQ,KAC/B,WAAY,UACZ,WAAY,IAAM,CACjBvC,IAAA,EACIuC,GAAQ,UACXA,EAAO,UAAA,EAEPlC,IAAuBiB,CAAe,CAExC,CAAA,EAWF,MAAMkB,EAAYzB,EAAM,OACtBM,IAAO7B,EAAO6B,CAAC,GAAG,QAAU,WAAaC,CAAA,EAK3C,GAFCkB,EAAU,QAAUD,EAAS,EAAI,KAAO,GACxC,EAAEA,IAAW,QAAaE,EAAAA,oBAAoBnB,CAAC,GACxB,CACvB,MAAMoB,EAAOV,EAAAA,WAAWV,CAAC,GAAKiB,GAAQ,KACtC,GAAIA,EACH,MAAO,CACN,GAAIjB,EACJ,MAAOiB,EAAO,MACd,SAAU,GACV,KAAAG,EACA,WAAY,IAAM,CACjB1C,IAAA,EACAuC,EAAO,SAAA,CACR,CAAA,EAGF,MAAMI,EAAOH,EAAU,CAAC,EACxB,MAAO,CACN,GAAI,OAAOG,EAAK,EAAE,EAClB,MAAOjD,EAASiD,CAAI,EACpB,SAAU,GACV,KAAAD,EACA,aAAclD,EAAOmD,CAAI,GAAG,aAC5B,WAAY,IAAM7C,EAAS6C,CAAI,CAAA,CAEjC,CACA,MAAO,CACN,GAAIrB,EACJ,MAAOS,EAAAA,gBAAgBT,CAAC,EACxB,SAAU,GACV,KAAMU,EAAAA,WAAWV,CAAC,GAAKiB,GAAQ,KAC/B,WAAY,IAAM7B,EAAUY,CAAC,CAAA,CAE/B,EAKA,OAAOe,EACL,KAAK,CAACb,EAAGoB,IAAMC,EAAAA,eAAerB,CAAC,EAAIqB,EAAAA,eAAeD,CAAC,CAAC,EACpD,IAAIN,CAAc,CACrB,CACA,MAAMQ,EAAIjC,EAAO,KAAA,EAAO,YAAA,EAClBsB,EAA2BpB,EAC/B,OAAQ,IAAOvB,EAAO,CAAC,GAAG,QAAU,WAAaiB,CAAM,EACvD,OAAQ,GAAM,CAACqC,GAAKpD,EAAS,CAAC,EAAE,cAAc,SAASoD,CAAC,CAAC,EACzD,IAAKrD,IAAU,CACf,GAAI,OAAOA,EAAK,EAAE,EAClB,MAAOC,EAASD,CAAI,EACpB,SAAU,GACV,aAAcD,EAAOC,CAAI,GAAG,aAC5B,WAAY,IAAMK,EAASL,CAAI,CAAA,EAC9B,EAMG8C,EAAShB,EAAe,IAAId,CAAM,EACxC,GAAI8B,EAAQ,CACX,MAAMQ,EAAetC,KAAUuC,EAAAA,oBAC/Bb,EAAO,KAAK,CACX,GAAI,UAAU1B,CAAM,GACpB,MAAO8B,EAAO,MACd,SAAU,GACV,SAAU,CAACQ,EACX,WAAY,IAAM,CACjB/C,IAAA,EACAuC,EAAO,SAAA,CACR,CAAA,CACA,CACF,CACA,OAAOJ,CACR,EAAG,CACFN,EACAJ,EACAhB,EACAI,EACAE,EACAG,EACAC,EACArB,EACAE,EACAC,EACAE,EACAoB,EACAnB,EACAC,CAAA,CACA,EAGD4C,YAAU,IAAMrC,EAAe,EAAE,EAAG,CAACiB,EAAgBpB,EAAQI,EAAQhB,CAAK,CAAC,EAE3EoD,EAAAA,UAAU,IAAMnC,EAAU,EAAE,EAAG,CAACe,EAAgBpB,CAAM,CAAC,EAGvD,MAAMyC,EAASC,EAAAA,OAAO,CAAE,KAAAlB,EAAM,YAAAtB,EAAa,OAAAmB,EAAQ,EACnDoB,EAAO,QAAU,CAAE,KAAAjB,EAAM,YAAAtB,EAAa,OAAAmB,CAAA,EAEtCmB,EAAAA,UAAU,IAAM,CACf,GAAKlD,EAGL,OAAAA,EAAoBqD,GAAU,CAC7B,KAAM,CAAE,KAAM,EAAG,YAAanC,EAAG,OAAQoC,GAAMH,EAAO,QACtD,OAAQE,EAAM,IAAA,CACb,IAAK,YACJ,OAAI,EAAE,QAAQxC,EAAgB0C,IAAOA,EAAI,GAAK,EAAE,MAAM,EAC/C,GACR,IAAK,UACJ,OAAI,EAAE,QAAQ1C,EAAgB0C,IAAOA,EAAI,EAAE,OAAS,GAAK,EAAE,MAAM,EAC1D,GACR,IAAK,aACL,IAAK,QAGJ,OAAC,EAAErC,CAAC,GAAK,EAAE,CAAC,IAAI,WAAA,EACT,GACR,IAAK,YACJ,OAAIoC,GAAG,QACNA,EAAE,OAAA,EACK,IAED,GACR,QACC,MAAO,EAAA,CAEV,CAAC,EACM,IAAMtD,EAAmB,IAAI,CACrC,EAAG,CAACA,CAAkB,CAAC,EAEvB,MAAMwD,EAAW1B,EAEdI,EAAK,QAAU,CAACA,EAAK,CAAC,EAAE,SACxB,QACA,UAHA,aAOGuB,EACJ3B,IAAmB,QAAU,CAAC,CAACpB,GAAWoB,IAAmB,WAE/D,OACC4B,EAAAA,KAACC,GAAA,CAAW,UAAW,0CAA0CH,CAAO,GACtE,SAAA,CAAAzB,GACA2B,EAAAA,KAACE,GAAA,CACA,KAAK,SACL,QAAS7B,EAAO,OAChB,SAAU,CAACA,EAAO,OAClB,MAAO,CACN,WAAY8B,EAAAA,OAAO,QAAQ,QAC3B,OAAQ9B,EAAO,OAAS,UAAY,SAAA,EAGpC,SAAA,CAAAA,EAAO,QACP+B,EAAAA,IAACC,EAAAA,QAAA,CACA,MAAO,GACP,OAAQ,GACR,MAAOF,EAAAA,OAAO,QAAQ,OAAA,CAAA,EAGvB9B,EAAO,MAAQiC,mBAAiBjC,EAAO,IAAI,SAC3CkC,EAAAA,WAAA,CAAW,SAAA,CAAA,IAAElC,EAAO,KAAA,CAAA,CAAM,CAAA,CAAA,CAAA,EAG5B0B,UACCS,GAAA,CACA,SAAA,CAAAJ,EAAAA,IAACK,EAAAA,QAAA,CACA,MAAO,GACP,OAAQ,GACR,MAAON,EAAAA,OAAO,QAAQ,WAAA,CAAA,EAEvBC,EAAAA,IAACM,GAAA,CAIA,UAAS,GACT,MAAOtD,EACP,YAAY,SACZ,YAAU,wBACV,SAAW,GAAMC,EAAU,EAAE,OAAO,KAAK,EACzC,UAAY,GAAM,CACZmB,EAAK,SAGN,EAAE,MAAQ,aACb,EAAE,eAAA,EACFrB,EAAgB0C,IAAOA,EAAI,GAAKrB,EAAK,MAAM,GACjC,EAAE,MAAQ,WACpB,EAAE,eAAA,EACFrB,EAAgB0C,IAAOA,EAAIrB,EAAK,OAAS,GAAKA,EAAK,MAAM,GAC/C,EAAE,MAAQ,UACpB,EAAE,eAAA,GACDA,EAAKtB,CAAW,GAAKsB,EAAK,CAAC,IAAI,WAAA,GAElC,CAAA,CAAA,CACD,EACD,EAEAA,EAAK,SAAW,EAChB4B,EAAAA,IAACO,IACC,SAAAvC,IAAmB,WAAa,KAAO,oBAAA,CACzC,EAEAI,EAAK,IAAI,CAACoC,EAAKpD,IACd4C,EAAAA,IAACS,GAAA,CAEA,KAAK,SACL,QAASrD,IAAMN,EACf,aAAc,IAAMC,EAAeK,CAAC,EACpC,aAAc,IAAML,EAAe,EAAE,EACrC,QAASyD,EAAI,WAEZ,WAAI,SACJR,EAAAA,IAACU,IAAe,SAAAF,EAAI,KAAA,CAAM,EAE1BZ,EAAAA,KAAAe,EAAAA,SAAA,CACC,SAAA,CAAAf,OAACgB,GAAA,CACC,SAAA,CAAAV,EAAAA,iBAAiBM,EAAI,IAAI,QACzBK,EAAAA,cAAA,CAAc,MAAOd,EAAAA,OAAO,QAAQ,QACnC,WAAI,MACN,EACCS,EAAI,cACJR,EAAAA,IAACc,EAAAA,QAAA,CACA,KAAM,GACN,aAAW,0CAAA,CAAA,CACZ,EAEF,EACCN,EAAI,WACJR,MAACe,GAAA,CAAiB,WAAI,UAAA,CAAW,EAEjCP,EAAI,UAAYR,EAAAA,IAACgB,EAAAA,QAAA,CAAa,MAAO,GAAI,OAAQ,EAAA,CAAI,CAAA,CAAA,CAEvD,CAAA,EA5BIR,EAAI,EAAA,CA+BV,EAEDpC,EAAK,KAAMoC,GAAQA,EAAI,YAAY,UAClCS,GAAA,CACA,SAAA,CAAAjB,EAAAA,IAACc,EAAAA,QAAA,CAAO,KAAM,EAAA,CAAI,QACjBI,EAAAA,YAAA,CAAY,MAAOnB,EAAAA,OAAO,QAAQ,UAAW,SAAA,0CAAA,CAE9C,CAAA,CAAA,CACD,CAAA,EAEF,CAEF,EAEMF,GAAasB,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAMXpB,EAAAA,OAAO,QAAQ,QAAQ;AAAA,qBACjBA,EAAAA,OAAO,OAAO,OAAO;AAAA;AAAA;AAAA,EAMpCK,GAAkBe,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAMHpB,EAAAA,OAAO,OAAO,OAAO;AAAA,EAG3CO,GAAoBa,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAQvBpB,EAAAA,OAAO,QAAQ,OAAO;AAAA;AAAA;AAAA,WAGrBA,EAAAA,OAAO,QAAQ,WAAW;AAAA;AAAA,EAI/BU,GAAYU,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAcGpB,EAAAA,OAAO,OAAO,OAAO;AAAA,eACjCN,GAAOA,EAAE,QAAUM,EAAAA,OAAO,QAAQ,QAAU,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA,gBAK1DA,EAAAA,OAAO,QAAQ,OAAO;AAAA;AAAA,EAKhCa,GAAgBO,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAQvBF,GAAeE,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,yBAKHpB,EAAAA,OAAO,OAAO,OAAO;AAAA,EAIxCgB,GAAkBI,EAAAA,QAAO;AAAA;AAAA,UAErBpB,EAAAA,OAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAQxBW,GAAgBS,EAAAA,QAAO;AAAA;AAAA;AAAA,UAGnBpB,EAAAA,OAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA,EAMxBD,GAAaqB,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA;AAAA,4BAKEpB,EAAAA,OAAO,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAY3CQ,GAAcY,EAAAA,QAAO;AAAA;AAAA;AAAA;AAAA,UAIjBpB,EAAAA,OAAO,QAAQ,SAAS;AAAA"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=[{key:"tool",label:"Tools"},{key:"subagent",label:"Sub-agent"}];var a=(e=>(e.Manifest="manifest",e.Shopify="shopify",e.Bigcommerce="bigcommerce",e.Shipstation="shipstation",e.Skio="skio",e.Gorgias="gorgias",e.Integration="integration",e.RestApi="rest_api",e.EmailHandover="email_handover",e.Slack="slack",e))(a||{});const n={manifest:"Manifest",shopify:"Shopify",bigcommerce:"BigCommerce",shipstation:"ShipStation",skio:"Skio",gorgias:"Gorgias",integration:"Integration",rest_api:"Rest API",email_handover:"Email",slack:"Slack"},o={rest_api:"REST API",email_handover:"Send email",slack:"Send Slack message"},O=["rest_api","email_handover","slack"],i={manifest:0,shopify:1,bigcommerce:2,shipstation:3,skio:4,gorgias:5,slack:6,email_handover:7,rest_api:8},s=["bigcommerce","shipstation","skio","gorgias","slack"],_=i.bigcommerce,S=new Set(s),c=e=>S.has(e),r=Object.keys(i).length,g=e=>i[e]??r,m={email_handover:"send_email",slack:"send_slack_message"};exports.CATEGORIES=t;exports.CONFIG_TOOL_SOURCES=m;exports.INTEGRATIONS_RANK=_;exports.INTEGRATION_SOURCES=s;exports.TOOL_ACTION_LABELS=o;exports.TOOL_ACTION_SOURCES=O;exports.TOOL_SOURCE_LABELS=n;exports.TOOL_SOURCE_RANK=i;exports.ToolSource=a;exports.isIntegrationSource=c;exports.toolSourceRank=g;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=[{key:"tool",label:"Tools"},{key:"subagent",label:"Sub-agent"}];var a=(i=>(i.Manifest="manifest",i.Shopify="shopify",i.Bigcommerce="bigcommerce",i.Shipstation="shipstation",i.Skio="skio",i.Gorgias="gorgias",i.Integration="integration",i.RestApi="rest_api",i.EmailHandover="email_handover",i.Slack="slack",i))(a||{});const n={manifest:"Manifest",shopify:"Shopify",bigcommerce:"BigCommerce",shipstation:"ShipStation",skio:"Skio",gorgias:"Gorgias",integration:"Integration",rest_api:"Rest API",email_handover:"Email",slack:"Slack"},o={rest_api:"REST API",email_handover:"Send email",slack:"Send Slack message"},O=["rest_api","email_handover","slack"],e={manifest:0,shopify:1,bigcommerce:2,shipstation:3,skio:4,gorgias:5,slack:6,email_handover:7,rest_api:8},s=["shopify","bigcommerce","shipstation","skio","gorgias","integration"],_=new Set(s),S=i=>_.has(i),r=Object.keys(e).length,c=i=>e[i]??r,g={email_handover:"send_email",slack:"send_slack_message"};exports.CATEGORIES=t;exports.CONFIG_TOOL_SOURCES=g;exports.INTEGRATION_SOURCES=s;exports.TOOL_ACTION_LABELS=o;exports.TOOL_ACTION_SOURCES=O;exports.TOOL_SOURCE_LABELS=n;exports.TOOL_SOURCE_RANK=e;exports.ToolSource=a;exports.isIntegrationSource=S;exports.toolSourceRank=c;
2
2
  //# sourceMappingURL=tools.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sources":["../../../../../src/components/agent-builder/constants/tools.ts"],"sourcesContent":["import type { ToolSource as ModelToolSource } from '@bikdotai/bik-models/ai-agents/models/agent-tool';\nimport type { FunctionComponent, SVGAttributes } from 'react';\n\n/**\n * Static tool-related constants for the builder's Step 3 (tools & sub-agents):\n * the reference-picker category tabs and the per-source display labels. Kept here\n * (rather than inline in the picker / serialization utils) so the labels a user\n * sees are all in one obvious place.\n */\n\n/** A reference-picker category tab. */\nexport type Category = 'tool' | 'subagent';\n\n/** Category tabs shown at the root of the `@` reference picker. */\nexport const CATEGORIES: { key: Category; label: string }[] = [\n\t{ key: 'tool', label: 'Tools' },\n\t{ key: 'subagent', label: 'Sub-agent' },\n];\n\n/**\n * Every tool \"source\" the builder renders an icon / label / picker entry for.\n * Enum VALUES are the backend's canonical read-only `source` wire strings\n * (`app/agents/config/schema.py` → `ToolSource`, derived from `tool_key`): the\n * configurable tools are `email_handover` / `rest_api` / `slack`, every native\n * tool is `manifest`. `shopify` / `integration` are legacy bik-models sources\n * kept for back-compat (the backend now collapses natives to `manifest`).\n * Dynamic/unknown sources are looked up leniently — see `toolSourceLabel` and\n * `sourceIcon`.\n *\n * This is the RUNTIME mirror of the canonical `@bikdotai/bik-models` `ToolSource`\n * union (the shape the backend persists as `AgentToolDoc.source`). We keep an\n * enum — not a re-export of the type — because the members are needed at runtime\n * for labels, ranks, icons and `===` comparisons; a type-only union can't do\n * that. The two are kept in lock-step by {@link ToolSourceMatchesBikModels}\n * below, which fails to compile if they ever drift.\n */\nexport enum ToolSource {\n\tManifest = 'manifest',\n\tShopify = 'shopify',\n\tBigcommerce = 'bigcommerce',\n\tShipstation = 'shipstation',\n\tSkio = 'skio',\n\tGorgias = 'gorgias',\n\tIntegration = 'integration',\n\tRestApi = 'rest_api',\n\tEmailHandover = 'email_handover',\n\tSlack = 'slack',\n}\n\n/**\n * Compile-time guard that {@link ToolSource} stays a faithful mirror of the\n * canonical `@bikdotai/bik-models` `ToolSource` union. If a source is added to\n * (or removed from) either side without the other, `AssertTrue` receives `false`\n * and this type stops compiling — so the runtime enum can never silently diverge\n * from what the backend persists as `AgentToolDoc.source`. The tuple wrappers\n * (`[…]`) stop the conditionals from distributing over the unions, so it checks\n * set-equality in both directions.\n *\n * Type-only (erased at build): a drift shows up as a compile error on\n * `ToolSourceMatchesBikModels` telling you to reconcile this enum with\n * `@bikdotai/bik-models` (bump the dep and/or the enum).\n */\ntype AssertTrue<T extends true> = T;\ntype ToolSourceMatchesBikModels = AssertTrue<\n\t[`${ToolSource}`] extends [ModelToolSource]\n\t\t? [ModelToolSource] extends [`${ToolSource}`]\n\t\t\t? true\n\t\t\t: false\n\t\t: false\n>;\n\n/**\n * Display labels for the known tool sources — the CATEGORY/integration name, used\n * for the picker's source headers (drill-in groups), the empty-state source\n * buttons and the mention-chip prefix. A source is a category (\"Slack\") you drill\n * into; the specific addable action inside it (\"Send Slack message\") is\n * `TOOL_ACTION_LABELS`. Unknown sources fall back to the raw key (see\n * `toolSourceLabel`).\n */\nexport const TOOL_SOURCE_LABELS: Record<ToolSource, string> = {\n\t[ToolSource.Manifest]: 'Manifest',\n\t[ToolSource.Shopify]: 'Shopify',\n\t[ToolSource.Bigcommerce]: 'BigCommerce',\n\t[ToolSource.Shipstation]: 'ShipStation',\n\t[ToolSource.Skio]: 'Skio',\n\t[ToolSource.Gorgias]: 'Gorgias',\n\t[ToolSource.Integration]: 'Integration',\n\t[ToolSource.RestApi]: 'Rest API',\n\t[ToolSource.EmailHandover]: 'Email',\n\t[ToolSource.Slack]: 'Slack',\n};\n\n/**\n * The addable action inside a configurable/rest source — shown as the \"add\" row\n * in the `@` picker (below any existing instances) and the empty-state button.\n * Distinct from `TOOL_SOURCE_LABELS`, which names the category the action lives in\n * (e.g. category \"Slack\" → action \"Send Slack message\").\n */\nexport const TOOL_ACTION_LABELS: Partial<Record<ToolSource, string>> = {\n\t[ToolSource.RestApi]: 'REST API',\n\t[ToolSource.EmailHandover]: 'Send email',\n\t[ToolSource.Slack]: 'Send Slack message',\n};\n\n/** A tool source's brand-glyph component. */\nexport type IconComp = FunctionComponent<SVGAttributes<SVGElement>>;\n\n/** Brand glyph for a tool source, with its own size so each keeps its aspect ratio. */\nexport interface SourceIcon {\n\tIcon: IconComp;\n\tw: number;\n\th: number;\n}\n\n/**\n * A built-in \"tool\" that opens a config drawer (Rest API / email handover /\n * Slack) rather than inserting a mention. Surfaced as an empty-state source\n * button in the Tools section and as a row in the `@`-picker Tools view; picking\n * it opens the drawer and never writes into the instructions text.\n */\nexport interface ToolAction {\n\tsource: ToolSource;\n\tlabel: string;\n\ticon?: SourceIcon;\n\t/** Open this tool's config drawer. */\n\tonSelect: () => void;\n\t/**\n\t * Integration connection state for this source. `undefined` = no connection\n\t * gating (default). `false` = the store hasn't connected this integration →\n\t * the `@` picker shows a \"Connect\" row that calls {@link onConnect} instead of\n\t * drilling in / offering \"Create new\". `true` = connected (renders normally).\n\t * Set by the consumer via `config.integrationStatus` (today: Slack only).\n\t */\n\tconnected?: boolean;\n\t/** Open the parent's connect flow for this source (used when `connected === false`). */\n\tonConnect?: () => void;\n}\n\n/** Sources of the built-in drawer tools, in display order. */\nexport const TOOL_ACTION_SOURCES: ToolSource[] = [\n\tToolSource.RestApi,\n\tToolSource.EmailHandover,\n\tToolSource.Slack,\n];\n\n/**\n * Fixed display rank for the `@`-picker's tool-source groups (lower = higher). The\n * picker sorts its source rows by this so adding/updating a tool never reshuffles\n * them. Manifest (the native tools) leads; any source not listed here\n * (dynamic/unknown, e.g. Integration) sorts AFTER Slack, keeping its discovery\n * order among the rest (Array.sort is stable).\n */\nexport const TOOL_SOURCE_RANK: Partial<Record<ToolSource, number>> = {\n\t[ToolSource.Manifest]: 0,\n\t[ToolSource.Shopify]: 1,\n\t// Integration sources (2–6) are grouped under one \"Integrations\" row in the\n\t// picker; their rank orders them WITHIN that group.\n\t[ToolSource.Bigcommerce]: 2,\n\t[ToolSource.Shipstation]: 3,\n\t[ToolSource.Skio]: 4,\n\t[ToolSource.Gorgias]: 5,\n\t[ToolSource.Slack]: 6,\n\t// Send Email then REST API sit after the Integrations group at the top level.\n\t[ToolSource.EmailHandover]: 7,\n\t[ToolSource.RestApi]: 8,\n};\n\n/**\n * Sources consolidated under the picker's single \"Integrations\" drill-in row\n * (BigCommerce / ShipStation / Skio / Gorgias / Slack). Manifest, Shopify, Send\n * Email and REST API stay as their own top-level rows.\n */\nexport const INTEGRATION_SOURCES: ToolSource[] = [\n\tToolSource.Bigcommerce,\n\tToolSource.Shipstation,\n\tToolSource.Skio,\n\tToolSource.Gorgias,\n\tToolSource.Slack,\n];\n\n/** Rank of the synthetic \"Integrations\" top-level row (where BigCommerce sat). */\nexport const INTEGRATIONS_RANK = TOOL_SOURCE_RANK[ToolSource.Bigcommerce] ?? 2;\n\nconst INTEGRATION_SOURCE_SET = new Set<string>(INTEGRATION_SOURCES);\n\n/** True when a source belongs under the picker's \"Integrations\" group. */\nexport const isIntegrationSource = (source: string): boolean =>\n\tINTEGRATION_SOURCE_SET.has(source);\n\nconst UNRANKED_SOURCE_RANK = Object.keys(TOOL_SOURCE_RANK).length;\n\n/** Sort rank for a source string; unknown sources rank after all known ones. */\nexport const toolSourceRank = (source: string): number =>\n\tTOOL_SOURCE_RANK[source as ToolSource] ?? UNRANKED_SOURCE_RANK;\n\n/**\n * `tool_key` of a configurable shared-drawer tool (email / Slack). Lives here (not\n * in AgentBuilder.model) so this leaf constants file has no back-edge to the model\n * — the dependency stays one-way (model → constants), avoiding a circular import.\n */\nexport type ConfigToolKey = 'send_email' | 'send_slack_message';\n\n/**\n * Drawer sources rendered by the shared dynamic panel (`ConfigToolPanel`), each\n * mapped to its backend `tool_key`. Rest API is absent — it has a bespoke panel.\n */\nexport const CONFIG_TOOL_SOURCES: Partial<Record<ToolSource, ConfigToolKey>> = {\n\t[ToolSource.EmailHandover]: 'send_email',\n\t[ToolSource.Slack]: 'send_slack_message',\n};\n"],"names":["CATEGORIES","ToolSource","TOOL_SOURCE_LABELS","TOOL_ACTION_LABELS","TOOL_ACTION_SOURCES","TOOL_SOURCE_RANK","INTEGRATION_SOURCES","INTEGRATIONS_RANK","INTEGRATION_SOURCE_SET","isIntegrationSource","source","UNRANKED_SOURCE_RANK","toolSourceRank","CONFIG_TOOL_SOURCES"],"mappings":"gFAcO,MAAMA,EAAiD,CAC7D,CAAE,IAAK,OAAQ,MAAO,OAAA,EACtB,CAAE,IAAK,WAAY,MAAO,WAAA,CAC3B,EAmBO,IAAKC,GAAAA,IACXA,EAAA,SAAW,WACXA,EAAA,QAAU,UACVA,EAAA,YAAc,cACdA,EAAA,YAAc,cACdA,EAAA,KAAO,OACPA,EAAA,QAAU,UACVA,EAAA,YAAc,cACdA,EAAA,QAAU,WACVA,EAAA,cAAgB,iBAChBA,EAAA,MAAQ,QAVGA,IAAAA,GAAA,CAAA,CAAA,EA2CL,MAAMC,EAAiD,CAC5D,SAAsB,WACtB,QAAqB,UACrB,YAAyB,cACzB,YAAyB,cACzB,KAAkB,OAClB,QAAqB,UACrB,YAAyB,cACzB,SAAqB,WACrB,eAA2B,QAC3B,MAAmB,OACrB,EAQaC,EAA0D,CACrE,SAAqB,WACrB,eAA2B,aAC3B,MAAmB,oBACrB,EAqCaC,EAAoC,CAChD,WACA,iBACA,OACD,EASaC,EAAwD,CACnE,SAAsB,EACtB,QAAqB,EAGrB,YAAyB,EACzB,YAAyB,EACzB,KAAkB,EAClB,QAAqB,EACrB,MAAmB,EAEnB,eAA2B,EAC3B,SAAqB,CACvB,EAOaC,EAAoC,CAChD,cACA,cACA,OACA,UACA,OACD,EAGaC,EAAoBF,EAAiB,YAE5CG,EAAyB,IAAI,IAAYF,CAAmB,EAGrDG,EAAuBC,GACnCF,EAAuB,IAAIE,CAAM,EAE5BC,EAAuB,OAAO,KAAKN,CAAgB,EAAE,OAG9CO,EAAkBF,GAC9BL,EAAiBK,CAAoB,GAAKC,EAa9BE,EAAkE,CAC7E,eAA2B,aAC3B,MAAmB,oBACrB"}
1
+ {"version":3,"file":"tools.js","sources":["../../../../../src/components/agent-builder/constants/tools.ts"],"sourcesContent":["import type { ToolSource as ModelToolSource } from '@bikdotai/bik-models/ai-agents/models/agent-tool';\nimport type { FunctionComponent, SVGAttributes } from 'react';\n\n/**\n * Static tool-related constants for the builder's Step 3 (tools & sub-agents):\n * the reference-picker category tabs and the per-source display labels. Kept here\n * (rather than inline in the picker / serialization utils) so the labels a user\n * sees are all in one obvious place.\n */\n\n/** A reference-picker category tab. */\nexport type Category = 'tool' | 'subagent';\n\n/** Category tabs shown at the root of the `@` reference picker. */\nexport const CATEGORIES: { key: Category; label: string }[] = [\n\t{ key: 'tool', label: 'Tools' },\n\t{ key: 'subagent', label: 'Sub-agent' },\n];\n\n/**\n * Every tool \"source\" the builder renders an icon / label / picker entry for.\n * Enum VALUES are the backend's canonical read-only `source` wire strings\n * (`app/agents/config/schema.py` → `ToolSource`, derived from `tool_key`): the\n * configurable tools are `email_handover` / `rest_api` / `slack`, every native\n * tool is `manifest`. `shopify` / `integration` are legacy bik-models sources\n * kept for back-compat (the backend now collapses natives to `manifest`).\n * Dynamic/unknown sources are looked up leniently — see `toolSourceLabel` and\n * `sourceIcon`.\n *\n * This is the RUNTIME mirror of the canonical `@bikdotai/bik-models` `ToolSource`\n * union (the shape the backend persists as `AgentToolDoc.source`). We keep an\n * enum — not a re-export of the type — because the members are needed at runtime\n * for labels, ranks, icons and `===` comparisons; a type-only union can't do\n * that. The two are kept in lock-step by {@link ToolSourceMatchesBikModels}\n * below, which fails to compile if they ever drift.\n */\nexport enum ToolSource {\n\tManifest = 'manifest',\n\tShopify = 'shopify',\n\tBigcommerce = 'bigcommerce',\n\tShipstation = 'shipstation',\n\tSkio = 'skio',\n\tGorgias = 'gorgias',\n\tIntegration = 'integration',\n\tRestApi = 'rest_api',\n\tEmailHandover = 'email_handover',\n\tSlack = 'slack',\n}\n\n/**\n * Compile-time guard that {@link ToolSource} stays a faithful mirror of the\n * canonical `@bikdotai/bik-models` `ToolSource` union. If a source is added to\n * (or removed from) either side without the other, `AssertTrue` receives `false`\n * and this type stops compiling — so the runtime enum can never silently diverge\n * from what the backend persists as `AgentToolDoc.source`. The tuple wrappers\n * (`[…]`) stop the conditionals from distributing over the unions, so it checks\n * set-equality in both directions.\n *\n * Type-only (erased at build): a drift shows up as a compile error on\n * `ToolSourceMatchesBikModels` telling you to reconcile this enum with\n * `@bikdotai/bik-models` (bump the dep and/or the enum).\n */\ntype AssertTrue<T extends true> = T;\ntype ToolSourceMatchesBikModels = AssertTrue<\n\t[`${ToolSource}`] extends [ModelToolSource]\n\t\t? [ModelToolSource] extends [`${ToolSource}`]\n\t\t\t? true\n\t\t\t: false\n\t\t: false\n>;\n\n/**\n * Display labels for the known tool sources — the CATEGORY/integration name, used\n * for the picker's source headers (drill-in groups), the empty-state source\n * buttons and the mention-chip prefix. A source is a category (\"Slack\") you drill\n * into; the specific addable action inside it (\"Send Slack message\") is\n * `TOOL_ACTION_LABELS`. Unknown sources fall back to the raw key (see\n * `toolSourceLabel`).\n */\nexport const TOOL_SOURCE_LABELS: Record<ToolSource, string> = {\n\t[ToolSource.Manifest]: 'Manifest',\n\t[ToolSource.Shopify]: 'Shopify',\n\t[ToolSource.Bigcommerce]: 'BigCommerce',\n\t[ToolSource.Shipstation]: 'ShipStation',\n\t[ToolSource.Skio]: 'Skio',\n\t[ToolSource.Gorgias]: 'Gorgias',\n\t[ToolSource.Integration]: 'Integration',\n\t[ToolSource.RestApi]: 'Rest API',\n\t[ToolSource.EmailHandover]: 'Email',\n\t[ToolSource.Slack]: 'Slack',\n};\n\n/**\n * The addable action inside a configurable/rest source — shown as the \"add\" row\n * in the `@` picker (below any existing instances) and the empty-state button.\n * Distinct from `TOOL_SOURCE_LABELS`, which names the category the action lives in\n * (e.g. category \"Slack\" → action \"Send Slack message\").\n */\nexport const TOOL_ACTION_LABELS: Partial<Record<ToolSource, string>> = {\n\t[ToolSource.RestApi]: 'REST API',\n\t[ToolSource.EmailHandover]: 'Send email',\n\t[ToolSource.Slack]: 'Send Slack message',\n};\n\n/** A tool source's brand-glyph component. */\nexport type IconComp = FunctionComponent<SVGAttributes<SVGElement>>;\n\n/** Brand glyph for a tool source, with its own size so each keeps its aspect ratio. */\nexport interface SourceIcon {\n\tIcon: IconComp;\n\tw: number;\n\th: number;\n}\n\n/**\n * A built-in \"tool\" that opens a config drawer (Rest API / email handover /\n * Slack) rather than inserting a mention. Surfaced as an empty-state source\n * button in the Tools section and as a row in the `@`-picker Tools view; picking\n * it opens the drawer and never writes into the instructions text.\n */\nexport interface ToolAction {\n\tsource: ToolSource;\n\tlabel: string;\n\ticon?: SourceIcon;\n\t/** Open this tool's config drawer. */\n\tonSelect: () => void;\n\t/**\n\t * Integration connection state for this source. `undefined` = no connection\n\t * gating (default). `false` = the store hasn't connected this integration →\n\t * the `@` picker shows a \"Connect\" row that calls {@link onConnect} instead of\n\t * drilling in / offering \"Create new\". `true` = connected (renders normally).\n\t * Set by the consumer via `config.integrationStatus` (today: Slack only).\n\t */\n\tconnected?: boolean;\n\t/** Open the parent's connect flow for this source (used when `connected === false`). */\n\tonConnect?: () => void;\n}\n\n/** Sources of the built-in drawer tools, in display order. */\nexport const TOOL_ACTION_SOURCES: ToolSource[] = [\n\tToolSource.RestApi,\n\tToolSource.EmailHandover,\n\tToolSource.Slack,\n];\n\n/**\n * Fixed display rank for the `@`-picker's tool-source groups (lower = higher). The\n * picker sorts its source rows by this so adding/updating a tool never reshuffles\n * them. Manifest (the native tools) leads; any source not listed here\n * (dynamic/unknown, e.g. Integration) sorts AFTER Slack, keeping its discovery\n * order among the rest (Array.sort is stable).\n */\nexport const TOOL_SOURCE_RANK: Partial<Record<ToolSource, number>> = {\n\t[ToolSource.Manifest]: 0,\n\t[ToolSource.Shopify]: 1,\n\t// Each integration/vendor source is its OWN top-level row (BigCommerce →\n\t// Gorgias); rank orders them so adding/updating a tool never reshuffles them.\n\t[ToolSource.Bigcommerce]: 2,\n\t[ToolSource.Shipstation]: 3,\n\t[ToolSource.Skio]: 4,\n\t[ToolSource.Gorgias]: 5,\n\t[ToolSource.Slack]: 6,\n\t// Send Email then REST API sit after the integration sources at the top level.\n\t[ToolSource.EmailHandover]: 7,\n\t[ToolSource.RestApi]: 8,\n};\n\n/**\n * External integration / vendor sources. Each renders as its OWN top-level\n * drill-in group in the picker — even when it has a single tool — so the vendor\n * reads as its own discoverable, connectable unit (never collapsed to a lone\n * leaf; see the single-leaf flatten in `MentionPicker`). Deliberately excludes\n * `Manifest` (the built-in natives) and the config/rest action sources (Rest API\n * / Email / Slack), whose single capability is surfaced flat.\n */\nexport const INTEGRATION_SOURCES: ToolSource[] = [\n\tToolSource.Shopify,\n\tToolSource.Bigcommerce,\n\tToolSource.Shipstation,\n\tToolSource.Skio,\n\tToolSource.Gorgias,\n\tToolSource.Integration,\n];\n\nconst INTEGRATION_SOURCE_SET = new Set<string>(INTEGRATION_SOURCES);\n\n/** True for an external integration/vendor source (never collapsed to a single leaf). */\nexport const isIntegrationSource = (source: string): boolean =>\n\tINTEGRATION_SOURCE_SET.has(source);\n\nconst UNRANKED_SOURCE_RANK = Object.keys(TOOL_SOURCE_RANK).length;\n\n/** Sort rank for a source string; unknown sources rank after all known ones. */\nexport const toolSourceRank = (source: string): number =>\n\tTOOL_SOURCE_RANK[source as ToolSource] ?? UNRANKED_SOURCE_RANK;\n\n/**\n * `tool_key` of a configurable shared-drawer tool (email / Slack). Lives here (not\n * in AgentBuilder.model) so this leaf constants file has no back-edge to the model\n * — the dependency stays one-way (model → constants), avoiding a circular import.\n */\nexport type ConfigToolKey = 'send_email' | 'send_slack_message';\n\n/**\n * Drawer sources rendered by the shared dynamic panel (`ConfigToolPanel`), each\n * mapped to its backend `tool_key`. Rest API is absent — it has a bespoke panel.\n */\nexport const CONFIG_TOOL_SOURCES: Partial<Record<ToolSource, ConfigToolKey>> = {\n\t[ToolSource.EmailHandover]: 'send_email',\n\t[ToolSource.Slack]: 'send_slack_message',\n};\n"],"names":["CATEGORIES","ToolSource","TOOL_SOURCE_LABELS","TOOL_ACTION_LABELS","TOOL_ACTION_SOURCES","TOOL_SOURCE_RANK","INTEGRATION_SOURCES","INTEGRATION_SOURCE_SET","isIntegrationSource","source","UNRANKED_SOURCE_RANK","toolSourceRank","CONFIG_TOOL_SOURCES"],"mappings":"gFAcO,MAAMA,EAAiD,CAC7D,CAAE,IAAK,OAAQ,MAAO,OAAA,EACtB,CAAE,IAAK,WAAY,MAAO,WAAA,CAC3B,EAmBO,IAAKC,GAAAA,IACXA,EAAA,SAAW,WACXA,EAAA,QAAU,UACVA,EAAA,YAAc,cACdA,EAAA,YAAc,cACdA,EAAA,KAAO,OACPA,EAAA,QAAU,UACVA,EAAA,YAAc,cACdA,EAAA,QAAU,WACVA,EAAA,cAAgB,iBAChBA,EAAA,MAAQ,QAVGA,IAAAA,GAAA,CAAA,CAAA,EA2CL,MAAMC,EAAiD,CAC5D,SAAsB,WACtB,QAAqB,UACrB,YAAyB,cACzB,YAAyB,cACzB,KAAkB,OAClB,QAAqB,UACrB,YAAyB,cACzB,SAAqB,WACrB,eAA2B,QAC3B,MAAmB,OACrB,EAQaC,EAA0D,CACrE,SAAqB,WACrB,eAA2B,aAC3B,MAAmB,oBACrB,EAqCaC,EAAoC,CAChD,WACA,iBACA,OACD,EASaC,EAAwD,CACnE,SAAsB,EACtB,QAAqB,EAGrB,YAAyB,EACzB,YAAyB,EACzB,KAAkB,EAClB,QAAqB,EACrB,MAAmB,EAEnB,eAA2B,EAC3B,SAAqB,CACvB,EAUaC,EAAoC,CAChD,UACA,cACA,cACA,OACA,UACA,aACD,EAEMC,EAAyB,IAAI,IAAYD,CAAmB,EAGrDE,EAAuBC,GACnCF,EAAuB,IAAIE,CAAM,EAE5BC,EAAuB,OAAO,KAAKL,CAAgB,EAAE,OAG9CM,EAAkBF,GAC9BJ,EAAiBI,CAAoB,GAAKC,EAa9BE,EAAkE,CAC7E,eAA2B,aAC3B,MAAmB,oBACrB"}
@@ -1,319 +1,301 @@
1
- import { jsxs as k, jsx as s, Fragment as oe } from "react/jsx-runtime";
2
- import ie from "../../../assets/icons/chevronRight.svg.js";
3
- import le from "../../../assets/icons/searchIcon.svg.js";
4
- import ae from "../../../icons/Arrows/Normal arrows/ArrowLeft.js";
5
- import { useState as A, useMemo as y, useEffect as U, useRef as ce } from "react";
6
- import h from "styled-components";
7
- import { TitleSmall as se, BodySecondary as de, BodyCaption as ue } from "../../TypographyStyle.js";
8
- import { COLORS as o } from "../../../constants/Theme.js";
9
- import { CATEGORIES as pe, isIntegrationSource as j, toolSourceRank as F, CONFIG_TOOL_SOURCES as he, INTEGRATIONS_RANK as fe } from "../constants/tools.js";
10
- import { toolSourceLabel as J } from "../utils/mentionSerialization.js";
11
- import { renderSourceIcon as H, sourceIcon as P } from "../utils/sourceIcons.js";
12
- import ee from "../../../icons/Informational/Common UI/Shield.js";
13
- const b = (a) => a.meta, C = (a) => b(a)?.plainLabel ?? a.label, ge = "__bik_create_subagent__", Ne = ({
1
+ import { jsxs as k, jsx as s, Fragment as ee } from "react/jsx-runtime";
2
+ import te from "../../../assets/icons/chevronRight.svg.js";
3
+ import ne from "../../../assets/icons/searchIcon.svg.js";
4
+ import oe from "../../../icons/Arrows/Normal arrows/ArrowLeft.js";
5
+ import { useState as q, useMemo as y, useEffect as N, useRef as re } from "react";
6
+ import p from "styled-components";
7
+ import { TitleSmall as ie, BodySecondary as le, BodyCaption as ae } from "../../TypographyStyle.js";
8
+ import { COLORS as r } from "../../../constants/Theme.js";
9
+ import { CATEGORIES as ce, toolSourceRank as W, isIntegrationSource as se, CONFIG_TOOL_SOURCES as de } from "../constants/tools.js";
10
+ import { toolSourceLabel as U } from "../utils/mentionSerialization.js";
11
+ import { renderSourceIcon as X, sourceIcon as P } from "../utils/sourceIcons.js";
12
+ import Y from "../../../icons/Informational/Common UI/Shield.js";
13
+ const g = (a) => a.meta, R = (a) => g(a)?.plainLabel ?? a.label, ue = "__bik_create_subagent__", ze = ({
14
14
  items: a,
15
- onSelect: $,
15
+ onSelect: C,
16
16
  registerKeyHandler: L,
17
17
  onClose: w,
18
18
  onCreateSubAgent: I,
19
- initialSource: Q,
19
+ initialSource: j,
20
20
  toolActions: v,
21
- integrationStatus: V,
22
- onConnectIntegration: W
21
+ integrationStatus: F,
22
+ onConnectIntegration: G
23
23
  }) => {
24
- const [te, z] = A(null), [c, B] = A(Q ?? null), [R, D] = A(null), [_, m] = A(-1), [S, X] = A(""), x = y(
25
- () => a.filter((e) => b(e)?.kind === "tool"),
24
+ const [Z, _] = q(null), [c, z] = q(j ?? null), [$, b] = q(-1), [S, J] = q(""), m = y(
25
+ () => a.filter((e) => g(e)?.kind === "tool"),
26
26
  [a]
27
- ), T = y(
28
- () => a.filter((e) => b(e)?.kind === "subagent"),
27
+ ), A = y(
28
+ () => a.filter((e) => g(e)?.kind === "subagent"),
29
29
  [a]
30
- ), N = y(() => {
30
+ ), O = y(() => {
31
31
  const e = [];
32
- return x.forEach((r) => {
33
- const f = b(r)?.source ?? "other";
34
- e.includes(f) || e.push(f);
32
+ return m.forEach((o) => {
33
+ const h = g(o)?.source ?? "other";
34
+ e.includes(h) || e.push(h);
35
35
  }), e;
36
- }, [x]), M = y(
36
+ }, [m]), D = y(
37
37
  () => new Map(
38
38
  (v ?? []).map((e) => [e.source, e])
39
39
  ),
40
40
  [v]
41
- ), E = y(
42
- () => pe.filter(
43
- (e) => e.key === "tool" ? x.length > 0 || (v?.length ?? 0) > 0 : T.length > 0 || !!I
41
+ ), B = y(
42
+ () => ce.filter(
43
+ (e) => e.key === "tool" ? m.length > 0 || (v?.length ?? 0) > 0 : A.length > 0 || !!I
44
44
  ),
45
- [x.length, T.length, I, v?.length]
46
- ), G = E.length === 1 ? E[0].key : null, d = te ?? G, u = d ? d === "subagent" ? (
45
+ [m.length, A.length, I, v?.length]
46
+ ), M = B.length === 1 ? B[0].key : null, d = Z ?? M, u = d ? d === "subagent" ? (
47
47
  // Always titled — with a back arrow only when the category chooser is above.
48
48
  {
49
49
  title: "Sub-agent",
50
- onBack: G ? void 0 : () => z(null)
50
+ onBack: M ? void 0 : () => _(null)
51
51
  }
52
52
  ) : c ? {
53
- title: J(c),
53
+ title: U(c),
54
54
  // Deep-linked to a source (opened from a right-panel source button):
55
55
  // that source IS the root, so no back arrow. Otherwise back clears the
56
- // source — returning to the Integrations group if we came via it (its
57
- // `group` state is untouched), else to the source chooser.
58
- onBack: Q ? void 0 : () => B(null),
56
+ // source — returning to the source chooser.
57
+ onBack: j ? void 0 : () => z(null),
59
58
  icon: P(c)
60
- } : R === "integrations" ? { title: "Integrations", onBack: () => D(null) } : (
59
+ } : (
61
60
  // Always titled — matches the Sub-agent header; back arrow only when the
62
61
  // category chooser is above (i.e. not the sole category).
63
62
  {
64
63
  title: "Tools",
65
- onBack: G ? void 0 : () => z(null)
64
+ onBack: M ? void 0 : () => _(null)
66
65
  }
67
66
  ) : null, l = y(() => {
68
67
  if (!d)
69
- return E.map((n) => ({
70
- id: n.key,
71
- label: n.label,
68
+ return B.map((t) => ({
69
+ id: t.key,
70
+ label: t.label,
72
71
  drillsIn: !0,
73
72
  onActivate: () => {
74
- z(n.key), B(null), D(null);
73
+ _(t.key), z(null);
75
74
  }
76
75
  }));
77
76
  if (d === "subagent") {
78
- const n = S.trim().toLowerCase(), p = T.filter((g) => !n || C(g).toLowerCase().includes(n)).map((g) => ({
79
- id: String(g.id),
80
- label: C(g),
77
+ const t = S.trim().toLowerCase(), f = A.filter((x) => !t || R(x).toLowerCase().includes(t)).map((x) => ({
78
+ id: String(x.id),
79
+ label: R(x),
81
80
  drillsIn: !1,
82
- onActivate: () => $(g)
81
+ onActivate: () => C(x)
83
82
  }));
84
- return I && p.push({
85
- id: ge,
83
+ return I && f.push({
84
+ id: ue,
86
85
  label: "Create new",
87
86
  drillsIn: !1,
88
87
  isCreate: !0,
89
88
  onActivate: () => {
90
89
  w?.(), I();
91
90
  }
92
- }), p;
91
+ }), f;
93
92
  }
94
93
  if (!c) {
95
- const n = (v ?? []).map((t) => t.source).filter((t) => !N.includes(t)), p = [...N, ...n], g = (t) => {
96
- const i = M.get(t);
97
- if ((i !== void 0 ? i.connected : V?.[t]) === !1)
94
+ const t = (v ?? []).map((n) => n.source).filter((n) => !O.includes(n)), f = [...O, ...t], x = (n) => {
95
+ const i = D.get(n);
96
+ if ((i !== void 0 ? i.connected : F?.[n]) === !1)
98
97
  return {
99
- id: t,
100
- label: J(t),
98
+ id: n,
99
+ label: U(n),
101
100
  drillsIn: !1,
102
- icon: P(t) ?? i?.icon,
101
+ icon: P(n) ?? i?.icon,
103
102
  rightLabel: "Connect",
104
103
  onActivate: () => {
105
- w?.(), i?.onConnect ? i.onConnect() : W?.(t);
104
+ w?.(), i?.onConnect ? i.onConnect() : G?.(n);
106
105
  }
107
106
  };
108
- const K = x.filter(
109
- (q) => (b(q)?.source ?? "other") === t
107
+ const V = m.filter(
108
+ (E) => (g(E)?.source ?? "other") === n
110
109
  );
111
- if (K.length + (i ? 1 : 0) === 1) {
112
- const q = P(t) ?? i?.icon;
110
+ if (V.length + (i ? 1 : 0) === 1 && !(i === void 0 && se(n))) {
111
+ const E = P(n) ?? i?.icon;
113
112
  if (i)
114
113
  return {
115
- id: t,
114
+ id: n,
116
115
  label: i.label,
117
116
  drillsIn: !1,
118
- icon: q,
117
+ icon: E,
119
118
  onActivate: () => {
120
119
  w?.(), i.onSelect();
121
120
  }
122
121
  };
123
- const O = K[0];
122
+ const T = V[0];
124
123
  return {
125
- id: String(O.id),
126
- label: C(O),
124
+ id: String(T.id),
125
+ label: R(T),
127
126
  drillsIn: !1,
128
- icon: q,
129
- authRequired: b(O)?.authRequired,
130
- onActivate: () => $(O)
127
+ icon: E,
128
+ authRequired: g(T)?.authRequired,
129
+ onActivate: () => C(T)
131
130
  };
132
131
  }
133
132
  return {
134
- id: t,
135
- label: J(t),
133
+ id: n,
134
+ label: U(n),
136
135
  drillsIn: !0,
137
- icon: P(t) ?? i?.icon,
138
- onActivate: () => B(t)
136
+ icon: P(n) ?? i?.icon,
137
+ onActivate: () => z(n)
139
138
  };
140
139
  };
141
- if (R === "integrations")
142
- return p.filter(j).sort((t, i) => F(t) - F(i)).map(g);
143
- const Z = p.filter((t) => !j(t)).map((t) => ({ rank: F(t), row: g(t) }));
144
- return p.some(j) && Z.push({
145
- rank: fe,
146
- row: {
147
- id: "__integrations__",
148
- label: "Integrations",
149
- drillsIn: !0,
150
- onActivate: () => {
151
- D("integrations"), B(null);
152
- }
153
- }
154
- }), Z.sort((t, i) => t.rank - i.rank).map((t) => t.row);
140
+ return f.sort((n, i) => W(n) - W(i)).map(x);
155
141
  }
156
- const e = S.trim().toLowerCase(), r = x.filter((n) => (b(n)?.source ?? "other") === c).filter((n) => !e || C(n).toLowerCase().includes(e)).map((n) => ({
157
- id: String(n.id),
158
- label: C(n),
142
+ const e = S.trim().toLowerCase(), o = m.filter((t) => (g(t)?.source ?? "other") === c).filter((t) => !e || R(t).toLowerCase().includes(e)).map((t) => ({
143
+ id: String(t.id),
144
+ label: R(t),
159
145
  drillsIn: !1,
160
- authRequired: b(n)?.authRequired,
161
- onActivate: () => $(n)
162
- })), f = M.get(c);
163
- if (f) {
164
- const n = c in he;
165
- r.push({
146
+ authRequired: g(t)?.authRequired,
147
+ onActivate: () => C(t)
148
+ })), h = D.get(c);
149
+ if (h) {
150
+ const t = c in de;
151
+ o.push({
166
152
  id: `create:${c}`,
167
- label: f.label,
153
+ label: h.label,
168
154
  drillsIn: !1,
169
- isCreate: !n,
155
+ isCreate: !t,
170
156
  onActivate: () => {
171
- w?.(), f.onSelect();
157
+ w?.(), h.onSelect();
172
158
  }
173
159
  });
174
160
  }
175
- return r;
161
+ return o;
176
162
  }, [
177
163
  d,
178
- E,
164
+ B,
179
165
  c,
180
- R,
181
166
  S,
182
- x,
183
- T,
184
- N,
185
- $,
167
+ m,
168
+ A,
169
+ O,
170
+ C,
186
171
  w,
187
172
  I,
188
173
  v,
189
- M,
190
- V,
191
- W
174
+ D,
175
+ F,
176
+ G
192
177
  ]);
193
- U(
194
- () => m(-1),
195
- [d, c, R, S, a]
196
- ), U(() => X(""), [d, c, R]);
197
- const Y = ce({ rows: l, activeIndex: _, header: u });
198
- Y.current = { rows: l, activeIndex: _, header: u }, U(() => {
178
+ N(() => b(-1), [d, c, S, a]), N(() => J(""), [d, c]);
179
+ const Q = re({ rows: l, activeIndex: $, header: u });
180
+ Q.current = { rows: l, activeIndex: $, header: u }, N(() => {
199
181
  if (L)
200
182
  return L((e) => {
201
- const { rows: r, activeIndex: f, header: n } = Y.current;
183
+ const { rows: o, activeIndex: h, header: t } = Q.current;
202
184
  switch (e.key) {
203
185
  case "ArrowDown":
204
- return r.length && m((p) => (p + 1) % r.length), !0;
186
+ return o.length && b((f) => (f + 1) % o.length), !0;
205
187
  case "ArrowUp":
206
- return r.length && m((p) => (p + r.length - 1) % r.length), !0;
188
+ return o.length && b((f) => (f + o.length - 1) % o.length), !0;
207
189
  case "ArrowRight":
208
190
  case "Enter":
209
- return (r[f] ?? r[0])?.onActivate(), !0;
191
+ return (o[h] ?? o[0])?.onActivate(), !0;
210
192
  case "ArrowLeft":
211
- return n?.onBack ? (n.onBack(), !0) : !1;
193
+ return t?.onBack ? (t.onBack(), !0) : !1;
212
194
  default:
213
195
  return !1;
214
196
  }
215
197
  }), () => L(null);
216
198
  }, [L]);
217
- const ne = d ? l.length && !l[0].drillsIn ? "items" : "sources" : "categories", re = d === "tool" && !!c || d === "subagent";
218
- return /* @__PURE__ */ k(be, { className: `bik-mention-picker bik-mention-picker--${ne}`, children: [
199
+ const K = d ? l.length && !l[0].drillsIn ? "items" : "sources" : "categories", H = d === "tool" && !!c || d === "subagent";
200
+ return /* @__PURE__ */ k(pe, { className: `bik-mention-picker bik-mention-picker--${K}`, children: [
219
201
  u && /* @__PURE__ */ k(
220
- Re,
202
+ ve,
221
203
  {
222
204
  type: "button",
223
205
  onClick: u.onBack,
224
206
  disabled: !u.onBack,
225
207
  style: {
226
- background: o.surface.subdued,
208
+ background: r.surface.subdued,
227
209
  cursor: u.onBack ? "pointer" : "default"
228
210
  },
229
211
  children: [
230
212
  u.onBack && /* @__PURE__ */ s(
231
- ae,
213
+ oe,
232
214
  {
233
215
  width: 20,
234
216
  height: 20,
235
- color: o.content.primary
217
+ color: r.content.primary
236
218
  }
237
219
  ),
238
- u.icon && H(u.icon),
239
- /* @__PURE__ */ k(se, { children: [
220
+ u.icon && X(u.icon),
221
+ /* @__PURE__ */ k(ie, { children: [
240
222
  " ",
241
223
  u.title
242
224
  ] })
243
225
  ]
244
226
  }
245
227
  ),
246
- re && /* @__PURE__ */ k(me, { children: [
228
+ H && /* @__PURE__ */ k(he, { children: [
247
229
  /* @__PURE__ */ s(
248
- le,
230
+ ne,
249
231
  {
250
232
  width: 20,
251
233
  height: 20,
252
- color: o.content.placeholder
234
+ color: r.content.placeholder
253
235
  }
254
236
  ),
255
237
  /* @__PURE__ */ s(
256
- xe,
238
+ fe,
257
239
  {
258
240
  autoFocus: !0,
259
241
  value: S,
260
242
  placeholder: "Search",
261
243
  "data-test": "mention-picker-search",
262
- onChange: (e) => X(e.target.value),
244
+ onChange: (e) => J(e.target.value),
263
245
  onKeyDown: (e) => {
264
- l.length && (e.key === "ArrowDown" ? (e.preventDefault(), m((r) => (r + 1) % l.length)) : e.key === "ArrowUp" ? (e.preventDefault(), m((r) => (r + l.length - 1) % l.length)) : e.key === "Enter" && (e.preventDefault(), (l[_] ?? l[0])?.onActivate()));
246
+ l.length && (e.key === "ArrowDown" ? (e.preventDefault(), b((o) => (o + 1) % l.length)) : e.key === "ArrowUp" ? (e.preventDefault(), b((o) => (o + l.length - 1) % l.length)) : e.key === "Enter" && (e.preventDefault(), (l[$] ?? l[0])?.onActivate()));
265
247
  }
266
248
  }
267
249
  )
268
250
  ] }),
269
- l.length === 0 ? /* @__PURE__ */ s(Se, { children: d === "subagent" ? null : "No tools available" }) : l.map((e, r) => /* @__PURE__ */ s(
270
- ke,
251
+ l.length === 0 ? /* @__PURE__ */ s(ye, { children: d === "subagent" ? null : "No tools available" }) : l.map((e, o) => /* @__PURE__ */ s(
252
+ ge,
271
253
  {
272
254
  type: "button",
273
- $active: r === _,
274
- onMouseEnter: () => m(r),
275
- onMouseLeave: () => m(-1),
255
+ $active: o === $,
256
+ onMouseEnter: () => b(o),
257
+ onMouseLeave: () => b(-1),
276
258
  onClick: e.onActivate,
277
- children: e.isCreate ? /* @__PURE__ */ s(Ie, { children: e.label }) : /* @__PURE__ */ k(oe, { children: [
278
- /* @__PURE__ */ k(ve, { children: [
279
- H(e.icon),
280
- /* @__PURE__ */ s(de, { color: o.content.primary, children: e.label }),
259
+ children: e.isCreate ? /* @__PURE__ */ s(ke, { children: e.label }) : /* @__PURE__ */ k(ee, { children: [
260
+ /* @__PURE__ */ k(be, { children: [
261
+ X(e.icon),
262
+ /* @__PURE__ */ s(le, { color: r.content.primary, children: e.label }),
281
263
  e.authRequired && /* @__PURE__ */ s(
282
- ee,
264
+ Y,
283
265
  {
284
266
  size: 16,
285
267
  "aria-label": "This tool requires customer verification"
286
268
  }
287
269
  )
288
270
  ] }),
289
- e.rightLabel ? /* @__PURE__ */ s(we, { children: e.rightLabel }) : e.drillsIn && /* @__PURE__ */ s(ie, { width: 12, height: 12 })
271
+ e.rightLabel ? /* @__PURE__ */ s(xe, { children: e.rightLabel }) : e.drillsIn && /* @__PURE__ */ s(te, { width: 12, height: 12 })
290
272
  ] })
291
273
  },
292
274
  e.id
293
275
  )),
294
- l.some((e) => e.authRequired) && /* @__PURE__ */ k(ye, { children: [
295
- /* @__PURE__ */ s(ee, { size: 16 }),
296
- /* @__PURE__ */ s(ue, { color: o.content.secondary, children: "This tool requires customer verification" })
276
+ l.some((e) => e.authRequired) && /* @__PURE__ */ k(me, { children: [
277
+ /* @__PURE__ */ s(Y, { size: 16 }),
278
+ /* @__PURE__ */ s(ae, { color: r.content.secondary, children: "This tool requires customer verification" })
297
279
  ] })
298
280
  ] });
299
- }, be = h.div`
281
+ }, pe = p.div`
300
282
  display: flex;
301
283
  flex-direction: column;
302
284
  min-width: 240px;
303
285
  max-height: 301px;
304
286
  overflow-y: auto;
305
- background: ${o.surface.standard};
306
- border: 1px solid ${o.stroke.primary};
287
+ background: ${r.surface.standard};
288
+ border: 1px solid ${r.stroke.primary};
307
289
  border-radius: 4px;
308
290
  box-shadow: 0px -2px 8px 0px #0000001f;
309
- `, me = h.div`
291
+ `, he = p.div`
310
292
  display: flex;
311
293
  align-items: center;
312
294
  gap: 8px;
313
295
  padding: 10px 12px;
314
296
  flex-shrink: 0;
315
- border-bottom: 1px solid ${o.stroke.primary};
316
- `, xe = h.input`
297
+ border-bottom: 1px solid ${r.stroke.primary};
298
+ `, fe = p.input`
317
299
  flex: 1;
318
300
  min-width: 0;
319
301
  border: none;
@@ -321,12 +303,12 @@ const b = (a) => a.meta, C = (a) => b(a)?.plainLabel ?? a.label, ge = "__bik_cre
321
303
  background: transparent;
322
304
  font-family: Inter;
323
305
  font-size: 14px;
324
- color: ${o.content.primary};
306
+ color: ${r.content.primary};
325
307
 
326
308
  &::placeholder {
327
- color: ${o.content.placeholder};
309
+ color: ${r.content.placeholder};
328
310
  }
329
- `, ke = h.button`
311
+ `, ge = p.button`
330
312
  display: flex;
331
313
  justify-content: space-between;
332
314
  align-items: center;
@@ -340,45 +322,45 @@ const b = (a) => a.meta, C = (a) => b(a)?.plainLabel ?? a.label, ge = "__bik_cre
340
322
  box-sizing: border-box;
341
323
  flex-shrink: 0;
342
324
  border: none;
343
- border-bottom: 1px solid ${o.stroke.primary};
344
- background: ${(a) => a.$active ? o.surface.subdued : "transparent"};
325
+ border-bottom: 1px solid ${r.stroke.primary};
326
+ background: ${(a) => a.$active ? r.surface.subdued : "transparent"};
345
327
  cursor: pointer;
346
328
  text-align: left;
347
329
 
348
330
  &:hover {
349
- background: ${o.surface.hovered};
331
+ background: ${r.surface.hovered};
350
332
  }
351
- `, ve = h.div`
333
+ `, be = p.div`
352
334
  display: flex;
353
335
  align-items: center;
354
336
  gap: 12px;
355
337
  min-width: 0;
356
- `, ye = h.div`
338
+ `, me = p.div`
357
339
  display: flex;
358
340
  align-items: center;
359
341
  gap: 6px;
360
342
  padding: 8px 12px;
361
- border-top: 1px solid ${o.stroke.primary};
362
- `, we = h.span`
343
+ border-top: 1px solid ${r.stroke.primary};
344
+ `, xe = p.span`
363
345
  flex-shrink: 0;
364
- color: ${o.content.brand};
346
+ color: ${r.content.brand};
365
347
  font-family: Inter;
366
348
  font-size: 14px;
367
349
  font-weight: 600;
368
350
  white-space: nowrap;
369
- `, Ie = h.div`
351
+ `, ke = p.div`
370
352
  width: 100%;
371
353
  text-align: center;
372
- color: ${o.content.brand};
354
+ color: ${r.content.brand};
373
355
  font-family: Inter;
374
356
  font-size: 14px;
375
357
  font-weight: 600;
376
- `, Re = h.button`
358
+ `, ve = p.button`
377
359
  display: flex;
378
360
  align-items: center;
379
361
  padding: 12px 16px;
380
362
  border: none;
381
- border-bottom: 1px solid ${o.stroke.primary};
363
+ border-bottom: 1px solid ${r.stroke.primary};
382
364
  background: transparent;
383
365
  cursor: pointer;
384
366
  font-family: Inter;
@@ -388,13 +370,13 @@ const b = (a) => a.meta, C = (a) => b(a)?.plainLabel ?? a.label, ge = "__bik_cre
388
370
  box-sizing: border-box;
389
371
  flex-shrink: 0;
390
372
  gap: 4px;
391
- `, Se = h.div`
373
+ `, ye = p.div`
392
374
  padding: 12px 10px;
393
375
  font-family: Inter;
394
376
  font-size: 13px;
395
- color: ${o.content.secondary};
377
+ color: ${r.content.secondary};
396
378
  `;
397
379
  export {
398
- Ne as MentionPicker
380
+ ze as MentionPicker
399
381
  };
400
382
  //# sourceMappingURL=MentionPicker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MentionPicker.js","sources":["../../../../../src/components/agent-builder/components/MentionPicker.tsx"],"sourcesContent":["// import ChevronLeft from '@src/assets/icons/chevronLeft.svg';\nimport ChevronRight from '@src/assets/icons/chevronRight.svg';\nimport SearchIcon from '@src/assets/icons/searchIcon.svg';\nimport type { MentionDropdownRenderProps, MentionItem } from '@src/editor';\nimport { Shield } from '@src/icons';\nimport SvgArrowLeft from '@src/icons/Arrows/Normal arrows/ArrowLeft';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport {\n\tBodyCaption,\n\tBodySecondary,\n\tTitleSmall,\n} from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tCATEGORIES,\n\tCONFIG_TOOL_SOURCES,\n\tINTEGRATIONS_RANK,\n\tisIntegrationSource,\n\ttoolSourceRank,\n} from '../constants/tools';\nimport type { Category, ToolAction, ToolSource } from '../constants/tools';\nimport {\n\tMentionKindMeta,\n\ttoolSourceLabel,\n} from '../utils/mentionSerialization';\nimport { renderSourceIcon, sourceIcon, SourceIcon } from '../utils/sourceIcons';\n\nconst metaOf = (item: MentionItem): MentionKindMeta | undefined =>\n\titem.meta as unknown as MentionKindMeta | undefined;\n\nconst rowLabel = (item: MentionItem): string =>\n\tmetaOf(item)?.plainLabel ?? item.label;\n\n/** One navigable row in the picker's current view. */\ntype PickerRowModel = {\n\tid: string;\n\tlabel: string;\n\t/** Drill-in rows show a chevron; leaf (selectable) rows do not. */\n\tdrillsIn: boolean;\n\t/** Leading brand glyph (source rows only). */\n\ticon?: SourceIcon;\n\t/** Brand-coloured \"Create new\" action row (not a selectable item). */\n\tisCreate?: boolean;\n\t/**\n\t * Brand-coloured right-aligned action text (e.g. \"Connect\") shown in place of\n\t * the drill-in chevron — used for an unconnected integration source.\n\t */\n\trightLabel?: string;\n\t/** Tool leaf touches customer-private data → shows a shield glyph. */\n\tauthRequired?: boolean;\n\tonActivate: () => void;\n};\n\n/** Sentinel id for the sub-agent \"Create new\" row. */\nconst CREATE_SUBAGENT_ID = '__bik_create_subagent__';\n\ntype MentionPickerProps = MentionDropdownRenderProps & {\n\t/** Opens the create-sub-agent drawer (shows a \"Create new\" row in the Sub-agent view). */\n\tonCreateSubAgent?: () => void;\n\t/**\n\t * Open already drilled into this tool source (e.g. `'shopify'`) — its tool list\n\t * is shown immediately. */\n\tinitialSource?: string;\n\t/**\n\t * Built-in tool actions (Rest API / Handover to email) shown in the Tools view.\n\t * Picking one opens its config drawer (via `onSelect`) and dismisses the picker\n\t * — it never inserts a mention into the text.\n\t */\n\ttoolActions?: ToolAction[];\n\t/**\n\t * Per-source integration connection state. A source whose value is `false`\n\t * renders a \"Connect\" row (like an unconnected action) instead of drilling in —\n\t * so native source groups (Shopify / BigCommerce / ShipStation) show \"Connect\"\n\t * consistently with the config actions (Slack).\n\t */\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\t/** Open the connect flow for an unconnected source (used by the Connect row). */\n\tonConnectIntegration?: (source: ToolSource) => void;\n};\n\n/**\n * `@` reference picker. Drills:\n * root → Tools → <source> (Manifest / Shopify / …) → tool\n * → Sub-agent → sub-agent\n * (\"Add condition\" and \"Variables\" are intentionally not shown yet.)\n *\n * Owns keyboard navigation (↑/↓ move, →/Enter activate, ← go back) over the\n * CURRENTLY visible rows — registered with the editor via `registerKeyHandler`.\n */\nexport const MentionPicker: React.FC<MentionPickerProps> = ({\n\titems,\n\tonSelect,\n\tregisterKeyHandler,\n\tonClose,\n\tonCreateSubAgent,\n\tinitialSource,\n\ttoolActions,\n\tintegrationStatus,\n\tonConnectIntegration,\n}) => {\n\tconst [category, setCategory] = useState<Category | null>(null);\n\tconst [source, setSource] = useState<string | null>(initialSource ?? null);\n\t// Non-null when drilled into the consolidated \"Integrations\" group (its member\n\t// sources are shown; picking one drills into that source's tools as usual).\n\tconst [group, setGroup] = useState<'integrations' | null>(null);\n\t// -1 = nothing highlighted; rows highlight only on hover / arrow keys\n\t// (a default highlight reads as a stuck hover state).\n\tconst [activeIndex, setActiveIndex] = useState(-1);\n\t// Search box shown inside a source's tool list (Manifest / Shopify); filters\n\t// that source's tools by name.\n\tconst [search, setSearch] = useState('');\n\n\tconst tools = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'tool'),\n\t\t[items],\n\t);\n\tconst subAgents = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'subagent'),\n\t\t[items],\n\t);\n\tconst sources = useMemo(() => {\n\t\tconst acc: string[] = [];\n\t\ttools.forEach((t) => {\n\t\t\tconst s = metaOf(t)?.source ?? 'other';\n\t\t\tif (!acc.includes(s)) {\n\t\t\t\tacc.push(s);\n\t\t\t}\n\t\t});\n\t\treturn acc;\n\t}, [tools]);\n\t// The built-in \"create\" action per source (Rest API / email / Slack). A source\n\t// with an action drills into [its instances + a \"Create new\" row] — like the\n\t// Sub-agent category — instead of showing a duplicate flat \"create\" row.\n\tconst actionBySource = useMemo(\n\t\t() =>\n\t\t\tnew Map<string, ToolAction>(\n\t\t\t\t(toolActions ?? []).map((a) => [a.source, a]),\n\t\t\t),\n\t\t[toolActions],\n\t);\n\n\t// Show a category when it has items — and ALWAYS show Sub-agent when creating\n\t// one is possible, so an agent with no sub-agents yet still gets the root\n\t// \"Tools / Sub-agent\" choice (with a \"Create new\" inside). When only one is\n\t// available (e.g. the sub-agent drawer offers tools only) the selector is skipped.\n\tconst availableCategories = useMemo(\n\t\t() =>\n\t\t\tCATEGORIES.filter((c) =>\n\t\t\t\tc.key === 'tool'\n\t\t\t\t\t? tools.length > 0 || (toolActions?.length ?? 0) > 0\n\t\t\t\t\t: subAgents.length > 0 || !!onCreateSubAgent,\n\t\t\t),\n\t\t[tools.length, subAgents.length, onCreateSubAgent, toolActions?.length],\n\t);\n\tconst soleCategory =\n\t\tavailableCategories.length === 1 ? availableCategories[0].key : null;\n\tconst activeCategory = category ?? soleCategory;\n\n\t// Title shown above the current view. `onBack` is omitted at a root level (a\n\t// sole category has nowhere to go back to) — the header then shows as a plain\n\t// title. When `onBack` is set the header leads with a back arrow, followed by\n\t// the source icon in a source detail view: `[← back][icon][title]`.\n\tconst header: {\n\t\ttitle: string;\n\t\tonBack?: () => void;\n\t\ticon?: SourceIcon;\n\t} | null = !activeCategory\n\t\t? null\n\t\t: activeCategory === 'subagent'\n\t\t? // Always titled — with a back arrow only when the category chooser is above.\n\t\t {\n\t\t\t\ttitle: 'Sub-agent',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t }\n\t\t: source\n\t\t? {\n\t\t\t\ttitle: toolSourceLabel(source),\n\t\t\t\t// Deep-linked to a source (opened from a right-panel source button):\n\t\t\t\t// that source IS the root, so no back arrow. Otherwise back clears the\n\t\t\t\t// source — returning to the Integrations group if we came via it (its\n\t\t\t\t// `group` state is untouched), else to the source chooser.\n\t\t\t\tonBack: initialSource ? undefined : () => setSource(null),\n\t\t\t\ticon: sourceIcon(source),\n\t\t }\n\t\t: group === 'integrations'\n\t\t? { title: 'Integrations', onBack: () => setGroup(null) }\n\t\t: // Always titled — matches the Sub-agent header; back arrow only when the\n\t\t // category chooser is above (i.e. not the sole category).\n\t\t {\n\t\t\t\ttitle: 'Tools',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t };\n\n\t// Build the navigable rows for the current view.\n\tconst rows: PickerRowModel[] = useMemo(() => {\n\t\tif (!activeCategory) {\n\t\t\treturn availableCategories.map((c) => ({\n\t\t\t\tid: c.key,\n\t\t\t\tlabel: c.label,\n\t\t\t\tdrillsIn: true,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tsetCategory(c.key);\n\t\t\t\t\tsetSource(null);\n\t\t\t\t\tsetGroup(null);\n\t\t\t\t},\n\t\t\t}));\n\t\t}\n\t\tif (activeCategory === 'subagent') {\n\t\t\tconst sq = search.trim().toLowerCase();\n\t\t\tconst leaves: PickerRowModel[] = subAgents\n\t\t\t\t.filter((item) => !sq || rowLabel(item).toLowerCase().includes(sq))\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tid: String(item.id),\n\t\t\t\t\tlabel: rowLabel(item),\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t\t}));\n\t\t\t// \"Create new\" opens the drawer — first dismiss the menu (strips the \"@\").\n\t\t\tif (onCreateSubAgent) {\n\t\t\t\tleaves.push({\n\t\t\t\t\tid: CREATE_SUBAGENT_ID,\n\t\t\t\t\tlabel: 'Create new',\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tisCreate: true,\n\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\tonCreateSubAgent();\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn leaves;\n\t\t}\n\t\tif (!source) {\n\t\t\t// The real sources (from instances) plus any action source (Rest API /\n\t\t\t// email / Slack) with no instances yet, so it still appears for first-time\n\t\t\t// creation. Deduped — no more twin rows.\n\t\t\tconst actionOnly = (toolActions ?? [])\n\t\t\t\t.map((a) => a.source)\n\t\t\t\t.filter((s) => !sources.includes(s));\n\t\t\tconst combined = [...sources, ...actionOnly];\n\n\t\t\t// One drill-in row per source: Connect (unconnected) / a single collapsed\n\t\t\t// leaf / a drill-in. Reused at the top level AND inside the Integrations\n\t\t\t// group so both behave identically.\n\t\t\tconst buildSourceRow = (s: string): PickerRowModel => {\n\t\t\t\tconst action = actionBySource.get(s);\n\t\t\t\t// Not connected → a \"Connect\" row (no drill-in / no instances / no\n\t\t\t\t// \"Create new\"); clicking dismisses the picker and runs the connect\n\t\t\t\t// flow. Applies to config actions (their own `connected`) AND native\n\t\t\t\t// source groups (via `integrationStatus`), so both look consistent.\n\t\t\t\tconst connected =\n\t\t\t\t\taction !== undefined\n\t\t\t\t\t\t? action.connected\n\t\t\t\t\t\t: integrationStatus?.[s as ToolSource];\n\t\t\t\tif (connected === false) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: s,\n\t\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\t\trightLabel: 'Connect',\n\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\tif (action?.onConnect) {\n\t\t\t\t\t\t\t\taction.onConnect();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tonConnectIntegration?.(s as ToolSource);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// A source whose drill-in view would hold exactly one leaf is pointless\n\t\t\t\t// to drill into — surface that single leaf right here (its function name\n\t\t\t\t// + the same source icon). Covers \"no Rest API added yet\" (→ open the\n\t\t\t\t// create modal directly) and a config tool's single capability (Slack →\n\t\t\t\t// \"Send Slack message\", email → \"Send email\").\n\t\t\t\tconst instances = tools.filter(\n\t\t\t\t\t(t) => (metaOf(t)?.source ?? 'other') === s,\n\t\t\t\t);\n\t\t\t\tif (instances.length + (action ? 1 : 0) === 1) {\n\t\t\t\t\tconst icon = sourceIcon(s) ?? action?.icon;\n\t\t\t\t\tif (action) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: s,\n\t\t\t\t\t\t\tlabel: action.label,\n\t\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\t\ticon,\n\t\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\t\taction.onSelect();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tconst only = instances[0];\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: String(only.id),\n\t\t\t\t\t\tlabel: rowLabel(only),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon,\n\t\t\t\t\t\tauthRequired: metaOf(only)?.authRequired,\n\t\t\t\t\t\tonActivate: () => onSelect(only),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tid: s,\n\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\tdrillsIn: true,\n\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\tonActivate: () => setSource(s),\n\t\t\t\t};\n\t\t\t};\n\n\t\t\t// Inside the Integrations group: just its member sources, ranked.\n\t\t\tif (group === 'integrations') {\n\t\t\t\treturn combined\n\t\t\t\t\t.filter(isIntegrationSource)\n\t\t\t\t\t.sort((a, b) => toolSourceRank(a) - toolSourceRank(b))\n\t\t\t\t\t.map(buildSourceRow);\n\t\t\t}\n\n\t\t\t// Top level: non-integration sources as their own rows, plus ONE\n\t\t\t// \"Integrations\" drill-in row (only when a member exists). Fixed rank order\n\t\t\t// so adding/updating a tool never reshuffles the picker rows.\n\t\t\tconst topRows = combined\n\t\t\t\t.filter((s) => !isIntegrationSource(s))\n\t\t\t\t.map((s) => ({ rank: toolSourceRank(s), row: buildSourceRow(s) }));\n\t\t\tif (combined.some(isIntegrationSource)) {\n\t\t\t\ttopRows.push({\n\t\t\t\t\trank: INTEGRATIONS_RANK,\n\t\t\t\t\trow: {\n\t\t\t\t\t\tid: '__integrations__',\n\t\t\t\t\t\tlabel: 'Integrations',\n\t\t\t\t\t\tdrillsIn: true,\n\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\tsetGroup('integrations');\n\t\t\t\t\t\t\tsetSource(null);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn topRows.sort((a, b) => a.rank - b.rank).map((x) => x.row);\n\t\t}\n\t\tconst q = search.trim().toLowerCase();\n\t\tconst leaves: PickerRowModel[] = tools\n\t\t\t.filter((t) => (metaOf(t)?.source ?? 'other') === source)\n\t\t\t.filter((t) => !q || rowLabel(t).toLowerCase().includes(q))\n\t\t\t.map((item) => ({\n\t\t\t\tid: String(item.id),\n\t\t\t\tlabel: rowLabel(item),\n\t\t\t\tdrillsIn: false,\n\t\t\t\tauthRequired: metaOf(item)?.authRequired,\n\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t}));\n\t\t// A configurable source's add row, below any existing instances, opening\n\t\t// its drawer. Config tools (Slack / email) are a single fixed capability →\n\t\t// render like a normal tool leaf (label only, no icon — matching the tool\n\t\t// rows). Rest API instances are user-created, so its \"add\" stays a\n\t\t// brand-coloured create row.\n\t\tconst action = actionBySource.get(source);\n\t\tif (action) {\n\t\t\tconst isConfigTool = source in CONFIG_TOOL_SOURCES;\n\t\t\tleaves.push({\n\t\t\t\tid: `create:${source}`,\n\t\t\t\tlabel: action.label,\n\t\t\t\tdrillsIn: false,\n\t\t\t\tisCreate: !isConfigTool,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tonClose?.();\n\t\t\t\t\taction.onSelect();\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn leaves;\n\t}, [\n\t\tactiveCategory,\n\t\tavailableCategories,\n\t\tsource,\n\t\tgroup,\n\t\tsearch,\n\t\ttools,\n\t\tsubAgents,\n\t\tsources,\n\t\tonSelect,\n\t\tonClose,\n\t\tonCreateSubAgent,\n\t\ttoolActions,\n\t\tactionBySource,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\n\t]);\n\n\t// Reset highlight whenever the view (or filtered result set) changes.\n\tuseEffect(\n\t\t() => setActiveIndex(-1),\n\t\t[activeCategory, source, group, search, items],\n\t);\n\t// Clear the search box when leaving a source view.\n\tuseEffect(() => setSearch(''), [activeCategory, source, group]);\n\n\t// Keep the latest rows/index reachable from the stable key handler.\n\tconst navRef = useRef({ rows, activeIndex, header });\n\tnavRef.current = { rows, activeIndex, header };\n\n\tuseEffect(() => {\n\t\tif (!registerKeyHandler) {\n\t\t\treturn;\n\t\t}\n\t\tregisterKeyHandler((event) => {\n\t\t\tconst { rows: r, activeIndex: i, header: h } = navRef.current;\n\t\t\tswitch (event.key) {\n\t\t\t\tcase 'ArrowDown':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowUp':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + r.length - 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowRight':\n\t\t\t\tcase 'Enter':\n\t\t\t\t\t// Nothing highlighted yet → treat the first row as the target so\n\t\t\t\t\t// the editor's @-flow (type, then Enter) still works.\n\t\t\t\t\t(r[i] ?? r[0])?.onActivate();\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowLeft':\n\t\t\t\t\tif (h?.onBack) {\n\t\t\t\t\t\th.onBack();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\treturn () => registerKeyHandler(null);\n\t}, [registerKeyHandler]);\n\n\tconst variant = !activeCategory\n\t\t? 'categories'\n\t\t: rows.length && !rows[0].drillsIn\n\t\t? 'items'\n\t\t: 'sources';\n\n\t// Search lives inside a source's tool list (Manifest / Shopify) and in the\n\t// sub-agent list.\n\tconst showSearch =\n\t\t(activeCategory === 'tool' && !!source) || activeCategory === 'subagent';\n\n\treturn (\n\t\t<PickerCard className={`bik-mention-picker bik-mention-picker--${variant}`}>\n\t\t\t{header && (\n\t\t\t\t<PickerBack\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={header.onBack}\n\t\t\t\t\tdisabled={!header.onBack}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackground: COLORS.surface.subdued,\n\t\t\t\t\t\tcursor: header.onBack ? 'pointer' : 'default',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{header.onBack && (\n\t\t\t\t\t\t<SvgArrowLeft\n\t\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\t\theight={20}\n\t\t\t\t\t\t\tcolor={COLORS.content.primary}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{header.icon && renderSourceIcon(header.icon)}\n\t\t\t\t\t<TitleSmall> {header.title}</TitleSmall>\n\t\t\t\t</PickerBack>\n\t\t\t)}\n\t\t\t{showSearch && (\n\t\t\t\t<PickerSearchRow>\n\t\t\t\t\t<SearchIcon\n\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\theight={20}\n\t\t\t\t\t\tcolor={COLORS.content.placeholder}\n\t\t\t\t\t/>\n\t\t\t\t\t<PickerSearchInput\n\t\t\t\t\t\t// Focus on open so the user can type immediately (appears only\n\t\t\t\t\t\t// after they drill into a source).\n\t\t\t\t\t\t// eslint-disable-next-line jsx-a11y/no-autofocus\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tplaceholder=\"Search\"\n\t\t\t\t\t\tdata-test=\"mention-picker-search\"\n\t\t\t\t\t\tonChange={(e) => setSearch(e.target.value)}\n\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\tif (!rows.length) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (e.key === 'ArrowDown') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'ArrowUp') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + rows.length - 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'Enter') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t(rows[activeIndex] ?? rows[0])?.onActivate();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</PickerSearchRow>\n\t\t\t)}\n\t\t\t{rows.length === 0 ? (\n\t\t\t\t<PickerEmpty>\n\t\t\t\t\t{activeCategory === 'subagent' ? null : 'No tools available'}\n\t\t\t\t</PickerEmpty>\n\t\t\t) : (\n\t\t\t\trows.map((row, i) => (\n\t\t\t\t\t<PickerRow\n\t\t\t\t\t\tkey={row.id}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t$active={i === activeIndex}\n\t\t\t\t\t\tonMouseEnter={() => setActiveIndex(i)}\n\t\t\t\t\t\tonMouseLeave={() => setActiveIndex(-1)}\n\t\t\t\t\t\tonClick={row.onActivate}\n\t\t\t\t\t>\n\t\t\t\t\t\t{row.isCreate ? (\n\t\t\t\t\t\t\t<CreateRowText>{row.label}</CreateRowText>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<PickerRowMain>\n\t\t\t\t\t\t\t\t\t{renderSourceIcon(row.icon)}\n\t\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t\t{row.label}\n\t\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t\t{row.authRequired && (\n\t\t\t\t\t\t\t\t\t\t<Shield\n\t\t\t\t\t\t\t\t\t\t\tsize={16}\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"This tool requires customer verification\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</PickerRowMain>\n\t\t\t\t\t\t\t\t{row.rightLabel ? (\n\t\t\t\t\t\t\t\t\t<RightActionText>{row.rightLabel}</RightActionText>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\trow.drillsIn && <ChevronRight width={12} height={12} />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</PickerRow>\n\t\t\t\t))\n\t\t\t)}\n\t\t\t{rows.some((row) => row.authRequired) && (\n\t\t\t\t<PickerLegend>\n\t\t\t\t\t<Shield size={16} />\n\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\tThis tool requires customer verification\n\t\t\t\t\t</BodyCaption>\n\t\t\t\t</PickerLegend>\n\t\t\t)}\n\t\t</PickerCard>\n\t);\n};\n\nconst PickerCard = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tmin-width: 240px;\n\tmax-height: 301px;\n\toverflow-y: auto;\n\tbackground: ${COLORS.surface.standard};\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tbox-shadow: 0px -2px 8px 0px #0000001f;\n`;\n\n// Search box at the top of a source's tool list (Manifest / Shopify).\nconst PickerSearchRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 10px 12px;\n\tflex-shrink: 0;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n`;\n\nconst PickerSearchInput = styled.input`\n\tflex: 1;\n\tmin-width: 0;\n\tborder: none;\n\toutline: none;\n\tbackground: transparent;\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tcolor: ${COLORS.content.primary};\n\n\t&::placeholder {\n\t\tcolor: ${COLORS.content.placeholder};\n\t}\n`;\n\nconst PickerRow = styled.button<{ $active?: boolean }>`\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n\tgap: 2px;\n\twidth: 100%;\n\tpadding: 8px 10px;\n\theight: 48px;\n\t/* The card is a flex column with a max-height; without these a long list\n\t compresses its rows below 48px (why only the short first step looked right)\n\t instead of scrolling. Pin the row so the card scrolls instead. */\n\tbox-sizing: border-box;\n\tflex-shrink: 0;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: ${(p) => (p.$active ? COLORS.surface.subdued : 'transparent')};\n\tcursor: pointer;\n\ttext-align: left;\n\n\t&:hover {\n\t\tbackground: ${COLORS.surface.hovered};\n\t}\n`;\n\n// Left cluster: leading source glyph + label (chevron stays right via PickerRow).\nconst PickerRowMain = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tmin-width: 0;\n`;\n\n// Footer legend, shown when the list holds any auth-required tool.\nconst PickerLegend = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 8px 12px;\n\tborder-top: 1px solid ${COLORS.stroke.primary};\n`;\n\n// Right-aligned brand action text (e.g. \"Connect\") in place of the chevron.\nconst RightActionText = styled.span`\n\tflex-shrink: 0;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n`;\n\n// \"Create new\" — centered brand text, no icon (matches the side-panel dropdown).\nconst CreateRowText = styled.div`\n\twidth: 100%;\n\ttext-align: center;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n`;\n\nconst PickerBack = styled.button`\n\tdisplay: flex;\n\talign-items: center;\n\tpadding: 12px 16px;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: transparent;\n\tcursor: pointer;\n\tfont-family: Inter;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\theight: 48px;\n\tbox-sizing: border-box;\n\tflex-shrink: 0;\n\tgap: 4px;\n`;\n\nconst PickerEmpty = styled.div`\n\tpadding: 12px 10px;\n\tfont-family: Inter;\n\tfont-size: 13px;\n\tcolor: ${COLORS.content.secondary};\n`;\n"],"names":["metaOf","item","rowLabel","CREATE_SUBAGENT_ID","MentionPicker","items","onSelect","registerKeyHandler","onClose","onCreateSubAgent","initialSource","toolActions","integrationStatus","onConnectIntegration","category","setCategory","useState","source","setSource","group","setGroup","activeIndex","setActiveIndex","search","setSearch","tools","useMemo","i","subAgents","sources","acc","t","s","actionBySource","a","availableCategories","CATEGORIES","c","soleCategory","activeCategory","header","toolSourceLabel","sourceIcon","rows","sq","leaves","actionOnly","combined","buildSourceRow","action","instances","icon","only","isIntegrationSource","b","toolSourceRank","topRows","INTEGRATIONS_RANK","x","q","isConfigTool","CONFIG_TOOL_SOURCES","useEffect","navRef","useRef","event","h","variant","showSearch","jsxs","PickerCard","PickerBack","COLORS","jsx","SvgArrowLeft","renderSourceIcon","TitleSmall","PickerSearchRow","SearchIcon","PickerSearchInput","p","PickerEmpty","row","PickerRow","CreateRowText","Fragment","PickerRowMain","BodySecondary","Shield","RightActionText","ChevronRight","PickerLegend","BodyCaption","styled"],"mappings":";;;;;;;;;;;;AA4BA,MAAMA,IAAS,CAACC,MACfA,EAAK,MAEAC,IAAW,CAACD,MACjBD,EAAOC,CAAI,GAAG,cAAcA,EAAK,OAuB5BE,KAAqB,2BAmCdC,KAA8C,CAAC;AAAA,EAC3D,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,SAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,aAAAC;AAAA,EACA,mBAAAC;AAAA,EACA,sBAAAC;AACD,MAAM;AACL,QAAM,CAACC,IAAUC,CAAW,IAAIC,EAA0B,IAAI,GACxD,CAACC,GAAQC,CAAS,IAAIF,EAAwBN,KAAiB,IAAI,GAGnE,CAACS,GAAOC,CAAQ,IAAIJ,EAAgC,IAAI,GAGxD,CAACK,GAAaC,CAAc,IAAIN,EAAS,EAAE,GAG3C,CAACO,GAAQC,CAAS,IAAIR,EAAS,EAAE,GAEjCS,IAAQC;AAAA,IACb,MAAMrB,EAAM,OAAO,CAACsB,MAAM3B,EAAO2B,CAAC,GAAG,SAAS,MAAM;AAAA,IACpD,CAACtB,CAAK;AAAA,EAAA,GAEDuB,IAAYF;AAAA,IACjB,MAAMrB,EAAM,OAAO,CAACsB,MAAM3B,EAAO2B,CAAC,GAAG,SAAS,UAAU;AAAA,IACxD,CAACtB,CAAK;AAAA,EAAA,GAEDwB,IAAUH,EAAQ,MAAM;AAC7B,UAAMI,IAAgB,CAAA;AACtB,WAAAL,EAAM,QAAQ,CAACM,MAAM;AACpB,YAAMC,IAAIhC,EAAO+B,CAAC,GAAG,UAAU;AAC/B,MAAKD,EAAI,SAASE,CAAC,KAClBF,EAAI,KAAKE,CAAC;AAAA,IAEZ,CAAC,GACMF;AAAA,EACR,GAAG,CAACL,CAAK,CAAC,GAIJQ,IAAiBP;AAAA,IACtB,MACC,IAAI;AAAA,OACFf,KAAe,CAAA,GAAI,IAAI,CAACuB,MAAM,CAACA,EAAE,QAAQA,CAAC,CAAC;AAAA,IAAA;AAAA,IAE9C,CAACvB,CAAW;AAAA,EAAA,GAOPwB,IAAsBT;AAAA,IAC3B,MACCU,GAAW;AAAA,MAAO,CAACC,MAClBA,EAAE,QAAQ,SACPZ,EAAM,SAAS,MAAMd,GAAa,UAAU,KAAK,IACjDiB,EAAU,SAAS,KAAK,CAAC,CAACnB;AAAA,IAAA;AAAA,IAE/B,CAACgB,EAAM,QAAQG,EAAU,QAAQnB,GAAkBE,GAAa,MAAM;AAAA,EAAA,GAEjE2B,IACLH,EAAoB,WAAW,IAAIA,EAAoB,CAAC,EAAE,MAAM,MAC3DI,IAAiBzB,MAAYwB,GAM7BE,IAIMD,IAETA,MAAmB;AAAA;AAAA,IAEnB;AAAA,MACA,OAAO;AAAA,MACP,QAAQD,IAAe,SAAY,MAAMvB,EAAY,IAAI;AAAA,IAAA;AAAA,MAEzDE,IACA;AAAA,IACA,OAAOwB,EAAgBxB,CAAM;AAAA;AAAA;AAAA;AAAA;AAAA,IAK7B,QAAQP,IAAgB,SAAY,MAAMQ,EAAU,IAAI;AAAA,IACxD,MAAMwB,EAAWzB,CAAM;AAAA,EAAA,IAEvBE,MAAU,iBACV,EAAE,OAAO,gBAAgB,QAAQ,MAAMC,EAAS,IAAI,EAAA;AAAA;AAAA;AAAA,IAGpD;AAAA,MACA,OAAO;AAAA,MACP,QAAQkB,IAAe,SAAY,MAAMvB,EAAY,IAAI;AAAA,IAAA;AAAA,MAvBzD,MA2BG4B,IAAyBjB,EAAQ,MAAM;AAC5C,QAAI,CAACa;AACJ,aAAOJ,EAAoB,IAAI,CAACE,OAAO;AAAA,QACtC,IAAIA,EAAE;AAAA,QACN,OAAOA,EAAE;AAAA,QACT,UAAU;AAAA,QACV,YAAY,MAAM;AACjB,UAAAtB,EAAYsB,EAAE,GAAG,GACjBnB,EAAU,IAAI,GACdE,EAAS,IAAI;AAAA,QACd;AAAA,MAAA,EACC;AAEH,QAAImB,MAAmB,YAAY;AAClC,YAAMK,IAAKrB,EAAO,KAAA,EAAO,YAAA,GACnBsB,IAA2BjB,EAC/B,OAAO,CAAC3B,MAAS,CAAC2C,KAAM1C,EAASD,CAAI,EAAE,YAAA,EAAc,SAAS2C,CAAE,CAAC,EACjE,IAAI,CAAC3C,OAAU;AAAA,QACf,IAAI,OAAOA,EAAK,EAAE;AAAA,QAClB,OAAOC,EAASD,CAAI;AAAA,QACpB,UAAU;AAAA,QACV,YAAY,MAAMK,EAASL,CAAI;AAAA,MAAA,EAC9B;AAEH,aAAIQ,KACHoC,EAAO,KAAK;AAAA,QACX,IAAI1C;AAAA,QACJ,OAAO;AAAA,QACP,UAAU;AAAA,QACV,UAAU;AAAA,QACV,YAAY,MAAM;AACjB,UAAAK,IAAA,GACAC,EAAA;AAAA,QACD;AAAA,MAAA,CACA,GAEKoC;AAAAA,IACR;AACA,QAAI,CAAC5B,GAAQ;AAIZ,YAAM6B,KAAcnC,KAAe,CAAA,GACjC,IAAI,CAACuB,MAAMA,EAAE,MAAM,EACnB,OAAO,CAACF,MAAM,CAACH,EAAQ,SAASG,CAAC,CAAC,GAC9Be,IAAW,CAAC,GAAGlB,GAAS,GAAGiB,CAAU,GAKrCE,IAAiB,CAAChB,MAA8B;AACrD,cAAMiB,IAAShB,EAAe,IAAID,CAAC;AASnC,aAHCiB,MAAW,SACRA,EAAO,YACPrC,IAAoBoB,CAAe,OACrB;AACjB,iBAAO;AAAA,YACN,IAAIA;AAAA,YACJ,OAAOS,EAAgBT,CAAC;AAAA,YACxB,UAAU;AAAA,YACV,MAAMU,EAAWV,CAAC,KAAKiB,GAAQ;AAAA,YAC/B,YAAY;AAAA,YACZ,YAAY,MAAM;AACjB,cAAAzC,IAAA,GACIyC,GAAQ,YACXA,EAAO,UAAA,IAEPpC,IAAuBmB,CAAe;AAAA,YAExC;AAAA,UAAA;AAQF,cAAMkB,IAAYzB,EAAM;AAAA,UACvB,CAACM,OAAO/B,EAAO+B,CAAC,GAAG,UAAU,aAAaC;AAAA,QAAA;AAE3C,YAAIkB,EAAU,UAAUD,IAAS,IAAI,OAAO,GAAG;AAC9C,gBAAME,IAAOT,EAAWV,CAAC,KAAKiB,GAAQ;AACtC,cAAIA;AACH,mBAAO;AAAA,cACN,IAAIjB;AAAA,cACJ,OAAOiB,EAAO;AAAA,cACd,UAAU;AAAA,cACV,MAAAE;AAAA,cACA,YAAY,MAAM;AACjB,gBAAA3C,IAAA,GACAyC,EAAO,SAAA;AAAA,cACR;AAAA,YAAA;AAGF,gBAAMG,IAAOF,EAAU,CAAC;AACxB,iBAAO;AAAA,YACN,IAAI,OAAOE,EAAK,EAAE;AAAA,YAClB,OAAOlD,EAASkD,CAAI;AAAA,YACpB,UAAU;AAAA,YACV,MAAAD;AAAA,YACA,cAAcnD,EAAOoD,CAAI,GAAG;AAAA,YAC5B,YAAY,MAAM9C,EAAS8C,CAAI;AAAA,UAAA;AAAA,QAEjC;AACA,eAAO;AAAA,UACN,IAAIpB;AAAA,UACJ,OAAOS,EAAgBT,CAAC;AAAA,UACxB,UAAU;AAAA,UACV,MAAMU,EAAWV,CAAC,KAAKiB,GAAQ;AAAA,UAC/B,YAAY,MAAM/B,EAAUc,CAAC;AAAA,QAAA;AAAA,MAE/B;AAGA,UAAIb,MAAU;AACb,eAAO4B,EACL,OAAOM,CAAmB,EAC1B,KAAK,CAACnB,GAAGoB,MAAMC,EAAerB,CAAC,IAAIqB,EAAeD,CAAC,CAAC,EACpD,IAAIN,CAAc;AAMrB,YAAMQ,IAAUT,EACd,OAAO,CAACf,MAAM,CAACqB,EAAoBrB,CAAC,CAAC,EACrC,IAAI,CAACA,OAAO,EAAE,MAAMuB,EAAevB,CAAC,GAAG,KAAKgB,EAAehB,CAAC,EAAA,EAAI;AAClE,aAAIe,EAAS,KAAKM,CAAmB,KACpCG,EAAQ,KAAK;AAAA,QACZ,MAAMC;AAAA,QACN,KAAK;AAAA,UACJ,IAAI;AAAA,UACJ,OAAO;AAAA,UACP,UAAU;AAAA,UACV,YAAY,MAAM;AACjB,YAAArC,EAAS,cAAc,GACvBF,EAAU,IAAI;AAAA,UACf;AAAA,QAAA;AAAA,MACD,CACA,GAEKsC,EAAQ,KAAK,CAACtB,GAAGoB,MAAMpB,EAAE,OAAOoB,EAAE,IAAI,EAAE,IAAI,CAACI,MAAMA,EAAE,GAAG;AAAA,IAChE;AACA,UAAMC,IAAIpC,EAAO,KAAA,EAAO,YAAA,GAClBsB,IAA2BpB,EAC/B,OAAO,CAACM,OAAO/B,EAAO+B,CAAC,GAAG,UAAU,aAAad,CAAM,EACvD,OAAO,CAACc,MAAM,CAAC4B,KAAKzD,EAAS6B,CAAC,EAAE,cAAc,SAAS4B,CAAC,CAAC,EACzD,IAAI,CAAC1D,OAAU;AAAA,MACf,IAAI,OAAOA,EAAK,EAAE;AAAA,MAClB,OAAOC,EAASD,CAAI;AAAA,MACpB,UAAU;AAAA,MACV,cAAcD,EAAOC,CAAI,GAAG;AAAA,MAC5B,YAAY,MAAMK,EAASL,CAAI;AAAA,IAAA,EAC9B,GAMGgD,IAAShB,EAAe,IAAIhB,CAAM;AACxC,QAAIgC,GAAQ;AACX,YAAMW,IAAe3C,KAAU4C;AAC/B,MAAAhB,EAAO,KAAK;AAAA,QACX,IAAI,UAAU5B,CAAM;AAAA,QACpB,OAAOgC,EAAO;AAAA,QACd,UAAU;AAAA,QACV,UAAU,CAACW;AAAA,QACX,YAAY,MAAM;AACjB,UAAApD,IAAA,GACAyC,EAAO,SAAA;AAAA,QACR;AAAA,MAAA,CACA;AAAA,IACF;AACA,WAAOJ;AAAA,EACR,GAAG;AAAA,IACFN;AAAA,IACAJ;AAAA,IACAlB;AAAA,IACAE;AAAA,IACAI;AAAA,IACAE;AAAA,IACAG;AAAA,IACAC;AAAA,IACAvB;AAAA,IACAE;AAAA,IACAC;AAAA,IACAE;AAAA,IACAsB;AAAA,IACArB;AAAA,IACAC;AAAA,EAAA,CACA;AAGD,EAAAiD;AAAA,IACC,MAAMxC,EAAe,EAAE;AAAA,IACvB,CAACiB,GAAgBtB,GAAQE,GAAOI,GAAQlB,CAAK;AAAA,EAAA,GAG9CyD,EAAU,MAAMtC,EAAU,EAAE,GAAG,CAACe,GAAgBtB,GAAQE,CAAK,CAAC;AAG9D,QAAM4C,IAASC,GAAO,EAAE,MAAArB,GAAM,aAAAtB,GAAa,QAAAmB,GAAQ;AACnD,EAAAuB,EAAO,UAAU,EAAE,MAAApB,GAAM,aAAAtB,GAAa,QAAAmB,EAAA,GAEtCsB,EAAU,MAAM;AACf,QAAKvD;AAGL,aAAAA,EAAmB,CAAC0D,MAAU;AAC7B,cAAM,EAAE,MAAM,GAAG,aAAatC,GAAG,QAAQuC,MAAMH,EAAO;AACtD,gBAAQE,EAAM,KAAA;AAAA,UACb,KAAK;AACJ,mBAAI,EAAE,UAAQ3C,EAAe,CAAC,OAAO,IAAI,KAAK,EAAE,MAAM,GAC/C;AAAA,UACR,KAAK;AACJ,mBAAI,EAAE,UAAQA,EAAe,CAAC,OAAO,IAAI,EAAE,SAAS,KAAK,EAAE,MAAM,GAC1D;AAAA,UACR,KAAK;AAAA,UACL,KAAK;AAGJ,oBAAC,EAAEK,CAAC,KAAK,EAAE,CAAC,IAAI,WAAA,GACT;AAAA,UACR,KAAK;AACJ,mBAAIuC,GAAG,UACNA,EAAE,OAAA,GACK,MAED;AAAA,UACR;AACC,mBAAO;AAAA,QAAA;AAAA,MAEV,CAAC,GACM,MAAM3D,EAAmB,IAAI;AAAA,EACrC,GAAG,CAACA,CAAkB,CAAC;AAEvB,QAAM4D,KAAW5B,IAEdI,EAAK,UAAU,CAACA,EAAK,CAAC,EAAE,WACxB,UACA,YAHA,cAOGyB,KACJ7B,MAAmB,UAAU,CAAC,CAACtB,KAAWsB,MAAmB;AAE/D,SACC,gBAAA8B,EAACC,IAAA,EAAW,WAAW,0CAA0CH,EAAO,IACtE,UAAA;AAAA,IAAA3B,KACA,gBAAA6B;AAAA,MAACE;AAAA,MAAA;AAAA,QACA,MAAK;AAAA,QACL,SAAS/B,EAAO;AAAA,QAChB,UAAU,CAACA,EAAO;AAAA,QAClB,OAAO;AAAA,UACN,YAAYgC,EAAO,QAAQ;AAAA,UAC3B,QAAQhC,EAAO,SAAS,YAAY;AAAA,QAAA;AAAA,QAGpC,UAAA;AAAA,UAAAA,EAAO,UACP,gBAAAiC;AAAA,YAACC;AAAA,YAAA;AAAA,cACA,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,OAAOF,EAAO,QAAQ;AAAA,YAAA;AAAA,UAAA;AAAA,UAGvBhC,EAAO,QAAQmC,EAAiBnC,EAAO,IAAI;AAAA,4BAC3CoC,IAAA,EAAW,UAAA;AAAA,YAAA;AAAA,YAAEpC,EAAO;AAAA,UAAA,EAAA,CAAM;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAG5B4B,wBACCS,IAAA,EACA,UAAA;AAAA,MAAA,gBAAAJ;AAAA,QAACK;AAAAA,QAAA;AAAA,UACA,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,OAAON,EAAO,QAAQ;AAAA,QAAA;AAAA,MAAA;AAAA,MAEvB,gBAAAC;AAAA,QAACM;AAAA,QAAA;AAAA,UAIA,WAAS;AAAA,UACT,OAAOxD;AAAA,UACP,aAAY;AAAA,UACZ,aAAU;AAAA,UACV,UAAU,CAAC,MAAMC,EAAU,EAAE,OAAO,KAAK;AAAA,UACzC,WAAW,CAAC,MAAM;AACjB,YAAKmB,EAAK,WAGN,EAAE,QAAQ,eACb,EAAE,eAAA,GACFrB,EAAe,CAAC0D,OAAOA,IAAI,KAAKrC,EAAK,MAAM,KACjC,EAAE,QAAQ,aACpB,EAAE,eAAA,GACFrB,EAAe,CAAC0D,OAAOA,IAAIrC,EAAK,SAAS,KAAKA,EAAK,MAAM,KAC/C,EAAE,QAAQ,YACpB,EAAE,eAAA,IACDA,EAAKtB,CAAW,KAAKsB,EAAK,CAAC,IAAI,WAAA;AAAA,UAElC;AAAA,QAAA;AAAA,MAAA;AAAA,IACD,GACD;AAAA,IAEAA,EAAK,WAAW,IAChB,gBAAA8B,EAACQ,MACC,UAAA1C,MAAmB,aAAa,OAAO,qBAAA,CACzC,IAEAI,EAAK,IAAI,CAACuC,GAAKvD,MACd,gBAAA8C;AAAA,MAACU;AAAA,MAAA;AAAA,QAEA,MAAK;AAAA,QACL,SAASxD,MAAMN;AAAA,QACf,cAAc,MAAMC,EAAeK,CAAC;AAAA,QACpC,cAAc,MAAML,EAAe,EAAE;AAAA,QACrC,SAAS4D,EAAI;AAAA,QAEZ,YAAI,WACJ,gBAAAT,EAACW,MAAe,UAAAF,EAAI,MAAA,CAAM,IAE1B,gBAAAb,EAAAgB,IAAA,EACC,UAAA;AAAA,UAAA,gBAAAhB,EAACiB,IAAA,EACC,UAAA;AAAA,YAAAX,EAAiBO,EAAI,IAAI;AAAA,8BACzBK,IAAA,EAAc,OAAOf,EAAO,QAAQ,SACnC,YAAI,OACN;AAAA,YACCU,EAAI,gBACJ,gBAAAT;AAAA,cAACe;AAAAA,cAAA;AAAA,gBACA,MAAM;AAAA,gBACN,cAAW;AAAA,cAAA;AAAA,YAAA;AAAA,UACZ,GAEF;AAAA,UACCN,EAAI,aACJ,gBAAAT,EAACgB,IAAA,EAAiB,YAAI,WAAA,CAAW,IAEjCP,EAAI,YAAY,gBAAAT,EAACiB,IAAA,EAAa,OAAO,IAAI,QAAQ,GAAA,CAAI;AAAA,QAAA,EAAA,CAEvD;AAAA,MAAA;AAAA,MA5BIR,EAAI;AAAA,IAAA,CA+BV;AAAA,IAEDvC,EAAK,KAAK,CAACuC,MAAQA,EAAI,YAAY,uBAClCS,IAAA,EACA,UAAA;AAAA,MAAA,gBAAAlB,EAACe,IAAA,EAAO,MAAM,GAAA,CAAI;AAAA,wBACjBI,IAAA,EAAY,OAAOpB,EAAO,QAAQ,WAAW,UAAA,2CAAA,CAE9C;AAAA,IAAA,EAAA,CACD;AAAA,EAAA,GAEF;AAEF,GAEMF,KAAauB,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAMXrB,EAAO,QAAQ,QAAQ;AAAA,qBACjBA,EAAO,OAAO,OAAO;AAAA;AAAA;AAAA,GAMpCK,KAAkBgB,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAMHrB,EAAO,OAAO,OAAO;AAAA,GAG3CO,KAAoBc,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAQvBrB,EAAO,QAAQ,OAAO;AAAA;AAAA;AAAA,WAGrBA,EAAO,QAAQ,WAAW;AAAA;AAAA,GAI/BW,KAAYU,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAcGrB,EAAO,OAAO,OAAO;AAAA,eAClC,CAACQ,MAAOA,EAAE,UAAUR,EAAO,QAAQ,UAAU,aAAc;AAAA;AAAA;AAAA;AAAA;AAAA,gBAK1DA,EAAO,QAAQ,OAAO;AAAA;AAAA,GAKhCc,KAAgBO,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA,GAQvBF,KAAeE,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA,yBAKHrB,EAAO,OAAO,OAAO;AAAA,GAIxCiB,KAAkBI,EAAO;AAAA;AAAA,UAErBrB,EAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,GAQxBY,KAAgBS,EAAO;AAAA;AAAA;AAAA,UAGnBrB,EAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA,GAMxBD,KAAasB,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA,4BAKErB,EAAO,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAY3CS,KAAcY,EAAO;AAAA;AAAA;AAAA;AAAA,UAIjBrB,EAAO,QAAQ,SAAS;AAAA;"}
1
+ {"version":3,"file":"MentionPicker.js","sources":["../../../../../src/components/agent-builder/components/MentionPicker.tsx"],"sourcesContent":["// import ChevronLeft from '@src/assets/icons/chevronLeft.svg';\nimport ChevronRight from '@src/assets/icons/chevronRight.svg';\nimport SearchIcon from '@src/assets/icons/searchIcon.svg';\nimport type { MentionDropdownRenderProps, MentionItem } from '@src/editor';\nimport { Shield } from '@src/icons';\nimport SvgArrowLeft from '@src/icons/Arrows/Normal arrows/ArrowLeft';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\nimport {\n\tBodyCaption,\n\tBodySecondary,\n\tTitleSmall,\n} from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport {\n\tCATEGORIES,\n\tCONFIG_TOOL_SOURCES,\n\tisIntegrationSource,\n\ttoolSourceRank,\n} from '../constants/tools';\nimport type { Category, ToolAction, ToolSource } from '../constants/tools';\nimport {\n\tMentionKindMeta,\n\ttoolSourceLabel,\n} from '../utils/mentionSerialization';\nimport { renderSourceIcon, sourceIcon, SourceIcon } from '../utils/sourceIcons';\n\nconst metaOf = (item: MentionItem): MentionKindMeta | undefined =>\n\titem.meta as unknown as MentionKindMeta | undefined;\n\nconst rowLabel = (item: MentionItem): string =>\n\tmetaOf(item)?.plainLabel ?? item.label;\n\n/** One navigable row in the picker's current view. */\ntype PickerRowModel = {\n\tid: string;\n\tlabel: string;\n\t/** Drill-in rows show a chevron; leaf (selectable) rows do not. */\n\tdrillsIn: boolean;\n\t/** Leading brand glyph (source rows only). */\n\ticon?: SourceIcon;\n\t/** Brand-coloured \"Create new\" action row (not a selectable item). */\n\tisCreate?: boolean;\n\t/**\n\t * Brand-coloured right-aligned action text (e.g. \"Connect\") shown in place of\n\t * the drill-in chevron — used for an unconnected integration source.\n\t */\n\trightLabel?: string;\n\t/** Tool leaf touches customer-private data → shows a shield glyph. */\n\tauthRequired?: boolean;\n\tonActivate: () => void;\n};\n\n/** Sentinel id for the sub-agent \"Create new\" row. */\nconst CREATE_SUBAGENT_ID = '__bik_create_subagent__';\n\ntype MentionPickerProps = MentionDropdownRenderProps & {\n\t/** Opens the create-sub-agent drawer (shows a \"Create new\" row in the Sub-agent view). */\n\tonCreateSubAgent?: () => void;\n\t/**\n\t * Open already drilled into this tool source (e.g. `'shopify'`) — its tool list\n\t * is shown immediately. */\n\tinitialSource?: string;\n\t/**\n\t * Built-in tool actions (Rest API / Handover to email) shown in the Tools view.\n\t * Picking one opens its config drawer (via `onSelect`) and dismisses the picker\n\t * — it never inserts a mention into the text.\n\t */\n\ttoolActions?: ToolAction[];\n\t/**\n\t * Per-source integration connection state. A source whose value is `false`\n\t * renders a \"Connect\" row (like an unconnected action) instead of drilling in —\n\t * so native source groups (Shopify / BigCommerce / ShipStation) show \"Connect\"\n\t * consistently with the config actions (Slack).\n\t */\n\tintegrationStatus?: Partial<Record<ToolSource, boolean>>;\n\t/** Open the connect flow for an unconnected source (used by the Connect row). */\n\tonConnectIntegration?: (source: ToolSource) => void;\n};\n\n/**\n * `@` reference picker. Drills:\n * root → Tools → <source> (Manifest / Shopify / …) → tool\n * → Sub-agent → sub-agent\n * (\"Add condition\" and \"Variables\" are intentionally not shown yet.)\n *\n * Owns keyboard navigation (↑/↓ move, →/Enter activate, ← go back) over the\n * CURRENTLY visible rows — registered with the editor via `registerKeyHandler`.\n */\nexport const MentionPicker: React.FC<MentionPickerProps> = ({\n\titems,\n\tonSelect,\n\tregisterKeyHandler,\n\tonClose,\n\tonCreateSubAgent,\n\tinitialSource,\n\ttoolActions,\n\tintegrationStatus,\n\tonConnectIntegration,\n}) => {\n\tconst [category, setCategory] = useState<Category | null>(null);\n\tconst [source, setSource] = useState<string | null>(initialSource ?? null);\n\t// -1 = nothing highlighted; rows highlight only on hover / arrow keys\n\t// (a default highlight reads as a stuck hover state).\n\tconst [activeIndex, setActiveIndex] = useState(-1);\n\t// Search box shown inside a source's tool list (Manifest / Shopify); filters\n\t// that source's tools by name.\n\tconst [search, setSearch] = useState('');\n\n\tconst tools = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'tool'),\n\t\t[items],\n\t);\n\tconst subAgents = useMemo(\n\t\t() => items.filter((i) => metaOf(i)?.kind === 'subagent'),\n\t\t[items],\n\t);\n\tconst sources = useMemo(() => {\n\t\tconst acc: string[] = [];\n\t\ttools.forEach((t) => {\n\t\t\tconst s = metaOf(t)?.source ?? 'other';\n\t\t\tif (!acc.includes(s)) {\n\t\t\t\tacc.push(s);\n\t\t\t}\n\t\t});\n\t\treturn acc;\n\t}, [tools]);\n\t// The built-in \"create\" action per source (Rest API / email / Slack). A source\n\t// with an action drills into [its instances + a \"Create new\" row] — like the\n\t// Sub-agent category — instead of showing a duplicate flat \"create\" row.\n\tconst actionBySource = useMemo(\n\t\t() =>\n\t\t\tnew Map<string, ToolAction>(\n\t\t\t\t(toolActions ?? []).map((a) => [a.source, a]),\n\t\t\t),\n\t\t[toolActions],\n\t);\n\n\t// Show a category when it has items — and ALWAYS show Sub-agent when creating\n\t// one is possible, so an agent with no sub-agents yet still gets the root\n\t// \"Tools / Sub-agent\" choice (with a \"Create new\" inside). When only one is\n\t// available (e.g. the sub-agent drawer offers tools only) the selector is skipped.\n\tconst availableCategories = useMemo(\n\t\t() =>\n\t\t\tCATEGORIES.filter((c) =>\n\t\t\t\tc.key === 'tool'\n\t\t\t\t\t? tools.length > 0 || (toolActions?.length ?? 0) > 0\n\t\t\t\t\t: subAgents.length > 0 || !!onCreateSubAgent,\n\t\t\t),\n\t\t[tools.length, subAgents.length, onCreateSubAgent, toolActions?.length],\n\t);\n\tconst soleCategory =\n\t\tavailableCategories.length === 1 ? availableCategories[0].key : null;\n\tconst activeCategory = category ?? soleCategory;\n\n\t// Title shown above the current view. `onBack` is omitted at a root level (a\n\t// sole category has nowhere to go back to) — the header then shows as a plain\n\t// title. When `onBack` is set the header leads with a back arrow, followed by\n\t// the source icon in a source detail view: `[← back][icon][title]`.\n\tconst header: {\n\t\ttitle: string;\n\t\tonBack?: () => void;\n\t\ticon?: SourceIcon;\n\t} | null = !activeCategory\n\t\t? null\n\t\t: activeCategory === 'subagent'\n\t\t? // Always titled — with a back arrow only when the category chooser is above.\n\t\t {\n\t\t\t\ttitle: 'Sub-agent',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t }\n\t\t: source\n\t\t? {\n\t\t\t\ttitle: toolSourceLabel(source),\n\t\t\t\t// Deep-linked to a source (opened from a right-panel source button):\n\t\t\t\t// that source IS the root, so no back arrow. Otherwise back clears the\n\t\t\t\t// source — returning to the source chooser.\n\t\t\t\tonBack: initialSource ? undefined : () => setSource(null),\n\t\t\t\ticon: sourceIcon(source),\n\t\t }\n\t\t: // Always titled — matches the Sub-agent header; back arrow only when the\n\t\t // category chooser is above (i.e. not the sole category).\n\t\t {\n\t\t\t\ttitle: 'Tools',\n\t\t\t\tonBack: soleCategory ? undefined : () => setCategory(null),\n\t\t };\n\n\t// Build the navigable rows for the current view.\n\tconst rows: PickerRowModel[] = useMemo(() => {\n\t\tif (!activeCategory) {\n\t\t\treturn availableCategories.map((c) => ({\n\t\t\t\tid: c.key,\n\t\t\t\tlabel: c.label,\n\t\t\t\tdrillsIn: true,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tsetCategory(c.key);\n\t\t\t\t\tsetSource(null);\n\t\t\t\t},\n\t\t\t}));\n\t\t}\n\t\tif (activeCategory === 'subagent') {\n\t\t\tconst sq = search.trim().toLowerCase();\n\t\t\tconst leaves: PickerRowModel[] = subAgents\n\t\t\t\t.filter((item) => !sq || rowLabel(item).toLowerCase().includes(sq))\n\t\t\t\t.map((item) => ({\n\t\t\t\t\tid: String(item.id),\n\t\t\t\t\tlabel: rowLabel(item),\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t\t}));\n\t\t\t// \"Create new\" opens the drawer — first dismiss the menu (strips the \"@\").\n\t\t\tif (onCreateSubAgent) {\n\t\t\t\tleaves.push({\n\t\t\t\t\tid: CREATE_SUBAGENT_ID,\n\t\t\t\t\tlabel: 'Create new',\n\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\tisCreate: true,\n\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\tonCreateSubAgent();\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn leaves;\n\t\t}\n\t\tif (!source) {\n\t\t\t// The real sources (from instances) plus any action source (Rest API /\n\t\t\t// email / Slack) with no instances yet, so it still appears for first-time\n\t\t\t// creation. Deduped — no more twin rows.\n\t\t\tconst actionOnly = (toolActions ?? [])\n\t\t\t\t.map((a) => a.source)\n\t\t\t\t.filter((s) => !sources.includes(s));\n\t\t\tconst combined = [...sources, ...actionOnly];\n\n\t\t\t// One row per source: Connect (unconnected) / a single collapsed leaf\n\t\t\t// (action sources) / a drill-in group (integrations + multi-tool sources).\n\t\t\tconst buildSourceRow = (s: string): PickerRowModel => {\n\t\t\t\tconst action = actionBySource.get(s);\n\t\t\t\t// Not connected → a \"Connect\" row (no drill-in / no instances / no\n\t\t\t\t// \"Create new\"); clicking dismisses the picker and runs the connect\n\t\t\t\t// flow. Applies to config actions (their own `connected`) AND native\n\t\t\t\t// source groups (via `integrationStatus`), so both look consistent.\n\t\t\t\tconst connected =\n\t\t\t\t\taction !== undefined\n\t\t\t\t\t\t? action.connected\n\t\t\t\t\t\t: integrationStatus?.[s as ToolSource];\n\t\t\t\tif (connected === false) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: s,\n\t\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\t\trightLabel: 'Connect',\n\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\tif (action?.onConnect) {\n\t\t\t\t\t\t\t\taction.onConnect();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tonConnectIntegration?.(s as ToolSource);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\t// A source whose drill-in view would hold exactly one leaf is normally\n\t\t\t\t// surfaced as that single leaf right here (its function name + the same\n\t\t\t\t// source icon). Covers \"no Rest API added yet\" (→ open the create modal\n\t\t\t\t// directly) and a config tool's single capability (Slack → \"Send Slack\n\t\t\t\t// message\", email → \"Send email\"). EXCEPTION: external integrations\n\t\t\t\t// (Shopify / BigCommerce / ShipStation / Skio / Gorgias) always stay a\n\t\t\t\t// drill-in group even with a single tool, so the vendor reads as its own\n\t\t\t\t// discoverable, connectable unit.\n\t\t\t\tconst instances = tools.filter(\n\t\t\t\t\t(t) => (metaOf(t)?.source ?? 'other') === s,\n\t\t\t\t);\n\t\t\t\tconst collapseSingleLeaf =\n\t\t\t\t\tinstances.length + (action ? 1 : 0) === 1 &&\n\t\t\t\t\t!(action === undefined && isIntegrationSource(s));\n\t\t\t\tif (collapseSingleLeaf) {\n\t\t\t\t\tconst icon = sourceIcon(s) ?? action?.icon;\n\t\t\t\t\tif (action) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tid: s,\n\t\t\t\t\t\t\tlabel: action.label,\n\t\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\t\ticon,\n\t\t\t\t\t\t\tonActivate: () => {\n\t\t\t\t\t\t\t\tonClose?.();\n\t\t\t\t\t\t\t\taction.onSelect();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tconst only = instances[0];\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: String(only.id),\n\t\t\t\t\t\tlabel: rowLabel(only),\n\t\t\t\t\t\tdrillsIn: false,\n\t\t\t\t\t\ticon,\n\t\t\t\t\t\tauthRequired: metaOf(only)?.authRequired,\n\t\t\t\t\t\tonActivate: () => onSelect(only),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tid: s,\n\t\t\t\t\tlabel: toolSourceLabel(s),\n\t\t\t\t\tdrillsIn: true,\n\t\t\t\t\ticon: sourceIcon(s) ?? action?.icon,\n\t\t\t\t\tonActivate: () => setSource(s),\n\t\t\t\t};\n\t\t\t};\n\n\t\t\t// Every source is its own top-level row (Manifest / Shopify / each\n\t\t\t// integration / the action sources), in fixed rank order so adding or\n\t\t\t// updating a tool never reshuffles the picker.\n\t\t\treturn combined\n\t\t\t\t.sort((a, b) => toolSourceRank(a) - toolSourceRank(b))\n\t\t\t\t.map(buildSourceRow);\n\t\t}\n\t\tconst q = search.trim().toLowerCase();\n\t\tconst leaves: PickerRowModel[] = tools\n\t\t\t.filter((t) => (metaOf(t)?.source ?? 'other') === source)\n\t\t\t.filter((t) => !q || rowLabel(t).toLowerCase().includes(q))\n\t\t\t.map((item) => ({\n\t\t\t\tid: String(item.id),\n\t\t\t\tlabel: rowLabel(item),\n\t\t\t\tdrillsIn: false,\n\t\t\t\tauthRequired: metaOf(item)?.authRequired,\n\t\t\t\tonActivate: () => onSelect(item),\n\t\t\t}));\n\t\t// A configurable source's add row, below any existing instances, opening\n\t\t// its drawer. Config tools (Slack / email) are a single fixed capability →\n\t\t// render like a normal tool leaf (label only, no icon — matching the tool\n\t\t// rows). Rest API instances are user-created, so its \"add\" stays a\n\t\t// brand-coloured create row.\n\t\tconst action = actionBySource.get(source);\n\t\tif (action) {\n\t\t\tconst isConfigTool = source in CONFIG_TOOL_SOURCES;\n\t\t\tleaves.push({\n\t\t\t\tid: `create:${source}`,\n\t\t\t\tlabel: action.label,\n\t\t\t\tdrillsIn: false,\n\t\t\t\tisCreate: !isConfigTool,\n\t\t\t\tonActivate: () => {\n\t\t\t\t\tonClose?.();\n\t\t\t\t\taction.onSelect();\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\treturn leaves;\n\t}, [\n\t\tactiveCategory,\n\t\tavailableCategories,\n\t\tsource,\n\t\tsearch,\n\t\ttools,\n\t\tsubAgents,\n\t\tsources,\n\t\tonSelect,\n\t\tonClose,\n\t\tonCreateSubAgent,\n\t\ttoolActions,\n\t\tactionBySource,\n\t\tintegrationStatus,\n\t\tonConnectIntegration,\n\t]);\n\n\t// Reset highlight whenever the view (or filtered result set) changes.\n\tuseEffect(() => setActiveIndex(-1), [activeCategory, source, search, items]);\n\t// Clear the search box when leaving a source view.\n\tuseEffect(() => setSearch(''), [activeCategory, source]);\n\n\t// Keep the latest rows/index reachable from the stable key handler.\n\tconst navRef = useRef({ rows, activeIndex, header });\n\tnavRef.current = { rows, activeIndex, header };\n\n\tuseEffect(() => {\n\t\tif (!registerKeyHandler) {\n\t\t\treturn;\n\t\t}\n\t\tregisterKeyHandler((event) => {\n\t\t\tconst { rows: r, activeIndex: i, header: h } = navRef.current;\n\t\t\tswitch (event.key) {\n\t\t\t\tcase 'ArrowDown':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowUp':\n\t\t\t\t\tif (r.length) setActiveIndex((p) => (p + r.length - 1) % r.length);\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowRight':\n\t\t\t\tcase 'Enter':\n\t\t\t\t\t// Nothing highlighted yet → treat the first row as the target so\n\t\t\t\t\t// the editor's @-flow (type, then Enter) still works.\n\t\t\t\t\t(r[i] ?? r[0])?.onActivate();\n\t\t\t\t\treturn true;\n\t\t\t\tcase 'ArrowLeft':\n\t\t\t\t\tif (h?.onBack) {\n\t\t\t\t\t\th.onBack();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\tdefault:\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\treturn () => registerKeyHandler(null);\n\t}, [registerKeyHandler]);\n\n\tconst variant = !activeCategory\n\t\t? 'categories'\n\t\t: rows.length && !rows[0].drillsIn\n\t\t? 'items'\n\t\t: 'sources';\n\n\t// Search lives inside a source's tool list (Manifest / Shopify) and in the\n\t// sub-agent list.\n\tconst showSearch =\n\t\t(activeCategory === 'tool' && !!source) || activeCategory === 'subagent';\n\n\treturn (\n\t\t<PickerCard className={`bik-mention-picker bik-mention-picker--${variant}`}>\n\t\t\t{header && (\n\t\t\t\t<PickerBack\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tonClick={header.onBack}\n\t\t\t\t\tdisabled={!header.onBack}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackground: COLORS.surface.subdued,\n\t\t\t\t\t\tcursor: header.onBack ? 'pointer' : 'default',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{header.onBack && (\n\t\t\t\t\t\t<SvgArrowLeft\n\t\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\t\theight={20}\n\t\t\t\t\t\t\tcolor={COLORS.content.primary}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{header.icon && renderSourceIcon(header.icon)}\n\t\t\t\t\t<TitleSmall> {header.title}</TitleSmall>\n\t\t\t\t</PickerBack>\n\t\t\t)}\n\t\t\t{showSearch && (\n\t\t\t\t<PickerSearchRow>\n\t\t\t\t\t<SearchIcon\n\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\theight={20}\n\t\t\t\t\t\tcolor={COLORS.content.placeholder}\n\t\t\t\t\t/>\n\t\t\t\t\t<PickerSearchInput\n\t\t\t\t\t\t// Focus on open so the user can type immediately (appears only\n\t\t\t\t\t\t// after they drill into a source).\n\t\t\t\t\t\t// eslint-disable-next-line jsx-a11y/no-autofocus\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tplaceholder=\"Search\"\n\t\t\t\t\t\tdata-test=\"mention-picker-search\"\n\t\t\t\t\t\tonChange={(e) => setSearch(e.target.value)}\n\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\tif (!rows.length) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (e.key === 'ArrowDown') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'ArrowUp') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tsetActiveIndex((p) => (p + rows.length - 1) % rows.length);\n\t\t\t\t\t\t\t} else if (e.key === 'Enter') {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t(rows[activeIndex] ?? rows[0])?.onActivate();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</PickerSearchRow>\n\t\t\t)}\n\t\t\t{rows.length === 0 ? (\n\t\t\t\t<PickerEmpty>\n\t\t\t\t\t{activeCategory === 'subagent' ? null : 'No tools available'}\n\t\t\t\t</PickerEmpty>\n\t\t\t) : (\n\t\t\t\trows.map((row, i) => (\n\t\t\t\t\t<PickerRow\n\t\t\t\t\t\tkey={row.id}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t$active={i === activeIndex}\n\t\t\t\t\t\tonMouseEnter={() => setActiveIndex(i)}\n\t\t\t\t\t\tonMouseLeave={() => setActiveIndex(-1)}\n\t\t\t\t\t\tonClick={row.onActivate}\n\t\t\t\t\t>\n\t\t\t\t\t\t{row.isCreate ? (\n\t\t\t\t\t\t\t<CreateRowText>{row.label}</CreateRowText>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<PickerRowMain>\n\t\t\t\t\t\t\t\t\t{renderSourceIcon(row.icon)}\n\t\t\t\t\t\t\t\t\t<BodySecondary color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\t\t\t{row.label}\n\t\t\t\t\t\t\t\t\t</BodySecondary>\n\t\t\t\t\t\t\t\t\t{row.authRequired && (\n\t\t\t\t\t\t\t\t\t\t<Shield\n\t\t\t\t\t\t\t\t\t\t\tsize={16}\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"This tool requires customer verification\"\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</PickerRowMain>\n\t\t\t\t\t\t\t\t{row.rightLabel ? (\n\t\t\t\t\t\t\t\t\t<RightActionText>{row.rightLabel}</RightActionText>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\trow.drillsIn && <ChevronRight width={12} height={12} />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</PickerRow>\n\t\t\t\t))\n\t\t\t)}\n\t\t\t{rows.some((row) => row.authRequired) && (\n\t\t\t\t<PickerLegend>\n\t\t\t\t\t<Shield size={16} />\n\t\t\t\t\t<BodyCaption color={COLORS.content.secondary}>\n\t\t\t\t\t\tThis tool requires customer verification\n\t\t\t\t\t</BodyCaption>\n\t\t\t\t</PickerLegend>\n\t\t\t)}\n\t\t</PickerCard>\n\t);\n};\n\nconst PickerCard = styled.div`\n\tdisplay: flex;\n\tflex-direction: column;\n\tmin-width: 240px;\n\tmax-height: 301px;\n\toverflow-y: auto;\n\tbackground: ${COLORS.surface.standard};\n\tborder: 1px solid ${COLORS.stroke.primary};\n\tborder-radius: 4px;\n\tbox-shadow: 0px -2px 8px 0px #0000001f;\n`;\n\n// Search box at the top of a source's tool list (Manifest / Shopify).\nconst PickerSearchRow = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 10px 12px;\n\tflex-shrink: 0;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n`;\n\nconst PickerSearchInput = styled.input`\n\tflex: 1;\n\tmin-width: 0;\n\tborder: none;\n\toutline: none;\n\tbackground: transparent;\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tcolor: ${COLORS.content.primary};\n\n\t&::placeholder {\n\t\tcolor: ${COLORS.content.placeholder};\n\t}\n`;\n\nconst PickerRow = styled.button<{ $active?: boolean }>`\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n\tgap: 2px;\n\twidth: 100%;\n\tpadding: 8px 10px;\n\theight: 48px;\n\t/* The card is a flex column with a max-height; without these a long list\n\t compresses its rows below 48px (why only the short first step looked right)\n\t instead of scrolling. Pin the row so the card scrolls instead. */\n\tbox-sizing: border-box;\n\tflex-shrink: 0;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: ${(p) => (p.$active ? COLORS.surface.subdued : 'transparent')};\n\tcursor: pointer;\n\ttext-align: left;\n\n\t&:hover {\n\t\tbackground: ${COLORS.surface.hovered};\n\t}\n`;\n\n// Left cluster: leading source glyph + label (chevron stays right via PickerRow).\nconst PickerRowMain = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tmin-width: 0;\n`;\n\n// Footer legend, shown when the list holds any auth-required tool.\nconst PickerLegend = styled.div`\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 8px 12px;\n\tborder-top: 1px solid ${COLORS.stroke.primary};\n`;\n\n// Right-aligned brand action text (e.g. \"Connect\") in place of the chevron.\nconst RightActionText = styled.span`\n\tflex-shrink: 0;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n`;\n\n// \"Create new\" — centered brand text, no icon (matches the side-panel dropdown).\nconst CreateRowText = styled.div`\n\twidth: 100%;\n\ttext-align: center;\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 14px;\n\tfont-weight: 600;\n`;\n\nconst PickerBack = styled.button`\n\tdisplay: flex;\n\talign-items: center;\n\tpadding: 12px 16px;\n\tborder: none;\n\tborder-bottom: 1px solid ${COLORS.stroke.primary};\n\tbackground: transparent;\n\tcursor: pointer;\n\tfont-family: Inter;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\theight: 48px;\n\tbox-sizing: border-box;\n\tflex-shrink: 0;\n\tgap: 4px;\n`;\n\nconst PickerEmpty = styled.div`\n\tpadding: 12px 10px;\n\tfont-family: Inter;\n\tfont-size: 13px;\n\tcolor: ${COLORS.content.secondary};\n`;\n"],"names":["metaOf","item","rowLabel","CREATE_SUBAGENT_ID","MentionPicker","items","onSelect","registerKeyHandler","onClose","onCreateSubAgent","initialSource","toolActions","integrationStatus","onConnectIntegration","category","setCategory","useState","source","setSource","activeIndex","setActiveIndex","search","setSearch","tools","useMemo","i","subAgents","sources","acc","t","s","actionBySource","a","availableCategories","CATEGORIES","c","soleCategory","activeCategory","header","toolSourceLabel","sourceIcon","rows","sq","leaves","actionOnly","combined","buildSourceRow","action","instances","isIntegrationSource","icon","only","b","toolSourceRank","q","isConfigTool","CONFIG_TOOL_SOURCES","useEffect","navRef","useRef","event","r","h","p","variant","showSearch","jsxs","PickerCard","PickerBack","COLORS","jsx","SvgArrowLeft","renderSourceIcon","TitleSmall","PickerSearchRow","SearchIcon","PickerSearchInput","PickerEmpty","row","PickerRow","CreateRowText","Fragment","PickerRowMain","BodySecondary","Shield","RightActionText","ChevronRight","PickerLegend","BodyCaption","styled"],"mappings":"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"}
@@ -99,14 +99,15 @@ export declare const TOOL_ACTION_SOURCES: ToolSource[];
99
99
  */
100
100
  export declare const TOOL_SOURCE_RANK: Partial<Record<ToolSource, number>>;
101
101
  /**
102
- * Sources consolidated under the picker's single "Integrations" drill-in row
103
- * (BigCommerce / ShipStation / Skio / Gorgias / Slack). Manifest, Shopify, Send
104
- * Email and REST API stay as their own top-level rows.
102
+ * External integration / vendor sources. Each renders as its OWN top-level
103
+ * drill-in group in the picker even when it has a single tool — so the vendor
104
+ * reads as its own discoverable, connectable unit (never collapsed to a lone
105
+ * leaf; see the single-leaf flatten in `MentionPicker`). Deliberately excludes
106
+ * `Manifest` (the built-in natives) and the config/rest action sources (Rest API
107
+ * / Email / Slack), whose single capability is surfaced flat.
105
108
  */
106
109
  export declare const INTEGRATION_SOURCES: ToolSource[];
107
- /** Rank of the synthetic "Integrations" top-level row (where BigCommerce sat). */
108
- export declare const INTEGRATIONS_RANK: number;
109
- /** True when a source belongs under the picker's "Integrations" group. */
110
+ /** True for an external integration/vendor source (never collapsed to a single leaf). */
110
111
  export declare const isIntegrationSource: (source: string) => boolean;
111
112
  /** Sort rank for a source string; unknown sources rank after all known ones. */
112
113
  export declare const toolSourceRank: (source: string) => number;
@@ -2,8 +2,8 @@ const o = [
2
2
  { key: "tool", label: "Tools" },
3
3
  { key: "subagent", label: "Sub-agent" }
4
4
  ];
5
- var a = /* @__PURE__ */ ((i) => (i.Manifest = "manifest", i.Shopify = "shopify", i.Bigcommerce = "bigcommerce", i.Shipstation = "shipstation", i.Skio = "skio", i.Gorgias = "gorgias", i.Integration = "integration", i.RestApi = "rest_api", i.EmailHandover = "email_handover", i.Slack = "slack", i))(a || {});
6
- const c = {
5
+ var s = /* @__PURE__ */ ((i) => (i.Manifest = "manifest", i.Shopify = "shopify", i.Bigcommerce = "bigcommerce", i.Shipstation = "shipstation", i.Skio = "skio", i.Gorgias = "gorgias", i.Integration = "integration", i.RestApi = "rest_api", i.EmailHandover = "email_handover", i.Slack = "slack", i))(s || {});
6
+ const _ = {
7
7
  manifest: "Manifest",
8
8
  shopify: "Shopify",
9
9
  bigcommerce: "BigCommerce",
@@ -14,7 +14,7 @@ const c = {
14
14
  rest_api: "Rest API",
15
15
  email_handover: "Email",
16
16
  slack: "Slack"
17
- }, _ = {
17
+ }, g = {
18
18
  rest_api: "REST API",
19
19
  email_handover: "Send email",
20
20
  slack: "Send Slack message"
@@ -23,41 +23,41 @@ const c = {
23
23
  "email_handover",
24
24
  "slack"
25
25
  /* Slack */
26
- ], s = {
26
+ ], a = {
27
27
  manifest: 0,
28
28
  shopify: 1,
29
- // Integration sources (2–6) are grouped under one "Integrations" row in the
30
- // picker; their rank orders them WITHIN that group.
29
+ // Each integration/vendor source is its OWN top-level row (BigCommerce
30
+ // Gorgias); rank orders them so adding/updating a tool never reshuffles them.
31
31
  bigcommerce: 2,
32
32
  shipstation: 3,
33
33
  skio: 4,
34
34
  gorgias: 5,
35
35
  slack: 6,
36
- // Send Email then REST API sit after the Integrations group at the top level.
36
+ // Send Email then REST API sit after the integration sources at the top level.
37
37
  email_handover: 7,
38
38
  rest_api: 8
39
39
  }, e = [
40
+ "shopify",
40
41
  "bigcommerce",
41
42
  "shipstation",
42
43
  "skio",
43
44
  "gorgias",
44
- "slack"
45
- /* Slack */
46
- ], g = s.bigcommerce, t = new Set(e), r = (i) => t.has(i), n = Object.keys(s).length, O = (i) => s[i] ?? n, S = {
45
+ "integration"
46
+ /* Integration */
47
+ ], t = new Set(e), r = (i) => t.has(i), n = Object.keys(a).length, c = (i) => a[i] ?? n, O = {
47
48
  email_handover: "send_email",
48
49
  slack: "send_slack_message"
49
50
  };
50
51
  export {
51
52
  o as CATEGORIES,
52
- S as CONFIG_TOOL_SOURCES,
53
- g as INTEGRATIONS_RANK,
53
+ O as CONFIG_TOOL_SOURCES,
54
54
  e as INTEGRATION_SOURCES,
55
- _ as TOOL_ACTION_LABELS,
55
+ g as TOOL_ACTION_LABELS,
56
56
  m as TOOL_ACTION_SOURCES,
57
- c as TOOL_SOURCE_LABELS,
58
- s as TOOL_SOURCE_RANK,
59
- a as ToolSource,
57
+ _ as TOOL_SOURCE_LABELS,
58
+ a as TOOL_SOURCE_RANK,
59
+ s as ToolSource,
60
60
  r as isIntegrationSource,
61
- O as toolSourceRank
61
+ c as toolSourceRank
62
62
  };
63
63
  //# sourceMappingURL=tools.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sources":["../../../../../src/components/agent-builder/constants/tools.ts"],"sourcesContent":["import type { ToolSource as ModelToolSource } from '@bikdotai/bik-models/ai-agents/models/agent-tool';\nimport type { FunctionComponent, SVGAttributes } from 'react';\n\n/**\n * Static tool-related constants for the builder's Step 3 (tools & sub-agents):\n * the reference-picker category tabs and the per-source display labels. Kept here\n * (rather than inline in the picker / serialization utils) so the labels a user\n * sees are all in one obvious place.\n */\n\n/** A reference-picker category tab. */\nexport type Category = 'tool' | 'subagent';\n\n/** Category tabs shown at the root of the `@` reference picker. */\nexport const CATEGORIES: { key: Category; label: string }[] = [\n\t{ key: 'tool', label: 'Tools' },\n\t{ key: 'subagent', label: 'Sub-agent' },\n];\n\n/**\n * Every tool \"source\" the builder renders an icon / label / picker entry for.\n * Enum VALUES are the backend's canonical read-only `source` wire strings\n * (`app/agents/config/schema.py` → `ToolSource`, derived from `tool_key`): the\n * configurable tools are `email_handover` / `rest_api` / `slack`, every native\n * tool is `manifest`. `shopify` / `integration` are legacy bik-models sources\n * kept for back-compat (the backend now collapses natives to `manifest`).\n * Dynamic/unknown sources are looked up leniently — see `toolSourceLabel` and\n * `sourceIcon`.\n *\n * This is the RUNTIME mirror of the canonical `@bikdotai/bik-models` `ToolSource`\n * union (the shape the backend persists as `AgentToolDoc.source`). We keep an\n * enum — not a re-export of the type — because the members are needed at runtime\n * for labels, ranks, icons and `===` comparisons; a type-only union can't do\n * that. The two are kept in lock-step by {@link ToolSourceMatchesBikModels}\n * below, which fails to compile if they ever drift.\n */\nexport enum ToolSource {\n\tManifest = 'manifest',\n\tShopify = 'shopify',\n\tBigcommerce = 'bigcommerce',\n\tShipstation = 'shipstation',\n\tSkio = 'skio',\n\tGorgias = 'gorgias',\n\tIntegration = 'integration',\n\tRestApi = 'rest_api',\n\tEmailHandover = 'email_handover',\n\tSlack = 'slack',\n}\n\n/**\n * Compile-time guard that {@link ToolSource} stays a faithful mirror of the\n * canonical `@bikdotai/bik-models` `ToolSource` union. If a source is added to\n * (or removed from) either side without the other, `AssertTrue` receives `false`\n * and this type stops compiling — so the runtime enum can never silently diverge\n * from what the backend persists as `AgentToolDoc.source`. The tuple wrappers\n * (`[…]`) stop the conditionals from distributing over the unions, so it checks\n * set-equality in both directions.\n *\n * Type-only (erased at build): a drift shows up as a compile error on\n * `ToolSourceMatchesBikModels` telling you to reconcile this enum with\n * `@bikdotai/bik-models` (bump the dep and/or the enum).\n */\ntype AssertTrue<T extends true> = T;\ntype ToolSourceMatchesBikModels = AssertTrue<\n\t[`${ToolSource}`] extends [ModelToolSource]\n\t\t? [ModelToolSource] extends [`${ToolSource}`]\n\t\t\t? true\n\t\t\t: false\n\t\t: false\n>;\n\n/**\n * Display labels for the known tool sources — the CATEGORY/integration name, used\n * for the picker's source headers (drill-in groups), the empty-state source\n * buttons and the mention-chip prefix. A source is a category (\"Slack\") you drill\n * into; the specific addable action inside it (\"Send Slack message\") is\n * `TOOL_ACTION_LABELS`. Unknown sources fall back to the raw key (see\n * `toolSourceLabel`).\n */\nexport const TOOL_SOURCE_LABELS: Record<ToolSource, string> = {\n\t[ToolSource.Manifest]: 'Manifest',\n\t[ToolSource.Shopify]: 'Shopify',\n\t[ToolSource.Bigcommerce]: 'BigCommerce',\n\t[ToolSource.Shipstation]: 'ShipStation',\n\t[ToolSource.Skio]: 'Skio',\n\t[ToolSource.Gorgias]: 'Gorgias',\n\t[ToolSource.Integration]: 'Integration',\n\t[ToolSource.RestApi]: 'Rest API',\n\t[ToolSource.EmailHandover]: 'Email',\n\t[ToolSource.Slack]: 'Slack',\n};\n\n/**\n * The addable action inside a configurable/rest source — shown as the \"add\" row\n * in the `@` picker (below any existing instances) and the empty-state button.\n * Distinct from `TOOL_SOURCE_LABELS`, which names the category the action lives in\n * (e.g. category \"Slack\" → action \"Send Slack message\").\n */\nexport const TOOL_ACTION_LABELS: Partial<Record<ToolSource, string>> = {\n\t[ToolSource.RestApi]: 'REST API',\n\t[ToolSource.EmailHandover]: 'Send email',\n\t[ToolSource.Slack]: 'Send Slack message',\n};\n\n/** A tool source's brand-glyph component. */\nexport type IconComp = FunctionComponent<SVGAttributes<SVGElement>>;\n\n/** Brand glyph for a tool source, with its own size so each keeps its aspect ratio. */\nexport interface SourceIcon {\n\tIcon: IconComp;\n\tw: number;\n\th: number;\n}\n\n/**\n * A built-in \"tool\" that opens a config drawer (Rest API / email handover /\n * Slack) rather than inserting a mention. Surfaced as an empty-state source\n * button in the Tools section and as a row in the `@`-picker Tools view; picking\n * it opens the drawer and never writes into the instructions text.\n */\nexport interface ToolAction {\n\tsource: ToolSource;\n\tlabel: string;\n\ticon?: SourceIcon;\n\t/** Open this tool's config drawer. */\n\tonSelect: () => void;\n\t/**\n\t * Integration connection state for this source. `undefined` = no connection\n\t * gating (default). `false` = the store hasn't connected this integration →\n\t * the `@` picker shows a \"Connect\" row that calls {@link onConnect} instead of\n\t * drilling in / offering \"Create new\". `true` = connected (renders normally).\n\t * Set by the consumer via `config.integrationStatus` (today: Slack only).\n\t */\n\tconnected?: boolean;\n\t/** Open the parent's connect flow for this source (used when `connected === false`). */\n\tonConnect?: () => void;\n}\n\n/** Sources of the built-in drawer tools, in display order. */\nexport const TOOL_ACTION_SOURCES: ToolSource[] = [\n\tToolSource.RestApi,\n\tToolSource.EmailHandover,\n\tToolSource.Slack,\n];\n\n/**\n * Fixed display rank for the `@`-picker's tool-source groups (lower = higher). The\n * picker sorts its source rows by this so adding/updating a tool never reshuffles\n * them. Manifest (the native tools) leads; any source not listed here\n * (dynamic/unknown, e.g. Integration) sorts AFTER Slack, keeping its discovery\n * order among the rest (Array.sort is stable).\n */\nexport const TOOL_SOURCE_RANK: Partial<Record<ToolSource, number>> = {\n\t[ToolSource.Manifest]: 0,\n\t[ToolSource.Shopify]: 1,\n\t// Integration sources (2–6) are grouped under one \"Integrations\" row in the\n\t// picker; their rank orders them WITHIN that group.\n\t[ToolSource.Bigcommerce]: 2,\n\t[ToolSource.Shipstation]: 3,\n\t[ToolSource.Skio]: 4,\n\t[ToolSource.Gorgias]: 5,\n\t[ToolSource.Slack]: 6,\n\t// Send Email then REST API sit after the Integrations group at the top level.\n\t[ToolSource.EmailHandover]: 7,\n\t[ToolSource.RestApi]: 8,\n};\n\n/**\n * Sources consolidated under the picker's single \"Integrations\" drill-in row\n * (BigCommerce / ShipStation / Skio / Gorgias / Slack). Manifest, Shopify, Send\n * Email and REST API stay as their own top-level rows.\n */\nexport const INTEGRATION_SOURCES: ToolSource[] = [\n\tToolSource.Bigcommerce,\n\tToolSource.Shipstation,\n\tToolSource.Skio,\n\tToolSource.Gorgias,\n\tToolSource.Slack,\n];\n\n/** Rank of the synthetic \"Integrations\" top-level row (where BigCommerce sat). */\nexport const INTEGRATIONS_RANK = TOOL_SOURCE_RANK[ToolSource.Bigcommerce] ?? 2;\n\nconst INTEGRATION_SOURCE_SET = new Set<string>(INTEGRATION_SOURCES);\n\n/** True when a source belongs under the picker's \"Integrations\" group. */\nexport const isIntegrationSource = (source: string): boolean =>\n\tINTEGRATION_SOURCE_SET.has(source);\n\nconst UNRANKED_SOURCE_RANK = Object.keys(TOOL_SOURCE_RANK).length;\n\n/** Sort rank for a source string; unknown sources rank after all known ones. */\nexport const toolSourceRank = (source: string): number =>\n\tTOOL_SOURCE_RANK[source as ToolSource] ?? UNRANKED_SOURCE_RANK;\n\n/**\n * `tool_key` of a configurable shared-drawer tool (email / Slack). Lives here (not\n * in AgentBuilder.model) so this leaf constants file has no back-edge to the model\n * — the dependency stays one-way (model → constants), avoiding a circular import.\n */\nexport type ConfigToolKey = 'send_email' | 'send_slack_message';\n\n/**\n * Drawer sources rendered by the shared dynamic panel (`ConfigToolPanel`), each\n * mapped to its backend `tool_key`. Rest API is absent — it has a bespoke panel.\n */\nexport const CONFIG_TOOL_SOURCES: Partial<Record<ToolSource, ConfigToolKey>> = {\n\t[ToolSource.EmailHandover]: 'send_email',\n\t[ToolSource.Slack]: 'send_slack_message',\n};\n"],"names":["CATEGORIES","ToolSource","TOOL_SOURCE_LABELS","TOOL_ACTION_LABELS","TOOL_ACTION_SOURCES","TOOL_SOURCE_RANK","INTEGRATION_SOURCES","INTEGRATIONS_RANK","INTEGRATION_SOURCE_SET","isIntegrationSource","source","UNRANKED_SOURCE_RANK","toolSourceRank","CONFIG_TOOL_SOURCES"],"mappings":"AAcO,MAAMA,IAAiD;AAAA,EAC7D,EAAE,KAAK,QAAQ,OAAO,QAAA;AAAA,EACtB,EAAE,KAAK,YAAY,OAAO,YAAA;AAC3B;AAmBO,IAAKC,sBAAAA,OACXA,EAAA,WAAW,YACXA,EAAA,UAAU,WACVA,EAAA,cAAc,eACdA,EAAA,cAAc,eACdA,EAAA,OAAO,QACPA,EAAA,UAAU,WACVA,EAAA,cAAc,eACdA,EAAA,UAAU,YACVA,EAAA,gBAAgB,kBAChBA,EAAA,QAAQ,SAVGA,IAAAA,KAAA,CAAA,CAAA;AA2CL,MAAMC,IAAiD;AAAA,EAC5D,UAAsB;AAAA,EACtB,SAAqB;AAAA,EACrB,aAAyB;AAAA,EACzB,aAAyB;AAAA,EACzB,MAAkB;AAAA,EAClB,SAAqB;AAAA,EACrB,aAAyB;AAAA,EACzB,UAAqB;AAAA,EACrB,gBAA2B;AAAA,EAC3B,OAAmB;AACrB,GAQaC,IAA0D;AAAA,EACrE,UAAqB;AAAA,EACrB,gBAA2B;AAAA,EAC3B,OAAmB;AACrB,GAqCaC,IAAoC;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA;AACD,GASaC,IAAwD;AAAA,EACnE,UAAsB;AAAA,EACtB,SAAqB;AAAA;AAAA;AAAA,EAGrB,aAAyB;AAAA,EACzB,aAAyB;AAAA,EACzB,MAAkB;AAAA,EAClB,SAAqB;AAAA,EACrB,OAAmB;AAAA;AAAA,EAEnB,gBAA2B;AAAA,EAC3B,UAAqB;AACvB,GAOaC,IAAoC;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AACD,GAGaC,IAAoBF,EAAiB,aAE5CG,IAAyB,IAAI,IAAYF,CAAmB,GAGrDG,IAAsB,CAACC,MACnCF,EAAuB,IAAIE,CAAM,GAE5BC,IAAuB,OAAO,KAAKN,CAAgB,EAAE,QAG9CO,IAAiB,CAACF,MAC9BL,EAAiBK,CAAoB,KAAKC,GAa9BE,IAAkE;AAAA,EAC7E,gBAA2B;AAAA,EAC3B,OAAmB;AACrB;"}
1
+ {"version":3,"file":"tools.js","sources":["../../../../../src/components/agent-builder/constants/tools.ts"],"sourcesContent":["import type { ToolSource as ModelToolSource } from '@bikdotai/bik-models/ai-agents/models/agent-tool';\nimport type { FunctionComponent, SVGAttributes } from 'react';\n\n/**\n * Static tool-related constants for the builder's Step 3 (tools & sub-agents):\n * the reference-picker category tabs and the per-source display labels. Kept here\n * (rather than inline in the picker / serialization utils) so the labels a user\n * sees are all in one obvious place.\n */\n\n/** A reference-picker category tab. */\nexport type Category = 'tool' | 'subagent';\n\n/** Category tabs shown at the root of the `@` reference picker. */\nexport const CATEGORIES: { key: Category; label: string }[] = [\n\t{ key: 'tool', label: 'Tools' },\n\t{ key: 'subagent', label: 'Sub-agent' },\n];\n\n/**\n * Every tool \"source\" the builder renders an icon / label / picker entry for.\n * Enum VALUES are the backend's canonical read-only `source` wire strings\n * (`app/agents/config/schema.py` → `ToolSource`, derived from `tool_key`): the\n * configurable tools are `email_handover` / `rest_api` / `slack`, every native\n * tool is `manifest`. `shopify` / `integration` are legacy bik-models sources\n * kept for back-compat (the backend now collapses natives to `manifest`).\n * Dynamic/unknown sources are looked up leniently — see `toolSourceLabel` and\n * `sourceIcon`.\n *\n * This is the RUNTIME mirror of the canonical `@bikdotai/bik-models` `ToolSource`\n * union (the shape the backend persists as `AgentToolDoc.source`). We keep an\n * enum — not a re-export of the type — because the members are needed at runtime\n * for labels, ranks, icons and `===` comparisons; a type-only union can't do\n * that. The two are kept in lock-step by {@link ToolSourceMatchesBikModels}\n * below, which fails to compile if they ever drift.\n */\nexport enum ToolSource {\n\tManifest = 'manifest',\n\tShopify = 'shopify',\n\tBigcommerce = 'bigcommerce',\n\tShipstation = 'shipstation',\n\tSkio = 'skio',\n\tGorgias = 'gorgias',\n\tIntegration = 'integration',\n\tRestApi = 'rest_api',\n\tEmailHandover = 'email_handover',\n\tSlack = 'slack',\n}\n\n/**\n * Compile-time guard that {@link ToolSource} stays a faithful mirror of the\n * canonical `@bikdotai/bik-models` `ToolSource` union. If a source is added to\n * (or removed from) either side without the other, `AssertTrue` receives `false`\n * and this type stops compiling — so the runtime enum can never silently diverge\n * from what the backend persists as `AgentToolDoc.source`. The tuple wrappers\n * (`[…]`) stop the conditionals from distributing over the unions, so it checks\n * set-equality in both directions.\n *\n * Type-only (erased at build): a drift shows up as a compile error on\n * `ToolSourceMatchesBikModels` telling you to reconcile this enum with\n * `@bikdotai/bik-models` (bump the dep and/or the enum).\n */\ntype AssertTrue<T extends true> = T;\ntype ToolSourceMatchesBikModels = AssertTrue<\n\t[`${ToolSource}`] extends [ModelToolSource]\n\t\t? [ModelToolSource] extends [`${ToolSource}`]\n\t\t\t? true\n\t\t\t: false\n\t\t: false\n>;\n\n/**\n * Display labels for the known tool sources — the CATEGORY/integration name, used\n * for the picker's source headers (drill-in groups), the empty-state source\n * buttons and the mention-chip prefix. A source is a category (\"Slack\") you drill\n * into; the specific addable action inside it (\"Send Slack message\") is\n * `TOOL_ACTION_LABELS`. Unknown sources fall back to the raw key (see\n * `toolSourceLabel`).\n */\nexport const TOOL_SOURCE_LABELS: Record<ToolSource, string> = {\n\t[ToolSource.Manifest]: 'Manifest',\n\t[ToolSource.Shopify]: 'Shopify',\n\t[ToolSource.Bigcommerce]: 'BigCommerce',\n\t[ToolSource.Shipstation]: 'ShipStation',\n\t[ToolSource.Skio]: 'Skio',\n\t[ToolSource.Gorgias]: 'Gorgias',\n\t[ToolSource.Integration]: 'Integration',\n\t[ToolSource.RestApi]: 'Rest API',\n\t[ToolSource.EmailHandover]: 'Email',\n\t[ToolSource.Slack]: 'Slack',\n};\n\n/**\n * The addable action inside a configurable/rest source — shown as the \"add\" row\n * in the `@` picker (below any existing instances) and the empty-state button.\n * Distinct from `TOOL_SOURCE_LABELS`, which names the category the action lives in\n * (e.g. category \"Slack\" → action \"Send Slack message\").\n */\nexport const TOOL_ACTION_LABELS: Partial<Record<ToolSource, string>> = {\n\t[ToolSource.RestApi]: 'REST API',\n\t[ToolSource.EmailHandover]: 'Send email',\n\t[ToolSource.Slack]: 'Send Slack message',\n};\n\n/** A tool source's brand-glyph component. */\nexport type IconComp = FunctionComponent<SVGAttributes<SVGElement>>;\n\n/** Brand glyph for a tool source, with its own size so each keeps its aspect ratio. */\nexport interface SourceIcon {\n\tIcon: IconComp;\n\tw: number;\n\th: number;\n}\n\n/**\n * A built-in \"tool\" that opens a config drawer (Rest API / email handover /\n * Slack) rather than inserting a mention. Surfaced as an empty-state source\n * button in the Tools section and as a row in the `@`-picker Tools view; picking\n * it opens the drawer and never writes into the instructions text.\n */\nexport interface ToolAction {\n\tsource: ToolSource;\n\tlabel: string;\n\ticon?: SourceIcon;\n\t/** Open this tool's config drawer. */\n\tonSelect: () => void;\n\t/**\n\t * Integration connection state for this source. `undefined` = no connection\n\t * gating (default). `false` = the store hasn't connected this integration →\n\t * the `@` picker shows a \"Connect\" row that calls {@link onConnect} instead of\n\t * drilling in / offering \"Create new\". `true` = connected (renders normally).\n\t * Set by the consumer via `config.integrationStatus` (today: Slack only).\n\t */\n\tconnected?: boolean;\n\t/** Open the parent's connect flow for this source (used when `connected === false`). */\n\tonConnect?: () => void;\n}\n\n/** Sources of the built-in drawer tools, in display order. */\nexport const TOOL_ACTION_SOURCES: ToolSource[] = [\n\tToolSource.RestApi,\n\tToolSource.EmailHandover,\n\tToolSource.Slack,\n];\n\n/**\n * Fixed display rank for the `@`-picker's tool-source groups (lower = higher). The\n * picker sorts its source rows by this so adding/updating a tool never reshuffles\n * them. Manifest (the native tools) leads; any source not listed here\n * (dynamic/unknown, e.g. Integration) sorts AFTER Slack, keeping its discovery\n * order among the rest (Array.sort is stable).\n */\nexport const TOOL_SOURCE_RANK: Partial<Record<ToolSource, number>> = {\n\t[ToolSource.Manifest]: 0,\n\t[ToolSource.Shopify]: 1,\n\t// Each integration/vendor source is its OWN top-level row (BigCommerce →\n\t// Gorgias); rank orders them so adding/updating a tool never reshuffles them.\n\t[ToolSource.Bigcommerce]: 2,\n\t[ToolSource.Shipstation]: 3,\n\t[ToolSource.Skio]: 4,\n\t[ToolSource.Gorgias]: 5,\n\t[ToolSource.Slack]: 6,\n\t// Send Email then REST API sit after the integration sources at the top level.\n\t[ToolSource.EmailHandover]: 7,\n\t[ToolSource.RestApi]: 8,\n};\n\n/**\n * External integration / vendor sources. Each renders as its OWN top-level\n * drill-in group in the picker — even when it has a single tool — so the vendor\n * reads as its own discoverable, connectable unit (never collapsed to a lone\n * leaf; see the single-leaf flatten in `MentionPicker`). Deliberately excludes\n * `Manifest` (the built-in natives) and the config/rest action sources (Rest API\n * / Email / Slack), whose single capability is surfaced flat.\n */\nexport const INTEGRATION_SOURCES: ToolSource[] = [\n\tToolSource.Shopify,\n\tToolSource.Bigcommerce,\n\tToolSource.Shipstation,\n\tToolSource.Skio,\n\tToolSource.Gorgias,\n\tToolSource.Integration,\n];\n\nconst INTEGRATION_SOURCE_SET = new Set<string>(INTEGRATION_SOURCES);\n\n/** True for an external integration/vendor source (never collapsed to a single leaf). */\nexport const isIntegrationSource = (source: string): boolean =>\n\tINTEGRATION_SOURCE_SET.has(source);\n\nconst UNRANKED_SOURCE_RANK = Object.keys(TOOL_SOURCE_RANK).length;\n\n/** Sort rank for a source string; unknown sources rank after all known ones. */\nexport const toolSourceRank = (source: string): number =>\n\tTOOL_SOURCE_RANK[source as ToolSource] ?? UNRANKED_SOURCE_RANK;\n\n/**\n * `tool_key` of a configurable shared-drawer tool (email / Slack). Lives here (not\n * in AgentBuilder.model) so this leaf constants file has no back-edge to the model\n * — the dependency stays one-way (model → constants), avoiding a circular import.\n */\nexport type ConfigToolKey = 'send_email' | 'send_slack_message';\n\n/**\n * Drawer sources rendered by the shared dynamic panel (`ConfigToolPanel`), each\n * mapped to its backend `tool_key`. Rest API is absent — it has a bespoke panel.\n */\nexport const CONFIG_TOOL_SOURCES: Partial<Record<ToolSource, ConfigToolKey>> = {\n\t[ToolSource.EmailHandover]: 'send_email',\n\t[ToolSource.Slack]: 'send_slack_message',\n};\n"],"names":["CATEGORIES","ToolSource","TOOL_SOURCE_LABELS","TOOL_ACTION_LABELS","TOOL_ACTION_SOURCES","TOOL_SOURCE_RANK","INTEGRATION_SOURCES","INTEGRATION_SOURCE_SET","isIntegrationSource","source","UNRANKED_SOURCE_RANK","toolSourceRank","CONFIG_TOOL_SOURCES"],"mappings":"AAcO,MAAMA,IAAiD;AAAA,EAC7D,EAAE,KAAK,QAAQ,OAAO,QAAA;AAAA,EACtB,EAAE,KAAK,YAAY,OAAO,YAAA;AAC3B;AAmBO,IAAKC,sBAAAA,OACXA,EAAA,WAAW,YACXA,EAAA,UAAU,WACVA,EAAA,cAAc,eACdA,EAAA,cAAc,eACdA,EAAA,OAAO,QACPA,EAAA,UAAU,WACVA,EAAA,cAAc,eACdA,EAAA,UAAU,YACVA,EAAA,gBAAgB,kBAChBA,EAAA,QAAQ,SAVGA,IAAAA,KAAA,CAAA,CAAA;AA2CL,MAAMC,IAAiD;AAAA,EAC5D,UAAsB;AAAA,EACtB,SAAqB;AAAA,EACrB,aAAyB;AAAA,EACzB,aAAyB;AAAA,EACzB,MAAkB;AAAA,EAClB,SAAqB;AAAA,EACrB,aAAyB;AAAA,EACzB,UAAqB;AAAA,EACrB,gBAA2B;AAAA,EAC3B,OAAmB;AACrB,GAQaC,IAA0D;AAAA,EACrE,UAAqB;AAAA,EACrB,gBAA2B;AAAA,EAC3B,OAAmB;AACrB,GAqCaC,IAAoC;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA;AACD,GASaC,IAAwD;AAAA,EACnE,UAAsB;AAAA,EACtB,SAAqB;AAAA;AAAA;AAAA,EAGrB,aAAyB;AAAA,EACzB,aAAyB;AAAA,EACzB,MAAkB;AAAA,EAClB,SAAqB;AAAA,EACrB,OAAmB;AAAA;AAAA,EAEnB,gBAA2B;AAAA,EAC3B,UAAqB;AACvB,GAUaC,IAAoC;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AACD,GAEMC,IAAyB,IAAI,IAAYD,CAAmB,GAGrDE,IAAsB,CAACC,MACnCF,EAAuB,IAAIE,CAAM,GAE5BC,IAAuB,OAAO,KAAKL,CAAgB,EAAE,QAG9CM,IAAiB,CAACF,MAC9BJ,EAAiBI,CAAoB,KAAKC,GAa9BE,IAAkE;AAAA,EAC7E,gBAA2B;AAAA,EAC3B,OAAmB;AACrB;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bikdotai/bik-component-library",
3
- "version": "0.0.850",
3
+ "version": "0.0.851",
4
4
  "description": "Bik Component Library",
5
5
  "repository": {
6
6
  "type": "git",