@jokeran/frontend-code-skimmer 0.1.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +67 -66
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ npm run build
|
|
|
60
60
|
### 多项目工作流
|
|
61
61
|
|
|
62
62
|
```
|
|
63
|
-
|
|
63
|
+
优先从编辑器工作区、已打开文件和当前上下文自动推断项目根目录绝对路径,填入 `project_path`(无需向用户追问)。
|
|
64
64
|
|
|
65
65
|
项目 A: skimmer_index_project({ project_path: "/work/project-a" })
|
|
66
66
|
项目 B: skimmer_index_project({ project_path: "/work/project-b" })
|
package/dist/index.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import D from'path';import'url';import Rt from'crypto';import {createRequire}from'module';import W from'fs';import Jt from'fast-glob';import {McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import vt from'os';import Tt from'better-sqlite3';import {z as z$1}from'zod';var At=Object.defineProperty;var U=(p,e)=>()=>(p&&(e=p(p=0)),e);var St=(p,e)=>{for(var t in e)At(p,t,{get:e[t],enumerable:true});};var S=U(()=>{});function _(p){return p.replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2").replace(/([a-z\d])([A-Z])/g,"$1 $2").replace(/_/g," ").replace(/-/g," ").toLowerCase().trim().replace(/\s+/g," ")}function ue(p,e){let t=p.length,
|
|
2
|
+
import D from'path';import'url';import Rt from'crypto';import {createRequire}from'module';import W from'fs';import Jt from'fast-glob';import {McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import vt from'os';import Tt from'better-sqlite3';import {z as z$1}from'zod';var At=Object.defineProperty;var U=(p,e)=>()=>(p&&(e=p(p=0)),e);var St=(p,e)=>{for(var t in e)At(p,t,{get:e[t],enumerable:true});};var S=U(()=>{});function _(p){return p.replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2").replace(/([a-z\d])([A-Z])/g,"$1 $2").replace(/_/g," ").replace(/-/g," ").toLowerCase().trim().replace(/\s+/g," ")}function ue(p,e){let t=p.length,r=e.length,n=Array.from({length:t+1},(s,o)=>Array.from({length:r+1},(i,c)=>o===0?c:c===0?o:0));for(let s=1;s<=t;s++)for(let o=1;o<=r;o++)p[s-1]===e[o-1]?n[s][o]=n[s-1][o-1]:n[s][o]=1+Math.min(n[s-1][o],n[s][o-1],n[s-1][o-1]);return n[t][r]}function Ke(p){return Rt.createHash("md5").update(p).digest("hex")}function Xe(p){if(!p)return 0;let e=1;for(let t=0;t<p.length;t++)p[t]===`
|
|
3
3
|
`&&e++;return e}function Z(p,e){return p===e?`L${p}`:`L${p}-L${e}`}function fe(p,e){return D.relative(e,p).replace(/\\/g,"/")}function te(p,e){if(!p)return e;try{return JSON.parse(p)}catch{return e}}function M(p,e){let t=p.split(`
|
|
4
|
-
`),
|
|
5
|
-
`),a;try{a=ot("@babel/parser").parse(o,{sourceType:"module",plugins:["jsx","typescript","decorators-legacy"],errorRecovery:!0});}catch(u){return
|
|
6
|
-
`&&
|
|
7
|
-
`),i=null;j(e,d=>{if(d.type==="ExportDefaultDeclaration"){let l=d.declaration;if(l?.type==="ObjectExpression")i=l;else if(l?.type==="CallExpression"){let f=l.arguments;f&&f.length>0&&f[0].type==="ObjectExpression"&&(i=f[0]);}else if(l?.type==="Identifier"){let f=l.name;j(e,g=>{if(g.type==="VariableDeclarator"&&g.id?.name===f){if(g.init?.type==="ObjectExpression")i=g.init;else if(g.init?.type==="CallExpression"){let m=g.init.arguments;m&&m.length>0&&m[0].type==="ObjectExpression"&&(i=m[0]);}}});}}});let a=false;if(!i&&(j(e,d=>{d.type==="ExportDefaultDeclaration"&&d.declaration?.type==="ClassDeclaration"&&(a=true,this.extractFromClassComponent(d.declaration,t,n,
|
|
8
|
-
`),m),b=s.symbols.length;s.symbols.push({name:l,category:"lifecycle",framework:"vue2",startLine:m,endLine:h,jsdoc:E,camelWords:_(l)});let R=F(f,l);s.behaviors.push(...R);let x=be(f,l);for(let $ of x){if($.args){let C=String($.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");s.symbols[b].camelWords+=` ${_(C)} ${C}`;}s.relations.push({callerName:l,callerLine:m,calleeName:$.calleeName,callType:"this_method",line:g($.line),args:$.args});}}break}}}extractData(e,t,n
|
|
9
|
-
`),u),f=this.extractParams(a),g=a.async===true,m=f?`${c}(${f.join(", ")})`:c;if(o.symbols.push({name:c,category:t,framework:"vue2",startLine:u,endLine:d,signature:m,params:f,isAsync:g,jsdoc:l,camelWords:_(c)}),t==="method"&&a){let h=F(a,c);o.behaviors.push(...h);let E=be(a,c);for(let b of E){if(b.args){let R=String(b.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");o.symbols[o.symbols.length-1].camelWords+=` ${_(R)} ${R}`;}o.relations.push({callerName:c,callerLine:u,calleeName:b.calleeName,callType:"this_method",line:
|
|
10
|
-
`),u);if(c.type==="ClassMethod"){let g=Te.includes(a)?"lifecycle":"method",m=this.extractParams(c),h=c.async===true,E=m?`${a}(${m.join(", ")})`:a;s.symbols.push({name:a,category:g,framework:"vue2",startLine:u,endLine:d,signature:E,params:m,isAsync:h,jsdoc:l,camelWords:_(a)});let b=F(c,a);s.behaviors.push(...b);let R=be(c,a);for(let x of R){if(x.args){let $=String(x.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");s.symbols[s.symbols.length-1].camelWords+=` ${_($)} ${$}`;}s.relations.push({callerName:a,callerLine:u,calleeName:x.calleeName,callType:"this_method",line:o(x.line),args:x.args});}}else if(c.type==="ClassProperty"){let f=(c.decorators||[]).some(m=>m.expression?.callee?.name==="Prop"),g=this.getLiteralValue(c.value);s.symbols.push({name:a,category:f?"prop":"state",framework:"vue2",startLine:u,endLine:d,defaultValue:g,camelWords:_(a)});}}}};});var Pe,_e,at=U(()=>{S();H();Ee();B();Pe=createRequire(import.meta.url),_e=class{name="Vue3Parser";canParse(e,t){return e.endsWith(".vue")?t.includes("<script setup")||t.includes("defineProps")||t.includes("defineEmits")||t.includes("from 'vue'")||t.includes('from "vue"'):false}parse(e,t){let
|
|
11
|
-
`),i=!!s.scriptSetup,c=!!s.script;if(i){let a=s.scriptSetup,u=a.loc.start.line;this.parseSetupContent(a.content,u,o,
|
|
12
|
-
`),c=s.program.body;for(let a of c||[])this.processTopLevelStatement(a,o,
|
|
13
|
-
`),c=false;j(s.program,a=>{if(a.type==="ExportDefaultDeclaration"&&a.declaration?.type==="ObjectExpression"){let u=a.declaration.properties?.find(d=>this.getPropKey(d)==="setup");if(u){c=true;let d=u.type==="ObjectMethod"?u:u.value;if(!d)return;let l=d.body;if(l?.type==="BlockStatement"){let f=l.body;for(let g of f||[])this.processTopLevelStatement(g,o,
|
|
14
|
-
`),t(c)),d=this.extractParams(e),l=$e.includes(i);if(s.symbols.push({name:i,category:l?"lifecycle":z(i)?"hook":"method",framework:"vue3",startLine:t(c),endLine:t(a),signature:`${i}(${(d||[]).join(", ")})`,params:d,isAsync:e.async===true,jsdoc:u,camelWords:_(i)}),e.body){let f=F(e.body,i);s.behaviors.push(...f);}}if(e.type==="ExpressionStatement"&&e.expression?.type==="CallExpression"){let c=e.expression.callee;if(c?.type==="Identifier"){let a=c.name;if(["defineProps","defineEmits","defineExpose"].includes(a)){let{start:u,end:d}=o(e);s.symbols.push({name:a,category:a==="defineProps"?"prop":a==="defineEmits"?"emit":"export",framework:"vue3",startLine:t(u),endLine:t(d),camelWords:_(a)});}}}if(e.type==="ExpressionStatement"&&e.expression?.type==="CallExpression"){let i=e.expression,c=i.callee;if(c?.type==="Identifier"){let a=c.name;if($e.includes(a)){let{start:u,end:d}=o(e);s.symbols.push({name:a,category:"lifecycle",framework:"vue3",startLine:t(u),endLine:t(d),camelWords:_(a)});let l=i.arguments;if(l?.[0]){let f=F(l[0],a);s.behaviors.push(...f);}}}}}classifyVue3Declaration(e,t,n,
|
|
15
|
-
`),c);if(qe.includes(i)){let d=t.arguments,l=d?.[0]?this.getLiteralValue(d[0]):void 0;return {name:e,category:"state",framework:"vue3",startLine:c,endLine:a,defaultValue:l,jsdoc:u,camelWords:_(e)}}return Ye.includes(i)?{name:e,category:"computed",framework:"vue3",startLine:c,endLine:a,jsdoc:u,camelWords:_(e)}:Ze.includes(i)?{name:e,category:"effect",framework:"vue3",startLine:c,endLine:a,camelWords:_(e)}:i==="provide"||i==="inject"?{name:e,category:"provide",framework:"vue3",startLine:c,endLine:a,camelWords:_(e)}:z(i)?{name:e,category:"hook",framework:"vue3",startLine:c,endLine:a,jsdoc:u,camelWords:_(e)}:null}getPropKey(e){let t=e?.key;return t?t.type==="Identifier"?t.name:t.type==="Literal"?String(t.value):null:null}extractParams(e){let t=e.params;if(t)return t.map(
|
|
16
|
-
`);this.extractFromAST(s.program?s.program:s,o,
|
|
17
|
-
`),o),d=this.extractParams(e);
|
|
18
|
-
`),i),u=this.extractParams(e);if(
|
|
19
|
-
`),l),m=this.extractParams(i);if(
|
|
4
|
+
`),n=e-1-1;for(;n>=0&&t[n].trim()==="";)n--;if(n<0||!t[n].trim().endsWith("*/"))return;let s=n;for(;s>0&&!t[s].trim().startsWith("/**");)s--;if(t[s].trim().startsWith("/**"))return t.slice(s,n+1).map(o=>o.replace(/^\s*\*\s?/,"").replace(/\/\*\*/,"").replace(/\*\//,"").trim()).filter(o=>o.length>0).join(" ")}function ze(p,e){let t=p.toLowerCase(),r=e.toLowerCase();if(t===r)return 100;if(r.includes(t)||t.includes(r))return 85;let n=ue(t,r),s=Math.max(t.length,r.length);if(s===0)return 100;let o=Math.max(0,100-n/s*100);return Math.round(o)}function z(p){return p.startsWith("use")&&p.length>3&&/[A-Z]/.test(p[3])}function Je(p,e,t){if(t===0||t>3)return;let r=_(p).split(" "),n=_(e).split(" ");for(let s of r)for(let o of n){let i=ue(s,o);if(i>0&&i<=3&&s!==o)return `"${s}" \u53EF\u80FD\u662F "${o}" \u7684\u62FC\u5199\u9519\u8BEF (\u7F16\u8F91\u8DDD\u79BB=${i})`}}var B=U(()=>{S();});var Re,ke,Ge,Te,$e,qe,Ye,Ze,ve,we,Le,Qe,me,et,tt,rt,H=U(()=>{S();Re=["**/node_modules/**","**/dist/**","**/build/**","**/.git/**","**/coverage/**","**/.nuxt/**","**/.next/**","**/__tests__/**","**/*.test.*","**/*.spec.*","**/*.min.js"],ke=["**/*.vue","**/*.js","**/*.jsx","**/*.ts","**/*.tsx"],Ge={storage:{localStorage:["setItem","getItem","removeItem","clear","key"],sessionStorage:["setItem","getItem","removeItem","clear","key"],cookie:["cookie"]},network:{axios:["get","post","put","delete","patch","request","create"],fetch:["fetch"],XMLHttpRequest:["open","send"],$http:["get","post","put","delete"]},router:{$router:["push","replace","go","back","forward"],$route:[],useRouter:[],useRoute:[],navigate:[],history:["push","replace","go"]},vuex:{$store:["commit","dispatch","getters","state"],useStore:[],store:["commit","dispatch"]},dom:{document:["querySelector","getElementById","createElement","addEventListener"],window:["addEventListener","removeEventListener","open","close"],$refs:[],$nextTick:[],nextTick:[]},event:{$emit:[],EventBus:["emit","on","off"],dispatchEvent:[],emit:[]},timer:{setTimeout:[],setInterval:[],clearTimeout:[],clearInterval:[],requestAnimationFrame:[]},i18n:{$t:[],useI18n:[],t:[],i18n:["t","tc","te"]}},Te=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured"],$e=["onBeforeMount","onMounted","onBeforeUpdate","onUpdated","onBeforeUnmount","onUnmounted","onActivated","onDeactivated","onErrorCaptured","onRenderTracked","onRenderTriggered","onServerPrefetch"],qe=["ref","reactive","shallowRef","shallowReactive","readonly"],Ye=["computed"],Ze=["watch","watchEffect","watchPostEffect","watchSyncEffect"],ve=["useState","useReducer","useRef","useImperativeHandle"],we=["useMemo","useCallback"],Le=["useEffect","useLayoutEffect","useInsertionEffect"],Qe=["useContext","useDebugValue","useDeferredValue","useId","useSyncExternalStore","useTransition"],me=".skimmer-index.db",et=30,tt=4,rt=300;});function F(p,e,t){let r=[];return j(p,n=>{if(n.type==="CallExpression"){let o=wt(n,e);o&&r.push(o);}if(n.type==="MemberExpression"){let s=Lt(n);s&&r.push(s);}}),Ft(r)}function wt(p,e,t){let r=p.callee;if(!r)return null;let n=st(p);if(r.type==="MemberExpression"){let s=Ct(r);if(!s)return null;let{apiName:o,operation:i}=s,c=p.arguments,a=V(c?.[0]),u=It(o);return u?{symbolName:e,category:u,apiName:o,operation:i,detail:a,line:n}:o==="this"&&ye(i)?{symbolName:e,category:"network",apiName:`this.${i}`,operation:"wrapped_call",detail:a||V(c?.[1]),line:n}:nt(i)&&jt(c)?{symbolName:e,category:"network",apiName:o,operation:i,detail:a||V(c?.[1]),line:n}:ye(o)||ye(`${o}.${i}`)?{symbolName:e,category:"network",apiName:o,operation:nt(i)?i:"wrapped_call",detail:a||V(c?.[1]),line:n}:null}if(r.type==="Identifier"){let s=r.name,o=Pt(s),i=p.arguments,c=V(i?.[0]);return o?{symbolName:e,category:o.category,apiName:s,operation:o.operation,detail:c,line:n}:ye(s)?{symbolName:e,category:"network",apiName:s,operation:"wrapped_call",detail:c||V(i?.[1]),line:n}:null}return null}function Lt(p,e,t){let r=p.object,n=p.property;if(!r||!n||r.type!=="MemberExpression"&&r.type!=="ThisExpression"&&r.type!=="Identifier")return null;let s=Ot(r);if(!s)return null;n.type==="Identifier"?n.name:"";if(s==="this"||s===""){r.type==="MemberExpression"?r.property?.name:"";return null}return null}function Ct(p){let e=p.object,t=p.property;if(!e||!t||t.type!=="Identifier")return null;let r=t.name;if(e.type==="MemberExpression"){let n=e.property?.name;if(n)return {apiName:n,operation:r}}return e.type==="Identifier"?{apiName:e.name,operation:r}:e.type==="ThisExpression"?{apiName:"this",operation:r}:null}function Pt(p){let e={fetch:"network",setTimeout:"timer",setInterval:"timer",clearTimeout:"timer",clearInterval:"timer",requestAnimationFrame:"timer",navigate:"router"};return e[p]?{category:e[p],operation:p}:null}function st(p){return p.loc?.start?.line??0}function Ot(p){return p.type==="Identifier"?p.name:p.type==="ThisExpression"?"this":null}function It(p){if(p==="this")return null;for(let[e,t]of Object.entries(Ge))if(p in t)return e;return null}function V(p,e){if(p){if(p.type==="Literal"||p.type==="StringLiteral"||p.type==="NumericLiteral"||p.type==="BooleanLiteral")return String(p.value);if(p.type==="NullLiteral")return "null";if(p.type==="TemplateLiteral"){let r=p.quasis.map(n=>n.value?.cooked||"").filter(Boolean);return r.length>0?r.join("${...}"):void 0}if(p.type==="Identifier")return `[\u53D8\u91CF: ${p.name}]`;if(p.type==="ObjectExpression"){let t=p.properties||[],r=["url","uri","path","api","endpoint"];for(let n of t){let s=n.key,o=n.value;if(!s||!o)continue;let i=s.type==="Identifier"?String(s.name):s.type==="Literal"?String(s.value):"";if(!r.includes(i))continue;let c=V(o);if(c)return `${i}:${c}`}return "{...}"}}}function ye(p){return /request|api|http|fetch|ajax|akscommonhandle|commonhandle/i.test(p)}function nt(p){return ["get","post","put","delete","patch","request"].includes(p.toLowerCase())}function jt(p,e){if(!p||p.length===0)return false;for(let t of p.slice(0,2)){let r=V(t);if(r&&(/https?:\/\//i.test(r)||r.includes("/")||/gw\d?\/|\/m\/|\/api\//i.test(r)))return true}return false}function Ft(p){let e=new Set;return p.filter(t=>{let r=`${t.apiName}:${t.operation}:${t.line}`;return e.has(r)?false:(e.add(r),true)})}function be(p,e,t){let r=[];return j(p,n=>{if(n.type==="CallExpression"&&n.callee?.type==="MemberExpression"){let s=n.callee,o=s.object,i=s.property;if(o.type==="ThisExpression"&&i.type==="Identifier"){let c=i.name;if(!c.startsWith("$")&&c!==e){let a=n.arguments,u=Mt(a);r.push({calleeName:c,line:st(n),args:u});}}}}),r}function Mt(p,e){if(!p||p.length===0)return;let t=p.slice(0,3).map(r=>V(r)).filter(r=>!!r);return t.length>0?t.join(", "):void 0}function j(p,e){if(!(!p||typeof p!="object")){e(p);for(let t of Object.keys(p)){if(t==="type"||t==="loc"||t==="start"||t==="end")continue;let r=p[t];if(Array.isArray(r))for(let n of r)n&&typeof n=="object"&&n.type&&j(n,e);else r&&typeof r=="object"&&r.type&&j(r,e);}}}var Ee=U(()=>{S();H();});var ot,Ne,it=U(()=>{S();H();Ee();B();ot=createRequire(import.meta.url),Ne=class{name="Vue2Parser";canParse(e,t){return e.endsWith(".vue")}parse(e,t){let r={framework:"vue2",filePath:e,symbols:[],relations:[],behaviors:[],errors:[]};try{let s=ot("vue-template-compiler").parseComponent(t);if(!s.script?.content)return r;let o=s.script.content,i=this.getScriptStartLine(t,s.script.start),c=t.split(`
|
|
5
|
+
`),a;try{a=ot("@babel/parser").parse(o,{sourceType:"module",plugins:["jsx","typescript","decorators-legacy"],errorRecovery:!0});}catch(u){return r.errors?.push(`AST \u89E3\u6790\u5931\u8D25: ${String(u)}`),r}this.extractFromAST(a.program,o,c,i,r);}catch(n){r.errors?.push(`\u89E3\u6790\u5931\u8D25: ${String(n)}`);}return r}getScriptStartLine(e,t){let r=1;for(let n=0;n<t&&n<e.length;n++)e[n]===`
|
|
6
|
+
`&&r++;return r}extractFromAST(e,t,r,n,s){let o=t.split(`
|
|
7
|
+
`),i=null;j(e,d=>{if(d.type==="ExportDefaultDeclaration"){let l=d.declaration;if(l?.type==="ObjectExpression")i=l;else if(l?.type==="CallExpression"){let f=l.arguments;f&&f.length>0&&f[0].type==="ObjectExpression"&&(i=f[0]);}else if(l?.type==="Identifier"){let f=l.name;j(e,g=>{if(g.type==="VariableDeclarator"&&g.id?.name===f){if(g.init?.type==="ObjectExpression")i=g.init;else if(g.init?.type==="CallExpression"){let m=g.init.arguments;m&&m.length>0&&m[0].type==="ObjectExpression"&&(i=m[0]);}}});}}});let a=false;if(!i&&(j(e,d=>{d.type==="ExportDefaultDeclaration"&&d.declaration?.type==="ClassDeclaration"&&(a=true,this.extractFromClassComponent(d.declaration,t,r,n,s));}),!a)){let d=null,l=0,f=["data","methods","computed","props","watch","components","created","mounted","mixins"];j(e,g=>{if(g.type==="ObjectExpression"){let m=g.properties||[],h=0;for(let E of m){let b=this.getPropKey(E);b&&f.includes(b)&&h++;}h>l&&(l=h,d=g);}}),l>=2&&d&&(i=d);}if(!i)return;let u=i.properties;for(let d of u||[]){let l=this.getPropKey(d);if(!l)continue;let f=d.type==="ObjectMethod"?d:d.value;if(!f)continue;let g=m=>m+n-1;switch(l){case "name":f?.type==="Literal"&&(String(f.value));break;case "data":this.extractData(f,o,g,s);break;case "props":this.extractProps(f,o,g,s);break;case "computed":this.extractComputedOrMethods(f,"computed",o,g,r,s);break;case "methods":this.extractComputedOrMethods(f,"method",o,g,r,s);break;case "watch":this.extractWatch(f,o,g,s);break;case "filters":this.extractComputedOrMethods(f,"filter",o,g,r,s);break;case "components":this.extractComponents(f,s);break;case "mixins":this.extractMixins(f,s);break;default:if(Te.includes(l)){let m=g(this.getStartLine(d)),h=g(this.getEndLine(d)),E=M(r.join(`
|
|
8
|
+
`),m),b=s.symbols.length;s.symbols.push({name:l,category:"lifecycle",framework:"vue2",startLine:m,endLine:h,jsdoc:E,camelWords:_(l)});let R=F(f,l);s.behaviors.push(...R);let x=be(f,l);for(let $ of x){if($.args){let C=String($.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");s.symbols[b].camelWords+=` ${_(C)} ${C}`;}s.relations.push({callerName:l,callerLine:m,calleeName:$.calleeName,callType:"this_method",line:g($.line),args:$.args});}}break}}}extractData(e,t,r,n){let s=null;if(e.type==="FunctionExpression"||e.type==="ArrowFunctionExpression"||e.type==="ObjectMethod"?j(e.body,o=>{o.type==="ReturnStatement"&&o.argument?.type==="ObjectExpression"&&(s=o.argument);}):e.type==="ObjectExpression"&&(s=e),!!s)for(let o of s.properties){let i=this.getPropKey(o);if(!i)continue;let c=r(this.getStartLine(o)),a=r(this.getEndLine(o)),u=this.getLiteralValue(o.value);n.symbols.push({name:i,category:"state",framework:"vue2",startLine:c,endLine:a,defaultValue:u,camelWords:_(i)});}}extractProps(e,t,r,n){if(e.type==="ArrayExpression"){for(let s of e.elements||[])if(s?.type==="Literal"){let o=String(s.value);n.symbols.push({name:o,category:"prop",framework:"vue2",startLine:r(this.getStartLine(s)),endLine:r(this.getEndLine(s)),camelWords:_(o)});}}else if(e.type==="ObjectExpression")for(let s of e.properties||[]){let o=this.getPropKey(s);if(!o)continue;let i=r(this.getStartLine(s)),c=r(this.getEndLine(s)),a;if(s.value?.type==="ObjectExpression"){let u=s.value.properties?.find(d=>this.getPropKey(d)==="default");u&&(a=this.getLiteralValue(u.value));}n.symbols.push({name:o,category:"prop",framework:"vue2",startLine:i,endLine:c,defaultValue:a,camelWords:_(o)});}}extractComputedOrMethods(e,t,r,n,s,o){if(e.type==="ObjectExpression")for(let i of e.properties||[]){let c=this.getPropKey(i);if(!c)continue;let a=i.type==="ObjectMethod"?i:i.value;if(!a)continue;let u=n(this.getStartLine(i)),d=n(this.getEndLine(i)),l=M(s.join(`
|
|
9
|
+
`),u),f=this.extractParams(a),g=a.async===true,m=f?`${c}(${f.join(", ")})`:c;if(o.symbols.push({name:c,category:t,framework:"vue2",startLine:u,endLine:d,signature:m,params:f,isAsync:g,jsdoc:l,camelWords:_(c)}),t==="method"&&a){let h=F(a,c);o.behaviors.push(...h);let E=be(a,c);for(let b of E){if(b.args){let R=String(b.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");o.symbols[o.symbols.length-1].camelWords+=` ${_(R)} ${R}`;}o.relations.push({callerName:c,callerLine:u,calleeName:b.calleeName,callType:"this_method",line:n(b.line),args:b.args});}}}}extractWatch(e,t,r,n){if(e.type==="ObjectExpression")for(let s of e.properties||[]){let o=this.getPropKey(s);if(!o)continue;let i=r(this.getStartLine(s)),c=r(this.getEndLine(s));n.symbols.push({name:o,category:"effect",framework:"vue2",startLine:i,endLine:c,camelWords:_(o)});}}extractComponents(e,t){if(e.type==="ObjectExpression")for(let r of e.properties||[]){let n=this.getPropKey(r);n&&t.symbols.push({name:n,category:"component",framework:"vue2",startLine:this.getStartLine(r),endLine:this.getEndLine(r),camelWords:_(n)});}}extractMixins(e,t){if(e.type==="ArrayExpression")for(let r of e.elements||[]){let n=r?.type==="Identifier"?r.name:null;n&&t.symbols.push({name:n,category:"mixin",framework:"vue2",startLine:this.getStartLine(r),endLine:this.getEndLine(r),camelWords:_(n)});}}getPropKey(e){if(!e)return null;let t=e.key;return t?t.type==="Identifier"?t.name:t.type==="Literal"?String(t.value):null:null}getStartLine(e){return e?.loc?.start?.line??1}getEndLine(e){return e?.loc?.end?.line??1}extractParams(e){if(!e)return;let t=e.params;if(t)return t.map(r=>r.type==="Identifier"?r.name:r.type==="AssignmentPattern"?r.left?.name||"?":r.type==="RestElement"?`...${r.argument?.name||""}`:r.type==="TSParameterProperty"&&r.parameter?.name||"?")}getLiteralValue(e){if(e){if(e.type==="Literal"||e.type==="StringLiteral"||e.type==="NumericLiteral"||e.type==="BooleanLiteral")return String(e.value);if(e.type==="NullLiteral"||e.value===null)return "null";if(e.type==="ObjectExpression")return "{}";if(e.type==="ArrayExpression")return "[]";if(e.type==="Identifier"&&e.name==="undefined")return "undefined";if(e.type==="ArrowFunctionExpression"||e.type==="FunctionExpression"||e.type==="ObjectMethod")return "function"}}extractFromClassComponent(e,t,r,n,s){let o=c=>c+n-1,i=e.body;if(!(!i||i.type!=="ClassBody"))for(let c of i.body||[]){let a=this.getPropKey(c);if(!a)continue;let u=o(this.getStartLine(c)),d=o(this.getEndLine(c)),l=M(r.join(`
|
|
10
|
+
`),u);if(c.type==="ClassMethod"){let g=Te.includes(a)?"lifecycle":"method",m=this.extractParams(c),h=c.async===true,E=m?`${a}(${m.join(", ")})`:a;s.symbols.push({name:a,category:g,framework:"vue2",startLine:u,endLine:d,signature:E,params:m,isAsync:h,jsdoc:l,camelWords:_(a)});let b=F(c,a);s.behaviors.push(...b);let R=be(c,a);for(let x of R){if(x.args){let $=String(x.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");s.symbols[s.symbols.length-1].camelWords+=` ${_($)} ${$}`;}s.relations.push({callerName:a,callerLine:u,calleeName:x.calleeName,callType:"this_method",line:o(x.line),args:x.args});}}else if(c.type==="ClassProperty"){let f=(c.decorators||[]).some(m=>m.expression?.callee?.name==="Prop"),g=this.getLiteralValue(c.value);s.symbols.push({name:a,category:f?"prop":"state",framework:"vue2",startLine:u,endLine:d,defaultValue:g,camelWords:_(a)});}}}};});var Pe,_e,at=U(()=>{S();H();Ee();B();Pe=createRequire(import.meta.url),_e=class{name="Vue3Parser";canParse(e,t){return e.endsWith(".vue")?t.includes("<script setup")||t.includes("defineProps")||t.includes("defineEmits")||t.includes("from 'vue'")||t.includes('from "vue"'):false}parse(e,t){let r={framework:"vue3",filePath:e,symbols:[],relations:[],behaviors:[],errors:[]};try{let{parse:n}=Pe("@vue/compiler-sfc"),{descriptor:s}=n(t),o=t.split(`
|
|
11
|
+
`),i=!!s.scriptSetup,c=!!s.script;if(i){let a=s.scriptSetup,u=a.loc.start.line;this.parseSetupContent(a.content,u,o,r);}else if(c){let a=s.script,u=a.loc.start.line;this.parseScriptContent(a.content,u,o,r);}}catch(n){r.errors?.push(`Vue3 \u89E3\u6790\u5931\u8D25: ${String(n)}`);}return r}parseSetupContent(e,t,r,n){let s;try{s=Pe("@babel/parser").parse(e,{sourceType:"module",plugins:["typescript","jsx","decorators-legacy"],errorRecovery:!0});}catch(a){n.errors?.push(`AST \u89E3\u6790\u5931\u8D25: ${String(a)}`);return}let o=a=>a+t-1,i=e.split(`
|
|
12
|
+
`),c=s.program.body;for(let a of c||[])this.processTopLevelStatement(a,o,r,i,n);}parseScriptContent(e,t,r,n){let s;try{s=Pe("@babel/parser").parse(e,{sourceType:"module",plugins:["typescript","jsx","decorators-legacy"],errorRecovery:!0});}catch(a){n.errors?.push(`AST \u89E3\u6790\u5931\u8D25: ${String(a)}`);return}let o=a=>a+t-1,i=e.split(`
|
|
13
|
+
`),c=false;j(s.program,a=>{if(a.type==="ExportDefaultDeclaration"&&a.declaration?.type==="ObjectExpression"){let u=a.declaration.properties?.find(d=>this.getPropKey(d)==="setup");if(u){c=true;let d=u.type==="ObjectMethod"?u:u.value;if(!d)return;let l=d.body;if(l?.type==="BlockStatement"){let f=l.body;for(let g of f||[])this.processTopLevelStatement(g,o,r,i,n);}}}}),c||j(s.program,a=>{if(!c&&a.type==="ObjectExpression"){let d=(a.properties||[]).find(l=>this.getPropKey(l)==="setup");if(d){c=true;let l=d.type==="ObjectMethod"?d:d.value;if(!l)return;let f=l.body;if(f?.type==="BlockStatement"){let g=f.body;for(let m of g||[])this.processTopLevelStatement(m,o,r,i,n);}}}});}processTopLevelStatement(e,t,r,n,s){let o=i=>{let c=i?.loc;return {start:c?.start?.line??1,end:c?.end?.line??1}};if(e.type==="VariableDeclaration")for(let i of e.declarations||[]){if(i.id?.type!=="Identifier"&&i.id?.type!=="ArrayPattern")continue;let c=i.init;if(c&&i.id.type==="Identifier"){let a=i.id.name,u=this.classifyVue3Declaration(a,c,t,o(e),r);u&&s.symbols.push(u);}}if(e.type==="FunctionDeclaration"&&e.id?.type==="Identifier"){let i=e.id.name,{start:c,end:a}=o(e),u=M(r.join(`
|
|
14
|
+
`),t(c)),d=this.extractParams(e),l=$e.includes(i);if(s.symbols.push({name:i,category:l?"lifecycle":z(i)?"hook":"method",framework:"vue3",startLine:t(c),endLine:t(a),signature:`${i}(${(d||[]).join(", ")})`,params:d,isAsync:e.async===true,jsdoc:u,camelWords:_(i)}),e.body){let f=F(e.body,i);s.behaviors.push(...f);}}if(e.type==="ExpressionStatement"&&e.expression?.type==="CallExpression"){let c=e.expression.callee;if(c?.type==="Identifier"){let a=c.name;if(["defineProps","defineEmits","defineExpose"].includes(a)){let{start:u,end:d}=o(e);s.symbols.push({name:a,category:a==="defineProps"?"prop":a==="defineEmits"?"emit":"export",framework:"vue3",startLine:t(u),endLine:t(d),camelWords:_(a)});}}}if(e.type==="ExpressionStatement"&&e.expression?.type==="CallExpression"){let i=e.expression,c=i.callee;if(c?.type==="Identifier"){let a=c.name;if($e.includes(a)){let{start:u,end:d}=o(e);s.symbols.push({name:a,category:"lifecycle",framework:"vue3",startLine:t(u),endLine:t(d),camelWords:_(a)});let l=i.arguments;if(l?.[0]){let f=F(l[0],a);s.behaviors.push(...f);}}}}}classifyVue3Declaration(e,t,r,n,s){if(t.type!=="CallExpression")return null;let o=t.callee;if(o?.type!=="Identifier")return null;let i=o.name,c=r(n.start),a=r(n.end),u=M(s.join(`
|
|
15
|
+
`),c);if(qe.includes(i)){let d=t.arguments,l=d?.[0]?this.getLiteralValue(d[0]):void 0;return {name:e,category:"state",framework:"vue3",startLine:c,endLine:a,defaultValue:l,jsdoc:u,camelWords:_(e)}}return Ye.includes(i)?{name:e,category:"computed",framework:"vue3",startLine:c,endLine:a,jsdoc:u,camelWords:_(e)}:Ze.includes(i)?{name:e,category:"effect",framework:"vue3",startLine:c,endLine:a,camelWords:_(e)}:i==="provide"||i==="inject"?{name:e,category:"provide",framework:"vue3",startLine:c,endLine:a,camelWords:_(e)}:z(i)?{name:e,category:"hook",framework:"vue3",startLine:c,endLine:a,jsdoc:u,camelWords:_(e)}:null}getPropKey(e){let t=e?.key;return t?t.type==="Identifier"?t.name:t.type==="Literal"?String(t.value):null:null}extractParams(e){let t=e.params;if(t)return t.map(r=>r.type==="Identifier"?r.name:r.type==="AssignmentPattern"?r.left?.name||"?":r.type==="RestElement"?`...${r.argument?.name||""}`:r.type==="ObjectPattern"?"{...}":r.type==="TSParameterProperty"&&r.parameter?.name||"?")}getLiteralValue(e){if(e){if(e.type==="Literal"||e.type==="StringLiteral"||e.type==="NumericLiteral"||e.type==="BooleanLiteral")return String(e.value);if(e.type==="NullLiteral")return "null";if(e.type==="ObjectExpression")return "{}";if(e.type==="ArrayExpression")return "[]"}}};});var Bt,Ht,ne,ct=U(()=>{S();H();Ee();B();Bt=createRequire(import.meta.url),Ht=[...ve,...we,...Le,...Qe],ne=class{name="ReactParser";canParse(e,t){let r=e.split(".").pop()?.toLowerCase();return ["jsx","tsx","js","ts"].includes(r||"")?t.includes("useState")||t.includes("useEffect")||t.includes("from 'react'")||t.includes('from "react"')||t.includes("React.")||t.includes("jsx")||t.includes("JSX"):false}parse(e,t){let r={framework:"react",filePath:e,symbols:[],relations:[],behaviors:[],errors:[]};try{let s=Bt("@babel/parser").parse(t,{sourceType:"module",plugins:["jsx","typescript","decorators-legacy"],errorRecovery:!0}),o=t.split(`
|
|
16
|
+
`);this.extractFromAST(s.program?s.program:s,o,r);}catch(n){r.errors?.push(`React \u89E3\u6790\u5931\u8D25: ${String(n)}`);}return r}extractFromAST(e,t,r){let n=e.body;for(let s of n||[]){if(s.type==="FunctionDeclaration"||s.type==="ExportDefaultDeclaration"&&s.declaration?.type==="FunctionDeclaration"||s.type==="ExportNamedDeclaration"&&s.declaration?.type==="FunctionDeclaration"){let o=s.type==="FunctionDeclaration"?s:s.declaration;o&&o.id?.type==="Identifier"&&this.processFunction(o,t,r);}if(s.type==="VariableDeclaration"||s.type==="ExportNamedDeclaration"&&s.declaration?.type==="VariableDeclaration"||s.type==="ExportDefaultDeclaration"&&s.declaration?.type==="VariableDeclaration"){let o=s.type==="VariableDeclaration"?s:s.declaration;if(o)for(let i of o.declarations||[]){let c=i.init;if(c&&(c.type==="ArrowFunctionExpression"||c.type==="FunctionExpression")&&i.id?.type==="Identifier"){let a={...c,id:i.id,loc:{start:o.loc?.start??c.loc?.start,end:c.loc?.end}};this.processFunction(a,t,r);}}}}}processFunction(e,t,r){let n=e.id?.name;if(!n)return;let s=e.loc,o=s?.start?.line??1,i=s?.end?.line??1,c=z(n),a=!c&&/^[A-Z]/.test(n),u=M(t.join(`
|
|
17
|
+
`),o),d=this.extractParams(e);r.symbols.push({name:n,category:c?"hook":"function",framework:"react",startLine:o,endLine:i,signature:`${n}(${(d||[]).join(", ")})`,params:d,isAsync:e.async===true,jsdoc:u,parentComponent:a?n:void 0,camelWords:_(n)});let l=e.body;if(l?.type!=="BlockStatement")return;let f=l.body;for(let m of f||[])this.processComponentStatement(m,n,t,r);let g=F(l,n);r.behaviors.push(...g);}processComponentStatement(e,t,r,n){let s=o=>{let i=o?.loc;return {start:i?.start?.line??1,end:i?.end?.line??1}};if(e.type==="VariableDeclaration")for(let o of e.declarations||[]){let i=o.init;if(!i||i.type!=="CallExpression")continue;let c=i.callee;if(c?.type!=="Identifier")continue;let a=c.name,{start:u,end:d}=s(e),l=u,f=d;if(ve.includes(a)&&a!=="useRef"){if(o.id?.type==="ArrayPattern"){let g=o.id.elements,m=g[0]?.name,h=g[1]?.name;if(m){let E=i.arguments;n.symbols.push({name:m,category:"state",framework:"react",startLine:l,endLine:f,stateSetterName:h,defaultValue:this.getLiteralValue(E?.[0]),parentComponent:t,camelWords:_(m)});}}else if(o.id?.type==="Identifier"){let g=o.id.name;n.symbols.push({name:g,category:"state",framework:"react",startLine:l,endLine:f,parentComponent:t,camelWords:_(g)});}}if(a==="useRef"&&o.id?.type==="Identifier"){let g=o.id.name,m=i.arguments;n.symbols.push({name:g,category:"state",framework:"react",startLine:l,endLine:f,defaultValue:this.getLiteralValue(m?.[0]),parentComponent:t,camelWords:_(g)});}if(we.includes(a)&&o.id?.type==="Identifier"){let g=o.id.name,h=i.arguments?.[1],E=this.extractDepsArray(h);n.symbols.push({name:g,category:"computed",framework:"react",startLine:l,endLine:f,hookDeps:E,parentComponent:t,camelWords:_(g)});}if(z(a)&&!Ht.includes(a)){let g=o.id?.type==="Identifier"?o.id.name:o.id?.type==="ObjectPattern"?"{...}":"?";n.symbols.push({name:g,category:"hook",framework:"react",startLine:l,endLine:f,parentComponent:t,camelWords:_(g)});}}if(e.type==="ExpressionStatement"&&e.expression?.type==="CallExpression"){let o=e.expression,i=o.callee;if(i?.type==="Identifier"){let c=i.name;if(Le.includes(c)){let{start:a,end:u}=s(e),d=o.arguments,l=d?.[1],f=this.extractDepsArray(l);if(n.symbols.push({name:c,category:"effect",framework:"react",startLine:a,endLine:u,hookDeps:f,parentComponent:t,camelWords:_(c)}),d?.[0]){let g=F(d[0],`${t}.${c}`);n.behaviors.push(...g);}}}}if(e.type==="FunctionDeclaration"&&e.id?.type==="Identifier"){let o=e.id.name;if(!z(o)){let{start:i,end:c}=s(e),a=M(r.join(`
|
|
18
|
+
`),i),u=this.extractParams(e);if(n.symbols.push({name:o,category:"method",framework:"react",startLine:i,endLine:c,signature:`${o}(${(u||[]).join(", ")})`,params:u,isAsync:e.async===true,jsdoc:a,parentComponent:t,camelWords:_(o)}),e.body){let d=F(e.body,o);n.behaviors.push(...d);}}}if(e.type==="VariableDeclaration")for(let o of e.declarations||[]){let i=o.init;if(!i)continue;let c=i.type==="ArrowFunctionExpression"||i.type==="FunctionExpression";if(!c||o.id?.type!=="Identifier")continue;let a=o.id.name,u=i.type==="CallExpression"?i.callee:null;if(u?.type==="Identifier"&&z(u.name))continue;if(i.type==="CallExpression"&&i.callee?.name==="useCallback"){let E=i.arguments?.[1],b=this.extractDepsArray(E),{start:R,end:x}=s(e);n.symbols.push({name:a,category:"computed",framework:"react",startLine:R,endLine:x,hookDeps:b,parentComponent:t,camelWords:_(a)});continue}if(!c)continue;let{start:l,end:f}=s(e),g=M(r.join(`
|
|
19
|
+
`),l),m=this.extractParams(i);if(n.symbols.push({name:a,category:"method",framework:"react",startLine:l,endLine:f,signature:`${a}(${(m||[]).join(", ")})`,params:m,isAsync:i.async===true,jsdoc:g,parentComponent:t,camelWords:_(a)}),i.body){let h=F(i.body,a);n.behaviors.push(...h);}}}extractDepsArray(e){if(!(!e||e.type!=="ArrayExpression"))return (e.elements||[]).filter(t=>!!t&&t.type==="Identifier").map(t=>t.name)}extractParams(e){let t=e.params;if(t)return t.map(r=>r.type==="Identifier"?r.name:r.type==="ObjectPattern"?"{...}":r.type==="ArrayPattern"?"[...]":r.type==="AssignmentPattern"?r.left?.name||"?":r.type==="RestElement"?`...${r.argument?.name||""}`:r.type==="TSParameterProperty"&&r.parameter?.name||"?")}getLiteralValue(e){if(e){if(e.type==="Literal"||e.type==="StringLiteral"||e.type==="NumericLiteral"||e.type==="BooleanLiteral")return String(e.value);if(e.type==="NullLiteral")return "null";if(e.type==="ObjectExpression")return "{}";if(e.type==="ArrayExpression")return "[]";if(e.type==="Identifier"&&e.name==="null")return "null"}}};});function lt(p,e){for(let t of Vt)if(t.canParse(p,e)){let r=t.parse(p,e);return Kt(r),r}return {framework:"js",filePath:p,symbols:[],relations:[],behaviors:[],errors:[`\u6CA1\u6709\u627E\u5230\u9002\u5408\u7684\u89E3\u6790\u5668: ${p}`]}}function Kt(p){if(!p.relations.length||!p.behaviors.length)return;let e=new Set(["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured","setup","onBeforeMount","onMounted","onBeforeUpdate","onUpdated","onBeforeUnmount","onUnmounted","onActivated","onDeactivated","onErrorCaptured","componentDidMount","componentDidUpdate","componentWillUnmount","componentDidCatch","getDerivedStateFromProps","getSnapshotBeforeUpdate","render","init","initialize"]),t=new Set(p.behaviors.filter(n=>n.category==="network").map(n=>n.symbolName));if(t.size===0)return;let r=new Set(p.behaviors.map(n=>`${n.symbolName}:${n.category}:${n.apiName}:${n.operation}:${n.line}`));for(let n of p.relations){if(!t.has(n.calleeName)||t.has(n.callerName)||e.has(n.callerName))continue;let s={symbolName:n.callerName,category:"network",apiName:"wrapped_network",operation:n.calleeName,detail:n.args,line:n.line},o=`${s.symbolName}:${s.category}:${s.apiName}:${s.operation}:${s.line}`;r.has(o)||(r.add(o),p.behaviors.push(s));}}var Oe,Vt,pt=U(()=>{S();it();at();ct();Oe=class extends ne{name="JsTsFallbackParser";canParse(e){let t=e.split(".").pop()?.toLowerCase();return ["js","ts","jsx","tsx"].includes(t||"")}parse(e,t){let r=super.parse(e,t);return r.framework=e.endsWith(".ts")||e.endsWith(".tsx")?"ts":"js",r}},Vt=[new _e,new Ne,new ne,new Oe];});var dt={};St(dt,{Indexer:()=>se});var se,Ie=U(()=>{S();pt();B();H();se=class{projectRoot;db;constructor(e,t){this.projectRoot=e,this.db=t;}async indexProject(e){let t=Date.now(),r=e?.include||[...ke],n=e?.exclude||[...Re],s=e?.force||false,o=await Jt(r,{cwd:this.projectRoot,ignore:n,absolute:true,onlyFiles:true}),i={totalFiles:o.length,indexedFiles:0,skippedFiles:0,totalSymbols:0,durationMs:0,errors:[]};for(let c=0;c<o.length;c++){let a=o[c],u=fe(a,this.projectRoot);e?.onProgress?.(c+1,o.length,u);try{let d=await this.indexFile(a,u,s);d.skipped?i.skippedFiles++:(i.indexedFiles++,i.totalSymbols+=d.symbolCount,d.errors?.length&&i.errors.push(...d.errors.map(l=>({file:u,error:l}))));}catch(d){i.errors.push({file:u,error:String(d)});}}return i.durationMs=Date.now()-t,i}async indexFile(e,t,r=false){let n=W.readFileSync(e,"utf-8"),s=Ke(n);if(!r&&this.db.getFileHash(t)===s)return {skipped:true,symbolCount:0};let o=Xe(n),i=Buffer.byteLength(n,"utf-8"),c=lt(e,n);return this.db.saveParseResult(c,e,t,s,i,o),{skipped:false,symbolCount:c.symbols.length,errors:c.errors}}removeFile(e){this.db.deleteFile(e);}async startWatcher(){let{default:e}=await import('chokidar'),t=e.watch([...ke].map(n=>D.join(this.projectRoot,n.replace("**/",""))),{cwd:this.projectRoot,ignored:[...Re],persistent:true,ignoreInitial:true,awaitWriteFinish:{stabilityThreshold:rt}}),r=async n=>{let s=fe(n,this.projectRoot);try{await this.indexFile(n,s),process.stderr.write(`[Frontend-Code-Skimmer] \u5DF2\u66F4\u65B0\u7D22\u5F15: ${s}
|
|
20
20
|
`);}catch(o){process.stderr.write(`[Frontend-Code-Skimmer] \u66F4\u65B0\u5931\u8D25: ${s} - ${String(o)}
|
|
21
|
-
`);}};return t.on("add",
|
|
22
|
-
`);}),()=>t.close()}};});S();S();S();B();H();var ge=class{db;constructor(e,t){let
|
|
21
|
+
`);}};return t.on("add",r).on("change",r).on("unlink",n=>{let s=fe(n,this.projectRoot);this.removeFile(s),process.stderr.write(`[Frontend-Code-Skimmer] \u5DF2\u5220\u9664\u7D22\u5F15: ${s}
|
|
22
|
+
`);}),()=>t.close()}};});S();S();S();B();H();var ge=class{db;constructor(e,t){let r=t||D.join(e,me);W.mkdirSync(D.dirname(r),{recursive:true}),this.db=new Tt(r),this.initialize();}initialize(){this.db.pragma("journal_mode = WAL"),this.db.pragma("foreign_keys = ON"),this.db.pragma("synchronous = NORMAL"),this.db.exec(`
|
|
23
23
|
-- \u6587\u4EF6\u5143\u4FE1\u606F
|
|
24
24
|
CREATE TABLE IF NOT EXISTS files (
|
|
25
25
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -117,15 +117,15 @@ import D from'path';import'url';import Rt from'crypto';import {createRequire}fro
|
|
|
117
117
|
CREATE INDEX IF NOT EXISTS idx_behaviors_category ON behaviors(category);
|
|
118
118
|
CREATE INDEX IF NOT EXISTS idx_behaviors_api ON behaviors(api_name, operation);
|
|
119
119
|
CREATE INDEX IF NOT EXISTS idx_behaviors_file ON behaviors(file_id);
|
|
120
|
-
`);try{this.db.exec("ALTER TABLE relations ADD COLUMN args TEXT;");}catch{}}saveParseResult(e,t,n,
|
|
120
|
+
`);try{this.db.exec("ALTER TABLE relations ADD COLUMN args TEXT;");}catch{}}saveParseResult(e,t,r,n,s,o){let i=D.extname(t).slice(1);this.db.transaction(()=>{let a=this.db.prepare("SELECT id FROM files WHERE path = ?").get(r),u;a?(u=a.id,this.db.prepare("DELETE FROM symbols WHERE file_id = ?").run(u),this.db.prepare(`
|
|
121
121
|
UPDATE files SET
|
|
122
122
|
abs_path = ?, framework = ?, content_hash = ?,
|
|
123
123
|
last_indexed_at = ?, file_size = ?, line_count = ?
|
|
124
124
|
WHERE id = ?
|
|
125
|
-
`).run(t,e.framework,
|
|
125
|
+
`).run(t,e.framework,n,Date.now(),s,o,u)):u=this.db.prepare(`
|
|
126
126
|
INSERT INTO files (path, abs_path, file_type, framework, content_hash, last_indexed_at, file_size, line_count)
|
|
127
127
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
128
|
-
`).run(
|
|
128
|
+
`).run(r,t,i,e.framework,n,Date.now(),s,o).lastInsertRowid;let d=this.db.prepare(`
|
|
129
129
|
INSERT INTO symbols (file_id, name, category, framework, start_line, end_line,
|
|
130
130
|
signature, params_json, default_value, camel_words, jsdoc,
|
|
131
131
|
is_async, hook_deps_json, state_setter_name, parent_component)
|
|
@@ -136,30 +136,30 @@ import D from'path';import'url';import Rt from'crypto';import {createRequire}fro
|
|
|
136
136
|
`);for(let m of e.relations){let h=l.get(m.callerName);h&&f.run(h,m.calleeName,m.callType,m.line,m.args||null);}let g=this.db.prepare(`
|
|
137
137
|
INSERT INTO behaviors (symbol_id, file_id, category, api_name, operation, detail, line_number)
|
|
138
138
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
139
|
-
`);for(let m of e.behaviors){let h=l.get(m.symbolName);h&&g.run(h,u,m.category,m.apiName,m.operation,m.detail||null,m.line);}})();}getFileHash(e){return this.db.prepare("SELECT content_hash FROM files WHERE path = ?").get(e)?.content_hash??null}deleteFile(e){this.db.prepare("DELETE FROM files WHERE path = ?").run(e);}getFileOutline(e){let t=this.db.prepare("SELECT * FROM files WHERE path = ?").get(e);if(!t)return {file:void 0,symbols:[],behaviors:[]};let
|
|
139
|
+
`);for(let m of e.behaviors){let h=l.get(m.symbolName);h&&g.run(h,u,m.category,m.apiName,m.operation,m.detail||null,m.line);}})();}getFileHash(e){return this.db.prepare("SELECT content_hash FROM files WHERE path = ?").get(e)?.content_hash??null}deleteFile(e){this.db.prepare("DELETE FROM files WHERE path = ?").run(e);}getFileOutline(e){let t=this.db.prepare("SELECT * FROM files WHERE path = ?").get(e);if(!t)return {file:void 0,symbols:[],behaviors:[]};let r=t.id,n=this.db.prepare(`
|
|
140
140
|
SELECT s.*, f.path as file_path
|
|
141
141
|
FROM symbols s JOIN files f ON s.file_id = f.id
|
|
142
142
|
WHERE s.file_id = ?
|
|
143
143
|
ORDER BY s.start_line ASC
|
|
144
|
-
`).all(
|
|
144
|
+
`).all(r),s=this.db.prepare(`
|
|
145
145
|
SELECT b.*, s.name as symbol_name
|
|
146
146
|
FROM behaviors b JOIN symbols s ON b.symbol_id = s.id
|
|
147
147
|
WHERE b.file_id = ?
|
|
148
|
-
`).all(
|
|
148
|
+
`).all(r);return {file:t,symbols:n,behaviors:s}}listFiles(e){let t="SELECT path, abs_path, framework, line_count FROM files",r=[];return e&&(t+=" WHERE path LIKE ?",r.push(`%${e}%`)),t+=" ORDER BY path",this.db.prepare(t).all(...r)}exactSearch(e,t,r,n){let s=`
|
|
149
149
|
SELECT s.*, f.path as file_path, f.abs_path
|
|
150
150
|
FROM symbols s JOIN files f ON s.file_id = f.id
|
|
151
151
|
WHERE LOWER(s.name) = LOWER(?)
|
|
152
|
-
`,o=[e];return t&&(s+=" AND s.category = ?",o.push(t)),
|
|
152
|
+
`,o=[e];return t&&(s+=" AND s.category = ?",o.push(t)),r&&(s+=" AND s.framework = ?",o.push(r)),n&&(s+=" AND f.path LIKE ?",o.push(`%${n}%`)),s+=" LIMIT 30",this.db.prepare(s).all(...o)}ftsSearch(e,t,r){let n=e.trim().split(/\s+/).map(s=>`${s}*`).join(" ");try{let s=`
|
|
153
153
|
SELECT s.*, f.path as file_path, f.abs_path,
|
|
154
154
|
symbols_fts.rank as fts_rank
|
|
155
155
|
FROM symbols_fts
|
|
156
156
|
JOIN symbols s ON symbols_fts.rowid = s.id
|
|
157
157
|
JOIN files f ON s.file_id = f.id
|
|
158
158
|
WHERE symbols_fts MATCH ?
|
|
159
|
-
`,o=[
|
|
159
|
+
`,o=[n];return t&&(s+=" AND s.category = ?",o.push(t)),r&&(s+=" AND f.path LIKE ?",o.push(`%${r}%`)),s+=" ORDER BY symbols_fts.rank LIMIT 20",this.db.prepare(s).all(...o)}catch{return []}}getAllSymbolNames(e){let t=`
|
|
160
160
|
SELECT DISTINCT s.name, f.path as file_path, s.id
|
|
161
161
|
FROM symbols s JOIN files f ON s.file_id = f.id
|
|
162
|
-
`,
|
|
162
|
+
`,r=[];return e&&(t+=" WHERE f.path LIKE ?",r.push(`%${e}%`)),this.db.prepare(t).all(...r)}getSymbolById(e){return this.db.prepare(`
|
|
163
163
|
SELECT s.*, f.path as file_path, f.abs_path
|
|
164
164
|
FROM symbols s JOIN files f ON s.file_id = f.id
|
|
165
165
|
WHERE s.id = ?
|
|
@@ -172,32 +172,32 @@ import D from'path';import'url';import Rt from'crypto';import {createRequire}fro
|
|
|
172
172
|
FROM symbols s JOIN files f ON s.file_id = f.id
|
|
173
173
|
WHERE s.name = ?
|
|
174
174
|
LIMIT 1
|
|
175
|
-
`).get(e)}behaviorSearch(e,t,n,
|
|
175
|
+
`).get(e)}behaviorSearch(e,t,r,n,s){let o=`
|
|
176
176
|
SELECT b.*, s.name as symbol_name, s.start_line, s.end_line, s.category as symbol_category,
|
|
177
177
|
f.path as file_path
|
|
178
178
|
FROM behaviors b
|
|
179
179
|
JOIN symbols s ON b.symbol_id = s.id
|
|
180
180
|
JOIN files f ON b.file_id = f.id
|
|
181
181
|
WHERE 1=1
|
|
182
|
-
`,i=[];return e&&(o+=" AND b.category = ?",i.push(e)),t&&(o+=" AND LOWER(b.api_name) = LOWER(?)",i.push(t)),
|
|
182
|
+
`,i=[];return e&&(o+=" AND b.category = ?",i.push(e)),t&&(o+=" AND LOWER(b.api_name) = LOWER(?)",i.push(t)),r&&(o+=" AND LOWER(b.operation) = LOWER(?)",i.push(r)),n&&(o+=" AND (LOWER(b.detail) LIKE LOWER(?) OR LOWER(b.api_name) LIKE LOWER(?))",i.push(`%${n}%`,`%${n}%`)),s&&(o+=" AND f.path LIKE ?",i.push(`%${s}%`)),o+=" ORDER BY f.path, b.line_number LIMIT 50",this.db.prepare(o).all(...i)}getCallers(e,t,r){let n=`
|
|
183
183
|
SELECT r.*, s.name as caller_name, s.start_line, s.end_line, s.category,
|
|
184
184
|
f.path as file_path
|
|
185
185
|
FROM relations r
|
|
186
186
|
JOIN symbols s ON r.caller_id = s.id
|
|
187
187
|
JOIN files f ON s.file_id = f.id
|
|
188
188
|
WHERE r.callee_name = ?
|
|
189
|
-
`,s=[e];return t&&(
|
|
189
|
+
`,s=[e];return t&&(n+=" AND f.path LIKE ?",s.push(`%${t}%`)),r&&(n+=" AND LOWER(COALESCE(r.args, '')) LIKE LOWER(?)",s.push(`%${r}%`)),n+=" ORDER BY f.path, r.line_number",this.db.prepare(n).all(...s)}getCallees(e){return this.db.prepare(`
|
|
190
190
|
SELECT r.*, r.callee_name
|
|
191
191
|
FROM relations r
|
|
192
192
|
WHERE r.caller_id = ?
|
|
193
|
-
`).all(e)}findRelationsByArgKeyword(e,t,
|
|
193
|
+
`).all(e)}findRelationsByArgKeyword(e,t,r=50){let n=`
|
|
194
194
|
SELECT r.*, s.name as caller_name, s.start_line, s.end_line, s.category,
|
|
195
195
|
f.path as file_path
|
|
196
196
|
FROM relations r
|
|
197
197
|
JOIN symbols s ON r.caller_id = s.id
|
|
198
198
|
JOIN files f ON s.file_id = f.id
|
|
199
199
|
WHERE LOWER(COALESCE(r.args, '')) LIKE LOWER(?)
|
|
200
|
-
`,s=[`%${e}%`];return t&&(
|
|
200
|
+
`,s=[`%${e}%`];return t&&(n+=" AND f.path LIKE ?",s.push(`%${t}%`)),n+=" ORDER BY f.path, r.line_number LIMIT ?",s.push(r),this.db.prepare(n).all(...s)}getProjectStats(){let e=this.db.prepare("SELECT COUNT(*) as c FROM files").get().c,t=this.db.prepare("SELECT COUNT(*) as c FROM symbols").get().c,r=this.db.prepare("SELECT COUNT(*) as c FROM behaviors").get().c,n=this.db.prepare("SELECT COUNT(*) as c FROM relations").get().c,s=this.db.prepare(`
|
|
201
201
|
SELECT framework, COUNT(*) as count FROM files GROUP BY framework
|
|
202
202
|
`).all(),o=this.db.prepare(`
|
|
203
203
|
SELECT f.path, f.line_count, COUNT(s.id) as symbol_count
|
|
@@ -206,18 +206,19 @@ import D from'path';import'url';import Rt from'crypto';import {createRequire}fro
|
|
|
206
206
|
ORDER BY f.line_count DESC LIMIT 10
|
|
207
207
|
`).all(),i=this.db.prepare(`
|
|
208
208
|
SELECT category, COUNT(*) as count FROM behaviors GROUP BY category ORDER BY count DESC
|
|
209
|
-
`).all(),c=this.db.prepare("SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size()").get()?.size??0;return {fileCount:e,symbolCount:t,behaviorCount:
|
|
210
|
-
`),process.stderr.write(`[Frontend-Code-Skimmer] \u6570\u636E\u5E93: ${
|
|
211
|
-
`),
|
|
212
|
-
\
|
|
209
|
+
`).all(),c=this.db.prepare("SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size()").get()?.size??0;return {fileCount:e,symbolCount:t,behaviorCount:r,relationCount:n,frameworkBreakdown:s,topFiles:o,behaviorStats:i,dbSize:c}}close(){this.db.close();}};H();var he=class{dbCache=new Map;lastProject=null;globalCacheDir;defaultProject;constructor(){this.globalCacheDir=D.join(vt.homedir(),".frontend-code-skimmer","databases"),W.mkdirSync(this.globalCacheDir,{recursive:true}),this.defaultProject=process.env.SKIMMER_PROJECT||null,this.defaultProject&&(this.defaultProject=D.resolve(this.defaultProject));}resolveProjectRoot(e){if(e){let t=D.resolve(e);if(!W.existsSync(t))throw new Error(`\u9879\u76EE\u8DEF\u5F84\u4E0D\u5B58\u5728: ${t}`);return t}return this.lastProject?this.lastProject:this.defaultProject?this.defaultProject:process.cwd()}getDatabase(e){let t=D.resolve(e);if(this.dbCache.has(t))return this.dbCache.get(t);let r=this.resolveDbPath(t),n=new ge(t,r);return this.dbCache.set(t,n),this.lastProject=t,process.stderr.write(`[Frontend-Code-Skimmer] \u5DF2\u8FDE\u63A5\u9879\u76EE: ${t}
|
|
210
|
+
`),process.stderr.write(`[Frontend-Code-Skimmer] \u6570\u636E\u5E93: ${r}
|
|
211
|
+
`),n}getContext(e){let t=this.resolveProjectRoot(e),r=this.getDatabase(t);return this.lastProject=t,{db:r,projectRoot:t}}setLastProject(e){this.lastProject=D.resolve(e);}listProjects(){return Array.from(this.dbCache.entries()).map(([e])=>({root:e,dbPath:this.resolveDbPath(e)}))}closeProject(e){let t=D.resolve(e),r=this.dbCache.get(t);r&&(r.close(),this.dbCache.delete(t));}closeAll(){for(let e of this.dbCache.values())e.close();this.dbCache.clear();}resolveDbPath(e){if(process.env.SKIMMER_DB&&this.dbCache.size===0)return D.resolve(process.env.SKIMMER_DB);let t=D.join(e,".agent","skimmer_find_symbol"),r=D.join(t,me);try{return W.mkdirSync(t,{recursive:!0}),W.accessSync(e,W.constants.W_OK),r}catch{let n=e.replace(/[/\\:]/g,"_").replace(/^_+/,"").slice(-60);return D.join(this.globalCacheDir,`${n}.db`)}}};S();Ie();function ut(p,e){p.registerTool("skimmer_index_project",{title:"\u7D22\u5F15\u9879\u76EE\u4EE3\u7801\uFF08\u652F\u6301\u4EFB\u610F\u9879\u76EE\uFF09",description:`\u521D\u59CB\u5316\u6216\u589E\u91CF\u66F4\u65B0\u524D\u7AEF\u9879\u76EE\u4EE3\u7801\u7D22\u5F15\u3002\u652F\u6301 Vue2/Vue3/React Hooks\u3002
|
|
212
|
+
\u6BCF\u6B21\u8C03\u7528\u5FC5\u987B\u4F20\u5165 project_path\uFF08\u9879\u76EE\u6839\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF09\uFF0C\u65E0\u9700\u5728\u542F\u52A8\u65F6\u56FA\u5B9A\u9879\u76EE\u3002
|
|
213
|
+
\u4F18\u5148\u4ECE\u7F16\u8F91\u5668\u5DE5\u4F5C\u533A\u3001\u5DF2\u6253\u5F00\u6587\u4EF6\u548C\u5F53\u524D\u4E0A\u4E0B\u6587\u4E2D\u81EA\u52A8\u63A8\u65AD project_path\uFF0C\u907F\u514D\u5411\u7528\u6237\u8FFD\u95EE\u8DEF\u5F84\u3002
|
|
213
214
|
\u591A\u4E2A\u9879\u76EE\u4F1A\u5E76\u884C\u7F13\u5B58\uFF0C\u5207\u6362\u65E0\u9700\u91CD\u542F\u3002
|
|
214
215
|
|
|
215
216
|
\u4F7F\u7528\u573A\u666F:
|
|
216
|
-
- \
|
|
217
|
-
- \u4EE3\u7801\u53D8\u66F4\u540E\
|
|
217
|
+
- \u9996\u6B21\u5206\u6790\u9879\u76EE: project_path="/Users/xxx/projects/my-app"
|
|
218
|
+
- \u4EE3\u7801\u53D8\u66F4\u540E\u5237\u65B0: \u76F8\u540C\u8DEF\u5F84\u518D\u6B21\u8C03\u7528\uFF08\u81EA\u52A8\u68C0\u6D4B\u53D8\u66F4\uFF0C\u589E\u91CF\u66F4\u65B0\uFF09
|
|
218
219
|
- \u5F3A\u5236\u5168\u91CF\u91CD\u5EFA: force=true
|
|
219
220
|
|
|
220
|
-
\u8FD4\u56DE: \u7D22\u5F15\u7EDF\u8BA1\uFF08\u6587\u4EF6\u6570\u3001\u7B26\u53F7\u6570\u3001\u8017\u65F6\uFF09`,inputSchema:z$1.object({project_path:z$1.string().describe('\u9879\u76EE\u6839\u76EE\u5F55\u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u5982 "/Users/xxx/projects/my-app"'),force:z$1.boolean().optional().default(false).describe("\u662F\u5426\u5F3A\u5236\u5168\u91CF\u91CD\u5EFA\uFF08\u9ED8\u8BA4\u589E\u91CF\uFF0C\u53EA\u66F4\u65B0\u53D8\u66F4\u6587\u4EF6\uFF09"),include:z$1.array(z$1.string()).optional().describe('\u8981\u5305\u542B\u7684\u6587\u4EF6 glob \u6A21\u5F0F\uFF0C\u5982 ["**/*.vue","**/*.tsx"]'),exclude:z$1.array(z$1.string()).optional().describe("\u8981\u989D\u5916\u6392\u9664\u7684 glob \u6A21\u5F0F")}),annotations:{readOnlyHint:false,destructiveHint:false,idempotentHint:true}},async({project_path:t,force:
|
|
221
|
+
\u8FD4\u56DE: \u7D22\u5F15\u7EDF\u8BA1\uFF08\u6587\u4EF6\u6570\u3001\u7B26\u53F7\u6570\u3001\u8017\u65F6\uFF09`,inputSchema:z$1.object({project_path:z$1.string().describe('\u9879\u76EE\u6839\u76EE\u5F55\u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u5982 "/Users/xxx/projects/my-app"'),force:z$1.boolean().optional().default(false).describe("\u662F\u5426\u5F3A\u5236\u5168\u91CF\u91CD\u5EFA\uFF08\u9ED8\u8BA4\u589E\u91CF\uFF0C\u53EA\u66F4\u65B0\u53D8\u66F4\u6587\u4EF6\uFF09"),include:z$1.array(z$1.string()).optional().describe('\u8981\u5305\u542B\u7684\u6587\u4EF6 glob \u6A21\u5F0F\uFF0C\u5982 ["**/*.vue","**/*.tsx"]'),exclude:z$1.array(z$1.string()).optional().describe("\u8981\u989D\u5916\u6392\u9664\u7684 glob \u6A21\u5F0F")}),annotations:{readOnlyHint:false,destructiveHint:false,idempotentHint:true}},async({project_path:t,force:r,include:n,exclude:s})=>{let{db:o,projectRoot:i}=e.getContext(t),a=await new se(i,o).indexProject({include:n,exclude:s,force:r,onProgress:(d,l)=>{(d%20===0||d===l)&&process.stderr.write(`[Frontend-Code-Skimmer] \u8FDB\u5EA6: ${d}/${l}
|
|
221
222
|
`);}});e.setLastProject(i);let u=[`\u2705 \u7D22\u5F15\u5B8C\u6210 \u2014 ${i}`,"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501",`\u{1F4C1} \u603B\u6587\u4EF6\u6570: ${a.totalFiles}`,`\u{1F504} \u5DF2\u7D22\u5F15: ${a.indexedFiles}`,`\u23E9 \u5DF2\u8DF3\u8FC7: ${a.skippedFiles} (\u5185\u5BB9\u672A\u53D8)`,`\u{1F523} \u603B\u7B26\u53F7\u6570: ${a.totalSymbols}`,`\u23F1\uFE0F \u8017\u65F6: ${a.durationMs}ms`,"","\u{1F4A1} \u540E\u7EED\u5DE5\u5177\u8C03\u7528\u53EF\u7701\u7565 project_path\uFF08\u81EA\u52A8\u4F7F\u7528\u6B64\u9879\u76EE\uFF09"];if(a.errors.length>0){u.push(`
|
|
222
223
|
\u26A0\uFE0F \u89E3\u6790\u5931\u8D25 (${a.errors.length} \u4E2A):`);for(let d of a.errors.slice(0,5))u.push(` - ${d.file}: ${d.error}`);a.errors.length>5&&u.push(` ... \u8FD8\u6709 ${a.errors.length-5} \u4E2A`);}return {content:[{type:"text",text:u.join(`
|
|
223
224
|
`)}]}});}S();B();function ft(p,e){p.registerTool("skimmer_get_component_outline",{title:"\u83B7\u53D6\u7EC4\u4EF6/\u6587\u4EF6\u7ED3\u6784\u9AA8\u67B6",description:`\u5C06\u6570\u5343\u884C\u4EE3\u7801\u538B\u7F29\u4E3A\u6E05\u6670\u7684\u7ED3\u6784\u9AA8\u67B6\uFF08\u7EA6 30-80 \u884C\uFF09\uFF0C\u8282\u7701 90%+ Token\u3002
|
|
@@ -225,22 +226,22 @@ import D from'path';import'url';import Rt from'crypto';import {createRequire}fro
|
|
|
225
226
|
\u884C\u4E3A\u6807\u7B7E\u81EA\u52A8\u6807\u51FA: [storage:localStorage.setItem] [network:axios.get] \u7B49\u3002
|
|
226
227
|
|
|
227
228
|
project_path \u53EF\u7701\u7565\uFF08\u4F7F\u7528\u4E0A\u6B21 skimmer_index_project \u6307\u5B9A\u7684\u9879\u76EE\uFF09\u3002
|
|
228
|
-
file_path \u4F7F\u7528\u76F8\u5BF9\u4E8E\u9879\u76EE\u6839\u76EE\u5F55\u7684\u8DEF\u5F84\uFF0C\u5982 "src/views/apply/index.vue"\u3002`,inputSchema:z$1.object({file_path:z$1.string().describe('\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u5982 "src/views/apply/index.vue"'),project_path:z$1.string().optional().describe("\u9879\u76EE\u6839\u76EE\u5F55\uFF08\u53EF\u7701\u7565\uFF0C\u4F7F\u7528\u4E0A\u6B21\u7D22\u5F15\u7684\u9879\u76EE\uFF09")}),annotations:{readOnlyHint:true,destructiveHint:false}},async({file_path:t,project_path:
|
|
229
|
+
file_path \u4F7F\u7528\u76F8\u5BF9\u4E8E\u9879\u76EE\u6839\u76EE\u5F55\u7684\u8DEF\u5F84\uFF0C\u5982 "src/views/apply/index.vue"\u3002`,inputSchema:z$1.object({file_path:z$1.string().describe('\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u5982 "src/views/apply/index.vue"'),project_path:z$1.string().optional().describe("\u9879\u76EE\u6839\u76EE\u5F55\uFF08\u53EF\u7701\u7565\uFF0C\u4F7F\u7528\u4E0A\u6B21\u7D22\u5F15\u7684\u9879\u76EE\uFF09")}),annotations:{readOnlyHint:true,destructiveHint:false}},async({file_path:t,project_path:r})=>{let{db:n}=e.getContext(r),{file:s,symbols:o,behaviors:i}=n.getFileOutline(t);if(!s)return {content:[{type:"text",text:`\u274C \u6587\u4EF6\u672A\u7D22\u5F15: ${t}
|
|
229
230
|
|
|
230
231
|
\u8BF7\u5148\u8FD0\u884C:
|
|
231
|
-
skimmer_index_project({ project_path: "${
|
|
232
|
+
skimmer_index_project({ project_path: "${r||"<\u9879\u76EE\u8DEF\u5F84>"}" })`}]};let c=new Map;for(let l of i){let f=l.symbol_name;c.has(f)||c.set(f,[]);let g=`[${l.category}:${l.api_name}.${l.operation}${l.detail?`("${l.detail}")`:""}]`,m=c.get(f);m.includes(g)||m.push(g);}let a=[];a.push(`\u{1F4C4} ${t} (${s.line_count} \u884C, ${s.framework})`),a.push(`${"\u2501".repeat(50)}`);let u={};for(let l of o){let f=l.category;u[f]||(u[f]=[]),u[f].push(l);}let d=[{key:"prop",icon:"\u{1F4E6}",label:"Props"},{key:"state",icon:"\u{1F4CA}",label:"Data / State"},{key:"computed",icon:"\u{1F504}",label:"Computed"},{key:"method",icon:"\u26A1",label:"Methods / Functions"},{key:"effect",icon:"\u{1F440}",label:"Watch / Effect"},{key:"lifecycle",icon:"\u{1F517}",label:"Lifecycle"},{key:"hook",icon:"\u{1FA9D}",label:"Hooks"},{key:"component",icon:"\u{1F9E9}",label:"Components"},{key:"mixin",icon:"\u{1F500}",label:"Mixins"},{key:"provide",icon:"\u{1F489}",label:"Provide / Inject"},{key:"emit",icon:"\u{1F4E1}",label:"Emits"},{key:"filter",icon:"\u{1F50D}",label:"Filters"},{key:"function",icon:"\u{1F527}",label:"Functions"},{key:"constant",icon:"\u{1F4CC}",label:"Constants"}];for(let{key:l,icon:f,label:g}of d){let m=u[l];if(m?.length){a.push(`
|
|
232
233
|
${f} ${g} (${m.length}):`);for(let h of m){let E=h.name,b=Z(h.start_line,h.end_line),R=te(h.params_json,[]),x=R.length>0?`(${R.join(", ")})`:"",$=h.default_value?` = ${h.default_value}`:"",C=h.is_async?"async ":"",q=c.get(E),Y=q?.length?` ${q.slice(0,3).join(" ")}`:"",Q=h.state_setter_name?` \u2192 ${h.state_setter_name}`:"",Se=h.hook_deps_json?` [deps:${te(h.hook_deps_json,[]).join(",")}]`:"";a.push(` \u2022 ${C}${E}${x}${$}${Q}${Se} ${b}${Y}`);}}}return a.push(`
|
|
233
234
|
${"\u2500".repeat(50)}`),a.push(`\u{1F4A1} \u67E5\u770B\u5177\u4F53\u4EE3\u7801: skimmer_get_code_slice({ file_path: "${t}", symbol_name: "\u65B9\u6CD5\u540D" })`),{content:[{type:"text",text:a.join(`
|
|
234
|
-
`)}]}});}S();S();B();H();var oe=class{constructor(e){this.db=e;}search(e,t){let{category:
|
|
235
|
-
`);for(let o=0;o<s.length;o++){let i=s[o];for(let c of e)if(c.regex.test(i)){
|
|
236
|
-
`).length;return [{content:t[1],lineOffset:
|
|
237
|
-
`),i=He(
|
|
238
|
-
`),c=He(s.path||D.basename(s.abs_path),o);for(let a of c){let u=Be(a.content);if(u&&(ce(u,d=>{if(!(
|
|
239
|
-
`),c=He(s.path||D.basename(s.abs_path),o);for(let a of c){let u=Be(a.content);if(u&&(ce(u,d=>{if(!(
|
|
235
|
+
`)}]}});}S();S();B();H();var oe=class{constructor(e){this.db=e;}search(e,t){let{category:r,framework:n,filePath:s,limit:o=et,fuzzy:i=true}=t||{},c=new Map,a=this.db.exactSearch(e,r,n,s);for(let m of a){let h=m.id;c.set(h,{symbol:m,filePath:m.file_path,score:100,matchReason:"\u7CBE\u786E\u5339\u914D"});}if(c.size>=o)return this.rankResults(c,o);let u=_(e),d=[e,u,...u.split(" ")].filter(Boolean);for(let m of d){if(m.length<2)continue;let h=this.db.ftsSearch(m,r,s);for(let E of h){let b=E.id;if(c.has(b))continue;let R=this.calcFtsScore(e,E.name);c.set(b,{symbol:E,filePath:E.file_path,score:R,matchReason:`FTS5 \u5168\u6587\u5339\u914D (${m})`});}}if(!i||c.size>=o)return this.rankResults(c,o);let l=this.db.getAllSymbolNames(s),f=e.toLowerCase(),g=_(e).split(" ");for(let{name:m,file_path:h,id:E}of l){if(c.has(E))continue;let b=ue(f,m.toLowerCase());if(b<=tt){let $=Math.max(0,80-b*15),C=this.db.getSymbolById(E);if(!C||r&&C.category!==r||n&&C.framework!==n)continue;let q=Je(e,m,b);c.set(E,{symbol:C,filePath:h,score:$,matchReason:`\u6A21\u7CCA\u5339\u914D (\u7F16\u8F91\u8DDD\u79BB=${b})`,spellingSuggestion:q});continue}let R=_(m).split(" "),x=g.filter($=>R.some(C=>ze($,C)>=75));if(x.length>0&&x.length>=Math.ceil(g.length*.6)){let $=50+x.length*10,C=this.db.getSymbolById(E);if(!C||r&&C.category!==r)continue;c.set(E,{symbol:C,filePath:h,score:$,matchReason:`\u5355\u8BCD\u5339\u914D (${x.join(", ")})`});}}return this.rankResults(c,o)}searchByBehavior(e){return this.db.behaviorSearch(e.category,e.apiName,e.operation,e.keyword,e.filePath).map(r=>({symbolName:r.symbol_name,category:r.category,apiName:r.api_name,operation:r.operation,detail:r.detail,line:r.line_number,filePath:r.file_path,startLine:r.start_line,endLine:r.end_line}))}calcFtsScore(e,t){let r=e.toLowerCase(),n=t.toLowerCase();if(n===r)return 98;if(n.startsWith(r))return 88;if(n.includes(r))return 78;let s=_(e).split(" "),o=_(t).split(" ");return 60+s.filter(c=>o.some(a=>a.startsWith(c))).length*8}rankResults(e,t){return Array.from(e.values()).sort((r,n)=>n.score-r.score).slice(0,t)}};B();var ht=createRequire(import.meta.url),K="\u9879\u76EE\u6839\u76EE\u5F55\uFF08\u53EF\u7701\u7565\uFF0C\u81EA\u52A8\u4F7F\u7528\u4E0A\u6B21 skimmer_index_project \u6307\u5B9A\u7684\u9879\u76EE\uFF09";function We(p){return p.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ie(p,e,t){let r=[];for(let n of p){if(!n?.abs_path||!W.existsSync(n.abs_path))continue;let s=W.readFileSync(n.abs_path,"utf-8").split(`
|
|
236
|
+
`);for(let o=0;o<s.length;o++){let i=s[o];for(let c of e)if(c.regex.test(i)){r.push({filePath:n.path,line:o+1,kind:c.kind,text:i.trim()});break}if(r.length>=t)return r}}return r}function mt(p,e){let t=We(p),r="(?:=|\\+=|-=|\\*=|/=|%=|\\|=|&=|\\^=|&&=|\\|\\|=|\\?\\?=)",n=[{kind:"declaration",regex:new RegExp(`\\b(?:const|let|var)\\s+${t}\\b`)},{kind:"assignment",regex:new RegExp(`\\b${t}\\b\\s*${r}`)},{kind:"update",regex:new RegExp(`(?:\\+\\+|--)\\s*\\b${t}\\b|\\b${t}\\b\\s*(?:\\+\\+|--)`)}];return e&&n.push({kind:"property_assignment",regex:new RegExp(`\\b${t}\\.[A-Za-z_$][\\w$]*\\s*${r}`)},{kind:"indexed_assignment",regex:new RegExp(`\\b${t}\\s*\\[[^\\]]+\\]\\s*${r}`)}),n}function ce(p,e){if(!(!p||typeof p!="object")){e(p);for(let t of Object.keys(p)){if(t==="type"||t==="loc"||t==="start"||t==="end")continue;let r=p[t];if(Array.isArray(r))for(let n of r)n&&typeof n=="object"&&n.type&&ce(n,e);else r&&typeof r=="object"&&r.type&&ce(r,e);}}}function Be(p){try{return ht("@babel/parser").parse(p,{sourceType:"module",plugins:["typescript","jsx","decorators-legacy"],errorRecovery:!0})}catch{return null}}function He(p,e){if(!p.endsWith(".vue"))return [{content:e,lineOffset:1}];try{let{parse:s}=ht("@vue/compiler-sfc"),{descriptor:o}=s(e),i=[];if(o.script?.content&&i.push({content:o.script.content,lineOffset:o.script.loc.start.line}),o.scriptSetup?.content&&i.push({content:o.scriptSetup.content,lineOffset:o.scriptSetup.loc.start.line}),i.length>0)return i}catch{}let t=e.match(/<script\b[^>]*>([\s\S]*?)<\/script>/i);if(!t||!t[1])return [];let n=e.slice(0,t.index||0).split(`
|
|
237
|
+
`).length;return [{content:t[1],lineOffset:n}]}function G(p,e){return (p.loc?.start?.line??1)+e-1}function ae(p){let e=p.property;return e?e.type==="Identifier"?String(e.name||""):e.type==="Literal"?String(e.value||""):null:null}function gt(p,e){if(p.type!=="MemberExpression")return false;let t=p.object;return !t||t.type!=="ThisExpression"?false:ae(p)===e}function Fe(p,e){return !!p&&p.type==="Identifier"&&String(p.name||"")===e}function xe(p){let e=p.object;return e?e.type==="Identifier"?String(e.name||""):e.type==="MemberExpression"&&e.object?.type==="ThisExpression"&&ae(e)||null:null}function yt(p){let e=new Set;return p.filter(t=>{let r=`${t.filePath}:${t.line}:${t.kind}:${t.text}`;return e.has(r)?false:(e.add(r),true)})}function qt(p,e,t){let r=[];for(let n of p){if(!n.abs_path||!W.existsSync(n.abs_path))continue;let s=W.readFileSync(n.abs_path,"utf-8"),o=s.split(`
|
|
238
|
+
`),i=He(n.path||D.basename(n.abs_path),s);for(let c of i){let a=Be(c.content);a&&ce(a,u=>{if(r.length>=t||u.type!=="VariableDeclarator")return;let d=u.id;if(!d||d.type!=="ObjectPattern")return;let l=d.properties||[];for(let f of l){if(f.type!=="ObjectProperty"&&f.type!=="Property")continue;let g=f.key,m=f.value,h=g?.type==="Identifier"?String(g.name||""):null;if(h!==e)continue;let E=m?.type==="Identifier"?String(m.name||""):h;if(!E)continue;let b=G(u,c.lineOffset),R=o[b-1]?.trim()||"";r.push({alias:E,filePath:n.path,line:b,text:R});}});}}return r}function Me(p,e,t,r){let n=[];for(let s of p){if(!s.abs_path||!W.existsSync(s.abs_path))continue;let o=W.readFileSync(s.abs_path,"utf-8"),i=o.split(`
|
|
239
|
+
`),c=He(s.path||D.basename(s.abs_path),o);for(let a of c){let u=Be(a.content);if(u&&(ce(u,d=>{if(!(n.length>=r)){if(d.type==="VariableDeclarator"){let l=d.id;if(Fe(l,e)){let f=G(d,a.lineOffset);n.push({filePath:s.path,line:f,kind:"declaration",text:i[f-1]?.trim()||""});}}if(d.type==="AssignmentExpression"){let l=d.left;if(!l)return;let f=G(d,a.lineOffset);if(Fe(l,e)||gt(l,e)){n.push({filePath:s.path,line:f,kind:"assignment",text:i[f-1]?.trim()||""});return}t&&l.type==="MemberExpression"&&xe(l)===e&&n.push({filePath:s.path,line:f,kind:l.computed?"indexed_assignment":"property_assignment",text:i[f-1]?.trim()||""});}if(d.type==="UpdateExpression"){let l=d.argument;if(!l)return;if(Fe(l,e)||gt(l,e)){let f=G(d,a.lineOffset);n.push({filePath:s.path,line:f,kind:"update",text:i[f-1]?.trim()||""});}}}}),n.length>=r))break}if(n.length>=r)break}return yt(n).slice(0,r)}function De(p,e,t,r){let n=[];for(let s of p){if(!s.abs_path||!W.existsSync(s.abs_path))continue;let o=W.readFileSync(s.abs_path,"utf-8"),i=o.split(`
|
|
240
|
+
`),c=He(s.path||D.basename(s.abs_path),o);for(let a of c){let u=Be(a.content);if(u&&(ce(u,d=>{if(!(n.length>=r)){if(d.type==="AssignmentExpression"){let l=d.left;if(!l||l.type!=="MemberExpression"||xe(l)!==e)return;let g=ae(l);if(t&&g!==t)return;let m=G(d,a.lineOffset);n.push({filePath:s.path,line:m,kind:l.computed?"bracket":"dot",text:i[m-1]?.trim()||""});}if(d.type==="UpdateExpression"){let l=d.argument;if(!l||l.type!=="MemberExpression"||xe(l)!==e)return;let g=ae(l);if(t&&g!==t)return;let m=G(d,a.lineOffset);n.push({filePath:s.path,line:m,kind:l.computed?"bracket":"dot",text:i[m-1]?.trim()||""});}if(d.type==="UnaryExpression"&&d.operator==="delete"){let l=d.argument;if(!l||l.type!=="MemberExpression"||xe(l)!==e)return;let g=ae(l);if(t&&g!==t)return;let m=G(d,a.lineOffset);n.push({filePath:s.path,line:m,kind:"delete",text:i[m-1]?.trim()||""});}}}),n.length>=r))break}if(n.length>=r)break}return yt(n).slice(0,r)}function bt(p,e){p.registerTool("skimmer_find_symbol",{title:"\u667A\u80FD\u7B26\u53F7\u641C\u7D22\uFF08\u652F\u6301\u62FC\u5199\u9519\u8BEF\uFF09",description:`\u4E09\u5C42\u641C\u7D22\uFF1A\u7CBE\u786E\u5339\u914D \u2192 FTS5\u5168\u6587 \u2192 Levenshtein\u6A21\u7CCA\u3002
|
|
240
241
|
\u89E3\u51B3\u62FC\u5199\u9519\u8BEF\uFF1A\u641C "changeCash" \u80FD\u627E\u5230 "changeCashValue"\uFF0C\u5E76\u63D0\u793A "cash \u53EF\u80FD\u662F cache \u7684\u62FC\u5199\u9519\u8BEF"\u3002
|
|
241
242
|
\u9A7C\u5CF0\u62C6\u8BCD\uFF1A\u641C "change cache" \u4E5F\u80FD\u627E\u5230 "changeCacheValue"\u3002
|
|
242
243
|
\u6846\u67B6\u611F\u77E5\uFF1A\u53EF\u6309 vue2/vue3/react \u8FC7\u6EE4\u3002
|
|
243
|
-
project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({query:z$1.string().describe('\u641C\u7D22\u8BCD\uFF0C\u5982 "changeCash" \u6216 "handle submit"'),project_path:z$1.string().optional().describe(K),category:z$1.enum(["state","computed","method","effect","prop","lifecycle","hook","component","mixin","function","all"]).optional().default("all").describe("\u7B26\u53F7\u7C7B\u578B\u8FC7\u6EE4"),framework:z$1.enum(["vue2","vue3","react","all"]).optional().default("all"),file_path:z$1.string().optional().describe('\u9650\u5B9A\u6587\u4EF6\u8DEF\u5F84\u641C\u7D22\uFF08\u5305\u542B\u5373\u53EF\uFF0C\u5982 "index.vue"\uFF09'),fuzzy:z$1.boolean().optional().default(true).describe("\u662F\u5426\u542F\u7528\u6A21\u7CCA\u5339\u914D\uFF08\u9ED8\u8BA4 true\uFF09"),limit:z$1.number().optional().default(15)}),annotations:{readOnlyHint:true,destructiveHint:false}},async({query:t,project_path:
|
|
244
|
+
project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({query:z$1.string().describe('\u641C\u7D22\u8BCD\uFF0C\u5982 "changeCash" \u6216 "handle submit"'),project_path:z$1.string().optional().describe(K),category:z$1.enum(["state","computed","method","effect","prop","lifecycle","hook","component","mixin","function","all"]).optional().default("all").describe("\u7B26\u53F7\u7C7B\u578B\u8FC7\u6EE4"),framework:z$1.enum(["vue2","vue3","react","all"]).optional().default("all"),file_path:z$1.string().optional().describe('\u9650\u5B9A\u6587\u4EF6\u8DEF\u5F84\u641C\u7D22\uFF08\u5305\u542B\u5373\u53EF\uFF0C\u5982 "index.vue"\uFF09'),fuzzy:z$1.boolean().optional().default(true).describe("\u662F\u5426\u542F\u7528\u6A21\u7CCA\u5339\u914D\uFF08\u9ED8\u8BA4 true\uFF09"),limit:z$1.number().optional().default(15)}),annotations:{readOnlyHint:true,destructiveHint:false}},async({query:t,project_path:r,category:n,framework:s,file_path:o,fuzzy:i,limit:c})=>{let{db:a}=e.getContext(r),d=new oe(a).search(t,{category:n==="all"?void 0:n,framework:s==="all"?void 0:s,filePath:o,fuzzy:i,limit:c});if(d.length===0)return {content:[{type:"text",text:`\u{1F50D} \u641C\u7D22 "${t}" \u65E0\u7ED3\u679C
|
|
244
245
|
|
|
245
246
|
\u{1F4A1} \u5C1D\u8BD5:
|
|
246
247
|
skimmer_find_by_behavior \u6309\u884C\u4E3A\u641C\u7D22
|
|
@@ -248,25 +249,25 @@ project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({query:z$1.string(
|
|
|
248
249
|
`];return d.forEach((f,g)=>{let m=f.symbol,h=te(m.params_json,[]),E=h.length>0?`(${h.join(", ")})`:"",b=Z(m.start_line,m.end_line);l.push(`${g+1}. ${m.name}${E} [${m.category}/${m.framework}] \u5339\u914D\u5EA6: ${f.score}%`),l.push(` \u{1F4C4} ${f.filePath}:${b}`),l.push(` \u{1F3AF} ${f.matchReason}`),f.spellingSuggestion&&l.push(` \u{1F4A1} ${f.spellingSuggestion}`),m.default_value&&l.push(` \u{1F4CC} \u9ED8\u8BA4\u503C: ${m.default_value}`),l.push("");}),{content:[{type:"text",text:l.join(`
|
|
249
250
|
`)}]}}),p.registerTool("skimmer_get_code_slice",{title:"\u83B7\u53D6\u7CBE\u51C6\u4EE3\u7801\u7247\u6BB5",description:`\u8FD4\u56DE\u6307\u5B9A\u51FD\u6570/\u53D8\u91CF\u7684\u5B8C\u6574\u4EE3\u7801\uFF0C\u907F\u514D\u8BFB\u53D6\u5927\u6587\u4EF6\u6D6A\u8D39 Token\u3002
|
|
250
251
|
\u540C\u65F6\u8FD4\u56DE\u8BE5\u7B26\u53F7\u7684\u884C\u4E3A\u6807\u7B7E\uFF08\u64CD\u4F5C\u4E86\u54EA\u4E9B\u5916\u90E8 API\uFF09\u3002
|
|
251
|
-
project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({file_path:z$1.string().describe("\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u9879\u76EE\u6839\u76EE\u5F55\uFF09"),symbol_name:z$1.string().describe("\u51FD\u6570\u6216\u53D8\u91CF\u540D"),project_path:z$1.string().optional().describe(K),context_lines:z$1.number().optional().default(0).describe("\u4E0A\u4E0B\u65B9\u989D\u5916\u5C55\u793A\u7684\u884C\u6570")}),annotations:{readOnlyHint:true,destructiveHint:false}},async({file_path:t,symbol_name:
|
|
252
|
+
project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({file_path:z$1.string().describe("\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84\uFF08\u76F8\u5BF9\u4E8E\u9879\u76EE\u6839\u76EE\u5F55\uFF09"),symbol_name:z$1.string().describe("\u51FD\u6570\u6216\u53D8\u91CF\u540D"),project_path:z$1.string().optional().describe(K),context_lines:z$1.number().optional().default(0).describe("\u4E0A\u4E0B\u65B9\u989D\u5916\u5C55\u793A\u7684\u884C\u6570")}),annotations:{readOnlyHint:true,destructiveHint:false}},async({file_path:t,symbol_name:r,project_path:n,context_lines:s})=>{let{db:o}=e.getContext(n),i=o.getSymbolByName(r,t);if(!i)return {content:[{type:"text",text:`\u274C \u672A\u627E\u5230: ${r}
|
|
252
253
|
\u{1F4C4} \u6587\u4EF6: ${t}
|
|
253
254
|
|
|
254
|
-
\u{1F4A1} \u8BD5\u8BD5: skimmer_find_symbol({ query: "${
|
|
255
|
+
\u{1F4A1} \u8BD5\u8BD5: skimmer_find_symbol({ query: "${r}" })`}]};let c=i.abs_path;if(!W.existsSync(c))return {content:[{type:"text",text:`\u274C \u6587\u4EF6\u4E0D\u5B58\u5728: ${c}`}]};let u=W.readFileSync(c,"utf-8").split(`
|
|
255
256
|
`),d=Math.max(1,i.start_line-s)-1,l=Math.min(u.length,i.end_line+s),f=u.slice(d,l).join(`
|
|
256
|
-
`),{behaviors:g}=o.getFileOutline(t),m=g.filter(R=>R.symbol_name===
|
|
257
|
+
`),{behaviors:g}=o.getFileOutline(t),m=g.filter(R=>R.symbol_name===r),h=c.split(".").pop()||"js",E=["tsx","jsx"].includes(h)?"jsx":["ts"].includes(h)?"typescript":"javascript",b=[`\u{1F4CD} ${i.name} [${i.category}/${i.framework}]`,`\u{1F4C4} ${t}:${Z(i.start_line,i.end_line)}`];if(i.jsdoc&&b.push(`\u{1F4DD} ${i.jsdoc}`),m.length>0){let R=[...new Set(m.map(x=>`[${x.category}:${x.api_name}.${x.operation}${x.detail?`("${x.detail}")`:""}]`))];b.push(`\u{1F3F7}\uFE0F \u884C\u4E3A: ${R.join(" ")}`);}return b.push(`
|
|
257
258
|
\`\`\`${E}`),b.push(f),b.push("```"),{content:[{type:"text",text:b.join(`
|
|
258
259
|
`)}]}}),p.registerTool("skimmer_trace_assignments",{title:"\u8FFD\u8E2A\u53D8\u91CF\u8D4B\u503C\u94FE\u8DEF\uFF08\u8F7B\u91CF\uFF09",description:`\u3010\u964D\u7EA7\u5DE5\u5177\u3011\u4EC5\u5728\u4EE5\u4E0B\u573A\u666F\u5355\u72EC\u4F7F\u7528\uFF1A\u53EA\u9700\u67E5\u770B\u67D0\u4E2A\u7B80\u5355\u53D8\u91CF\uFF08\u975E\u5BF9\u8C61\uFF09\u7684\u8D4B\u503C\u4F4D\u7F6E\uFF0C\u4E14\u4E0D\u5173\u5FC3\u5C5E\u6027\u4FEE\u6539/\u53C2\u6570\u4F20\u9012/storage\u94FE\u8DEF\u3002
|
|
259
260
|
\u26A0\uFE0F \u7EDD\u5927\u591A\u6570\u53D8\u91CF\u6EAF\u6E90\u573A\u666F\u8BF7\u4F18\u5148\u4F7F\u7528 skimmer_trace_data_lifecycle\uFF0C\u5B83\u80FD\u4E00\u6B21\u62FF\u5230\u6240\u6709\u4FE1\u606F\u3002
|
|
260
261
|
\u2705 \u672C\u5DE5\u5177\u9002\u5408\uFF1Aloading / errorMsg / count \u8FD9\u7C7B\u7B80\u5355 flag \u7684\u8D4B\u503C\u8FFD\u8E2A\u3002
|
|
261
|
-
\u274C \u4E0D\u9002\u5408\uFF1AstorageParams / savedData \u8FD9\u7C7B\u5BF9\u8C61\u3001\u9700\u8981\u8FFD\u8E2A\u5B8C\u6574\u6570\u636E\u6D41\u7684\u573A\u666F\u3002`,inputSchema:z$1.object({variable:z$1.string().describe('\u53D8\u91CF\u540D\uFF0C\u5982 "changeResult"'),project_path:z$1.string().optional().describe(K),file_path:z$1.string().optional().describe("\u9650\u5B9A\u6587\u4EF6\u8DEF\u5F84\uFF08\u5305\u542B\u5373\u53EF\uFF09"),include_properties:z$1.boolean().optional().default(true).describe("\u662F\u5426\u5305\u542B variable.xxx / variable[...] \u8D4B\u503C"),limit:z$1.number().optional().default(80)}),annotations:{readOnlyHint:true,destructiveHint:false}},async({variable:t,project_path:
|
|
262
|
+
\u274C \u4E0D\u9002\u5408\uFF1AstorageParams / savedData \u8FD9\u7C7B\u5BF9\u8C61\u3001\u9700\u8981\u8FFD\u8E2A\u5B8C\u6574\u6570\u636E\u6D41\u7684\u573A\u666F\u3002`,inputSchema:z$1.object({variable:z$1.string().describe('\u53D8\u91CF\u540D\uFF0C\u5982 "changeResult"'),project_path:z$1.string().optional().describe(K),file_path:z$1.string().optional().describe("\u9650\u5B9A\u6587\u4EF6\u8DEF\u5F84\uFF08\u5305\u542B\u5373\u53EF\uFF09"),include_properties:z$1.boolean().optional().default(true).describe("\u662F\u5426\u5305\u542B variable.xxx / variable[...] \u8D4B\u503C"),limit:z$1.number().optional().default(80)}),annotations:{readOnlyHint:true,destructiveHint:false}},async({variable:t,project_path:r,file_path:n,include_properties:s,limit:o})=>{let{db:i}=e.getContext(r),c=i.listFiles(n),a=Math.min(300,Math.max(1,o||80)),u=s??true,d=Me(c,t,u,a);if(d.length===0){let f=mt(t,u);d=ie(c,f,a);}if(d.length===0)return {content:[{type:"text",text:`\u{1F9E9} \u53D8\u91CF\u8D4B\u503C\u8FFD\u8E2A: "${t}"
|
|
262
263
|
\u672A\u627E\u5230\u5339\u914D\u8D4B\u503C\u8BED\u53E5
|
|
263
|
-
\u8FC7\u6EE4: file_path=${
|
|
264
|
+
\u8FC7\u6EE4: file_path=${n||"*"} include_properties=${u}`}]};let l=[`\u{1F9E9} \u53D8\u91CF\u8D4B\u503C\u8FFD\u8E2A: "${t}"`,`\u8FC7\u6EE4: file_path=${n||"*"} include_properties=${u}`,`\u547D\u4E2D: ${d.length} \u5904`,""];return d.forEach((f,g)=>{l.push(`${g+1}. [${f.kind}] \u{1F4C4} ${f.filePath}:L${f.line}`),l.push(` ${f.text}`);}),{content:[{type:"text",text:l.join(`
|
|
264
265
|
`)}]}}),p.registerTool("skimmer_trace_property_changes",{title:"\u8FFD\u8E2A\u5BF9\u8C61\u5C5E\u6027\u4FEE\u6539",description:`\u3010\u964D\u7EA7\u5DE5\u5177\u3011\u4EC5\u5728\u4EE5\u4E0B\u573A\u666F\u5355\u72EC\u4F7F\u7528\uFF1A\u9700\u8981\u7CBE\u786E\u8FC7\u6EE4\u67D0\u4E00\u4E2A\u5177\u4F53\u5C5E\u6027\u5B57\u6BB5\uFF08\u5982 storageParams.receiveAdr\uFF09\uFF0C\u800C\u4E0D\u9700\u8981\u6574\u4F53\u8D4B\u503C/\u53C2\u6570\u4F20\u9012/storage\u94FE\u8DEF\u4FE1\u606F\u3002
|
|
265
266
|
\u26A0\uFE0F \u7EDD\u5927\u591A\u6570\u5BF9\u8C61\u6EAF\u6E90\u573A\u666F\u8BF7\u4F18\u5148\u4F7F\u7528 skimmer_trace_data_lifecycle\uFF0C\u5B83\u80FD\u4E00\u6B21\u62FF\u5230\u6240\u6709\u4FE1\u606F\u3002
|
|
266
267
|
\u2705 \u672C\u5DE5\u5177\u9002\u5408\uFF1Aobject.specificProp \u7684\u5355\u5B57\u6BB5\u7EA7\u522B\u7CBE\u786E\u8FFD\u8E2A\u3002
|
|
267
|
-
\u274C \u4E0D\u9002\u5408\uFF1A\u9700\u8981\u4E86\u89E3\u5BF9\u8C61\u6574\u4F53\u6765\u6E90\u6216\u6570\u636E\u6D41\u5411\u7684\u573A\u666F\u3002`,inputSchema:z$1.object({object:z$1.string().describe('\u5BF9\u8C61\u540D\uFF0C\u5982 "storageParams" / "params"'),property:z$1.string().optional().describe('\u5C5E\u6027\u540D\uFF0C\u5982 "receiveAdr"'),project_path:z$1.string().optional().describe(K),file_path:z$1.string().optional().describe("\u9650\u5B9A\u6587\u4EF6\u8DEF\u5F84\uFF08\u5305\u542B\u5373\u53EF\uFF09"),limit:z$1.number().optional().default(80)}),annotations:{readOnlyHint:true,destructiveHint:false}},async({object:t,property:
|
|
268
|
+
\u274C \u4E0D\u9002\u5408\uFF1A\u9700\u8981\u4E86\u89E3\u5BF9\u8C61\u6574\u4F53\u6765\u6E90\u6216\u6570\u636E\u6D41\u5411\u7684\u573A\u666F\u3002`,inputSchema:z$1.object({object:z$1.string().describe('\u5BF9\u8C61\u540D\uFF0C\u5982 "storageParams" / "params"'),property:z$1.string().optional().describe('\u5C5E\u6027\u540D\uFF0C\u5982 "receiveAdr"'),project_path:z$1.string().optional().describe(K),file_path:z$1.string().optional().describe("\u9650\u5B9A\u6587\u4EF6\u8DEF\u5F84\uFF08\u5305\u542B\u5373\u53EF\uFF09"),limit:z$1.number().optional().default(80)}),annotations:{readOnlyHint:true,destructiveHint:false}},async({object:t,property:r,project_path:n,file_path:s,limit:o})=>{let{db:i}=e.getContext(n),c=i.listFiles(s),a=Math.min(300,Math.max(1,o||80)),u=De(c,t,r,a);if(u.length===0){let l=We(t),f="(?:=|\\+=|-=|\\*=|/=|%=|\\|=|&=|\\^=|&&=|\\|\\|=|\\?\\?=)",g=[];if(r){let m=We(r);g.push({kind:"dot",regex:new RegExp(`\\b${l}\\.${m}\\s*${f}`)},{kind:"bracket",regex:new RegExp(`\\b${l}\\s*\\[(?:'${m}'|"${m}")\\]\\s*${f}`)},{kind:"delete",regex:new RegExp(`\\bdelete\\s+${l}\\.(?:${m})\\b`)});}else g.push({kind:"dot",regex:new RegExp(`\\b${l}\\.[A-Za-z_$][\\w$]*\\s*${f}`)},{kind:"bracket",regex:new RegExp(`\\b${l}\\s*\\[(?:'[^']+'|"[^"]+")\\]\\s*${f}`)},{kind:"delete",regex:new RegExp(`\\bdelete\\s+${l}\\.[A-Za-z_$][\\w$]*\\b`)});u=ie(c,g,a);}if(u.length===0)return {content:[{type:"text",text:`\u{1F9ED} \u5C5E\u6027\u4FEE\u6539\u8FFD\u8E2A: ${t}${r?`.${r}`:".*"}
|
|
268
269
|
\u672A\u627E\u5230\u5339\u914D\u8BED\u53E5
|
|
269
|
-
\u8FC7\u6EE4: file_path=${s||"*"}`}]};let d=[`\u{1F9ED} \u5C5E\u6027\u4FEE\u6539\u8FFD\u8E2A: ${t}${
|
|
270
|
+
\u8FC7\u6EE4: file_path=${s||"*"}`}]};let d=[`\u{1F9ED} \u5C5E\u6027\u4FEE\u6539\u8FFD\u8E2A: ${t}${r?`.${r}`:".*"}`,`\u8FC7\u6EE4: file_path=${s||"*"}`,`\u547D\u4E2D: ${u.length} \u5904`,""];return u.forEach((l,f)=>{d.push(`${f+1}. [${l.kind}] \u{1F4C4} ${l.filePath}:L${l.line}`),d.push(` ${l.text}`);}),{content:[{type:"text",text:d.join(`
|
|
270
271
|
`)}]}}),p.registerTool("skimmer_find_by_behavior",{title:"\u6309\u884C\u4E3A\u6807\u7B7E\u641C\u7D22\u51FD\u6570",description:`\u6309 API \u8C03\u7528\u884C\u4E3A\u641C\u7D22\uFF0C\u5B8C\u5168\u7ED5\u8FC7\u547D\u540D\u95EE\u9898\u3002
|
|
271
272
|
\u793A\u4F8B:
|
|
272
273
|
- \u627E\u6240\u6709\u64CD\u4F5C localStorage \u7684\u51FD\u6570: { category: "storage" }
|
|
@@ -274,20 +275,20 @@ project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({file_path:z$1.str
|
|
|
274
275
|
- \u627E\u53D1\u8BF7\u6C42\u7684: { category: "network" }
|
|
275
276
|
- \u627E\u8DEF\u7531\u8DF3\u8F6C\u7684: { category: "router" }
|
|
276
277
|
- \u6309 key \u540D\u641C\u7D22: { keyword: "cacheData" }
|
|
277
|
-
project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({project_path:z$1.string().optional().describe(K),category:z$1.enum(["storage","network","router","vuex","dom","event","timer","i18n"]).optional().describe("\u884C\u4E3A\u7C7B\u522B"),api_name:z$1.string().optional().describe('"localStorage" / "axios" / "$router"'),operation:z$1.string().optional().describe('"setItem" / "get" / "push" / "commit"'),keyword:z$1.string().optional().describe('\u5728\u53C2\u6570\u503C\u4E2D\u641C\u7D22\uFF08\u5982 key \u540D "cacheData"\uFF09'),file_path:z$1.string().optional().describe('\u9650\u5B9A\u6587\u4EF6\u8DEF\u5F84\u641C\u7D22\uFF08\u5305\u542B\u5373\u53EF\uFF0C\u5982 "src/views/apply/index.vue"\uFF09')}),annotations:{readOnlyHint:true,destructiveHint:false}},async({project_path:t,category:
|
|
278
|
-
\u8FC7\u6EE4\u6761\u4EF6: ${JSON.stringify({category:
|
|
278
|
+
project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({project_path:z$1.string().optional().describe(K),category:z$1.enum(["storage","network","router","vuex","dom","event","timer","i18n"]).optional().describe("\u884C\u4E3A\u7C7B\u522B"),api_name:z$1.string().optional().describe('"localStorage" / "axios" / "$router"'),operation:z$1.string().optional().describe('"setItem" / "get" / "push" / "commit"'),keyword:z$1.string().optional().describe('\u5728\u53C2\u6570\u503C\u4E2D\u641C\u7D22\uFF08\u5982 key \u540D "cacheData"\uFF09'),file_path:z$1.string().optional().describe('\u9650\u5B9A\u6587\u4EF6\u8DEF\u5F84\u641C\u7D22\uFF08\u5305\u542B\u5373\u53EF\uFF0C\u5982 "src/views/apply/index.vue"\uFF09')}),annotations:{readOnlyHint:true,destructiveHint:false}},async({project_path:t,category:r,api_name:n,operation:s,keyword:o,file_path:i})=>{let{db:c}=e.getContext(t),u=new oe(c).searchByBehavior({category:r,apiName:n,operation:s,keyword:o,filePath:i});if(u.length===0)return {content:[{type:"text",text:`\u{1F3F7}\uFE0F \u672A\u627E\u5230\u5339\u914D\u7684\u884C\u4E3A
|
|
279
|
+
\u8FC7\u6EE4\u6761\u4EF6: ${JSON.stringify({category:r,api_name:n,operation:s,keyword:o,file_path:i})}`}]};let d=new Map;for(let f of u){let g=`${f.category}:${f.apiName}`;d.has(g)||d.set(g,[]),d.get(g).push(f);}let l=[`\u{1F3F7}\uFE0F \u884C\u4E3A\u641C\u7D22\u7ED3\u679C \u2014 ${u.length} \u6761
|
|
279
280
|
`];for(let[f,g]of d){let[m,h]=f.split(":"),E=new Map;for(let b of g)E.has(b.operation)||E.set(b.operation,[]),E.get(b.operation).push(b);l.push(`\u{1F4C2} ${m} \u2192 ${h}:`);for(let[b,R]of E){l.push(` ${b}:`);for(let x of R){let $=x.detail?` key="${x.detail}"`:"";l.push(` \u2022 ${x.symbolName}${$} \u{1F4C4} ${x.filePath}:${Z(x.startLine,x.endLine)}`);}}l.push("");}return {content:[{type:"text",text:l.join(`
|
|
280
|
-
`)}]}}),p.registerTool("skimmer_get_call_graph",{title:"\u83B7\u53D6\u51FD\u6570\u8C03\u7528\u5173\u7CFB\u56FE\u8C31",description:"\u67E5\u770B\u51FD\u6570\u88AB\u8C01\u8C03\u7528\uFF08callers\uFF09\u4EE5\u53CA\u5B83\u8C03\u7528\u4E86\u4EC0\u4E48\uFF08callees\uFF09\u3002project_path \u53EF\u7701\u7565\u3002",inputSchema:z$1.object({symbol_name:z$1.string().describe("\u51FD\u6570\u540D"),project_path:z$1.string().optional().describe(K),file_path:z$1.string().optional().describe("\u6587\u4EF6\u8DEF\u5F84\uFF08\u540C\u540D\u51FD\u6570\u65F6\u7528\u4E8E\u7CBE\u786E\u5B9A\u4F4D\uFF09"),direction:z$1.enum(["callers","callees","both"]).optional().default("both"),arg_keyword:z$1.string().optional().describe('\u8C03\u7528\u53C2\u6570\u5173\u952E\u5B57\u8FC7\u6EE4\uFF08\u5982 "storageParams"\uFF09')}),annotations:{readOnlyHint:true,destructiveHint:false}},async({symbol_name:t,project_path:
|
|
281
|
-
`];if(s==="callers"||s==="both"){let u=i.getCallers(t,
|
|
282
|
-
`)}]}}),p.registerTool("skimmer_get_blast_radius",{title:"\u8BC4\u4F30\u4FEE\u6539\u5F71\u54CD\u8303\u56F4",description:"\u5206\u6790\u4FEE\u6539\u67D0\u51FD\u6570\u4F1A\u5F71\u54CD\u54EA\u4E9B\u8C03\u7528\u70B9\uFF0C\u7ED9\u51FA\u98CE\u9669\u7B49\u7EA7\u3002\u4FEE\u6539\u524D\u8C03\u7528\u8BC4\u4F30\u98CE\u9669\u3002project_path \u53EF\u7701\u7565\u3002",inputSchema:z$1.object({symbol_name:z$1.string().describe("\u8981\u4FEE\u6539\u7684\u51FD\u6570\u540D"),project_path:z$1.string().optional().describe(K),file_path:z$1.string().optional().describe("\u6587\u4EF6\u8DEF\u5F84\uFF08\u540C\u540D\u65F6\u7CBE\u786E\u5B9A\u4F4D\uFF09")}),annotations:{readOnlyHint:true,destructiveHint:false}},async({symbol_name:t,project_path:
|
|
281
|
+
`)}]}}),p.registerTool("skimmer_get_call_graph",{title:"\u83B7\u53D6\u51FD\u6570\u8C03\u7528\u5173\u7CFB\u56FE\u8C31",description:"\u67E5\u770B\u51FD\u6570\u88AB\u8C01\u8C03\u7528\uFF08callers\uFF09\u4EE5\u53CA\u5B83\u8C03\u7528\u4E86\u4EC0\u4E48\uFF08callees\uFF09\u3002project_path \u53EF\u7701\u7565\u3002",inputSchema:z$1.object({symbol_name:z$1.string().describe("\u51FD\u6570\u540D"),project_path:z$1.string().optional().describe(K),file_path:z$1.string().optional().describe("\u6587\u4EF6\u8DEF\u5F84\uFF08\u540C\u540D\u51FD\u6570\u65F6\u7528\u4E8E\u7CBE\u786E\u5B9A\u4F4D\uFF09"),direction:z$1.enum(["callers","callees","both"]).optional().default("both"),arg_keyword:z$1.string().optional().describe('\u8C03\u7528\u53C2\u6570\u5173\u952E\u5B57\u8FC7\u6EE4\uFF08\u5982 "storageParams"\uFF09')}),annotations:{readOnlyHint:true,destructiveHint:false}},async({symbol_name:t,project_path:r,file_path:n,direction:s,arg_keyword:o})=>{let{db:i}=e.getContext(r),c=i.getSymbolByName(t,n),a=[`\u{1F4CA} ${t} \u7684\u8C03\u7528\u56FE\u8C31
|
|
282
|
+
`];if(s==="callers"||s==="both"){let u=i.getCallers(t,n,o);if(a.push(`\u2B06\uFE0F \u88AB\u8C03\u7528 (${u.length} \u5904):`),u.length===0)a.push(" \uFF08\u672A\u627E\u5230\u8C03\u7528\u8005\uFF09");else for(let d of u){let l=d.args?` \u53C2\u6570: "${d.args}"`:"";a.push(` \u2022 ${d.caller_name} [${d.category}] \u{1F4C4} ${d.file_path}:L${d.start_line}${l}`);}a.push("");}if((s==="callees"||s==="both")&&c){let u=i.getCallees(c.id);if(a.push(`\u2B07\uFE0F \u8C03\u7528\u4E86 (${u.length} \u4E2A):`),u.length===0)a.push(" \uFF08\u672A\u5206\u6790\u5230\u8C03\u7528\u5173\u7CFB\uFF09");else for(let d of u){let l=d.args?`("${d.args}")`:"";a.push(` \u2022 ${d.callee_name}${l} [${d.call_type}] L${d.line_number}`);}a.push("");}if(c){let{behaviors:u}=i.getFileOutline(c.file_path),d=u.filter(l=>l.symbol_name===t);if(d.length>0){a.push("\u{1F4E6} \u5916\u90E8\u72B6\u6001\u64CD\u4F5C:");for(let l of d){let f=l.detail?` ("${l.detail}")`:"";a.push(` \u2022 ${l.api_name}.${l.operation}${f} [${l.category}] L${l.line_number}`);}}}return {content:[{type:"text",text:a.join(`
|
|
283
|
+
`)}]}}),p.registerTool("skimmer_get_blast_radius",{title:"\u8BC4\u4F30\u4FEE\u6539\u5F71\u54CD\u8303\u56F4",description:"\u5206\u6790\u4FEE\u6539\u67D0\u51FD\u6570\u4F1A\u5F71\u54CD\u54EA\u4E9B\u8C03\u7528\u70B9\uFF0C\u7ED9\u51FA\u98CE\u9669\u7B49\u7EA7\u3002\u4FEE\u6539\u524D\u8C03\u7528\u8BC4\u4F30\u98CE\u9669\u3002project_path \u53EF\u7701\u7565\u3002",inputSchema:z$1.object({symbol_name:z$1.string().describe("\u8981\u4FEE\u6539\u7684\u51FD\u6570\u540D"),project_path:z$1.string().optional().describe(K),file_path:z$1.string().optional().describe("\u6587\u4EF6\u8DEF\u5F84\uFF08\u540C\u540D\u65F6\u7CBE\u786E\u5B9A\u4F4D\uFF09")}),annotations:{readOnlyHint:true,destructiveHint:false}},async({symbol_name:t,project_path:r,file_path:n})=>{let{db:s}=e.getContext(r),o=s.getCallers(t,n),i=s.getSymbolByName(t,n),{behaviors:c}=i?s.getFileOutline(i.file_path):{behaviors:[]},a=c.filter(f=>f.symbol_name===t),u=o.length===0?"\u{1F7E2}":o.length<=3?"\u{1F7E1}":"\u{1F534}",d=o.length===0?"\u4F4E":o.length<=3?"\u4E2D":"\u9AD8",l=[`\u{1F4A5} \u4FEE\u6539 ${t} \u7684\u5F71\u54CD\u8BC4\u4F30`,"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501",`${u} \u98CE\u9669\u7B49\u7EA7: ${d} (${o.length} \u5904\u76F4\u63A5\u8C03\u7528)`,""];if(o.length>0?(l.push("\u{1F534} \u76F4\u63A5\u5F71\u54CD:"),o.forEach((f,g)=>{l.push(` ${g+1}. ${f.caller_name} [${f.category}] \u{1F4C4} ${f.file_path}:L${f.start_line}`);}),l.push("")):l.push(`\u2705 \u65E0\u8C03\u7528\u8005\uFF0C\u5F71\u54CD\u8303\u56F4\u53EF\u63A7
|
|
283
284
|
`),a.length>0){l.push("\u{1F4E6} \u5916\u90E8\u72B6\u6001\u5F71\u54CD:");for(let f of a)l.push(` \u2022 ${f.api_name}.${f.operation}${f.detail?` key="${f.detail}"`:""} [${f.category}]`);l.push(`
|
|
284
285
|
\u26A0\uFE0F \u4FEE\u6539\u65F6\u6CE8\u610F\u5916\u90E8\u72B6\u6001\u7684\u8BFB\u5199\u683C\u5F0F\u4FDD\u6301\u4E00\u81F4`);}return {content:[{type:"text",text:l.join(`
|
|
285
286
|
`)}]}}),p.registerTool("skimmer_get_project_overview",{title:"\u83B7\u53D6\u9879\u76EE\u6574\u4F53\u6982\u89C8",description:`\u8FD4\u56DE\u9879\u76EE\u7684\u5168\u666F\u7EDF\u8BA1\uFF1A\u6587\u4EF6\u6570\u3001\u6846\u67B6\u5206\u5E03\u3001\u6700\u5927\u6587\u4EF6\u3001\u884C\u4E3A\u7EDF\u8BA1\u3002
|
|
286
|
-
\u652F\u6301\u5217\u51FA\u5F53\u524D\u6240\u6709\u5DF2\u7F13\u5B58\u7684\u9879\u76EE\u3002project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({project_path:z$1.string().optional().describe(K),list_all_projects:z$1.boolean().optional().default(false).describe("\u662F\u5426\u5217\u51FA\u6240\u6709\u5DF2\u7D22\u5F15\u7684\u9879\u76EE")}),annotations:{readOnlyHint:true,destructiveHint:false}},async({project_path:t,list_all_projects:
|
|
287
|
+
\u652F\u6301\u5217\u51FA\u5F53\u524D\u6240\u6709\u5DF2\u7F13\u5B58\u7684\u9879\u76EE\u3002project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({project_path:z$1.string().optional().describe(K),list_all_projects:z$1.boolean().optional().default(false).describe("\u662F\u5426\u5217\u51FA\u6240\u6709\u5DF2\u7D22\u5F15\u7684\u9879\u76EE")}),annotations:{readOnlyHint:true,destructiveHint:false}},async({project_path:t,list_all_projects:r})=>{if(r){let d=e.listProjects();if(d.length===0)return {content:[{type:"text",text:`\u{1F4CB} \u5F53\u524D\u6CA1\u6709\u5DF2\u7D22\u5F15\u7684\u9879\u76EE
|
|
287
288
|
|
|
288
289
|
\u4F7F\u7528 skimmer_index_project({ project_path: "/your/project" }) \u5F00\u59CB\u7D22\u5F15`}]};let l=[`\u{1F4CB} \u5DF2\u7D22\u5F15\u7684\u9879\u76EE (${d.length} \u4E2A):
|
|
289
290
|
`];return d.forEach((f,g)=>{l.push(`${g+1}. ${f.root}`),l.push(` \u6570\u636E\u5E93: ${f.dbPath}`);}),{content:[{type:"text",text:l.join(`
|
|
290
|
-
`)}]}}let{db:
|
|
291
|
+
`)}]}}let{db:n,projectRoot:s}=e.getContext(t),o=n.getProjectStats(),i=["\u{1F4CA} \u9879\u76EE\u6982\u89C8","\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501",`\u{1F4C1} ${s}`,"",`\u{1F4C8} \u6574\u4F53: \u6587\u4EF6 ${o.fileCount} | \u7B26\u53F7 ${o.symbolCount} | \u884C\u4E3A\u6807\u7B7E ${o.behaviorCount} | \u8C03\u7528\u5173\u7CFB ${o.relationCount}`,""],c=o.frameworkBreakdown;if(c?.length){let d={vue2:"\u{1F7E2} Vue2",vue3:"\u{1F535} Vue3",react:"\u269B\uFE0F React",js:"\u{1F4DC} JS",ts:"\u{1F4D8} TS"};i.push("\u{1F527} \u6846\u67B6\u5206\u5E03:");for(let l of c)i.push(` ${d[l.framework]||l.framework}: ${l.count} \u4E2A`);i.push("");}let a=o.topFiles;a?.length&&(i.push("\u{1F5C2}\uFE0F Top 10 \u6700\u5927\u6587\u4EF6:"),a.forEach((d,l)=>i.push(` ${l+1}. ${d.path} (${d.line_count} \u884C, ${d.symbol_count} \u7B26\u53F7)`)),i.push(""));let u=o.behaviorStats;if(u?.length){let d={storage:"\u{1F4BE} \u5B58\u50A8",network:"\u{1F310} \u7F51\u7EDC",router:"\u{1F6E3}\uFE0F \u8DEF\u7531",vuex:"\u{1F4E6} Vuex",dom:"\u{1F5A5}\uFE0F DOM",event:"\u{1F4E1} \u4E8B\u4EF6",timer:"\u23F1\uFE0F \u5B9A\u65F6\u5668",i18n:"\u{1F30D} \u56FD\u9645\u5316"};i.push("\u{1F3F7}\uFE0F \u884C\u4E3A\u7EDF\u8BA1:");for(let l of u)i.push(` ${d[l.category]||l.category}: ${l.count} \u5904`);i.push("");}return i.push(`\u{1F4BD} \u6570\u636E\u5E93: ${Math.round(o.dbSize/1024)} KB`),{content:[{type:"text",text:i.join(`
|
|
291
292
|
`)}]}}),p.registerTool("skimmer_trace_data_lifecycle",{title:"\u53D8\u91CF\u5B8C\u6574\u751F\u547D\u5468\u671F\u8FFD\u8E2A\uFF08\u4E00\u952E\u7248\uFF09",description:`\u2B50 \u3010\u9996\u9009\u5DE5\u5177\u3011\u8FFD\u8E2A\u53D8\u91CF/\u72B6\u6001\u7684\u5B8C\u6574\u6570\u636E\u751F\u547D\u5468\u671F\uFF0C\u4E00\u6B21\u8C03\u7528\u805A\u5408 4 \u4E2A\u7EF4\u5EA6\uFF0C\u66FF\u4EE3\u8FC7\u53BB\u591A\u6B65\u624B\u52A8\u8FFD\u8E2A\u3002
|
|
292
293
|
|
|
293
294
|
\u{1F3AF} \u89E6\u53D1\u89C4\u5219\uFF08\u9047\u5230\u4EE5\u4E0B\u4EFB\u610F\u4E00\u79CD\u95EE\u9898\uFF0C\u76F4\u63A5\u4F7F\u7528\u672C\u5DE5\u5177\uFF09\uFF1A
|
|
@@ -306,10 +307,10 @@ project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({project_path:z$1.
|
|
|
306
307
|
\u65E7\u65B9\u5F0F: trace_assignments \u2192 find_symbol \u2192 get_code_slice \u2192 find_by_behavior \u2192 trace_key_flow
|
|
307
308
|
\u65B0\u65B9\u5F0F: skimmer_trace_data_lifecycle({ variable: "xxx" }) \u2190 \u76F4\u63A5\u5F97\u5230\u5168\u90E8
|
|
308
309
|
|
|
309
|
-
project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({variable:z$1.string().describe('\u8981\u8FFD\u8E2A\u7684\u53D8\u91CF\u540D\u6216 key\uFF0C\u5982 "storageParams" / "savedData"'),project_path:z$1.string().optional().describe(K),file_path:z$1.string().optional().describe('\u9650\u5B9A\u6587\u4EF6\u8DEF\u5F84\uFF08\u5305\u542B\u5373\u53EF\uFF0C\u5982 "src/views/apply/index.vue"\uFF09'),storage_api:z$1.enum(["localStorage","sessionStorage","all"]).optional().default("all").describe("storage \u843D\u70B9\u8FC7\u6EE4"),max_depth:z$1.number().optional().default(2).describe("storage \u94FE\u8DEF\u5411\u4E0B\u8FFD\u8E2A\u6DF1\u5EA6\uFF081-5\uFF09"),limit:z$1.number().optional().default(40).describe("\u6BCF\u7EF4\u5EA6\u6700\u5927\u7ED3\u679C\u6570")}),annotations:{readOnlyHint:true,destructiveHint:false}},async({variable:t,project_path:
|
|
310
|
+
project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({variable:z$1.string().describe('\u8981\u8FFD\u8E2A\u7684\u53D8\u91CF\u540D\u6216 key\uFF0C\u5982 "storageParams" / "savedData"'),project_path:z$1.string().optional().describe(K),file_path:z$1.string().optional().describe('\u9650\u5B9A\u6587\u4EF6\u8DEF\u5F84\uFF08\u5305\u542B\u5373\u53EF\uFF0C\u5982 "src/views/apply/index.vue"\uFF09'),storage_api:z$1.enum(["localStorage","sessionStorage","all"]).optional().default("all").describe("storage \u843D\u70B9\u8FC7\u6EE4"),max_depth:z$1.number().optional().default(2).describe("storage \u94FE\u8DEF\u5411\u4E0B\u8FFD\u8E2A\u6DF1\u5EA6\uFF081-5\uFF09"),limit:z$1.number().optional().default(40).describe("\u6BCF\u7EF4\u5EA6\u6700\u5927\u7ED3\u679C\u6570")}),annotations:{readOnlyHint:true,destructiveHint:false}},async({variable:t,project_path:r,file_path:n,storage_api:s,max_depth:o,limit:i})=>{let{db:c}=e.getContext(r),a=Math.min(5,Math.max(1,o||2)),u=Math.min(120,Math.max(1,i||40)),d=c.listFiles(n),l=qt(d,t,20),f=[...new Set(l.map(N=>N.alias).filter(N=>N!==t))],g=Me(d,t,false,u);for(let N of f)g.push(...Me(d,N,false,Math.floor(u/2)));let m=g.length===0?ie(d,mt(t,false),u):[],h=g.length>0?g:m,E=De(d,t,void 0,u);for(let N of f)E.push(...De(d,N,void 0,Math.floor(u/2)));let b=E.length===0?ie(d,[{kind:"dot",regex:new RegExp(`\\b${t}\\.[A-Za-z_$][\\w$]*\\s*(?:=|\\+=|-=|\\*=|\\/=|%=|\\|=|&=|\\^=|&&=|\\|\\|=|\\?\\?=)`)},{kind:"bracket",regex:new RegExp(`\\b${t}\\s*\\[(?:'[^']+'|"[^"]+")\\]\\s*(?:=|\\+=)`)},{kind:"delete",regex:new RegExp(`\\bdelete\\s+${t}\\.[A-Za-z_$][\\w$]*\\b`)}],u):[],R=E.length>0?E:b,x=c.findRelationsByArgKeyword(t,n,u),$=ie(d,[{kind:"template",regex:new RegExp(`(?::\\w+|v-model|v-if|v-show|@\\w+)="[^"]*\\b${t}\\b|\\{\\{[^}]*\\b${t}\\b[^}]*\\}\\}`)},{kind:"return",regex:new RegExp(`\\breturn\\b[^=]*\\b${t}\\b`)},{kind:"watch",regex:new RegExp(`watch[^(]*['"]\\.?${t}['"]`)},{kind:"computed_read",regex:new RegExp(`=>[^=]*\\b${t}\\b|return[^=]*\\b${t}\\b`)},{kind:"arg_usage",regex:new RegExp(`\\(\\s*[^)]*\\b${t}\\b[^)]*\\)`)}],u),C=new RegExp(`\\b${t}\\b\\s*(?:=|\\+=|-=|\\*=|\\/=)(?!=)|\\b(?:const|let|var)\\s+${t}\\b`),q=new RegExp(`\\b${t}\\b\\.\\w+\\s*(?:=|\\+=|-=)(?!=)|\\b${t}\\b\\s*\\[`),Y=$.filter(N=>!C.test(N.text)&&!q.test(N.text)),Q=new Map,Se=(N,T)=>{if(!Q.has(N)){let{behaviors:v}=c.getFileOutline(N),L=new Map;for(let w of v){let X=String(w.symbol_name||"");L.has(X)||L.set(X,[]),L.get(X).push(w);}Q.set(N,L);}return (Q.get(N)?.get(T)||[]).filter(v=>String(v.category||"")!=="storage"?false:s==="all"?true:String(v.api_name||"").toLowerCase()===s.toLowerCase())},Et=(N,T)=>{let k=[],v=[{name:N,filePath:T,path:[N],level:0}],L=new Set([`${T}::${N}`]);for(;v.length>0;){let w=v.shift(),X=Se(w.filePath,w.name);if(X.length>0){k.push({path:w.path,file:w.filePath,behaviors:X});continue}if(w.level>=a)continue;let I=c.getSymbolByName(w.name,w.filePath);if(I||(I=c.getSymbolByName(w.name)),!I)continue;let de=String(I.file_path||I.abs_path||w.filePath),_t=c.getCallees(I.id);for(let xt of _t){let ee=String(xt.callee_name||"");if(!ee||ee.startsWith("$"))continue;let Ve=`${de}::${ee}`;L.has(Ve)||(L.add(Ve),v.push({name:ee,filePath:de,path:[...w.path,ee],level:w.level+1}));}}return k},Nt=f.length>0?` \u{1F517} \u53D1\u73B0\u89E3\u6784\u522B\u540D: ${f.map(N=>`"${N}"`).join(", ")}\uFF08\u5DF2\u4E00\u5E76\u8FFD\u8E2A\uFF09`:"",A=[`\u{1F52C} \u53D8\u91CF\u751F\u547D\u5468\u671F\u8FFD\u8E2A: "${t}"`,"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501",`\u8FC7\u6EE4: file_path=${n||"*"} storage_api=${s} depth=${a}${Nt}`,""];if(A.push(`\u2460 \u58F0\u660E & \u6574\u4F53\u8D4B\u503C (${h.length} \u5904)`),h.length===0)A.push(" \uFF08\u672A\u627E\u5230\uFF09");else {let N=["declaration","assignment","update"],T=new Map;for(let k of h)T.has(k.kind)||T.set(k.kind,[]),T.get(k.kind).push(k);for(let k of [...N,...Array.from(T.keys()).filter(v=>!N.includes(v))]){let v=T.get(k);!v||v.length===0||(A.push(` \u25B8 [${k}]`),v.slice(0,15).forEach(L=>A.push(` \u{1F4C4} ${L.filePath}:L${L.line} ${L.text}`)));}}if(A.push(""),A.push(`\u2461 \u5C5E\u6027\u4FEE\u6539 (${R.length} \u5904)`),R.length===0?A.push(' \uFF08\u672A\u627E\u5230 object.prop \u6216 object["prop"] \u5199\u5165\uFF09'):R.slice(0,20).forEach(N=>A.push(` \u{1F4C4} ${N.filePath}:L${N.line} [${N.kind}] ${N.text}`)),A.push(""),A.push(`\u2462 \u4F5C\u4E3A\u53C2\u6570\u88AB\u4F20\u5165\u8C03\u7528 (${x.length} \u5904)`),x.length===0?A.push(" \uFF08\u672A\u53D1\u73B0\u4EE5\u8BE5\u53D8\u91CF\u4F5C\u4E3A\u53C2\u6570\u7684\u51FD\u6570\u8C03\u7528\uFF09"):x.slice(0,20).forEach(N=>{let T=String(N.args||"");A.push(` \u{1F4C4} ${N.file_path}:L${N.line_number} ${N.caller_name} \u2192 ${N.callee_name} \u53C2\u6570: "${T}"`);}),A.push(""),A.push(`\u2463 \u8BFB\u53D6/\u4F7F\u7528 (${Y.length} \u5904)`),Y.length===0)A.push(" \uFF08\u672A\u53D1\u73B0 template \u7ED1\u5B9A / watch / computed / return \u4E2D\u7684\u5F15\u7528\uFF09");else {let N=new Map;for(let k of Y)N.has(k.kind)||N.set(k.kind,[]),N.get(k.kind).push(k);let T={template:"\u{1F5BC}\uFE0F template \u7ED1\u5B9A",return:"\u21A9\uFE0F return \u8FD4\u56DE",watch:"\u{1F441}\uFE0F watch \u76D1\u542C",computed_read:"\u{1F9EE} computed \u5F15\u7528",arg_usage:"\u{1F4E8} \u51FD\u6570\u53C2\u6570\u4F7F\u7528"};for(let[k,v]of N)A.push(` \u25B8 ${T[k]||k}`),v.slice(0,8).forEach(L=>A.push(` \u{1F4C4} ${L.filePath}:L${L.line} ${L.text}`));}A.push("");let pe=0;if(A.push(`\u2464 Storage \u843D\u70B9\u8FFD\u8E2A (storage_api=${s}, depth=${a})`),x.length===0)A.push(" \uFF08\u65E0\u8C03\u7528\u5165\u53E3\uFF0C\u65E0\u6CD5\u5C55\u5F00 storage \u8FFD\u8E2A\uFF09");else {let N=new Map;for(let T of x){let k=`${T.file_path}::${T.callee_name}`;N.has(k)||N.set(k,T);}for(let[,T]of N){let k=String(T.callee_name||""),v=String(T.file_path||""),L=Et(k,v);L.length!==0&&(pe+=1,L.slice(0,3).forEach(w=>{let X=w.file!==v?` \u2197 \u8DE8\u6587\u4EF6: ${w.file}`:"";A.push(` \u94FE\u8DEF: ${w.path.join(" \u2192 ")}${X}`),w.behaviors.forEach(I=>{let de=I.detail?`("${String(I.detail)}")`:"";A.push(` \u843D\u70B9: ${I.api_name}.${I.operation}${de} [${I.category}] L${I.line_number}`);});}));}pe===0&&A.push(` \uFF08\u5728 depth=${a} \u5C42\u5185\u672A\u627E\u5230 storage \u5199\u5165\u94FE\u8DEF\uFF09`);}return A.push(""),A.push("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"),A.push("\u2705 \u6C47\u603B:"),A.push(` \u2460 \u58F0\u660E/\u8D4B\u503C: ${h.length} \u5904`),A.push(` \u2461 \u5C5E\u6027\u4FEE\u6539: ${R.length} \u5904`),A.push(` \u2462 \u53C2\u6570\u4F20\u9012: ${x.length} \u5904`),A.push(` \u2463 \u8BFB\u53D6\u5F15\u7528: ${Y.length} \u5904`),A.push(` \u2464 storage: ${pe>0?`\u2713 \u53D1\u73B0\u5199\u5165\u94FE\u8DEF (${pe} \u6761)`:"\u2717 \u672A\u53D1\u73B0"}`),{content:[{type:"text",text:A.join(`
|
|
310
311
|
`)}]}});}var le=new he,Ae=new McpServer({name:"frontend-code-skimmer",version:"0.1.0"});ut(Ae,le);ft(Ae,le);bt(Ae,le);async function Qt(){if(process.env.SKIMMER_AUTO_INDEX==="true"&&process.env.SKIMMER_PROJECT){process.stderr.write(`[Frontend-Code-Skimmer] \u81EA\u52A8\u7D22\u5F15: ${process.env.SKIMMER_PROJECT}
|
|
311
|
-
`);try{let{Indexer:
|
|
312
|
-
`);}catch(
|
|
312
|
+
`);try{let{Indexer:r}=await Promise.resolve().then(()=>(Ie(),dt)),{db:n,projectRoot:s}=le.getContext(process.env.SKIMMER_PROJECT),i=await new r(s,n).indexProject();process.stderr.write(`[Frontend-Code-Skimmer] \u5B8C\u6210: ${i.indexedFiles} \u6587\u4EF6, ${i.totalSymbols} \u7B26\u53F7
|
|
313
|
+
`);}catch(r){process.stderr.write(`[Frontend-Code-Skimmer] \u7D22\u5F15\u5931\u8D25: ${String(r)}
|
|
313
314
|
`);}}let e=new StdioServerTransport;await Ae.connect(e),process.stderr.write(`[Frontend-Code-Skimmer MCP] \u5DF2\u542F\u52A8
|
|
314
315
|
`),process.stderr.write(`[Frontend-Code-Skimmer MCP] \u652F\u6301\u6846\u67B6: Vue 2 / Vue 3 / React Hooks
|
|
315
316
|
`),process.stderr.write(`[Frontend-Code-Skimmer MCP] \u652F\u6301\u6A21\u5F0F: \u52A8\u6001\u4EFB\u610F\u9879\u76EE\uFF08\u65E0\u9700\u542F\u52A8\u65F6\u6307\u5B9A\uFF09
|
package/package.json
CHANGED