@zhin.js/adapter-icqq 2.0.24 → 2.0.26

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 CHANGED
@@ -1,5 +1,26 @@
1
1
  # @zhin.js/adapter-icqq
2
2
 
3
+ ## 2.0.26
4
+
5
+ ### Patch Changes
6
+
7
+ - 8086ccb: fix: ai 增强/优化
8
+ - Updated dependencies [8086ccb]
9
+ - @zhin.js/core@1.1.23
10
+ - zhin.js@1.0.81
11
+ - @zhin.js/console@2.0.24
12
+ - @zhin.js/http@1.0.74
13
+
14
+ ## 2.0.25
15
+
16
+ ### Patch Changes
17
+
18
+ - 3b3e49b: fix: ask 工具修复,icqq skill 优化
19
+ - zhin.js@1.0.80
20
+ - @zhin.js/console@2.0.23
21
+ - @zhin.js/http@1.0.73
22
+ - @zhin.js/core@1.1.22
23
+
3
24
  ## 2.0.24
4
25
 
5
26
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{useCallback as Fe,useEffect as De,useState as N}from"react";import{forwardRef as re,createElement as fe}from"react";var E=(...a)=>a.filter((u,r,f)=>!!u&&u.trim()!==""&&f.indexOf(u)===r).join(" ").trim();var Q=a=>a.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();var J=a=>a.replace(/^([A-Z])|[\s-_]+(\w)/g,(u,r,f)=>f?f.toUpperCase():r.toLowerCase());var X=a=>{let u=J(a);return u.charAt(0).toUpperCase()+u.slice(1)};import{forwardRef as le,createElement as Y}from"react";var V={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};var _=a=>{for(let u in a)if(u.startsWith("aria-")||u==="role"||u==="title")return!0;return!1};import{createContext as oe,useContext as ue,useMemo as Ge,createElement as We}from"react";var de=oe({});var j=()=>ue(de);var $=le(({color:a,size:u,strokeWidth:r,absoluteStrokeWidth:f,className:n="",children:c,iconNode:C,...h},m)=>{let{size:d=24,strokeWidth:p=2,absoluteStrokeWidth:G=!1,color:g="currentColor",className:M=""}=j()??{},B=f??G?Number(r??p)*24/Number(u??d):r??p;return Y("svg",{ref:m,...V,width:u??d??V.width,height:u??d??V.height,stroke:a??g,strokeWidth:B,className:E("lucide",M,n),...!c&&!_(h)&&{"aria-hidden":"true"},...h},[...C.map(([z,e])=>Y(z,e)),...Array.isArray(c)?c:[c]])});var t=(a,u)=>{let r=re(({className:f,...n},c)=>fe($,{ref:c,iconNode:u,className:E(`lucide-${Q(X(a))}`,`lucide-${a}`,f),...n}));return r.displayName=X(a),r};var se=[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",key:"169zse"}]],F=t("activity",se);var ie=[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]],P=t("bot",ie);var ce=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]],k=t("circle-alert",ce);var ne=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],I=t("loader-circle",ne);var pe=[["path",{d:"m10 17 5-5-5-5",key:"1bsop3"}],["path",{d:"M15 12H3",key:"6jk70r"}],["path",{d:"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4",key:"u53s6r"}]],w=t("log-in",pe);var me=[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",key:"18887p"}]],D=t("message-square",me);var Le=[["path",{d:"M12.586 12.586 19 19",key:"ea5xo7"}],["path",{d:"M3.688 3.037a.497.497 0 0 0-.651.651l6.5 15.999a.501.501 0 0 0 .947-.062l1.569-6.083a2 2 0 0 1 1.448-1.479l6.124-1.579a.5.5 0 0 0 .063-.947z",key:"277e5u"}]],y=t("mouse-pointer",Le);var Ie=[["rect",{width:"5",height:"5",x:"3",y:"3",rx:"1",key:"1tu5fj"}],["rect",{width:"5",height:"5",x:"16",y:"3",rx:"1",key:"1v8r4q"}],["rect",{width:"5",height:"5",x:"3",y:"16",rx:"1",key:"1x03jg"}],["path",{d:"M21 16h-3a2 2 0 0 0-2 2v3",key:"177gqh"}],["path",{d:"M21 21v.01",key:"ents32"}],["path",{d:"M12 7v3a2 2 0 0 1-2 2H7",key:"8crl2c"}],["path",{d:"M3 12h.01",key:"nlz23k"}],["path",{d:"M12 3h.01",key:"n36tog"}],["path",{d:"M12 16v.01",key:"133mhm"}],["path",{d:"M16 12h1",key:"1slzba"}],["path",{d:"M21 12v.01",key:"1lwtk9"}],["path",{d:"M12 21v-1",key:"1880an"}]],R=t("qr-code",Ie);var xe=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],T=t("refresh-cw",xe);var Ce=[["rect",{width:"14",height:"20",x:"5",y:"2",rx:"2",ry:"2",key:"1yt0o3"}],["path",{d:"M12 18h.01",key:"mhygvu"}]],q=t("smartphone",Ce);var he=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744",key:"16gr8j"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}]],b=t("users",he);var ge=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}],["path",{d:"M5 12.859a10 10 0 0 1 5.17-2.69",key:"1dl1wf"}],["path",{d:"M19 12.859a10 10 0 0 0-2.007-1.523",key:"4k23kn"}],["path",{d:"M2 8.82a15 15 0 0 1 4.177-2.643",key:"1grhjp"}],["path",{d:"M22 8.82a15 15 0 0 0-11.288-3.764",key:"z3jwby"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],v=t("wifi-off",ge);var Se=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]],U=t("wifi",Se);var ke=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],O=t("x",ke);import{useCallback as ae,useEffect as Pe,useRef as te,useState as H}from"react";var ee="zhin_api_token";function we(){return localStorage.getItem(ee)}async function A(a,u){let r=we(),f=new Headers(u?.headers);r&&f.set("Authorization",`Bearer ${r}`);let n=await fetch(a,{...u,headers:f});return n.status===401&&(localStorage.removeItem(ee),window.dispatchEvent(new CustomEvent("zhin:auth-required"))),n}import{jsx as o,jsxs as x}from"react/jsx-runtime";var Ae=2e3,Me=15e3,Be={qrcode:{icon:o(R,{className:"w-4 h-4"}),label:"\u626B\u7801\u767B\u5F55"},sms:{icon:o(D,{className:"w-4 h-4"}),label:"\u77ED\u4FE1\u9A8C\u8BC1\u7801"},device:{icon:o(q,{className:"w-4 h-4"}),label:"\u8BBE\u5907\u9A8C\u8BC1"},slider:{icon:o(y,{className:"w-4 h-4"}),label:"\u6ED1\u5757\u9A8C\u8BC1"}};function K(){let[a,u]=H([]),[r,f]=H(!0),[n,c]=H(null),[C,h]=H({}),[m,d]=H({}),p=te(0),G=te(),g=ae(async()=>{try{let e=await A("/api/login-assist/pending");if(!e.ok)throw new Error("\u83B7\u53D6\u5F85\u529E\u5931\u8D25");let S=await e.json(),L=(Array.isArray(S)?S:[]).filter(W=>W.adapter==="icqq");u(L),c(null),p.current=L.length>0?0:p.current+1}catch(e){c(e.message),p.current++}finally{f(!1)}},[]),M=ae(()=>{let e=Math.min(Ae*Math.pow(1.5,p.current),Me);G.current=setTimeout(async()=>{await g(),M()},e)},[g]);Pe(()=>(g().then(M),()=>clearTimeout(G.current)),[g,M]);let B=async(e,S)=>{h(i=>({...i,[e]:!0}));try{if(!(await A("/api/login-assist/submit",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:e,value:S})})).ok)throw new Error("\u63D0\u4EA4\u5931\u8D25");d(L=>{let W={...L};return delete W[e],W}),p.current=0,await g()}catch(i){c(i.message)}finally{h(i=>({...i,[e]:!1}))}},z=async e=>{try{(await A("/api/login-assist/cancel",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:e})})).ok&&await g()}catch{}};return r&&a.length===0?o("div",{className:"flex justify-center py-12",children:o(I,{className:"w-6 h-6 animate-spin text-blue-500"})}):x("div",{className:"space-y-4",children:[o("p",{className:"text-sm text-muted-foreground",children:"\u626B\u7801\u3001\u77ED\u4FE1\u6216\u6ED1\u5757\u7B49\u9A8C\u8BC1\u4F1A\u51FA\u73B0\u5728\u4E0B\u65B9\uFF1B\u5237\u65B0\u9875\u9762\u540E\u4ECD\u53EF\u7EE7\u7EED\u5904\u7406\uFF08\u4EC5 ICQQ \u5F85\u529E\uFF09\u3002"}),n&&x("div",{className:"flex items-center gap-2 p-3 rounded border border-red-200 bg-red-50 text-red-600 text-sm dark:bg-red-900/20 dark:text-red-400 dark:border-red-800",children:[o(k,{className:"w-4 h-4 shrink-0"}),o("span",{children:n}),o("button",{onClick:()=>c(null),className:"ml-auto",children:o(O,{className:"w-3.5 h-3.5"})})]}),a.length===0?x("div",{className:"border rounded-lg bg-card p-12 text-center",children:[o(w,{className:"w-16 h-16 mx-auto mb-4 opacity-25"}),o("h3",{className:"text-lg font-semibold mb-1",children:"\u6682\u65E0\u5F85\u529E"}),o("p",{className:"text-sm text-muted-foreground",children:"\u673A\u5668\u4EBA\u9700\u8981\u9A8C\u8BC1\u65F6\uFF0C\u5F85\u529E\u5C06\u663E\u793A\u5728\u6B64\u5904"})]}):o("div",{className:"space-y-4",children:a.map(e=>{let S=Be[e.type]??{icon:o(w,{className:"w-4 h-4"}),label:e.type};return x("div",{className:"border rounded-lg bg-card p-4 shadow-sm",children:[x("div",{className:"flex items-start justify-between flex-wrap gap-2 mb-2",children:[x("div",{className:"flex items-center gap-2 font-semibold",children:[S.icon," ",S.label]}),x("div",{className:"flex gap-1 text-xs",children:[o("span",{className:"px-2 py-0.5 rounded border",children:e.adapter}),o("span",{className:"px-2 py-0.5 rounded bg-muted",children:e.botId})]})]}),e.payload?.message&&o("p",{className:"text-sm text-muted-foreground mb-3",children:e.payload.message}),e.type==="qrcode"&&e.payload?.image&&o("div",{className:"flex justify-center p-4 bg-muted/30 rounded-lg mb-3",children:o("img",{src:String(e.payload.image),alt:"\u767B\u5F55\u4E8C\u7EF4\u7801",className:"max-w-[200px] w-full h-auto"})}),e.type==="slider"&&e.payload?.url&&x("p",{className:"text-sm break-all mb-3",children:[o("span",{className:"text-muted-foreground",children:"\u6ED1\u5757\u94FE\u63A5\uFF1A"})," ",o("a",{href:String(e.payload.url),target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:String(e.payload.url)})]}),(e.type==="sms"||e.type==="device"||e.type==="slider")&&x("div",{className:"flex flex-wrap gap-2 items-center",children:[o("input",{className:"h-9 px-3 rounded-md border border-input bg-background text-sm max-w-[18rem] flex-1",placeholder:e.type==="slider"?"\u8F93\u5165 ticket":"\u8F93\u5165\u9A8C\u8BC1\u7801",value:m[e.id]??"",onChange:i=>d(L=>({...L,[e.id]:i.target.value})),onKeyDown:i=>{if(i.key==="Enter"){let L=m[e.id]?.trim();L&&B(e.id,e.type==="slider"?{ticket:L}:L)}}}),o("button",{className:"h-9 px-4 rounded-md bg-primary text-primary-foreground text-sm disabled:opacity-50",disabled:C[e.id]||!m[e.id]?.trim(),onClick:()=>{let i=m[e.id]?.trim();i&&B(e.id,e.type==="slider"?{ticket:i}:i)},children:C[e.id]?"\u63D0\u4EA4\u4E2D\u2026":"\u63D0\u4EA4"})]}),e.type==="qrcode"&&x("div",{className:"flex gap-2 mt-3",children:[o("button",{className:"h-9 px-4 rounded-md bg-primary text-primary-foreground text-sm disabled:opacity-50",disabled:!!C[e.id],onClick:()=>{B(e.id,{done:!0})},children:C[e.id]?"\u63D0\u4EA4\u4E2D\u2026":"\u6211\u5DF2\u626B\u7801"}),o("button",{className:"h-9 px-4 rounded-md border text-sm hover:bg-accent transition-colors",onClick:()=>{z(e.id)},children:"\u53D6\u6D88"})]})]},e.id)})})]})}import{Fragment as ye,jsx as l,jsxs as s}from"react/jsx-runtime";function Z(){let[a,u]=N("overview"),[r,f]=N([]),[n,c]=N(!0),[C,h]=N(null),m=Fe(async()=>{c(!0),h(null);try{let d=await A("/api/icqq/bots"),p=await d.json();if(!d.ok||!p.success)throw new Error(p.message||"\u52A0\u8F7D\u5931\u8D25");f(Array.isArray(p.data)?p.data:[])}catch(d){h(d.message),f([])}finally{c(!1)}},[]);return De(()=>{a==="overview"&&m()},[a,m]),s("div",{className:"p-6 max-w-5xl mx-auto space-y-5",children:[s("div",{className:"flex items-center justify-between",children:[s("div",{children:[s("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[l(P,{className:"w-6 h-6"})," ICQQ \u7BA1\u7406"]}),l("p",{className:"text-sm text-muted-foreground mt-1",children:"\u673A\u5668\u4EBA\u6982\u89C8\u4E0E\u767B\u5F55\u8F85\u52A9\uFF08\u626B\u7801 / \u9A8C\u8BC1\u7801 / \u6ED1\u5757\uFF09"})]}),a==="overview"&&s("button",{onClick:m,disabled:n,className:"flex items-center gap-1 px-3 py-1.5 rounded bg-blue-500 text-white hover:bg-blue-600 disabled:opacity-50 text-sm",children:[l(T,{className:`w-4 h-4 ${n?"animate-spin":""}`})," \u5237\u65B0"]})]}),s("div",{className:"flex gap-1 border-b",children:[l("button",{onClick:()=>u("overview"),className:`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${a==="overview"?"border-blue-500 text-blue-600":"border-transparent text-gray-500 hover:text-gray-700"}`,children:s("span",{className:"flex items-center gap-1.5",children:[l(P,{className:"w-4 h-4"})," \u6982\u89C8"]})}),l("button",{onClick:()=>u("login"),className:`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${a==="login"?"border-blue-500 text-blue-600":"border-transparent text-gray-500 hover:text-gray-700"}`,children:s("span",{className:"flex items-center gap-1.5",children:[l(w,{className:"w-4 h-4"})," \u767B\u5F55\u8F85\u52A9"]})})]}),a==="overview"&&s(ye,{children:[C&&l("div",{className:"p-3 bg-red-50 text-red-600 rounded border border-red-200 text-sm dark:bg-red-900/20 dark:text-red-400 dark:border-red-800",children:C}),n?l("div",{className:"flex justify-center py-12",children:l(I,{className:"w-6 h-6 animate-spin text-blue-500"})}):r.length===0?l("div",{className:"text-center text-muted-foreground py-12",children:"\u6682\u65E0 ICQQ \u673A\u5668\u4EBA\u5B9E\u4F8B"}):l("div",{className:"grid gap-4 md:grid-cols-2",children:r.map(d=>s("div",{className:"border rounded-lg p-4 bg-card shadow-sm",children:[s("div",{className:"flex items-center justify-between mb-3",children:[l("span",{className:"font-medium text-lg",children:d.name}),d.connected?s("span",{className:"flex items-center gap-1 text-green-600 text-sm",children:[l(U,{className:"w-4 h-4"})," \u5728\u7EBF"]}):s("span",{className:"flex items-center gap-1 text-gray-400 text-sm",children:[l(v,{className:"w-4 h-4"})," \u79BB\u7EBF"]})]}),s("div",{className:"space-y-2 text-sm text-muted-foreground",children:[s("div",{className:"flex items-center gap-1.5",children:[l(b,{className:"w-3.5 h-3.5"}),"\u7FA4 ",d.groupCount," \xB7 \u597D\u53CB ",d.friendCount]}),s("div",{className:"flex items-center gap-1.5",children:[l(F,{className:"w-3.5 h-3.5"}),"\u767B\u5F55\u65B9\u5F0F ",d.loginMode," \xB7 ",d.status]})]})]},d.name))})]}),a==="login"&&l(K,{})]})}function tt(a){a.addRoute({path:"/console/icqq",name:"ICQQ\u7BA1\u7406",element:a.React.createElement(Z,{hostReact:a.React})}),a.addTool({id:"icqq",name:"ICQQ",path:"/console/icqq"})}export{tt as register};
1
+ import{useCallback as Fe,useEffect as De,useState as N}from"react";import{forwardRef as re,createElement as fe}from"react";var E=(...a)=>a.filter((u,r,f)=>!!u&&u.trim()!==""&&f.indexOf(u)===r).join(" ").trim();var Q=a=>a.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();var J=a=>a.replace(/^([A-Z])|[\s-_]+(\w)/g,(u,r,f)=>f?f.toUpperCase():r.toLowerCase());var X=a=>{let u=J(a);return u.charAt(0).toUpperCase()+u.slice(1)};import{forwardRef as le,createElement as Y}from"react";var V={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};var _=a=>{for(let u in a)if(u.startsWith("aria-")||u==="role"||u==="title")return!0;return!1};import{createContext as oe,useContext as ue,useMemo as Ge,createElement as We}from"react";var de=oe({});var j=()=>ue(de);var $=le(({color:a,size:u,strokeWidth:r,absoluteStrokeWidth:f,className:n="",children:c,iconNode:C,...h},m)=>{let{size:d=24,strokeWidth:p=2,absoluteStrokeWidth:G=!1,color:g="currentColor",className:B=""}=j()??{},M=f??G?Number(r??p)*24/Number(u??d):r??p;return Y("svg",{ref:m,...V,width:u??d??V.width,height:u??d??V.height,stroke:a??g,strokeWidth:M,className:E("lucide",B,n),...!c&&!_(h)&&{"aria-hidden":"true"},...h},[...C.map(([z,e])=>Y(z,e)),...Array.isArray(c)?c:[c]])});var t=(a,u)=>{let r=re(({className:f,...n},c)=>fe($,{ref:c,iconNode:u,className:E(`lucide-${Q(X(a))}`,`lucide-${a}`,f),...n}));return r.displayName=X(a),r};var se=[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",key:"169zse"}]],F=t("activity",se);var ie=[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]],P=t("bot",ie);var ce=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]],k=t("circle-alert",ce);var ne=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],I=t("loader-circle",ne);var pe=[["path",{d:"m10 17 5-5-5-5",key:"1bsop3"}],["path",{d:"M15 12H3",key:"6jk70r"}],["path",{d:"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4",key:"u53s6r"}]],w=t("log-in",pe);var me=[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",key:"18887p"}]],D=t("message-square",me);var Le=[["path",{d:"M12.586 12.586 19 19",key:"ea5xo7"}],["path",{d:"M3.688 3.037a.497.497 0 0 0-.651.651l6.5 15.999a.501.501 0 0 0 .947-.062l1.569-6.083a2 2 0 0 1 1.448-1.479l6.124-1.579a.5.5 0 0 0 .063-.947z",key:"277e5u"}]],y=t("mouse-pointer",Le);var Ie=[["rect",{width:"5",height:"5",x:"3",y:"3",rx:"1",key:"1tu5fj"}],["rect",{width:"5",height:"5",x:"16",y:"3",rx:"1",key:"1v8r4q"}],["rect",{width:"5",height:"5",x:"3",y:"16",rx:"1",key:"1x03jg"}],["path",{d:"M21 16h-3a2 2 0 0 0-2 2v3",key:"177gqh"}],["path",{d:"M21 21v.01",key:"ents32"}],["path",{d:"M12 7v3a2 2 0 0 1-2 2H7",key:"8crl2c"}],["path",{d:"M3 12h.01",key:"nlz23k"}],["path",{d:"M12 3h.01",key:"n36tog"}],["path",{d:"M12 16v.01",key:"133mhm"}],["path",{d:"M16 12h1",key:"1slzba"}],["path",{d:"M21 12v.01",key:"1lwtk9"}],["path",{d:"M12 21v-1",key:"1880an"}]],R=t("qr-code",Ie);var xe=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],T=t("refresh-cw",xe);var Ce=[["rect",{width:"14",height:"20",x:"5",y:"2",rx:"2",ry:"2",key:"1yt0o3"}],["path",{d:"M12 18h.01",key:"mhygvu"}]],q=t("smartphone",Ce);var he=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744",key:"16gr8j"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}]],b=t("users",he);var ge=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}],["path",{d:"M5 12.859a10 10 0 0 1 5.17-2.69",key:"1dl1wf"}],["path",{d:"M19 12.859a10 10 0 0 0-2.007-1.523",key:"4k23kn"}],["path",{d:"M2 8.82a15 15 0 0 1 4.177-2.643",key:"1grhjp"}],["path",{d:"M22 8.82a15 15 0 0 0-11.288-3.764",key:"z3jwby"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],v=t("wifi-off",ge);var Se=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]],U=t("wifi",Se);var ke=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],O=t("x",ke);import{useCallback as ae,useEffect as Pe,useRef as te,useState as H}from"react";var ee="zhin_api_token";function we(){return localStorage.getItem(ee)}async function A(a,u){let r=we(),f=new Headers(u?.headers);r&&f.set("Authorization",`Bearer ${r}`);let n=await fetch(a,{...u,headers:f});return n.status===401&&(localStorage.removeItem(ee),window.dispatchEvent(new CustomEvent("zhin:auth-required"))),n}import{jsx as o,jsxs as x}from"react/jsx-runtime";var Ae=2e3,Be=15e3,Me={qrcode:{icon:o(R,{className:"w-4 h-4"}),label:"\u626B\u7801\u767B\u5F55"},sms:{icon:o(D,{className:"w-4 h-4"}),label:"\u77ED\u4FE1\u9A8C\u8BC1\u7801"},device:{icon:o(q,{className:"w-4 h-4"}),label:"\u8BBE\u5907\u9A8C\u8BC1"},slider:{icon:o(y,{className:"w-4 h-4"}),label:"\u6ED1\u5757\u9A8C\u8BC1"}};function K(){let[a,u]=H([]),[r,f]=H(!0),[n,c]=H(null),[C,h]=H({}),[m,d]=H({}),p=te(0),G=te(),g=ae(async()=>{try{let e=await A("/api/login-assist/pending");if(!e.ok)throw new Error("\u83B7\u53D6\u5F85\u529E\u5931\u8D25");let S=await e.json(),L=(Array.isArray(S)?S:[]).filter(W=>W.adapter==="icqq");u(L),c(null),p.current=L.length>0?0:p.current+1}catch(e){c(e.message),p.current++}finally{f(!1)}},[]),B=ae(()=>{let e=Math.min(Ae*Math.pow(1.5,p.current),Be);G.current=setTimeout(async()=>{await g(),B()},e)},[g]);Pe(()=>(g().then(B),()=>clearTimeout(G.current)),[g,B]);let M=async(e,S)=>{h(i=>({...i,[e]:!0}));try{if(!(await A("/api/login-assist/submit",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:e,value:S})})).ok)throw new Error("\u63D0\u4EA4\u5931\u8D25");d(L=>{let W={...L};return delete W[e],W}),p.current=0,await g()}catch(i){c(i.message)}finally{h(i=>({...i,[e]:!1}))}},z=async e=>{try{(await A("/api/login-assist/cancel",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:e})})).ok&&await g()}catch{}};return r&&a.length===0?o("div",{className:"flex justify-center py-12",children:o(I,{className:"w-6 h-6 animate-spin text-blue-500"})}):x("div",{className:"space-y-4",children:[o("p",{className:"text-sm text-muted-foreground",children:"\u626B\u7801\u3001\u77ED\u4FE1\u6216\u6ED1\u5757\u7B49\u9A8C\u8BC1\u4F1A\u51FA\u73B0\u5728\u4E0B\u65B9\uFF1B\u5237\u65B0\u9875\u9762\u540E\u4ECD\u53EF\u7EE7\u7EED\u5904\u7406\uFF08\u4EC5 ICQQ \u5F85\u529E\uFF09\u3002"}),n&&x("div",{className:"flex items-center gap-2 p-3 rounded border border-red-200 bg-red-50 text-red-600 text-sm dark:bg-red-900/20 dark:text-red-400 dark:border-red-800",children:[o(k,{className:"w-4 h-4 shrink-0"}),o("span",{children:n}),o("button",{onClick:()=>c(null),className:"ml-auto",children:o(O,{className:"w-3.5 h-3.5"})})]}),a.length===0?x("div",{className:"border rounded-lg bg-card p-12 text-center",children:[o(w,{className:"w-16 h-16 mx-auto mb-4 opacity-25"}),o("h3",{className:"text-lg font-semibold mb-1",children:"\u6682\u65E0\u5F85\u529E"}),o("p",{className:"text-sm text-muted-foreground",children:"\u673A\u5668\u4EBA\u9700\u8981\u9A8C\u8BC1\u65F6\uFF0C\u5F85\u529E\u5C06\u663E\u793A\u5728\u6B64\u5904"})]}):o("div",{className:"space-y-4",children:a.map(e=>{let S=Me[e.type]??{icon:o(w,{className:"w-4 h-4"}),label:e.type};return x("div",{className:"border rounded-lg bg-card p-4 shadow-sm",children:[x("div",{className:"flex items-start justify-between flex-wrap gap-2 mb-2",children:[x("div",{className:"flex items-center gap-2 font-semibold",children:[S.icon," ",S.label]}),x("div",{className:"flex gap-1 text-xs",children:[o("span",{className:"px-2 py-0.5 rounded border",children:e.adapter}),o("span",{className:"px-2 py-0.5 rounded bg-muted",children:e.botId})]})]}),e.payload?.message&&o("p",{className:"text-sm text-muted-foreground mb-3",children:e.payload.message}),e.type==="qrcode"&&e.payload?.image&&o("div",{className:"flex justify-center p-4 bg-muted/30 rounded-lg mb-3",children:o("img",{src:String(e.payload.image),alt:"\u767B\u5F55\u4E8C\u7EF4\u7801",className:"max-w-[200px] w-full h-auto"})}),e.type==="slider"&&e.payload?.url&&x("p",{className:"text-sm break-all mb-3",children:[o("span",{className:"text-muted-foreground",children:"\u6ED1\u5757\u94FE\u63A5\uFF1A"})," ",o("a",{href:String(e.payload.url),target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:String(e.payload.url)})]}),(e.type==="sms"||e.type==="device"||e.type==="slider")&&x("div",{className:"flex flex-wrap gap-2 items-center",children:[o("input",{className:"h-9 px-3 rounded-md border border-input bg-background text-sm max-w-[18rem] flex-1",placeholder:e.type==="slider"?"\u8F93\u5165 ticket":"\u8F93\u5165\u9A8C\u8BC1\u7801",value:m[e.id]??"",onChange:i=>d(L=>({...L,[e.id]:i.target.value})),onKeyDown:i=>{if(i.key==="Enter"){let L=m[e.id]?.trim();L&&M(e.id,e.type==="slider"?{ticket:L}:L)}}}),o("button",{className:"h-9 px-4 rounded-md bg-primary text-primary-foreground text-sm disabled:opacity-50",disabled:C[e.id]||!m[e.id]?.trim(),onClick:()=>{let i=m[e.id]?.trim();i&&M(e.id,e.type==="slider"?{ticket:i}:i)},children:C[e.id]?"\u63D0\u4EA4\u4E2D\u2026":"\u63D0\u4EA4"})]}),e.type==="qrcode"&&x("div",{className:"flex gap-2 mt-3",children:[o("button",{className:"h-9 px-4 rounded-md bg-primary text-primary-foreground text-sm disabled:opacity-50",disabled:!!C[e.id],onClick:()=>{M(e.id,{done:!0})},children:C[e.id]?"\u63D0\u4EA4\u4E2D\u2026":"\u6211\u5DF2\u626B\u7801"}),o("button",{className:"h-9 px-4 rounded-md border text-sm hover:bg-accent transition-colors",onClick:()=>{z(e.id)},children:"\u53D6\u6D88"})]})]},e.id)})})]})}import{Fragment as ye,jsx as l,jsxs as s}from"react/jsx-runtime";function Z(){let[a,u]=N("overview"),[r,f]=N([]),[n,c]=N(!0),[C,h]=N(null),m=Fe(async()=>{c(!0),h(null);try{let d=await A("/api/icqq/bots"),p=await d.json();if(!d.ok||!p.success)throw new Error(p.message||"\u52A0\u8F7D\u5931\u8D25");f(Array.isArray(p.data)?p.data:[])}catch(d){h(d.message),f([])}finally{c(!1)}},[]);return De(()=>{a==="overview"&&m()},[a,m]),s("div",{className:"p-6 max-w-5xl mx-auto space-y-5",children:[s("div",{className:"flex items-center justify-between",children:[s("div",{children:[s("h1",{className:"text-2xl font-bold flex items-center gap-2",children:[l(P,{className:"w-6 h-6"})," ICQQ \u7BA1\u7406"]}),l("p",{className:"text-sm text-muted-foreground mt-1",children:"\u673A\u5668\u4EBA\u6982\u89C8\u4E0E\u767B\u5F55\u8F85\u52A9\uFF08\u626B\u7801 / \u9A8C\u8BC1\u7801 / \u6ED1\u5757\uFF09"})]}),a==="overview"&&s("button",{onClick:m,disabled:n,className:"flex items-center gap-1 px-3 py-1.5 rounded bg-blue-500 text-white hover:bg-blue-600 disabled:opacity-50 text-sm",children:[l(T,{className:`w-4 h-4 ${n?"animate-spin":""}`})," \u5237\u65B0"]})]}),s("div",{className:"flex gap-1 border-b",children:[l("button",{onClick:()=>u("overview"),className:`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${a==="overview"?"border-blue-500 text-blue-600":"border-transparent text-gray-500 hover:text-gray-700"}`,children:s("span",{className:"flex items-center gap-1.5",children:[l(P,{className:"w-4 h-4"})," \u6982\u89C8"]})}),l("button",{onClick:()=>u("login"),className:`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${a==="login"?"border-blue-500 text-blue-600":"border-transparent text-gray-500 hover:text-gray-700"}`,children:s("span",{className:"flex items-center gap-1.5",children:[l(w,{className:"w-4 h-4"})," \u767B\u5F55\u8F85\u52A9"]})})]}),a==="overview"&&s(ye,{children:[C&&l("div",{className:"p-3 bg-red-50 text-red-600 rounded border border-red-200 text-sm dark:bg-red-900/20 dark:text-red-400 dark:border-red-800",children:C}),n?l("div",{className:"flex justify-center py-12",children:l(I,{className:"w-6 h-6 animate-spin text-blue-500"})}):r.length===0?l("div",{className:"text-center text-muted-foreground py-12",children:"\u6682\u65E0 ICQQ \u673A\u5668\u4EBA\u5B9E\u4F8B"}):l("div",{className:"grid gap-4 md:grid-cols-2",children:r.map(d=>s("div",{className:"border rounded-lg p-4 bg-card shadow-sm",children:[s("div",{className:"flex items-center justify-between mb-3",children:[l("span",{className:"font-medium text-lg",children:d.name}),d.connected?s("span",{className:"flex items-center gap-1 text-green-600 text-sm",children:[l(U,{className:"w-4 h-4"})," \u5728\u7EBF"]}):s("span",{className:"flex items-center gap-1 text-gray-400 text-sm",children:[l(v,{className:"w-4 h-4"})," \u79BB\u7EBF"]})]}),s("div",{className:"space-y-2 text-sm text-muted-foreground",children:[s("div",{className:"flex items-center gap-1.5",children:[l(b,{className:"w-3.5 h-3.5"}),"\u7FA4 ",d.groupCount," \xB7 \u597D\u53CB ",d.friendCount]}),s("div",{className:"flex items-center gap-1.5",children:[l(F,{className:"w-3.5 h-3.5"}),"\u767B\u5F55\u65B9\u5F0F ",d.loginMode," \xB7 ",d.status]})]})]},d.name))})]}),a==="login"&&l(K,{})]})}function tt(a){a.addRoute({path:"/console/icqq",name:"ICQQ\u7BA1\u7406",element:a.React.createElement(Z,{hostReact:a.React})}),a.addTool({id:"icqq",name:"ICQQ",path:"/console/icqq"})}export{tt as register};
2
2
  /*! Bundled license information:
3
3
 
4
4
  lucide-react/dist/esm/shared/src/utils/mergeClasses.mjs:
@@ -26,7 +26,7 @@ lucide-react/dist/esm/icons/wifi.mjs:
26
26
  lucide-react/dist/esm/icons/x.mjs:
27
27
  lucide-react/dist/esm/lucide-react.mjs:
28
28
  (**
29
- * @license lucide-react v1.14.0 - ISC
29
+ * @license lucide-react v1.16.0 - ISC
30
30
  *
31
31
  * This source code is licensed under the ISC license.
32
32
  * See the LICENSE file in the root directory of this source tree.
@@ -0,0 +1,3 @@
1
+ import type { AgentPromptContributor } from 'zhin.js';
2
+ export declare function createIcqqAgentPromptContributor(): AgentPromptContributor;
3
+ //# sourceMappingURL=agent-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-prompt.d.ts","sourceRoot":"","sources":["../src/agent-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AAuEjB,wBAAgB,gCAAgC,IAAI,sBAAsB,CAuCzE"}
@@ -0,0 +1,104 @@
1
+ import { filterTools } from 'zhin.js';
2
+ function isIcqqDelegatedTask(query, goal) {
3
+ const text = `${query} ${goal}`;
4
+ const lower = text.toLowerCase();
5
+ if (/\bicqq\b|mcp_icqq|send_private_msg|friend\s+send/i.test(text))
6
+ return true;
7
+ if (/\bfriend\s+like\b/.test(lower) && /qq|好友|\d{5,}/i.test(text))
8
+ return true;
9
+ if (/点赞/.test(text) && /qq|好友|\d{5,}/i.test(text))
10
+ return true;
11
+ if (/发消息|发送消息|私聊/.test(text) && /qq|\d{5,}/i.test(text))
12
+ return true;
13
+ return false;
14
+ }
15
+ function selectIcqqDeferredTools(query, goal, deferredCatalog, maxTools) {
16
+ const pool = deferredCatalog.filter(t => !t.name.startsWith('mcp_filesystem') && !t.name.startsWith('mcp_memory_'));
17
+ const icqqMcpTools = pool.filter(t => t.name.startsWith('mcp_icqq_'));
18
+ const icqqTools = pool.filter(t => t.name.startsWith('icqq_'));
19
+ const pinned = [];
20
+ const bash = pool.find(t => t.name === 'bash');
21
+ if (bash)
22
+ pinned.push(bash);
23
+ const preferOrder = [
24
+ 'mcp_icqq_icqq_invoke',
25
+ 'mcp_icqq_icqq_list_actions',
26
+ 'icqq_send_user_like',
27
+ 'icqq_friend_list',
28
+ 'icqq_poke',
29
+ ];
30
+ for (const name of preferOrder) {
31
+ const t = icqqMcpTools.find(x => x.name === name) ??
32
+ icqqTools.find(x => x.name === name);
33
+ if (t)
34
+ pinned.push(t);
35
+ }
36
+ for (const t of [...icqqMcpTools, ...icqqTools]) {
37
+ if (pinned.length >= maxTools)
38
+ break;
39
+ if (!pinned.some(p => p.name === t.name))
40
+ pinned.push(t);
41
+ }
42
+ const extra = filterTools(query, pool, { maxTools, minScore: 0.08 })
43
+ .filter(t => !pinned.some(p => p.name === t.name));
44
+ const merged = [...pinned];
45
+ for (const t of extra) {
46
+ if (merged.length >= maxTools)
47
+ break;
48
+ merged.push(t);
49
+ }
50
+ return merged.slice(0, maxTools);
51
+ }
52
+ const ORCHESTRATOR_ICQQ = [
53
+ 'On icqq/QQ: use run_deferred_task with tool_query "mcp_icqq_icqq_invoke" or "icqq_send_user_like".',
54
+ 'Examples: send_private_msg, friend_like; do not use mcp_filesystem_* for QQ tasks.',
55
+ 'Skip tool_search when the user clearly asks to send a message, like a friend, or poke on QQ.',
56
+ ].join('\n');
57
+ const WORKER_ICQQ = [
58
+ 'Send private message: `mcp_icqq_icqq_invoke` action `send_private_msg` params `{ user_id, message }`, or bash `icqq friend send <uid> "<text>"`.',
59
+ 'Friend like: action `friend_like` or `icqq_send_user_like`, or bash `icqq friend like <uid> -t <times>`.',
60
+ 'Use `icqq_list_actions` only if action name is unclear.',
61
+ 'Do NOT use mcp_filesystem_* or explore node_modules / package.json to "discover" icqq.',
62
+ 'Do not stop at --help; execute the action the goal describes.',
63
+ ].map(line => `- ${line}`).join('\n');
64
+ export function createIcqqAgentPromptContributor() {
65
+ return {
66
+ platform: 'icqq',
67
+ async buildSections(ctx) {
68
+ if (ctx.slot === 'orchestrator') {
69
+ if (!ctx.toolSearch)
70
+ return null;
71
+ return [{
72
+ id: 'platform.icqq.orchestrator',
73
+ title: '## icqq / QQ',
74
+ body: ORCHESTRATOR_ICQQ,
75
+ priority: 50,
76
+ }];
77
+ }
78
+ if (ctx.slot === 'deferred_worker') {
79
+ const query = ctx.deferred?.toolQuery ?? ctx.deferred?.goal ?? '';
80
+ const goal = ctx.deferred?.goal ?? '';
81
+ if (!isIcqqDelegatedTask(query, goal))
82
+ return null;
83
+ return [{
84
+ id: 'platform.icqq.deferred_worker',
85
+ title: '## icqq / QQ(本任务)',
86
+ body: WORKER_ICQQ,
87
+ priority: 50,
88
+ }];
89
+ }
90
+ return null;
91
+ },
92
+ matchesDeferredTask(ctx) {
93
+ const query = ctx.deferred?.toolQuery ?? ctx.deferred?.goal ?? ctx.userMessagePreview ?? '';
94
+ const goal = ctx.deferred?.goal ?? ctx.userMessagePreview ?? '';
95
+ return isIcqqDelegatedTask(query, goal);
96
+ },
97
+ selectDeferredTools(query, goal, catalog, maxTools) {
98
+ if (!isIcqqDelegatedTask(query, goal))
99
+ return null;
100
+ return selectIcqqDeferredTools(query, goal, catalog, maxTools);
101
+ },
102
+ };
103
+ }
104
+ //# sourceMappingURL=agent-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-prompt.js","sourceRoot":"","sources":["../src/agent-prompt.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAK3C,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,MAAM,CAAC;QACf,UAAU,QAAQ;YAChB,GAAG,EAAE,WAAW,CAAC;YACjB,MAAM,EAAE,MAAM,CAAC;SAChB;KACF;IACD,UAAU,QAAQ;QAChB,IAAI,EAAE,WAAW,CAAC;KACnB;CACF;AAED,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAK3C,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,MAAM,CAAC;QACf,UAAU,QAAQ;YAChB,GAAG,EAAE,WAAW,CAAC;YACjB,MAAM,EAAE,MAAM,CAAC;SAChB;KACF;IACD,UAAU,QAAQ;QAChB,IAAI,EAAE,WAAW,CAAC;KACnB;CACF;AAED,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
package/lib/index.js CHANGED
@@ -2,7 +2,8 @@
2
2
  * ICQQ 适配器入口:类型扩展、导出、注册
3
3
  */
4
4
  import path from "path";
5
- import { usePlugin } from "zhin.js";
5
+ import { usePlugin, registerAgentPromptContributor, unregisterAgentPromptContributor, } from "zhin.js";
6
+ import { createIcqqAgentPromptContributor } from "./agent-prompt.js";
6
7
  import { IcqqAdapter } from "./adapter.js";
7
8
  import { registerCommands } from "./commands/index.js";
8
9
  import { registerTools } from "./tools/index.js";
@@ -17,11 +18,13 @@ provide({
17
18
  name: "icqq",
18
19
  description: "ICQQ Adapter",
19
20
  mounted: async (p) => {
21
+ registerAgentPromptContributor(createIcqqAgentPromptContributor());
20
22
  const adapter = new IcqqAdapter(p);
21
23
  await adapter.start();
22
24
  return adapter;
23
25
  },
24
26
  dispose: async (adapter) => {
27
+ unregisterAgentPromptContributor("icqq");
25
28
  await adapter.stop();
26
29
  },
27
30
  });
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAiC,MAAM,SAAS,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAc7C,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;AAC3B,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;AAEzD,iEAAiE;AACjE,OAAO,CAAC;IACN,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,cAAc;IAC3B,OAAO,EAAE,KAAK,EAAE,CAAS,EAAE,EAAE;QAC3B,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAoB,EAAE,EAAE;QACtC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;CACK,CAAC,CAAC;AAEV,kEAAkE;AAClE,UAAU,CAAC,MAAM,EAAE,CAAC,IAAiB,EAAE,EAAE;IACvC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,kEAAkE;AAClE,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,WAAwB,EAAE,IAAiB,EAAE,EAAE;IACzE,OAAO,aAAa,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,iEAAiE;AACjE,UAAU,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,EAAE;IAChC,WAAW,CAAC,QAAQ,CAAC;QACnB,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,qBAAqB,CAAC;QACrE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC;QACjE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;KACvB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,oEAAoE;AACpE,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAc,EAAE,IAAiB,EAAE,EAAE;IACvE,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EACL,SAAS,EAGT,8BAA8B,EAC9B,gCAAgC,GACjC,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,gCAAgC,EAAE,MAAM,mBAAmB,CAAC;AAGrE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAc7C,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;AAC3B,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;AAEzD,iEAAiE;AACjE,OAAO,CAAC;IACN,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,cAAc;IAC3B,OAAO,EAAE,KAAK,EAAE,CAAS,EAAE,EAAE;QAC3B,8BAA8B,CAAC,gCAAgC,EAAE,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAoB,EAAE,EAAE;QACtC,gCAAgC,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;CACK,CAAC,CAAC;AAEV,kEAAkE;AAClE,UAAU,CAAC,MAAM,EAAE,CAAC,IAAiB,EAAE,EAAE;IACvC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,kEAAkE;AAClE,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,WAAwB,EAAE,IAAiB,EAAE,EAAE;IACzE,OAAO,aAAa,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,iEAAiE;AACjE,UAAU,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,EAAE;IAChC,WAAW,CAAC,QAAQ,CAAC;QACnB,EAAE,EAAE,MAAM;QACV,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,qBAAqB,CAAC;QACrE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC;QACjE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;KACvB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,oEAAoE;AACpE,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAc,EAAE,IAAiB,EAAE,EAAE;IACvE,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-icqq",
3
- "version": "2.0.24",
3
+ "version": "2.0.26",
4
4
  "description": "Zhin.js adapter for ICQQ (QQ Bot)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -48,19 +48,19 @@
48
48
  "@radix-ui/themes": "^3.2.1",
49
49
  "@types/react": "^19.2.14",
50
50
  "@types/react-dom": "^19.2.3",
51
- "lucide-react": "^1.14.0",
51
+ "lucide-react": "^1.16.0",
52
52
  "radix-ui": "^1.4.3",
53
53
  "typescript": "^6.0.3",
54
- "@zhin.js/cli": "1.0.75",
55
- "@zhin.js/console": "2.0.22",
56
- "zhin.js": "1.0.79"
54
+ "@zhin.js/cli": "1.0.77",
55
+ "@zhin.js/console": "2.0.24",
56
+ "zhin.js": "1.0.81"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "@zhin.js/client": "1.0.18",
60
- "@zhin.js/console": "2.0.22",
61
- "@zhin.js/core": "1.1.21",
62
- "zhin.js": "1.0.79",
63
- "@zhin.js/http": "1.0.72"
60
+ "@zhin.js/console": "2.0.24",
61
+ "@zhin.js/core": "1.1.23",
62
+ "@zhin.js/http": "1.0.74",
63
+ "zhin.js": "1.0.81"
64
64
  },
65
65
  "peerDependenciesMeta": {
66
66
  "@zhin.js/client": {
@@ -0,0 +1,115 @@
1
+ import type {
2
+ AgentPromptBuildContext,
3
+ AgentPromptContributor,
4
+ AgentPromptSection,
5
+ } from 'zhin.js';
6
+ import type { AgentTool } from 'zhin.js';
7
+ import { filterTools } from 'zhin.js';
8
+
9
+ function isIcqqDelegatedTask(query: string, goal: string): boolean {
10
+ const text = `${query} ${goal}`;
11
+ const lower = text.toLowerCase();
12
+ if (/\bicqq\b|mcp_icqq|send_private_msg|friend\s+send/i.test(text)) return true;
13
+ if (/\bfriend\s+like\b/.test(lower) && /qq|好友|\d{5,}/i.test(text)) return true;
14
+ if (/点赞/.test(text) && /qq|好友|\d{5,}/i.test(text)) return true;
15
+ if (/发消息|发送消息|私聊/.test(text) && /qq|\d{5,}/i.test(text)) return true;
16
+ return false;
17
+ }
18
+
19
+ function selectIcqqDeferredTools(
20
+ query: string,
21
+ goal: string,
22
+ deferredCatalog: AgentTool[],
23
+ maxTools: number,
24
+ ): AgentTool[] {
25
+ const pool = deferredCatalog.filter(
26
+ t => !t.name.startsWith('mcp_filesystem') && !t.name.startsWith('mcp_memory_'),
27
+ );
28
+ const icqqMcpTools = pool.filter(t => t.name.startsWith('mcp_icqq_'));
29
+ const icqqTools = pool.filter(t => t.name.startsWith('icqq_'));
30
+ const pinned: AgentTool[] = [];
31
+ const bash = pool.find(t => t.name === 'bash');
32
+ if (bash) pinned.push(bash);
33
+ const preferOrder = [
34
+ 'mcp_icqq_icqq_invoke',
35
+ 'mcp_icqq_icqq_list_actions',
36
+ 'icqq_send_user_like',
37
+ 'icqq_friend_list',
38
+ 'icqq_poke',
39
+ ];
40
+ for (const name of preferOrder) {
41
+ const t =
42
+ icqqMcpTools.find(x => x.name === name) ??
43
+ icqqTools.find(x => x.name === name);
44
+ if (t) pinned.push(t);
45
+ }
46
+ for (const t of [...icqqMcpTools, ...icqqTools]) {
47
+ if (pinned.length >= maxTools) break;
48
+ if (!pinned.some(p => p.name === t.name)) pinned.push(t);
49
+ }
50
+
51
+ const extra = filterTools(query, pool, { maxTools, minScore: 0.08 })
52
+ .filter(t => !pinned.some(p => p.name === t.name));
53
+
54
+ const merged: AgentTool[] = [...pinned];
55
+ for (const t of extra) {
56
+ if (merged.length >= maxTools) break;
57
+ merged.push(t);
58
+ }
59
+ return merged.slice(0, maxTools);
60
+ }
61
+
62
+ const ORCHESTRATOR_ICQQ = [
63
+ 'On icqq/QQ: use run_deferred_task with tool_query "mcp_icqq_icqq_invoke" or "icqq_send_user_like".',
64
+ 'Examples: send_private_msg, friend_like; do not use mcp_filesystem_* for QQ tasks.',
65
+ 'Skip tool_search when the user clearly asks to send a message, like a friend, or poke on QQ.',
66
+ ].join('\n');
67
+
68
+ const WORKER_ICQQ = [
69
+ 'Send private message: `mcp_icqq_icqq_invoke` action `send_private_msg` params `{ user_id, message }`, or bash `icqq friend send <uid> "<text>"`.',
70
+ 'Friend like: action `friend_like` or `icqq_send_user_like`, or bash `icqq friend like <uid> -t <times>`.',
71
+ 'Use `icqq_list_actions` only if action name is unclear.',
72
+ 'Do NOT use mcp_filesystem_* or explore node_modules / package.json to "discover" icqq.',
73
+ 'Do not stop at --help; execute the action the goal describes.',
74
+ ].map(line => `- ${line}`).join('\n');
75
+
76
+ export function createIcqqAgentPromptContributor(): AgentPromptContributor {
77
+ return {
78
+ platform: 'icqq',
79
+
80
+ async buildSections(ctx: AgentPromptBuildContext): Promise<AgentPromptSection[] | null> {
81
+ if (ctx.slot === 'orchestrator') {
82
+ if (!ctx.toolSearch) return null;
83
+ return [{
84
+ id: 'platform.icqq.orchestrator',
85
+ title: '## icqq / QQ',
86
+ body: ORCHESTRATOR_ICQQ,
87
+ priority: 50,
88
+ }];
89
+ }
90
+ if (ctx.slot === 'deferred_worker') {
91
+ const query = ctx.deferred?.toolQuery ?? ctx.deferred?.goal ?? '';
92
+ const goal = ctx.deferred?.goal ?? '';
93
+ if (!isIcqqDelegatedTask(query, goal)) return null;
94
+ return [{
95
+ id: 'platform.icqq.deferred_worker',
96
+ title: '## icqq / QQ(本任务)',
97
+ body: WORKER_ICQQ,
98
+ priority: 50,
99
+ }];
100
+ }
101
+ return null;
102
+ },
103
+
104
+ matchesDeferredTask(ctx: AgentPromptBuildContext): boolean {
105
+ const query = ctx.deferred?.toolQuery ?? ctx.deferred?.goal ?? ctx.userMessagePreview ?? '';
106
+ const goal = ctx.deferred?.goal ?? ctx.userMessagePreview ?? '';
107
+ return isIcqqDelegatedTask(query, goal);
108
+ },
109
+
110
+ selectDeferredTools(query, goal, catalog, maxTools) {
111
+ if (!isIcqqDelegatedTask(query, goal)) return null;
112
+ return selectIcqqDeferredTools(query, goal, catalog, maxTools);
113
+ },
114
+ };
115
+ }
package/src/index.ts CHANGED
@@ -2,7 +2,14 @@
2
2
  * ICQQ 适配器入口:类型扩展、导出、注册
3
3
  */
4
4
  import path from "path";
5
- import { usePlugin, type Plugin, type ToolFeature } from "zhin.js";
5
+ import {
6
+ usePlugin,
7
+ type Plugin,
8
+ type ToolFeature,
9
+ registerAgentPromptContributor,
10
+ unregisterAgentPromptContributor,
11
+ } from "zhin.js";
12
+ import { createIcqqAgentPromptContributor } from "./agent-prompt.js";
6
13
  import type { Router } from "@zhin.js/http";
7
14
  import { PageManager } from "@zhin.js/console";
8
15
  import { IcqqAdapter } from "./adapter.js";
@@ -34,11 +41,13 @@ provide({
34
41
  name: "icqq",
35
42
  description: "ICQQ Adapter",
36
43
  mounted: async (p: Plugin) => {
44
+ registerAgentPromptContributor(createIcqqAgentPromptContributor());
37
45
  const adapter = new IcqqAdapter(p);
38
46
  await adapter.start();
39
47
  return adapter;
40
48
  },
41
49
  dispose: async (adapter: IcqqAdapter) => {
50
+ unregisterAgentPromptContributor("icqq");
42
51
  await adapter.stop();
43
52
  },
44
53
  } as any);
@@ -1,43 +0,0 @@
1
- ---
2
- name: icqq
3
- platforms:
4
- - icqq
5
- description: 'Operate QQ account via icqq CLI. Use when asked to: send QQ message, manage QQ groups, check QQ friends, poke friend, like friend, mute member, kick member, set nickname, view QQ profile, handle friend/group requests, manage group files, set group announcement, QQ签到, 发消息, 管群, 好友操作, 群文件.'
6
- argument-hint: 'Describe what QQ operation to perform, e.g. "send hello to friend 12345" or "mute user 67890 in group 11111"'
7
- disable-model-invocation: true
8
- ---
9
-
10
- # icqq — QQ Account Operations via CLI
11
-
12
- Operate a QQ account through the `icqq` command-line tool. The daemon must be running first (`icqq login`).
13
-
14
- ## Procedure
15
-
16
- 1. **Identify the module** — Match the user's intent to one of the modules below
17
- 2. **Load the reference** — Read ONLY the relevant module reference file(s)
18
- 3. **Check daemon** — Use `icqq service status` for install/running state, then probe the account with `icqq profile` or `icqq friend list` to confirm IPC responds
19
- 4. **Execute** — Run the command in terminal and report results
20
-
21
- ## Modules
22
-
23
- Load the corresponding reference file based on what the user wants:
24
-
25
- | Intent | Module | Reference |
26
- |--------|--------|-----------|
27
- | 发消息、撤回、聊天记录、消息详情、合并转发 | Messaging | [messaging.md](./references/messaging.md) |
28
- | 好友列表、查看、发消息、戳一戳、点赞、删除、备注、文件、好友分组 | Friends | [friends.md](./references/friends.md) |
29
- | 群管理:发消息、禁言、踢人、公告、邀请、签到、精华、成员、表态 | Groups | [groups.md](./references/groups.md) |
30
- | 设置:昵称、头像、签名、群名片、群头衔、加群方式、匿名 | Settings | [settings.md](./references/settings.md) |
31
- | 好友/群请求处理 | Requests | [requests.md](./references/requests.md) |
32
- | 群文件:目录管理、上传下载、转发 | Group Files | [gfs.md](./references/gfs.md) |
33
- | 登录、服务/守护、配置、OCR、黑名单、Webhook、通知、UID转换、陌生人、漫游表情、缓存、重载、频道与子频道(Guild & Channel)、RPC 远程连接、补全 | General | [general.md](./references/general.md) |
34
-
35
- ## Global Notes
36
-
37
- - All `<uid>` = QQ number (integer), `<gid>` = group number (integer)
38
- - Daemon must run first: `icqq login`
39
- - Multi-instance: use `-u <uin>` or `ICQQ_CURRENT_UIN` env to specify account; defaults to `config.currentUin`
40
- - **Use `icqq friend send` / `icqq group send` for non-interactive messaging** (agent-friendly); `icqq friend chat` / `icqq group chat` are interactive
41
- - CQ code syntax in messages: `[face:id]` `[image:path]` `[at:uid]` `[at:all]` `[dice]` `[rps]`
42
- - Quote strings with spaces: `icqq friend send 12345 "hello world"`
43
- - Chain batch ops with `&&`
@@ -1,54 +0,0 @@
1
- # Friends
2
-
3
- ## List & View
4
-
5
- ```
6
- icqq friend list # List all friends
7
- icqq friend view <uid> # View friend profile
8
- icqq friend avatar-url <uid> # Get avatar URL
9
- ```
10
-
11
- ## Actions
12
-
13
- ```
14
- icqq friend send <uid> <message> # Send private message
15
- icqq friend poke <uid> # Poke a friend
16
- icqq friend like <uid> [-t times] # Like (1-20 times, default 1)
17
- icqq friend delete <uid> [-b] # Delete friend (-b: also block)
18
- icqq friend remark <uid> <remark> # Set friend remark/alias
19
- icqq friend add <uid> # Add friend (optionally via group)
20
- ```
21
-
22
- ## Files
23
-
24
- ```
25
- icqq friend send-file <uid> <file> # Send file to friend
26
- icqq friend file-info <uid> <fid> # Get file info
27
- icqq friend file-url <uid> <fid> # Get file download URL
28
- icqq friend recall-file <uid> <fid> # Recall a sent file
29
- ```
30
-
31
- ## Friend Classes (Groups)
32
-
33
- ```
34
- icqq friend class list # List friend groups
35
- icqq friend class add <name> # Create friend group
36
- icqq friend class delete <id> # Delete friend group
37
- icqq friend class rename <id> <name> # Rename friend group
38
- icqq friend class set <uid> <id> # Move friend to group
39
- ```
40
-
41
- ## Examples
42
-
43
- ```bash
44
- icqq friend list
45
- icqq friend view 12345
46
- icqq friend send 12345 "你好"
47
- icqq friend poke 12345
48
- icqq friend like 12345 -t 10
49
- icqq friend remark 12345 "小王"
50
- icqq friend delete 12345 -b
51
- icqq friend send-file 12345 ./doc.pdf
52
- icqq friend class list
53
- icqq friend class add "大学同学"
54
- ```
@@ -1,230 +0,0 @@
1
- # General
2
-
3
- ## Account
4
-
5
- > Use **`icqq service status`** for service/daemon state, or **`icqq profile`** / **`icqq friend list`** to verify the daemon answers over IPC.
6
-
7
- ```
8
- icqq login # Login QQ and start daemon (interactive wizard)
9
- icqq login -r # Quick reconnect using saved token
10
- icqq login -q <uid> -r # Quick reconnect specific account
11
- icqq logout # Logout and stop daemon (token invalidated)
12
- icqq logout -k # Disconnect only, keep token (login -r still works)
13
- icqq logout <uin> # Logout specific account
14
- icqq switch # Switch current account (interactive)
15
- icqq switch <uin> # Switch to specific account
16
- icqq profile # View current account profile
17
- icqq requests # View pending friend/group requests
18
- ```
19
-
20
- ## System Service (auto-restart on crash, start on boot)
21
-
22
- ```
23
- icqq service install # Register daemon as system service (launchd/systemd)
24
- icqq service install -a # Install service for all configured accounts
25
- icqq service uninstall # Remove system service
26
- icqq service uninstall -a # Uninstall all
27
- icqq service start # Start installed service
28
- icqq service start -a # Start all
29
- icqq service stop # Stop service (keeps service file, no restart until start)
30
- icqq service stop -a # Stop all
31
- icqq service status # Show service install/running state
32
- icqq service status -a # Show status for all accounts
33
- ```
34
-
35
- Note: `icqq logout` does NOT prevent service auto-restart. To permanently stop, uninstall the service first.
36
-
37
- ## Config
38
-
39
- ```
40
- icqq config get # View all config
41
- icqq config get <key> # View specific config key (currentUin, webhookUrl, notifyEnabled)
42
- icqq config set <key> <value> # Set config value
43
- ```
44
-
45
- ## Multi-Instance
46
-
47
- Use `-u <uin>` global flag or `ICQQ_CURRENT_UIN` env to target a specific account.
48
- Default falls back to `config.currentUin`.
49
-
50
- ```
51
- icqq -u 12345 profile # View profile for account 12345
52
- ICQQ_CURRENT_UIN=12345 icqq friend list
53
- ```
54
-
55
- ## Blacklist
56
-
57
- ```
58
- icqq blacklist # View blacklist
59
- ```
60
-
61
- ## OCR
62
-
63
- ```
64
- icqq ocr <image> # OCR image text recognition (local file path)
65
- ```
66
-
67
- ## Webhook
68
-
69
- ```
70
- icqq webhook # View current webhook config
71
- icqq webhook set <url> # Set webhook URL (daemon pushes events via POST)
72
- icqq webhook off # Disable webhook
73
- ```
74
-
75
- ## Notification
76
-
77
- ```
78
- icqq notify # View notification status
79
- icqq notify on # Enable system notifications
80
- icqq notify off # Disable system notifications
81
- ```
82
-
83
- ## Conversion
84
-
85
- ```
86
- icqq convert uid <qq> # QQ number to UID
87
- icqq convert uin <uid> # UID to QQ number
88
- ```
89
-
90
- ## Keys & URLs
91
-
92
- ```
93
- icqq get client-key # Get ClientKey
94
- icqq get pskey # Get PSKey
95
- icqq get video-url <vid> # Get video download URL
96
- ```
97
-
98
- ## Stranger
99
-
100
- ```
101
- icqq stranger view <uid> # View stranger profile
102
- icqq stranger status <uid> # Check online status
103
- icqq stranger add-setting <uid> # Check add-friend settings
104
- ```
105
-
106
- ## Roaming Emoji (Stamps)
107
-
108
- ```
109
- icqq stamp list # List roaming emojis
110
- icqq stamp delete # Delete roaming emoji
111
- ```
112
-
113
- ## Cache & Reload
114
-
115
- ```
116
- icqq cache clean # Clear cache
117
- icqq reload friends # Refresh friend list
118
- icqq reload groups # Refresh group list
119
- icqq reload blacklist # Reload blacklist
120
- icqq reload guilds # Reload guild list
121
- icqq reload strangers # Reload stranger list
122
- ```
123
-
124
- ## Guild (Server & Channel)
125
-
126
- ```
127
- icqq guild list # List guilds
128
- icqq guild info <guild_id> # View guild info
129
- icqq guild members <guild_id> # List guild members
130
- icqq guild channel list <guild_id> # List subchannels
131
- icqq guild channel send <guild_id> <channel_id> <message> # Send channel message
132
- icqq guild channel chat <guild_id> <channel_id> # Interactive channel chat
133
- icqq guild channel recall <guild_id> <channel_id> <seq> # Recall channel message
134
- icqq guild channel share <guild_id> <channel_id> <url> <title> # Share post link
135
- icqq guild channel forum-url <guild_id> <channel_id> <forum_id> # Get forum URL
136
- ```
137
-
138
- ## Shell Completion
139
-
140
- ```
141
- icqq completion [shell] # Generate shell completion script (bash/zsh/fish)
142
- ```
143
-
144
- ## RPC (TCP Remote Connection)
145
-
146
- The daemon supports optional TCP remote access for cross-machine QQ account control.
147
-
148
- ### Configuration
149
-
150
- In `~/.icqq/config.json`:
151
-
152
- ```json
153
- {
154
- "rpc": {
155
- "enabled": true,
156
- "host": "127.0.0.1",
157
- "port": 0
158
- }
159
- }
160
- ```
161
-
162
- Or via CLI:
163
-
164
- ```
165
- icqq config set rpc.enabled true # Enable RPC TCP listener
166
- icqq config set rpc.host 0.0.0.0 # Listen on all interfaces (for remote access)
167
- icqq config set rpc.port 9100 # Set listen port (0 = auto-assign)
168
- ```
169
-
170
- | Field | Description | Default |
171
- |-------|-------------|---------|
172
- | `enabled` | Enable RPC TCP listener | `false` |
173
- | `host` | Listen address, `"0.0.0.0"` for remote | `"127.0.0.1"` |
174
- | `port` | Listen port, `0` = auto-assign | `0` |
175
-
176
- ### Security
177
-
178
- - **HMAC-SHA256 challenge-response auth** — token never transmitted over network
179
- - **IP rate limiting** — 5 failures in 5 minutes → auto-block
180
- - **Default localhost only** — must explicitly set `host: "0.0.0.0"` for remote access
181
- - **4KB unauthenticated buffer limit** — prevents memory exhaustion
182
-
183
- ### Programmatic Access
184
-
185
- ```typescript
186
- import { IpcClient } from "@icqqjs/cli/lib/ipc-client";
187
-
188
- // Option 1: Specify host/port/token directly
189
- const client = await IpcClient.connectRpc({
190
- host: "192.168.1.100",
191
- port: 9100,
192
- token: "your-token-here",
193
- });
194
-
195
- // Option 2: Auto-read from daemon.rpc file (local only)
196
- const client = await IpcClient.connectRpcByUin(12345);
197
-
198
- const resp = await client.request("list_friends");
199
- client.close();
200
- ```
201
-
202
- ### Auth Flow
203
-
204
- 1. Client connects to TCP port
205
- 2. Server sends `{ "challenge": "<random-hex>" }`
206
- 3. Client computes `HMAC-SHA256(token, challenge)` → digest
207
- 4. Client sends `{ "action": "auth", "params": { "digest": "<hex>" } }`
208
- 5. Server verifies → authenticated
209
-
210
- ## Examples
211
-
212
- ```bash
213
- icqq service status
214
- icqq profile
215
- icqq requests
216
- icqq login -r
217
- icqq config get
218
- icqq config set currentUin 12345
219
- icqq switch 12345
220
- icqq -u 12345 profile
221
- icqq ocr ./screenshot.png
222
- icqq webhook set https://example.com/hook
223
- icqq notify on
224
- icqq convert uid 12345
225
- icqq stranger view 12345
226
- icqq stamp list
227
- icqq cache clean
228
- icqq reload friends
229
- icqq guild list
230
- ```
@@ -1,49 +0,0 @@
1
- # Group File System (GFS)
2
-
3
- ## List Files
4
-
5
- ```
6
- icqq group fs list <gid> # List root directory
7
- icqq group fs list <gid> -p <pid> # List subdirectory by parent ID
8
- ```
9
-
10
- ## Info & Stats
11
-
12
- ```
13
- icqq group fs info <gid> # View GFS usage stats (space, file count)
14
- icqq group fs stat <gid> <fid> # View file/directory details
15
- ```
16
-
17
- ## Manage
18
-
19
- ```
20
- icqq group fs mkdir <gid> <name> # Create directory
21
- icqq group fs delete <gid> <fid> # Delete file/directory by ID
22
- icqq group fs rename <gid> <fid> <name> # Rename file/directory
23
- icqq group fs move <gid> <fid> <pid> # Move file to directory
24
- ```
25
-
26
- ## Upload & Download
27
-
28
- ```
29
- icqq group fs upload <gid> <file> # Upload file to group
30
- icqq group fs download <gid> <fid> # Get download URL
31
- icqq group fs forward <gid> <fid> <target_gid> # Forward file to another group
32
- icqq group fs forward-offline <gid> <fid> # Convert to offline file
33
- ```
34
-
35
- The `<fid>` (file ID) is shown in `icqq group fs list` output.
36
-
37
- ## Examples
38
-
39
- ```bash
40
- icqq group fs list 67890
41
- icqq group fs info 67890
42
- icqq group fs stat 67890 abc123
43
- icqq group fs mkdir 67890 "会议资料"
44
- icqq group fs upload 67890 ./report.pdf
45
- icqq group fs download 67890 abc123
46
- icqq group fs rename 67890 abc123 "新文件名"
47
- icqq group fs move 67890 abc123 def456
48
- icqq group fs delete 67890 abc123
49
- ```
@@ -1,71 +0,0 @@
1
- # Groups
2
-
3
- ## List & View
4
-
5
- ```
6
- icqq group list # List all groups
7
- icqq group view <gid> # View group info
8
- icqq group member list <gid> # List group members
9
- icqq group member view <gid> <uid> # View member info
10
- icqq group avatar-url <gid> # Get group avatar URL
11
- icqq group share <gid> # Get group share link
12
- icqq group anon-info <gid> # View anonymous info
13
- icqq group at-all-remain <gid> # Check @all remaining count
14
- icqq group muted-list <gid> # View muted members list
15
- ```
16
-
17
- ## Mute
18
-
19
- ```
20
- icqq group mute <gid> <uid> [-d seconds] # Mute member (default 600s, -d 0 to unmute)
21
- icqq group mute-all <gid> # Mute all
22
- icqq group mute-all <gid> --off # Unmute all
23
- icqq group mute-anon <gid> <flag> # Mute anonymous member
24
- ```
25
-
26
- ## Kick & Quit
27
-
28
- ```
29
- icqq group kick <gid> <uid> [-b] # Kick member (-b: block rejoin)
30
- icqq group quit <gid> # Quit group
31
- icqq group screen-member <gid> <uid> # Block/unblock member messages
32
- ```
33
-
34
- ## Social
35
-
36
- ```
37
- icqq group send <gid> <message> # Send group message
38
- icqq group poke <gid> <uid> # Poke group member
39
- icqq group invite <gid> <uid> # Invite friend to group
40
- icqq group sign <gid> # Group check-in
41
- ```
42
-
43
- ## Reactions
44
-
45
- ```
46
- icqq group reaction add <msgid> <emoji> # React to message
47
- icqq group reaction remove <msgid> <emoji> # Remove reaction
48
- ```
49
-
50
- ## Announcement & Essence
51
-
52
- ```
53
- icqq group announce <gid> <content> # Post announcement
54
- icqq group essence add <message_id> # Set essence message
55
- icqq group essence remove <message_id> # Remove essence message
56
- ```
57
-
58
- ## Examples
59
-
60
- ```bash
61
- icqq group list
62
- icqq group view 67890
63
- icqq group send 67890 "大家好"
64
- icqq group member list 67890
65
- icqq group member view 67890 12345
66
- icqq group mute 67890 12345 -d 3600
67
- icqq group kick 67890 12345 -b
68
- icqq group announce 67890 "今晚8点开会"
69
- icqq group sign 67890
70
- icqq group reaction add abc123 👍
71
- ```
@@ -1,64 +0,0 @@
1
- # Messaging
2
-
3
- ## Send Message (non-interactive)
4
-
5
- ```
6
- icqq friend send <uid> <message> # Send private message
7
- icqq group send <gid> <message> # Send group message
8
- ```
9
-
10
- **IMPORTANT**: Always use `icqq friend send` / `icqq group send` for agent operations (non-interactive). The `icqq friend chat` / `icqq group chat` commands enter interactive mode that the agent cannot operate.
11
-
12
- ## CQ Code Syntax
13
-
14
- Messages support inline CQ codes for rich content:
15
-
16
- ```
17
- [face:178] # QQ face emoji (id 0~348)
18
- [image:/path/to/pic.jpg] # Image (local path or URL)
19
- [at:12345] # @ a user
20
- [at:all] # @ everyone
21
- [dice] # Dice
22
- [rps] # Rock-paper-scissors
23
- ```
24
-
25
- Mixed example: `icqq send group 67890 "你好[face:178]看看[image:/tmp/pic.jpg]"`
26
-
27
- ## Recall
28
-
29
- ```
30
- icqq recall <message_id>
31
- ```
32
-
33
- ## Message Operations
34
-
35
- ```
36
- icqq msg get <message_id> # View message details
37
- icqq msg mark-read <message_id> # Mark message as read
38
- icqq forward get <message_id> # View forwarded message content
39
- ```
40
-
41
- ## Chat History
42
-
43
- ```
44
- icqq friend chat history <uid> [-c count] # Private chat history (default 20)
45
- icqq group chat history <gid> [-c count] # Group chat history (default 20)
46
- ```
47
-
48
- ## Interactive Chat (human only)
49
-
50
- ```
51
- icqq friend chat <uid> # Enter private chat mode
52
- icqq group chat <gid> # Enter group chat mode
53
- ```
54
-
55
- ## Examples
56
-
57
- ```bash
58
- icqq friend send 12345 "你好"
59
- icqq group send 67890 "大家好[face:21]"
60
- icqq friend send 12345 "[image:https://example.com/pic.jpg]看这个"
61
- icqq friend chat history 12345 -c 50
62
- icqq group chat history 67890
63
- icqq recall abc123
64
- ```
@@ -1,27 +0,0 @@
1
- # Friend & Group Requests
2
-
3
- ## View Pending Requests
4
-
5
- ```
6
- icqq requests # Show all pending friend/group requests with flags
7
- ```
8
-
9
- ## Handle Requests
10
-
11
- ```
12
- icqq request accept <flag> # Accept friend request
13
- icqq request accept <flag> -g # Accept group request
14
- icqq request reject <flag> # Reject friend request
15
- icqq request reject <flag> -g # Reject group request
16
- icqq request reject <flag> -g -r "理由" # Reject with reason
17
- ```
18
-
19
- The `<flag>` value is shown in `icqq requests` output.
20
-
21
- ## Examples
22
-
23
- ```bash
24
- icqq requests
25
- icqq request accept abc123
26
- icqq request reject def456 -g -r "群已满"
27
- ```
@@ -1,38 +0,0 @@
1
- # Settings
2
-
3
- ## Personal Settings
4
-
5
- ```
6
- icqq set nickname <name> # Set nickname
7
- icqq set gender <0|1|2> # 0=unknown, 1=male, 2=female
8
- icqq set birthday <YYYYMMDD> # Set birthday
9
- icqq set signature <text> # Set signature
10
- icqq set description <text> # Set description
11
- icqq set avatar <file> # Set avatar (image file path)
12
- icqq set online-status <code> # 11=online, 31=away, 41=invisible, 50=busy, 60=Q-me, 70=DND
13
- ```
14
-
15
- ## Group Settings
16
-
17
- ```
18
- icqq group set name <gid> <name> # Set group name
19
- icqq group set avatar <gid> <file> # Set group avatar
20
- icqq group set card <gid> <uid> <card> # Set member card/nickname
21
- icqq group set title <gid> <uid> <title> # Set member special title
22
- icqq group set admin <gid> <uid> # Set admin
23
- icqq group set admin <gid> <uid> -r # Remove admin
24
- icqq group set remark <gid> <remark> # Set group remark
25
- icqq group set anonymous <gid> # Toggle anonymous
26
- icqq group set join-type <gid> <type> # Set join method
27
- icqq group set rate-limit <gid> <limit> # Set message rate limit
28
- ```
29
-
30
- ## Examples
31
-
32
- ```bash
33
- icqq set nickname "新昵称"
34
- icqq set signature "今天天气不错"
35
- icqq set online-status 50
36
- icqq group set name 67890 "新群名"
37
- icqq group set card 67890 12345 "管理员小王"
38
- ```