@bikdotai/bik-component-library 0.0.821-beta.8 → 0.0.821

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/cjs/assets/icons/Shopify.svg.js +2 -0
  2. package/dist/cjs/assets/icons/Shopify.svg.js.map +1 -0
  3. package/dist/cjs/components/agent-builder/AgentBuilder.js +1 -1
  4. package/dist/cjs/components/agent-builder/AgentBuilder.js.map +1 -1
  5. package/dist/cjs/components/agent-builder/AgentBuilder.styled.js +57 -23
  6. package/dist/cjs/components/agent-builder/AgentBuilder.styled.js.map +1 -1
  7. package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js +1 -1
  8. package/dist/cjs/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
  9. package/dist/cjs/components/agent-builder/components/GoLiveModal.js.map +1 -1
  10. package/dist/cjs/components/agent-builder/components/MentionEditor.js +1 -1
  11. package/dist/cjs/components/agent-builder/components/MentionEditor.js.map +1 -1
  12. package/dist/cjs/components/agent-builder/components/MentionField.js +1 -1
  13. package/dist/cjs/components/agent-builder/components/MentionField.js.map +1 -1
  14. package/dist/cjs/components/agent-builder/components/MentionPicker.js +37 -6
  15. package/dist/cjs/components/agent-builder/components/MentionPicker.js.map +1 -1
  16. package/dist/cjs/components/agent-builder/components/SelectableListSection.js +1 -1
  17. package/dist/cjs/components/agent-builder/components/SelectableListSection.js.map +1 -1
  18. package/dist/cjs/components/agent-builder/constants/charLimits.js +1 -1
  19. package/dist/cjs/components/agent-builder/constants/charLimits.js.map +1 -1
  20. package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js +1 -1
  21. package/dist/cjs/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
  22. package/dist/cjs/components/agent-builder/steps/Step2WhenItStepsIn.js +1 -1
  23. package/dist/cjs/components/agent-builder/steps/Step2WhenItStepsIn.js.map +1 -1
  24. package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js +1 -1
  25. package/dist/cjs/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
  26. package/dist/cjs/components/agent-builder/utils/mentionSerialization.js +1 -1
  27. package/dist/cjs/components/agent-builder/utils/mentionSerialization.js.map +1 -1
  28. package/dist/cjs/components/agent-builder/utils/sourceIcons.js +2 -0
  29. package/dist/cjs/components/agent-builder/utils/sourceIcons.js.map +1 -0
  30. package/dist/cjs/components/agent-listing/AgentListing.js +1 -1
  31. package/dist/cjs/components/agent-listing/AgentListing.js.map +1 -1
  32. package/dist/cjs/components/agent-listing/AgentListingFilters.js +1 -1
  33. package/dist/cjs/components/agent-listing/AgentListingFilters.js.map +1 -1
  34. package/dist/cjs/editor/BikEditor.types.js.map +1 -1
  35. package/dist/cjs/editor/extensions/mention/MentionDropdown.js +1 -1
  36. package/dist/cjs/editor/extensions/mention/MentionDropdown.js.map +1 -1
  37. package/dist/cjs/editor/extensions/mention/MentionExtension.js +1 -1
  38. package/dist/cjs/editor/extensions/mention/MentionExtension.js.map +1 -1
  39. package/dist/esm/assets/icons/Shopify.svg.js +6 -0
  40. package/dist/esm/assets/icons/Shopify.svg.js.map +1 -0
  41. package/dist/esm/components/agent-builder/AgentBuilder.js +47 -47
  42. package/dist/esm/components/agent-builder/AgentBuilder.js.map +1 -1
  43. package/dist/esm/components/agent-builder/AgentBuilder.model.d.ts +1 -1
  44. package/dist/esm/components/agent-builder/AgentBuilder.styled.d.ts +6 -0
  45. package/dist/esm/components/agent-builder/AgentBuilder.styled.js +82 -42
  46. package/dist/esm/components/agent-builder/AgentBuilder.styled.js.map +1 -1
  47. package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js +84 -76
  48. package/dist/esm/components/agent-builder/components/CreateSubAgentPanel.js.map +1 -1
  49. package/dist/esm/components/agent-builder/components/GoLiveModal.js.map +1 -1
  50. package/dist/esm/components/agent-builder/components/MentionEditor.d.ts +6 -0
  51. package/dist/esm/components/agent-builder/components/MentionEditor.js +31 -30
  52. package/dist/esm/components/agent-builder/components/MentionEditor.js.map +1 -1
  53. package/dist/esm/components/agent-builder/components/MentionField.js +40 -37
  54. package/dist/esm/components/agent-builder/components/MentionField.js.map +1 -1
  55. package/dist/esm/components/agent-builder/components/MentionPicker.d.ts +6 -1
  56. package/dist/esm/components/agent-builder/components/MentionPicker.js +202 -101
  57. package/dist/esm/components/agent-builder/components/MentionPicker.js.map +1 -1
  58. package/dist/esm/components/agent-builder/components/SelectableListSection.d.ts +18 -2
  59. package/dist/esm/components/agent-builder/components/SelectableListSection.js +159 -91
  60. package/dist/esm/components/agent-builder/components/SelectableListSection.js.map +1 -1
  61. package/dist/esm/components/agent-builder/constants/charLimits.d.ts +1 -1
  62. package/dist/esm/components/agent-builder/constants/charLimits.js +1 -1
  63. package/dist/esm/components/agent-builder/constants/charLimits.js.map +1 -1
  64. package/dist/esm/components/agent-builder/context/AgentBuilderContext.d.ts +7 -0
  65. package/dist/esm/components/agent-builder/context/AgentBuilderContext.js +107 -99
  66. package/dist/esm/components/agent-builder/context/AgentBuilderContext.js.map +1 -1
  67. package/dist/esm/components/agent-builder/steps/Step2WhenItStepsIn.js +7 -7
  68. package/dist/esm/components/agent-builder/steps/Step2WhenItStepsIn.js.map +1 -1
  69. package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js +131 -106
  70. package/dist/esm/components/agent-builder/steps/Step3HowItResponds.js.map +1 -1
  71. package/dist/esm/components/agent-builder/utils/mentionSerialization.js +2 -2
  72. package/dist/esm/components/agent-builder/utils/mentionSerialization.js.map +1 -1
  73. package/dist/esm/components/agent-builder/utils/sourceIcons.d.ts +10 -0
  74. package/dist/esm/components/agent-builder/utils/sourceIcons.js +10 -0
  75. package/dist/esm/components/agent-builder/utils/sourceIcons.js.map +1 -0
  76. package/dist/esm/components/agent-listing/AgentListing.js +108 -101
  77. package/dist/esm/components/agent-listing/AgentListing.js.map +1 -1
  78. package/dist/esm/components/agent-listing/AgentListing.model.d.ts +8 -0
  79. package/dist/esm/components/agent-listing/AgentListingFilters.d.ts +2 -0
  80. package/dist/esm/components/agent-listing/AgentListingFilters.js +37 -33
  81. package/dist/esm/components/agent-listing/AgentListingFilters.js.map +1 -1
  82. package/dist/esm/editor/BikEditor.types.d.ts +7 -0
  83. package/dist/esm/editor/BikEditor.types.js.map +1 -1
  84. package/dist/esm/editor/extensions/mention/MentionDropdown.d.ts +2 -0
  85. package/dist/esm/editor/extensions/mention/MentionDropdown.js +21 -20
  86. package/dist/esm/editor/extensions/mention/MentionDropdown.js.map +1 -1
  87. package/dist/esm/editor/extensions/mention/MentionExtension.js +66 -55
  88. package/dist/esm/editor/extensions/mention/MentionExtension.js.map +1 -1
  89. package/package.json +2 -2
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),o=require("react"),A=require("../../TypographyStyle.js"),x=require("../../../constants/Theme.js"),b=require("../AgentBuilder.styled.js"),D=require("../components/CreateSubAgentPanel.js"),T=require("../components/MentionField.js"),C=require("../components/SelectableListSection.js"),K=require("../components/StepSectionHeader.js"),I=require("../constants/charLimits.js"),z=require("../constants/steps.js"),U=require("../context/AgentBuilderContext.js"),W=require("../utils/mentionSerialization.js"),$=require("../../dropdown/Dropdown.js"),j=z.STEP_DEFINITIONS[2],J=()=>{const{value:s,patch:i,updateField:q,removeReference:v,availableTools:S,availableSubAgents:O,availableModels:m,applicationType:w,insertMention:r,onCreateSubAgent:c,onFetchSubAgent:u,onUpdateSubAgent:h,onImproveSubAgent:R}=U.useAgentBuilderContext(),[l,d]=o.useState(null),g=o.useRef(0),[L,y]=o.useState([]),p=new Map;O.forEach(e=>p.set(e.id,e)),L.forEach(e=>p.set(e.id,e));const M=Array.from(p.values()),k=o.useCallback(()=>{g.current+=1,d({key:g.current,title:"Create sub-agent"})},[]),H=o.useCallback(async e=>{if(!u)return;const t=await u(e);g.current+=1,d({key:g.current,title:"Edit sub-agent",editingId:e,initial:t})},[u]),N=o.useCallback(async e=>{if(l?.editingId){if(h){const t=await h(l.editingId,e);y(a=>[...a.filter(G=>G.id!==t.id),t])}}else if(c){const t=await c(e);y(a=>[...a,t]),i({subagents:[...s.subagents,t.id]}),r("subagent",t.id,`sub-agent: ${t.name}`)}d(null)},[l,h,c,i,s.subagents,r]),P=s.tools.map(e=>{const t=S.find(a=>a.tool_id===e);return t?{id:e,label:t.displayName}:null}).filter(e=>e!==null),E=S.map(e=>({label:e.displayName,value:e.tool_id,subText:e.description})),_=s.subagents.map(e=>{const t=p.get(e);return t?{id:e,label:t.name}:null}).filter(e=>e!==null),F=M.map(e=>({label:e.name,value:e.id})),B=m.map(e=>({label:e.label,value:e.value,selected:e.value===s.model})),f=m.find(e=>e.value===s.model);return n.jsxs("div",{className:"bik-agent-step bik-agent-step--response",children:[n.jsx(K.StepSectionHeader,{title:j.title,helper:j.helper}),n.jsxs(b.Step3Grid,{children:[n.jsxs(b.Step3Main,{children:[n.jsx(T.MentionField,{fieldKey:"instructions","data-test":"agent-instructions",label:"Instructions",maxLength:I.AGENT_CHAR_LIMITS.instructions,placeholder:"Write what this agent should do. Type @ to reference a tool or sub-agent.",minHeight:"200px"}),n.jsx(T.MentionField,{fieldKey:"guardrail","data-test":"agent-guardrail",label:"Guardrails",maxLength:I.AGENT_CHAR_LIMITS.guardrail,placeholder:"Things this agent must never do. Type @ to reference a tool or sub-agent.",minHeight:"140px"})]}),n.jsxs(b.Step3Side,{children:[n.jsx(C.SelectableListSection,{title:"Tools",helper:"Actions this agent can take while responding.",dataTestPrefix:"agent-tools",items:P,addableOptions:E,emptyText:"No tools added yet.",onAdd:e=>{r("tool",e),s.tools.includes(e)||i({tools:[...s.tools,e]})},onRemove:e=>v("tool",e)}),n.jsx(C.SelectableListSection,{title:"Sub-agents",helper:"Other agents this agent can hand off the conversation to.",dataTestPrefix:"agent-subagents",items:_,addableOptions:F,emptyText:"No sub-agents added yet.",onAdd:e=>{r("subagent",e),s.subagents.includes(e)||i({subagents:[...s.subagents,e]})},onRemove:e=>v("subagent",e),onConfigure:u?H:void 0,createOption:c?{label:"Create new",onSelect:k}:void 0}),m.length>0&&n.jsxs(b.SideSection,{children:[n.jsx(A.TitleSmall,{color:x.COLORS.content.primary,children:"Advanced settings"}),n.jsx(A.TitleSmall,{color:x.COLORS.content.secondary,children:"Select AI model"}),n.jsx($.Dropdown,{"data-test":"agent-model",size:"small",width:"100%",placeHolder:"Select model",options:B,defaultOptions:f?[{label:f.label,value:f.value}]:void 0,onSelect:e=>{const a=(Array.isArray(e)?e[0]:e)?.value;a&&q("model",a)}})]})]})]}),l&&n.jsx(D.CreateSubAgentPanel,{title:l.title,initial:l.initial,availableTools:S,appLabel:W.appTypeLabel(w),onImprove:R,onClose:()=>d(null),onSave:N},l.key)]})};exports.Step3HowItResponds=J;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),l=require("react"),I=require("../../TypographyStyle.js"),T=require("../../../constants/Theme.js"),m=require("../AgentBuilder.styled.js"),$=require("../components/CreateSubAgentPanel.js"),O=require("../components/MentionField.js"),j=require("../components/SelectableListSection.js"),J=require("../components/StepSectionHeader.js"),w=require("../constants/charLimits.js"),Q=require("../constants/steps.js"),V=require("../context/AgentBuilderContext.js"),R=require("../utils/mentionSerialization.js"),E=require("../utils/sourceIcons.js"),X=require("../../dropdown/Dropdown.js"),Y=t=>t&&typeof t=="object"&&"default"in t?t:{default:t},Z=Y(l),ee=t=>{const a=E.SOURCE_ICONS[t];return a?Z.default.createElement(a.Icon,{width:a.w,height:a.h}):void 0},q=t=>({label:t.display_name,value:t.tool_id,leadingIcon:ee(t.source??"manifest")}),_=Q.STEP_DEFINITIONS[2],te=()=>{const{value:t,patch:a,updateField:L,removeReference:x,availableTools:u,availableSubAgents:M,availableModels:h,applicationType:k,insertMention:d,onCreateSubAgent:r,onFetchSubAgent:p,onUpdateSubAgent:f,onImproveSubAgent:H,registerSubAgentCreator:y}=V.useAgentBuilderContext(),[i,g]=l.useState(null),b=l.useRef(0),[N,C]=l.useState([]),S=new Map;M.forEach(e=>S.set(e.id,e)),N.forEach(e=>S.set(e.id,e));const P=Array.from(S.values()),v=l.useCallback(()=>{b.current+=1,g({key:b.current,title:"Create sub-agent"})},[]);l.useEffect(()=>{if(r)return y(v),()=>y(null)},[y,v,r]);const F=l.useCallback(async e=>{if(!p)return;const n=await p(e);b.current+=1,g({key:b.current,title:"Edit sub-agent",editingId:e,initial:n})},[p]),G=l.useCallback(async e=>{if(i?.editingId){if(f){const n=await f(i.editingId,e);C(o=>[...o.filter(c=>c.id!==n.id),n])}}else if(r){const n=await r(e);C(o=>[...o,n]),a({subagents:[...t.subagents,n.id]}),d("subagent",n.id,`sub-agent: ${n.name}`)}g(null)},[i,f,r,a,t.subagents,d]),B=t.tools.map(e=>{const n=u.find(o=>o.tool_id===e);return n?{id:e,label:n.display_name,icon:E.SOURCE_ICONS[n.source??"manifest"]}:null}).filter(e=>e!==null),D=u.map(q),K=(()=>{const e=[],n=new Map;return u.forEach(o=>{const c=o.source??"manifest";n.has(c)||(n.set(c,[]),e.push(c)),n.get(c)?.push(q(o))}),e.map(o=>({source:o,label:R.toolSourceLabel(o),options:n.get(o)??[]}))})(),U=t.subagents.map(e=>{const n=S.get(e);return n?{id:e,label:n.name}:null}).filter(e=>e!==null),z=P.map(e=>({label:e.name,value:e.id})),W=h.map(e=>({label:e.label,value:e.value,selected:e.value===t.model})),A=h.find(e=>e.value===t.model);return s.jsxs("div",{className:"bik-agent-step bik-agent-step--response",children:[s.jsx(J.StepSectionHeader,{title:_.title,helper:_.helper}),s.jsxs(m.Step3Grid,{children:[s.jsxs(m.Step3Main,{children:[s.jsx(O.MentionField,{fieldKey:"instructions","data-test":"agent-instructions",label:"Instructions",maxLength:w.AGENT_CHAR_LIMITS.instructions,placeholder:"Write what this agent should do. Type @ to reference a tool or sub-agent.",minHeight:"200px"}),s.jsx(O.MentionField,{fieldKey:"guardrail","data-test":"agent-guardrail",label:"Guardrails",maxLength:w.AGENT_CHAR_LIMITS.guardrail,placeholder:"Things this agent must never do. Type @ to reference a tool or sub-agent.",minHeight:"140px"})]}),s.jsxs(m.Step3Side,{children:[s.jsx(j.SelectableListSection,{title:"Tools",helper:"Actions this agent can take while responding.",dataTestPrefix:"agent-tools",items:B,addableOptions:D,sourceGroups:K,emptyText:"No tools added yet.",onAdd:e=>{d("tool",e),t.tools.includes(e)||a({tools:[...t.tools,e]})},onRemove:e=>x("tool",e)}),s.jsx(j.SelectableListSection,{title:"Sub-agents",helper:"Other agents this agent can hand off the conversation to.",dataTestPrefix:"agent-subagents",items:U,addableOptions:z,emptyText:"No sub-agents added yet.",onAdd:e=>{d("subagent",e),t.subagents.includes(e)||a({subagents:[...t.subagents,e]})},onRemove:e=>x("subagent",e),onConfigure:p?F:void 0,createOption:r?{label:"Create new",onSelect:v}:void 0}),h.length>0&&s.jsxs(m.SideSection,{children:[s.jsx(I.TitleSmall,{color:T.COLORS.content.primary,children:"Advanced settings"}),s.jsx(I.TitleSmall,{color:T.COLORS.content.secondary,children:"Select AI model"}),s.jsx(X.Dropdown,{"data-test":"agent-model",size:"small",width:"100%",placeHolder:"Select model",options:W,defaultOptions:A?[{label:A.label,value:A.value}]:void 0,onSelect:e=>{const o=(Array.isArray(e)?e[0]:e)?.value;o&&L("model",o)}})]})]})]}),i&&s.jsx($.CreateSubAgentPanel,{title:i.title,initial:i.initial,availableTools:u,appLabel:R.appTypeLabel(k),onImprove:H,onClose:()=>g(null),onSave:G},i.key)]})};exports.Step3HowItResponds=te;
2
2
  //# sourceMappingURL=Step3HowItResponds.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Step3HowItResponds.js","sources":["../../../../../src/components/agent-builder/steps/Step3HowItResponds.tsx"],"sourcesContent":["import React, { useCallback, useRef, useState } from 'react';\nimport { Dropdown } from '@src/components/dropdown';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport { SubAgentDraft, SubAgentRef } from '../AgentBuilder.model';\nimport {\n\tSideSection,\n\tStep3Grid,\n\tStep3Main,\n\tStep3Side,\n} from '../AgentBuilder.styled';\nimport { CreateSubAgentPanel } from '../components/CreateSubAgentPanel';\nimport { MentionField } from '../components/MentionField';\nimport {\n\tSelectableItem,\n\tSelectableListSection,\n} from '../components/SelectableListSection';\nimport { StepSectionHeader } from '../components/StepSectionHeader';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport { STEP_DEFINITIONS } from '../constants/steps';\nimport { useAgentBuilderContext } from '../context/AgentBuilderContext';\nimport { appTypeLabel } from '../utils/mentionSerialization';\n\nconst STEP = STEP_DEFINITIONS[2];\n\n/** Drawer state — null when closed; `key` remounts it fresh per open. */\ninterface SubAgentPanelState {\n\tkey: number;\n\ttitle: string;\n\teditingId?: string;\n\tinitial?: SubAgentDraft;\n}\n\nexport const Step3HowItResponds: React.FC = () => {\n\tconst {\n\t\tvalue,\n\t\tpatch,\n\t\tupdateField,\n\t\tremoveReference,\n\t\tavailableTools,\n\t\tavailableSubAgents,\n\t\tavailableModels,\n\t\tapplicationType,\n\t\tinsertMention,\n\t\tonCreateSubAgent,\n\t\tonFetchSubAgent,\n\t\tonUpdateSubAgent,\n\t\tonImproveSubAgent,\n\t} = useAgentBuilderContext();\n\n\tconst [panel, setPanel] = useState<SubAgentPanelState | null>(null);\n\tconst panelKeyRef = useRef(0);\n\t// Sub-agents created / edited in this session, so a chip resolves (and reflects\n\t// a renamed sub-agent) before the consumer refreshes `availableSubAgents`.\n\tconst [createdSubAgents, setCreatedSubAgents] = useState<SubAgentRef[]>([]);\n\t// Created/edited refs take precedence over the consumer-supplied list.\n\tconst subAgentById = new Map<string, SubAgentRef>();\n\tavailableSubAgents.forEach((s) => subAgentById.set(s.id, s));\n\tcreatedSubAgents.forEach((s) => subAgentById.set(s.id, s));\n\tconst knownSubAgents = Array.from(subAgentById.values());\n\n\tconst openCreate = useCallback(() => {\n\t\tpanelKeyRef.current += 1;\n\t\tsetPanel({ key: panelKeyRef.current, title: 'Create sub-agent' });\n\t}, []);\n\n\tconst openConfigure = useCallback(\n\t\tasync (id: string) => {\n\t\t\tif (!onFetchSubAgent) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst data = await onFetchSubAgent(id);\n\t\t\tpanelKeyRef.current += 1;\n\t\t\tsetPanel({\n\t\t\t\tkey: panelKeyRef.current,\n\t\t\t\ttitle: 'Edit sub-agent',\n\t\t\t\teditingId: id,\n\t\t\t\tinitial: data,\n\t\t\t});\n\t\t},\n\t\t[onFetchSubAgent],\n\t);\n\n\tconst handlePanelSave = useCallback(\n\t\tasync (draft: SubAgentDraft) => {\n\t\t\tif (panel?.editingId) {\n\t\t\t\tif (onUpdateSubAgent) {\n\t\t\t\t\tconst ref = await onUpdateSubAgent(panel.editingId, draft);\n\t\t\t\t\tsetCreatedSubAgents((prev) => [\n\t\t\t\t\t\t...prev.filter((s) => s.id !== ref.id),\n\t\t\t\t\t\tref,\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t} else if (onCreateSubAgent) {\n\t\t\t\tconst ref = await onCreateSubAgent(draft);\n\t\t\t\tsetCreatedSubAgents((prev) => [...prev, ref]);\n\t\t\t\tpatch({ subagents: [...value.subagents, ref.id] });\n\t\t\t\tinsertMention('subagent', ref.id, `sub-agent: ${ref.name}`);\n\t\t\t}\n\t\t\tsetPanel(null);\n\t\t},\n\t\t[\n\t\t\tpanel,\n\t\t\tonUpdateSubAgent,\n\t\t\tonCreateSubAgent,\n\t\t\tpatch,\n\t\t\tvalue.subagents,\n\t\t\tinsertMention,\n\t\t],\n\t);\n\n\tconst toolItems: SelectableItem[] = value.tools\n\t\t.map((id): SelectableItem | null => {\n\t\t\tconst tool = availableTools.find((t) => t.tool_id === id);\n\t\t\treturn tool ? { id, label: tool.displayName } : null;\n\t\t})\n\t\t.filter((x): x is SelectableItem => x !== null);\n\n\t// All tools are offered (even already-added ones) so a tool can be referenced\n\t// again in the text; the chip list below still shows each only once.\n\tconst toolOptions: SingleOption[] = availableTools.map((t) => ({\n\t\tlabel: t.displayName,\n\t\tvalue: t.tool_id,\n\t\tsubText: t.description,\n\t}));\n\n\tconst subAgentItems: SelectableItem[] = value.subagents\n\t\t.map((id): SelectableItem | null => {\n\t\t\tconst sub = subAgentById.get(id);\n\t\t\treturn sub ? { id, label: sub.name } : null;\n\t\t})\n\t\t.filter((x): x is SelectableItem => x !== null);\n\n\tconst subAgentOptions: SingleOption[] = knownSubAgents.map((s) => ({\n\t\tlabel: s.name,\n\t\tvalue: s.id,\n\t}));\n\n\tconst modelOptions: SingleOption[] = availableModels.map((m) => ({\n\t\tlabel: m.label,\n\t\tvalue: m.value,\n\t\tselected: m.value === value.model,\n\t}));\n\tconst selectedModel = availableModels.find((m) => m.value === value.model);\n\n\treturn (\n\t\t<div className=\"bik-agent-step bik-agent-step--response\">\n\t\t\t<StepSectionHeader title={STEP.title} helper={STEP.helper} />\n\n\t\t\t<Step3Grid>\n\t\t\t\t<Step3Main>\n\t\t\t\t\t<MentionField\n\t\t\t\t\t\tfieldKey=\"instructions\"\n\t\t\t\t\t\tdata-test=\"agent-instructions\"\n\t\t\t\t\t\tlabel=\"Instructions\"\n\t\t\t\t\t\tmaxLength={AGENT_CHAR_LIMITS.instructions}\n\t\t\t\t\t\tplaceholder=\"Write what this agent should do. Type @ to reference a tool or sub-agent.\"\n\t\t\t\t\t\tminHeight=\"200px\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<MentionField\n\t\t\t\t\t\tfieldKey=\"guardrail\"\n\t\t\t\t\t\tdata-test=\"agent-guardrail\"\n\t\t\t\t\t\tlabel=\"Guardrails\"\n\t\t\t\t\t\tmaxLength={AGENT_CHAR_LIMITS.guardrail}\n\t\t\t\t\t\tplaceholder=\"Things this agent must never do. Type @ to reference a tool or sub-agent.\"\n\t\t\t\t\t\tminHeight=\"140px\"\n\t\t\t\t\t/>\n\t\t\t\t</Step3Main>\n\n\t\t\t\t<Step3Side>\n\t\t\t\t\t<SelectableListSection\n\t\t\t\t\t\ttitle=\"Tools\"\n\t\t\t\t\t\thelper=\"Actions this agent can take while responding.\"\n\t\t\t\t\t\tdataTestPrefix=\"agent-tools\"\n\t\t\t\t\t\titems={toolItems}\n\t\t\t\t\t\taddableOptions={toolOptions}\n\t\t\t\t\t\temptyText=\"No tools added yet.\"\n\t\t\t\t\t\tonAdd={(id) => {\n\t\t\t\t\t\t\t// Always drop a chip at the cursor; keep the list deduped.\n\t\t\t\t\t\t\tinsertMention('tool', id);\n\t\t\t\t\t\t\tif (!value.tools.includes(id)) {\n\t\t\t\t\t\t\t\tpatch({ tools: [...value.tools, id] });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonRemove={(id) => removeReference('tool', id)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<SelectableListSection\n\t\t\t\t\t\ttitle=\"Sub-agents\"\n\t\t\t\t\t\thelper=\"Other agents this agent can hand off the conversation to.\"\n\t\t\t\t\t\tdataTestPrefix=\"agent-subagents\"\n\t\t\t\t\t\titems={subAgentItems}\n\t\t\t\t\t\taddableOptions={subAgentOptions}\n\t\t\t\t\t\temptyText=\"No sub-agents added yet.\"\n\t\t\t\t\t\tonAdd={(id) => {\n\t\t\t\t\t\t\tinsertMention('subagent', id);\n\t\t\t\t\t\t\tif (!value.subagents.includes(id)) {\n\t\t\t\t\t\t\t\tpatch({ subagents: [...value.subagents, id] });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonRemove={(id) => removeReference('subagent', id)}\n\t\t\t\t\t\tonConfigure={onFetchSubAgent ? openConfigure : undefined}\n\t\t\t\t\t\tcreateOption={\n\t\t\t\t\t\t\tonCreateSubAgent\n\t\t\t\t\t\t\t\t? { label: 'Create new', onSelect: openCreate }\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\n\t\t\t\t\t{availableModels.length > 0 && (\n\t\t\t\t\t\t<SideSection>\n\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\tAdvanced settings\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\tSelect AI model\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t<Dropdown\n\t\t\t\t\t\t\t\tdata-test=\"agent-model\"\n\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\t\tplaceHolder=\"Select model\"\n\t\t\t\t\t\t\t\toptions={modelOptions}\n\t\t\t\t\t\t\t\tdefaultOptions={\n\t\t\t\t\t\t\t\t\tselectedModel\n\t\t\t\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tlabel: selectedModel.label,\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: selectedModel.value,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t ]\n\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\t\t\t\tconst single = Array.isArray(opt) ? opt[0] : opt;\n\t\t\t\t\t\t\t\t\tconst v = (single as SingleOption)?.value;\n\t\t\t\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\t\t\t\tupdateField('model', v);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</SideSection>\n\t\t\t\t\t)}\n\t\t\t\t</Step3Side>\n\t\t\t</Step3Grid>\n\n\t\t\t{panel && (\n\t\t\t\t<CreateSubAgentPanel\n\t\t\t\t\tkey={panel.key}\n\t\t\t\t\ttitle={panel.title}\n\t\t\t\t\tinitial={panel.initial}\n\t\t\t\t\tavailableTools={availableTools}\n\t\t\t\t\tappLabel={appTypeLabel(applicationType)}\n\t\t\t\t\tonImprove={onImproveSubAgent}\n\t\t\t\t\tonClose={() => setPanel(null)}\n\t\t\t\t\tonSave={handlePanelSave}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</div>\n\t);\n};\n"],"names":["STEP","STEP_DEFINITIONS","Step3HowItResponds","value","patch","updateField","removeReference","availableTools","availableSubAgents","availableModels","applicationType","insertMention","onCreateSubAgent","onFetchSubAgent","onUpdateSubAgent","onImproveSubAgent","useAgentBuilderContext","panel","setPanel","useState","panelKeyRef","useRef","createdSubAgents","setCreatedSubAgents","subAgentById","s","knownSubAgents","openCreate","useCallback","openConfigure","id","data","handlePanelSave","draft","ref","prev","toolItems","tool","t","x","toolOptions","subAgentItems","sub","subAgentOptions","modelOptions","m","selectedModel","jsxs","jsx","StepSectionHeader","Step3Grid","Step3Main","MentionField","AGENT_CHAR_LIMITS","Step3Side","SelectableListSection","SideSection","TitleSmall","COLORS","Dropdown","opt","v","CreateSubAgentPanel","appTypeLabel"],"mappings":"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"}
1
+ {"version":3,"file":"Step3HowItResponds.js","sources":["../../../../../src/components/agent-builder/steps/Step3HowItResponds.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Dropdown } from '@src/components/dropdown';\nimport { SingleOption } from '@src/components/dropdown/type';\nimport { TitleSmall } from '@src/components/TypographyStyle';\nimport { COLORS } from '@src/constants/Theme';\nimport { AgentTool, SubAgentDraft, SubAgentRef } from '../AgentBuilder.model';\nimport {\n\tSideSection,\n\tStep3Grid,\n\tStep3Main,\n\tStep3Side,\n} from '../AgentBuilder.styled';\nimport { CreateSubAgentPanel } from '../components/CreateSubAgentPanel';\nimport { MentionField } from '../components/MentionField';\nimport {\n\tSelectableItem,\n\tSelectableListSection,\n\tSourceGroup,\n} from '../components/SelectableListSection';\nimport { StepSectionHeader } from '../components/StepSectionHeader';\nimport { AGENT_CHAR_LIMITS } from '../constants/charLimits';\nimport { STEP_DEFINITIONS } from '../constants/steps';\nimport { useAgentBuilderContext } from '../context/AgentBuilderContext';\nimport { appTypeLabel, toolSourceLabel } from '../utils/mentionSerialization';\nimport { SOURCE_ICONS } from '../utils/sourceIcons';\n\n/** Source brand glyph for a tool, as a dropdown leadingIcon element. */\nconst toolIconEl = (source: string): JSX.Element | undefined => {\n\tconst ic = SOURCE_ICONS[source];\n\treturn ic\n\t\t? React.createElement(ic.Icon, { width: ic.w, height: ic.h })\n\t\t: undefined;\n};\n\n/** Dropdown option for a tool: icon left of the name, no description. */\nconst toolOption = (t: AgentTool): SingleOption => ({\n\tlabel: t.display_name,\n\tvalue: t.tool_id,\n\tleadingIcon: toolIconEl(t.source ?? 'manifest'),\n});\n\nconst STEP = STEP_DEFINITIONS[2];\n\n/** Drawer state — null when closed; `key` remounts it fresh per open. */\ninterface SubAgentPanelState {\n\tkey: number;\n\ttitle: string;\n\teditingId?: string;\n\tinitial?: SubAgentDraft;\n}\n\nexport const Step3HowItResponds: React.FC = () => {\n\tconst {\n\t\tvalue,\n\t\tpatch,\n\t\tupdateField,\n\t\tremoveReference,\n\t\tavailableTools,\n\t\tavailableSubAgents,\n\t\tavailableModels,\n\t\tapplicationType,\n\t\tinsertMention,\n\t\tonCreateSubAgent,\n\t\tonFetchSubAgent,\n\t\tonUpdateSubAgent,\n\t\tonImproveSubAgent,\n\t\tregisterSubAgentCreator,\n\t} = useAgentBuilderContext();\n\n\tconst [panel, setPanel] = useState<SubAgentPanelState | null>(null);\n\tconst panelKeyRef = useRef(0);\n\t// Sub-agents created / edited in this session, so a chip resolves (and reflects\n\t// a renamed sub-agent) before the consumer refreshes `availableSubAgents`.\n\tconst [createdSubAgents, setCreatedSubAgents] = useState<SubAgentRef[]>([]);\n\t// Created/edited refs take precedence over the consumer-supplied list.\n\tconst subAgentById = new Map<string, SubAgentRef>();\n\tavailableSubAgents.forEach((s) => subAgentById.set(s.id, s));\n\tcreatedSubAgents.forEach((s) => subAgentById.set(s.id, s));\n\tconst knownSubAgents = Array.from(subAgentById.values());\n\n\tconst openCreate = useCallback(() => {\n\t\tpanelKeyRef.current += 1;\n\t\tsetPanel({ key: panelKeyRef.current, title: 'Create sub-agent' });\n\t}, []);\n\n\t// Let the `@` picker's \"Create new\" row open this step's drawer.\n\tuseEffect(() => {\n\t\tif (!onCreateSubAgent) {\n\t\t\treturn;\n\t\t}\n\t\tregisterSubAgentCreator(openCreate);\n\t\treturn () => registerSubAgentCreator(null);\n\t}, [registerSubAgentCreator, openCreate, onCreateSubAgent]);\n\n\tconst openConfigure = useCallback(\n\t\tasync (id: string) => {\n\t\t\tif (!onFetchSubAgent) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst data = await onFetchSubAgent(id);\n\t\t\tpanelKeyRef.current += 1;\n\t\t\tsetPanel({\n\t\t\t\tkey: panelKeyRef.current,\n\t\t\t\ttitle: 'Edit sub-agent',\n\t\t\t\teditingId: id,\n\t\t\t\tinitial: data,\n\t\t\t});\n\t\t},\n\t\t[onFetchSubAgent],\n\t);\n\n\tconst handlePanelSave = useCallback(\n\t\tasync (draft: SubAgentDraft) => {\n\t\t\tif (panel?.editingId) {\n\t\t\t\tif (onUpdateSubAgent) {\n\t\t\t\t\tconst ref = await onUpdateSubAgent(panel.editingId, draft);\n\t\t\t\t\tsetCreatedSubAgents((prev) => [\n\t\t\t\t\t\t...prev.filter((s) => s.id !== ref.id),\n\t\t\t\t\t\tref,\n\t\t\t\t\t]);\n\t\t\t\t}\n\t\t\t} else if (onCreateSubAgent) {\n\t\t\t\tconst ref = await onCreateSubAgent(draft);\n\t\t\t\tsetCreatedSubAgents((prev) => [...prev, ref]);\n\t\t\t\tpatch({ subagents: [...value.subagents, ref.id] });\n\t\t\t\tinsertMention('subagent', ref.id, `sub-agent: ${ref.name}`);\n\t\t\t}\n\t\t\tsetPanel(null);\n\t\t},\n\t\t[\n\t\t\tpanel,\n\t\t\tonUpdateSubAgent,\n\t\t\tonCreateSubAgent,\n\t\t\tpatch,\n\t\t\tvalue.subagents,\n\t\t\tinsertMention,\n\t\t],\n\t);\n\n\tconst toolItems: SelectableItem[] = value.tools\n\t\t.map((id): SelectableItem | null => {\n\t\t\tconst tool = availableTools.find((t) => t.tool_id === id);\n\t\t\treturn tool\n\t\t\t\t? {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tlabel: tool.display_name,\n\t\t\t\t\t\ticon: SOURCE_ICONS[tool.source ?? 'manifest'],\n\t\t\t\t }\n\t\t\t\t: null;\n\t\t})\n\t\t.filter((x): x is SelectableItem => x !== null);\n\n\t// All tools are offered (even already-added ones) so a tool can be referenced\n\t// again in the text; the chip list below still shows each only once.\n\tconst toolOptions: SingleOption[] = availableTools.map(toolOption);\n\n\t// Group tools by source (Manifest / Shopify / …) for the empty-state buttons.\n\tconst toolSourceGroups: SourceGroup[] = (() => {\n\t\tconst order: string[] = [];\n\t\tconst bySource = new Map<string, SingleOption[]>();\n\t\tavailableTools.forEach((t) => {\n\t\t\tconst src = t.source ?? 'manifest';\n\t\t\tif (!bySource.has(src)) {\n\t\t\t\tbySource.set(src, []);\n\t\t\t\torder.push(src);\n\t\t\t}\n\t\t\tbySource.get(src)?.push(toolOption(t));\n\t\t});\n\t\treturn order.map((src) => ({\n\t\t\tsource: src,\n\t\t\tlabel: toolSourceLabel(src),\n\t\t\toptions: bySource.get(src) ?? [],\n\t\t}));\n\t})();\n\n\tconst subAgentItems: SelectableItem[] = value.subagents\n\t\t.map((id): SelectableItem | null => {\n\t\t\tconst sub = subAgentById.get(id);\n\t\t\treturn sub ? { id, label: sub.name } : null;\n\t\t})\n\t\t.filter((x): x is SelectableItem => x !== null);\n\n\tconst subAgentOptions: SingleOption[] = knownSubAgents.map((s) => ({\n\t\tlabel: s.name,\n\t\tvalue: s.id,\n\t}));\n\n\tconst modelOptions: SingleOption[] = availableModels.map((m) => ({\n\t\tlabel: m.label,\n\t\tvalue: m.value,\n\t\tselected: m.value === value.model,\n\t}));\n\tconst selectedModel = availableModels.find((m) => m.value === value.model);\n\n\treturn (\n\t\t<div className=\"bik-agent-step bik-agent-step--response\">\n\t\t\t<StepSectionHeader title={STEP.title} helper={STEP.helper} />\n\n\t\t\t<Step3Grid>\n\t\t\t\t<Step3Main>\n\t\t\t\t\t<MentionField\n\t\t\t\t\t\tfieldKey=\"instructions\"\n\t\t\t\t\t\tdata-test=\"agent-instructions\"\n\t\t\t\t\t\tlabel=\"Instructions\"\n\t\t\t\t\t\tmaxLength={AGENT_CHAR_LIMITS.instructions}\n\t\t\t\t\t\tplaceholder=\"Write what this agent should do. Type @ to reference a tool or sub-agent.\"\n\t\t\t\t\t\tminHeight=\"200px\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<MentionField\n\t\t\t\t\t\tfieldKey=\"guardrail\"\n\t\t\t\t\t\tdata-test=\"agent-guardrail\"\n\t\t\t\t\t\tlabel=\"Guardrails\"\n\t\t\t\t\t\tmaxLength={AGENT_CHAR_LIMITS.guardrail}\n\t\t\t\t\t\tplaceholder=\"Things this agent must never do. Type @ to reference a tool or sub-agent.\"\n\t\t\t\t\t\tminHeight=\"140px\"\n\t\t\t\t\t/>\n\t\t\t\t</Step3Main>\n\n\t\t\t\t<Step3Side>\n\t\t\t\t\t<SelectableListSection\n\t\t\t\t\t\ttitle=\"Tools\"\n\t\t\t\t\t\thelper=\"Actions this agent can take while responding.\"\n\t\t\t\t\t\tdataTestPrefix=\"agent-tools\"\n\t\t\t\t\t\titems={toolItems}\n\t\t\t\t\t\taddableOptions={toolOptions}\n\t\t\t\t\t\tsourceGroups={toolSourceGroups}\n\t\t\t\t\t\temptyText=\"No tools added yet.\"\n\t\t\t\t\t\tonAdd={(id) => {\n\t\t\t\t\t\t\t// Always drop a chip at the cursor; keep the list deduped.\n\t\t\t\t\t\t\tinsertMention('tool', id);\n\t\t\t\t\t\t\tif (!value.tools.includes(id)) {\n\t\t\t\t\t\t\t\tpatch({ tools: [...value.tools, id] });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonRemove={(id) => removeReference('tool', id)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<SelectableListSection\n\t\t\t\t\t\ttitle=\"Sub-agents\"\n\t\t\t\t\t\thelper=\"Other agents this agent can hand off the conversation to.\"\n\t\t\t\t\t\tdataTestPrefix=\"agent-subagents\"\n\t\t\t\t\t\titems={subAgentItems}\n\t\t\t\t\t\taddableOptions={subAgentOptions}\n\t\t\t\t\t\temptyText=\"No sub-agents added yet.\"\n\t\t\t\t\t\tonAdd={(id) => {\n\t\t\t\t\t\t\tinsertMention('subagent', id);\n\t\t\t\t\t\t\tif (!value.subagents.includes(id)) {\n\t\t\t\t\t\t\t\tpatch({ subagents: [...value.subagents, id] });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonRemove={(id) => removeReference('subagent', id)}\n\t\t\t\t\t\tonConfigure={onFetchSubAgent ? openConfigure : undefined}\n\t\t\t\t\t\tcreateOption={\n\t\t\t\t\t\t\tonCreateSubAgent\n\t\t\t\t\t\t\t\t? { label: 'Create new', onSelect: openCreate }\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\n\t\t\t\t\t{availableModels.length > 0 && (\n\t\t\t\t\t\t<SideSection>\n\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.primary}>\n\t\t\t\t\t\t\t\tAdvanced settings\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t<TitleSmall color={COLORS.content.secondary}>\n\t\t\t\t\t\t\t\tSelect AI model\n\t\t\t\t\t\t\t</TitleSmall>\n\t\t\t\t\t\t\t<Dropdown\n\t\t\t\t\t\t\t\tdata-test=\"agent-model\"\n\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\t\tplaceHolder=\"Select model\"\n\t\t\t\t\t\t\t\toptions={modelOptions}\n\t\t\t\t\t\t\t\tdefaultOptions={\n\t\t\t\t\t\t\t\t\tselectedModel\n\t\t\t\t\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tlabel: selectedModel.label,\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue: selectedModel.value,\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t ]\n\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\t\t\t\tconst single = Array.isArray(opt) ? opt[0] : opt;\n\t\t\t\t\t\t\t\t\tconst v = (single as SingleOption)?.value;\n\t\t\t\t\t\t\t\t\tif (v) {\n\t\t\t\t\t\t\t\t\t\tupdateField('model', v);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</SideSection>\n\t\t\t\t\t)}\n\t\t\t\t</Step3Side>\n\t\t\t</Step3Grid>\n\n\t\t\t{panel && (\n\t\t\t\t<CreateSubAgentPanel\n\t\t\t\t\tkey={panel.key}\n\t\t\t\t\ttitle={panel.title}\n\t\t\t\t\tinitial={panel.initial}\n\t\t\t\t\tavailableTools={availableTools}\n\t\t\t\t\tappLabel={appTypeLabel(applicationType)}\n\t\t\t\t\tonImprove={onImproveSubAgent}\n\t\t\t\t\tonClose={() => setPanel(null)}\n\t\t\t\t\tonSave={handlePanelSave}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</div>\n\t);\n};\n"],"names":["toolIconEl","source","ic","SOURCE_ICONS","React","toolOption","STEP","STEP_DEFINITIONS","Step3HowItResponds","value","patch","updateField","removeReference","availableTools","availableSubAgents","availableModels","applicationType","insertMention","onCreateSubAgent","onFetchSubAgent","onUpdateSubAgent","onImproveSubAgent","registerSubAgentCreator","useAgentBuilderContext","panel","setPanel","useState","panelKeyRef","useRef","createdSubAgents","setCreatedSubAgents","subAgentById","s","knownSubAgents","openCreate","useCallback","useEffect","openConfigure","id","data","handlePanelSave","draft","ref","prev","toolItems","tool","t","x","toolOptions","toolSourceGroups","order","bySource","src","toolSourceLabel","subAgentItems","sub","subAgentOptions","modelOptions","m","selectedModel","jsxs","jsx","StepSectionHeader","Step3Grid","Step3Main","MentionField","AGENT_CHAR_LIMITS","Step3Side","SelectableListSection","SideSection","TitleSmall","COLORS","Dropdown","opt","v","CreateSubAgentPanel","appTypeLabel"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c={manifest:"Manifest",shopify:"Shopify",integration:"Integration"},u=(t,n="Manifest")=>t?c[t]??t:n,b=t=>{const n=t?String(t):"";return n==="BIK"?"BIK":n==="BSP"?"BSP":"Manifest"},g=(t,n,e="Manifest")=>[...t.map(o=>({id:o.tool_id,label:`${u(o.source,e)} : ${o.displayName}`,meta:{kind:"tool",functionKey:o.function_key,plainLabel:o.displayName,source:o.source}})),...n.map(o=>({id:o.id,label:`sub-agent: ${o.name}`,meta:{kind:"subagent",plainLabel:o.name}}))],a=t=>t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),s=t=>a(t).replace(/"/g,"&quot;"),d=(t,n,e)=>`<span data-type="mentionAgent" class="bik-mention bik-mention--agent" data-id="${s(t)}" data-label="${s(n)}" data-kind="${s(e)}">${a(n)}</span>`,f=(t,n,e)=>d(t,n,e),k=t=>{const n=new Map;for(const e of t){const o=e.meta;o?.kind==="tool"&&o.functionKey?n.set(`tool:${o.functionKey}`,e):o?.kind==="subagent"&&n.set(`subagent:${String(e.id)}`,e)}return n},l=/\{\{(tool:[^}]+|subagent:[^}]+)\}\}/g,y=(t,n)=>{let e="",o=0;l.lastIndex=0;let i;for(;(i=l.exec(t))!==null;){e+=a(t.slice(o,i.index));const r=n.get(i[1]);if(r){const m=r.meta.kind;e+=d(String(r.id),r.label,m)}else e+=a(i[0]);o=l.lastIndex}return e+=a(t.slice(o)),e.replace(/\n/g,"<br>")},S=(t,n=[])=>{if(!t)return"";const e=k(n);return t.split(/\n{2,}/).map(o=>`<p>${y(o,e)}</p>`).join("")},T=(t,n)=>{const e=n[t];return e?`{{tool:${e}}}`:`{{subagent:${t}}}`},p=(t,n)=>{switch(t.type){case"text":return t.text??"";case"mentionAgent":case"mentionTeam":{const e=t.attrs?.id;return e==null?"":T(String(e),n)}case"variable":return`{{${String(t.attrs?.variableName??"")}}}`;case"hardBreak":return`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c={manifest:"Manifest",shopify:"Shopify",integration:"Integration"},u=(t,n="Manifest")=>t?c[t]??t:n,b=t=>{const n=t?String(t):"";return n==="BIK"?"BIK":n==="BSP"?"BSP":"Manifest"},g=(t,n,e="Manifest")=>[...t.map(o=>({id:o.tool_id,label:`${u(o.source,e)} : ${o.display_name}`,meta:{kind:"tool",functionKey:o.function_key,plainLabel:o.display_name,source:o.source}})),...n.map(o=>({id:o.id,label:`sub-agent: ${o.name}`,meta:{kind:"subagent",plainLabel:o.name}}))],a=t=>t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),s=t=>a(t).replace(/"/g,"&quot;"),d=(t,n,e)=>`<span data-type="mentionAgent" class="bik-mention bik-mention--agent" data-id="${s(t)}" data-label="${s(n)}" data-kind="${s(e)}">${a(n)}</span>`,f=(t,n,e)=>d(t,n,e),k=t=>{const n=new Map;for(const e of t){const o=e.meta;o?.kind==="tool"&&o.functionKey?n.set(`tool:${o.functionKey}`,e):o?.kind==="subagent"&&n.set(`subagent:${String(e.id)}`,e)}return n},l=/\{\{(tool:[^}]+|subagent:[^}]+)\}\}/g,y=(t,n)=>{let e="",o=0;l.lastIndex=0;let i;for(;(i=l.exec(t))!==null;){e+=a(t.slice(o,i.index));const r=n.get(i[1]);if(r){const m=r.meta.kind;e+=d(String(r.id),r.label,m)}else e+=a(i[0]);o=l.lastIndex}return e+=a(t.slice(o)),e.replace(/\n/g,"<br>")},S=(t,n=[])=>{if(!t)return"";const e=k(n);return t.split(/\n{2,}/).map(o=>`<p>${y(o,e)}</p>`).join("")},T=(t,n)=>{const e=n[t];return e?`{{tool:${e}}}`:`{{subagent:${t}}}`},p=(t,n)=>{switch(t.type){case"text":return t.text??"";case"mentionAgent":case"mentionTeam":{const e=t.attrs?.id;return e==null?"":T(String(e),n)}case"variable":return`{{${String(t.attrs?.variableName??"")}}}`;case"hardBreak":return`
2
2
  `;default:{const e=(t.content??[]).map(i=>p(i,n)).join("");return["paragraph","heading","listItem","blockquote"].includes(t.type)?`${e}
3
3
  `:e}}},L=(t,n)=>{if(!t)return"";const e=n.reduce((o,i)=>(o[i.tool_id]=i.function_key,o),{});return p(t,e).replace(/\n+$/,"")};exports.TOOL_SOURCE_LABELS=c;exports.appTypeLabel=b;exports.buildAgentMentionItems=g;exports.buildMentionHtml=f;exports.editorDocToInstructions=L;exports.instructionsToEditorHtml=S;exports.toolSourceLabel=u;
4
4
  //# sourceMappingURL=mentionSerialization.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mentionSerialization.js","sources":["../../../../../src/components/agent-builder/utils/mentionSerialization.ts"],"sourcesContent":["import type { ApplicationType } from '@bikdotai/bik-models/growth';\nimport { MentionItem } from '@src/editor';\nimport { AgentTool, SubAgentRef } from '../AgentBuilder.model';\n\n/**\n * Serialization helpers between the BikEditor document and the firebase\n * `instructions` string.\n *\n * Firebase stores `instructions` as PLAIN TEXT with inline reference tokens:\n * - `{{subagent:<agentId>}}` — hand-off to another agent\n * - `{{tool:<function_key>}}` — an action the agent can call\n * - `{{<variableName>}}` — a template variable\n *\n * In the editor those references are inserted via the `@` mention menu (which we\n * populate with BOTH tools and sub-agents). Mention nodes keep their `id` in the\n * ProseMirror doc JSON (the rendered HTML drops it), so we serialize from the doc\n * JSON — not from HTML.\n */\n\nexport interface MentionKindMeta {\n\t/** Distinguishes a tool reference from a sub-agent reference. */\n\tkind: 'tool' | 'subagent';\n\t/** For tools: the function_key used in the `{{tool:KEY}}` token. */\n\tfunctionKey?: string;\n\t/** Plain item name (no prefix) shown in the picker dropdown rows. */\n\tplainLabel?: string;\n\t/** For tools: the source bucket (manifest / shopify / …) the picker groups by. */\n\tsource?: string;\n}\n\n/** Display labels for the known tool sources (drives picker headers + chip prefix). */\nexport const TOOL_SOURCE_LABELS: Record<string, string> = {\n\tmanifest: 'Manifest',\n\tshopify: 'Shopify',\n\tintegration: 'Integration',\n};\n\n/** Human label for a tool source; falls back to the host-app label, then the raw key. */\nexport const toolSourceLabel = (\n\tsource: string | undefined,\n\tfallback = 'Manifest',\n): string => {\n\tif (!source) {\n\t\treturn fallback;\n\t}\n\treturn TOOL_SOURCE_LABELS[source] ?? source;\n};\n\n/** Human label for the host application, used as the tool-chip prefix. */\nexport const appTypeLabel = (applicationType?: ApplicationType): string => {\n\tconst key = applicationType ? String(applicationType) : '';\n\tif (key === 'BIK') {\n\t\treturn 'BIK';\n\t}\n\tif (key === 'BSP') {\n\t\treturn 'BSP';\n\t}\n\treturn 'Manifest';\n};\n\n/**\n * Build the combined `@` mention list from the available tools + sub-agents.\n *\n * The `label` is the CHIP text shown once inserted — tools read\n * `\"<App> : <tool name>\"` (e.g. \"Manifest : Look up order\"), sub-agents read\n * `\"sub-agent: <name>\"`. `meta.plainLabel` is the un-prefixed name for the\n * picker rows, and `meta.kind` drives the `{{tool}}` / `{{subagent}}` colour.\n */\nexport const buildAgentMentionItems = (\n\ttools: AgentTool[],\n\tsubAgents: SubAgentRef[],\n\tappLabel = 'Manifest',\n): MentionItem[] => [\n\t...tools.map(\n\t\t(t): MentionItem => ({\n\t\t\tid: t.tool_id,\n\t\t\tlabel: `${toolSourceLabel(t.source, appLabel)} : ${t.displayName}`,\n\t\t\tmeta: {\n\t\t\t\tkind: 'tool',\n\t\t\t\tfunctionKey: t.function_key,\n\t\t\t\tplainLabel: t.displayName,\n\t\t\t\tsource: t.source,\n\t\t\t},\n\t\t}),\n\t),\n\t...subAgents.map(\n\t\t(s): MentionItem => ({\n\t\t\tid: s.id,\n\t\t\tlabel: `sub-agent: ${s.name}`,\n\t\t\tmeta: { kind: 'subagent', plainLabel: s.name },\n\t\t}),\n\t),\n];\n\nconst escapeHtml = (raw: string): string =>\n\traw.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\nconst escapeAttr = (raw: string): string =>\n\tescapeHtml(raw).replace(/\"/g, '&quot;');\n\n/**\n * The HTML for a single mention chip. Must round-trip through the TipTap mention\n * extension's `parseHTML` (`span[data-type=\"mentionAgent\"]`, reading\n * `data-id`/`data-label`/`data-kind`) — see MentionExtension.ts. `normalizeHtml`\n * is taught to keep `data-type=\"mention…\"` spans so this survives to the parser.\n */\nconst mentionSpanHtml = (id: string, label: string, kind: string): string =>\n\t`<span data-type=\"mentionAgent\" class=\"bik-mention bik-mention--agent\"` +\n\t` data-id=\"${escapeAttr(id)}\" data-label=\"${escapeAttr(label)}\"` +\n\t` data-kind=\"${escapeAttr(kind)}\">${escapeHtml(label)}</span>`;\n\n/**\n * Public: HTML for one mention chip, for inserting at the cursor (e.g. when a\n * tool / sub-agent is added from the Step-3 side panel). Round-trips through the\n * same parser path as the rehydrated chips.\n */\nexport const buildMentionHtml = (\n\tid: string,\n\tlabel: string,\n\tkind: 'tool' | 'subagent',\n): string => mentionSpanHtml(id, label, kind);\n\n/** `{{tool:KEY}}` / `{{subagent:ID}}` → the mention item that produced them. */\nconst buildTokenLookup = (\n\tmentionItems: MentionItem[],\n): Map<string, MentionItem> => {\n\tconst byToken = new Map<string, MentionItem>();\n\tfor (const item of mentionItems) {\n\t\tconst meta = item.meta as unknown as MentionKindMeta | undefined;\n\t\tif (meta?.kind === 'tool' && meta.functionKey) {\n\t\t\tbyToken.set(`tool:${meta.functionKey}`, item);\n\t\t} else if (meta?.kind === 'subagent') {\n\t\t\tbyToken.set(`subagent:${String(item.id)}`, item);\n\t\t}\n\t}\n\treturn byToken;\n};\n\n// Matches the reference tokens we render as chips. Other `{{var}}` tokens fall\n// through untouched (left as literal text for the variable decoration).\nconst REFERENCE_TOKEN = /\\{\\{(tool:[^}]+|subagent:[^}]+)\\}\\}/g;\n\n/** Escape plain text, swapping recognised reference tokens for mention spans. */\nconst inlineToHtml = (\n\tsegment: string,\n\tbyToken: Map<string, MentionItem>,\n): string => {\n\tlet out = '';\n\tlet lastIndex = 0;\n\tREFERENCE_TOKEN.lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\twhile ((match = REFERENCE_TOKEN.exec(segment)) !== null) {\n\t\tout += escapeHtml(segment.slice(lastIndex, match.index));\n\t\tconst item = byToken.get(match[1]);\n\t\tif (item) {\n\t\t\tconst kind = (item.meta as unknown as MentionKindMeta).kind;\n\t\t\tout += mentionSpanHtml(String(item.id), item.label, kind);\n\t\t} else {\n\t\t\t// Tool/sub-agent no longer in the available list → keep the raw token.\n\t\t\tout += escapeHtml(match[0]);\n\t\t}\n\t\tlastIndex = REFERENCE_TOKEN.lastIndex;\n\t}\n\tout += escapeHtml(segment.slice(lastIndex));\n\treturn out.replace(/\\n/g, '<br>');\n};\n\n/**\n * Convert the stored instructions string into HTML for `BikEditor.initialContent`.\n * `{{tool:KEY}}` / `{{subagent:ID}}` tokens are rehydrated into mention chips\n * (resolved via `mentionItems`); any other `{{…}}` token is left as literal text\n * for the editor's variable decoration. Newlines become paragraph / line breaks.\n */\nexport const instructionsToEditorHtml = (\n\ttext: string,\n\tmentionItems: MentionItem[] = [],\n): string => {\n\tif (!text) {\n\t\treturn '';\n\t}\n\tconst byToken = buildTokenLookup(mentionItems);\n\treturn text\n\t\t.split(/\\n{2,}/)\n\t\t.map((para) => `<p>${inlineToHtml(para, byToken)}</p>`)\n\t\t.join('');\n};\n\ninterface ProseMirrorNode {\n\ttype: string;\n\ttext?: string;\n\tattrs?: Record<string, unknown>;\n\tcontent?: ProseMirrorNode[];\n}\n\n/** Map of mention node id → token, derived from the available tools. */\nconst resolveMentionToken = (\n\tid: string,\n\ttoolKeyById: Record<string, string>,\n): string => {\n\tconst functionKey = toolKeyById[id];\n\tif (functionKey) {\n\t\treturn `{{tool:${functionKey}}}`;\n\t}\n\treturn `{{subagent:${id}}}`;\n};\n\nconst nodeToText = (\n\tnode: ProseMirrorNode,\n\ttoolKeyById: Record<string, string>,\n): string => {\n\tswitch (node.type) {\n\t\tcase 'text':\n\t\t\treturn node.text ?? '';\n\t\tcase 'mentionAgent':\n\t\tcase 'mentionTeam': {\n\t\t\tconst id = node.attrs?.['id'];\n\t\t\treturn id == null ? '' : resolveMentionToken(String(id), toolKeyById);\n\t\t}\n\t\tcase 'variable':\n\t\t\treturn `{{${String(node.attrs?.['variableName'] ?? '')}}}`;\n\t\tcase 'hardBreak':\n\t\t\treturn '\\n';\n\t\tdefault: {\n\t\t\tconst inner = (node.content ?? [])\n\t\t\t\t.map((child) => nodeToText(child, toolKeyById))\n\t\t\t\t.join('');\n\t\t\t// Block nodes terminate with a newline so paragraphs stay separated.\n\t\t\tconst BLOCK_NODES = ['paragraph', 'heading', 'listItem', 'blockquote'];\n\t\t\treturn BLOCK_NODES.includes(node.type) ? `${inner}\\n` : inner;\n\t\t}\n\t}\n};\n\n/**\n * Convert a BikEditor document (from `ref.getJSON()`) into the firebase\n * instructions string, replacing mention nodes with `{{subagent:ID}}` /\n * `{{tool:KEY}}` tokens.\n */\nexport const editorDocToInstructions = (\n\tdoc: Record<string, unknown> | null,\n\ttools: AgentTool[],\n): string => {\n\tif (!doc) {\n\t\treturn '';\n\t}\n\tconst toolKeyById = tools.reduce<Record<string, string>>((acc, t) => {\n\t\tacc[t.tool_id] = t.function_key;\n\t\treturn acc;\n\t}, {});\n\treturn nodeToText(doc as unknown as ProseMirrorNode, toolKeyById).replace(\n\t\t/\\n+$/,\n\t\t'',\n\t);\n};\n"],"names":["TOOL_SOURCE_LABELS","toolSourceLabel","source","fallback","appTypeLabel","applicationType","key","buildAgentMentionItems","tools","subAgents","appLabel","t","s","escapeHtml","raw","escapeAttr","mentionSpanHtml","id","label","kind","buildMentionHtml","buildTokenLookup","mentionItems","byToken","item","meta","REFERENCE_TOKEN","inlineToHtml","segment","out","lastIndex","match","instructionsToEditorHtml","text","para","resolveMentionToken","toolKeyById","functionKey","nodeToText","node","inner","child","editorDocToInstructions","doc","acc"],"mappings":"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"}
1
+ {"version":3,"file":"mentionSerialization.js","sources":["../../../../../src/components/agent-builder/utils/mentionSerialization.ts"],"sourcesContent":["import type { ApplicationType } from '@bikdotai/bik-models/growth';\nimport { MentionItem } from '@src/editor';\nimport { AgentTool, SubAgentRef } from '../AgentBuilder.model';\n\n/**\n * Serialization helpers between the BikEditor document and the firebase\n * `instructions` string.\n *\n * Firebase stores `instructions` as PLAIN TEXT with inline reference tokens:\n * - `{{subagent:<agentId>}}` — hand-off to another agent\n * - `{{tool:<function_key>}}` — an action the agent can call\n * - `{{<variableName>}}` — a template variable\n *\n * In the editor those references are inserted via the `@` mention menu (which we\n * populate with BOTH tools and sub-agents). Mention nodes keep their `id` in the\n * ProseMirror doc JSON (the rendered HTML drops it), so we serialize from the doc\n * JSON — not from HTML.\n */\n\nexport interface MentionKindMeta {\n\t/** Distinguishes a tool reference from a sub-agent reference. */\n\tkind: 'tool' | 'subagent';\n\t/** For tools: the function_key used in the `{{tool:KEY}}` token. */\n\tfunctionKey?: string;\n\t/** Plain item name (no prefix) shown in the picker dropdown rows. */\n\tplainLabel?: string;\n\t/** For tools: the source bucket (manifest / shopify / …) the picker groups by. */\n\tsource?: string;\n}\n\n/** Display labels for the known tool sources (drives picker headers + chip prefix). */\nexport const TOOL_SOURCE_LABELS: Record<string, string> = {\n\tmanifest: 'Manifest',\n\tshopify: 'Shopify',\n\tintegration: 'Integration',\n};\n\n/** Human label for a tool source; falls back to the host-app label, then the raw key. */\nexport const toolSourceLabel = (\n\tsource: string | undefined,\n\tfallback = 'Manifest',\n): string => {\n\tif (!source) {\n\t\treturn fallback;\n\t}\n\treturn TOOL_SOURCE_LABELS[source] ?? source;\n};\n\n/** Human label for the host application, used as the tool-chip prefix. */\nexport const appTypeLabel = (applicationType?: ApplicationType): string => {\n\tconst key = applicationType ? String(applicationType) : '';\n\tif (key === 'BIK') {\n\t\treturn 'BIK';\n\t}\n\tif (key === 'BSP') {\n\t\treturn 'BSP';\n\t}\n\treturn 'Manifest';\n};\n\n/**\n * Build the combined `@` mention list from the available tools + sub-agents.\n *\n * The `label` is the CHIP text shown once inserted — tools read\n * `\"<App> : <tool name>\"` (e.g. \"Manifest : Look up order\"), sub-agents read\n * `\"sub-agent: <name>\"`. `meta.plainLabel` is the un-prefixed name for the\n * picker rows, and `meta.kind` drives the `{{tool}}` / `{{subagent}}` colour.\n */\nexport const buildAgentMentionItems = (\n\ttools: AgentTool[],\n\tsubAgents: SubAgentRef[],\n\tappLabel = 'Manifest',\n): MentionItem[] => [\n\t...tools.map(\n\t\t(t): MentionItem => ({\n\t\t\tid: t.tool_id,\n\t\t\tlabel: `${toolSourceLabel(t.source, appLabel)} : ${t.display_name}`,\n\t\t\tmeta: {\n\t\t\t\tkind: 'tool',\n\t\t\t\tfunctionKey: t.function_key,\n\t\t\t\tplainLabel: t.display_name,\n\t\t\t\tsource: t.source,\n\t\t\t},\n\t\t}),\n\t),\n\t...subAgents.map(\n\t\t(s): MentionItem => ({\n\t\t\tid: s.id,\n\t\t\tlabel: `sub-agent: ${s.name}`,\n\t\t\tmeta: { kind: 'subagent', plainLabel: s.name },\n\t\t}),\n\t),\n];\n\nconst escapeHtml = (raw: string): string =>\n\traw.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\nconst escapeAttr = (raw: string): string =>\n\tescapeHtml(raw).replace(/\"/g, '&quot;');\n\n/**\n * The HTML for a single mention chip. Must round-trip through the TipTap mention\n * extension's `parseHTML` (`span[data-type=\"mentionAgent\"]`, reading\n * `data-id`/`data-label`/`data-kind`) — see MentionExtension.ts. `normalizeHtml`\n * is taught to keep `data-type=\"mention…\"` spans so this survives to the parser.\n */\nconst mentionSpanHtml = (id: string, label: string, kind: string): string =>\n\t`<span data-type=\"mentionAgent\" class=\"bik-mention bik-mention--agent\"` +\n\t` data-id=\"${escapeAttr(id)}\" data-label=\"${escapeAttr(label)}\"` +\n\t` data-kind=\"${escapeAttr(kind)}\">${escapeHtml(label)}</span>`;\n\n/**\n * Public: HTML for one mention chip, for inserting at the cursor (e.g. when a\n * tool / sub-agent is added from the Step-3 side panel). Round-trips through the\n * same parser path as the rehydrated chips.\n */\nexport const buildMentionHtml = (\n\tid: string,\n\tlabel: string,\n\tkind: 'tool' | 'subagent',\n): string => mentionSpanHtml(id, label, kind);\n\n/** `{{tool:KEY}}` / `{{subagent:ID}}` → the mention item that produced them. */\nconst buildTokenLookup = (\n\tmentionItems: MentionItem[],\n): Map<string, MentionItem> => {\n\tconst byToken = new Map<string, MentionItem>();\n\tfor (const item of mentionItems) {\n\t\tconst meta = item.meta as unknown as MentionKindMeta | undefined;\n\t\tif (meta?.kind === 'tool' && meta.functionKey) {\n\t\t\tbyToken.set(`tool:${meta.functionKey}`, item);\n\t\t} else if (meta?.kind === 'subagent') {\n\t\t\tbyToken.set(`subagent:${String(item.id)}`, item);\n\t\t}\n\t}\n\treturn byToken;\n};\n\n// Matches the reference tokens we render as chips. Other `{{var}}` tokens fall\n// through untouched (left as literal text for the variable decoration).\nconst REFERENCE_TOKEN = /\\{\\{(tool:[^}]+|subagent:[^}]+)\\}\\}/g;\n\n/** Escape plain text, swapping recognised reference tokens for mention spans. */\nconst inlineToHtml = (\n\tsegment: string,\n\tbyToken: Map<string, MentionItem>,\n): string => {\n\tlet out = '';\n\tlet lastIndex = 0;\n\tREFERENCE_TOKEN.lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\twhile ((match = REFERENCE_TOKEN.exec(segment)) !== null) {\n\t\tout += escapeHtml(segment.slice(lastIndex, match.index));\n\t\tconst item = byToken.get(match[1]);\n\t\tif (item) {\n\t\t\tconst kind = (item.meta as unknown as MentionKindMeta).kind;\n\t\t\tout += mentionSpanHtml(String(item.id), item.label, kind);\n\t\t} else {\n\t\t\t// Tool/sub-agent no longer in the available list → keep the raw token.\n\t\t\tout += escapeHtml(match[0]);\n\t\t}\n\t\tlastIndex = REFERENCE_TOKEN.lastIndex;\n\t}\n\tout += escapeHtml(segment.slice(lastIndex));\n\treturn out.replace(/\\n/g, '<br>');\n};\n\n/**\n * Convert the stored instructions string into HTML for `BikEditor.initialContent`.\n * `{{tool:KEY}}` / `{{subagent:ID}}` tokens are rehydrated into mention chips\n * (resolved via `mentionItems`); any other `{{…}}` token is left as literal text\n * for the editor's variable decoration. Newlines become paragraph / line breaks.\n */\nexport const instructionsToEditorHtml = (\n\ttext: string,\n\tmentionItems: MentionItem[] = [],\n): string => {\n\tif (!text) {\n\t\treturn '';\n\t}\n\tconst byToken = buildTokenLookup(mentionItems);\n\treturn text\n\t\t.split(/\\n{2,}/)\n\t\t.map((para) => `<p>${inlineToHtml(para, byToken)}</p>`)\n\t\t.join('');\n};\n\ninterface ProseMirrorNode {\n\ttype: string;\n\ttext?: string;\n\tattrs?: Record<string, unknown>;\n\tcontent?: ProseMirrorNode[];\n}\n\n/** Map of mention node id → token, derived from the available tools. */\nconst resolveMentionToken = (\n\tid: string,\n\ttoolKeyById: Record<string, string>,\n): string => {\n\tconst functionKey = toolKeyById[id];\n\tif (functionKey) {\n\t\treturn `{{tool:${functionKey}}}`;\n\t}\n\treturn `{{subagent:${id}}}`;\n};\n\nconst nodeToText = (\n\tnode: ProseMirrorNode,\n\ttoolKeyById: Record<string, string>,\n): string => {\n\tswitch (node.type) {\n\t\tcase 'text':\n\t\t\treturn node.text ?? '';\n\t\tcase 'mentionAgent':\n\t\tcase 'mentionTeam': {\n\t\t\tconst id = node.attrs?.['id'];\n\t\t\treturn id == null ? '' : resolveMentionToken(String(id), toolKeyById);\n\t\t}\n\t\tcase 'variable':\n\t\t\treturn `{{${String(node.attrs?.['variableName'] ?? '')}}}`;\n\t\tcase 'hardBreak':\n\t\t\treturn '\\n';\n\t\tdefault: {\n\t\t\tconst inner = (node.content ?? [])\n\t\t\t\t.map((child) => nodeToText(child, toolKeyById))\n\t\t\t\t.join('');\n\t\t\t// Block nodes terminate with a newline so paragraphs stay separated.\n\t\t\tconst BLOCK_NODES = ['paragraph', 'heading', 'listItem', 'blockquote'];\n\t\t\treturn BLOCK_NODES.includes(node.type) ? `${inner}\\n` : inner;\n\t\t}\n\t}\n};\n\n/**\n * Convert a BikEditor document (from `ref.getJSON()`) into the firebase\n * instructions string, replacing mention nodes with `{{subagent:ID}}` /\n * `{{tool:KEY}}` tokens.\n */\nexport const editorDocToInstructions = (\n\tdoc: Record<string, unknown> | null,\n\ttools: AgentTool[],\n): string => {\n\tif (!doc) {\n\t\treturn '';\n\t}\n\tconst toolKeyById = tools.reduce<Record<string, string>>((acc, t) => {\n\t\tacc[t.tool_id] = t.function_key;\n\t\treturn acc;\n\t}, {});\n\treturn nodeToText(doc as unknown as ProseMirrorNode, toolKeyById).replace(\n\t\t/\\n+$/,\n\t\t'',\n\t);\n};\n"],"names":["TOOL_SOURCE_LABELS","toolSourceLabel","source","fallback","appTypeLabel","applicationType","key","buildAgentMentionItems","tools","subAgents","appLabel","t","s","escapeHtml","raw","escapeAttr","mentionSpanHtml","id","label","kind","buildMentionHtml","buildTokenLookup","mentionItems","byToken","item","meta","REFERENCE_TOKEN","inlineToHtml","segment","out","lastIndex","match","instructionsToEditorHtml","text","para","resolveMentionToken","toolKeyById","functionKey","nodeToText","node","inner","child","editorDocToInstructions","doc","acc"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../../../assets/icons/ManifestGlass.svg.js"),t=require("../../../assets/icons/Shopify.svg.js"),o={manifest:{Icon:e.default,w:24,h:24},shopify:{Icon:t.default,w:21,h:24}};exports.SOURCE_ICONS=o;
2
+ //# sourceMappingURL=sourceIcons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceIcons.js","sources":["../../../../../src/components/agent-builder/utils/sourceIcons.ts"],"sourcesContent":["import ManifestGlass from '@src/assets/icons/ManifestGlass.svg';\nimport Shopify from '@src/assets/icons/Shopify.svg';\nimport type React from 'react';\n\nexport type IconComp = React.FunctionComponent<React.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/** Per-source brand glyph — shared by the `@` picker and the Tools source buttons. */\nexport const SOURCE_ICONS: Record<string, SourceIcon> = {\n\tmanifest: { Icon: ManifestGlass, w: 24, h: 24 },\n\tshopify: { Icon: Shopify, w: 21, h: 24 },\n};\n"],"names":["SOURCE_ICONS","ManifestGlass","Shopify"],"mappings":"gMAcaA,EAA2C,CACvD,SAAU,CAAE,KAAMC,EAAAA,QAAe,EAAG,GAAI,EAAG,EAAA,EAC3C,QAAS,CAAE,KAAMC,EAAAA,QAAS,EAAG,GAAI,EAAG,EAAA,CACrC"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),n=require("react"),G=require("../TablePagination/TablePagination.js"),J=require("../zeroState/ZeroState.js"),A=require("./AgentListing.styled.js"),K=require("./AgentListingFilters.js"),Q=require("./AgentListingHeader.js"),U=require("./AgentTable.js"),W=require("./DeleteAgentModal.js"),x=({config:L,onSearchChange:C,onFilterChange:o,onSortChange:r,onNewAgent:m,onBrowseTemplates:g,onRunAgent:p,onEditAgent:S,onDeleteAgent:l,onRowClick:c,...q})=>{const[i,u]=n.useState(null),[y,k]=n.useState(!1),{agents:N,isLoading:d,searchValue:w,searchPlaceholder:T="Search",filterOptions:R,filterPlaceholder:v="Filters",sortOptions:z,selectedSort:D,title:F="AI Agents",pagination:s,emptyState:h,debugLog:P}=L,O=!d&&N.length===0,t=n.useCallback((e,...b)=>{P&&console.log(`[AgentListing] ${e}`,...b)},[P]),B=n.useCallback(e=>{t("onSearchChange",e),C(e)},[t,C]),E=n.useCallback(e=>{t("onFilterChange",e),o?.(e)},[t,o]),I=n.useCallback(e=>{t("onSortChange",e),r?.(e)},[t,r]),f=n.useCallback(()=>{t("onNewAgent"),m()},[t,m]),H=n.useCallback(()=>{t("onBrowseTemplates"),g?.()},[t,g]),M=n.useCallback(e=>{t("onRunAgent",e.id),p(e)},[t,p]),Z=n.useCallback(e=>{t("onEditAgent",e.id),S(e)},[t,S]),V=n.useCallback(e=>{t("onRowClick",e.id),c?.(e)},[t,c]),_=n.useCallback(e=>{t("onDeleteAgent",e.id),u(e)},[t]),$=n.useCallback(async()=>{if(!(!i||!l)){k(!0);try{await l(i),u(null)}finally{k(!1)}}},[i,l]);return a.jsxs(A.Page,{"data-test":q["data-test"]??"agent-listing",children:[a.jsx(Q.AgentListingHeader,{title:F,onNewAgent:f,onBrowseTemplates:g?H:void 0}),a.jsx(K.AgentListingFilters,{searchValue:w,onSearchChange:B,searchPlaceholder:T,filterOptions:R,onFilterChange:o?E:void 0,filterPlaceholder:v,sortOptions:z,selectedSort:D,onSortChange:r?I:void 0}),a.jsx(A.Body,{children:d||O?a.jsx(A.EmptyHolder,{children:a.jsx(J.ZeroState,{isLoading:d,title:h?.title??"No agents yet",subTitle:h?.subTitle??"Create your first AI agent to start automating conversations.",actionButton:h?.actionButton??{buttonText:"New AI agent",buttonType:"primary",size:"small",onClick:f}})}):a.jsxs(a.Fragment,{children:[a.jsx(U.AgentTable,{agents:N,onRunAgent:M,onEditAgent:Z,onDeleteAgent:l?_:void 0,onRowClick:c?V:void 0}),s&&s.totalRows>0&&a.jsx(G.TablePagination,{pageNumber:s.pageNumber,pageSize:s.pageSize,totalRows:s.totalRows,hidePageSizeOptions:s.hidePageSizeOptions,updatePageNumber:s.onPageChange,updatePageSize:e=>{const b=Array.isArray(e)?e[0]:e,j=Number(b?.value);Number.isNaN(j)||s.onPageSizeChange(j)}})]})}),i&&a.jsx(W.DeleteAgentModal,{agentName:i.name,isDeleting:y,onClose:()=>y?void 0:u(null),onConfirm:$})]})};x.displayName="AgentListing";exports.AgentListing=x;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),n=require("react"),K=require("../TablePagination/TablePagination.js"),Q=require("../zeroState/ZeroState.js"),C=require("./AgentListing.styled.js"),U=require("./AgentListingFilters.js"),W=require("./AgentListingHeader.js"),X=require("./AgentTable.js"),Y=require("./DeleteAgentModal.js"),L=({config:q,onSearchChange:m,onSearchSubmit:o,onFilterChange:r,onSortChange:g,onNewAgent:S,onBrowseTemplates:c,onRunAgent:p,onEditAgent:y,onDeleteAgent:l,onRowClick:u,...w})=>{const[i,d]=n.useState(null),[k,N]=n.useState(!1),{agents:P,isLoading:h,searchValue:T,searchPlaceholder:R="Search",filterOptions:v,filterPlaceholder:z="Filters",sortOptions:D,selectedSort:F,title:O="AI Agents",pagination:s,emptyState:b,debugLog:f}=q,B=!h&&P.length===0,t=n.useCallback((e,...A)=>{f&&console.log(`[AgentListing] ${e}`,...A)},[f]),E=n.useCallback(e=>{t("onSearchChange",e),m(e)},[t,m]),I=n.useCallback(e=>{t("onSearchSubmit",e),o?.(e)},[t,o]),H=n.useCallback(e=>{t("onFilterChange",e),r?.(e)},[t,r]),M=n.useCallback(e=>{t("onSortChange",e),g?.(e)},[t,g]),j=n.useCallback(()=>{t("onNewAgent"),S()},[t,S]),Z=n.useCallback(()=>{t("onBrowseTemplates"),c?.()},[t,c]),V=n.useCallback(e=>{t("onRunAgent",e.id),p(e)},[t,p]),_=n.useCallback(e=>{t("onEditAgent",e.id),y(e)},[t,y]),$=n.useCallback(e=>{t("onRowClick",e.id),u?.(e)},[t,u]),G=n.useCallback(e=>{t("onDeleteAgent",e.id),d(e)},[t]),J=n.useCallback(async()=>{if(!(!i||!l)){N(!0);try{await l(i),d(null)}finally{N(!1)}}},[i,l]);return a.jsxs(C.Page,{"data-test":w["data-test"]??"agent-listing",children:[a.jsx(W.AgentListingHeader,{title:O,onNewAgent:j,onBrowseTemplates:c?Z:void 0}),a.jsx(U.AgentListingFilters,{searchValue:T,onSearchChange:E,onSearchSubmit:o?I:void 0,searchPlaceholder:R,filterOptions:v,onFilterChange:r?H:void 0,filterPlaceholder:z,sortOptions:D,selectedSort:F,onSortChange:g?M:void 0}),a.jsx(C.Body,{children:h||B?a.jsx(C.EmptyHolder,{children:a.jsx(Q.ZeroState,{isLoading:h,title:b?.title??"No agents yet",subTitle:b?.subTitle??"Create your first AI agent to start automating conversations.",actionButton:b?.actionButton??{buttonText:"New AI agent",buttonType:"primary",size:"small",onClick:j}})}):a.jsxs(a.Fragment,{children:[a.jsx(X.AgentTable,{agents:P,onRunAgent:V,onEditAgent:_,onDeleteAgent:l?G:void 0,onRowClick:u?$:void 0}),s&&s.totalRows>0&&a.jsx(K.TablePagination,{pageNumber:s.pageNumber,pageSize:s.pageSize,totalRows:s.totalRows,hidePageSizeOptions:s.hidePageSizeOptions,updatePageNumber:s.onPageChange,updatePageSize:e=>{const A=Array.isArray(e)?e[0]:e,x=Number(A?.value);Number.isNaN(x)||s.onPageSizeChange(x)}})]})}),i&&a.jsx(Y.DeleteAgentModal,{agentName:i.name,isDeleting:k,onClose:()=>k?void 0:d(null),onConfirm:J})]})};L.displayName="AgentListing";exports.AgentListing=L;
2
2
  //# sourceMappingURL=AgentListing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentListing.js","sources":["../../../../src/components/agent-listing/AgentListing.tsx"],"sourcesContent":["import React, { useCallback, useState } from 'react';\nimport { DropdownOption } from '@src/components/dropdown/type';\nimport { TablePagination } from '@src/components/TablePagination/TablePagination';\nimport { ZeroState } from '@src/components/zeroState/ZeroState';\nimport { AgentListingProps, AgentListItem } from './AgentListing.model';\nimport { Body, EmptyHolder, Page } from './AgentListing.styled';\nimport { AgentListingFilters } from './AgentListingFilters';\nimport { AgentListingHeader } from './AgentListingHeader';\nimport { AgentTable } from './AgentTable';\nimport { DeleteAgentModal } from './DeleteAgentModal';\n\n/**\n * Full body of the \"AI Agents\" listing screen (header + filters + table).\n * Presentational and fully controlled — the consumer owns data, search, sort,\n * pagination and routing. Render it inside your app shell (next to the sidebar).\n *\n * @example\n * <AgentListing\n * agents={rows}\n * searchValue={search}\n * onSearchChange={setSearch}\n * onNewAgent={() => router.push('/agents/new')}\n * onRunAgent={runAgent}\n * onEditAgent={(a) => router.push(`/agents/${a.id}`)}\n * />\n */\nexport const AgentListing: React.FC<AgentListingProps> = ({\n\tconfig,\n\tonSearchChange,\n\tonFilterChange,\n\tonSortChange,\n\tonNewAgent,\n\tonBrowseTemplates,\n\tonRunAgent,\n\tonEditAgent,\n\tonDeleteAgent,\n\tonRowClick,\n\t...rest\n}) => {\n\t// Agent pending delete-confirmation (null = dialog closed).\n\tconst [pendingDelete, setPendingDelete] = useState<AgentListItem | null>(\n\t\tnull,\n\t);\n\tconst [isDeleting, setIsDeleting] = useState(false);\n\tconst {\n\t\tagents,\n\t\tisLoading,\n\t\tsearchValue,\n\t\tsearchPlaceholder = 'Search',\n\t\tfilterOptions,\n\t\tfilterPlaceholder = 'Filters',\n\t\tsortOptions,\n\t\tselectedSort,\n\t\ttitle = 'AI Agents',\n\t\tpagination,\n\t\temptyState,\n\t\tdebugLog,\n\t} = config;\n\n\tconst showEmpty = !isLoading && agents.length === 0;\n\n\t// Gated debug logging: each handler logs at its start only when `debugLog`.\n\tconst logAction = useCallback(\n\t\t(action: string, ...args: unknown[]) => {\n\t\t\tif (debugLog) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.log(`[AgentListing] ${action}`, ...args);\n\t\t\t}\n\t\t},\n\t\t[debugLog],\n\t);\n\n\tconst handleSearchChange = useCallback(\n\t\t(v: string) => {\n\t\t\tlogAction('onSearchChange', v);\n\t\t\tonSearchChange(v);\n\t\t},\n\t\t[logAction, onSearchChange],\n\t);\n\tconst handleFilterChange = useCallback(\n\t\t(selected: DropdownOption | DropdownOption[]) => {\n\t\t\tlogAction('onFilterChange', selected);\n\t\t\tonFilterChange?.(selected);\n\t\t},\n\t\t[logAction, onFilterChange],\n\t);\n\tconst handleSortChange = useCallback(\n\t\t(v: string) => {\n\t\t\tlogAction('onSortChange', v);\n\t\t\tonSortChange?.(v);\n\t\t},\n\t\t[logAction, onSortChange],\n\t);\n\tconst handleNewAgent = useCallback(() => {\n\t\tlogAction('onNewAgent');\n\t\tonNewAgent();\n\t}, [logAction, onNewAgent]);\n\tconst handleBrowseTemplates = useCallback(() => {\n\t\tlogAction('onBrowseTemplates');\n\t\tonBrowseTemplates?.();\n\t}, [logAction, onBrowseTemplates]);\n\tconst handleRunAgent = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onRunAgent', agent.id);\n\t\t\tonRunAgent(agent);\n\t\t},\n\t\t[logAction, onRunAgent],\n\t);\n\tconst handleEditAgent = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onEditAgent', agent.id);\n\t\t\tonEditAgent(agent);\n\t\t},\n\t\t[logAction, onEditAgent],\n\t);\n\tconst handleRowClick = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onRowClick', agent.id);\n\t\t\tonRowClick?.(agent);\n\t\t},\n\t\t[logAction, onRowClick],\n\t);\n\t// Row delete just opens the confirm dialog; the actual delete runs on confirm.\n\tconst handleDeleteRequest = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onDeleteAgent', agent.id);\n\t\t\tsetPendingDelete(agent);\n\t\t},\n\t\t[logAction],\n\t);\n\tconst handleConfirmDelete = useCallback(async () => {\n\t\tif (!pendingDelete || !onDeleteAgent) {\n\t\t\treturn;\n\t\t}\n\t\tsetIsDeleting(true);\n\t\ttry {\n\t\t\tawait onDeleteAgent(pendingDelete);\n\t\t\tsetPendingDelete(null);\n\t\t} finally {\n\t\t\tsetIsDeleting(false);\n\t\t}\n\t}, [pendingDelete, onDeleteAgent]);\n\n\treturn (\n\t\t<Page data-test={rest['data-test'] ?? 'agent-listing'}>\n\t\t\t<AgentListingHeader\n\t\t\t\ttitle={title}\n\t\t\t\tonNewAgent={handleNewAgent}\n\t\t\t\tonBrowseTemplates={\n\t\t\t\t\tonBrowseTemplates ? handleBrowseTemplates : undefined\n\t\t\t\t}\n\t\t\t/>\n\n\t\t\t<AgentListingFilters\n\t\t\t\tsearchValue={searchValue}\n\t\t\t\tonSearchChange={handleSearchChange}\n\t\t\t\tsearchPlaceholder={searchPlaceholder}\n\t\t\t\tfilterOptions={filterOptions}\n\t\t\t\tonFilterChange={onFilterChange ? handleFilterChange : undefined}\n\t\t\t\tfilterPlaceholder={filterPlaceholder}\n\t\t\t\tsortOptions={sortOptions}\n\t\t\t\tselectedSort={selectedSort}\n\t\t\t\tonSortChange={onSortChange ? handleSortChange : undefined}\n\t\t\t/>\n\n\t\t\t<Body>\n\t\t\t\t{isLoading || showEmpty ? (\n\t\t\t\t\t<EmptyHolder>\n\t\t\t\t\t\t<ZeroState\n\t\t\t\t\t\t\tisLoading={isLoading}\n\t\t\t\t\t\t\ttitle={emptyState?.title ?? 'No agents yet'}\n\t\t\t\t\t\t\tsubTitle={\n\t\t\t\t\t\t\t\temptyState?.subTitle ??\n\t\t\t\t\t\t\t\t'Create your first AI agent to start automating conversations.'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tactionButton={\n\t\t\t\t\t\t\t\temptyState?.actionButton ?? {\n\t\t\t\t\t\t\t\t\tbuttonText: 'New AI agent',\n\t\t\t\t\t\t\t\t\tbuttonType: 'primary',\n\t\t\t\t\t\t\t\t\tsize: 'small',\n\t\t\t\t\t\t\t\t\tonClick: handleNewAgent,\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</EmptyHolder>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<AgentTable\n\t\t\t\t\t\t\tagents={agents}\n\t\t\t\t\t\t\tonRunAgent={handleRunAgent}\n\t\t\t\t\t\t\tonEditAgent={handleEditAgent}\n\t\t\t\t\t\t\tonDeleteAgent={onDeleteAgent ? handleDeleteRequest : undefined}\n\t\t\t\t\t\t\tonRowClick={onRowClick ? handleRowClick : undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{pagination && pagination.totalRows > 0 && (\n\t\t\t\t\t\t\t<TablePagination\n\t\t\t\t\t\t\t\tpageNumber={pagination.pageNumber}\n\t\t\t\t\t\t\t\tpageSize={pagination.pageSize}\n\t\t\t\t\t\t\t\ttotalRows={pagination.totalRows}\n\t\t\t\t\t\t\t\thidePageSizeOptions={pagination.hidePageSizeOptions}\n\t\t\t\t\t\t\t\tupdatePageNumber={pagination.onPageChange}\n\t\t\t\t\t\t\t\tupdatePageSize={(opt) => {\n\t\t\t\t\t\t\t\t\tconst single = Array.isArray(opt) ? opt[0] : opt;\n\t\t\t\t\t\t\t\t\tconst value = Number((single as { value?: string })?.value);\n\t\t\t\t\t\t\t\t\tif (!Number.isNaN(value)) {\n\t\t\t\t\t\t\t\t\t\tpagination.onPageSizeChange(value);\n\t\t\t\t\t\t\t\t\t}\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</>\n\t\t\t\t)}\n\t\t\t</Body>\n\n\t\t\t{pendingDelete && (\n\t\t\t\t<DeleteAgentModal\n\t\t\t\t\tagentName={pendingDelete.name}\n\t\t\t\t\tisDeleting={isDeleting}\n\t\t\t\t\tonClose={() => (isDeleting ? undefined : setPendingDelete(null))}\n\t\t\t\t\tonConfirm={handleConfirmDelete}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Page>\n\t);\n};\n\nAgentListing.displayName = 'AgentListing';\n"],"names":["AgentListing","config","onSearchChange","onFilterChange","onSortChange","onNewAgent","onBrowseTemplates","onRunAgent","onEditAgent","onDeleteAgent","onRowClick","rest","pendingDelete","setPendingDelete","useState","isDeleting","setIsDeleting","agents","isLoading","searchValue","searchPlaceholder","filterOptions","filterPlaceholder","sortOptions","selectedSort","title","pagination","emptyState","debugLog","showEmpty","logAction","useCallback","action","args","handleSearchChange","v","handleFilterChange","selected","handleSortChange","handleNewAgent","handleBrowseTemplates","handleRunAgent","agent","handleEditAgent","handleRowClick","handleDeleteRequest","handleConfirmDelete","Page","jsx","AgentListingHeader","AgentListingFilters","Body","EmptyHolder","ZeroState","jsxs","Fragment","AgentTable","TablePagination","opt","single","value","DeleteAgentModal"],"mappings":"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"}
1
+ {"version":3,"file":"AgentListing.js","sources":["../../../../src/components/agent-listing/AgentListing.tsx"],"sourcesContent":["import React, { useCallback, useState } from 'react';\nimport { DropdownOption } from '@src/components/dropdown/type';\nimport { TablePagination } from '@src/components/TablePagination/TablePagination';\nimport { ZeroState } from '@src/components/zeroState/ZeroState';\nimport { AgentListingProps, AgentListItem } from './AgentListing.model';\nimport { Body, EmptyHolder, Page } from './AgentListing.styled';\nimport { AgentListingFilters } from './AgentListingFilters';\nimport { AgentListingHeader } from './AgentListingHeader';\nimport { AgentTable } from './AgentTable';\nimport { DeleteAgentModal } from './DeleteAgentModal';\n\n/**\n * Full body of the \"AI Agents\" listing screen (header + filters + table).\n * Presentational and fully controlled — the consumer owns data, search, sort,\n * pagination and routing. Render it inside your app shell (next to the sidebar).\n *\n * @example\n * <AgentListing\n * agents={rows}\n * searchValue={search}\n * onSearchChange={setSearch}\n * onNewAgent={() => router.push('/agents/new')}\n * onRunAgent={runAgent}\n * onEditAgent={(a) => router.push(`/agents/${a.id}`)}\n * />\n */\nexport const AgentListing: React.FC<AgentListingProps> = ({\n\tconfig,\n\tonSearchChange,\n\tonSearchSubmit,\n\tonFilterChange,\n\tonSortChange,\n\tonNewAgent,\n\tonBrowseTemplates,\n\tonRunAgent,\n\tonEditAgent,\n\tonDeleteAgent,\n\tonRowClick,\n\t...rest\n}) => {\n\t// Agent pending delete-confirmation (null = dialog closed).\n\tconst [pendingDelete, setPendingDelete] = useState<AgentListItem | null>(\n\t\tnull,\n\t);\n\tconst [isDeleting, setIsDeleting] = useState(false);\n\tconst {\n\t\tagents,\n\t\tisLoading,\n\t\tsearchValue,\n\t\tsearchPlaceholder = 'Search',\n\t\tfilterOptions,\n\t\tfilterPlaceholder = 'Filters',\n\t\tsortOptions,\n\t\tselectedSort,\n\t\ttitle = 'AI Agents',\n\t\tpagination,\n\t\temptyState,\n\t\tdebugLog,\n\t} = config;\n\n\tconst showEmpty = !isLoading && agents.length === 0;\n\n\t// Gated debug logging: each handler logs at its start only when `debugLog`.\n\tconst logAction = useCallback(\n\t\t(action: string, ...args: unknown[]) => {\n\t\t\tif (debugLog) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.log(`[AgentListing] ${action}`, ...args);\n\t\t\t}\n\t\t},\n\t\t[debugLog],\n\t);\n\n\tconst handleSearchChange = useCallback(\n\t\t(v: string) => {\n\t\t\tlogAction('onSearchChange', v);\n\t\t\tonSearchChange(v);\n\t\t},\n\t\t[logAction, onSearchChange],\n\t);\n\tconst handleSearchSubmit = useCallback(\n\t\t(v: string) => {\n\t\t\tlogAction('onSearchSubmit', v);\n\t\t\tonSearchSubmit?.(v);\n\t\t},\n\t\t[logAction, onSearchSubmit],\n\t);\n\tconst handleFilterChange = useCallback(\n\t\t(selected: DropdownOption | DropdownOption[]) => {\n\t\t\tlogAction('onFilterChange', selected);\n\t\t\tonFilterChange?.(selected);\n\t\t},\n\t\t[logAction, onFilterChange],\n\t);\n\tconst handleSortChange = useCallback(\n\t\t(v: string) => {\n\t\t\tlogAction('onSortChange', v);\n\t\t\tonSortChange?.(v);\n\t\t},\n\t\t[logAction, onSortChange],\n\t);\n\tconst handleNewAgent = useCallback(() => {\n\t\tlogAction('onNewAgent');\n\t\tonNewAgent();\n\t}, [logAction, onNewAgent]);\n\tconst handleBrowseTemplates = useCallback(() => {\n\t\tlogAction('onBrowseTemplates');\n\t\tonBrowseTemplates?.();\n\t}, [logAction, onBrowseTemplates]);\n\tconst handleRunAgent = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onRunAgent', agent.id);\n\t\t\tonRunAgent(agent);\n\t\t},\n\t\t[logAction, onRunAgent],\n\t);\n\tconst handleEditAgent = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onEditAgent', agent.id);\n\t\t\tonEditAgent(agent);\n\t\t},\n\t\t[logAction, onEditAgent],\n\t);\n\tconst handleRowClick = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onRowClick', agent.id);\n\t\t\tonRowClick?.(agent);\n\t\t},\n\t\t[logAction, onRowClick],\n\t);\n\t// Row delete just opens the confirm dialog; the actual delete runs on confirm.\n\tconst handleDeleteRequest = useCallback(\n\t\t(agent: AgentListItem) => {\n\t\t\tlogAction('onDeleteAgent', agent.id);\n\t\t\tsetPendingDelete(agent);\n\t\t},\n\t\t[logAction],\n\t);\n\tconst handleConfirmDelete = useCallback(async () => {\n\t\tif (!pendingDelete || !onDeleteAgent) {\n\t\t\treturn;\n\t\t}\n\t\tsetIsDeleting(true);\n\t\ttry {\n\t\t\tawait onDeleteAgent(pendingDelete);\n\t\t\tsetPendingDelete(null);\n\t\t} finally {\n\t\t\tsetIsDeleting(false);\n\t\t}\n\t}, [pendingDelete, onDeleteAgent]);\n\n\treturn (\n\t\t<Page data-test={rest['data-test'] ?? 'agent-listing'}>\n\t\t\t<AgentListingHeader\n\t\t\t\ttitle={title}\n\t\t\t\tonNewAgent={handleNewAgent}\n\t\t\t\tonBrowseTemplates={\n\t\t\t\t\tonBrowseTemplates ? handleBrowseTemplates : undefined\n\t\t\t\t}\n\t\t\t/>\n\n\t\t\t<AgentListingFilters\n\t\t\t\tsearchValue={searchValue}\n\t\t\t\tonSearchChange={handleSearchChange}\n\t\t\t\tonSearchSubmit={onSearchSubmit ? handleSearchSubmit : undefined}\n\t\t\t\tsearchPlaceholder={searchPlaceholder}\n\t\t\t\tfilterOptions={filterOptions}\n\t\t\t\tonFilterChange={onFilterChange ? handleFilterChange : undefined}\n\t\t\t\tfilterPlaceholder={filterPlaceholder}\n\t\t\t\tsortOptions={sortOptions}\n\t\t\t\tselectedSort={selectedSort}\n\t\t\t\tonSortChange={onSortChange ? handleSortChange : undefined}\n\t\t\t/>\n\n\t\t\t<Body>\n\t\t\t\t{isLoading || showEmpty ? (\n\t\t\t\t\t<EmptyHolder>\n\t\t\t\t\t\t<ZeroState\n\t\t\t\t\t\t\tisLoading={isLoading}\n\t\t\t\t\t\t\ttitle={emptyState?.title ?? 'No agents yet'}\n\t\t\t\t\t\t\tsubTitle={\n\t\t\t\t\t\t\t\temptyState?.subTitle ??\n\t\t\t\t\t\t\t\t'Create your first AI agent to start automating conversations.'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tactionButton={\n\t\t\t\t\t\t\t\temptyState?.actionButton ?? {\n\t\t\t\t\t\t\t\t\tbuttonText: 'New AI agent',\n\t\t\t\t\t\t\t\t\tbuttonType: 'primary',\n\t\t\t\t\t\t\t\t\tsize: 'small',\n\t\t\t\t\t\t\t\t\tonClick: handleNewAgent,\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</EmptyHolder>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<AgentTable\n\t\t\t\t\t\t\tagents={agents}\n\t\t\t\t\t\t\tonRunAgent={handleRunAgent}\n\t\t\t\t\t\t\tonEditAgent={handleEditAgent}\n\t\t\t\t\t\t\tonDeleteAgent={onDeleteAgent ? handleDeleteRequest : undefined}\n\t\t\t\t\t\t\tonRowClick={onRowClick ? handleRowClick : undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{pagination && pagination.totalRows > 0 && (\n\t\t\t\t\t\t\t<TablePagination\n\t\t\t\t\t\t\t\tpageNumber={pagination.pageNumber}\n\t\t\t\t\t\t\t\tpageSize={pagination.pageSize}\n\t\t\t\t\t\t\t\ttotalRows={pagination.totalRows}\n\t\t\t\t\t\t\t\thidePageSizeOptions={pagination.hidePageSizeOptions}\n\t\t\t\t\t\t\t\tupdatePageNumber={pagination.onPageChange}\n\t\t\t\t\t\t\t\tupdatePageSize={(opt) => {\n\t\t\t\t\t\t\t\t\tconst single = Array.isArray(opt) ? opt[0] : opt;\n\t\t\t\t\t\t\t\t\tconst value = Number((single as { value?: string })?.value);\n\t\t\t\t\t\t\t\t\tif (!Number.isNaN(value)) {\n\t\t\t\t\t\t\t\t\t\tpagination.onPageSizeChange(value);\n\t\t\t\t\t\t\t\t\t}\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</>\n\t\t\t\t)}\n\t\t\t</Body>\n\n\t\t\t{pendingDelete && (\n\t\t\t\t<DeleteAgentModal\n\t\t\t\t\tagentName={pendingDelete.name}\n\t\t\t\t\tisDeleting={isDeleting}\n\t\t\t\t\tonClose={() => (isDeleting ? undefined : setPendingDelete(null))}\n\t\t\t\t\tonConfirm={handleConfirmDelete}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Page>\n\t);\n};\n\nAgentListing.displayName = 'AgentListing';\n"],"names":["AgentListing","config","onSearchChange","onSearchSubmit","onFilterChange","onSortChange","onNewAgent","onBrowseTemplates","onRunAgent","onEditAgent","onDeleteAgent","onRowClick","rest","pendingDelete","setPendingDelete","useState","isDeleting","setIsDeleting","agents","isLoading","searchValue","searchPlaceholder","filterOptions","filterPlaceholder","sortOptions","selectedSort","title","pagination","emptyState","debugLog","showEmpty","logAction","useCallback","action","args","handleSearchChange","v","handleSearchSubmit","handleFilterChange","selected","handleSortChange","handleNewAgent","handleBrowseTemplates","handleRunAgent","agent","handleEditAgent","handleRowClick","handleDeleteRequest","handleConfirmDelete","Page","jsx","AgentListingHeader","AgentListingFilters","Body","EmptyHolder","ZeroState","jsxs","Fragment","AgentTable","TablePagination","opt","single","value","DeleteAgentModal"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),x=require("../../assets/icons/search.svg.js"),w=require("../../constants/Theme.js"),o=require("./AgentListing.styled.js"),j=require("../input/Input.js"),a=require("../dropdown/Dropdown.js"),v=({searchValue:c,onSearchChange:u,searchPlaceholder:d,filterOptions:r,onFilterChange:s,filterPlaceholder:h,sortOptions:l,selectedSort:p,onSortChange:n})=>{const g=(l??[]).map(e=>({label:e.label,value:e.value,selected:e.value===p}));return t.jsxs(o.FilterRow,{children:[t.jsxs(o.FilterRowLeft,{children:[t.jsx(j.Input,{"data-test":"agent-search",variant:"small",width:"320px",type:"text",value:c,placeholder:d,hideInputHeader:!0,noErrorHint:!0,leftIcon:{icon:()=>t.jsx(x.default,{width:18,height:18,color:w.COLORS.content.placeholder})},onChangeText:e=>u(e)}),r&&s&&t.jsx(a.Dropdown,{"data-test":"agent-filters",size:"small",width:"140px",placeHolder:h,showPlaceholderWhenSelected:!0,options:r,isMultiSelect:!0,onSelect:s})]}),l&&n&&t.jsx(a.Dropdown,{"data-test":"agent-sort",size:"small",width:"200px",options:g,onSelect:e=>{const i=(Array.isArray(e)?e[0]:e)?.value;i&&n(i)}})]})};exports.AgentListingFilters=v;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),x=require("../../assets/icons/search.svg.js"),v=require("../../constants/Theme.js"),a=require("./AgentListing.styled.js"),j=require("../input/Input.js"),c=require("../dropdown/Dropdown.js"),y=({searchValue:d,onSearchChange:u,onSearchSubmit:r,searchPlaceholder:h,filterOptions:n,onFilterChange:s,filterPlaceholder:p,sortOptions:l,selectedSort:g,onSortChange:i})=>{const w=(l??[]).map(e=>({label:e.label,value:e.value,selected:e.value===g}));return t.jsxs(a.FilterRow,{children:[t.jsxs(a.FilterRowLeft,{children:[t.jsx(j.Input,{"data-test":"agent-search",variant:"small",width:"320px",type:"text",value:d,placeholder:h,hideInputHeader:!0,noErrorHint:!0,leftIcon:{icon:()=>t.jsx(x.default,{width:18,height:18,color:v.COLORS.content.placeholder})},onChangeText:e=>u(e),onKeyDownEvent:r?e=>{e.key==="Enter"&&r(e.target.value)}:void 0}),n&&s&&t.jsx(c.Dropdown,{"data-test":"agent-filters",size:"small",width:"140px",placeHolder:p,showPlaceholderWhenSelected:!0,options:n,isMultiSelect:!0,onSelect:s})]}),l&&i&&t.jsx(c.Dropdown,{"data-test":"agent-sort",size:"small",width:"200px",options:w,onSelect:e=>{const o=(Array.isArray(e)?e[0]:e)?.value;o&&i(o)}})]})};exports.AgentListingFilters=y;
2
2
  //# sourceMappingURL=AgentListingFilters.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentListingFilters.js","sources":["../../../../src/components/agent-listing/AgentListingFilters.tsx"],"sourcesContent":["import SearchIcon from '@src/assets/icons/search.svg';\nimport React from 'react';\nimport { Dropdown } from '@src/components/dropdown';\nimport { DropdownOption, SingleOption } from '@src/components/dropdown/type';\nimport { Input } from '@src/components/input';\nimport { COLORS } from '@src/constants/Theme';\nimport { AgentListSortOption } from './AgentListing.model';\nimport { FilterRow, FilterRowLeft } from './AgentListing.styled';\n\ninterface AgentListingFiltersProps {\n\tsearchValue: string;\n\tonSearchChange: (value: string) => void;\n\tsearchPlaceholder: string;\n\n\tfilterOptions?: DropdownOption[];\n\tonFilterChange?: (selected: DropdownOption | DropdownOption[]) => void;\n\tfilterPlaceholder: string;\n\n\tsortOptions?: AgentListSortOption[];\n\tselectedSort?: string;\n\tonSortChange?: (value: string) => void;\n}\n\nexport const AgentListingFilters: React.FC<AgentListingFiltersProps> = ({\n\tsearchValue,\n\tonSearchChange,\n\tsearchPlaceholder,\n\tfilterOptions,\n\tonFilterChange,\n\tfilterPlaceholder,\n\tsortOptions,\n\tselectedSort,\n\tonSortChange,\n}) => {\n\tconst sortDropdownOptions: SingleOption[] = (sortOptions ?? []).map((o) => ({\n\t\tlabel: o.label,\n\t\tvalue: o.value,\n\t\tselected: o.value === selectedSort,\n\t}));\n\n\treturn (\n\t\t<FilterRow>\n\t\t\t<FilterRowLeft>\n\t\t\t\t<Input\n\t\t\t\t\tdata-test=\"agent-search\"\n\t\t\t\t\tvariant=\"small\"\n\t\t\t\t\twidth=\"320px\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tvalue={searchValue}\n\t\t\t\t\tplaceholder={searchPlaceholder}\n\t\t\t\t\thideInputHeader\n\t\t\t\t\tnoErrorHint\n\t\t\t\t\tleftIcon={{\n\t\t\t\t\t\ticon: () => (\n\t\t\t\t\t\t\t<SearchIcon\n\t\t\t\t\t\t\t\twidth={18}\n\t\t\t\t\t\t\t\theight={18}\n\t\t\t\t\t\t\t\tcolor={COLORS.content.placeholder}\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\tonChangeText={(text) => onSearchChange(text)}\n\t\t\t\t/>\n\n\t\t\t\t{filterOptions && onFilterChange && (\n\t\t\t\t\t<Dropdown\n\t\t\t\t\t\tdata-test=\"agent-filters\"\n\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\twidth=\"140px\"\n\t\t\t\t\t\tplaceHolder={filterPlaceholder}\n\t\t\t\t\t\tshowPlaceholderWhenSelected\n\t\t\t\t\t\toptions={filterOptions}\n\t\t\t\t\t\tisMultiSelect\n\t\t\t\t\t\tonSelect={onFilterChange}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</FilterRowLeft>\n\n\t\t\t{sortOptions && onSortChange && (\n\t\t\t\t<Dropdown\n\t\t\t\t\tdata-test=\"agent-sort\"\n\t\t\t\t\tsize=\"small\"\n\t\t\t\t\twidth=\"200px\"\n\t\t\t\t\toptions={sortDropdownOptions}\n\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\tconst single = Array.isArray(opt) ? opt[0] : opt;\n\t\t\t\t\t\tconst value = (single as SingleOption)?.value;\n\t\t\t\t\t\tif (value) {\n\t\t\t\t\t\t\tonSortChange(value);\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</FilterRow>\n\t);\n};\n"],"names":["AgentListingFilters","searchValue","onSearchChange","searchPlaceholder","filterOptions","onFilterChange","filterPlaceholder","sortOptions","selectedSort","onSortChange","sortDropdownOptions","o","FilterRow","jsxs","FilterRowLeft","jsx","Input","SearchIcon","COLORS","text","Dropdown","opt","value"],"mappings":"mTAuBaA,EAA0D,CAAC,CACvE,YAAAC,EACA,eAAAC,EACA,kBAAAC,EACA,cAAAC,EACA,eAAAC,EACA,kBAAAC,EACA,YAAAC,EACA,aAAAC,EACA,aAAAC,CACD,IAAM,CACL,MAAMC,GAAuCH,GAAe,CAAA,GAAI,IAAKI,IAAO,CAC3E,MAAOA,EAAE,MACT,MAAOA,EAAE,MACT,SAAUA,EAAE,QAAUH,CAAA,EACrB,EAEF,cACEI,YAAA,CACA,SAAA,CAAAC,OAACC,EAAAA,cAAA,CACA,SAAA,CAAAC,EAAAA,IAACC,EAAAA,MAAA,CACA,YAAU,eACV,QAAQ,QACR,MAAM,QACN,KAAK,OACL,MAAOf,EACP,YAAaE,EACb,gBAAe,GACf,YAAW,GACX,SAAU,CACT,KAAM,IACLY,EAAAA,IAACE,EAAAA,QAAA,CACA,MAAO,GACP,OAAQ,GACR,MAAOC,EAAAA,OAAO,QAAQ,WAAA,CAAA,CACvB,EAGF,aAAeC,GAASjB,EAAeiB,CAAI,CAAA,CAAA,EAG3Cf,GAAiBC,GACjBU,EAAAA,IAACK,EAAAA,SAAA,CACA,YAAU,gBACV,KAAK,QACL,MAAM,QACN,YAAad,EACb,4BAA2B,GAC3B,QAASF,EACT,cAAa,GACb,SAAUC,CAAA,CAAA,CACX,EAEF,EAECE,GAAeE,GACfM,EAAAA,IAACK,EAAAA,SAAA,CACA,YAAU,aACV,KAAK,QACL,MAAM,QACN,QAASV,EACT,SAAWW,GAAQ,CAElB,MAAMC,GADS,MAAM,QAAQD,CAAG,EAAIA,EAAI,CAAC,EAAIA,IACL,MACpCC,GACHb,EAAaa,CAAK,CAEpB,CAAA,CAAA,CACD,EAEF,CAEF"}
1
+ {"version":3,"file":"AgentListingFilters.js","sources":["../../../../src/components/agent-listing/AgentListingFilters.tsx"],"sourcesContent":["import SearchIcon from '@src/assets/icons/search.svg';\nimport React from 'react';\nimport { Dropdown } from '@src/components/dropdown';\nimport { DropdownOption, SingleOption } from '@src/components/dropdown/type';\nimport { Input } from '@src/components/input';\nimport { COLORS } from '@src/constants/Theme';\nimport { AgentListSortOption } from './AgentListing.model';\nimport { FilterRow, FilterRowLeft } from './AgentListing.styled';\n\ninterface AgentListingFiltersProps {\n\tsearchValue: string;\n\tonSearchChange: (value: string) => void;\n\t/** When set, Enter in the search box runs the search (typing only edits text). */\n\tonSearchSubmit?: (value: string) => void;\n\tsearchPlaceholder: string;\n\n\tfilterOptions?: DropdownOption[];\n\tonFilterChange?: (selected: DropdownOption | DropdownOption[]) => void;\n\tfilterPlaceholder: string;\n\n\tsortOptions?: AgentListSortOption[];\n\tselectedSort?: string;\n\tonSortChange?: (value: string) => void;\n}\n\nexport const AgentListingFilters: React.FC<AgentListingFiltersProps> = ({\n\tsearchValue,\n\tonSearchChange,\n\tonSearchSubmit,\n\tsearchPlaceholder,\n\tfilterOptions,\n\tonFilterChange,\n\tfilterPlaceholder,\n\tsortOptions,\n\tselectedSort,\n\tonSortChange,\n}) => {\n\tconst sortDropdownOptions: SingleOption[] = (sortOptions ?? []).map((o) => ({\n\t\tlabel: o.label,\n\t\tvalue: o.value,\n\t\tselected: o.value === selectedSort,\n\t}));\n\n\treturn (\n\t\t<FilterRow>\n\t\t\t<FilterRowLeft>\n\t\t\t\t<Input\n\t\t\t\t\tdata-test=\"agent-search\"\n\t\t\t\t\tvariant=\"small\"\n\t\t\t\t\twidth=\"320px\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tvalue={searchValue}\n\t\t\t\t\tplaceholder={searchPlaceholder}\n\t\t\t\t\thideInputHeader\n\t\t\t\t\tnoErrorHint\n\t\t\t\t\tleftIcon={{\n\t\t\t\t\t\ticon: () => (\n\t\t\t\t\t\t\t<SearchIcon\n\t\t\t\t\t\t\t\twidth={18}\n\t\t\t\t\t\t\t\theight={18}\n\t\t\t\t\t\t\t\tcolor={COLORS.content.placeholder}\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\tonChangeText={(text) => onSearchChange(text)}\n\t\t\t\t\tonKeyDownEvent={\n\t\t\t\t\t\tonSearchSubmit\n\t\t\t\t\t\t\t? (e) => {\n\t\t\t\t\t\t\t\t\tif ((e as unknown as KeyboardEvent).key === 'Enter') {\n\t\t\t\t\t\t\t\t\t\tonSearchSubmit((e.target as HTMLInputElement).value);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t}\n\t\t\t\t/>\n\n\t\t\t\t{filterOptions && onFilterChange && (\n\t\t\t\t\t<Dropdown\n\t\t\t\t\t\tdata-test=\"agent-filters\"\n\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\twidth=\"140px\"\n\t\t\t\t\t\tplaceHolder={filterPlaceholder}\n\t\t\t\t\t\tshowPlaceholderWhenSelected\n\t\t\t\t\t\toptions={filterOptions}\n\t\t\t\t\t\tisMultiSelect\n\t\t\t\t\t\tonSelect={onFilterChange}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</FilterRowLeft>\n\n\t\t\t{sortOptions && onSortChange && (\n\t\t\t\t<Dropdown\n\t\t\t\t\tdata-test=\"agent-sort\"\n\t\t\t\t\tsize=\"small\"\n\t\t\t\t\twidth=\"200px\"\n\t\t\t\t\toptions={sortDropdownOptions}\n\t\t\t\t\tonSelect={(opt) => {\n\t\t\t\t\t\tconst single = Array.isArray(opt) ? opt[0] : opt;\n\t\t\t\t\t\tconst value = (single as SingleOption)?.value;\n\t\t\t\t\t\tif (value) {\n\t\t\t\t\t\t\tonSortChange(value);\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</FilterRow>\n\t);\n};\n"],"names":["AgentListingFilters","searchValue","onSearchChange","onSearchSubmit","searchPlaceholder","filterOptions","onFilterChange","filterPlaceholder","sortOptions","selectedSort","onSortChange","sortDropdownOptions","o","FilterRow","jsxs","FilterRowLeft","jsx","Input","SearchIcon","COLORS","text","Dropdown","opt","value"],"mappings":"mTAyBaA,EAA0D,CAAC,CACvE,YAAAC,EACA,eAAAC,EACA,eAAAC,EACA,kBAAAC,EACA,cAAAC,EACA,eAAAC,EACA,kBAAAC,EACA,YAAAC,EACA,aAAAC,EACA,aAAAC,CACD,IAAM,CACL,MAAMC,GAAuCH,GAAe,CAAA,GAAI,IAAKI,IAAO,CAC3E,MAAOA,EAAE,MACT,MAAOA,EAAE,MACT,SAAUA,EAAE,QAAUH,CAAA,EACrB,EAEF,cACEI,YAAA,CACA,SAAA,CAAAC,OAACC,EAAAA,cAAA,CACA,SAAA,CAAAC,EAAAA,IAACC,EAAAA,MAAA,CACA,YAAU,eACV,QAAQ,QACR,MAAM,QACN,KAAK,OACL,MAAOhB,EACP,YAAaG,EACb,gBAAe,GACf,YAAW,GACX,SAAU,CACT,KAAM,IACLY,EAAAA,IAACE,EAAAA,QAAA,CACA,MAAO,GACP,OAAQ,GACR,MAAOC,EAAAA,OAAO,QAAQ,WAAA,CAAA,CACvB,EAGF,aAAeC,GAASlB,EAAekB,CAAI,EAC3C,eACCjB,EACI,GAAM,CACF,EAA+B,MAAQ,SAC3CA,EAAgB,EAAE,OAA4B,KAAK,CAEpD,EACA,MAAA,CAAA,EAIJE,GAAiBC,GACjBU,EAAAA,IAACK,EAAAA,SAAA,CACA,YAAU,gBACV,KAAK,QACL,MAAM,QACN,YAAad,EACb,4BAA2B,GAC3B,QAASF,EACT,cAAa,GACb,SAAUC,CAAA,CAAA,CACX,EAEF,EAECE,GAAeE,GACfM,EAAAA,IAACK,EAAAA,SAAA,CACA,YAAU,aACV,KAAK,QACL,MAAM,QACN,QAASV,EACT,SAAWW,GAAQ,CAElB,MAAMC,GADS,MAAM,QAAQD,CAAG,EAAIA,EAAI,CAAC,EAAIA,IACL,MACpCC,GACHb,EAAaa,CAAK,CAEpB,CAAA,CAAA,CACD,EAEF,CAEF"}
@@ -1 +1 @@
1
- {"version":3,"file":"BikEditor.types.js","sources":["../../../src/editor/BikEditor.types.ts"],"sourcesContent":["/**\n * ┌─────────────────────────────────────────────────────────────────────────┐\n * │ PUBLIC API LAYER — zero editor-framework imports │\n * │ │\n * │ This file is the consumer contract for BikEditor. It has NO dependency │\n * │ on TipTap, Lexical, Slate, or any other rich-text library. │\n * │ │\n * │ If the underlying editor is ever swapped, ONLY the implementation files │\n * │ change — this file, src/editor/index.ts, and all consumer code stay as- │\n * │ is. The files that would change are: │\n * │ • BikEditor.tsx — wires props into the editor instance │\n * │ • BikEditor.utils.ts — HTML / document-state adapters │\n * │ • extensions/ — extension / plugin layer │\n * └─────────────────────────────────────────────────────────────────────────┘\n */\nimport React from 'react';\n\n/**\n * Opt in to specific editor capabilities. Both default to `false`.\n *\n * @example\n * // Email editor with full rich text support\n * <BikEditor features={{ richPaste: true, richTypography: true }} />\n */\nexport interface EditorFeatures {\n\t/** Preserve HTML formatting on paste. Default: `false`. */\n\trichPaste?: boolean;\n\t/** Enable font family, font size, text alignment, highlight, subscript, superscript, and image. Default: `false`. */\n\trichTypography?: boolean;\n\t/**\n\t * Restrict which inline marks are active in the editor.\n\t * When set, only the listed marks are registered — all others are disabled\n\t * (no rendering, no keyboard shortcuts, no paste preservation).\n\t * Omit to allow all marks (default).\n\t *\n\t * @example\n\t * // LiveChat: bold only, no italic / underline / strike\n\t * features={{ allowedMarks: ['bold'] }}\n\t */\n\tallowedMarks?: Array<'bold' | 'italic' | 'strike' | 'underline' | 'code'>;\n}\n\n/**\n * A named content section placed below the main body, separated by an invisible divider.\n *\n * Sections let you split a single editor instance into independently readable\n * and writable zones — for example: body / signature / forwarded mail.\n *\n * @example\n * sections={[\n * { id: 'signature', content: '<p>Best regards,<br/>Alice</p>' },\n * { id: 'forwarded', content: '<p>--- Forwarded message ---</p>' },\n * ]}\n */\nexport interface EditorSection {\n\t/**\n\t * Unique identifier. Used in ref methods: `getSectionContent(id)`,\n\t * `setSectionContent(id, html)`, `focusSection(id)`, `clearSection(id)`.\n\t * The string `'body'` is reserved for the main content above all dividers.\n\t */\n\tid: string;\n\t/** Initial HTML content of this section. */\n\tcontent: string;\n}\n\n/**\n * Data passed to the `onPaste` callback.\n * Return `true` from your handler to suppress BikEditor's default paste handling\n * (rich-paste and plain-text stripping won't run for that event).\n */\nexport interface PasteData {\n\t/** All files in the clipboard (images, PDFs, etc.). */\n\tfiles: File[];\n\t/** Image files only — a filtered subset of `files`. */\n\timages: File[];\n\t/** Plain text from the clipboard. */\n\ttext: string;\n\t/** HTML from the clipboard (empty string if the source doesn't provide HTML). */\n\thtml: string;\n\t/** The raw browser ClipboardEvent — for advanced use. */\n\tevent: ClipboardEvent;\n}\n\n/**\n * A custom keyboard shortcut registered with the editor.\n *\n * @example\n * shortcuts={[\n * // Mod = Cmd on Mac, Ctrl on Windows/Linux\n * { key: 'Enter', modifiers: ['mod'], handler: handleSend },\n * { key: 's', modifiers: ['mod'], handler: handleSave },\n * { key: 'k', modifiers: ['mod', 'shift'], handler: openLinkModal },\n * ]}\n */\nexport interface KeyboardShortcut {\n\t/** Key name. Use the same strings as KeyboardEvent.key, e.g. `'Enter'`, `'s'`, `'k'`. */\n\tkey: string;\n\t/**\n\t * Modifier keys.\n\t * `'mod'` maps to Cmd on macOS and Ctrl on Windows/Linux — prefer it over\n\t * `'ctrl'` for cross-platform shortcuts.\n\t */\n\tmodifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'>;\n\t/** Called when the shortcut fires. Returning nothing is fine. */\n\thandler: () => void;\n}\n\n/** Content object returned by onChange, onSend, getContent(), and getSectionContent(). */\nexport interface EditorSnapshot {\n\t/** Serialised HTML. Safe to pass back to setContent() or setSectionContent(). */\n\thtml: string;\n\t/** Plain text, stripped of all marks and block nodes. */\n\ttext: string;\n\t/** True when the document contains no user-visible content. */\n\tisEmpty: boolean;\n\t/** Character count at this point in time. */\n\tcharacterCount: number;\n}\n\n/** One item shown in the @agent or #team mention dropdown. */\nexport interface MentionItem {\n\t/** Unique identifier stored as a node attribute. Used to look up the item later. */\n\tid: string | number;\n\t/** Display name shown in the dropdown and inserted into the document. */\n\tlabel: string;\n\t/** Avatar image URL. Shown in the built-in row when renderMentionItem is not provided. */\n\tavatarUrl?: string;\n\t/** When true, a green presence dot appears in the built-in row. */\n\tisOnline?: boolean;\n\t/** Any extra data your app needs. Passed back as-is in onMentionSelected. */\n\tmeta?: Record<string, unknown>;\n}\n\n/** One item shown in the / slash-command dropdown. */\nexport interface SlashCommandItem {\n\t/** Unique identifier. */\n\tid: string;\n\t/** Short command name shown as the primary label in the menu. */\n\tlabel: string;\n\t/** Optional one-line description shown below the label in the built-in row. */\n\tdescription?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Feature config objects — pass one object per feature instead of N flat props\n// ---------------------------------------------------------------------------\n\n/**\n * Props passed to the `renderDropdown` function in `MentionConfig`.\n * `activeIndex` is the keyboard-navigated row — highlight it in your UI.\n * Call `onSelect(item)` when the user picks one.\n */\nexport interface MentionDropdownRenderProps {\n\titems: MentionItem[];\n\t/** The text the user typed after the `@` or `#` trigger. */\n\tquery: string;\n\t/**\n\t * Index of the currently highlighted row (arrow-key navigation).\n\t * The editor manages this automatically — just use it for visual highlighting.\n\t */\n\tactiveIndex: number;\n\t/** Call this when the user selects an item (click, touch, etc.). */\n\tonSelect: (item: MentionItem) => void;\n\t/**\n\t * Register a keyboard handler so a CUSTOM dropdown can own arrow-key / Enter\n\t * navigation (e.g. a multi-level picker whose visible rows differ from the\n\t * flat `items` list). Return `true` from the handler to consume the key.\n\t * Pass `null` to unregister. When not registered, the editor falls back to\n\t * navigating the flat `items` list.\n\t */\n\tregisterKeyHandler?: (\n\t\thandler: ((event: KeyboardEvent) => boolean) | null,\n\t) => void;\n}\n\n/**\n * Everything related to @ and # mention dropdowns, in one place.\n *\n * @example\n * mentions={{\n * agents: [{ id: 1, label: 'Alice', avatarUrl: '...' }],\n * teams: [{ id: 't1', label: 'Support' }],\n * onSelect: (item, char) => console.log(char, item),\n * }}\n */\nexport interface MentionConfig {\n\t/** Items shown when the user types `@`. */\n\tagents?: MentionItem[];\n\t/** Items shown when the user types `#`. */\n\tteams?: MentionItem[];\n\t/** Called when the user picks an item. `char` is `'@'` or `'#'`. */\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void;\n\t/**\n\t * Custom renderer for each row in the dropdown.\n\t * `isActive` is `true` when that row is currently highlighted by keyboard\n\t * navigation (arrows move it, Enter selects it). Use it to apply a highlight\n\t * style so the user can see which item they're about to select.\n\t * Omit to use the built-in avatar + name row.\n\t *\n\t * Use `renderDropdown` instead when you need a completely different structure.\n\t *\n\t * @example\n\t * renderItem={(item, isActive) => (\n\t * <div style={{ background: isActive ? '#f0f0f0' : undefined }}>\n\t * {item.label}\n\t * </div>\n\t * )}\n\t */\n\trenderItem?: (item: MentionItem, isActive: boolean) => React.ReactNode;\n\t/**\n\t * Render the entire dropdown yourself instead of individual rows.\n\t * The editor still manages keyboard navigation — `activeIndex` tells you\n\t * which row is highlighted, and `onSelect(item)` confirms the selection.\n\t * Takes priority over `renderItem` when both are provided.\n\t *\n\t * @example\n\t * renderDropdown={({ items, query, activeIndex, onSelect }) => (\n\t * <MyDropdown\n\t * items={items}\n\t * highlightedIndex={activeIndex}\n\t * onPick={onSelect}\n\t * />\n\t * )}\n\t */\n\trenderDropdown?: (props: MentionDropdownRenderProps) => React.ReactNode;\n\t/**\n\t * When true, a typed trigger char (`@` / `#`) and its query are removed if the\n\t * suggestion menu closes without a selection (click-outside / no match). Default\n\t * false — the typed text is kept.\n\t */\n\tremoveTriggerOnDismiss?: boolean;\n}\n\n/**\n * Props passed to the `renderDropdown` function in `SlashCommandConfig`.\n */\nexport interface SlashCommandDropdownRenderProps {\n\titems: SlashCommandItem[];\n\t/** The text the user typed after `/`. */\n\tquery: string;\n\t/** Index of the currently highlighted row. Use for visual highlighting. */\n\tactiveIndex: number;\n\t/** Call this when the user selects an item. */\n\tonSelect: (item: SlashCommandItem) => void;\n}\n\n/**\n * Everything related to the `/` slash-command menu, in one place.\n *\n * @example\n * slashCommands={{\n * items: [{ id: 'ai-reply', label: 'AI Reply', description: 'Generate a reply' }],\n * onSelect: (cmd) => triggerAI(cmd.id),\n * }}\n */\nexport interface SlashCommandConfig {\n\t/** The list of commands. Filtered client-side as the user types after `/`. */\n\titems: SlashCommandItem[];\n\t/** Called when the user selects a command. The `/` trigger is removed from the doc. */\n\tonSelect?: (command: SlashCommandItem) => void;\n\t/**\n\t * Custom renderer for each row.\n\t * `isActive` is `true` when that row is highlighted by keyboard navigation.\n\t * Omit to use the built-in label + description row.\n\t *\n\t * Use `renderDropdown` instead when you need a completely different structure.\n\t */\n\trenderItem?: (item: SlashCommandItem, isActive: boolean) => React.ReactNode;\n\t/**\n\t * Render the entire slash-command dropdown yourself.\n\t * The editor manages keyboard navigation — use `activeIndex` to highlight\n\t * the active row and call `onSelect(item)` to confirm selection.\n\t * Takes priority over `renderItem` when both are provided.\n\t *\n\t * @example\n\t * renderDropdown={({ items, activeIndex, onSelect }) => (\n\t * <MyCmdPalette commands={items} active={activeIndex} onPick={onSelect} />\n\t * )}\n\t */\n\trenderDropdown?: (props: SlashCommandDropdownRenderProps) => React.ReactNode;\n}\n\n/**\n * Configuration for how hyperlinks behave in the editor.\n *\n * @example\n * link={{ renderTooltip: ({ href, text, onOpen, onRemove }) => (\n * <MyLinkPopover href={href} onOpen={onOpen} onRemove={onRemove} />\n * )}}\n */\nexport interface LinkConfig {\n\t/**\n\t * Custom tooltip rendered when the user clicks a link.\n\t * Receives the href, display text, bounding rect (for positioning),\n\t * and ready-to-call action handlers.\n\t * Omit to use the minimal built-in tooltip.\n\t */\n\trenderTooltip?: (props: LinkTooltipProps) => React.ReactNode;\n}\n\n/**\n * Snapshot of all active marks and block types at the current cursor or selection.\n * Returned by onSelectionChange and ref.getActiveFormats().\n *\n * Keep this in component state and pass it to BikEditorToolbar (or your own toolbar)\n * to keep button active-states in sync.\n *\n * @example\n * const [formats, setFormats] = useState(DEFAULT_ACTIVE_FORMATS);\n * <BikEditor onSelectionChange={setFormats} ... />\n * <BikEditorToolbar activeFormats={formats} ... />\n */\nexport interface FormatState {\n\tbold: boolean;\n\titalic: boolean;\n\tunderline: boolean;\n\tstrike: boolean;\n\tbulletList: boolean;\n\torderedList: boolean;\n\tblockquote: boolean;\n\tcodeBlock: boolean;\n\t/** Non-null when the cursor is inside (or selection spans) a hyperlink. */\n\tlink: { href: string } | null;\n\ttextAlign: 'left' | 'center' | 'right' | 'justify' | null;\n\tfontFamily: string | null;\n\tfontSize: string | null;\n\t/** Active text colour as a CSS colour string, or null if none. */\n\tcolor: string | null;\n\t/** Active highlight (background) colour, or null if none. */\n\thighlight: string | null;\n\t/** True when the cursor/selection is in a superscript. */\n\tsuperscript: boolean;\n\t/** True when the cursor/selection is in a subscript. */\n\tsubscript: boolean;\n}\n\nexport const DEFAULT_FORMAT_STATE: FormatState = {\n\tbold: false,\n\titalic: false,\n\tunderline: false,\n\tstrike: false,\n\tbulletList: false,\n\torderedList: false,\n\tblockquote: false,\n\tcodeBlock: false,\n\tlink: null,\n\ttextAlign: null,\n\tfontFamily: null,\n\tfontSize: null,\n\tcolor: null,\n\thighlight: null,\n\tsuperscript: false,\n\tsubscript: false,\n};\n\n/**\n * All formatting and insertion commands. Access via `editorRef.current.actions`.\n *\n * Every method focuses the editor internally — no need to call `.focus()` first.\n *\n * @example\n * editorRef.current?.actions.toggleBold();\n * editorRef.current?.actions.setLink('https://example.com', 'Visit example');\n */\nexport interface EditorActions {\n\t// ── Basic marks ───────────────────────────────────────────────────────────\n\ttoggleBold: () => void;\n\ttoggleItalic: () => void;\n\ttoggleUnderline: () => void;\n\ttoggleStrike: () => void;\n\n\t// ── Blocks ────────────────────────────────────────────────────────────────\n\ttoggleBulletList: () => void;\n\ttoggleOrderedList: () => void;\n\ttoggleBlockquote: () => void;\n\ttoggleCodeBlock: () => void;\n\n\t// ── Alignment & typography ────────────────────────────────────────────────\n\tsetTextAlign: (align: 'left' | 'center' | 'right' | 'justify') => void;\n\t/** Pass a CSS font-family value, e.g. `'Inter, sans-serif'`. Only works when richTypography is on. */\n\tsetFontFamily: (font: string) => void;\n\t/** Pass a CSS size value, e.g. `'16px'` or `'1.25rem'`. Only works when richTypography is on. */\n\tsetFontSize: (size: string) => void;\n\n\t// ── Colour ────────────────────────────────────────────────────────────────\n\t/** Sets the text colour. Pass any CSS colour value, e.g. `'#e53e3e'`. */\n\tsetColor: (color: string) => void;\n\t/** Sets the highlight (background) colour. */\n\tsetHighlight: (color: string) => void;\n\t/** Removes the text colour mark from the current selection. */\n\tunsetColor: () => void;\n\t/** Removes the highlight mark from the current selection. */\n\tunsetHighlight: () => void;\n\n\t// ── Links ─────────────────────────────────────────────────────────────────\n\t/**\n\t * Applies a hyperlink to the current selection, or updates the link the\n\t * cursor is already inside.\n\t *\n\t * @param href The URL.\n\t * @param text Optional display text. When provided, the visible text of the\n\t * linked range is replaced atomically in the same undo step.\n\t *\n\t * @example\n\t * actions.setLink('https://example.com');\n\t * actions.setLink('https://example.com', 'Visit example');\n\t */\n\tsetLink: (href: string, text?: string) => void;\n\t/** Updates only the href of the link at the current cursor. */\n\tupdateLink: (href: string) => void;\n\t/** Removes the link mark but keeps the visible text. */\n\tremoveLink: () => void;\n\n\t// ── Insertions ────────────────────────────────────────────────────────────\n\t/** Inserts an emoji character at the cursor. */\n\tinsertEmoji: (emoji: string) => void;\n\t/**\n\t * Inserts a `{{variableName}}` token at the cursor.\n\t * The token renders with a distinct highlight inside the editor.\n\t */\n\tinsertVariable: (variableName: string) => void;\n\t/** Inserts arbitrary HTML at the current cursor position. */\n\tinsertHtml: (html: string) => void;\n\n\t// ── History ───────────────────────────────────────────────────────────────\n\tundo: () => void;\n\tredo: () => void;\n\tcanUndo: () => boolean;\n\tcanRedo: () => boolean;\n\n\t// ── Rich typography (richTypography feature required) ─────────────────────\n\t/** Toggles superscript on the selection. Only works when richTypography is on. */\n\ttoggleSuperscript: () => void;\n\t/** Toggles subscript on the selection. Only works when richTypography is on. */\n\ttoggleSubscript: () => void;\n\t/** Inserts an inline image at the cursor. Only works when richTypography is on. */\n\tinsertImage: (src: string) => void;\n}\n\n/** Props passed to your renderLinkTooltip render prop. */\nexport interface LinkTooltipProps {\n\t/** The href of the active link. */\n\thref: string;\n\t/** The display text of the link. */\n\ttext: string;\n\t/** Bounding rect of the link element — use this to position your popover. */\n\trect: DOMRect;\n\t/** Opens the link in a new tab. */\n\tonOpen: () => void;\n\t/** Removes the link mark but keeps the visible text. */\n\tonRemove: () => void;\n\t/** Hides the bubble menu. Call this before opening an edit modal so the tooltip doesn't linger. */\n\tonHide: () => void;\n}\n\n/**\n * Imperative handle exposed by BikEditor.\n *\n * Obtain via `useRef<BikEditorRef>()` and pass to `<BikEditor ref={...} />`.\n * All methods are safe to call after the first render.\n *\n * @example\n * const ref = useRef<BikEditorRef>(null);\n * <BikEditor ref={ref} ... />\n * ref.current?.clearContent();\n * ref.current?.actions.toggleBold();\n */\nexport interface BikEditorRef {\n\t// ── Focus ─────────────────────────────────────────────────────────────────\n\t/** Moves focus into the editor. Optionally pass a position: 'start', 'end', 'all', or a numeric offset. */\n\tfocus: (position?: 'start' | 'end' | 'all' | number | boolean | null) => void;\n\t/** Removes focus from the editor. */\n\tblur: () => void;\n\n\t// ── Content ───────────────────────────────────────────────────────────────\n\t/** Clears the entire document and fires onChange. */\n\tclearContent: () => void;\n\t/**\n\t * Replaces the full document with the given HTML and fires onChange.\n\t * Overwrites all sections. Use setSectionContent() / setBodyContent() to\n\t * update a single section without touching the others.\n\t */\n\tsetContent: (html: string) => void;\n\t/** Inserts HTML at the current cursor position without replacing anything. */\n\tinsertContent: (html: string) => void;\n\t/**\n\t * Inserts HTML inline at the current cursor position, unwrapping block\n\t * wrappers (e.g. `<p>`) so the content merges into the surrounding paragraph\n\t * instead of creating new blocks. Use for macros, quick replies, etc.\n\t */\n\tinsertInlineContent: (html: string) => void;\n\t/** Inserts HTML at the very start of the document. */\n\tinsertAtStart: (html: string) => void;\n\t/** Inserts HTML as a new block at the end of the document. */\n\tinsertBlock: (html: string) => void;\n\t/**\n\t * Appends HTML inline inside the last paragraph of the document.\n\t * Ideal for streaming — call repeatedly with each text chunk.\n\t * Use `appendBodyContent` instead if the editor has named sections.\n\t */\n\tappendInline: (html: string) => void;\n\t/** @deprecated Use `insertBlock` */\n\tinsertAtEnd: (html: string) => void;\n\t/** @deprecated Use `appendInline` */\n\tappendContent: (html: string) => void;\n\t/** Returns the full document as `{ html, text, isEmpty, characterCount }`. */\n\tgetContent: () => EditorSnapshot;\n\t/**\n\t * Returns the raw TipTap document as a plain JSON object.\n\t * Returns `null` when the editor is not yet mounted.\n\t */\n\tgetJSON: () => Record<string, unknown> | null;\n\t/**\n\t * Walks the document and returns all mention IDs currently in the editor,\n\t * split by type. IDs are deduplicated and returned as arrays.\n\t *\n\t * @example\n\t * const { agentIds, teamIds } = ref.current?.getMentions() ?? { agentIds: [], teamIds: [] };\n\t */\n\tgetMentions: () => { agentIds: string[]; teamIds: string[] };\n\n\t// ── Selection ─────────────────────────────────────────────────────────────\n\t/**\n\t * Returns the current cursor / selection position as a `{ from, to }` pair.\n\t * When nothing is selected, `from === to` (a collapsed cursor).\n\t * Pass the returned value to `insertAtPosition()` to insert at an exact spot.\n\t *\n\t * @example\n\t * const { from } = ref.current?.getCursorPosition() ?? { from: 0, to: 0 };\n\t * ref.current?.insertAtPosition(from, '<strong>inserted</strong>');\n\t */\n\tgetCursorPosition: () => { from: number; to: number };\n\t/**\n\t * Inserts HTML at an explicit document position rather than at the current cursor.\n\t * Use `getCursorPosition()` to get the position, or any value from\n\t * `findSectionStartPos` / `findSectionEndPos` if you need section-relative insertion.\n\t *\n\t * @example\n\t * const { from } = ref.current!.getCursorPosition();\n\t * ref.current?.insertAtPosition(from, '<em>hello</em>');\n\t */\n\tinsertAtPosition: (pos: number, html: string) => void;\n\t/**\n\t * Returns the currently selected plain text.\n\t * When the cursor is inside a link with nothing selected, returns the full\n\t * link text — useful for pre-filling a link modal's text field.\n\t */\n\tgetSelectedText: () => string;\n\n\t// ── Character count ───────────────────────────────────────────────────────\n\t/**\n\t * Returns the current character count and the configured limit (or null).\n\t * Use this to render your own character counter anywhere you like.\n\t *\n\t * @example\n\t * const { count, limit } = ref.current?.getCharacterCount() ?? { count: 0, limit: null };\n\t * <span style={{ color: count >= (limit ?? Infinity) ? 'red' : 'inherit' }}>\n\t * {count}{limit != null ? ` / ${limit}` : ''}\n\t * </span>\n\t */\n\tgetCharacterCount: () => { count: number; limit: number | null };\n\n\t// ── Sections ─────────────────────────────────────────────────────────────\n\t/**\n\t * Returns content for a named section.\n\t * Use `'body'` to get the main content above all section dividers.\n\t *\n\t * @example\n\t * const sig = ref.current?.getSectionContent('signature');\n\t */\n\tgetSectionContent: (sectionId: string) => EditorSnapshot;\n\t/**\n\t * Replaces the content of a named section without touching other sections.\n\t * If the section doesn't exist yet it is appended at the end.\n\t *\n\t * @example\n\t * ref.current?.setSectionContent('signature', '<p>New signature</p>');\n\t * ref.current?.setSectionContent('body', rephrased); // same as setBodyContent\n\t */\n\tsetSectionContent: (sectionId: string, html: string) => void;\n\t/**\n\t * Moves the cursor to the start of a named section.\n\t * Use `'body'` to focus the main content area.\n\t */\n\tfocusSection: (sectionId: string) => void;\n\t/** Clears all content in a named section (replaces with an empty paragraph). */\n\tclearSection: (sectionId: string) => void;\n\n\t// ── Convenience body shorthands ───────────────────────────────────────────\n\t/** Shorthand for `getSectionContent('body')`. */\n\tgetBodyContent: () => EditorSnapshot;\n\t/** Shorthand for `setSectionContent('body', html)`. */\n\tsetBodyContent: (html: string) => void;\n\t/**\n\t * Atomically sets the body AND all sections in a single editor update.\n\t * Sections are laid out in the exact order supplied — use this instead of\n\t * multiple `setSectionContent()` calls whenever order matters (e.g. forward\n\t * mail where signature must appear before the forwarded thread).\n\t *\n\t * @example\n\t * ref.current?.setBodyAndSections('<p></p>', [\n\t * { id: 'signature', content: '<p>Alice</p>' },\n\t * { id: 'forwarded', content: '<p>--- Forwarded ---</p>' },\n\t * ]);\n\t */\n\tsetBodyAndSections: (\n\t\tbody: string,\n\t\tsections: Array<{ id: string; content: string }>,\n\t) => void;\n\t/**\n\t * Appends HTML to the end of the body section without moving the cursor.\n\t * Ideal for streaming AI-generated content — call repeatedly with each chunk.\n\t * Does NOT clear existing content; call `setBodyContent('')` first if needed.\n\t *\n\t * @example\n\t * // Stream AI response chunk-by-chunk\n\t * ref.current?.setBodyContent('');\n\t * for await (const chunk of aiStream) {\n\t * ref.current?.appendBodyContent(chunk);\n\t * }\n\t */\n\tappendBodyContent: (html: string) => void;\n\n\t/**\n\t * Inserts HTML at the start of a named section (or `'body'`).\n\t * Inserts at the very start of the document when `sectionId` is `'body'`.\n\t */\n\tinsertAtSectionStart: (sectionId: string, html: string) => void;\n\t/**\n\t * Inserts HTML at the end of a named section (or `'body'`).\n\t * For `'body'`, inserts just before the first section divider (or at end of doc).\n\t */\n\tinsertAtSectionEnd: (sectionId: string, html: string) => void;\n\n\t// ── Formats & actions ─────────────────────────────────────────────────────\n\t/** Returns a snapshot of all active marks at the current cursor or selection. */\n\tgetActiveFormats: () => FormatState;\n\t/** All formatting and insertion commands. See EditorActions. */\n\tactions: EditorActions;\n}\n\n/**\n * Props for `<BikEditor />`. All props are optional.\n */\nexport interface BikEditorProps {\n\t// ── Features ──────────────────────────────────────────────────────────────\n\t/**\n\t * Opt in to specific editor capabilities. Both default to `false`.\n\t *\n\t * @example\n\t * <BikEditor features={{ richPaste: true, richTypography: true }} />\n\t */\n\tfeatures?: EditorFeatures;\n\n\t// ── Content ───────────────────────────────────────────────────────────────\n\t/**\n\t * HTML loaded on mount. Ignored after first render.\n\t * Use `ref.setContent()` to change content imperatively later.\n\t */\n\tinitialContent?: string;\n\t/**\n\t * Named sections placed below the main body.\n\t * Each section is separated from the previous one by an invisible divider node.\n\t * The array order determines the visual order in the document.\n\t *\n\t * These are only the INITIAL values — use `ref.setSectionContent()` to update\n\t * a section after mount without re-mounting the editor.\n\t *\n\t * @example\n\t * sections={[\n\t * { id: 'signature', content: '<p>Best regards, Alice</p>' },\n\t * { id: 'forwarded', content: '<p>--- Forwarded message ---</p>' },\n\t * ]}\n\t */\n\tsections?: EditorSection[];\n\t/** Placeholder text shown when the editor is empty. */\n\tplaceholder?: string;\n\n\t// ── Behaviour ─────────────────────────────────────────────────────────────\n\t/** Makes the editor read-only. The toolbar still renders but actions are no-ops. */\n\tdisabled?: boolean;\n\t/**\n\t * Hard character limit. The editor refuses to accept input beyond this point.\n\t * The limit is enforced silently — no UI is rendered. Use\n\t * `ref.getCharacterCount()` or `onChange.characterCount` to display it yourself.\n\t */\n\tmaxCharacters?: number;\n\n\t// ── Keyboard shortcuts ────────────────────────────────────────────────────\n\t/**\n\t * Custom keyboard shortcuts. BikEditor registers no shortcuts of its own —\n\t * every shortcut must be explicitly listed here.\n\t *\n\t * @example\n\t * shortcuts={[\n\t * { key: 'Enter', modifiers: ['mod'], handler: handleSend },\n\t * { key: 's', modifiers: ['mod', 'shift'], handler: handleDraft },\n\t * ]}\n\t */\n\tshortcuts?: KeyboardShortcut[];\n\t/**\n\t * Shortcut key that fires `onSend`. No key is bound to `onSend` unless you\n\t * set this explicitly. Requires `onSend` to also be provided.\n\t *\n\t * `'mod'` maps to Cmd on macOS and Ctrl on Windows/Linux.\n\t *\n\t * @example\n\t * // Single shortcut\n\t * sendShortcut={{ key: 'Enter', modifiers: ['mod'] }}\n\t * // Multiple shortcuts\n\t * sendShortcut={[\n\t * { key: 'Enter', modifiers: ['mod'] },\n\t * { key: 's', modifiers: ['mod'] },\n\t * ]}\n\t */\n\tsendShortcut?:\n\t\t| { key: string; modifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'> }\n\t\t| Array<{\n\t\t\t\tkey: string;\n\t\t\t\tmodifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'>;\n\t\t }>;\n\n\t// ── Mentions ─────────────────────────────────────────────────────────────\n\t/**\n\t * Enables `@` (agent) and `#` (team) mention dropdowns.\n\t * Bundle all mention-related config in one object so it's easy to find.\n\t *\n\t * @example\n\t * mentions={{\n\t * agents: myAgents,\n\t * teams: myTeams,\n\t * onSelect: (item, char) => track(char, item.id),\n\t * }}\n\t */\n\tmentions?: MentionConfig;\n\n\t// ── Slash commands ────────────────────────────────────────────────────────\n\t/**\n\t * Enables the `/` slash-command menu.\n\t * Bundle all slash-command config in one object.\n\t *\n\t * @example\n\t * slashCommands={{\n\t * items: MY_COMMANDS,\n\t * onSelect: (cmd) => handleCommand(cmd.id),\n\t * }}\n\t */\n\tslashCommands?: SlashCommandConfig;\n\n\t// ── Link ─────────────────────────────────────────────────────────────────\n\t/**\n\t * Link-related configuration — currently just the click tooltip.\n\t *\n\t * @example\n\t * link={{ renderTooltip: ({ href, onOpen, onRemove }) => (\n\t * <MyTooltip href={href} onOpen={onOpen} onRemove={onRemove} />\n\t * )}}\n\t */\n\tlink?: LinkConfig;\n\n\t// ── Callbacks ─────────────────────────────────────────────────────────────\n\t/**\n\t * Called once, immediately after the editor finishes initializing.\n\t * Any imperative ref methods called before this fires are queued internally\n\t * and executed automatically once the editor is ready — consumers do not\n\t * need timers or readiness guards.\n\t *\n\t * @example\n\t * <BikEditor\n\t * ref={editorRef}\n\t * onReady={() => editorRef.current?.setContent(savedDraft)}\n\t * />\n\t */\n\tonReady?: () => void;\n\t/** Called on every document change. */\n\tonChange?: (content: EditorSnapshot) => void;\n\t/**\n\t * Called when the user presses the key combo defined by `sendShortcut`.\n\t * Only fires when both `onSend` and `sendShortcut` are provided.\n\t */\n\tonSend?: (content: EditorSnapshot) => void;\n\t/** Called when the editor gains focus. */\n\tonFocus?: () => void;\n\t/** Called when the editor loses focus. */\n\tonBlur?: () => void;\n\t/**\n\t * Called on every paste event. Return `true` to fully suppress BikEditor's\n\t * own paste handling (useful when you want to handle images or HTML yourself).\n\t *\n\t * @example\n\t * onPaste={({ images }) => {\n\t * if (images.length) {\n\t * uploadImages(images).then(urls => {\n\t * urls.forEach(url => ref.current?.actions.insertHtml(`<img src=\"${url}\" />`));\n\t * });\n\t * return true; // suppress default — don't embed the raw image data\n\t * }\n\t * }}\n\t */\n\tonPaste?: (data: PasteData) => boolean | void;\n\t/**\n\t * Called on every cursor move or selection change with a snapshot of all\n\t * active marks. Keep in state and pass to your toolbar to sync button states.\n\t */\n\tonSelectionChange?: (activeFormats: FormatState) => void;\n\n\t// ── Styling ───────────────────────────────────────────────────────────────\n\t// Outer wrapper — use these to control the shell (border, border-radius,\n\t// background, shadow, etc.).\n\t/** Extra class name applied to the outer wrapper div. */\n\tclassName?: string;\n\t/** Inline styles applied to the outer wrapper div. */\n\tstyle?: React.CSSProperties;\n\n\t// Inner editable area — use these to control the content div itself\n\t// (padding, font, line-height, etc.).\n\t/** Extra class name applied to the content-editable area (`.ProseMirror` in TipTap). */\n\teditorClassName?: string;\n\t/** Inline styles applied to the content-editable area. */\n\teditorStyle?: React.CSSProperties;\n\n\t// Sizing — applied to the content-editable area.\n\t/** Minimum height of the editable area. CSS value, e.g. `'80px'`. */\n\tminHeight?: string;\n\t/** Maximum height. The editor scrolls internally when exceeded. CSS value, e.g. `'400px'`. */\n\tmaxHeight?: string;\n}\n"],"names":["DEFAULT_FORMAT_STATE"],"mappings":"gFAgVO,MAAMA,EAAoC,CAChD,KAAM,GACN,OAAQ,GACR,UAAW,GACX,OAAQ,GACR,WAAY,GACZ,YAAa,GACb,WAAY,GACZ,UAAW,GACX,KAAM,KACN,UAAW,KACX,WAAY,KACZ,SAAU,KACV,MAAO,KACP,UAAW,KACX,YAAa,GACb,UAAW,EACZ"}
1
+ {"version":3,"file":"BikEditor.types.js","sources":["../../../src/editor/BikEditor.types.ts"],"sourcesContent":["/**\n * ┌─────────────────────────────────────────────────────────────────────────┐\n * │ PUBLIC API LAYER — zero editor-framework imports │\n * │ │\n * │ This file is the consumer contract for BikEditor. It has NO dependency │\n * │ on TipTap, Lexical, Slate, or any other rich-text library. │\n * │ │\n * │ If the underlying editor is ever swapped, ONLY the implementation files │\n * │ change — this file, src/editor/index.ts, and all consumer code stay as- │\n * │ is. The files that would change are: │\n * │ • BikEditor.tsx — wires props into the editor instance │\n * │ • BikEditor.utils.ts — HTML / document-state adapters │\n * │ • extensions/ — extension / plugin layer │\n * └─────────────────────────────────────────────────────────────────────────┘\n */\nimport React from 'react';\n\n/**\n * Opt in to specific editor capabilities. Both default to `false`.\n *\n * @example\n * // Email editor with full rich text support\n * <BikEditor features={{ richPaste: true, richTypography: true }} />\n */\nexport interface EditorFeatures {\n\t/** Preserve HTML formatting on paste. Default: `false`. */\n\trichPaste?: boolean;\n\t/** Enable font family, font size, text alignment, highlight, subscript, superscript, and image. Default: `false`. */\n\trichTypography?: boolean;\n\t/**\n\t * Restrict which inline marks are active in the editor.\n\t * When set, only the listed marks are registered — all others are disabled\n\t * (no rendering, no keyboard shortcuts, no paste preservation).\n\t * Omit to allow all marks (default).\n\t *\n\t * @example\n\t * // LiveChat: bold only, no italic / underline / strike\n\t * features={{ allowedMarks: ['bold'] }}\n\t */\n\tallowedMarks?: Array<'bold' | 'italic' | 'strike' | 'underline' | 'code'>;\n}\n\n/**\n * A named content section placed below the main body, separated by an invisible divider.\n *\n * Sections let you split a single editor instance into independently readable\n * and writable zones — for example: body / signature / forwarded mail.\n *\n * @example\n * sections={[\n * { id: 'signature', content: '<p>Best regards,<br/>Alice</p>' },\n * { id: 'forwarded', content: '<p>--- Forwarded message ---</p>' },\n * ]}\n */\nexport interface EditorSection {\n\t/**\n\t * Unique identifier. Used in ref methods: `getSectionContent(id)`,\n\t * `setSectionContent(id, html)`, `focusSection(id)`, `clearSection(id)`.\n\t * The string `'body'` is reserved for the main content above all dividers.\n\t */\n\tid: string;\n\t/** Initial HTML content of this section. */\n\tcontent: string;\n}\n\n/**\n * Data passed to the `onPaste` callback.\n * Return `true` from your handler to suppress BikEditor's default paste handling\n * (rich-paste and plain-text stripping won't run for that event).\n */\nexport interface PasteData {\n\t/** All files in the clipboard (images, PDFs, etc.). */\n\tfiles: File[];\n\t/** Image files only — a filtered subset of `files`. */\n\timages: File[];\n\t/** Plain text from the clipboard. */\n\ttext: string;\n\t/** HTML from the clipboard (empty string if the source doesn't provide HTML). */\n\thtml: string;\n\t/** The raw browser ClipboardEvent — for advanced use. */\n\tevent: ClipboardEvent;\n}\n\n/**\n * A custom keyboard shortcut registered with the editor.\n *\n * @example\n * shortcuts={[\n * // Mod = Cmd on Mac, Ctrl on Windows/Linux\n * { key: 'Enter', modifiers: ['mod'], handler: handleSend },\n * { key: 's', modifiers: ['mod'], handler: handleSave },\n * { key: 'k', modifiers: ['mod', 'shift'], handler: openLinkModal },\n * ]}\n */\nexport interface KeyboardShortcut {\n\t/** Key name. Use the same strings as KeyboardEvent.key, e.g. `'Enter'`, `'s'`, `'k'`. */\n\tkey: string;\n\t/**\n\t * Modifier keys.\n\t * `'mod'` maps to Cmd on macOS and Ctrl on Windows/Linux — prefer it over\n\t * `'ctrl'` for cross-platform shortcuts.\n\t */\n\tmodifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'>;\n\t/** Called when the shortcut fires. Returning nothing is fine. */\n\thandler: () => void;\n}\n\n/** Content object returned by onChange, onSend, getContent(), and getSectionContent(). */\nexport interface EditorSnapshot {\n\t/** Serialised HTML. Safe to pass back to setContent() or setSectionContent(). */\n\thtml: string;\n\t/** Plain text, stripped of all marks and block nodes. */\n\ttext: string;\n\t/** True when the document contains no user-visible content. */\n\tisEmpty: boolean;\n\t/** Character count at this point in time. */\n\tcharacterCount: number;\n}\n\n/** One item shown in the @agent or #team mention dropdown. */\nexport interface MentionItem {\n\t/** Unique identifier stored as a node attribute. Used to look up the item later. */\n\tid: string | number;\n\t/** Display name shown in the dropdown and inserted into the document. */\n\tlabel: string;\n\t/** Avatar image URL. Shown in the built-in row when renderMentionItem is not provided. */\n\tavatarUrl?: string;\n\t/** When true, a green presence dot appears in the built-in row. */\n\tisOnline?: boolean;\n\t/** Any extra data your app needs. Passed back as-is in onMentionSelected. */\n\tmeta?: Record<string, unknown>;\n}\n\n/** One item shown in the / slash-command dropdown. */\nexport interface SlashCommandItem {\n\t/** Unique identifier. */\n\tid: string;\n\t/** Short command name shown as the primary label in the menu. */\n\tlabel: string;\n\t/** Optional one-line description shown below the label in the built-in row. */\n\tdescription?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Feature config objects — pass one object per feature instead of N flat props\n// ---------------------------------------------------------------------------\n\n/**\n * Props passed to the `renderDropdown` function in `MentionConfig`.\n * `activeIndex` is the keyboard-navigated row — highlight it in your UI.\n * Call `onSelect(item)` when the user picks one.\n */\nexport interface MentionDropdownRenderProps {\n\titems: MentionItem[];\n\t/** The text the user typed after the `@` or `#` trigger. */\n\tquery: string;\n\t/**\n\t * Index of the currently highlighted row (arrow-key navigation).\n\t * The editor manages this automatically — just use it for visual highlighting.\n\t */\n\tactiveIndex: number;\n\t/** Call this when the user selects an item (click, touch, etc.). */\n\tonSelect: (item: MentionItem) => void;\n\t/**\n\t * Register a keyboard handler so a CUSTOM dropdown can own arrow-key / Enter\n\t * navigation (e.g. a multi-level picker whose visible rows differ from the\n\t * flat `items` list). Return `true` from the handler to consume the key.\n\t * Pass `null` to unregister. When not registered, the editor falls back to\n\t * navigating the flat `items` list.\n\t */\n\tregisterKeyHandler?: (\n\t\thandler: ((event: KeyboardEvent) => boolean) | null,\n\t) => void;\n\t/**\n\t * Dismiss the dropdown WITHOUT selecting an item: closes the menu and strips\n\t * the typed `@`/`#` trigger + query. Use for custom actions in a multi-level\n\t * picker (e.g. a \"Create new\" row that opens a drawer instead of inserting a\n\t * mention).\n\t */\n\tonClose?: () => void;\n}\n\n/**\n * Everything related to @ and # mention dropdowns, in one place.\n *\n * @example\n * mentions={{\n * agents: [{ id: 1, label: 'Alice', avatarUrl: '...' }],\n * teams: [{ id: 't1', label: 'Support' }],\n * onSelect: (item, char) => console.log(char, item),\n * }}\n */\nexport interface MentionConfig {\n\t/** Items shown when the user types `@`. */\n\tagents?: MentionItem[];\n\t/** Items shown when the user types `#`. */\n\tteams?: MentionItem[];\n\t/** Called when the user picks an item. `char` is `'@'` or `'#'`. */\n\tonSelect?: (item: MentionItem, char: '@' | '#') => void;\n\t/**\n\t * Custom renderer for each row in the dropdown.\n\t * `isActive` is `true` when that row is currently highlighted by keyboard\n\t * navigation (arrows move it, Enter selects it). Use it to apply a highlight\n\t * style so the user can see which item they're about to select.\n\t * Omit to use the built-in avatar + name row.\n\t *\n\t * Use `renderDropdown` instead when you need a completely different structure.\n\t *\n\t * @example\n\t * renderItem={(item, isActive) => (\n\t * <div style={{ background: isActive ? '#f0f0f0' : undefined }}>\n\t * {item.label}\n\t * </div>\n\t * )}\n\t */\n\trenderItem?: (item: MentionItem, isActive: boolean) => React.ReactNode;\n\t/**\n\t * Render the entire dropdown yourself instead of individual rows.\n\t * The editor still manages keyboard navigation — `activeIndex` tells you\n\t * which row is highlighted, and `onSelect(item)` confirms the selection.\n\t * Takes priority over `renderItem` when both are provided.\n\t *\n\t * @example\n\t * renderDropdown={({ items, query, activeIndex, onSelect }) => (\n\t * <MyDropdown\n\t * items={items}\n\t * highlightedIndex={activeIndex}\n\t * onPick={onSelect}\n\t * />\n\t * )}\n\t */\n\trenderDropdown?: (props: MentionDropdownRenderProps) => React.ReactNode;\n\t/**\n\t * When true, a typed trigger char (`@` / `#`) and its query are removed if the\n\t * suggestion menu closes without a selection (click-outside / no match). Default\n\t * false — the typed text is kept.\n\t */\n\tremoveTriggerOnDismiss?: boolean;\n}\n\n/**\n * Props passed to the `renderDropdown` function in `SlashCommandConfig`.\n */\nexport interface SlashCommandDropdownRenderProps {\n\titems: SlashCommandItem[];\n\t/** The text the user typed after `/`. */\n\tquery: string;\n\t/** Index of the currently highlighted row. Use for visual highlighting. */\n\tactiveIndex: number;\n\t/** Call this when the user selects an item. */\n\tonSelect: (item: SlashCommandItem) => void;\n}\n\n/**\n * Everything related to the `/` slash-command menu, in one place.\n *\n * @example\n * slashCommands={{\n * items: [{ id: 'ai-reply', label: 'AI Reply', description: 'Generate a reply' }],\n * onSelect: (cmd) => triggerAI(cmd.id),\n * }}\n */\nexport interface SlashCommandConfig {\n\t/** The list of commands. Filtered client-side as the user types after `/`. */\n\titems: SlashCommandItem[];\n\t/** Called when the user selects a command. The `/` trigger is removed from the doc. */\n\tonSelect?: (command: SlashCommandItem) => void;\n\t/**\n\t * Custom renderer for each row.\n\t * `isActive` is `true` when that row is highlighted by keyboard navigation.\n\t * Omit to use the built-in label + description row.\n\t *\n\t * Use `renderDropdown` instead when you need a completely different structure.\n\t */\n\trenderItem?: (item: SlashCommandItem, isActive: boolean) => React.ReactNode;\n\t/**\n\t * Render the entire slash-command dropdown yourself.\n\t * The editor manages keyboard navigation — use `activeIndex` to highlight\n\t * the active row and call `onSelect(item)` to confirm selection.\n\t * Takes priority over `renderItem` when both are provided.\n\t *\n\t * @example\n\t * renderDropdown={({ items, activeIndex, onSelect }) => (\n\t * <MyCmdPalette commands={items} active={activeIndex} onPick={onSelect} />\n\t * )}\n\t */\n\trenderDropdown?: (props: SlashCommandDropdownRenderProps) => React.ReactNode;\n}\n\n/**\n * Configuration for how hyperlinks behave in the editor.\n *\n * @example\n * link={{ renderTooltip: ({ href, text, onOpen, onRemove }) => (\n * <MyLinkPopover href={href} onOpen={onOpen} onRemove={onRemove} />\n * )}}\n */\nexport interface LinkConfig {\n\t/**\n\t * Custom tooltip rendered when the user clicks a link.\n\t * Receives the href, display text, bounding rect (for positioning),\n\t * and ready-to-call action handlers.\n\t * Omit to use the minimal built-in tooltip.\n\t */\n\trenderTooltip?: (props: LinkTooltipProps) => React.ReactNode;\n}\n\n/**\n * Snapshot of all active marks and block types at the current cursor or selection.\n * Returned by onSelectionChange and ref.getActiveFormats().\n *\n * Keep this in component state and pass it to BikEditorToolbar (or your own toolbar)\n * to keep button active-states in sync.\n *\n * @example\n * const [formats, setFormats] = useState(DEFAULT_ACTIVE_FORMATS);\n * <BikEditor onSelectionChange={setFormats} ... />\n * <BikEditorToolbar activeFormats={formats} ... />\n */\nexport interface FormatState {\n\tbold: boolean;\n\titalic: boolean;\n\tunderline: boolean;\n\tstrike: boolean;\n\tbulletList: boolean;\n\torderedList: boolean;\n\tblockquote: boolean;\n\tcodeBlock: boolean;\n\t/** Non-null when the cursor is inside (or selection spans) a hyperlink. */\n\tlink: { href: string } | null;\n\ttextAlign: 'left' | 'center' | 'right' | 'justify' | null;\n\tfontFamily: string | null;\n\tfontSize: string | null;\n\t/** Active text colour as a CSS colour string, or null if none. */\n\tcolor: string | null;\n\t/** Active highlight (background) colour, or null if none. */\n\thighlight: string | null;\n\t/** True when the cursor/selection is in a superscript. */\n\tsuperscript: boolean;\n\t/** True when the cursor/selection is in a subscript. */\n\tsubscript: boolean;\n}\n\nexport const DEFAULT_FORMAT_STATE: FormatState = {\n\tbold: false,\n\titalic: false,\n\tunderline: false,\n\tstrike: false,\n\tbulletList: false,\n\torderedList: false,\n\tblockquote: false,\n\tcodeBlock: false,\n\tlink: null,\n\ttextAlign: null,\n\tfontFamily: null,\n\tfontSize: null,\n\tcolor: null,\n\thighlight: null,\n\tsuperscript: false,\n\tsubscript: false,\n};\n\n/**\n * All formatting and insertion commands. Access via `editorRef.current.actions`.\n *\n * Every method focuses the editor internally — no need to call `.focus()` first.\n *\n * @example\n * editorRef.current?.actions.toggleBold();\n * editorRef.current?.actions.setLink('https://example.com', 'Visit example');\n */\nexport interface EditorActions {\n\t// ── Basic marks ───────────────────────────────────────────────────────────\n\ttoggleBold: () => void;\n\ttoggleItalic: () => void;\n\ttoggleUnderline: () => void;\n\ttoggleStrike: () => void;\n\n\t// ── Blocks ────────────────────────────────────────────────────────────────\n\ttoggleBulletList: () => void;\n\ttoggleOrderedList: () => void;\n\ttoggleBlockquote: () => void;\n\ttoggleCodeBlock: () => void;\n\n\t// ── Alignment & typography ────────────────────────────────────────────────\n\tsetTextAlign: (align: 'left' | 'center' | 'right' | 'justify') => void;\n\t/** Pass a CSS font-family value, e.g. `'Inter, sans-serif'`. Only works when richTypography is on. */\n\tsetFontFamily: (font: string) => void;\n\t/** Pass a CSS size value, e.g. `'16px'` or `'1.25rem'`. Only works when richTypography is on. */\n\tsetFontSize: (size: string) => void;\n\n\t// ── Colour ────────────────────────────────────────────────────────────────\n\t/** Sets the text colour. Pass any CSS colour value, e.g. `'#e53e3e'`. */\n\tsetColor: (color: string) => void;\n\t/** Sets the highlight (background) colour. */\n\tsetHighlight: (color: string) => void;\n\t/** Removes the text colour mark from the current selection. */\n\tunsetColor: () => void;\n\t/** Removes the highlight mark from the current selection. */\n\tunsetHighlight: () => void;\n\n\t// ── Links ─────────────────────────────────────────────────────────────────\n\t/**\n\t * Applies a hyperlink to the current selection, or updates the link the\n\t * cursor is already inside.\n\t *\n\t * @param href The URL.\n\t * @param text Optional display text. When provided, the visible text of the\n\t * linked range is replaced atomically in the same undo step.\n\t *\n\t * @example\n\t * actions.setLink('https://example.com');\n\t * actions.setLink('https://example.com', 'Visit example');\n\t */\n\tsetLink: (href: string, text?: string) => void;\n\t/** Updates only the href of the link at the current cursor. */\n\tupdateLink: (href: string) => void;\n\t/** Removes the link mark but keeps the visible text. */\n\tremoveLink: () => void;\n\n\t// ── Insertions ────────────────────────────────────────────────────────────\n\t/** Inserts an emoji character at the cursor. */\n\tinsertEmoji: (emoji: string) => void;\n\t/**\n\t * Inserts a `{{variableName}}` token at the cursor.\n\t * The token renders with a distinct highlight inside the editor.\n\t */\n\tinsertVariable: (variableName: string) => void;\n\t/** Inserts arbitrary HTML at the current cursor position. */\n\tinsertHtml: (html: string) => void;\n\n\t// ── History ───────────────────────────────────────────────────────────────\n\tundo: () => void;\n\tredo: () => void;\n\tcanUndo: () => boolean;\n\tcanRedo: () => boolean;\n\n\t// ── Rich typography (richTypography feature required) ─────────────────────\n\t/** Toggles superscript on the selection. Only works when richTypography is on. */\n\ttoggleSuperscript: () => void;\n\t/** Toggles subscript on the selection. Only works when richTypography is on. */\n\ttoggleSubscript: () => void;\n\t/** Inserts an inline image at the cursor. Only works when richTypography is on. */\n\tinsertImage: (src: string) => void;\n}\n\n/** Props passed to your renderLinkTooltip render prop. */\nexport interface LinkTooltipProps {\n\t/** The href of the active link. */\n\thref: string;\n\t/** The display text of the link. */\n\ttext: string;\n\t/** Bounding rect of the link element — use this to position your popover. */\n\trect: DOMRect;\n\t/** Opens the link in a new tab. */\n\tonOpen: () => void;\n\t/** Removes the link mark but keeps the visible text. */\n\tonRemove: () => void;\n\t/** Hides the bubble menu. Call this before opening an edit modal so the tooltip doesn't linger. */\n\tonHide: () => void;\n}\n\n/**\n * Imperative handle exposed by BikEditor.\n *\n * Obtain via `useRef<BikEditorRef>()` and pass to `<BikEditor ref={...} />`.\n * All methods are safe to call after the first render.\n *\n * @example\n * const ref = useRef<BikEditorRef>(null);\n * <BikEditor ref={ref} ... />\n * ref.current?.clearContent();\n * ref.current?.actions.toggleBold();\n */\nexport interface BikEditorRef {\n\t// ── Focus ─────────────────────────────────────────────────────────────────\n\t/** Moves focus into the editor. Optionally pass a position: 'start', 'end', 'all', or a numeric offset. */\n\tfocus: (position?: 'start' | 'end' | 'all' | number | boolean | null) => void;\n\t/** Removes focus from the editor. */\n\tblur: () => void;\n\n\t// ── Content ───────────────────────────────────────────────────────────────\n\t/** Clears the entire document and fires onChange. */\n\tclearContent: () => void;\n\t/**\n\t * Replaces the full document with the given HTML and fires onChange.\n\t * Overwrites all sections. Use setSectionContent() / setBodyContent() to\n\t * update a single section without touching the others.\n\t */\n\tsetContent: (html: string) => void;\n\t/** Inserts HTML at the current cursor position without replacing anything. */\n\tinsertContent: (html: string) => void;\n\t/**\n\t * Inserts HTML inline at the current cursor position, unwrapping block\n\t * wrappers (e.g. `<p>`) so the content merges into the surrounding paragraph\n\t * instead of creating new blocks. Use for macros, quick replies, etc.\n\t */\n\tinsertInlineContent: (html: string) => void;\n\t/** Inserts HTML at the very start of the document. */\n\tinsertAtStart: (html: string) => void;\n\t/** Inserts HTML as a new block at the end of the document. */\n\tinsertBlock: (html: string) => void;\n\t/**\n\t * Appends HTML inline inside the last paragraph of the document.\n\t * Ideal for streaming — call repeatedly with each text chunk.\n\t * Use `appendBodyContent` instead if the editor has named sections.\n\t */\n\tappendInline: (html: string) => void;\n\t/** @deprecated Use `insertBlock` */\n\tinsertAtEnd: (html: string) => void;\n\t/** @deprecated Use `appendInline` */\n\tappendContent: (html: string) => void;\n\t/** Returns the full document as `{ html, text, isEmpty, characterCount }`. */\n\tgetContent: () => EditorSnapshot;\n\t/**\n\t * Returns the raw TipTap document as a plain JSON object.\n\t * Returns `null` when the editor is not yet mounted.\n\t */\n\tgetJSON: () => Record<string, unknown> | null;\n\t/**\n\t * Walks the document and returns all mention IDs currently in the editor,\n\t * split by type. IDs are deduplicated and returned as arrays.\n\t *\n\t * @example\n\t * const { agentIds, teamIds } = ref.current?.getMentions() ?? { agentIds: [], teamIds: [] };\n\t */\n\tgetMentions: () => { agentIds: string[]; teamIds: string[] };\n\n\t// ── Selection ─────────────────────────────────────────────────────────────\n\t/**\n\t * Returns the current cursor / selection position as a `{ from, to }` pair.\n\t * When nothing is selected, `from === to` (a collapsed cursor).\n\t * Pass the returned value to `insertAtPosition()` to insert at an exact spot.\n\t *\n\t * @example\n\t * const { from } = ref.current?.getCursorPosition() ?? { from: 0, to: 0 };\n\t * ref.current?.insertAtPosition(from, '<strong>inserted</strong>');\n\t */\n\tgetCursorPosition: () => { from: number; to: number };\n\t/**\n\t * Inserts HTML at an explicit document position rather than at the current cursor.\n\t * Use `getCursorPosition()` to get the position, or any value from\n\t * `findSectionStartPos` / `findSectionEndPos` if you need section-relative insertion.\n\t *\n\t * @example\n\t * const { from } = ref.current!.getCursorPosition();\n\t * ref.current?.insertAtPosition(from, '<em>hello</em>');\n\t */\n\tinsertAtPosition: (pos: number, html: string) => void;\n\t/**\n\t * Returns the currently selected plain text.\n\t * When the cursor is inside a link with nothing selected, returns the full\n\t * link text — useful for pre-filling a link modal's text field.\n\t */\n\tgetSelectedText: () => string;\n\n\t// ── Character count ───────────────────────────────────────────────────────\n\t/**\n\t * Returns the current character count and the configured limit (or null).\n\t * Use this to render your own character counter anywhere you like.\n\t *\n\t * @example\n\t * const { count, limit } = ref.current?.getCharacterCount() ?? { count: 0, limit: null };\n\t * <span style={{ color: count >= (limit ?? Infinity) ? 'red' : 'inherit' }}>\n\t * {count}{limit != null ? ` / ${limit}` : ''}\n\t * </span>\n\t */\n\tgetCharacterCount: () => { count: number; limit: number | null };\n\n\t// ── Sections ─────────────────────────────────────────────────────────────\n\t/**\n\t * Returns content for a named section.\n\t * Use `'body'` to get the main content above all section dividers.\n\t *\n\t * @example\n\t * const sig = ref.current?.getSectionContent('signature');\n\t */\n\tgetSectionContent: (sectionId: string) => EditorSnapshot;\n\t/**\n\t * Replaces the content of a named section without touching other sections.\n\t * If the section doesn't exist yet it is appended at the end.\n\t *\n\t * @example\n\t * ref.current?.setSectionContent('signature', '<p>New signature</p>');\n\t * ref.current?.setSectionContent('body', rephrased); // same as setBodyContent\n\t */\n\tsetSectionContent: (sectionId: string, html: string) => void;\n\t/**\n\t * Moves the cursor to the start of a named section.\n\t * Use `'body'` to focus the main content area.\n\t */\n\tfocusSection: (sectionId: string) => void;\n\t/** Clears all content in a named section (replaces with an empty paragraph). */\n\tclearSection: (sectionId: string) => void;\n\n\t// ── Convenience body shorthands ───────────────────────────────────────────\n\t/** Shorthand for `getSectionContent('body')`. */\n\tgetBodyContent: () => EditorSnapshot;\n\t/** Shorthand for `setSectionContent('body', html)`. */\n\tsetBodyContent: (html: string) => void;\n\t/**\n\t * Atomically sets the body AND all sections in a single editor update.\n\t * Sections are laid out in the exact order supplied — use this instead of\n\t * multiple `setSectionContent()` calls whenever order matters (e.g. forward\n\t * mail where signature must appear before the forwarded thread).\n\t *\n\t * @example\n\t * ref.current?.setBodyAndSections('<p></p>', [\n\t * { id: 'signature', content: '<p>Alice</p>' },\n\t * { id: 'forwarded', content: '<p>--- Forwarded ---</p>' },\n\t * ]);\n\t */\n\tsetBodyAndSections: (\n\t\tbody: string,\n\t\tsections: Array<{ id: string; content: string }>,\n\t) => void;\n\t/**\n\t * Appends HTML to the end of the body section without moving the cursor.\n\t * Ideal for streaming AI-generated content — call repeatedly with each chunk.\n\t * Does NOT clear existing content; call `setBodyContent('')` first if needed.\n\t *\n\t * @example\n\t * // Stream AI response chunk-by-chunk\n\t * ref.current?.setBodyContent('');\n\t * for await (const chunk of aiStream) {\n\t * ref.current?.appendBodyContent(chunk);\n\t * }\n\t */\n\tappendBodyContent: (html: string) => void;\n\n\t/**\n\t * Inserts HTML at the start of a named section (or `'body'`).\n\t * Inserts at the very start of the document when `sectionId` is `'body'`.\n\t */\n\tinsertAtSectionStart: (sectionId: string, html: string) => void;\n\t/**\n\t * Inserts HTML at the end of a named section (or `'body'`).\n\t * For `'body'`, inserts just before the first section divider (or at end of doc).\n\t */\n\tinsertAtSectionEnd: (sectionId: string, html: string) => void;\n\n\t// ── Formats & actions ─────────────────────────────────────────────────────\n\t/** Returns a snapshot of all active marks at the current cursor or selection. */\n\tgetActiveFormats: () => FormatState;\n\t/** All formatting and insertion commands. See EditorActions. */\n\tactions: EditorActions;\n}\n\n/**\n * Props for `<BikEditor />`. All props are optional.\n */\nexport interface BikEditorProps {\n\t// ── Features ──────────────────────────────────────────────────────────────\n\t/**\n\t * Opt in to specific editor capabilities. Both default to `false`.\n\t *\n\t * @example\n\t * <BikEditor features={{ richPaste: true, richTypography: true }} />\n\t */\n\tfeatures?: EditorFeatures;\n\n\t// ── Content ───────────────────────────────────────────────────────────────\n\t/**\n\t * HTML loaded on mount. Ignored after first render.\n\t * Use `ref.setContent()` to change content imperatively later.\n\t */\n\tinitialContent?: string;\n\t/**\n\t * Named sections placed below the main body.\n\t * Each section is separated from the previous one by an invisible divider node.\n\t * The array order determines the visual order in the document.\n\t *\n\t * These are only the INITIAL values — use `ref.setSectionContent()` to update\n\t * a section after mount without re-mounting the editor.\n\t *\n\t * @example\n\t * sections={[\n\t * { id: 'signature', content: '<p>Best regards, Alice</p>' },\n\t * { id: 'forwarded', content: '<p>--- Forwarded message ---</p>' },\n\t * ]}\n\t */\n\tsections?: EditorSection[];\n\t/** Placeholder text shown when the editor is empty. */\n\tplaceholder?: string;\n\n\t// ── Behaviour ─────────────────────────────────────────────────────────────\n\t/** Makes the editor read-only. The toolbar still renders but actions are no-ops. */\n\tdisabled?: boolean;\n\t/**\n\t * Hard character limit. The editor refuses to accept input beyond this point.\n\t * The limit is enforced silently — no UI is rendered. Use\n\t * `ref.getCharacterCount()` or `onChange.characterCount` to display it yourself.\n\t */\n\tmaxCharacters?: number;\n\n\t// ── Keyboard shortcuts ────────────────────────────────────────────────────\n\t/**\n\t * Custom keyboard shortcuts. BikEditor registers no shortcuts of its own —\n\t * every shortcut must be explicitly listed here.\n\t *\n\t * @example\n\t * shortcuts={[\n\t * { key: 'Enter', modifiers: ['mod'], handler: handleSend },\n\t * { key: 's', modifiers: ['mod', 'shift'], handler: handleDraft },\n\t * ]}\n\t */\n\tshortcuts?: KeyboardShortcut[];\n\t/**\n\t * Shortcut key that fires `onSend`. No key is bound to `onSend` unless you\n\t * set this explicitly. Requires `onSend` to also be provided.\n\t *\n\t * `'mod'` maps to Cmd on macOS and Ctrl on Windows/Linux.\n\t *\n\t * @example\n\t * // Single shortcut\n\t * sendShortcut={{ key: 'Enter', modifiers: ['mod'] }}\n\t * // Multiple shortcuts\n\t * sendShortcut={[\n\t * { key: 'Enter', modifiers: ['mod'] },\n\t * { key: 's', modifiers: ['mod'] },\n\t * ]}\n\t */\n\tsendShortcut?:\n\t\t| { key: string; modifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'> }\n\t\t| Array<{\n\t\t\t\tkey: string;\n\t\t\t\tmodifiers?: Array<'mod' | 'ctrl' | 'shift' | 'alt'>;\n\t\t }>;\n\n\t// ── Mentions ─────────────────────────────────────────────────────────────\n\t/**\n\t * Enables `@` (agent) and `#` (team) mention dropdowns.\n\t * Bundle all mention-related config in one object so it's easy to find.\n\t *\n\t * @example\n\t * mentions={{\n\t * agents: myAgents,\n\t * teams: myTeams,\n\t * onSelect: (item, char) => track(char, item.id),\n\t * }}\n\t */\n\tmentions?: MentionConfig;\n\n\t// ── Slash commands ────────────────────────────────────────────────────────\n\t/**\n\t * Enables the `/` slash-command menu.\n\t * Bundle all slash-command config in one object.\n\t *\n\t * @example\n\t * slashCommands={{\n\t * items: MY_COMMANDS,\n\t * onSelect: (cmd) => handleCommand(cmd.id),\n\t * }}\n\t */\n\tslashCommands?: SlashCommandConfig;\n\n\t// ── Link ─────────────────────────────────────────────────────────────────\n\t/**\n\t * Link-related configuration — currently just the click tooltip.\n\t *\n\t * @example\n\t * link={{ renderTooltip: ({ href, onOpen, onRemove }) => (\n\t * <MyTooltip href={href} onOpen={onOpen} onRemove={onRemove} />\n\t * )}}\n\t */\n\tlink?: LinkConfig;\n\n\t// ── Callbacks ─────────────────────────────────────────────────────────────\n\t/**\n\t * Called once, immediately after the editor finishes initializing.\n\t * Any imperative ref methods called before this fires are queued internally\n\t * and executed automatically once the editor is ready — consumers do not\n\t * need timers or readiness guards.\n\t *\n\t * @example\n\t * <BikEditor\n\t * ref={editorRef}\n\t * onReady={() => editorRef.current?.setContent(savedDraft)}\n\t * />\n\t */\n\tonReady?: () => void;\n\t/** Called on every document change. */\n\tonChange?: (content: EditorSnapshot) => void;\n\t/**\n\t * Called when the user presses the key combo defined by `sendShortcut`.\n\t * Only fires when both `onSend` and `sendShortcut` are provided.\n\t */\n\tonSend?: (content: EditorSnapshot) => void;\n\t/** Called when the editor gains focus. */\n\tonFocus?: () => void;\n\t/** Called when the editor loses focus. */\n\tonBlur?: () => void;\n\t/**\n\t * Called on every paste event. Return `true` to fully suppress BikEditor's\n\t * own paste handling (useful when you want to handle images or HTML yourself).\n\t *\n\t * @example\n\t * onPaste={({ images }) => {\n\t * if (images.length) {\n\t * uploadImages(images).then(urls => {\n\t * urls.forEach(url => ref.current?.actions.insertHtml(`<img src=\"${url}\" />`));\n\t * });\n\t * return true; // suppress default — don't embed the raw image data\n\t * }\n\t * }}\n\t */\n\tonPaste?: (data: PasteData) => boolean | void;\n\t/**\n\t * Called on every cursor move or selection change with a snapshot of all\n\t * active marks. Keep in state and pass to your toolbar to sync button states.\n\t */\n\tonSelectionChange?: (activeFormats: FormatState) => void;\n\n\t// ── Styling ───────────────────────────────────────────────────────────────\n\t// Outer wrapper — use these to control the shell (border, border-radius,\n\t// background, shadow, etc.).\n\t/** Extra class name applied to the outer wrapper div. */\n\tclassName?: string;\n\t/** Inline styles applied to the outer wrapper div. */\n\tstyle?: React.CSSProperties;\n\n\t// Inner editable area — use these to control the content div itself\n\t// (padding, font, line-height, etc.).\n\t/** Extra class name applied to the content-editable area (`.ProseMirror` in TipTap). */\n\teditorClassName?: string;\n\t/** Inline styles applied to the content-editable area. */\n\teditorStyle?: React.CSSProperties;\n\n\t// Sizing — applied to the content-editable area.\n\t/** Minimum height of the editable area. CSS value, e.g. `'80px'`. */\n\tminHeight?: string;\n\t/** Maximum height. The editor scrolls internally when exceeded. CSS value, e.g. `'400px'`. */\n\tmaxHeight?: string;\n}\n"],"names":["DEFAULT_FORMAT_STATE"],"mappings":"gFAuVO,MAAMA,EAAoC,CAChD,KAAM,GACN,OAAQ,GACR,UAAW,GACX,OAAQ,GACR,WAAY,GACZ,YAAa,GACb,WAAY,GACZ,UAAW,GACX,KAAM,KACN,UAAW,KACX,WAAY,KACZ,SAAU,KACV,MAAO,KACP,UAAW,KACX,YAAa,GACb,UAAW,EACZ"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),o=require("react"),c=require("../editorDropdown.styles.js"),g=o.forwardRef(({items:r,query:j,command:d,renderItem:f,renderDropdown:u},w)=>{const[s,a]=o.useState(0),x=o.useRef(null),i=o.useRef(null),y=o.useCallback(e=>{i.current=e},[]),h=o.useCallback(e=>{const n=x.current;if(!n)return;n.children[e]?.scrollIntoView({block:"nearest"})},[]),p=e=>{r[e]&&d(r[e])};return o.useImperativeHandle(w,()=>({onKeyDown:({event:e})=>u&&i.current?i.current(e):r.length?e.key==="ArrowUp"?(a(n=>{const l=(n+r.length-1)%r.length;return h(l),l}),!0):e.key==="ArrowDown"?(a(n=>{const l=(n+1)%r.length;return h(l),l}),!0):e.key==="Enter"?(p(s),!0):!1:!1})),o.useEffect(()=>a(0),[r]),r.length?u?t.jsx(t.Fragment,{children:u({items:r,query:j,activeIndex:s,onSelect:e=>d(e),registerKeyHandler:y})}):t.jsx(c.DropdownContainer,{ref:x,children:r.map((e,n)=>t.jsx(c.DropdownItem,{$isActive:n===s,onMouseEnter:()=>a(n),onClick:()=>p(n),children:f?f(e,n===s):t.jsxs(t.Fragment,{children:[e.avatarUrl?t.jsx(c.MentionAvatar,{src:e.avatarUrl,alt:""}):t.jsx(c.MentionAvatarFallback,{children:e.label.charAt(0).toUpperCase()}),t.jsx(c.MentionLabel,{children:e.label}),e.isOnline!==void 0&&t.jsx(c.MentionPresenceDot,{$online:e.isOnline})]})},e.id))}):null});g.displayName="MentionDropdown";exports.MentionDropdown=g;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),o=require("react"),c=require("../editorDropdown.styles.js"),g=o.forwardRef(({items:r,query:j,command:d,renderItem:f,renderDropdown:u,dismiss:w},y)=>{const[s,a]=o.useState(0),x=o.useRef(null),i=o.useRef(null),b=o.useCallback(e=>{i.current=e},[]),h=o.useCallback(e=>{const n=x.current;if(!n)return;n.children[e]?.scrollIntoView({block:"nearest"})},[]),p=e=>{r[e]&&d(r[e])};return o.useImperativeHandle(y,()=>({onKeyDown:({event:e})=>u&&i.current?i.current(e):r.length?e.key==="ArrowUp"?(a(n=>{const l=(n+r.length-1)%r.length;return h(l),l}),!0):e.key==="ArrowDown"?(a(n=>{const l=(n+1)%r.length;return h(l),l}),!0):e.key==="Enter"?(p(s),!0):!1:!1})),o.useEffect(()=>a(0),[r]),r.length?u?t.jsx(t.Fragment,{children:u({items:r,query:j,activeIndex:s,onSelect:e=>d(e),registerKeyHandler:b,onClose:w})}):t.jsx(c.DropdownContainer,{ref:x,children:r.map((e,n)=>t.jsx(c.DropdownItem,{$isActive:n===s,onMouseEnter:()=>a(n),onClick:()=>p(n),children:f?f(e,n===s):t.jsxs(t.Fragment,{children:[e.avatarUrl?t.jsx(c.MentionAvatar,{src:e.avatarUrl,alt:""}):t.jsx(c.MentionAvatarFallback,{children:e.label.charAt(0).toUpperCase()}),t.jsx(c.MentionLabel,{children:e.label}),e.isOnline!==void 0&&t.jsx(c.MentionPresenceDot,{$online:e.isOnline})]})},e.id))}):null});g.displayName="MentionDropdown";exports.MentionDropdown=g;
2
2
  //# sourceMappingURL=MentionDropdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MentionDropdown.js","sources":["../../../../../src/editor/extensions/mention/MentionDropdown.tsx"],"sourcesContent":["import React, {\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tDropdownContainer,\n\tDropdownItem,\n\tMentionAvatar,\n\tMentionAvatarFallback,\n\tMentionLabel,\n\tMentionPresenceDot,\n} from '../editorDropdown.styles';\n\ninterface Props {\n\titems: MentionItem[];\n\tquery: string;\n\tcommand: (item: MentionItem) => void;\n\t/** Custom per-row renderer. Receives the item and whether it is the active row. */\n\trenderItem?: (item: MentionItem, isActive: boolean) => React.ReactNode;\n\t/**\n\t * Full custom dropdown renderer. Takes priority over renderItem.\n\t * The editor passes activeIndex and onSelect — you handle all the visual rendering.\n\t */\n\trenderDropdown?: (props: MentionDropdownRenderProps) => React.ReactNode;\n}\n\nexport const MentionDropdown = forwardRef<any, Props>(\n\t({ items, query, command, renderItem, renderDropdown }, ref) => {\n\t\tconst [selectedIndex, setSelectedIndex] = useState(0);\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\n\t\t// A custom dropdown (renderDropdown) can claim keyboard nav for itself.\n\t\tconst customKeyHandlerRef = useRef<\n\t\t\t((event: KeyboardEvent) => boolean) | null\n\t\t>(null);\n\n\t\tconst registerKeyHandler = useCallback(\n\t\t\t(handler: ((event: KeyboardEvent) => boolean) | null) => {\n\t\t\t\tcustomKeyHandlerRef.current = handler;\n\t\t\t},\n\t\t\t[],\n\t\t);\n\n\t\tconst scrollToIndex = useCallback((index: number) => {\n\t\t\tconst container = containerRef.current;\n\t\t\tif (!container) return;\n\t\t\tconst item = container.children[index] as HTMLElement | undefined;\n\t\t\titem?.scrollIntoView({ block: 'nearest' });\n\t\t}, []);\n\n\t\tconst select = (i: number) => {\n\t\t\tif (items[i]) command(items[i]);\n\t\t};\n\n\t\tuseImperativeHandle(ref, () => ({\n\t\t\tonKeyDown: ({ event }: { event: KeyboardEvent }) => {\n\t\t\t\t// A custom dropdown that registered a handler owns navigation.\n\t\t\t\tif (renderDropdown && customKeyHandlerRef.current) {\n\t\t\t\t\treturn customKeyHandlerRef.current(event);\n\t\t\t\t}\n\t\t\t\tif (!items.length) return false;\n\t\t\t\tif (event.key === 'ArrowUp') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + items.length - 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'ArrowDown') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\tselect(selectedIndex);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t}));\n\n\t\tuseEffect(() => setSelectedIndex(0), [items]);\n\n\t\tif (!items.length) return null;\n\n\t\t// Full custom dropdown — editor still manages keyboard nav via selectedIndex\n\t\tif (renderDropdown) {\n\t\t\treturn (\n\t\t\t\t<>\n\t\t\t\t\t{renderDropdown({\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tquery,\n\t\t\t\t\t\tactiveIndex: selectedIndex,\n\t\t\t\t\t\tonSelect: (item) => command(item),\n\t\t\t\t\t\tregisterKeyHandler,\n\t\t\t\t\t})}\n\t\t\t\t</>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<DropdownContainer ref={containerRef}>\n\t\t\t\t{items.map((item, i) => (\n\t\t\t\t\t<DropdownItem\n\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t$isActive={i === selectedIndex}\n\t\t\t\t\t\tonMouseEnter={() => setSelectedIndex(i)}\n\t\t\t\t\t\tonClick={() => select(i)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{renderItem ? (\n\t\t\t\t\t\t\trenderItem(item, i === selectedIndex)\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t{item.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t<MentionAvatar src={item.avatarUrl} alt=\"\" />\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<MentionAvatarFallback>\n\t\t\t\t\t\t\t\t\t\t{item.label.charAt(0).toUpperCase()}\n\t\t\t\t\t\t\t\t\t</MentionAvatarFallback>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<MentionLabel>{item.label}</MentionLabel>\n\t\t\t\t\t\t\t\t{item.isOnline !== undefined && (\n\t\t\t\t\t\t\t\t\t<MentionPresenceDot $online={item.isOnline} />\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</DropdownItem>\n\t\t\t\t))}\n\t\t\t</DropdownContainer>\n\t\t);\n\t},\n);\nMentionDropdown.displayName = 'MentionDropdown';\n"],"names":["MentionDropdown","forwardRef","items","query","command","renderItem","renderDropdown","ref","selectedIndex","setSelectedIndex","useState","containerRef","useRef","customKeyHandlerRef","registerKeyHandler","useCallback","handler","scrollToIndex","index","container","select","i","useImperativeHandle","event","prev","next","useEffect","item","jsx","DropdownContainer","DropdownItem","jsxs","Fragment","MentionAvatar","MentionAvatarFallback","MentionLabel","MentionPresenceDot"],"mappings":"iLAkCaA,EAAkBC,EAAAA,WAC9B,CAAC,CAAE,MAAAC,EAAO,MAAAC,EAAO,QAAAC,EAAS,WAAAC,EAAY,eAAAC,CAAA,EAAkBC,IAAQ,CAC/D,KAAM,CAACC,EAAeC,CAAgB,EAAIC,EAAAA,SAAS,CAAC,EAC9CC,EAAeC,EAAAA,OAAuB,IAAI,EAE1CC,EAAsBD,EAAAA,OAE1B,IAAI,EAEAE,EAAqBC,EAAAA,YACzBC,GAAwD,CACxDH,EAAoB,QAAUG,CAC/B,EACA,CAAA,CAAC,EAGIC,EAAgBF,cAAaG,GAAkB,CACpD,MAAMC,EAAYR,EAAa,QAC/B,GAAI,CAACQ,EAAW,OACHA,EAAU,SAASD,CAAK,GAC/B,eAAe,CAAE,MAAO,SAAA,CAAW,CAC1C,EAAG,CAAA,CAAE,EAECE,EAAUC,GAAc,CACzBnB,EAAMmB,CAAC,GAAGjB,EAAQF,EAAMmB,CAAC,CAAC,CAC/B,EAmCA,OAjCAC,EAAAA,oBAAoBf,EAAK,KAAO,CAC/B,UAAW,CAAC,CAAE,MAAAgB,KAETjB,GAAkBO,EAAoB,QAClCA,EAAoB,QAAQU,CAAK,EAEpCrB,EAAM,OACPqB,EAAM,MAAQ,WACjBd,EAAkBe,GAAS,CAC1B,MAAMC,GAAQD,EAAOtB,EAAM,OAAS,GAAKA,EAAM,OAC/C,OAAAe,EAAcQ,CAAI,EACXA,CACR,CAAC,EACM,IAEJF,EAAM,MAAQ,aACjBd,EAAkBe,GAAS,CAC1B,MAAMC,GAAQD,EAAO,GAAKtB,EAAM,OAChC,OAAAe,EAAcQ,CAAI,EACXA,CACR,CAAC,EACM,IAEJF,EAAM,MAAQ,SACjBH,EAAOZ,CAAa,EACb,IAED,GArBmB,EAsB3B,EACC,EAEFkB,EAAAA,UAAU,IAAMjB,EAAiB,CAAC,EAAG,CAACP,CAAK,CAAC,EAEvCA,EAAM,OAGPI,oBAGA,SAAAA,EAAe,CACf,MAAAJ,EACA,MAAAC,EACA,YAAaK,EACb,SAAWmB,GAASvB,EAAQuB,CAAI,EAChC,mBAAAb,CAAA,CACA,EACF,EAKDc,MAACC,EAAAA,mBAAkB,IAAKlB,EACtB,WAAM,IAAI,CAACgB,EAAMN,IACjBO,EAAAA,IAACE,EAAAA,aAAA,CAEA,UAAWT,IAAMb,EACjB,aAAc,IAAMC,EAAiBY,CAAC,EACtC,QAAS,IAAMD,EAAOC,CAAC,EAEtB,WACAhB,EAAWsB,EAAMN,IAAMb,CAAa,EAEpCuB,EAAAA,KAAAC,WAAA,CACE,SAAA,CAAAL,EAAK,UACLC,EAAAA,IAACK,gBAAA,CAAc,IAAKN,EAAK,UAAW,IAAI,EAAA,CAAG,EAE3CC,EAAAA,IAACM,EAAAA,uBACC,SAAAP,EAAK,MAAM,OAAO,CAAC,EAAE,cACvB,EAEDC,EAAAA,IAACO,EAAAA,aAAA,CAAc,SAAAR,EAAK,KAAA,CAAM,EACzBA,EAAK,WAAa,cACjBS,EAAAA,mBAAA,CAAmB,QAAST,EAAK,QAAA,CAAU,CAAA,CAAA,CAE9C,CAAA,EApBIA,EAAK,EAAA,CAuBX,EACF,EA7CyB,IA+C3B,CACD,EACA3B,EAAgB,YAAc"}
1
+ {"version":3,"file":"MentionDropdown.js","sources":["../../../../../src/editor/extensions/mention/MentionDropdown.tsx"],"sourcesContent":["import React, {\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport type {\n\tMentionDropdownRenderProps,\n\tMentionItem,\n} from '../../BikEditor.types';\nimport {\n\tDropdownContainer,\n\tDropdownItem,\n\tMentionAvatar,\n\tMentionAvatarFallback,\n\tMentionLabel,\n\tMentionPresenceDot,\n} from '../editorDropdown.styles';\n\ninterface Props {\n\titems: MentionItem[];\n\tquery: string;\n\tcommand: (item: MentionItem) => void;\n\t/** Custom per-row renderer. Receives the item and whether it is the active row. */\n\trenderItem?: (item: MentionItem, isActive: boolean) => React.ReactNode;\n\t/**\n\t * Full custom dropdown renderer. Takes priority over renderItem.\n\t * The editor passes activeIndex and onSelect — you handle all the visual rendering.\n\t */\n\trenderDropdown?: (props: MentionDropdownRenderProps) => React.ReactNode;\n\t/** Close the menu without selecting (strips the typed trigger). Injected by the extension. */\n\tdismiss?: () => void;\n}\n\nexport const MentionDropdown = forwardRef<any, Props>(\n\t({ items, query, command, renderItem, renderDropdown, dismiss }, ref) => {\n\t\tconst [selectedIndex, setSelectedIndex] = useState(0);\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\n\t\t// A custom dropdown (renderDropdown) can claim keyboard nav for itself.\n\t\tconst customKeyHandlerRef = useRef<\n\t\t\t((event: KeyboardEvent) => boolean) | null\n\t\t>(null);\n\n\t\tconst registerKeyHandler = useCallback(\n\t\t\t(handler: ((event: KeyboardEvent) => boolean) | null) => {\n\t\t\t\tcustomKeyHandlerRef.current = handler;\n\t\t\t},\n\t\t\t[],\n\t\t);\n\n\t\tconst scrollToIndex = useCallback((index: number) => {\n\t\t\tconst container = containerRef.current;\n\t\t\tif (!container) return;\n\t\t\tconst item = container.children[index] as HTMLElement | undefined;\n\t\t\titem?.scrollIntoView({ block: 'nearest' });\n\t\t}, []);\n\n\t\tconst select = (i: number) => {\n\t\t\tif (items[i]) command(items[i]);\n\t\t};\n\n\t\tuseImperativeHandle(ref, () => ({\n\t\t\tonKeyDown: ({ event }: { event: KeyboardEvent }) => {\n\t\t\t\t// A custom dropdown that registered a handler owns navigation.\n\t\t\t\tif (renderDropdown && customKeyHandlerRef.current) {\n\t\t\t\t\treturn customKeyHandlerRef.current(event);\n\t\t\t\t}\n\t\t\t\tif (!items.length) return false;\n\t\t\t\tif (event.key === 'ArrowUp') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + items.length - 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'ArrowDown') {\n\t\t\t\t\tsetSelectedIndex((prev) => {\n\t\t\t\t\t\tconst next = (prev + 1) % items.length;\n\t\t\t\t\t\tscrollToIndex(next);\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\tselect(selectedIndex);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t}));\n\n\t\tuseEffect(() => setSelectedIndex(0), [items]);\n\n\t\tif (!items.length) return null;\n\n\t\t// Full custom dropdown — editor still manages keyboard nav via selectedIndex\n\t\tif (renderDropdown) {\n\t\t\treturn (\n\t\t\t\t<>\n\t\t\t\t\t{renderDropdown({\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tquery,\n\t\t\t\t\t\tactiveIndex: selectedIndex,\n\t\t\t\t\t\tonSelect: (item) => command(item),\n\t\t\t\t\t\tregisterKeyHandler,\n\t\t\t\t\t\tonClose: dismiss,\n\t\t\t\t\t})}\n\t\t\t\t</>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<DropdownContainer ref={containerRef}>\n\t\t\t\t{items.map((item, i) => (\n\t\t\t\t\t<DropdownItem\n\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\t$isActive={i === selectedIndex}\n\t\t\t\t\t\tonMouseEnter={() => setSelectedIndex(i)}\n\t\t\t\t\t\tonClick={() => select(i)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{renderItem ? (\n\t\t\t\t\t\t\trenderItem(item, i === selectedIndex)\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t{item.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t<MentionAvatar src={item.avatarUrl} alt=\"\" />\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<MentionAvatarFallback>\n\t\t\t\t\t\t\t\t\t\t{item.label.charAt(0).toUpperCase()}\n\t\t\t\t\t\t\t\t\t</MentionAvatarFallback>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<MentionLabel>{item.label}</MentionLabel>\n\t\t\t\t\t\t\t\t{item.isOnline !== undefined && (\n\t\t\t\t\t\t\t\t\t<MentionPresenceDot $online={item.isOnline} />\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</DropdownItem>\n\t\t\t\t))}\n\t\t\t</DropdownContainer>\n\t\t);\n\t},\n);\nMentionDropdown.displayName = 'MentionDropdown';\n"],"names":["MentionDropdown","forwardRef","items","query","command","renderItem","renderDropdown","dismiss","ref","selectedIndex","setSelectedIndex","useState","containerRef","useRef","customKeyHandlerRef","registerKeyHandler","useCallback","handler","scrollToIndex","index","container","select","i","useImperativeHandle","event","prev","next","useEffect","item","jsx","DropdownContainer","DropdownItem","jsxs","Fragment","MentionAvatar","MentionAvatarFallback","MentionLabel","MentionPresenceDot"],"mappings":"iLAoCaA,EAAkBC,EAAAA,WAC9B,CAAC,CAAE,MAAAC,EAAO,MAAAC,EAAO,QAAAC,EAAS,WAAAC,EAAY,eAAAC,EAAgB,QAAAC,CAAA,EAAWC,IAAQ,CACxE,KAAM,CAACC,EAAeC,CAAgB,EAAIC,EAAAA,SAAS,CAAC,EAC9CC,EAAeC,EAAAA,OAAuB,IAAI,EAE1CC,EAAsBD,EAAAA,OAE1B,IAAI,EAEAE,EAAqBC,EAAAA,YACzBC,GAAwD,CACxDH,EAAoB,QAAUG,CAC/B,EACA,CAAA,CAAC,EAGIC,EAAgBF,cAAaG,GAAkB,CACpD,MAAMC,EAAYR,EAAa,QAC/B,GAAI,CAACQ,EAAW,OACHA,EAAU,SAASD,CAAK,GAC/B,eAAe,CAAE,MAAO,SAAA,CAAW,CAC1C,EAAG,CAAA,CAAE,EAECE,EAAUC,GAAc,CACzBpB,EAAMoB,CAAC,GAAGlB,EAAQF,EAAMoB,CAAC,CAAC,CAC/B,EAmCA,OAjCAC,EAAAA,oBAAoBf,EAAK,KAAO,CAC/B,UAAW,CAAC,CAAE,MAAAgB,KAETlB,GAAkBQ,EAAoB,QAClCA,EAAoB,QAAQU,CAAK,EAEpCtB,EAAM,OACPsB,EAAM,MAAQ,WACjBd,EAAkBe,GAAS,CAC1B,MAAMC,GAAQD,EAAOvB,EAAM,OAAS,GAAKA,EAAM,OAC/C,OAAAgB,EAAcQ,CAAI,EACXA,CACR,CAAC,EACM,IAEJF,EAAM,MAAQ,aACjBd,EAAkBe,GAAS,CAC1B,MAAMC,GAAQD,EAAO,GAAKvB,EAAM,OAChC,OAAAgB,EAAcQ,CAAI,EACXA,CACR,CAAC,EACM,IAEJF,EAAM,MAAQ,SACjBH,EAAOZ,CAAa,EACb,IAED,GArBmB,EAsB3B,EACC,EAEFkB,EAAAA,UAAU,IAAMjB,EAAiB,CAAC,EAAG,CAACR,CAAK,CAAC,EAEvCA,EAAM,OAGPI,oBAGA,SAAAA,EAAe,CACf,MAAAJ,EACA,MAAAC,EACA,YAAaM,EACb,SAAWmB,GAASxB,EAAQwB,CAAI,EAChC,mBAAAb,EACA,QAASR,CAAA,CACT,EACF,EAKDsB,MAACC,EAAAA,mBAAkB,IAAKlB,EACtB,WAAM,IAAI,CAACgB,EAAMN,IACjBO,EAAAA,IAACE,EAAAA,aAAA,CAEA,UAAWT,IAAMb,EACjB,aAAc,IAAMC,EAAiBY,CAAC,EACtC,QAAS,IAAMD,EAAOC,CAAC,EAEtB,WACAjB,EAAWuB,EAAMN,IAAMb,CAAa,EAEpCuB,EAAAA,KAAAC,WAAA,CACE,SAAA,CAAAL,EAAK,UACLC,EAAAA,IAACK,gBAAA,CAAc,IAAKN,EAAK,UAAW,IAAI,EAAA,CAAG,EAE3CC,EAAAA,IAACM,EAAAA,uBACC,SAAAP,EAAK,MAAM,OAAO,CAAC,EAAE,cACvB,EAEDC,EAAAA,IAACO,EAAAA,aAAA,CAAc,SAAAR,EAAK,KAAA,CAAM,EACzBA,EAAK,WAAa,cACjBS,EAAAA,mBAAA,CAAmB,QAAST,EAAK,QAAA,CAAU,CAAA,CAAA,CAE9C,CAAA,EApBIA,EAAK,EAAA,CAuBX,EACF,EA9CyB,IAgD3B,CACD,EACA5B,EAAgB,YAAc"}