profclaw 0.0.1-beta.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -38
- package/CONTRIBUTING.md +3 -5
- package/README.md +128 -63
- package/dist/chat/execution/tools/index.d.ts +1 -1
- package/dist/chat/execution/tools/index.js +41 -2
- package/dist/chat/providers/slack/index.d.ts +2 -2
- package/dist/cli/commands/models.js +39 -26
- package/dist/cli/commands/onboard.js +64 -79
- package/dist/cli/commands/setup.js +293 -90
- package/dist/cli/index.js +0 -6
- package/dist/cli/providers.d.ts +15 -0
- package/dist/cli/providers.js +41 -0
- package/dist/core/deployment.js +2 -0
- package/dist/providers/ai-sdk.js +26 -6
- package/dist/routes/channels.d.ts +12 -0
- package/dist/routes/channels.js +166 -0
- package/dist/server/route-loader.js +1 -0
- package/dist/server.js +115 -109
- package/package.json +1 -1
- package/skills/git-workflow/SKILL.md +3 -3
- package/ui/dist/assets/{ActivityView-DIPQSJ_d.js → ActivityView-BeshZXmE.js} +1 -1
- package/ui/dist/assets/{AgentList-CqyaYrcq.js → AgentList-QVHeldPi.js} +1 -1
- package/ui/dist/assets/{AnalyticsDashboard-C-mjuGHT.js → AnalyticsDashboard-C9R97dXE.js} +1 -1
- package/ui/dist/assets/{AreaChart-CfYWmbtr.js → AreaChart-B73gaiVQ.js} +1 -1
- package/ui/dist/assets/{CartesianChart-BaQ3It0c.js → CartesianChart-CXYL2R-A.js} +1 -1
- package/ui/dist/assets/{ChatView-DxxQy6pl.js → ChatView-qjZErlrp.js} +1 -1
- package/ui/dist/assets/{CostsDashboard-CDBBcGkg.js → CostsDashboard-O4DCLy1i.js} +1 -1
- package/ui/dist/assets/{EstimateSelect-CDjf5qKl.js → EstimateSelect-1hQf4Osk.js} +1 -1
- package/ui/dist/assets/{FloatingChatbot-CZHjvJIe.js → FloatingChatbot-BZBzrJxd.js} +1 -1
- package/ui/dist/assets/{InviteCodeManagement-DTm-IPTm.js → InviteCodeManagement-LEoGqYeA.js} +1 -1
- package/ui/dist/assets/{ProjectDetail-DlYUcOss.js → ProjectDetail--gPfvATB.js} +1 -1
- package/ui/dist/assets/{ProjectIcon-BMRpnM04.js → ProjectIcon-Chd_ofsw.js} +1 -1
- package/ui/dist/assets/{ProjectList-D85TN0i0.js → ProjectList-BvUfVB6c.js} +1 -1
- package/ui/dist/assets/{Settings-CgPqzUvj.js → Settings-1kaf7VHE.js} +1 -1
- package/ui/dist/assets/{StatusIndicator-yig0uZEA.js → StatusIndicator-pRfkNcdV.js} +1 -1
- package/ui/dist/assets/{SummaryDetail-CwLAfHgJ.js → SummaryDetail-DV3AmONk.js} +1 -1
- package/ui/dist/assets/{SummaryList-BvS5Idnu.js → SummaryList-B6kXiTxL.js} +1 -1
- package/ui/dist/assets/{TaskDetail-zarC1fOt.js → TaskDetail-CV6CzbOS.js} +1 -1
- package/ui/dist/assets/{TaskList-CyJq3ANE.js → TaskList-DL7brQKd.js} +1 -1
- package/ui/dist/assets/{TicketBoard-BlWr3-iH.js → TicketBoard-CrkkFj7C.js} +1 -1
- package/ui/dist/assets/{TicketDetail-DmqWKj2W.js → TicketDetail-hnnYclpD.js} +1 -1
- package/ui/dist/assets/{TicketList-Scj4pMWa.js → TicketList-CsDAyQCL.js} +1 -1
- package/ui/dist/assets/{UserManagement-BH7uG7dw.js → UserManagement-BGFQyTSr.js} +1 -1
- package/ui/dist/assets/{ViewSwitcher-3HzZUdWn.js → ViewSwitcher-CnL0OqA8.js} +1 -1
- package/ui/dist/assets/{alert-dialog-DWPb2IfQ.js → alert-dialog-SKM6Gjz4.js} +1 -1
- package/ui/dist/assets/{archive-CGck7gxR.js → archive-BsLa7brF.js} +1 -1
- package/ui/dist/assets/{badge-DEmc3Z_l.js → badge-CVHH1a-v.js} +1 -1
- package/ui/dist/assets/{brain-CfFdLVqb.js → brain-6o_RHVpe.js} +1 -1
- package/ui/dist/assets/{bug-DqSGPUUE.js → bug-CmZI7jqM.js} +1 -1
- package/ui/dist/assets/{calendar-BuZ4zbPW.js → calendar-Bf0t2B82.js} +1 -1
- package/ui/dist/assets/{chevron-up-DcJ4LL_N.js → chevron-up-CoUsOvZj.js} +1 -1
- package/ui/dist/assets/{circle-x-C78PNZjF.js → circle-x-Dgw11LgT.js} +1 -1
- package/ui/dist/assets/{constants-DhDjZe4P.js → constants-Q5Zivl-a.js} +1 -1
- package/ui/dist/assets/{cpu-Ck6AoG8c.js → cpu-DiPMQICV.js} +1 -1
- package/ui/dist/assets/{database-CA2w8Lvt.js → database-BwTfupDi.js} +1 -1
- package/ui/dist/assets/{dialog-BOdGWhgE.js → dialog-BUqN9Psj.js} +1 -1
- package/ui/dist/assets/{ellipsis-FhHKRbfl.js → ellipsis-UJx4Xnf6.js} +1 -1
- package/ui/dist/assets/{ellipsis-vertical-CO0UqE4-.js → ellipsis-vertical-DoULYEKn.js} +1 -1
- package/ui/dist/assets/{file-code-ChnhYYj1.js → file-code-B2UrJLwi.js} +1 -1
- package/ui/dist/assets/{folder-open-CHwA1-ve.js → folder-open-BJi577JH.js} +1 -1
- package/ui/dist/assets/{funnel-ByEjRFNB.js → funnel-PkaD_HSR.js} +1 -1
- package/ui/dist/assets/{git-branch-GTOPQgU4.js → git-branch-C_K30am0.js} +1 -1
- package/ui/dist/assets/{git-commit-horizontal-F5M84Kut.js → git-commit-horizontal-IT6ecxWQ.js} +1 -1
- package/ui/dist/assets/{globe-CQWfr7hT.js → globe-f-jjCa_g.js} +1 -1
- package/ui/dist/assets/{hash-nKC9gtLg.js → hash-DNEv8Elo.js} +1 -1
- package/ui/dist/assets/{history-DfFSA9xJ.js → history-BQSBo_1Q.js} +1 -1
- package/ui/dist/assets/{index-DHGvP9mp.js → index-BUmnwPQr.js} +1 -1
- package/ui/dist/assets/{index-Z4-RtZcs.js → index-BfF5G4Cw.js} +1 -1
- package/ui/dist/assets/{index-DeI8lKRR.js → index-C8N375c2.js} +1 -1
- package/ui/dist/assets/index-CuxnqVVz.css +1 -0
- package/ui/dist/assets/{index-Ca3vk7Gq.js → index-CzMM3QOk.js} +1 -1
- package/ui/dist/assets/{index--JkIxVXb.js → index-lJlNPFVJ.js} +3 -3
- package/ui/dist/assets/{index-a4Fxq0Hb.js → index-nS3EErDg.js} +1 -1
- package/ui/dist/assets/{layers-DFeLExSa.js → layers-jFqVrWMD.js} +1 -1
- package/ui/dist/assets/{layout-dashboard-WmgjMhWF.js → layout-dashboard-CcKt1hXw.js} +1 -1
- package/ui/dist/assets/{lightbulb-Bo8hEr7B.js → lightbulb-Jhp7FvbU.js} +1 -1
- package/ui/dist/assets/{link-2-YqrpQXBH.js → link-2-DdO7ostF.js} +1 -1
- package/ui/dist/assets/{markdown-renderer-Croje6Xe.js → markdown-renderer-n1ToC4XQ.js} +1 -1
- package/ui/dist/assets/{message-square-CD0H5hot.js → message-square-CBgH65X7.js} +1 -1
- package/ui/dist/assets/{pencil-DpFnj5dn.js → pencil-CYXCEPQh.js} +1 -1
- package/ui/dist/assets/{play-DVgea_jT.js → play-d1ONaH0-.js} +1 -1
- package/ui/dist/assets/{popover-JXecfWG5.js → popover-CrmZgoWu.js} +1 -1
- package/ui/dist/assets/{progress-C1ghf1Fu.js → progress-uv4SPkL5.js} +1 -1
- package/ui/dist/assets/{rocket-BFxPYGx9.js → rocket-DhvUetsk.js} +1 -1
- package/ui/dist/assets/{select-MADP8m6Q.js → select-CeQ8AHGy.js} +1 -1
- package/ui/dist/assets/{send-eYnW_7n-.js → send-P0r5D7td.js} +1 -1
- package/ui/dist/assets/{server-CPMaysH8.js → server-CVHTZB72.js} +1 -1
- package/ui/dist/assets/{settings-2-scXUOuE_.js → settings-2-ocj5uHGx.js} +1 -1
- package/ui/dist/assets/{sheet-r6NSOxi-.js → sheet-DuQExSho.js} +1 -1
- package/ui/dist/assets/{shield-check-PEr7nmVw.js → shield-check-DfVdE34l.js} +1 -1
- package/ui/dist/assets/{shield-off-CLtXio62.js → shield-off-8l0J6R-8.js} +1 -1
- package/ui/dist/assets/{skeleton-C9oEzNlU.js → skeleton-TFiFJ3nB.js} +1 -1
- package/ui/dist/assets/{smartphone-DusFfY0U.js → smartphone-77_g3SQn.js} +1 -1
- package/ui/dist/assets/{square-e1yxB2eR.js → square-Ckzsr3Rn.js} +1 -1
- package/ui/dist/assets/{switch-tNs0n-kz.js → switch-CAePkd6k.js} +1 -1
- package/ui/dist/assets/{table-CXxtLicg.js → table-ZjAZ7hkt.js} +1 -1
- package/ui/dist/assets/{tag-tAwMmQ9G.js → tag-C35mgoEv.js} +1 -1
- package/ui/dist/assets/{textarea-BjiEeIWh.js → textarea-DsVPnSgR.js} +1 -1
- package/ui/dist/assets/{timer-Vel1N3RP.js → timer-DHJBS2w1.js} +1 -1
- package/ui/dist/assets/{tooltip-ZMwtfr1J.js → tooltip-BYmQ331W.js} +1 -1
- package/ui/dist/assets/{trash-2-eM-CNwsZ.js → trash-2-keO5tKPE.js} +1 -1
- package/ui/dist/assets/{trending-up-BGafmjRo.js → trending-up-BBv8KbrY.js} +1 -1
- package/ui/dist/assets/{wand-sparkles-DPvcd9Pi.js → wand-sparkles-BusQ52ZK.js} +1 -1
- package/ui/dist/assets/{wrench-B8s3zYVV.js → wrench-02YaOSiK.js} +1 -1
- package/ui/dist/index.html +2 -2
- package/dist/chat/auto-reply.d.ts +0 -90
- package/dist/chat/auto-reply.js +0 -272
- package/dist/chat/execution/pty.d.ts +0 -92
- package/dist/chat/execution/pty.js +0 -285
- package/dist/chat/execution/tools/glinr-ops.d.ts +0 -202
- package/dist/chat/execution/tools/glinr-ops.js +0 -694
- package/dist/cli/commands/browser.d.ts +0 -3
- package/dist/cli/commands/browser.js +0 -138
- package/dist/cli/commands/canvas.d.ts +0 -3
- package/dist/cli/commands/canvas.js +0 -155
- package/dist/cli/commands/nodes.d.ts +0 -3
- package/dist/cli/commands/nodes.js +0 -193
- package/dist/diagnostics/exporters.d.ts +0 -21
- package/dist/diagnostics/exporters.js +0 -138
- package/dist/diagnostics/index.d.ts +0 -10
- package/dist/diagnostics/index.js +0 -9
- package/dist/diagnostics/middleware.d.ts +0 -12
- package/dist/diagnostics/middleware.js +0 -58
- package/dist/diagnostics/tracer.d.ts +0 -133
- package/dist/diagnostics/tracer.js +0 -257
- package/dist/discovery/index.d.ts +0 -8
- package/dist/discovery/index.js +0 -7
- package/dist/discovery/mdns.d.ts +0 -40
- package/dist/discovery/mdns.js +0 -249
- package/dist/plugins/registry.d.ts +0 -122
- package/dist/plugins/registry.js +0 -352
- package/dist/plugins/sandbox.d.ts +0 -77
- package/dist/plugins/sandbox.js +0 -287
- package/dist/plugins/search/brave.d.ts +0 -9
- package/dist/plugins/search/brave.js +0 -157
- package/dist/plugins/search/duckduckgo.d.ts +0 -9
- package/dist/plugins/search/duckduckgo.js +0 -171
- package/dist/plugins/search/index.d.ts +0 -13
- package/dist/plugins/search/index.js +0 -23
- package/dist/plugins/search/searxng.d.ts +0 -9
- package/dist/plugins/search/searxng.js +0 -170
- package/dist/plugins/search/serper.d.ts +0 -9
- package/dist/plugins/search/serper.js +0 -135
- package/dist/plugins/search/tavily.d.ts +0 -9
- package/dist/plugins/search/tavily.js +0 -146
- package/dist/providers/adapters/anthropic.d.ts +0 -26
- package/dist/providers/adapters/anthropic.js +0 -306
- package/dist/providers/adapters/base.d.ts +0 -53
- package/dist/providers/adapters/base.js +0 -99
- package/dist/providers/adapters/ollama.d.ts +0 -30
- package/dist/providers/adapters/ollama.js +0 -292
- package/dist/utils/ai-cache.d.ts +0 -72
- package/dist/utils/ai-cache.js +0 -204
- package/dist/utils/file-lock.d.ts +0 -85
- package/dist/utils/file-lock.js +0 -204
- package/ui/dist/assets/index-WclMPci1.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as e}from"./index
|
|
1
|
+
import{c as e}from"./index-lJlNPFVJ.js";const t=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]],o=e("square",t);export{o as S};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as s,at as g,ao as B,j as a,ap as k,ar as T,b9 as I,av as M,i as H}from"./index
|
|
1
|
+
import{r as s,at as g,ao as B,j as a,ap as k,ar as T,b9 as I,av as M,i as H}from"./index-lJlNPFVJ.js";import{u as A}from"./select-CeQ8AHGy.js";var b="Switch",[U]=M(b),[X,q]=U(b),y=s.forwardRef((t,o)=>{const{__scopeSwitch:e,name:n,checked:r,defaultChecked:m,required:l,disabled:i,value:u="on",onCheckedChange:w,form:c,...v}=t,[d,p]=s.useState(null),S=g(o,h=>p(h)),x=s.useRef(!1),C=d?c||!!d.closest("form"):!0,[f,_]=B({prop:r,defaultProp:m??!1,onChange:w,caller:b});return a.jsxs(X,{scope:e,checked:f,disabled:i,children:[a.jsx(k.button,{type:"button",role:"switch","aria-checked":f,"aria-required":l,"data-state":j(f),"data-disabled":i?"":void 0,disabled:i,value:u,...v,ref:S,onClick:T(t.onClick,h=>{_(N=>!N),C&&(x.current=h.isPropagationStopped(),x.current||h.stopPropagation())})}),C&&a.jsx(R,{control:d,bubbles:!x.current,name:n,value:u,checked:f,required:l,disabled:i,form:c,style:{transform:"translateX(-100%)"}})]})});y.displayName=b;var P="SwitchThumb",E=s.forwardRef((t,o)=>{const{__scopeSwitch:e,...n}=t,r=q(P,e);return a.jsx(k.span,{"data-state":j(r.checked),"data-disabled":r.disabled?"":void 0,...n,ref:o})});E.displayName=P;var z="SwitchBubbleInput",R=s.forwardRef(({__scopeSwitch:t,control:o,checked:e,bubbles:n=!0,...r},m)=>{const l=s.useRef(null),i=g(l,m),u=A(e),w=I(o);return s.useEffect(()=>{const c=l.current;if(!c)return;const v=window.HTMLInputElement.prototype,p=Object.getOwnPropertyDescriptor(v,"checked").set;if(u!==e&&p){const S=new Event("click",{bubbles:n});p.call(c,e),c.dispatchEvent(S)}},[u,e,n]),a.jsx("input",{type:"checkbox","aria-hidden":!0,defaultChecked:e,...r,tabIndex:-1,ref:i,style:{...r.style,...w,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});R.displayName=z;function j(t){return t?"checked":"unchecked"}var L=y,O=E;function W({className:t,checked:o,...e}){return a.jsx(L,{"data-slot":"switch",checked:o,className:H("peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full","border-2 border-transparent shadow-sm transition-colors duration-200","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2","disabled:cursor-not-allowed disabled:opacity-50",t),style:{backgroundColor:o?"var(--primary)":"#a1a1aa"},...e,children:a.jsx(O,{"data-slot":"switch-thumb",className:"pointer-events-none block h-5 w-5 rounded-full bg-white shadow-lg ring-0 transition-transform duration-200",style:{transform:o?"translateX(20px)":"translateX(0px)"}})})}export{W as S};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as o,j as t,i as r}from"./index
|
|
1
|
+
import{r as o,j as t,i as r}from"./index-lJlNPFVJ.js";const l=o.forwardRef(({className:a,...e},s)=>t.jsx("div",{className:"relative w-full overflow-auto",children:t.jsx("table",{ref:s,className:r("w-full caption-bottom text-sm",a),...e})}));l.displayName="Table";const d=o.forwardRef(({className:a,...e},s)=>t.jsx("thead",{ref:s,className:r("[&_tr]:border-b",a),...e}));d.displayName="TableHeader";const m=o.forwardRef(({className:a,...e},s)=>t.jsx("tbody",{ref:s,className:r("[&_tr:last-child]:border-0",a),...e}));m.displayName="TableBody";const b=o.forwardRef(({className:a,...e},s)=>t.jsx("tfoot",{ref:s,className:r("border-t bg-[var(--muted)]/50 font-medium [&>tr]:last:border-b-0",a),...e}));b.displayName="TableFooter";const c=o.forwardRef(({className:a,...e},s)=>t.jsx("tr",{ref:s,className:r("border-b transition-colors hover:bg-[var(--muted)]/50 data-[state=selected]:bg-[var(--muted)]",a),...e}));c.displayName="TableRow";const i=o.forwardRef(({className:a,...e},s)=>t.jsx("th",{ref:s,className:r("h-12 px-4 text-left align-middle font-medium text-[var(--muted-foreground)] [&:has([role=checkbox])]:pr-0",a),...e}));i.displayName="TableHead";const f=o.forwardRef(({className:a,...e},s)=>t.jsx("td",{ref:s,className:r("p-4 align-middle [&:has([role=checkbox])]:pr-0",a),...e}));f.displayName="TableCell";const n=o.forwardRef(({className:a,...e},s)=>t.jsx("caption",{ref:s,className:r("mt-4 text-sm text-[var(--muted-foreground)]",a),...e}));n.displayName="TableCaption";export{l as T,d as a,c as b,i as c,m as d,f as e};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c}from"./index
|
|
1
|
+
import{c}from"./index-lJlNPFVJ.js";const a=[["path",{d:"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z",key:"vktsd0"}],["circle",{cx:"7.5",cy:"7.5",r:".5",fill:"currentColor",key:"kqv944"}]],e=c("tag",a);export{e as T};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as t,j as o,i as s}from"./index
|
|
1
|
+
import{r as t,j as o,i as s}from"./index-lJlNPFVJ.js";const d=t.forwardRef(({className:e,...r},a)=>o.jsx("textarea",{className:s("flex min-h-[80px] w-full rounded-2xl border-none field-recessed px-4 py-3 text-sm transition-all duration-300 placeholder:text-[var(--muted-foreground)]/50 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 font-medium",e),ref:a,...r}));d.displayName="Textarea";export{d as T};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as e}from"./index
|
|
1
|
+
import{c as e}from"./index-lJlNPFVJ.js";const c=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],i=e("circle-question-mark",c);const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],n=e("info",a);const o=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],s=e("save",o);const t=[["line",{x1:"10",x2:"14",y1:"2",y2:"2",key:"14vaq8"}],["line",{x1:"12",x2:"15",y1:"14",y2:"11",key:"17fdiu"}],["circle",{cx:"12",cy:"14",r:"8",key:"1e1u0o"}]],r=e("timer",t);export{i as C,n as I,s as S,r as T};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as s,aq as Y,ao as X,j as u,bf as K,at as N,bg as W,ap as J,ar as y,as as H,bh as Q,bi as S,bj as Z,bk as ee,av as te,bl as oe,bm as re,i as ne}from"./index
|
|
1
|
+
import{r as s,aq as Y,ao as X,j as u,bf as K,at as N,bg as W,ap as J,ar as y,as as H,bh as Q,bi as S,bj as Z,bk as ee,av as te,bl as oe,bm as re,i as ne}from"./index-lJlNPFVJ.js";import{R as se}from"./select-CeQ8AHGy.js";var[_]=te("Tooltip",[S]),O=S(),G="TooltipProvider",ae=700,k="tooltip.open",[ie,L]=_(G),F=e=>{const{__scopeTooltip:o,delayDuration:t=ae,skipDelayDuration:r=300,disableHoverableContent:n=!1,children:l}=e,i=s.useRef(!0),v=s.useRef(!1),a=s.useRef(0);return s.useEffect(()=>{const p=a.current;return()=>window.clearTimeout(p)},[]),u.jsx(ie,{scope:o,isOpenDelayedRef:i,delayDuration:t,onOpen:s.useCallback(()=>{window.clearTimeout(a.current),i.current=!1},[]),onClose:s.useCallback(()=>{window.clearTimeout(a.current),a.current=window.setTimeout(()=>i.current=!0,r)},[r]),isPointerInTransitRef:v,onPointerInTransitChange:s.useCallback(p=>{v.current=p},[]),disableHoverableContent:n,children:l})};F.displayName=G;var R="Tooltip",[le,j]=_(R),$=e=>{const{__scopeTooltip:o,children:t,open:r,defaultOpen:n,onOpenChange:l,disableHoverableContent:i,delayDuration:v}=e,a=L(R,e.__scopeTooltip),p=O(o),[c,f]=s.useState(null),x=Y(),d=s.useRef(0),h=i??a.disableHoverableContent,T=v??a.delayDuration,g=s.useRef(!1),[b,m]=X({prop:r,defaultProp:n??!1,onChange:I=>{I?(a.onOpen(),document.dispatchEvent(new CustomEvent(k))):a.onClose(),l?.(I)},caller:R}),w=s.useMemo(()=>b?g.current?"delayed-open":"instant-open":"closed",[b]),P=s.useCallback(()=>{window.clearTimeout(d.current),d.current=0,g.current=!1,m(!0)},[m]),E=s.useCallback(()=>{window.clearTimeout(d.current),d.current=0,m(!1)},[m]),M=s.useCallback(()=>{window.clearTimeout(d.current),d.current=window.setTimeout(()=>{g.current=!0,m(!0),d.current=0},T)},[T,m]);return s.useEffect(()=>()=>{d.current&&(window.clearTimeout(d.current),d.current=0)},[]),u.jsx(K,{...p,children:u.jsx(le,{scope:o,contentId:x,open:b,stateAttribute:w,trigger:c,onTriggerChange:f,onTriggerEnter:s.useCallback(()=>{a.isOpenDelayedRef.current?M():P()},[a.isOpenDelayedRef,M,P]),onTriggerLeave:s.useCallback(()=>{h?E():(window.clearTimeout(d.current),d.current=0)},[E,h]),onOpen:P,onClose:E,disableHoverableContent:h,children:t})})};$.displayName=R;var D="TooltipTrigger",B=s.forwardRef((e,o)=>{const{__scopeTooltip:t,...r}=e,n=j(D,t),l=L(D,t),i=O(t),v=s.useRef(null),a=N(o,v,n.onTriggerChange),p=s.useRef(!1),c=s.useRef(!1),f=s.useCallback(()=>p.current=!1,[]);return s.useEffect(()=>()=>document.removeEventListener("pointerup",f),[f]),u.jsx(W,{asChild:!0,...i,children:u.jsx(J.button,{"aria-describedby":n.open?n.contentId:void 0,"data-state":n.stateAttribute,...r,ref:a,onPointerMove:y(e.onPointerMove,x=>{x.pointerType!=="touch"&&!c.current&&!l.isPointerInTransitRef.current&&(n.onTriggerEnter(),c.current=!0)}),onPointerLeave:y(e.onPointerLeave,()=>{n.onTriggerLeave(),c.current=!1}),onPointerDown:y(e.onPointerDown,()=>{n.open&&n.onClose(),p.current=!0,document.addEventListener("pointerup",f,{once:!0})}),onFocus:y(e.onFocus,()=>{p.current||n.onOpen()}),onBlur:y(e.onBlur,n.onClose),onClick:y(e.onClick,n.onClose)})})});B.displayName=D;var A="TooltipPortal",[ce,ue]=_(A,{forceMount:void 0}),q=e=>{const{__scopeTooltip:o,forceMount:t,children:r,container:n}=e,l=j(A,o);return u.jsx(ce,{scope:o,forceMount:t,children:u.jsx(H,{present:t||l.open,children:u.jsx(Q,{asChild:!0,container:n,children:r})})})};q.displayName=A;var C="TooltipContent",z=s.forwardRef((e,o)=>{const t=ue(C,e.__scopeTooltip),{forceMount:r=t.forceMount,side:n="top",...l}=e,i=j(C,e.__scopeTooltip);return u.jsx(H,{present:r||i.open,children:i.disableHoverableContent?u.jsx(U,{side:n,...l,ref:o}):u.jsx(de,{side:n,...l,ref:o})})}),de=s.forwardRef((e,o)=>{const t=j(C,e.__scopeTooltip),r=L(C,e.__scopeTooltip),n=s.useRef(null),l=N(o,n),[i,v]=s.useState(null),{trigger:a,onClose:p}=t,c=n.current,{onPointerInTransitChange:f}=r,x=s.useCallback(()=>{v(null),f(!1)},[f]),d=s.useCallback((h,T)=>{const g=h.currentTarget,b={x:h.clientX,y:h.clientY},m=he(b,g.getBoundingClientRect()),w=ge(b,m),P=Te(T.getBoundingClientRect()),E=be([...w,...P]);v(E),f(!0)},[f]);return s.useEffect(()=>()=>x(),[x]),s.useEffect(()=>{if(a&&c){const h=g=>d(g,c),T=g=>d(g,a);return a.addEventListener("pointerleave",h),c.addEventListener("pointerleave",T),()=>{a.removeEventListener("pointerleave",h),c.removeEventListener("pointerleave",T)}}},[a,c,d,x]),s.useEffect(()=>{if(i){const h=T=>{const g=T.target,b={x:T.clientX,y:T.clientY},m=a?.contains(g)||c?.contains(g),w=!me(b,i);m?x():w&&(x(),p())};return document.addEventListener("pointermove",h),()=>document.removeEventListener("pointermove",h)}},[a,c,i,p,x]),u.jsx(U,{...e,ref:l})}),[pe,fe]=_(R,{isInside:!1}),ve=oe("TooltipContent"),U=s.forwardRef((e,o)=>{const{__scopeTooltip:t,children:r,"aria-label":n,onEscapeKeyDown:l,onPointerDownOutside:i,...v}=e,a=j(C,t),p=O(t),{onClose:c}=a;return s.useEffect(()=>(document.addEventListener(k,c),()=>document.removeEventListener(k,c)),[c]),s.useEffect(()=>{if(a.trigger){const f=x=>{x.target?.contains(a.trigger)&&c()};return window.addEventListener("scroll",f,{capture:!0}),()=>window.removeEventListener("scroll",f,{capture:!0})}},[a.trigger,c]),u.jsx(Z,{asChild:!0,disableOutsidePointerEvents:!1,onEscapeKeyDown:l,onPointerDownOutside:i,onFocusOutside:f=>f.preventDefault(),onDismiss:c,children:u.jsxs(ee,{"data-state":a.stateAttribute,...p,...v,ref:o,style:{...v.style,"--radix-tooltip-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-tooltip-content-available-width":"var(--radix-popper-available-width)","--radix-tooltip-content-available-height":"var(--radix-popper-available-height)","--radix-tooltip-trigger-width":"var(--radix-popper-anchor-width)","--radix-tooltip-trigger-height":"var(--radix-popper-anchor-height)"},children:[u.jsx(ve,{children:r}),u.jsx(pe,{scope:t,isInside:!0,children:u.jsx(se,{id:a.contentId,role:"tooltip",children:n||r})})]})})});z.displayName=C;var V="TooltipArrow",xe=s.forwardRef((e,o)=>{const{__scopeTooltip:t,...r}=e,n=O(t);return fe(V,t).isInside?null:u.jsx(re,{...n,...r,ref:o})});xe.displayName=V;function he(e,o){const t=Math.abs(o.top-e.y),r=Math.abs(o.bottom-e.y),n=Math.abs(o.right-e.x),l=Math.abs(o.left-e.x);switch(Math.min(t,r,n,l)){case l:return"left";case n:return"right";case t:return"top";case r:return"bottom";default:throw new Error("unreachable")}}function ge(e,o,t=5){const r=[];switch(o){case"top":r.push({x:e.x-t,y:e.y+t},{x:e.x+t,y:e.y+t});break;case"bottom":r.push({x:e.x-t,y:e.y-t},{x:e.x+t,y:e.y-t});break;case"left":r.push({x:e.x+t,y:e.y-t},{x:e.x+t,y:e.y+t});break;case"right":r.push({x:e.x-t,y:e.y-t},{x:e.x-t,y:e.y+t});break}return r}function Te(e){const{top:o,right:t,bottom:r,left:n}=e;return[{x:n,y:o},{x:t,y:o},{x:t,y:r},{x:n,y:r}]}function me(e,o){const{x:t,y:r}=e;let n=!1;for(let l=0,i=o.length-1;l<o.length;i=l++){const v=o[l],a=o[i],p=v.x,c=v.y,f=a.x,x=a.y;c>r!=x>r&&t<(f-p)*(r-c)/(x-c)+p&&(n=!n)}return n}function be(e){const o=e.slice();return o.sort((t,r)=>t.x<r.x?-1:t.x>r.x?1:t.y<r.y?-1:t.y>r.y?1:0),ye(o)}function ye(e){if(e.length<=1)return e.slice();const o=[];for(let r=0;r<e.length;r++){const n=e[r];for(;o.length>=2;){const l=o[o.length-1],i=o[o.length-2];if((l.x-i.x)*(n.y-i.y)>=(l.y-i.y)*(n.x-i.x))o.pop();else break}o.push(n)}o.pop();const t=[];for(let r=e.length-1;r>=0;r--){const n=e[r];for(;t.length>=2;){const l=t[t.length-1],i=t[t.length-2];if((l.x-i.x)*(n.y-i.y)>=(l.y-i.y)*(n.x-i.x))t.pop();else break}t.push(n)}return t.pop(),o.length===1&&t.length===1&&o[0].x===t[0].x&&o[0].y===t[0].y?o:o.concat(t)}var Ce=F,we=$,Pe=B,Ee=q,Re=z;function je({delayDuration:e=200,...o}){return u.jsx(Ce,{"data-slot":"tooltip-provider",delayDuration:e,...o})}function ke({...e}){return u.jsx(je,{children:u.jsx(we,{"data-slot":"tooltip",...e})})}function De({...e}){return u.jsx(Pe,{"data-slot":"tooltip-trigger",...e})}function Le({className:e,sideOffset:o=6,children:t,...r}){return u.jsx(Ee,{children:u.jsx(Re,{"data-slot":"tooltip-content",sideOffset:o,className:ne("z-50 w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin)","rounded-2xl px-4 py-3 text-sm","bg-(--card)/80 backdrop-blur-xl backdrop-saturate-150","border border-white/10 shadow-lg shadow-black/10","text-(--foreground)","animate-in fade-in-0 zoom-in-95","data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95","data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2","data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",e),...r,children:t})})}export{ke as T,De as a,Le as b,je as c};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as a}from"./index
|
|
1
|
+
import{c as a}from"./index-lJlNPFVJ.js";const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],o=a("trash-2",t);export{o as T};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as e}from"./index
|
|
1
|
+
import{c as e}from"./index-lJlNPFVJ.js";const o=[["path",{d:"M16 7h6v6",key:"box55l"}],["path",{d:"m22 7-8.5 8.5-5-5L2 17",key:"1t1m79"}]],n=e("trending-up",o);export{n as T};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as a}from"./index
|
|
1
|
+
import{c as a}from"./index-lJlNPFVJ.js";const e=[["path",{d:"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72",key:"ul74o6"}],["path",{d:"m14 7 3 3",key:"1r5n42"}],["path",{d:"M5 6v4",key:"ilb8ba"}],["path",{d:"M19 14v4",key:"blhpug"}],["path",{d:"M10 2v2",key:"7u0qdc"}],["path",{d:"M7 8H3",key:"zfb6yr"}],["path",{d:"M21 16h-4",key:"1cnmox"}],["path",{d:"M11 3H9",key:"1obp7u"}]],d=a("wand-sparkles",e);export{d as W};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c}from"./index
|
|
1
|
+
import{c}from"./index-lJlNPFVJ.js";const a=[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z",key:"1ngwbx"}]],o=c("wrench",a);export{o as W};
|
package/ui/dist/index.html
CHANGED
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
24
24
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
25
25
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Manrope:wght@400;500;600;700&family=Plus+Jakarta+Sans:wght@500;600;700;800&display=swap" rel="stylesheet" />
|
|
26
|
-
<script type="module" crossorigin src="/assets/index
|
|
27
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
26
|
+
<script type="module" crossorigin src="/assets/index-lJlNPFVJ.js"></script>
|
|
27
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CuxnqVVz.css">
|
|
28
28
|
</head>
|
|
29
29
|
<body>
|
|
30
30
|
<div id="root"></div>
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auto-Reply System
|
|
3
|
-
*
|
|
4
|
-
* Template-based automatic responses for chat messages.
|
|
5
|
-
* Supports:
|
|
6
|
-
* - Out-of-office / away mode
|
|
7
|
-
* - Busy/DND mode with queue position
|
|
8
|
-
* - Keyword-triggered quick replies
|
|
9
|
-
* - Rate-limited to prevent spam
|
|
10
|
-
* - Per-channel configuration
|
|
11
|
-
*/
|
|
12
|
-
export interface AutoReplyTemplate {
|
|
13
|
-
id: string;
|
|
14
|
-
name: string;
|
|
15
|
-
trigger: AutoReplyTrigger;
|
|
16
|
-
message: string;
|
|
17
|
-
enabled: boolean;
|
|
18
|
-
channels?: string[];
|
|
19
|
-
cooldownMs: number;
|
|
20
|
-
maxPerHour?: number;
|
|
21
|
-
priority: number;
|
|
22
|
-
variables?: Record<string, string>;
|
|
23
|
-
}
|
|
24
|
-
export type AutoReplyTrigger = {
|
|
25
|
-
type: 'always';
|
|
26
|
-
} | {
|
|
27
|
-
type: 'keyword';
|
|
28
|
-
keywords: string[];
|
|
29
|
-
} | {
|
|
30
|
-
type: 'regex';
|
|
31
|
-
pattern: string;
|
|
32
|
-
} | {
|
|
33
|
-
type: 'no_agent';
|
|
34
|
-
} | {
|
|
35
|
-
type: 'after_hours';
|
|
36
|
-
schedule: WeeklySchedule;
|
|
37
|
-
};
|
|
38
|
-
export interface WeeklySchedule {
|
|
39
|
-
timezone: string;
|
|
40
|
-
hours: {
|
|
41
|
-
start: number;
|
|
42
|
-
end: number;
|
|
43
|
-
};
|
|
44
|
-
days: number[];
|
|
45
|
-
}
|
|
46
|
-
export interface AutoReplyConfig {
|
|
47
|
-
enabled: boolean;
|
|
48
|
-
templates: AutoReplyTemplate[];
|
|
49
|
-
globalCooldownMs: number;
|
|
50
|
-
maxRepliesPerHour: number;
|
|
51
|
-
}
|
|
52
|
-
export interface AutoReplyResult {
|
|
53
|
-
shouldReply: boolean;
|
|
54
|
-
templateId?: string;
|
|
55
|
-
message?: string;
|
|
56
|
-
reason?: string;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Load auto-reply configuration
|
|
60
|
-
*/
|
|
61
|
-
export declare function configureAutoReply(newConfig: Partial<AutoReplyConfig>): void;
|
|
62
|
-
/**
|
|
63
|
-
* Get current auto-reply configuration
|
|
64
|
-
*/
|
|
65
|
-
export declare function getAutoReplyConfig(): AutoReplyConfig;
|
|
66
|
-
/**
|
|
67
|
-
* Check if a message should trigger an auto-reply
|
|
68
|
-
*/
|
|
69
|
-
export declare function checkAutoReply(message: string, userId: string, channelId?: string): AutoReplyResult;
|
|
70
|
-
/**
|
|
71
|
-
* Add or replace a template by ID
|
|
72
|
-
*/
|
|
73
|
-
export declare function addTemplate(template: AutoReplyTemplate): void;
|
|
74
|
-
/**
|
|
75
|
-
* Remove a template by ID
|
|
76
|
-
*/
|
|
77
|
-
export declare function removeTemplate(id: string): boolean;
|
|
78
|
-
/**
|
|
79
|
-
* Get built-in template presets
|
|
80
|
-
*/
|
|
81
|
-
export declare function getTemplatePresets(): AutoReplyTemplate[];
|
|
82
|
-
/**
|
|
83
|
-
* Cleanup stale tracking entries (call periodically)
|
|
84
|
-
*/
|
|
85
|
-
export declare function cleanupAutoReplyState(): void;
|
|
86
|
-
/**
|
|
87
|
-
* Reset all state (for testing)
|
|
88
|
-
*/
|
|
89
|
-
export declare function resetAutoReply(): void;
|
|
90
|
-
//# sourceMappingURL=auto-reply.d.ts.map
|
package/dist/chat/auto-reply.js
DELETED
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auto-Reply System
|
|
3
|
-
*
|
|
4
|
-
* Template-based automatic responses for chat messages.
|
|
5
|
-
* Supports:
|
|
6
|
-
* - Out-of-office / away mode
|
|
7
|
-
* - Busy/DND mode with queue position
|
|
8
|
-
* - Keyword-triggered quick replies
|
|
9
|
-
* - Rate-limited to prevent spam
|
|
10
|
-
* - Per-channel configuration
|
|
11
|
-
*/
|
|
12
|
-
import { logger } from '../utils/logger.js';
|
|
13
|
-
// --- State ---
|
|
14
|
-
const DEFAULT_CONFIG = {
|
|
15
|
-
enabled: false,
|
|
16
|
-
templates: [],
|
|
17
|
-
globalCooldownMs: 30_000, // 30 seconds between replies to same user
|
|
18
|
-
maxRepliesPerHour: 10,
|
|
19
|
-
};
|
|
20
|
-
let config = { ...DEFAULT_CONFIG };
|
|
21
|
-
// Track last reply time per user to enforce cooldowns
|
|
22
|
-
const lastReplyMap = new Map();
|
|
23
|
-
// --- Core Functions ---
|
|
24
|
-
/**
|
|
25
|
-
* Load auto-reply configuration
|
|
26
|
-
*/
|
|
27
|
-
export function configureAutoReply(newConfig) {
|
|
28
|
-
config = { ...config, ...newConfig };
|
|
29
|
-
if (newConfig.templates) {
|
|
30
|
-
// Sort by priority descending
|
|
31
|
-
config.templates.sort((a, b) => b.priority - a.priority);
|
|
32
|
-
}
|
|
33
|
-
logger.info('[AutoReply] Configuration updated', {
|
|
34
|
-
enabled: config.enabled,
|
|
35
|
-
templates: config.templates.length,
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Get current auto-reply configuration
|
|
40
|
-
*/
|
|
41
|
-
export function getAutoReplyConfig() {
|
|
42
|
-
return { ...config };
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Check if a message should trigger an auto-reply
|
|
46
|
-
*/
|
|
47
|
-
export function checkAutoReply(message, userId, channelId) {
|
|
48
|
-
if (!config.enabled || config.templates.length === 0) {
|
|
49
|
-
return { shouldReply: false, reason: 'disabled' };
|
|
50
|
-
}
|
|
51
|
-
// Check global cooldown
|
|
52
|
-
const userState = lastReplyMap.get(userId);
|
|
53
|
-
const now = Date.now();
|
|
54
|
-
if (userState) {
|
|
55
|
-
// Reset hourly counter if hour has passed
|
|
56
|
-
if (now - userState.hourStart > 3_600_000) {
|
|
57
|
-
userState.count = 0;
|
|
58
|
-
userState.hourStart = now;
|
|
59
|
-
}
|
|
60
|
-
// Check cooldown
|
|
61
|
-
if (now - userState.time < config.globalCooldownMs) {
|
|
62
|
-
return { shouldReply: false, reason: 'cooldown' };
|
|
63
|
-
}
|
|
64
|
-
// Check rate limit
|
|
65
|
-
if (userState.count >= config.maxRepliesPerHour) {
|
|
66
|
-
return { shouldReply: false, reason: 'rate_limited' };
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
// Find matching template (sorted by priority)
|
|
70
|
-
for (const template of config.templates) {
|
|
71
|
-
if (!template.enabled)
|
|
72
|
-
continue;
|
|
73
|
-
// Check channel filter
|
|
74
|
-
if (template.channels && template.channels.length > 0 && channelId) {
|
|
75
|
-
if (!template.channels.includes(channelId))
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
// Check per-template cooldown
|
|
79
|
-
const templateKey = `${userId}:${template.id}`;
|
|
80
|
-
const templateState = lastReplyMap.get(templateKey);
|
|
81
|
-
if (templateState && now - templateState.time < template.cooldownMs) {
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
// Check trigger
|
|
85
|
-
if (matchesTrigger(template.trigger, message)) {
|
|
86
|
-
// Update global user state
|
|
87
|
-
const existing = lastReplyMap.get(userId);
|
|
88
|
-
const updatedState = existing
|
|
89
|
-
? { ...existing, time: now, count: existing.count + 1 }
|
|
90
|
-
: { time: now, count: 1, hourStart: now };
|
|
91
|
-
lastReplyMap.set(userId, updatedState);
|
|
92
|
-
// Update per-template state
|
|
93
|
-
lastReplyMap.set(templateKey, { time: now, count: 1, hourStart: now });
|
|
94
|
-
// Render message with variables
|
|
95
|
-
const rendered = renderTemplate(template.message, {
|
|
96
|
-
...template.variables,
|
|
97
|
-
user: userId,
|
|
98
|
-
channel: channelId ?? 'unknown',
|
|
99
|
-
time: new Date().toLocaleTimeString(),
|
|
100
|
-
date: new Date().toLocaleDateString(),
|
|
101
|
-
});
|
|
102
|
-
logger.debug('[AutoReply] Triggered', { templateId: template.id, userId, channelId });
|
|
103
|
-
return {
|
|
104
|
-
shouldReply: true,
|
|
105
|
-
templateId: template.id,
|
|
106
|
-
message: rendered,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return { shouldReply: false, reason: 'no_match' };
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Check if a trigger matches the message
|
|
114
|
-
*/
|
|
115
|
-
function matchesTrigger(trigger, message) {
|
|
116
|
-
switch (trigger.type) {
|
|
117
|
-
case 'always':
|
|
118
|
-
return true;
|
|
119
|
-
case 'keyword': {
|
|
120
|
-
const lower = message.toLowerCase();
|
|
121
|
-
return trigger.keywords.some(kw => lower.includes(kw.toLowerCase()));
|
|
122
|
-
}
|
|
123
|
-
case 'regex': {
|
|
124
|
-
try {
|
|
125
|
-
const re = new RegExp(trigger.pattern, 'i');
|
|
126
|
-
return re.test(message);
|
|
127
|
-
}
|
|
128
|
-
catch {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
case 'no_agent':
|
|
133
|
-
// This is checked externally - always matches when the trigger is selected
|
|
134
|
-
return true;
|
|
135
|
-
case 'after_hours':
|
|
136
|
-
return isAfterHours(trigger.schedule);
|
|
137
|
-
default:
|
|
138
|
-
return false;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Check if current time is outside business hours
|
|
143
|
-
*/
|
|
144
|
-
function isAfterHours(schedule) {
|
|
145
|
-
try {
|
|
146
|
-
const now = new Date();
|
|
147
|
-
// Use Intl to get time in the specified timezone
|
|
148
|
-
const formatter = new Intl.DateTimeFormat('en-US', {
|
|
149
|
-
timeZone: schedule.timezone,
|
|
150
|
-
hour: 'numeric',
|
|
151
|
-
minute: 'numeric',
|
|
152
|
-
hour12: false,
|
|
153
|
-
weekday: 'short',
|
|
154
|
-
});
|
|
155
|
-
const parts = formatter.formatToParts(now);
|
|
156
|
-
const hour = Number(parts.find(p => p.type === 'hour')?.value ?? 0);
|
|
157
|
-
const weekday = parts.find(p => p.type === 'weekday')?.value ?? '';
|
|
158
|
-
// Map weekday names to numbers
|
|
159
|
-
const dayMap = {
|
|
160
|
-
Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6,
|
|
161
|
-
};
|
|
162
|
-
const dayNum = dayMap[weekday] ?? -1;
|
|
163
|
-
// Check if today is a business day
|
|
164
|
-
if (!schedule.days.includes(dayNum))
|
|
165
|
-
return true;
|
|
166
|
-
// Check if current hour is outside business hours
|
|
167
|
-
return hour < schedule.hours.start || hour >= schedule.hours.end;
|
|
168
|
-
}
|
|
169
|
-
catch {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Render template variables: {{variable}} -> value
|
|
175
|
-
*/
|
|
176
|
-
function renderTemplate(template, vars) {
|
|
177
|
-
return template.replace(/\{\{(\w+)\}\}/g, (_match, key) => {
|
|
178
|
-
return vars[key] ?? `{{${key}}}`;
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Add or replace a template by ID
|
|
183
|
-
*/
|
|
184
|
-
export function addTemplate(template) {
|
|
185
|
-
// Remove existing with same ID
|
|
186
|
-
config.templates = config.templates.filter(t => t.id !== template.id);
|
|
187
|
-
config.templates.push(template);
|
|
188
|
-
config.templates.sort((a, b) => b.priority - a.priority);
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Remove a template by ID
|
|
192
|
-
*/
|
|
193
|
-
export function removeTemplate(id) {
|
|
194
|
-
const before = config.templates.length;
|
|
195
|
-
config.templates = config.templates.filter(t => t.id !== id);
|
|
196
|
-
return config.templates.length < before;
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Get built-in template presets
|
|
200
|
-
*/
|
|
201
|
-
export function getTemplatePresets() {
|
|
202
|
-
return [
|
|
203
|
-
{
|
|
204
|
-
id: 'away',
|
|
205
|
-
name: 'Away / Out of Office',
|
|
206
|
-
trigger: { type: 'always' },
|
|
207
|
-
message: "I'm currently away and will respond when I return. For urgent matters, please contact the team directly.",
|
|
208
|
-
enabled: false,
|
|
209
|
-
cooldownMs: 300_000, // 5 min
|
|
210
|
-
maxPerHour: 5,
|
|
211
|
-
priority: 100,
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
id: 'after-hours',
|
|
215
|
-
name: 'After Hours',
|
|
216
|
-
trigger: {
|
|
217
|
-
type: 'after_hours',
|
|
218
|
-
schedule: {
|
|
219
|
-
timezone: 'America/New_York',
|
|
220
|
-
hours: { start: 9, end: 17 },
|
|
221
|
-
days: [1, 2, 3, 4, 5], // Mon-Fri
|
|
222
|
-
},
|
|
223
|
-
},
|
|
224
|
-
message: "Thanks for your message! I'm currently outside business hours (Mon-Fri 9AM-5PM ET). I'll respond during the next business day.",
|
|
225
|
-
enabled: false,
|
|
226
|
-
cooldownMs: 600_000, // 10 min
|
|
227
|
-
maxPerHour: 3,
|
|
228
|
-
priority: 90,
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
id: 'help',
|
|
232
|
-
name: 'Help / FAQ',
|
|
233
|
-
trigger: { type: 'keyword', keywords: ['help', 'faq', 'how to', 'getting started'] },
|
|
234
|
-
message: "Need help? Here are some commands:\n- `/help` - Show all commands\n- `/status` - System status\n- `/skills` - Available skills\n\nOr just ask me anything!",
|
|
235
|
-
enabled: false,
|
|
236
|
-
cooldownMs: 60_000,
|
|
237
|
-
maxPerHour: 10,
|
|
238
|
-
priority: 50,
|
|
239
|
-
},
|
|
240
|
-
{
|
|
241
|
-
id: 'no-agent',
|
|
242
|
-
name: 'No Agent Available',
|
|
243
|
-
trigger: { type: 'no_agent' },
|
|
244
|
-
message: "All agents are currently busy. Your message has been queued and will be processed shortly. Current wait time: approximately {{waitTime}}.",
|
|
245
|
-
enabled: false,
|
|
246
|
-
cooldownMs: 120_000,
|
|
247
|
-
maxPerHour: 5,
|
|
248
|
-
priority: 80,
|
|
249
|
-
variables: { waitTime: '1-2 minutes' },
|
|
250
|
-
},
|
|
251
|
-
];
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Cleanup stale tracking entries (call periodically)
|
|
255
|
-
*/
|
|
256
|
-
export function cleanupAutoReplyState() {
|
|
257
|
-
const now = Date.now();
|
|
258
|
-
const staleThreshold = 3_600_000; // 1 hour
|
|
259
|
-
for (const [key, state] of lastReplyMap) {
|
|
260
|
-
if (now - state.time > staleThreshold) {
|
|
261
|
-
lastReplyMap.delete(key);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Reset all state (for testing)
|
|
267
|
-
*/
|
|
268
|
-
export function resetAutoReply() {
|
|
269
|
-
config = { ...DEFAULT_CONFIG };
|
|
270
|
-
lastReplyMap.clear();
|
|
271
|
-
}
|
|
272
|
-
//# sourceMappingURL=auto-reply.js.map
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PTY (Pseudo-Terminal) Support
|
|
3
|
-
*
|
|
4
|
-
* Provides interactive terminal support for commands that require TTY.
|
|
5
|
-
* Uses node-pty for cross-platform PTY handling.
|
|
6
|
-
*
|
|
7
|
-
* Use cases:
|
|
8
|
-
* - Interactive installers (npm init, create-react-app)
|
|
9
|
-
* - Text editors (vim, nano)
|
|
10
|
-
* - Pagers (less, more)
|
|
11
|
-
* - Password prompts
|
|
12
|
-
* - SSH sessions
|
|
13
|
-
*/
|
|
14
|
-
import { EventEmitter } from 'events';
|
|
15
|
-
export interface PTYSession {
|
|
16
|
-
id: string;
|
|
17
|
-
pid: number;
|
|
18
|
-
command: string;
|
|
19
|
-
cols: number;
|
|
20
|
-
rows: number;
|
|
21
|
-
status: 'running' | 'exited';
|
|
22
|
-
exitCode?: number;
|
|
23
|
-
output: string;
|
|
24
|
-
createdAt: Date;
|
|
25
|
-
exitedAt?: Date;
|
|
26
|
-
}
|
|
27
|
-
export interface PTYOptions {
|
|
28
|
-
cols?: number;
|
|
29
|
-
rows?: number;
|
|
30
|
-
cwd?: string;
|
|
31
|
-
env?: Record<string, string>;
|
|
32
|
-
timeout?: number;
|
|
33
|
-
maxOutputChars?: number;
|
|
34
|
-
}
|
|
35
|
-
export interface PTYResult {
|
|
36
|
-
success: boolean;
|
|
37
|
-
exitCode: number;
|
|
38
|
-
output: string;
|
|
39
|
-
durationMs: number;
|
|
40
|
-
truncated: boolean;
|
|
41
|
-
secretsRedacted: boolean;
|
|
42
|
-
}
|
|
43
|
-
export declare class PTYManager extends EventEmitter {
|
|
44
|
-
private sessions;
|
|
45
|
-
private sessionCounter;
|
|
46
|
-
/**
|
|
47
|
-
* Spawn a new PTY session
|
|
48
|
-
*/
|
|
49
|
-
spawn(command: string, args?: string[], options?: PTYOptions): PTYSession;
|
|
50
|
-
/**
|
|
51
|
-
* Execute a command and wait for completion
|
|
52
|
-
*/
|
|
53
|
-
execute(command: string, args?: string[], options?: PTYOptions): Promise<PTYResult>;
|
|
54
|
-
/**
|
|
55
|
-
* Write input to PTY
|
|
56
|
-
*/
|
|
57
|
-
write(sessionId: string, data: string): boolean;
|
|
58
|
-
/**
|
|
59
|
-
* Resize PTY dimensions
|
|
60
|
-
*/
|
|
61
|
-
resize(sessionId: string, cols: number, rows: number): boolean;
|
|
62
|
-
/**
|
|
63
|
-
* Kill a PTY session
|
|
64
|
-
*/
|
|
65
|
-
kill(sessionId: string, signal?: string): boolean;
|
|
66
|
-
/**
|
|
67
|
-
* Get session info
|
|
68
|
-
*/
|
|
69
|
-
getSession(sessionId: string): PTYSession | null;
|
|
70
|
-
/**
|
|
71
|
-
* Get all active sessions
|
|
72
|
-
*/
|
|
73
|
-
getActiveSessions(): PTYSession[];
|
|
74
|
-
/**
|
|
75
|
-
* Subscribe to session output
|
|
76
|
-
*/
|
|
77
|
-
subscribe(sessionId: string, listener: (data: string) => void): () => void;
|
|
78
|
-
/**
|
|
79
|
-
* Clean up completed session
|
|
80
|
-
*/
|
|
81
|
-
cleanup(sessionId: string): void;
|
|
82
|
-
/**
|
|
83
|
-
* Clean up all sessions
|
|
84
|
-
*/
|
|
85
|
-
cleanupAll(): void;
|
|
86
|
-
}
|
|
87
|
-
export declare function getPTYManager(): PTYManager;
|
|
88
|
-
/**
|
|
89
|
-
* Check if a command likely requires PTY
|
|
90
|
-
*/
|
|
91
|
-
export declare function commandNeedsPTY(command: string): boolean;
|
|
92
|
-
//# sourceMappingURL=pty.d.ts.map
|