### Install FQGate Python SDK Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/sdk/python/README.md Install the SDK using pip. The base installation is sufficient for HTTP examples. ```powershell python -m pip install . ``` -------------------------------- ### Install FQGate and Qianwen skills with setup.ps1 Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/qianwen/README.md Run this command after entering a Qianwen work task and extracting the Qianwen installation package. It installs and starts FQGate, then installs the Qianwen skills and connection. If the same official version already exists, it will be reused directly. ```powershell powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\setup.ps1 ``` -------------------------------- ### I1: run component setup Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Runs the setup function of a component, handling synchronous and asynchronous results. Sets up the proxy and setup context, and handles async dependencies. ```javascript function I1(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,e1);const{setup:o}=n;if(o){Ln();const s=e.setupContext=o.length>1?N1(e):null,r=Vr(e),i=Dr(o,e,0,[e.props,s]),a=Og(i);if(qn(),r(),(a||e.sp)&&!os(e)&&fv(e),a){if(i.then(Pf,Pf),t)return i.then(l=>{Nr(!0);try{xf(e,l,t)}finally{Nr(!1)}}).catch(l=>{qa(l,e,0)});e.asyncDep=i}else xf(e,i)}else qv(e)} ``` -------------------------------- ### xf: apply setup result Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Assigns the render function or setup state from the setup result, then calls qv to finalize the component. ```javascript function xf(e,t,n){Oe(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:We(t)&&(e.setupState=Qg(t)),qv(e)} ``` -------------------------------- ### Install FQGate Python SDK with realtime extra Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/sdk/python/README.md Install the SDK with the 'realtime' extra to enable real-time streaming support. ```powershell python -m pip install ".[realtime]" ``` -------------------------------- ### Install and configure fqgate-agent plugin Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/deepseek-harness/README.md Adds the fqgate-agent plugin, configures it with the FQGate executable path, and starts the web interface. Requires FQGate 0.1.0 or higher and a built npm package. ```powershell dsh plugin --profile web add dsh plugin --profile web exec fqgate-agent configure --fqgate-path "" --json dsh web ``` -------------------------------- ### N1: create setup context Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Creates the setup context object with attrs proxy, slots, emit, and expose function. ```javascript function N1(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,z1),slots:e.slots,emit:e.emit,expose:t}} ``` -------------------------------- ### HTTP example using Client.discover() Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/sdk/python/README.md Create a client via discovery and call health, search, market data, and klines endpoints. ```python from fqgate_client import Client client = Client.discover() print(client.health()) print(client.search("贵州茅台")) print(client.market_data([{"market": "USHA", "code": "600519"}])) print(client.klines("USHA", "600519", count=30, interval="day", adjust="forward")) ``` -------------------------------- ### Install FQGate via install-fqgate.ps1 scripts Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/qianwen/README.md Windows users can run the first command from the repository root to install FQGate. If using an already-extracted plugin package, run the second command. Both commands perform official version download, verification, fixed-directory installation, shortcut creation, startup, and connection check. ```powershell powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\installer\runtime\install-fqgate.ps1 ``` ```powershell powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\install-fqgate.ps1 ``` -------------------------------- ### O1: initialize component Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Initializes a component instance: sets up props, slots, and then runs setup or render. Returns the result of setup if it is a function. ```javascript let Mr=!1;function O1(e,t=!1,n=!1){t&&Nr(t);const{props:o,children:s}=e.vnode,r=Lv(e);m1(e,o,r,t),b1(e,s,n||t);const i=r?I1(e,t):void 0;return t&&Nr(!1),i} ``` -------------------------------- ### WebSocket example using RealtimeClient Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/sdk/python/README.md Subscribe to real-time quotes via WebSocket and print each message asynchronously. ```python import asyncio from fqgate_client import RealtimeClient async def main(): client = RealtimeClient.discover() async for message in client.subscribe(kind="quote", market="USHA", code="600519"): print(message) asyncio.run(main()) ``` -------------------------------- ### Alert component registration with install Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/login.html Registers the alert component with a plugin install function that adds it globally using the component name prefix. ```javascript var bl=Pe(j9,\[\["render",F9\]\]);const B9=Object.assign(bl,{install:(e,t)=>{Vt(e,t);const n=Bt(t);e.component(n+bl.name,bl)}}); ``` -------------------------------- ### HTTP example using client.request() for unknown endpoints Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/sdk/python/README.md Use the generic request method to call public paths for unknown or new interfaces. ```python document = client.request("GET", "/openapi.json") result = client.request("POST", "/v1/market/history/intraday", { "market": "USHA", "code": "600519", }) ``` -------------------------------- ### Zod Check Starts With Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/login.html Registers the $ZodCheckStartsWith check. Builds a regex that matches the prefix at the start of the value, attaches the pattern, and checks if the value starts with the prefix, pushing an 'invalid_format' issue if not. ```javascript wv=M("$ZodCheckStartsWith",(e,t)=>{Ut.init(e,t);const n=new RegExp(\`^${ir(t.prefix)}.*\`);t.pattern??(t.pattern=n),e.\_zod.onattach.push(o=>{const r=o.\_zod.bag;r.patterns??(r.patterns=new Set),r.patterns.add(n)}),e.\_zod.check=o=>{o.value.startsWith(t.prefix)||o.issues.push({origin:"string",code:"invalid\_format",format:"starts\_with",prefix:t.prefix,input:o.value,inst:e,continue:!t.abort})}}) ``` -------------------------------- ### Alert component setup with prefixCls and close handlers Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/login.html Computed properties and handlers for an alert component: prefix class, dynamic class bindings, visibility state, and close/after-close callbacks. ```javascript o=\_e("alert"),r=se(!0),s=l=>{r.value=!1,n("close",l)},i=()=>{n("afterClose")},a=w(()=>\[o,\`${o}-${e.type}\`,{\[\`${o}-with-title\`\]:!!(e.title||t.title),\[\`${o}-banner\`\]:e.banner,\[\`${o}-center\`\]:e.center}\]);return{prefixCls:o,cls:a,visible:r,handleClose:s,handleAfterLeave:i} ``` -------------------------------- ### Get originating tool snapshot Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Returns the originating tool snapshot with the tool name from host context or configured name, and the latest arguments and result. ```javascript getOriginatingToolSnapshot(){return{name:this.app.getHostContext()?.toolInfo?.tool.name??this.configuredOriginatingToolName,arguments:this.latestArguments,result:this.latestResult}} ``` -------------------------------- ### 卸载旧版 tonghuasun-agent 插件 Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/claude-code/README.md 在 Claude Code 中依次执行这些命令以卸载旧版 tonghuasun-agent 插件并移除旧市场。如果第一条命令提示找不到默认范围中的插件,请运行 /plugin 进入 Installed 页手动卸载。 ```text /plugin uninstall tonghuasun-agent@tonghuasun-agent /plugin marketplace remove tonghuasun-agent /reload-plugins ``` -------------------------------- ### Vue.js watch option setup function bv Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Minified Vue.js function that sets up watchers for the watch option, handling different forms of watch sources. ```javascript function bv(e,t,n,o){let s=o.includes(".")?rv(n,o):()=>n[o];if(ot(e)){const r=t[e];Oe(r)&&Be(s,r)}else if(Oe(e))Be(s,e.bind(n));else if(We(e))if(ke(e))e.forEach(r=>bv(r,t,n,o));else{const r=Oe(e.handler)?e.handler.bind(n):t[e.handler];Oe(r)&&Be(s,r,e)}} ``` -------------------------------- ### Message transport with JSON-RPC parsing Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/login.html The p3 class handles message events from a parent window, parsing JSON-RPC messages. It ignores messages from unknown sources and logs errors for invalid messages. The start method adds a message listener, and send posts messages to the parent. ```javascript class p3{eventTarget;eventSource;messageListener;constructor(t=window.parent,n){this.eventTarget=t,this.eventSource=n,this.messageListener=o=>{if(n&&o.source!==this.eventSource){console.debug("Ignoring message from unknown source",o);return}let r=th.safeParse(o.data);r.success?(console.debug("Parsed message",r.data),this.onmessage?.(r.data)):o.data?.jsonrpc!=="2.0"?console.debug("Ignoring non-JSON-RPC message",r.error.message,o):(console.error("Failed to parse message",r.error.message,o),this.onerror?.(Error("Invalid JSON-RPC message received: "+r.error.message)))}}async start(){window.addEventListener("message",this.messageListener)}async send(t,n){t.method!==f3&&console.debug("Sending message",t),this.eventTarget.postMessage(t,"*")}async close(){window.removeEventListener("message",this.messageListener),this.onclose?.()}onclose;onerror;onmessage;sessionId;setProtocolVersion} ``` -------------------------------- ### Remove old tonghuasun-agent plugin Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/deepseek-harness/README.md Removes the old tonghuasun-agent plugin from the web profile, lists installed plugins to confirm removal, and starts the web interface. Do not load the old and new agents simultaneously. ```powershell dsh plugin --profile web remove tonghuasun-agent-deepseek-harness dsh plugin --profile web list dsh web ``` -------------------------------- ### M1: get component name Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Gets the component name from a function or object, preferring displayName and name properties. ```javascript function M1(e,t=!0){return Oe(e)?e.displayName||e.name:e.name||t&&e.__name} ``` -------------------------------- ### 启动开发服务器 Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/examples/trading-demo/README.md 在 examples\trading-demo 目录下安装依赖并启动开发服务器,然后访问 http://127.0.0.1:5173/。 ```powershell cd examples\trading-demo npm install npm run dev ``` -------------------------------- ### ui/initialize Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Initializes the UI app with app information, capabilities, and protocol version. ```APIDOC ## ui/initialize ### Description Initializes the UI app with app information, capabilities, and protocol version. ### Method Notification ### Parameters - **appInfo** (object) - Required - App identification (name and version). - **appCapabilities** (object) - Required - Features and capabilities this app provides. - **protocolVersion** (string) - Required - Protocol version this app supports. ``` -------------------------------- ### PowerShell 安装 FQGate 命令 Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/README.md 在 Windows 仓库根目录运行此命令,自动下载并安装 FQGate 主程序。使用已解压的插件安装包时,将脚本路径替换为 .\scripts\install-fqgate.ps1。 ```powershell powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\installer\runtime\install-fqgate.ps1 ``` -------------------------------- ### Get transform origin for placement Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/login.html Returns CSS transform-origin values for a placement. ```javascript C_=e=>{let t="0";["top","bottom"].includes(e)?t="50%":["left","lt","lb","tr","br"].includes(e)&&(t="100%");let n="0";return["left","right"].includes(e)?n="50%":["top","tl","tr","lb","rb"].includes(e)&&(n="100%"),`${t} ${n}`} ``` -------------------------------- ### Initialize MCP App with event listeners Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Initializes the MCP app with autoResize, strict, and allowUnsafeEval options. Sets up event listeners for tool input, tool result, and host context changes, subscribes to the OpenAI bridge, and defines teardown cleanup. ```javascript ju({name:t,version:n},{},{autoResize:!0,strict:!0,allowUnsafeEval:!1}),this.app.addEventListener("toolinput",({arguments:s})=>{this.acceptToolInput(SR(s)?s:{})}),this.app.addEventListener("toolresult",s=>{this.acceptToolResult(s)}),this.releaseOpenAiListener=this.openAiBridge.subscribe(s=>{this.acceptOpenAiSnapshot(s)}),this.acceptOpenAiSnapshot(this.openAiBridge.getSnapshot()),this.app.addEventListener("hostcontextchanged",s=>nf(s)),this.app.onteardown=async()=>(this.inputListeners.clear(),this.resultListeners.clear(),this.releaseOpenAiListener?.(),this.releaseOpenAiListener=void 0,{})} ``` -------------------------------- ### x1: create component instance Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Creates a component instance object with all its reactive state and lifecycle hooks. Initializes the instance context, root, and emit function. ```javascript const E1=_v();let P1=0;function x1(e,t,n){const o=e.type,s=(t?t.appContext:e.appContext)||E1,r={uid:P1++,vnode:e,type:o,parent:t,appContext:s,root:null,next:null,subTree:null,effect:null,update:null,job:null,scope:new tk(!0),render:null,proxy:null,exposed:null,exposeProxy:null,withProxy:null,provides:t?t.provides:Object.create(s.provides),ids:t?t.ids:["",0,0],accessCache:null,renderCache:[],components:null,directives:null,propsOptions:Ev(o,s),emitsOptions:Cv(o,s),emit:null,emitted:null,propsDefaults:Qe,inheritAttrs:o.inheritAttrs,ctx:Qe,data:Qe,props:Qe,attrs:Qe,slots:Qe,refs:Qe,setupState:Qe,setupContext:null,suspense:n,suspenseId:n?n.pendingId:0,asyncDep:null,asyncResolved:!1,isMounted:!1,isDeactivated:!1,bc:null,c:null,bm:null,m:null,bu:null,u:null,um:null,bum:null,da:null,a:null,rtg:null,rtc:null,ec:null,sp:null};return r.ctx={_:r},r.root=t?t.root:r,r.emit=c1.bind(null,r),e.ce&&e.ce(r),r} ``` -------------------------------- ### z1: attrs proxy getter Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Proxy handler for attrs that logs a get operation and returns the attribute value. ```javascript const z1={get(e,t){return Lt(e,"get",""),e[t]}}; ``` -------------------------------- ### Vue icon components and Alert component definition Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/login.html Minified JavaScript code defining Vue icon components (IconCheckCircleFill, IconExclamationCircleFill, IconCloseCircleFill) and an Alert component. It sets up SVG rendering with stroke properties, size/rotate handling, and component installation via `install` methods. The Alert component accepts props like `type`, `showIcon`, `closable`, `title`, `banner`, and `center`, and emits `close` and `afterClose` events. ```javascript e.size&&(i.fontSize=je(e.size)?`${e.size}px`:e.size),e.rotate&&(i.transform=`rotate(${e.rotate}deg)`),i});return{cls:o,innerStyle:r,onClick:i=>{t("click",i)}}}),O9=["stroke-width","stroke-linecap","stroke-linejoin"];function L9(e,t,n,o,r,s){return q(),le("svg",{viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg",stroke:"currentColor",class:te(e.cls),style:Ve(e.innerStyle),"stroke-width":e.strokeWidth,"stroke-linecap":e.strokeLinecap,"stroke-linejoin":e.strokeLinejoin,onClick:t[0]||(t[0]=(...i)=>e.onClick&&e.onClick(...i))},t[1]||(t[1]=[de("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M24 44c11.046 0 20-8.954 20-20S35.046 4 24 4 4 12.954 4 24s8.954 20 20 20Zm10.207-24.379a1 1 0 0 0 0-1.414l-1.414-1.414a1 1 0 0 0-1.414 0L22 26.172l-4.878-4.88a1 1 0 0 0-1.415 0l-1.414 1.415a1 1 0 0 0 0 1.414l7 7a1 1 0 0 0 1.414 0l11.5-11.5Z",fill:"currentColor",stroke:"none"},null,-1)]),14,O9)}var gl=Pe(P9,[["render",L9]]);const Ng=Object.assign(gl,{install:(e,t)=>{var n;const o=(n=t?.iconPrefix)!=null?n:"";e.component(o+gl.name,gl)}}),A9=fe({name:"IconExclamationCircleFill",props:{size:{type:[Number,String]},strokeWidth:{type:Number,default:4},strokeLinecap:{type:String,default:"butt",validator:e=>["butt","round","square"].includes(e)},strokeLinejoin:{type:String,default:"miter",validator:e=>["arcs","bevel","miter","miter-clip","round"].includes(e)},rotate:Number,spin:Boolean},emits:{click:e=>!0},setup(e,{emit:t}){const n=_e("icon"),o=w(()=>[n,`${n}-exclamation-circle-fill`,{[`${n}-spin`]:e.spin}]),r=w(()=>{const i={};return e.size&&(i.fontSize=je(e.size)?`${e.size}px`:e.size),e.rotate&&(i.transform=`rotate(${e.rotate}deg)`),i});return{cls:o,innerStyle:r,onClick:i=>{t("click",i)}}}),z9=["stroke-width","stroke-linecap","stroke-linejoin"];function M9(e,t,n,o,r,s){return q(),le("svg",{viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg",stroke:"currentColor",class:te(e.cls),style:Ve(e.innerStyle),"stroke-width":e.strokeWidth,"stroke-linecap":e.strokeLinecap,"stroke-linejoin":e.strokeLinejoin,onClick:t[0]||(t[0]=(...i)=>e.onClick&&e.onClick(...i))},t[1]||(t[1]=[de("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M24 44c11.046 0 20-8.954 20-20S35.046 4 24 4 4 12.954 4 24s8.954 20 20 20Zm-2-11a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v2Zm4-18a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V15Z",fill:"currentColor",stroke:"none"},null,-1)]),14,z9)}var vl=Pe(A9,[["render",M9]]);const qg=Object.assign(vl,{install:(e,t)=>{var n;const o=(n=t?.iconPrefix)!=null?n:"";e.component(o+vl.name,vl)}}),I9=fe({name:"IconCloseCircleFill",props:{size:{type:[Number,String]},strokeWidth:{type:Number,default:4},strokeLinecap:{type:String,default:"butt",validator:e=>["butt","round","square"].includes(e)},strokeLinejoin:{type:String,default:"miter",validator:e=>["arcs","bevel","miter","miter-clip","round"].includes(e)},rotate:Number,spin:Boolean},emits:{click:e=>!0},setup(e,{emit:t}){const n=_e("icon"),o=w(()=>[n,`${n}-close-circle-fill`,{[`${n}-spin`]:e.spin}]),r=w(()=>{const i={};return e.size&&(i.fontSize=je(e.size)?`${e.size}px`:e.size),e.rotate&&(i.transform=`rotate(${e.rotate}deg)`),i});return{cls:o,innerStyle:r,onClick:i=>{t("click",i)}}}),N9=["stroke-width","stroke-linecap","stroke-linejoin"];function q9(e,t,n,o,r,s){return q(),le("svg",{viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg",stroke:"currentColor",class:te(e.cls),style:Ve(e.innerStyle),"stroke-width":e.strokeWidth,"stroke-linecap":e.strokeLinecap,"stroke-linejoin":e.strokeLinejoin,onClick:t[0]||(t[0]=(...i)=>e.onClick&&e.onClick(...i))},t[1]||(t[1]=[de("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M24 44c11.046 0 20-8.954 20-20S35.046 4 24 4 4 12.954 4 24s8.954 20 20 20Zm4.955-27.771-4.95 4.95-4.95-4.95a1 1 0 0 0-1.414 0l-1.414 1.414a1 1 0 0 0 0 1.414l4.95 4.95-4.95 4.95a1 1 0 0 0 0 1.414l1.414 1.414a1 1 0 0 0 1.414 0l4.95-4.95 4.95 4.95a1 1 0 0 0 1.414 0l1.414-1.414a1 1 0 0 0 0-1.414l-4.95-4.95 4.95-4.95a1 1 0 0 0 0-1.414l-1.414-1.414a1 1 0 0 0-1.414 0Z",fill:"currentColor",stroke:"none"},null,-1)]),14,N9)}var yl=Pe(I9,[["render",q9]]);const jg=Object.assign(yl,{install:(e,t)=>{var n;const o=(n=t?.iconPrefix)!=null?n:"";e.component(o+yl.name,yl)}}),j9=fe({name:"Alert",components:{IconHover:Qn,IconClose:ji,IconInfoCircleFill:$9,IconCheckCircleFill:Ng,IconExclamationCircleFill:qg,IconCloseCircleFill:jg},props:{type:{type:String,default:"info"},showIcon:{type:Boolean,default:!0},closable:{type:Boolean,default:!1},title:String,banner:{type:Boolean,default:!1},center:{type:Boolean,default:!1}},emits:{close:e=>!0,afterClose:()=>!0},setup(e,{slots:t,emit:n}){const ``` -------------------------------- ### 正式发布:生成稳定通道指针、版本清单、页面和签名 Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/ui-apps/README.md 需要提供 Ed25519 私钥,可通过 --signing-key-file 参数或 FQGATE_MCP_APPS_ED25519_PRIVATE_KEY 环境变量提供。未提供私钥时命令必须失败,不会生成未签名的正式包。私钥不得放进项目目录或提交到仓库。 ```powershell npm run release:mcp-apps -- --signing-key-file D:\安全目录\mcp-apps-private.pem ``` -------------------------------- ### 构建 MCP Apps 独立界面资源 Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/ui-apps/README.md 生成供 FQGate 返回的独立界面资源和开发清单,产物位于 dist/mcp-apps/,包括 manifest.json 和自包含 HTML 文件。 ```powershell npm run build:mcp-apps ``` -------------------------------- ### 开发发布:构建并发布到 FQGate 开发目录 Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/ui-apps/README.md 首次运行会检查类型、构建全部页面,并发布到 FQGate/target/debug/mcp-apps/;之后监听 src/ 和 mcp-apps/,修改后自动重新构建、校验并发布。可通过 FQGATE_DEV_MCP_APPS_DIR 指定其他开发目录。 ```powershell npm run dev:publish ``` -------------------------------- ### 测试 MCP Apps 资源完整性 Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/ui-apps/README.md 检查首屏工具结果不会重复请求,并验证五个资源均为完整的自包含文件。 ```powershell npm run test:mcp-apps ``` -------------------------------- ### Zod lazy schema definition with lazy inner type Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Defines the $ZodLazy schema type. It lazily gets the inner type and delegates parsing to it. ```javascript const Qy=F("$ZodLazy",(e,t)=>{et.init(e,t),He(e._zod,"innerType",()=>t.getter()),He(e._zod,"pattern",()=>e._zod.innerType?._zod?.pattern),He(e._zod,"propValues",()=>e._zod.innerType?._zod?.propValues),He(e._zod,"optin",()=>e._zod.innerType?._zod?.optin??void 0),He(e._zod,"optout",()=>e._zod.innerType?._zod?.optout??void 0),e._zod.parse=(n,o)=>{const s=e._zod.innerType._zod.run(n,o);return s instanceof Promise?s.then(r=>{n.value=r.value;return n}):(n.value=s.value,n)}}); ``` -------------------------------- ### Get element bounding rect with scroll offsets Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/login.html Calculates the bounding rectangle of an element relative to a container, including scroll offsets and fallback dimensions. ```javascript r=e.getBoundingClientRect();return{top:r.top,bottom:r.bottom,left:r.left,right:r.right,scrollTop:r.top-t.top,scrollBottom:r.bottom-t.top,scrollLeft:r.left-t.left,scrollRight:r.right-t.left,width:(n=e.offsetWidth)!=null?n:e.clientWidth,height:(o=e.offsetHeight)!=null?o:e.clientHeight} ``` -------------------------------- ### Apply host context styles Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Applies host context theme, style variables, and CSS fonts to the app. ```javascript function nf(e){e?.theme&&uR(e.theme),e?.styles?.variables&&dR(e.styles.variables),e?.styles?.css?.fonts&&fR(e.styles.css.fonts)} ``` -------------------------------- ### Ha: get public proxy Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Returns the public proxy for a component, either the expose proxy or the regular proxy. The expose proxy only exposes declared properties. ```javascript function Ha(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Qg(Ck(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in yr)return yr[n](e)},has(t,n){return n in t||n in yr}})):e.proxy} ``` -------------------------------- ### 运行评测检查 (npm test) Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/docs/AI工具调用路由评测.md 在仓库根目录执行此命令,检查用例数量和格式、九类场景覆盖、技能和工具引用、五个界面入口,以及登录与交易的重要安全要求。整个过程只读取仓库文件,不连接网络,不调用 AI 服务,也不会访问真实账户。 ```powershell npm test ``` -------------------------------- ### 卸载豆包技能 Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/doubao/README.md 运行此命令卸载豆包技能,但不会删除共享 FQGate 配置或程序。 ```powershell .\setup.ps1 -Uninstall ``` -------------------------------- ### Initialize Zod to JSON Schema conversion context Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Defines helper functions K_ and Ai that initialize a conversion context and run processors for Zod to JSON Schema conversion. ```javascript const K_=(e,t={})=>n=>{const o=zi({...n,processors:t});return it(e,o),Ni(o,e),Mi(o,e)},Ai=(e,t)=>n=>{const{libraryOptions:o,target:s}=n??{},r=zi({...o??{},target:s,io:t,processors:{}});return it(e,r),Ni(r,e),Mi(r,e)} ``` -------------------------------- ### ZodString class definition with format validators Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Defines the ZodString class with format-specific validation methods for email, URL, JWT, UUID, GUID, cuid, ulid, base64, IP addresses, CIDR, E.164, datetime, date, time, and duration. ```javascript P0=F("ZodString",(e,t)=>{eu.init(e,t),ch.init(e,t),e.email=n=>e.check(xp(uh,n)),e.url=n=>e.check(Op(dh,n)),e.jwt=n=>e.check(_(U0,n)),e.emoji=n=>e.check(a_(O0,n)),e.guid=n=>e.check(xd(Md,n)),e.uuid=n=>e.check(o_(ui,n)),e.uuidv4=n=>e.check(s_(ui,n)),e.uuidv6=n=>e.check(r_(ui,n)),e.uuidv7=n=>e.check(i_(ui,n)),e.nanoid=n=>e.check(l_(I0,n)),e.guid=n=>e.check(xd(Md,n)),e.cuid=n=>e.check(c_(z0,n)),e.cuid2=n=>e.check(u_(N0,n)),e.ulid=n=>e.check(d_(M0,n)),e.base64=n=>e.check(S_(D0,n)),e.base64url=n=>e.check(b_(V0,n)),e.xid=n=>e.check(f_(A0,n)),e.ksuid=n=>e.check(p_(L0,n)),e.ipv4=n=>e.check(h_(q0,n)),e.ipv6=n=>e.check(m_(j0,n)),e.cidrv4=n=>e.check(g_(B0,n)),e.cidrv6=n=>e.check(v_(F0,n)),e.e164=n=>e.check(y_(H0,n)),e.datetime=n=>e.check(jr(n)),e.date=n=>e.check(ah(n)),e.time=n=>e.check(h0(n)),e.duration=n=>e.check(g0(n))}) ``` -------------------------------- ### agent-plugin repository directory structure Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/docs/架构设计.md Directory layout of the public agent-plugin repository. The installer/runtime directory holds cross-host configuration and launch scripts; skills contains public responsibility-type skills; fqgate holds compatibility and release metadata; sdk/python is an optional public interface client; scripts contains build and release checks; docs/legal holds legal, license, and privacy notes; update holds the agent update manifest. ```text agent-plugin/ AI-plugins/ 八个宿主入口 installer/runtime/ 跨宿主配置与启动脚本 skills/ 公共职责型技能 fqgate/ 兼容与发行元数据 sdk/python/ 可选公开接口客户端 scripts/ 构建与发行检查 docs/legal/ 法律、许可与隐私说明 update/ Agent 更新清单 ``` -------------------------------- ### IconSearch component with SVG render Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Vue component definition for an IconSearch SVG icon with props for size, strokeWidth, strokeLinecap, strokeLinejoin, rotate, and spin. Includes a render function that outputs an SVG path for a search icon and an install method for plugin registration. ```javascript const CE=ue({name:"IconSearch",props:{size:{type:[Number,String]},strokeWidth:{type:Number,default:4},strokeLinecap:{type:String,default:"butt",validator:e=>["butt","round","square"].includes(e)},strokeLinejoin:{type:String,default:"miter",validator:e=>["arcs","bevel","miter","miter-clip","round"].includes(e)},rotate:Number,spin:Boolean},emits:{click:e=>!0},setup(e,{emit:t}){const n=me("icon"),o=C(()=>[n,`${n}-search`,{[`${n}-spin`]:e.spin}]),s=C(()=>{const i={};return e.size&&(i.fontSize=Ie(e.size)?`${e.size}px`:e.size),e.rotate&&(i.transform=`rotate(${e.rotate}deg)`),i});return{cls:o,innerStyle:s,onClick:i=>{t("click",i)}}}}),wE=["stroke-width","stroke-linecap","stroke-linejoin"];function $E(e,t,n,o,s,r){return W(),pe("svg",{viewBox:"0 0 48 48",fill:"none",xmlns:"http://www.w3.org/2000/svg",stroke:"currentColor",class:ie(e.cls),style:Ue(e.innerStyle),"stroke-width":e.strokeWidth,"stroke-linecap":e.strokeLinecap,"stroke-linejoin":e.strokeLinejoin,onClick:t[0]||(t[0]=(...i)=>e.onClick&&e.onClick(...i))},t[1]||(t[1]=[Te("path",{d:"M33.072 33.071c6.248-6.248 6.248-16.379 0-22.627-6.249-6.249-16.38-6.249-22.628 0-6.248 6.248-6.248 16.379 0 22.627 6.248 6.248 16.38 6.248 22.628 0Zm0 0 8.485 8.485"},null,-1)]),14,wE)}var kl=Pe(CE,[["render",$E]]);const Vc=Object.assign(kl,{install:(e,t)=>{var n;const ``` -------------------------------- ### Look up tool name from method and path Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Constructs the method and path key and looks up the corresponding tool name from the mapping. ```javascript function CR(e,t){const n=`${e.toUpperCase()} ${t}`;return bR[n]} ``` -------------------------------- ### Zod Type Definition and Run Function Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/login.html Registers the $ZodType check. Initializes the definition, bag, and version. Gets all checks, attaches, and defines a run function that executes checks sequentially, supports async, and handles forward/backward direction. The run function also handles deferred execution. ```javascript Ge=M("$ZodType",(e,t)=>{var n;e??(e={}),e.\_zod.def=t,e.\_zod.bag=e.\_zod.bag||{},e.\_zod.version=Tv;const o=\[...e.\_zod.def.checks??\[\]\];e.\_zod.traits.has("$ZodCheck")&&o.unshift(e);for(const r of o)for(const s of r.\_zod.onattach)s(e);if(o.length===0)(n=e.\_zod).deferred??(n.deferred=\[]),e.\_zod.deferred?.push(()=>{e.\_zod.run=e.\_zod.parse});else{const r=(i,a,l)=>{let u=Zo(i),f;for(const p of a){if(p.\_zod.def.when){if(!p.\_zod.def.when(i))continue}else if(u)continue;const m=i.issues.length,b=p.\_zod.check(i);if(b instanceof Promise&&l?.async===!1)throw new Uo;if(f||b instanceof Promise)f=(f??Promise.resolve()).then(async()=>{await b,i.issues.length!==m&&(u||(u=Zo(i,m)))});else{if(i.issues.length===m)continue;u||(u=Zo(i,m))}}return f?f.then(()=>i):i},s=(i,a,l)=>{if(Zo(i))return i.aborted=!0,i;const u=r(a,o,l);if(u instanceof Promise){if(l.async===!1)throw new Uo;return u.then(f=>e.\_zod.parse(f,l))}return e.\_zod.parse(u,l)};e.\_zod.run=(i,a)=>{if(a.skipChecks)return e.\_zod.parse(i,a);if(a.direction==="backward"){const u=e.\_zod.parse({value:i.value,issues:\[\]},{...a,skipChecks:!0});return u instanceof ``` -------------------------------- ### 检查 fqgate-agent 插件入口 Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/openclaw/README.md 检查 fqgate-agent 插件的运行时信息,用于验证安装和连接。 ```powershell openclaw plugins inspect fqgate-agent --runtime --json ``` -------------------------------- ### 安装 FQGate 插件到 WorkBuddy Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/AI-plugins/workbuddy/README.md 在 WorkBuddy 终端执行两条命令,将发行包作为插件市场添加并安装 fqgate-agent。发行包本身就是正式插件市场,无需创建本机验收市场。 ```powershell codebuddy plugin marketplace add .\fqgate-agent-workbuddy-1.0.0.zip --name fqgate-official codebuddy plugin install fqgate-agent@fqgate-official ``` -------------------------------- ### Input component logic with maxLength and events Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/fqgate/mcp-apps/releases/0.1.2/information.html Vue component setup for an input field with maxLength, word limit, clear button, and composition handling. It manages value updates, emits events like 'update:modelValue', 'change', 'focus', 'blur', 'input', 'clear', and 'pressEnter'. Includes rendering logic for prefix/suffix slots and error states. ```javascript k=E.value;Be(a,m=>{(mn(m)||Ua(m))&&(T.value="")}),Be(E,(m,b)=>{k=b});const q=Z(!1),w=C(()=>e.allowClear&&!e.readonly&&!f.value&&!!E.value),$=Z(!1),D=Z(""),M=m=>{var b;return Nn(e.wordLength)?e.wordLength(m):(b=m.length)!=null?b:0},U=C(()=>M(E.value)),V=C(()=>p.value||!!(Xe(e.maxLength)&&e.maxLength.errorOnly&&U.value>X.value)),j=C(()=>Xe(e.maxLength)&&!!e.maxLength.errorOnly),X=C(()=>Xe(e.maxLength)?e.maxLength.length:e.maxLength),Y=C(()=>{const m=M("a");return Math.floor(X.value/m)}),se=m=>{var b,x;X.value&&!j.value&&M(m)>X.value&&(m=(x=(b=e.wordSlice)==null?void 0:b.call(e,m,X.value))!=null?x:m.slice(0,Y.value)),T.value=m,t("update:modelValue",m)},ne=m=>{c.value&&m.target!==c.value&&(m.preventDefault(),c.value.focus())},ee=(m,b)=>{var x,z;m!==k&&(k=m,t("change",m,b),(z=(x=y.value)==null?void 0:x.onChange)==null||z.call(x,b))},oe=m=>{var b,x;q.value=!0,t("focus",m),(x=(b=y.value)==null?void 0:b.onFocus)==null||x.call(b,m)},$e=m=>{var b,x;q.value=!1,ee(E.value,m),t("blur",m),(x=(b=y.value)==null?void 0:b.onBlur)==null||x.call(b,m)},Me=m=>{var b,x,z;const{value:L,selectionStart:Q,selectionEnd:te}=m.target;if(m.type==="compositionend"){if($.value=!1,D.value="",X.value&&!j.value&&U.value>=X.value&&M(L)>X.value&&Q===te){H();return}se(L),t("input",L,m),(x=(b=y.value)==null?void 0:b.onInput)==null||x.call(b,m),H()}else $.value=!0,D.value=E.value+((z=m.data)!=null?z:"")},H=()=>{P(),Jt(()=>{c.value&&E.value!==c.value.value&&(c.value.value=E.value,N())})},fe=m=>{var b,x;const{value:z}=m.target;if(!$.value){if(X.value&&!j.value&&U.value>=X.value&&M(z)>X.value&&m.inputType==="insertText"){H();return}se(z),t("input",z,m),(x=(b=y.value)==null?void 0:b.onInput)==null||x.call(b,m),H()}},be=m=>{se(""),ee("",m),t("clear",m)},Le=m=>{const b=m.key||m.code;!$.value&&b===dd.key&&(ee(E.value,m),t("pressEnter",m))},Ce=C(()=>[`${l}-outer`,`${l}-outer-size-${_.value}`,{[`${l}-outer-has-suffix`]:!!n.suffix,[`${l}-outer-disabled`]:f.value}]),Ee=C(()=>[`${l}-wrapper`,{[`${l}-error`]:V.value,[`${l}-disabled`]:f.value,[`${l}-focus`]:q.value}]),rt=C(()=>[l,`${l}-size-${_.value}`]),Je=C(()=>xo(o,bs)),at=C(()=>Ka(o,bs)),dt=C(()=>{const m={...at.value,...e.inputAttrs};return V.value&&(m["aria-invalid"]=!0),m}),gt=m=>{var b;return R("span",Fe({class:Ee.value,onMousedown:ne},m?void 0:Je.value),[n.prefix&&R("span",{class:`${l}-prefix`},[n.prefix()]),R("input",Fe({ref:c,class:rt.value,value:E.value,type:e.type,placeholder:e.placeholder,readonly:e.readonly,disabled:f.value,onInput:fe,onKeydown:Le,onFocus:oe,onBlur:$e,onCompositionstart:Me,onCompositionupdate:Me,onCompositionend:Me},dt.value),null),w.value&&R(to,{prefix:l,class:`${l}-clear-btn`,onClick:be},{default:()=>[R(Ja,null,null)]}),(n.suffix||!!e.maxLength&&e.showWordLimit||!!v.value)&&R("span",{class:[`${l}-suffix`,{[`${l}-suffix-has-feedback`]:v.value}]},[!!e.maxLength&&e.showWordLimit&&R("span",{class:`${l}-word-limit`},[U.value,Et("/"),X.value]),(b=n.suffix)==null?void 0:b.call(n),!!v.value&&R(ud,{type:v.value},null)])])};return{inputRef:c,render:()=>n.prepend||n.append||e.prepend||e.append?R("span",Fe({class:Ce.value},Je.value),[(n.prepend||e.prepend)&&R("span",{class:`${l}-prepend`},[n.prepend?n.prepend():e.prepend]),gt(!0),(n.append||e.append)&&R("span",{class:`${l}-append`},[n.append?n.append():e.append])]):gt()}},methods:{focus(){var e;(e=this.inputRef)==null||e.focus()},blur(){var e;(e=this.inputRef)==null||e.blur()}},render(){return this.render()}}); ``` -------------------------------- ### 运行测试和构建 Source: https://github.com/zhuyifang/tonghuasun-agent/blob/main/examples/trading-demo/README.md 运行测试和构建命令,用于验证项目。 ```powershell npm test npm run build ```