@jokeran/frontend-code-skimmer 0.2.7 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +4 -3
  2. package/dist/index.js +327 -152
  3. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,40 +1,52 @@
1
1
  #!/usr/bin/env node
2
- import H from'path';import'url';import nn,{createHash}from'crypto';import {createRequire}from'module';import F from'fs';import Ln from'fast-glob';import {McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import an from'os';import rn from'better-sqlite3';import {z as z$1}from'zod';var en=Object.defineProperty;var J=(l,e)=>()=>(l&&(e=l(l=0)),e);var tn=(l,e)=>{for(var t in e)en(l,t,{get:e[t],enumerable:true});};var w=J(()=>{});function A(l){return l.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 Ae(l,e){let t=l.length,n=e.length,s=Array.from({length:t+1},(r,o)=>Array.from({length:n+1},(i,a)=>o===0?a:a===0?o:0));for(let r=1;r<=t;r++)for(let o=1;o<=n;o++)l[r-1]===e[o-1]?s[r][o]=s[r-1][o-1]:s[r][o]=1+Math.min(s[r-1][o],s[r][o-1],s[r-1][o-1]);return s[t][n]}function pt(l){return nn.createHash("md5").update(l).digest("hex")}function dt(l){if(!l)return 0;let e=1;for(let t=0;t<l.length;t++)l[t]===`
3
- `&&e++;return e}function le(l,e){return l===e?`L${l}`:`L${l}-L${e}`}function xe(l,e){return H.relative(e,l).replace(/\\/g,"/")}function me(l,e){if(!l)return e;try{return JSON.parse(l)}catch{return e}}function V(l,e){let t=l.split(`
4
- `),s=e-1-1;for(;s>=0&&t[s].trim()==="";)s--;if(s<0||!t[s].trim().endsWith("*/"))return;let r=s;for(;r>0&&!t[r].trim().startsWith("/**");)r--;if(t[r].trim().startsWith("/**"))return t.slice(r,s+1).map(o=>o.replace(/^\s*\*\s?/,"").replace(/\/\*\*/,"").replace(/\*\//,"").trim()).filter(o=>o.length>0).join(" ")}function ut(l,e){let t=l.toLowerCase(),n=e.toLowerCase();if(t===n)return 100;if(n.includes(t)||t.includes(n))return 85;let s=Ae(t,n),r=Math.max(t.length,n.length);if(r===0)return 100;let o=Math.max(0,100-s/r*100);return Math.round(o)}function ee(l){return l.startsWith("use")&&l.length>3&&/[A-Z]/.test(l[3])}function ft(l,e,t){if(t===0||t>3)return;let n=A(l).split(" "),s=A(e).split(" ");for(let r of n)for(let o of s){let i=Ae(r,o);if(i>0&&i<=3&&r!==o)return `"${r}" \u53EF\u80FD\u662F "${o}" \u7684\u62FC\u5199\u9519\u8BEF (\u7F16\u8F91\u8DDD\u79BB=${i})`}}var G=J(()=>{w();});var Ke,Ve,mt,ze,Xe,gt,ht,yt,Je,Ge,Ye,bt,$e,Et,Nt,_t,Y=J(()=>{w();Ke=["**/node_modules/**","**/dist/**","**/build/**","**/.git/**","**/coverage/**","**/.nuxt/**","**/.next/**","**/__tests__/**","**/*.test.*","**/*.spec.*","**/*.min.js"],Ve=["**/*.vue","**/*.js","**/*.jsx","**/*.ts","**/*.tsx"],mt={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"]}},ze=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured"],Xe=["onBeforeMount","onMounted","onBeforeUpdate","onUpdated","onBeforeUnmount","onUnmounted","onActivated","onDeactivated","onErrorCaptured","onRenderTracked","onRenderTriggered","onServerPrefetch"],gt=["ref","reactive","shallowRef","shallowReactive","readonly"],ht=["computed"],yt=["watch","watchEffect","watchPostEffect","watchSyncEffect"],Je=["useState","useReducer","useRef","useImperativeHandle"],Ge=["useMemo","useCallback"],Ye=["useEffect","useLayoutEffect","useInsertionEffect"],bt=["useContext","useDebugValue","useDeferredValue","useId","useSyncExternalStore","useTransition"],$e=".skimmer-index.db",Et=30,Nt=4,_t=300;});function B(l,e,t,n=false){let s=[];return j(l,o=>{if(n&&o!==l&&(o.type==="FunctionDeclaration"||o.type==="ArrowFunctionExpression"||o.type==="FunctionExpression"||o.type==="ClassDeclaration"))return false;if(o.type==="CallExpression"){let a=fn(o,e);a&&s.push(a);}if(o.type==="MemberExpression"){let i=mn(o);i&&s.push(i);}}),Nn(s)}function fn(l,e,t){let n=l.callee;if(!n)return null;let s=Le(l);if(n.type==="MemberExpression"){let r=gn(n);if(!r)return null;let{apiName:o,operation:i}=r,a=l.arguments,c=z(a?.[0]),u=bn(o);return u?{symbolName:e,category:u,apiName:o,operation:i,detail:c,line:s}:o==="this"&&Re(i)?{symbolName:e,category:"network",apiName:`this.${i}`,operation:"wrapped_call",detail:c||z(a?.[1]),line:s}:St(i)&&En(a)?{symbolName:e,category:"network",apiName:o,operation:i,detail:c||z(a?.[1]),line:s}:Re(o)||Re(`${o}.${i}`)?{symbolName:e,category:"network",apiName:o,operation:St(i)?i:"wrapped_call",detail:c||z(a?.[1]),line:s}:null}if(n.type==="Identifier"){let r=n.name,o=hn(r),i=l.arguments,a=z(i?.[0]);return o?{symbolName:e,category:o.category,apiName:r,operation:o.operation,detail:a,line:s}:Re(r)?{symbolName:e,category:"network",apiName:r,operation:"wrapped_call",detail:a||z(i?.[1]),line:s}:null}return null}function mn(l,e,t){let n=l.object,s=l.property;if(!n||!s||n.type!=="MemberExpression"&&n.type!=="ThisExpression"&&n.type!=="Identifier")return null;let r=yn(n);if(!r)return null;s.type==="Identifier"?s.name:"";if(r==="this"||r===""){n.type==="MemberExpression"?n.property?.name:"";return null}return null}function gn(l){let e=l.object,t=l.property;if(!e||!t||t.type!=="Identifier")return null;let n=t.name;if(e.type==="MemberExpression"){let s=e.property?.name;if(s)return {apiName:s,operation:n}}return e.type==="Identifier"?{apiName:e.name,operation:n}:e.type==="ThisExpression"?{apiName:"this",operation:n}:null}function hn(l){let e={fetch:"network",setTimeout:"timer",setInterval:"timer",clearTimeout:"timer",clearInterval:"timer",requestAnimationFrame:"timer",navigate:"router"};return e[l]?{category:e[l],operation:l}:null}function Le(l){return l.loc?.start?.line??0}function yn(l){return l.type==="Identifier"?l.name:l.type==="ThisExpression"?"this":null}function bn(l){if(l==="this")return null;for(let[e,t]of Object.entries(mt))if(l in t)return e;return null}function z(l,e){if(l){if(l.type==="Literal"||l.type==="StringLiteral"||l.type==="NumericLiteral"||l.type==="BooleanLiteral")return String(l.value);if(l.type==="NullLiteral")return "null";if(l.type==="TemplateLiteral"){let t=l.quasis,n=l.expressions||[],s=[];for(let o=0;o<t.length;o++){let i=t[o].value?.cooked||"";if(i&&s.push(i),o<n.length){let a=ve(n[o])||"expr";s.push(`\${${a}}`);}}return s.join("")||"${expr}"}if(l.type==="Identifier")return `[\u53D8\u91CF: ${l.name}]`;if(l.type==="ObjectExpression"){let t=l.properties||[],n=["url","uri","path","api","endpoint"];for(let s of t){let r=s.key,o=s.value;if(!r||!o)continue;let i=r.type==="Identifier"?String(r.name):r.type==="Literal"?String(r.value):"";if(!n.includes(i))continue;let a=z(o);if(a)return `${i}:${a}`}return "{...}"}}}function ve(l,e){if(!l)return;if(l.type==="Identifier")return l.name;if(l.type==="ThisExpression")return "this";if(l.type==="Literal"||l.type==="StringLiteral"||l.type==="NumericLiteral"||l.type==="BooleanLiteral")return String(l.value);if(l.type==="NullLiteral")return "null";if(l.type==="MemberExpression"){let n=ve(l.object)||"obj",s=l.property,r=s?.type==="Identifier"?String(s.name):ve(s)||"prop";return l.computed?`${n}[${r}]`:`${n}.${r}`}if(l.type==="CallExpression")return `${ve(l.callee)||"fn"}(...)`;if(l.type==="TemplateLiteral")return z(l);let t=z(l);return t?.startsWith("[\u53D8\u91CF: ")?t.replace(/^\[变量: /,"").replace(/\]$/,""):t}function Re(l){return /request|api|http|fetch|ajax|akscommonhandle|commonhandle/i.test(l)}function St(l){return ["get","post","put","delete","patch","request"].includes(l.toLowerCase())}function En(l,e){if(!l||l.length===0)return false;for(let t of l.slice(0,2)){let n=z(t);if(n&&(/https?:\/\//i.test(n)||n.includes("/")||/gw\d?\/|\/m\/|\/api\//i.test(n)))return true}return false}function Nn(l){let e=new Set;return l.filter(t=>{let n=`${t.apiName}:${t.operation}:${t.line}`;return e.has(n)?false:(e.add(n),true)})}function we(l,e,t){let n=[];return j(l,s=>{if(s.type==="CallExpression"&&s.callee?.type==="MemberExpression"){let r=s.callee,o=r.object,i=r.property;if(o.type==="ThisExpression"&&i.type==="Identifier"){let a=i.name;if(!a.startsWith("$")&&a!==e){let c=s.arguments,u=At(c);n.push({calleeName:a,line:Le(s),args:u});}}}}),n}function Z(l,e,t,n=false){let s=[];return j(l,o=>{if(n&&o!==l&&(o.type==="FunctionDeclaration"||o.type==="ArrowFunctionExpression"||o.type==="FunctionExpression"||o.type==="ClassDeclaration"))return false;if(o.type==="CallExpression"&&o.callee?.type==="Identifier"){let i=o.callee.name;if(i!==e&&!_n(i)){let a=o.arguments,c=At(a);s.push({calleeName:i,line:Le(o),args:c});}}}),s}function _n(l){return /^(useState|useEffect|useMemo|useCallback|useRef|useContext|useReducer|ref|reactive|computed|watch|watchEffect|console|setTimeout|setInterval|Math|Object|Array|JSON|String|Number|Boolean|Promise|require|import)$/.test(l)}function At(l,e){if(!l||l.length===0)return;let t=l.slice(0,3).map(n=>z(n)).filter(n=>!!n);return t.length>0?t.join(", "):void 0}function j(l,e){if(!(!l||typeof l!="object")&&e(l)!==false)for(let t of Object.keys(l)){if(t==="type"||t==="loc"||t==="start"||t==="end")continue;let n=l[t];if(Array.isArray(n))for(let s of n)s&&typeof s=="object"&&s.type&&j(s,e);else n&&typeof n=="object"&&n.type&&j(n,e);}}function Ce(l,e){let t=[],n=new Set,s=l.split(`
5
- `);for(let r=0;r<s.length;r++){let o=/(?:@|v-on:)[a-z][a-z0-9-]*(?:\.[a-z-]+)*="([^"]+)"/g,i;for(;(i=o.exec(s[r]))!==null;){let c=i[1].trim().match(/^([a-zA-Z_$][a-zA-Z0-9_$]*)(?:\([^)]*\))?$/);if(!c)continue;let u=c[1];u.startsWith("$")||n.has(u)||(n.add(u),t.push({calleeName:u,line:e+r}));}}return t}function xt(l,e){let t=[],n=new Set;return j(l,s=>{if(s.type!=="JSXAttribute")return;let r=s.name,o=s.value;if(!r||!o)return;let i=r.type==="JSXIdentifier"?String(r.name):"";if(!/^on[A-Z]/.test(i)||o.type!=="JSXExpressionContainer")return;let a=o.expression;if(!a)return;let c;if(a.type==="Identifier")c=a.name;else if(a.type==="MemberExpression"){let u=a.property?.name;u&&!/^\$/.test(u)&&(c=u);}!c||n.has(c)||(n.add(c),t.push({calleeName:c,line:Le(s)}));}),t}var Ie=J(()=>{w();Y();});var $t,pe,Ze=J(()=>{w();Y();Ie();G();$t=createRequire(import.meta.url),pe=class{name="Vue2Parser";canParse(e,t){return e.endsWith(".vue")}parse(e,t){let n={framework:"vue2",filePath:e,symbols:[],relations:[],behaviors:[],errors:[]};try{let r=$t("vue-template-compiler").parseComponent(t);if(!r.script?.content)return n;let o=r.script.content,i=this.getScriptStartLine(t,r.script.start),a=t.split(`
6
- `),c;try{c=$t("@babel/parser").parse(o,{sourceType:"module",plugins:["jsx","typescript","decorators-legacy"],errorRecovery:!0});}catch(u){return n.errors?.push(`AST \u89E3\u6790\u5931\u8D25: ${String(u)}`),n}if(this.extractFromAST(c.program,o,a,i,n),r.template?.content){let u=this.getScriptStartLine(t,r.template.start),p=Ce(r.template.content,u);if(p.length>0){let d=r.template.content.split(`
7
- `).length;n.symbols.push({name:"<template>",category:"lifecycle",framework:"vue2",startLine:u,endLine:u+d-1,camelWords:"template"});for(let f of p)n.relations.push({callerName:"<template>",callerLine:u,calleeName:f.calleeName,callType:"template_event",line:f.line});}}}catch(s){n.errors?.push(`\u89E3\u6790\u5931\u8D25: ${String(s)}`);}return n}getScriptStartLine(e,t){let n=1;for(let s=0;s<t&&s<e.length;s++)e[s]===`
8
- `&&n++;return n}extractFromAST(e,t,n,s,r){let o=t.split(`
9
- `),i=null;j(e,p=>{if(p.type==="ExportDefaultDeclaration"){let d=p.declaration;if(d?.type==="ObjectExpression")i=d;else if(d?.type==="CallExpression"){let f=d.arguments;f&&f.length>0&&f[0].type==="ObjectExpression"&&(i=f[0]);}else if(d?.type==="Identifier"){let f=d.name;j(e,m=>{if(m.type==="VariableDeclarator"&&m.id?.name===f){if(m.init?.type==="ObjectExpression")i=m.init;else if(m.init?.type==="CallExpression"){let g=m.init.arguments;g&&g.length>0&&g[0].type==="ObjectExpression"&&(i=g[0]);}}});}}});let c=false;if(!i&&(j(e,p=>{p.type==="ExportDefaultDeclaration"&&p.declaration?.type==="ClassDeclaration"&&(c=true,this.extractFromClassComponent(p.declaration,t,n,s,r));}),!c)){let p=null,d=0,f=["data","methods","computed","props","watch","components","created","mounted","mixins"];j(e,m=>{if(m.type==="ObjectExpression"){let g=m.properties||[],E=0;for(let h of g){let y=this.getPropKey(h);y&&f.includes(y)&&E++;}E>d&&(d=E,p=m);}}),d>=2&&p&&(i=p);}if(!i)return;let u=i.properties;for(let p of u||[]){let d=this.getPropKey(p);if(!d)continue;let f=p.type==="ObjectMethod"?p:p.value;if(!f)continue;let m=g=>g+s-1;switch(d){case "name":f?.type==="Literal"&&(String(f.value));break;case "data":this.extractData(f,o,m,r);break;case "props":this.extractProps(f,o,m,r);break;case "computed":this.extractComputedOrMethods(f,"computed",o,m,n,r);break;case "methods":this.extractComputedOrMethods(f,"method",o,m,n,r);break;case "watch":this.extractWatch(f,o,m,r);break;case "filters":this.extractComputedOrMethods(f,"filter",o,m,n,r);break;case "components":this.extractComponents(f,r);break;case "mixins":this.extractMixins(f,r);break;default:if(ze.includes(d)){let g=m(this.getStartLine(p)),E=m(this.getEndLine(p)),h=V(n.join(`
10
- `),g),y=r.symbols.length;r.symbols.push({name:d,category:"lifecycle",framework:"vue2",startLine:g,endLine:E,jsdoc:h,camelWords:A(d)});let S=B(f,d);r.behaviors.push(...S);let b=we(f,d);for(let T of b){if(T.args){let v=String(T.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");r.symbols[y].camelWords+=` ${A(v)} ${v}`;}r.relations.push({callerName:d,callerLine:g,calleeName:T.calleeName,callType:"this_method",line:m(T.line),args:T.args});}}break}}}extractData(e,t,n,s){let r=null;if(e.type==="FunctionExpression"||e.type==="ArrowFunctionExpression"||e.type==="ObjectMethod"?j(e.body,o=>{o.type==="ReturnStatement"&&o.argument?.type==="ObjectExpression"&&(r=o.argument);}):e.type==="ObjectExpression"&&(r=e),!!r)for(let o of r.properties){let i=this.getPropKey(o);if(!i)continue;let a=n(this.getStartLine(o)),c=n(this.getEndLine(o)),u=this.getLiteralValue(o.value);s.symbols.push({name:i,category:"state",framework:"vue2",startLine:a,endLine:c,defaultValue:u,camelWords:A(i)});}}extractProps(e,t,n,s){if(e.type==="ArrayExpression"){for(let r of e.elements||[])if(r?.type==="Literal"){let o=String(r.value);s.symbols.push({name:o,category:"prop",framework:"vue2",startLine:n(this.getStartLine(r)),endLine:n(this.getEndLine(r)),camelWords:A(o)});}}else if(e.type==="ObjectExpression")for(let r of e.properties||[]){let o=this.getPropKey(r);if(!o)continue;let i=n(this.getStartLine(r)),a=n(this.getEndLine(r)),c;if(r.value?.type==="ObjectExpression"){let u=r.value.properties?.find(p=>this.getPropKey(p)==="default");u&&(c=this.getLiteralValue(u.value));}s.symbols.push({name:o,category:"prop",framework:"vue2",startLine:i,endLine:a,defaultValue:c,camelWords:A(o)});}}extractComputedOrMethods(e,t,n,s,r,o){if(e.type==="ObjectExpression")for(let i of e.properties||[]){let a=this.getPropKey(i);if(!a)continue;let c=i.type==="ObjectMethod"?i:i.value;if(!c)continue;let u=s(this.getStartLine(i)),p=s(this.getEndLine(i)),d=V(r.join(`
11
- `),u),f=this.extractParams(c),m=c.async===true,g=f?`${a}(${f.join(", ")})`:a;if(o.symbols.push({name:a,category:t,framework:"vue2",startLine:u,endLine:p,signature:g,params:f,isAsync:m,jsdoc:d,camelWords:A(a)}),t==="method"&&c){let E=B(c,a);o.behaviors.push(...E);let h=we(c,a);for(let y of h){if(y.args){let S=String(y.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");o.symbols[o.symbols.length-1].camelWords+=` ${A(S)} ${S}`;}o.relations.push({callerName:a,callerLine:u,calleeName:y.calleeName,callType:"this_method",line:s(y.line),args:y.args});}}}}extractWatch(e,t,n,s){if(e.type==="ObjectExpression")for(let r of e.properties||[]){let o=this.getPropKey(r);if(!o)continue;let i=n(this.getStartLine(r)),a=n(this.getEndLine(r));s.symbols.push({name:o,category:"effect",framework:"vue2",startLine:i,endLine:a,camelWords:A(o)});}}extractComponents(e,t){if(e.type==="ObjectExpression")for(let n of e.properties||[]){let s=this.getPropKey(n);s&&t.symbols.push({name:s,category:"component",framework:"vue2",startLine:this.getStartLine(n),endLine:this.getEndLine(n),camelWords:A(s)});}}extractMixins(e,t){if(e.type==="ArrayExpression")for(let n of e.elements||[]){let s=n?.type==="Identifier"?n.name:null;s&&t.symbols.push({name:s,category:"mixin",framework:"vue2",startLine:this.getStartLine(n),endLine:this.getEndLine(n),camelWords:A(s)});}}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(n=>n.type==="Identifier"?n.name:n.type==="AssignmentPattern"?n.left?.name||"?":n.type==="RestElement"?`...${n.argument?.name||""}`:n.type==="TSParameterProperty"&&n.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,n,s,r){let o=a=>a+s-1,i=e.body;if(!(!i||i.type!=="ClassBody"))for(let a of i.body||[]){let c=this.getPropKey(a);if(!c)continue;let u=o(this.getStartLine(a)),p=o(this.getEndLine(a)),d=V(n.join(`
12
- `),u);if(a.type==="ClassMethod"){let m=ze.includes(c)?"lifecycle":"method",g=this.extractParams(a),E=a.async===true,h=g?`${c}(${g.join(", ")})`:c;r.symbols.push({name:c,category:m,framework:"vue2",startLine:u,endLine:p,signature:h,params:g,isAsync:E,jsdoc:d,camelWords:A(c)});let y=B(a,c);r.behaviors.push(...y);let S=we(a,c);for(let b of S){if(b.args){let T=String(b.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");r.symbols[r.symbols.length-1].camelWords+=` ${A(T)} ${T}`;}r.relations.push({callerName:c,callerLine:u,calleeName:b.calleeName,callType:"this_method",line:o(b.line),args:b.args});}}else if(a.type==="ClassProperty"){let f=(a.decorators||[]).some(g=>g.expression?.callee?.name==="Prop"),m=this.getLiteralValue(a.value);r.symbols.push({name:c,category:f?"prop":"state",framework:"vue2",startLine:u,endLine:p,defaultValue:m,camelWords:A(c)});}}}};});var Qe,Pe,Tt=J(()=>{w();Y();Ie();G();Ze();Qe=createRequire(import.meta.url),Pe=class{name="Vue3Parser";canParse(e,t){return e.endsWith(".vue")?this.looksLikeVue3File(t):false}parse(e,t){let n={framework:"vue3",filePath:e,symbols:[],relations:[],behaviors:[],errors:[]};try{let{parse:s}=Qe("@vue/compiler-sfc"),{descriptor:r}=s(t),o=t.split(`
13
- `),i=!!r.scriptSetup,a=!!r.script;if(i){let c=r.scriptSetup,u=c.loc.start.line;this.parseSetupContent(c.content,u,o,n);}else if(a){let c=r.script,u=c.loc.start.line;this.parseScriptContent(c.content,u,o,n)||this.populateFromOptionsApiFallback(e,t,n);}if(r.template?.content){let c=r.template.loc.start.line,u=Ce(r.template.content,c);if(u.length>0){let p=r.template.content.split(`
14
- `).length;n.symbols.push({name:"<template>",category:"lifecycle",framework:"vue3",startLine:c,endLine:c+p-1,camelWords:"template"});for(let d of u)n.relations.push({callerName:"<template>",callerLine:c,calleeName:d.calleeName,callType:"template_event",line:d.line});}}}catch(s){n.errors?.push(`Vue3 \u89E3\u6790\u5931\u8D25: ${String(s)}`);}return n}parseSetupContent(e,t,n,s){let r;try{r=Qe("@babel/parser").parse(e,{sourceType:"module",plugins:["typescript","jsx","decorators-legacy"],errorRecovery:!0});}catch(c){s.errors?.push(`AST \u89E3\u6790\u5931\u8D25: ${String(c)}`);return}let o=c=>c+t-1,i=e.split(`
15
- `),a=r.program.body;for(let c of a||[])this.processTopLevelStatement(c,o,n,i,s);}parseScriptContent(e,t,n,s){let r;try{r=Qe("@babel/parser").parse(e,{sourceType:"module",plugins:["typescript","jsx","decorators-legacy"],errorRecovery:!0});}catch(c){return s.errors?.push(`AST \u89E3\u6790\u5931\u8D25: ${String(c)}`),false}let o=c=>c+t-1,i=e.split(`
16
- `),a=false;return j(r.program,c=>{if(c.type==="ExportDefaultDeclaration"&&c.declaration?.type==="ObjectExpression"){let u=c.declaration.properties?.find(p=>this.getPropKey(p)==="setup");if(u){a=true;let p=u.type==="ObjectMethod"?u:u.value;if(!p)return;let d=p.body;if(d?.type==="BlockStatement"){let f=d.body;for(let m of f||[])this.processTopLevelStatement(m,o,n,i,s);}}}}),a||j(r.program,c=>{if(!a&&c.type==="ObjectExpression"){let p=(c.properties||[]).find(d=>this.getPropKey(d)==="setup");if(p){a=true;let d=p.type==="ObjectMethod"?p:p.value;if(!d)return;let f=d.body;if(f?.type==="BlockStatement"){let m=f.body;for(let g of m||[])this.processTopLevelStatement(g,o,n,i,s);}}}}),a}processTopLevelStatement(e,t,n,s,r){let o=i=>{let a=i?.loc;return {start:a?.start?.line??1,end:a?.end?.line??1}};if(e.type==="VariableDeclaration")for(let i of e.declarations||[]){if(i.id?.type!=="Identifier"&&i.id?.type!=="ArrayPattern")continue;let a=i.init;if(a&&i.id.type==="Identifier"){let c=i.id.name;if(a.type==="ArrowFunctionExpression"||a.type==="FunctionExpression"){let{start:u,end:p}=o(e),d=V(n.join(`
17
- `),t(u)),f=this.extractParams(a),m=r.symbols.length;if(r.symbols.push({name:c,category:"method",framework:"vue3",startLine:t(u),endLine:t(p),signature:`${c}(${(f||[]).join(", ")})`,params:f,isAsync:a.async===true,jsdoc:d,camelWords:A(c)}),a.body){let g=B(a.body,c);r.behaviors.push(...g);let E=Z(a.body,c);for(let h of E){if(h.args){let y=String(h.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");r.symbols[m].camelWords+=` ${A(y)} ${y}`;}r.relations.push({callerName:c,callerLine:t(u),calleeName:h.calleeName,callType:"direct_call",line:t(h.line),args:h.args});}}}else {let u=this.classifyVue3Declaration(c,a,t,o(e),n);u&&r.symbols.push(u);}}}if(e.type==="FunctionDeclaration"&&e.id?.type==="Identifier"){let i=e.id.name,{start:a,end:c}=o(e),u=V(n.join(`
18
- `),t(a)),p=this.extractParams(e),d=Xe.includes(i);if(r.symbols.push({name:i,category:d?"lifecycle":ee(i)?"hook":"method",framework:"vue3",startLine:t(a),endLine:t(c),signature:`${i}(${(p||[]).join(", ")})`,params:p,isAsync:e.async===true,jsdoc:u,camelWords:A(i)}),e.body){let f=B(e.body,i);r.behaviors.push(...f);let m=Z(e.body,i);for(let g of m){if(g.args){let E=String(g.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");r.symbols[r.symbols.length-1].camelWords+=` ${A(E)} ${E}`;}r.relations.push({callerName:i,callerLine:t(a),calleeName:g.calleeName,callType:"direct_call",line:t(g.line),args:g.args});}}}if(e.type==="ExpressionStatement"&&e.expression?.type==="CallExpression"){let a=e.expression.callee;if(a?.type==="Identifier"){let c=a.name;if(["defineProps","defineEmits","defineExpose"].includes(c)){let{start:u,end:p}=o(e);r.symbols.push({name:c,category:c==="defineProps"?"prop":c==="defineEmits"?"emit":"export",framework:"vue3",startLine:t(u),endLine:t(p),camelWords:A(c)});}}}if(e.type==="ExpressionStatement"&&e.expression?.type==="CallExpression"){let i=e.expression,a=i.callee;if(a?.type==="Identifier"){let c=a.name;if(Xe.includes(c)){let{start:u,end:p}=o(e);r.symbols.push({name:c,category:"lifecycle",framework:"vue3",startLine:t(u),endLine:t(p),camelWords:A(c)});let d=i.arguments;if(d?.[0]){let f=B(d[0],c);r.behaviors.push(...f);let m=Z(d[0],c);for(let g of m){if(g.args){let E=String(g.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");r.symbols[r.symbols.length-1].camelWords+=` ${A(E)} ${E}`;}r.relations.push({callerName:c,callerLine:t(u),calleeName:g.calleeName,callType:"direct_call",line:t(g.line),args:g.args});}}}}}}classifyVue3Declaration(e,t,n,s,r){if(t.type!=="CallExpression")return null;let o=t.callee;if(o?.type!=="Identifier")return null;let i=o.name,a=n(s.start),c=n(s.end),u=V(r.join(`
19
- `),a);if(gt.includes(i)){let p=t.arguments,d=p?.[0]?this.getLiteralValue(p[0]):void 0;return {name:e,category:"state",framework:"vue3",startLine:a,endLine:c,defaultValue:d,jsdoc:u,camelWords:A(e)}}return ht.includes(i)?{name:e,category:"computed",framework:"vue3",startLine:a,endLine:c,jsdoc:u,camelWords:A(e)}:yt.includes(i)?{name:e,category:"effect",framework:"vue3",startLine:a,endLine:c,camelWords:A(e)}:i==="provide"||i==="inject"?{name:e,category:"provide",framework:"vue3",startLine:a,endLine:c,camelWords:A(e)}:ee(i)?{name:e,category:"hook",framework:"vue3",startLine:a,endLine:c,jsdoc:u,camelWords:A(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(n=>n.type==="Identifier"?n.name:n.type==="AssignmentPattern"?n.left?.name||"?":n.type==="RestElement"?`...${n.argument?.name||""}`:n.type==="ObjectPattern"?"{...}":n.type==="TSParameterProperty"&&n.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 "[]"}}looksLikeVue3File(e){return e.includes("<script setup")?true:/\bdefine(?:Props|Emits|Expose|Slots|Model)\s*\(/.test(e)||/\bwithDefaults\s*\(/.test(e)||/\bdefineComponent\s*\(/.test(e)||/\bsetup\s*\(/.test(e)||/\b(?:ref|reactive|shallowRef|shallowReactive|readonly|computed|watch|watchEffect|watchPostEffect|watchSyncEffect|provide|inject|nextTick|onBeforeMount|onMounted|onBeforeUpdate|onUpdated|onBeforeUnmount|onUnmounted|onActivated|onDeactivated|onErrorCaptured|onRenderTracked|onRenderTriggered|onServerPrefetch)\s*\(/.test(e)}populateFromOptionsApiFallback(e,t,n){let s=new pe().parse(e,t);n.symbols=s.symbols.map(r=>({...r,framework:"vue3"})),n.relations=s.relations,n.behaviors=s.behaviors,n.errors=[...n.errors||[],...s.errors||[]];}};});var $n,Tn,ge,kt=J(()=>{w();Y();Ie();G();$n=createRequire(import.meta.url),Tn=[...Je,...Ge,...Ye,...bt],ge=class{name="ReactParser";canParse(e,t){let n=e.split(".").pop()?.toLowerCase();return ["jsx","tsx","js","ts"].includes(n||"")?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 n={framework:"react",filePath:e,symbols:[],relations:[],behaviors:[],errors:[]};try{let r=$n("@babel/parser").parse(t,{sourceType:"module",plugins:["jsx","typescript","decorators-legacy"],errorRecovery:!0}),o=t.split(`
20
- `);this.extractFromAST(r.program?r.program:r,o,n);}catch(s){n.errors?.push(`React \u89E3\u6790\u5931\u8D25: ${String(s)}`);}return n}extractFromAST(e,t,n){let s=e.body;for(let r of s||[]){if(r.type==="FunctionDeclaration"||r.type==="ExportDefaultDeclaration"&&r.declaration?.type==="FunctionDeclaration"||r.type==="ExportNamedDeclaration"&&r.declaration?.type==="FunctionDeclaration"){let o=r.type==="FunctionDeclaration"?r:r.declaration;o&&o.id?.type==="Identifier"&&this.processFunction(o,t,n);}if(r.type==="VariableDeclaration"||r.type==="ExportNamedDeclaration"&&r.declaration?.type==="VariableDeclaration"||r.type==="ExportDefaultDeclaration"&&r.declaration?.type==="VariableDeclaration"){let o=r.type==="VariableDeclaration"?r:r.declaration;if(o)for(let i of o.declarations||[]){let a=i.init;if(a&&(a.type==="ArrowFunctionExpression"||a.type==="FunctionExpression")&&i.id?.type==="Identifier"){let c={...a,id:i.id,loc:{start:o.loc?.start??a.loc?.start,end:a.loc?.end}};this.processFunction(c,t,n);}}}}}processFunction(e,t,n){let s=e.id?.name;if(!s)return;let r=e.loc,o=r?.start?.line??1,i=r?.end?.line??1,a=ee(s),c=!a&&/^[A-Z]/.test(s),u=V(t.join(`
21
- `),o),p=this.extractParams(e),d=this.buildSymbolKey(s,o,i);n.symbols.push({name:s,category:a?"hook":c?"component":"function",framework:"react",startLine:o,endLine:i,internalKey:d,signature:`${s}(${(p||[]).join(", ")})`,params:p,isAsync:e.async===true,jsdoc:u,parentComponent:c?s:void 0,camelWords:A(s)});let f=e.body;if(f?.type!=="BlockStatement")return;let m=f.body;for(let y of m||[])this.processComponentStatement(y,s,t,n);let g=B(f,s,t,true);n.behaviors.push(...g);let E=Z(f,s,t,true);for(let y of E){let S=n.symbols.findIndex(b=>b.name===s&&b.startLine===o);if(y.args&&S!==-1){let b=String(y.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");n.symbols[S].camelWords+=` ${A(b)} ${b}`;}n.relations.push({callerName:s,callerLine:o,callerKey:d,calleeName:y.calleeName,callType:"direct_call",line:y.line,args:y.args});}let h=xt(f);for(let y of h)n.relations.push({callerName:s,callerLine:o,callerKey:d,calleeName:y.calleeName,callType:"jsx_event",line:y.line});}processComponentStatement(e,t,n,s){let r=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 a=i.callee;if(a?.type!=="Identifier")continue;let c=a.name,{start:u,end:p}=r(e),d=u,f=p;if(Je.includes(c)&&c!=="useRef"){if(o.id?.type==="ArrayPattern"){let m=o.id.elements,g=m[0]?.name,E=m[1]?.name;if(g){let h=i.arguments;s.symbols.push({name:g,category:"state",framework:"react",startLine:d,endLine:f,internalKey:this.buildSymbolKey(g,d,f,t),stateSetterName:E,defaultValue:this.getLiteralValue(h?.[0]),parentComponent:t,camelWords:A(g)});}}else if(o.id?.type==="Identifier"){let m=o.id.name;s.symbols.push({name:m,category:"state",framework:"react",startLine:d,endLine:f,internalKey:this.buildSymbolKey(m,d,f,t),parentComponent:t,camelWords:A(m)});}}if(c==="useRef"&&o.id?.type==="Identifier"){let m=o.id.name,g=i.arguments;s.symbols.push({name:m,category:"state",framework:"react",startLine:d,endLine:f,internalKey:this.buildSymbolKey(m,d,f,t),defaultValue:this.getLiteralValue(g?.[0]),parentComponent:t,camelWords:A(m)});}if(Ge.includes(c)&&o.id?.type==="Identifier"){let m=o.id.name,E=i.arguments?.[1],h=this.extractDepsArray(E);s.symbols.push({name:m,category:"computed",framework:"react",startLine:d,endLine:f,internalKey:this.buildSymbolKey(m,d,f,t),hookDeps:h,parentComponent:t,camelWords:A(m)});}if(ee(c)&&!Tn.includes(c)){let m=o.id?.type==="Identifier"?o.id.name:o.id?.type==="ObjectPattern"?"{...}":"?";s.symbols.push({name:m,category:"hook",framework:"react",startLine:d,endLine:f,internalKey:this.buildSymbolKey(m,d,f,t),parentComponent:t,camelWords:A(m)});}}if(e.type==="ExpressionStatement"&&e.expression?.type==="CallExpression"){let o=e.expression,i=o.callee;if(i?.type==="Identifier"){let a=i.name;if(Ye.includes(a)){let{start:c,end:u}=r(e),p=o.arguments,d=p?.[1],f=this.extractDepsArray(d),m=this.buildSymbolKey(a,c,u,t),g=`${t}.${a}`;if(s.symbols.push({name:a,category:"effect",framework:"react",startLine:c,endLine:u,internalKey:m,hookDeps:f,parentComponent:t,camelWords:A(a)}),p?.[0]){let E=B(p[0],g,n,true).map(y=>({...y,symbolKey:m}));s.behaviors.push(...E);let h=Z(p[0],g,n,true);for(let y of h){let S=s.symbols.findIndex(b=>b.name===a&&b.startLine===c);if(y.args&&S!==-1){let b=String(y.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");s.symbols[S].camelWords+=` ${A(b)} ${b}`;}s.relations.push({callerName:g,callerLine:c,callerKey:m,calleeName:y.calleeName,callType:"direct_call",line:y.line,args:y.args});}}}}}if(e.type==="FunctionDeclaration"&&e.id?.type==="Identifier"){let o=e.id.name;if(!ee(o)){let{start:i,end:a}=r(e),c=V(n.join(`
22
- `),i),u=this.extractParams(e);if(s.symbols.push({name:o,category:"method",framework:"react",startLine:i,endLine:a,internalKey:this.buildSymbolKey(o,i,a,t),signature:`${o}(${(u||[]).join(", ")})`,params:u,isAsync:e.async===true,jsdoc:c,parentComponent:t,camelWords:A(o)}),e.body){let p=B(e.body,o,n,true);s.behaviors.push(...p);let d=Z(e.body,o,n,true);for(let f of d){let m=s.symbols.findIndex(g=>g.name===o&&g.startLine===i);if(f.args&&m!==-1){let g=String(f.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");s.symbols[m].camelWords+=` ${A(g)} ${g}`;}s.relations.push({callerName:o,callerLine:i,callerKey:this.buildSymbolKey(o,i,a,t),calleeName:f.calleeName,callType:"direct_call",line:f.line,args:f.args});}}}}if(e.type==="VariableDeclaration")for(let o of e.declarations||[]){let i=o.init;if(!i)continue;let a=i.type==="ArrowFunctionExpression"||i.type==="FunctionExpression";if(!a||o.id?.type!=="Identifier")continue;let c=o.id.name,u=i.type==="CallExpression"?i.callee:null;if(u?.type==="Identifier"&&ee(u.name))continue;if(i.type==="CallExpression"&&i.callee?.name==="useCallback"){let h=i.arguments?.[1],y=this.extractDepsArray(h),{start:S,end:b}=r(e);s.symbols.push({name:c,category:"computed",framework:"react",startLine:S,endLine:b,internalKey:this.buildSymbolKey(c,S,b,t),hookDeps:y,parentComponent:t,camelWords:A(c)});continue}if(!a)continue;let{start:d,end:f}=r(e),m=V(n.join(`
23
- `),d),g=this.extractParams(i);if(s.symbols.push({name:c,category:"method",framework:"react",startLine:d,endLine:f,internalKey:this.buildSymbolKey(c,d,f,t),signature:`${c}(${(g||[]).join(", ")})`,params:g,isAsync:i.async===true,jsdoc:m,parentComponent:t,camelWords:A(c)}),i.body){let E=B(i.body,c,n,true);s.behaviors.push(...E);let h=Z(i.body,c,n,true);for(let y of h){let S=s.symbols.findIndex(b=>b.name===c&&b.startLine===d);if(y.args&&S!==-1){let b=String(y.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");s.symbols[S].camelWords+=` ${A(b)} ${b}`;}s.relations.push({callerName:c,callerLine:d,callerKey:this.buildSymbolKey(c,d,f,t),calleeName:y.calleeName,callType:"direct_call",line:y.line,args:y.args});}}}}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(n=>n.type==="Identifier"?n.name:n.type==="ObjectPattern"?"{...}":n.type==="ArrayPattern"?"[...]":n.type==="AssignmentPattern"?n.left?.name||"?":n.type==="RestElement"?`...${n.argument?.name||""}`:n.type==="TSParameterProperty"&&n.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"}}buildSymbolKey(e,t,n,s){return `${s||"root"}:${e}:${t}:${n}`}};});function Rt(l,e){for(let t of kn)if(t.canParse(l,e)){let n=t.parse(l,e);return Rn(n),n}return {framework:"js",filePath:l,symbols:[],relations:[],behaviors:[],errors:[`\u6CA1\u6709\u627E\u5230\u9002\u5408\u7684\u89E3\u6790\u5668: ${l}`]}}function Rn(l){if(!l.relations.length||!l.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(l.behaviors.filter(s=>s.category==="network").map(s=>s.symbolName));if(t.size===0)return;let n=new Set(l.behaviors.map(s=>`${s.symbolName}:${s.category}:${s.apiName}:${s.operation}:${s.line}`));for(let s of l.relations){if(!t.has(s.calleeName)||t.has(s.callerName)||e.has(s.callerName))continue;let r={symbolName:s.callerName,symbolKey:s.callerKey,category:"network",apiName:"wrapped_network",operation:s.calleeName,detail:s.args,line:s.line},o=`${r.symbolName}:${r.category}:${r.apiName}:${r.operation}:${r.line}`;n.has(o)||(n.add(o),l.behaviors.push(r));}}var et,kn,vt=J(()=>{w();Ze();Tt();kt();et=class extends ge{name="JsTsFallbackParser";canParse(e){let t=e.split(".").pop()?.toLowerCase();return ["js","ts","jsx","tsx"].includes(t||"")}parse(e,t){let n=super.parse(e,t);return n.framework=e.endsWith(".ts")||e.endsWith(".tsx")?"ts":"js",n}},kn=[new Pe,new pe,new ge,new et];});var wt={};tn(wt,{Indexer:()=>he});var he,tt=J(()=>{w();vt();G();Y();he=class{projectRoot;db;constructor(e,t){this.projectRoot=e,this.db=t;}async indexProject(e){let t=Date.now(),n=e?.include||[...Ve],s=e?.exclude||[...Ke],r=e?.force||false,o=await Ln(n,{cwd:this.projectRoot,ignore:s,absolute:true,onlyFiles:true}),i={totalFiles:o.length,indexedFiles:0,skippedFiles:0,totalSymbols:0,durationMs:0,errors:[]};for(let a=0;a<o.length;a++){let c=o[a],u=xe(c,this.projectRoot);e?.onProgress?.(a+1,o.length,u);try{let p=await this.indexFile(c,u,r);p.skipped?i.skippedFiles++:(i.indexedFiles++,i.totalSymbols+=p.symbolCount,p.errors?.length&&i.errors.push(...p.errors.map(d=>({file:u,error:d}))));}catch(p){i.errors.push({file:u,error:String(p)});}}return i.durationMs=Date.now()-t,i}async indexFile(e,t,n=false){let s=0,r=0,o=null;if(!n){try{let d=F.statSync(e);s=d.mtimeMs,r=d.size;}catch{}if(o=this.db.getFileMeta(t),o&&o.mtime>0&&o.mtime===s&&!(o.fileSize>0&&o.fileSize!==r))return {skipped:true,symbolCount:0}}let i=F.readFileSync(e,"utf-8"),a=pt(i);if(!n&&o&&o.hash===a)return s>0&&o.mtime!==s&&this.db.updateFileMtime(t,s),{skipped:true,symbolCount:0};let c=dt(i),u=Buffer.byteLength(i,"utf-8"),p=Rt(e,i);return this.db.saveParseResult(p,e,t,a,u,c,s),{skipped:false,symbolCount:p.symbols.length,errors:p.errors}}removeFile(e){this.db.deleteFile(e);}async startWatcher(){let{default:e}=await import('chokidar'),t=e.watch([...Ve].map(s=>H.posix.join(this.projectRoot,s)),{cwd:this.projectRoot,ignored:[...Ke],persistent:true,ignoreInitial:true,awaitWriteFinish:{stabilityThreshold:_t}}),n=async s=>{let r=xe(s,this.projectRoot);try{await this.indexFile(s,r),process.stderr.write(`[Frontend-Code-Skimmer] \u5DF2\u66F4\u65B0\u7D22\u5F15: ${r}
24
- `);}catch(o){process.stderr.write(`[Frontend-Code-Skimmer] \u66F4\u65B0\u5931\u8D25: ${r} - ${String(o)}
25
- `);}};return t.on("add",n).on("change",n).on("unlink",s=>{let r=xe(s,this.projectRoot);this.removeFile(r),process.stderr.write(`[Frontend-Code-Skimmer] \u5DF2\u5220\u9664\u7D22\u5F15: ${r}
26
- `);}),()=>t.close()}};});w();w();w();G();Y();var Te=class{db;constructor(e,t){let n=t||H.join(e,$e);F.mkdirSync(H.dirname(n),{recursive:true}),this.db=new rn(n),this.initialize();}initialize(){this.db.pragma("journal_mode = WAL"),this.db.pragma("foreign_keys = ON"),this.db.pragma("synchronous = NORMAL"),this.db.exec(`
2
+ import {McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import*as K from'path';import K__default from'path';import _s from'os';import*as J from'fs';import J__default from'fs';import Fn,{createHash}from'crypto';import Bn from'better-sqlite3';import Es from'fast-glob';import {createRequire}from'module';import {z as z$1}from'zod';function He(o){switch(o){case "template_event":return "template_event";case "jsx_event":return "jsx_event";case "hook_call":return "hook_call";case "import_func":return "import_call";default:return "method_call"}}function w(o){return o.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 Be(o,e){let t=o.length,n=e.length,s=Array.from({length:t+1},(r,i)=>Array.from({length:n+1},(a,c)=>i===0?c:c===0?i:0));for(let r=1;r<=t;r++)for(let i=1;i<=n;i++)o[r-1]===e[i-1]?s[r][i]=s[r-1][i-1]:s[r][i]=1+Math.min(s[r-1][i],s[r][i-1],s[r-1][i-1]);return s[t][n]}function Ce(o){return Fn.createHash("md5").update(o).digest("hex")}function Xe(o){if(!o)return 0;let e=1;for(let t=0;t<o.length;t++)o[t]===`
3
+ `&&e++;return e}function Le(o,e){return o===e?`L${o}`:`L${o}-L${e}`}function pe(o,e){return K__default.relative(e,o).replace(/\\/g,"/")}function Ie(o,e){if(!o)return e;try{return JSON.parse(o)}catch{return e}}function Q(o,e){let t=o.split(`
4
+ `),s=e-1-1;for(;s>=0&&t[s].trim()==="";)s--;if(s<0||!t[s].trim().endsWith("*/"))return;let r=s;for(;r>0&&!t[r].trim().startsWith("/**");)r--;if(t[r].trim().startsWith("/**"))return t.slice(r,s+1).map(i=>i.replace(/^\s*\*\s?/,"").replace(/\/\*\*/,"").replace(/\*\//,"").trim()).filter(i=>i.length>0).join(" ")}function Dt(o,e){let t=o.toLowerCase(),n=e.toLowerCase();if(t===n)return 100;if(n.includes(t)||t.includes(n))return 85;let s=Be(t,n),r=Math.max(t.length,n.length);if(r===0)return 100;let i=Math.max(0,100-s/r*100);return Math.round(i)}function ye(o){return o.startsWith("use")&&o.length>3&&/[A-Z]/.test(o[3])}function jt(o,e,t){if(t===0||t>3)return;let n=w(o).split(" "),s=w(e).split(" ");for(let r of n)for(let i of s){let a=Be(r,i);if(a>0&&a<=3&&r!==i)return `"${r}" \u53EF\u80FD\u662F "${i}" \u7684\u62FC\u5199\u9519\u8BEF (\u7F16\u8F91\u8DDD\u79BB=${a})`}}var jn=[".ts",".tsx",".js",".jsx",".vue"],Un=["index.ts","index.tsx","index.js","index.jsx","index.vue"];function Wn(o){return [...jn.map(e=>`${o}${e}`),...Un.map(e=>K.join(o,e))]}function Ne(o){if(J.existsSync(o))try{if(J.statSync(o).isFile())return o}catch{}for(let e of Wn(o))if(J.existsSync(e))return e;return o}var ft=["**/node_modules/**","**/dist/**","**/build/**","**/.git/**","**/coverage/**","**/.nuxt/**","**/.next/**","**/__tests__/**","**/*.test.*","**/*.spec.*","**/*.min.js"],mt=["**/*.vue","**/*.js","**/*.jsx","**/*.ts","**/*.tsx"],Wt={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"]}},ht=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured"],gt=["onBeforeMount","onMounted","onBeforeUpdate","onUpdated","onBeforeUnmount","onUnmounted","onActivated","onDeactivated","onErrorCaptured","onRenderTracked","onRenderTriggered","onServerPrefetch"],Ht=["ref","reactive","shallowRef","shallowReactive","readonly"],Bt=["computed"],Xt=["watch","watchEffect","watchPostEffect","watchSyncEffect"],yt=["useState","useReducer","useRef","useImperativeHandle"],bt=["useMemo","useCallback"],Et=["useEffect","useLayoutEffect","useInsertionEffect"],Kt=["useContext","useDebugValue","useDeferredValue","useId","useSyncExternalStore","useTransition"],Ke=".skimmer-index.db",zt=30,Vt=4,Gt=300;var Hn=[{version:1,description:"\u5EFA\u7ACB schema_version \u8868",statements:[`CREATE TABLE IF NOT EXISTS schema_version (
5
+ version INTEGER PRIMARY KEY,
6
+ applied_at INTEGER NOT NULL,
7
+ description TEXT
8
+ )`]},{version:2,description:"\u6DFB\u52A0 file_mtime + relations.args + _lc \u5F52\u4E00\u5316\u5217\uFF0C\u907F\u514D\u67E5\u8BE2\u65F6 LOWER() \u51FD\u6570\u8C03\u7528\u7834\u574F\u7D22\u5F15\u547D\u4E2D",statements:["ALTER TABLE relations ADD COLUMN args TEXT","ALTER TABLE files ADD COLUMN file_mtime INTEGER DEFAULT 0","ALTER TABLE files ADD COLUMN path_lc TEXT DEFAULT ''","ALTER TABLE symbols ADD COLUMN name_lc TEXT DEFAULT ''","ALTER TABLE symbols ADD COLUMN category_lc TEXT DEFAULT ''","ALTER TABLE relations ADD COLUMN callee_name_lc TEXT DEFAULT ''","ALTER TABLE behaviors ADD COLUMN api_name_lc TEXT DEFAULT ''","ALTER TABLE behaviors ADD COLUMN operation_lc TEXT DEFAULT ''","UPDATE files SET path_lc = LOWER(path) WHERE path_lc = ''","UPDATE symbols SET name_lc = LOWER(name) WHERE name_lc = ''","UPDATE symbols SET category_lc = LOWER(category) WHERE category_lc = ''","UPDATE relations SET callee_name_lc = LOWER(callee_name) WHERE callee_name_lc = ''","UPDATE behaviors SET api_name_lc = LOWER(api_name) WHERE api_name_lc = ''","UPDATE behaviors SET operation_lc = LOWER(operation) WHERE operation_lc = ''"]},{version:3,description:"\u8865\u7EC4\u5408\u7D22\u5F15\uFF0C\u66FF\u4EE3\u65E7\u7684\u5355\u5217\u7D22\u5F15",statements:["CREATE INDEX IF NOT EXISTS idx_symbols_name_lc_cat_fw ON symbols(name_lc, category_lc, framework)","CREATE INDEX IF NOT EXISTS idx_symbols_file_line ON symbols(file_id, start_line)","CREATE INDEX IF NOT EXISTS idx_files_path_lc ON files(path_lc)","CREATE INDEX IF NOT EXISTS idx_relations_callee_lc_caller ON relations(callee_name_lc, caller_id)","CREATE INDEX IF NOT EXISTS idx_relations_caller_callee ON relations(caller_id, callee_name_lc)","CREATE INDEX IF NOT EXISTS idx_behaviors_cat_api_op ON behaviors(category, api_name_lc, operation_lc)"]},{version:4,description:"\u6E05\u7406\u88AB\u7EC4\u5408\u7D22\u5F15\u66FF\u4EE3\u7684\u65E7\u5355\u5217\u7D22\u5F15\uFF0C\u8865 behaviors api_name_lc + detail_lc",statements:["DROP INDEX IF EXISTS idx_symbols_category","DROP INDEX IF EXISTS idx_symbols_file","DROP INDEX IF EXISTS idx_relations_caller","DROP INDEX IF EXISTS idx_relations_callee","DROP INDEX IF EXISTS idx_behaviors_category","DROP INDEX IF EXISTS idx_behaviors_api","ALTER TABLE behaviors ADD COLUMN detail_lc TEXT DEFAULT ''","UPDATE behaviors SET detail_lc = LOWER(detail) WHERE detail_lc = '' AND detail IS NOT NULL","CREATE INDEX IF NOT EXISTS idx_behaviors_api_lc ON behaviors(api_name_lc, operation_lc)","CREATE INDEX IF NOT EXISTS idx_behaviors_detail_lc ON behaviors(detail_lc)"]},{version:5,description:"Phase 2: relations \u8868\u52A0 source_kind/import_source/receiver_token/edge_kind\uFF0C\u65B0\u5EFA file_dependencies \u8868",statements:["ALTER TABLE relations ADD COLUMN source_kind TEXT DEFAULT 'method_call'","ALTER TABLE relations ADD COLUMN import_source TEXT","ALTER TABLE relations ADD COLUMN receiver_token TEXT","ALTER TABLE relations ADD COLUMN edge_kind TEXT DEFAULT 'heuristic'","UPDATE relations SET source_kind = 'template_event' WHERE call_type = 'template_event' AND (source_kind IS NULL OR source_kind = 'method_call')","UPDATE relations SET source_kind = 'jsx_event' WHERE call_type = 'jsx_event' AND (source_kind IS NULL OR source_kind = 'method_call')","UPDATE relations SET source_kind = 'hook_call' WHERE call_type = 'hook_call' AND (source_kind IS NULL OR source_kind = 'method_call')","UPDATE relations SET source_kind = 'import_call' WHERE call_type = 'import_func' AND (source_kind IS NULL OR source_kind = 'method_call')",`CREATE TABLE IF NOT EXISTS file_dependencies (
9
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
10
+ from_file TEXT NOT NULL,
11
+ to_file TEXT NOT NULL,
12
+ dependency_kind TEXT NOT NULL DEFAULT 'import',
13
+ line_number INTEGER NOT NULL DEFAULT 0
14
+ )`,"CREATE INDEX IF NOT EXISTS idx_file_deps_from ON file_dependencies(from_file)","CREATE INDEX IF NOT EXISTS idx_file_deps_to ON file_dependencies(to_file)","CREATE INDEX IF NOT EXISTS idx_relations_source_kind ON relations(source_kind)"]},{version:6,description:"\u4FEE\u6B63 idx_symbols_name_lc_cat_fw \u5217\u987A\u5E8F\uFF1Acategory \u2192 category_lc \u4EE5\u5BF9\u9F50\u67E5\u8BE2",statements:["DROP INDEX IF EXISTS idx_symbols_name_lc_cat_fw","CREATE INDEX IF NOT EXISTS idx_symbols_name_lc_cat_fw ON symbols(name_lc, category_lc, framework)"]},{version:7,description:"Phase 3: \u65B0\u5EFA data_assignments \u548C property_writes \u8868\uFF0C\u5C06\u751F\u547D\u5468\u671F\u6570\u636E\u7ED3\u6784\u5316\u5165\u5E93",statements:[`CREATE TABLE IF NOT EXISTS data_assignments (
15
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
16
+ symbol_name TEXT NOT NULL,
17
+ symbol_name_lc TEXT NOT NULL DEFAULT '',
18
+ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
19
+ kind TEXT NOT NULL,
20
+ line_number INTEGER NOT NULL,
21
+ text_snippet TEXT
22
+ )`,`CREATE TABLE IF NOT EXISTS property_writes (
23
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
24
+ object_name TEXT NOT NULL,
25
+ object_name_lc TEXT NOT NULL DEFAULT '',
26
+ property_name TEXT,
27
+ property_name_lc TEXT DEFAULT '',
28
+ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
29
+ kind TEXT NOT NULL,
30
+ line_number INTEGER NOT NULL,
31
+ text_snippet TEXT
32
+ )`,"CREATE INDEX IF NOT EXISTS idx_data_assign_name_lc ON data_assignments(symbol_name_lc)","CREATE INDEX IF NOT EXISTS idx_data_assign_file ON data_assignments(file_id)","CREATE INDEX IF NOT EXISTS idx_prop_writes_obj_lc ON property_writes(object_name_lc)","CREATE INDEX IF NOT EXISTS idx_prop_writes_file ON property_writes(file_id)"]},{version:8,description:"Phase 5: files \u8868\u589E\u52A0 export_signature_hash \u548C import_signature_hash\uFF0C\u652F\u6491\u9009\u62E9\u6027 precise \u91CD\u7B97",statements:["ALTER TABLE files ADD COLUMN export_signature_hash TEXT DEFAULT ''","ALTER TABLE files ADD COLUMN import_signature_hash TEXT DEFAULT ''"]},{version:9,description:"Phase 3 \u4FEE\u6B63\uFF1Adata_assignments / property_writes \u6301\u4E45\u5316 source_layer",statements:["ALTER TABLE data_assignments ADD COLUMN source_layer TEXT NOT NULL DEFAULT 'unknown'","ALTER TABLE property_writes ADD COLUMN source_layer TEXT NOT NULL DEFAULT 'unknown'"]}];function qt(o){let e=[],t=[];o.exec(`CREATE TABLE IF NOT EXISTS schema_version (
33
+ version INTEGER PRIMARY KEY,
34
+ applied_at INTEGER NOT NULL,
35
+ description TEXT
36
+ )`);let n=o.prepare("SELECT MAX(version) as v FROM schema_version").get()?.v??0;for(let s of Hn){if(s.version<=n)continue;let r=Date.now(),i=true;for(let a of s.statements)try{o.exec(a);}catch(c){let l=String(c);if(l.includes("duplicate column name"))continue;t.push(`v${s.version}: ${l.slice(0,120)}`),i=false;}o.prepare("INSERT OR REPLACE INTO schema_version (version, applied_at, description) VALUES (?, ?, ?)").run(s.version,r,i?s.description:`${s.description} (\u90E8\u5206\u8BED\u53E5\u8DF3\u8FC7)`),e.push(s.version);}return {applied:e,errors:t}}function Kn(o,e){let t=K__default.posix.dirname(e),n=t==="."?[]:t.split("/").map(()=>"..");return K__default.resolve(K__default.dirname(o),...n)}function zn(o,e,t){if(!o)return o;if(K__default.isAbsolute(o)){let n=pe(Ne(o),t);return n.startsWith("..")?o.replace(/\\/g,"/"):n}if(o.startsWith(".")){let n=Ne(K__default.resolve(K__default.dirname(e),o)),s=pe(n,t);return s.startsWith("..")?o.replace(/\\/g,"/"):s}if(o.startsWith("@/")){let n=Ne(K__default.resolve(t,"src",o.slice(2))),s=pe(n,t);return s.startsWith("..")?o.replace(/\\/g,"/"):s}return o.replace(/\\/g,"/")}var ze=class{db;constructor(e,t){let n=t||K__default.join(e,Ke);J__default.mkdirSync(K__default.dirname(n),{recursive:true}),this.db=new Bn(n),this.initialize();}initialize(){this.db.pragma("journal_mode = WAL"),this.db.pragma("foreign_keys = ON"),this.db.pragma("synchronous = NORMAL"),this.db.exec(`
27
37
  -- \u6587\u4EF6\u5143\u4FE1\u606F
28
38
  CREATE TABLE IF NOT EXISTS files (
29
39
  id INTEGER PRIMARY KEY AUTOINCREMENT,
30
40
  path TEXT UNIQUE NOT NULL,
41
+ path_lc TEXT NOT NULL DEFAULT '',
31
42
  abs_path TEXT NOT NULL,
32
43
  file_type TEXT NOT NULL,
33
44
  framework TEXT NOT NULL DEFAULT 'unknown',
34
45
  content_hash TEXT NOT NULL,
35
46
  last_indexed_at INTEGER NOT NULL,
36
47
  file_size INTEGER DEFAULT 0,
37
- line_count INTEGER DEFAULT 0
48
+ line_count INTEGER DEFAULT 0,
49
+ file_mtime INTEGER DEFAULT 0
38
50
  );
39
51
 
40
52
  -- \u7B26\u53F7\u4FE1\u606F\uFF08\u6846\u67B6\u65E0\u5173\u7684\u7EDF\u4E00\u6A21\u578B\uFF09
@@ -42,7 +54,9 @@ import H from'path';import'url';import nn,{createHash}from'crypto';import {creat
42
54
  id INTEGER PRIMARY KEY AUTOINCREMENT,
43
55
  file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
44
56
  name TEXT NOT NULL,
57
+ name_lc TEXT NOT NULL DEFAULT '',
45
58
  category TEXT NOT NULL,
59
+ category_lc TEXT NOT NULL DEFAULT '',
46
60
  framework TEXT NOT NULL,
47
61
  start_line INTEGER NOT NULL,
48
62
  end_line INTEGER NOT NULL,
@@ -94,9 +108,48 @@ import H from'path';import'url';import nn,{createHash}from'crypto';import {creat
94
108
  id INTEGER PRIMARY KEY AUTOINCREMENT,
95
109
  caller_id INTEGER NOT NULL REFERENCES symbols(id) ON DELETE CASCADE,
96
110
  callee_name TEXT NOT NULL,
111
+ callee_name_lc TEXT NOT NULL DEFAULT '',
97
112
  call_type TEXT NOT NULL DEFAULT 'this_method',
98
113
  line_number INTEGER NOT NULL DEFAULT 0,
99
- args TEXT
114
+ args TEXT,
115
+ source_kind TEXT NOT NULL DEFAULT 'method_call',
116
+ import_source TEXT,
117
+ receiver_token TEXT,
118
+ edge_kind TEXT NOT NULL DEFAULT 'heuristic'
119
+ );
120
+
121
+ -- Phase 3: \u8D4B\u503C/\u58F0\u660E\u7ED3\u6784\u5316\u5B58\u50A8\uFF08\u907F\u514D\u67E5\u8BE2\u65F6\u5168\u4ED3 AST \u626B\u63CF\uFF09
122
+ CREATE TABLE IF NOT EXISTS data_assignments (
123
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
124
+ symbol_name TEXT NOT NULL,
125
+ symbol_name_lc TEXT NOT NULL DEFAULT '',
126
+ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
127
+ kind TEXT NOT NULL,
128
+ source_layer TEXT NOT NULL DEFAULT 'unknown',
129
+ line_number INTEGER NOT NULL,
130
+ text_snippet TEXT
131
+ );
132
+
133
+ CREATE TABLE IF NOT EXISTS property_writes (
134
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
135
+ object_name TEXT NOT NULL,
136
+ object_name_lc TEXT NOT NULL DEFAULT '',
137
+ property_name TEXT,
138
+ property_name_lc TEXT DEFAULT '',
139
+ file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
140
+ kind TEXT NOT NULL,
141
+ source_layer TEXT NOT NULL DEFAULT 'unknown',
142
+ line_number INTEGER NOT NULL,
143
+ text_snippet TEXT
144
+ );
145
+
146
+ -- \u6587\u4EF6\u4F9D\u8D56\uFF08import/export/\u7EC4\u4EF6\u5F15\u7528/store\u5F15\u7528\uFF09Phase 2
147
+ CREATE TABLE IF NOT EXISTS file_dependencies (
148
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
149
+ from_file TEXT NOT NULL,
150
+ to_file TEXT NOT NULL,
151
+ dependency_kind TEXT NOT NULL DEFAULT 'import',
152
+ line_number INTEGER NOT NULL DEFAULT 0
100
153
  );
101
154
 
102
155
  -- \u884C\u4E3A\u6807\u7B7E
@@ -106,23 +159,32 @@ import H from'path';import'url';import nn,{createHash}from'crypto';import {creat
106
159
  file_id INTEGER NOT NULL REFERENCES files(id) ON DELETE CASCADE,
107
160
  category TEXT NOT NULL,
108
161
  api_name TEXT NOT NULL,
162
+ api_name_lc TEXT NOT NULL DEFAULT '',
109
163
  operation TEXT NOT NULL,
164
+ operation_lc TEXT NOT NULL DEFAULT '',
110
165
  detail TEXT,
166
+ detail_lc TEXT NOT NULL DEFAULT '',
111
167
  line_number INTEGER NOT NULL DEFAULT 0
112
168
  );
113
169
 
114
- -- \u7D22\u5F15
170
+ -- \u7D22\u5F15\uFF08\u4EC5\u4FDD\u7559\u65E7\u5217\u7D22\u5F15\u2014\u2014\u65B0\u5217\u7D22\u5F15\u5728 migration \u4E4B\u540E\u521B\u5EFA\uFF09
115
171
  CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
116
- CREATE INDEX IF NOT EXISTS idx_symbols_category ON symbols(category);
117
- CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_id);
118
172
  CREATE INDEX IF NOT EXISTS idx_symbols_framework ON symbols(framework);
119
- CREATE INDEX IF NOT EXISTS idx_relations_caller ON relations(caller_id);
120
- CREATE INDEX IF NOT EXISTS idx_relations_callee ON relations(callee_name);
121
- CREATE INDEX IF NOT EXISTS idx_behaviors_category ON behaviors(category);
122
- CREATE INDEX IF NOT EXISTS idx_behaviors_api ON behaviors(api_name, operation);
123
173
  CREATE INDEX IF NOT EXISTS idx_behaviors_file ON behaviors(file_id);
174
+ `);let{applied:e,errors:t}=qt(this.db);e.length>0&&process.stderr.write(`[Frontend-Code-Skimmer] \u6570\u636E\u5E93\u8FC1\u79FB\u5B8C\u6210: v${e.join(", v")}
175
+ `),t.length>0&&process.stderr.write(`[Frontend-Code-Skimmer] \u8FC1\u79FB\u8B66\u544A: ${t.join("; ")}
176
+ `),this.db.exec(`
177
+ CREATE INDEX IF NOT EXISTS idx_behaviors_api_lc ON behaviors(api_name_lc, operation_lc);
178
+ CREATE INDEX IF NOT EXISTS idx_behaviors_detail_lc ON behaviors(detail_lc);
179
+ CREATE INDEX IF NOT EXISTS idx_file_deps_from ON file_dependencies(from_file);
180
+ CREATE INDEX IF NOT EXISTS idx_file_deps_to ON file_dependencies(to_file);
181
+ CREATE INDEX IF NOT EXISTS idx_relations_source_kind ON relations(source_kind);
182
+
183
+ CREATE INDEX IF NOT EXISTS idx_data_assign_name_lc ON data_assignments(symbol_name_lc);
184
+ CREATE INDEX IF NOT EXISTS idx_data_assign_file ON data_assignments(file_id);
185
+ CREATE INDEX IF NOT EXISTS idx_prop_writes_obj_lc ON property_writes(object_name_lc);
186
+ CREATE INDEX IF NOT EXISTS idx_prop_writes_file ON property_writes(file_id);
124
187
 
125
- -- \u8C03\u7528\u5173\u7CFB\u53C2\u6570 FTS5 \u5168\u6587\u641C\u7D22\u865A\u62DF\u8868
126
188
  CREATE VIRTUAL TABLE IF NOT EXISTS relations_fts USING fts5(
127
189
  args,
128
190
  content='relations',
@@ -149,26 +211,38 @@ import H from'path';import'url';import nn,{createHash}from'crypto';import {creat
149
211
  INSERT INTO relations_fts(rowid, args)
150
212
  VALUES (new.id, new.args);
151
213
  END;
152
- `);try{this.db.exec("ALTER TABLE relations ADD COLUMN args TEXT;");}catch{}try{this.db.exec("ALTER TABLE files ADD COLUMN file_mtime INTEGER DEFAULT 0;");}catch{}try{this.db.prepare("SELECT 1 FROM relations_fts LIMIT 1").get()||this.db.exec("INSERT OR IGNORE INTO relations_fts(rowid, args) SELECT id, args FROM relations WHERE args IS NOT NULL;");}catch{}}saveParseResult(e,t,n,s,r,o,i=0){let a=H.extname(t).slice(1);this.db.transaction(()=>{let u=this.db.prepare("SELECT id FROM files WHERE path = ?").get(n),p;u?(p=u.id,this.db.prepare("DELETE FROM symbols WHERE file_id = ?").run(p),this.db.prepare(`
214
+ `);}saveParseResult(e,t,n,s,r,i,a=0,c="",l=""){let u=K__default.extname(t).slice(1),p=Kn(t,n);this.db.transaction(()=>{let h=this.db.prepare("SELECT id FROM files WHERE path = ?").get(n),f;h?(f=h.id,this.db.prepare("DELETE FROM symbols WHERE file_id = ?").run(f),this.db.prepare(`
153
215
  UPDATE files SET
154
216
  abs_path = ?, framework = ?, content_hash = ?,
155
- last_indexed_at = ?, file_size = ?, line_count = ?, file_mtime = ?
217
+ last_indexed_at = ?, file_size = ?, line_count = ?, file_mtime = ?,
218
+ path_lc = LOWER(?),
219
+ export_signature_hash = ?, import_signature_hash = ?
156
220
  WHERE id = ?
157
- `).run(t,e.framework,s,Date.now(),r,o,i,p)):p=this.db.prepare(`
158
- INSERT INTO files (path, abs_path, file_type, framework, content_hash, last_indexed_at, file_size, line_count, file_mtime)
159
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
160
- `).run(n,t,a,e.framework,s,Date.now(),r,o,i).lastInsertRowid;let d=this.db.prepare(`
161
- INSERT INTO symbols (file_id, name, category, framework, start_line, end_line,
221
+ `).run(t,e.framework,s,Date.now(),r,i,a,n,c,l,f)):f=this.db.prepare(`
222
+ INSERT INTO files (path, path_lc, abs_path, file_type, framework, content_hash, last_indexed_at, file_size, line_count, file_mtime, export_signature_hash, import_signature_hash)
223
+ VALUES (?, LOWER(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
224
+ `).run(n,n,t,u,e.framework,s,Date.now(),r,i,a,c,l).lastInsertRowid;let m=this.db.prepare(`
225
+ INSERT INTO symbols (file_id, name, name_lc, category, category_lc, framework, start_line, end_line,
162
226
  signature, params_json, default_value, camel_words, jsdoc,
163
227
  is_async, hook_deps_json, state_setter_name, parent_component)
164
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
165
- `),f=new Map,m=new Map,g=b=>b.internalKey||`${b.name}:${b.startLine}:${b.endLine}`,E=(b,T)=>{f.set(g(b),T);let v=m.get(b.name)||[];v.push({id:T,name:b.name,startLine:b.startLine,endLine:b.endLine}),m.set(b.name,v);},h=(b,T,v)=>{if(v&&f.has(v))return f.get(v);let C=m.get(b)||[];if(C.length===0)return;if(C.length===1||T==null)return C[0]?.id;let P=C.filter(O=>O.startLine<=T&&T<=O.endLine);return P.length===1?P[0].id:P.length>1?P.sort((O,M)=>O.endLine-O.startLine-(M.endLine-M.startLine)||Math.abs(O.startLine-T)-Math.abs(M.startLine-T))[0]?.id:C.slice().sort((O,M)=>Math.abs(O.startLine-T)-Math.abs(M.startLine-T)||O.endLine-O.startLine-(M.endLine-M.startLine))[0]?.id};for(let b of e.symbols){let v=b.camelWords||A(b.name),C=d.run(p,b.name,b.category,b.framework,b.startLine,b.endLine,b.signature||null,b.params?JSON.stringify(b.params):null,b.defaultValue||null,v,b.jsdoc||null,b.isAsync?1:0,b.hookDeps?JSON.stringify(b.hookDeps):null,b.stateSetterName||null,b.parentComponent||null);E(b,C.lastInsertRowid);}let y=this.db.prepare(`
166
- INSERT INTO relations (caller_id, callee_name, call_type, line_number, args)
167
- VALUES (?, ?, ?, ?, ?)
168
- `);for(let b of e.relations){let T=h(b.callerName,b.callerLine,b.callerKey);T&&y.run(T,b.calleeName,b.callType,b.line,b.args||null);}let S=this.db.prepare(`
169
- INSERT INTO behaviors (symbol_id, file_id, category, api_name, operation, detail, line_number)
170
- VALUES (?, ?, ?, ?, ?, ?, ?)
171
- `);for(let b of e.behaviors){let T=h(b.symbolName,b.line,b.symbolKey);T&&S.run(T,p,b.category,b.apiName,b.operation,b.detail||null,b.line);}})();}getFileHash(e){return this.db.prepare("SELECT content_hash FROM files WHERE path = ?").get(e)?.content_hash??null}getFileMeta(e){let t=this.db.prepare("SELECT content_hash, file_mtime, file_size FROM files WHERE path = ?").get(e);return t?{hash:t.content_hash,mtime:t.file_mtime??0,fileSize:t.file_size??0}:null}updateFileMtime(e,t){this.db.prepare("UPDATE files SET file_mtime = ? WHERE path = ?").run(t,e);}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 n=t.id,s=this.db.prepare(`
228
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
229
+ `),b=new Map,g=new Map,E=_=>_.internalKey||`${_.name}:${_.startLine}:${_.endLine}`,y=(_,x)=>{b.set(E(_),x);let A=g.get(_.name)||[];A.push({id:x,name:_.name,startLine:_.startLine,endLine:_.endLine}),g.set(_.name,A);},N=(_,x,A)=>{if(A&&b.has(A))return b.get(A);let k=g.get(_)||[];if(k.length===0)return;if(k.length===1||x==null)return k[0]?.id;let I=k.filter(j=>j.startLine<=x&&x<=j.endLine);return I.length===1?I[0].id:I.length>1?I.sort((j,H)=>j.endLine-j.startLine-(H.endLine-H.startLine)||Math.abs(j.startLine-x)-Math.abs(H.startLine-x))[0]?.id:k.slice().sort((j,H)=>Math.abs(j.startLine-x)-Math.abs(H.startLine-x)||j.endLine-j.startLine-(H.endLine-H.startLine))[0]?.id};for(let _ of e.symbols){let A=_.camelWords||w(_.name),k=_.name.toLowerCase(),I=_.category.toLowerCase(),j=m.run(f,_.name,k,_.category,I,_.framework,_.startLine,_.endLine,_.signature||null,_.params?JSON.stringify(_.params):null,_.defaultValue||null,A,_.jsdoc||null,_.isAsync?1:0,_.hookDeps?JSON.stringify(_.hookDeps):null,_.stateSetterName||null,_.parentComponent||null);y(_,j.lastInsertRowid);}let T=this.db.prepare(`
230
+ INSERT INTO relations (caller_id, callee_name, callee_name_lc, call_type, line_number, args,
231
+ source_kind, import_source, receiver_token, edge_kind)
232
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
233
+ `);for(let _ of e.relations){let x=N(_.callerName,_.callerLine,_.callerKey);if(x){let A=_.sourceKind||He(_.callType);T.run(x,_.calleeName,_.calleeName.toLowerCase(),_.callType,_.line,_.args||null,A,_.importSource||null,_.receiverToken||null,_.edgeKind||"heuristic");}}if(this.db.prepare("DELETE FROM data_assignments WHERE file_id = ?").run(f),e.assignments?.length){let _=this.db.prepare(`
234
+ INSERT INTO data_assignments (symbol_name, symbol_name_lc, file_id, kind, source_layer, line_number, text_snippet)
235
+ VALUES (?, ?, ?, ?, ?, ?, ?)
236
+ `);for(let x of e.assignments)_.run(x.symbolName,x.symbolName.toLowerCase(),f,x.kind,x.sourceLayer||"unknown",x.line,x.text);}if(this.db.prepare("DELETE FROM property_writes WHERE file_id = ?").run(f),e.propertyWrites?.length){let _=this.db.prepare(`
237
+ INSERT INTO property_writes (object_name, object_name_lc, property_name, property_name_lc, file_id, kind, source_layer, line_number, text_snippet)
238
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
239
+ `);for(let x of e.propertyWrites)_.run(x.objectName,x.objectName.toLowerCase(),x.propertyName||null,x.propertyName?.toLowerCase()||"",f,x.kind,x.sourceLayer||"unknown",x.line,x.text);}if(this.db.prepare("DELETE FROM file_dependencies WHERE from_file = ?").run(n),e.fileDependencies?.length){let _=this.db.prepare(`
240
+ INSERT INTO file_dependencies (from_file, to_file, dependency_kind, line_number)
241
+ VALUES (?, ?, ?, ?)
242
+ `);for(let x of e.fileDependencies)_.run(n,zn(x.toFile,t,p),x.dependencyKind,x.line);}let R=this.db.prepare(`
243
+ INSERT INTO behaviors (symbol_id, file_id, category, api_name, api_name_lc, operation, operation_lc, detail, detail_lc, line_number)
244
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
245
+ `);for(let _ of e.behaviors){let x=N(_.symbolName,_.line,_.symbolKey);if(x){let A=_.detail||null;R.run(x,f,_.category,_.apiName,_.apiName.toLowerCase(),_.operation,_.operation.toLowerCase(),A,A?.toLowerCase()??"",_.line);}}})();}getFileHash(e){return this.db.prepare("SELECT content_hash FROM files WHERE path = ?").get(e)?.content_hash??null}getFileMeta(e){let t=this.db.prepare("SELECT content_hash, file_mtime, file_size FROM files WHERE path = ?").get(e);return t?{hash:t.content_hash,mtime:t.file_mtime??0,fileSize:t.file_size??0}:null}updateFileMtime(e,t){this.db.prepare("UPDATE files SET file_mtime = ? WHERE path = ?").run(t,e);}getFileSignatures(e){let t=this.db.prepare("SELECT content_hash, export_signature_hash, import_signature_hash FROM files WHERE path = ?").get(e);return t?{contentHash:t.content_hash,exportSignatureHash:t.export_signature_hash||"",importSignatureHash:t.import_signature_hash||""}:null}getReverseDependencies(e){return this.db.prepare("SELECT from_file FROM file_dependencies WHERE to_file = ? AND dependency_kind = 'import'").all(e).map(n=>n.from_file)}getReverseDependencyMap(){let e=this.db.prepare("SELECT from_file, to_file FROM file_dependencies WHERE dependency_kind = 'import'").all(),t=new Map;for(let{from_file:n,to_file:s}of e){let r=t.get(s)||[];r.push(n),t.set(s,r);}return t}getAllFilePaths(){return this.db.prepare("SELECT path FROM files ORDER BY path").all().map(t=>t.path)}getFileHashAndMtime(e){let t=this.db.prepare("SELECT content_hash, file_mtime FROM files WHERE path = ?").get(e);return t?{contentHash:t.content_hash,mtime:t.file_mtime??0}:null}deleteFile(e){this.db.prepare("DELETE FROM file_dependencies WHERE from_file = ? OR to_file = ?").run(e,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 n=t.id,s=this.db.prepare(`
172
246
  SELECT s.*, f.path as file_path
173
247
  FROM symbols s JOIN files f ON s.file_id = f.id
174
248
  WHERE s.file_id = ?
@@ -177,25 +251,25 @@ import H from'path';import'url';import nn,{createHash}from'crypto';import {creat
177
251
  SELECT b.*, s.name as symbol_name
178
252
  FROM behaviors b JOIN symbols s ON b.symbol_id = s.id
179
253
  WHERE b.file_id = ?
180
- `).all(n);return {file:t,symbols:s,behaviors:r}}listFiles(e){let t="SELECT path, abs_path, framework, line_count FROM files",n=[];return e&&(t+=" WHERE path LIKE ?",n.push(`%${e}%`)),t+=" ORDER BY path",this.db.prepare(t).all(...n)}exactSearch(e,t,n,s){let r=`
254
+ `).all(n);return {file:t,symbols:s,behaviors:r}}listFiles(e){let t="SELECT path, abs_path, framework, line_count FROM files",n=[];return e&&(t+=" WHERE path_lc LIKE ?",n.push(`%${e.toLowerCase()}%`)),t+=" ORDER BY path",this.db.prepare(t).all(...n)}exactSearch(e,t,n,s){let r=`
181
255
  SELECT s.*, f.path as file_path, f.abs_path
182
256
  FROM symbols s JOIN files f ON s.file_id = f.id
183
- WHERE LOWER(s.name) = LOWER(?)
184
- `,o=[e];return t&&(r+=" AND s.category = ?",o.push(t)),n&&(r+=" AND s.framework = ?",o.push(n)),s&&(r+=" AND f.path LIKE ?",o.push(`%${s}%`)),r+=" LIMIT 30",this.db.prepare(r).all(...o)}ftsSearch(e,t,n,s,r=20){let o=Math.max(1,Math.min(200,r)),a=e.replace(/[^\w\u4e00-\u9fa5\s]/g," ").trim().split(/\s+/).filter(c=>c.length>=2);if(a.length>0){let c=a.map(u=>`${u}*`).join(" ");try{let u=`
257
+ WHERE s.name_lc = ?
258
+ `,i=[e.toLowerCase()];return t&&(r+=" AND s.category_lc = ?",i.push(t.toLowerCase())),n&&(r+=" AND s.framework = ?",i.push(n)),s&&(r+=" AND f.path_lc LIKE ?",i.push(`%${s.toLowerCase()}%`)),r+=" LIMIT 30",this.db.prepare(r).all(...i)}ftsSearch(e,t,n,s,r=20,i=true){let a=Math.max(1,Math.min(200,r)),l=e.replace(/[^\w\u4e00-\u9fa5\s]/g," ").trim().split(/\s+/).filter(u=>u.length>=2);if(l.length>0){let u=l.map(p=>`${p}*`).join(" ");try{let p=`
185
259
  SELECT s.*, f.path as file_path, f.abs_path,
186
260
  bm25(symbols_fts, 10.0, 1.0, 0.5, 0.5) as fts_rank
187
261
  FROM symbols_fts
188
262
  JOIN symbols s ON symbols_fts.rowid = s.id
189
263
  JOIN files f ON s.file_id = f.id
190
264
  WHERE symbols_fts MATCH ?
191
- `,p=[c];return t&&(u+=" AND s.category = ?",p.push(t)),n&&(u+=" AND s.framework = ?",p.push(n)),s&&(u+=" AND f.path LIKE ?",p.push(`%${s}%`)),u+=` ORDER BY fts_rank LIMIT ${o}`,this.db.prepare(u).all(...p)}catch{}}return this.ftsLikeFallback(e,t,n,s,o)}ftsLikeFallback(e,t,n,s,r=20){let o=e.replace(/[\\%_]/g,"\\$&"),i=`
265
+ `,d=[u];return t&&(p+=" AND s.category_lc = ?",d.push(t.toLowerCase())),n&&(p+=" AND s.framework = ?",d.push(n)),s&&(p+=" AND f.path_lc LIKE ?",d.push(`%${s.toLowerCase()}%`)),p+=` ORDER BY fts_rank LIMIT ${a}`,this.db.prepare(p).all(...d)}catch{if(i)return []}}return i?[]:this.ftsLikeFallback(e,t,n,s,a)}ftsSearchWithFallback(e,t,n,s,r=20){return this.ftsSearch(e,t,n,s,r,false)}ftsLikeFallback(e,t,n,s,r=20){let i=e.toLowerCase().replace(/[\\%_]/g,"\\$&"),a=`
192
266
  SELECT s.*, f.path as file_path, f.abs_path, 0 as fts_rank
193
267
  FROM symbols s JOIN files f ON s.file_id = f.id
194
- WHERE (LOWER(s.name) LIKE LOWER(?) OR LOWER(s.camel_words) LIKE LOWER(?)) ESCAPE '\\'
195
- `,a=[`%${o}%`,`%${o}%`];return t&&(i+=" AND s.category = ?",a.push(t)),n&&(i+=" AND s.framework = ?",a.push(n)),s&&(i+=" AND f.path LIKE ?",a.push(`%${s}%`)),i+=` LIMIT ${Math.max(1,Math.min(200,r))}`,this.db.prepare(i).all(...a)}getAllSymbolNames(e){let t=`
268
+ WHERE (s.name_lc LIKE ? OR LOWER(s.camel_words) LIKE ?) ESCAPE '\\'
269
+ `,c=[`%${i}%`,`%${i}%`];return t&&(a+=" AND s.category_lc = ?",c.push(t.toLowerCase())),n&&(a+=" AND s.framework = ?",c.push(n)),s&&(a+=" AND f.path_lc LIKE ?",c.push(`%${s.toLowerCase()}%`)),a+=` LIMIT ${Math.max(1,Math.min(200,r))}`,this.db.prepare(a).all(...c)}getAllSymbolNames(e){let t=`
196
270
  SELECT DISTINCT s.name, f.path as file_path, s.id
197
271
  FROM symbols s JOIN files f ON s.file_id = f.id
198
- `,n=[];return e&&(t+=" WHERE f.path LIKE ?",n.push(`%${e}%`)),this.db.prepare(t).all(...n)}getSymbolById(e){return this.db.prepare(`
272
+ `,n=[];return e&&(t+=" WHERE f.path_lc LIKE ?",n.push(`%${e.toLowerCase()}%`)),this.db.prepare(t).all(...n)}getSymbolById(e){return this.db.prepare(`
199
273
  SELECT s.*, f.path as file_path, f.abs_path
200
274
  FROM symbols s JOIN files f ON s.file_id = f.id
201
275
  WHERE s.id = ?
@@ -207,53 +281,53 @@ import H from'path';import'url';import nn,{createHash}from'crypto';import {creat
207
281
  `).get(e,t);return s||(s=this.db.prepare(`
208
282
  SELECT s.*, f.path as file_path, f.abs_path
209
283
  FROM symbols s JOIN files f ON s.file_id = f.id
210
- WHERE s.name = ? AND f.path LIKE ?
211
- ORDER BY
284
+ WHERE s.name = ? AND f.path_lc LIKE ?
285
+ ORDER BY
212
286
  LENGTH(f.path) ASC,
213
- CASE s.category
214
- WHEN 'component' THEN 1
215
- WHEN 'hook' THEN 2
216
- WHEN 'method' THEN 3
217
- WHEN 'state' THEN 4
218
- ELSE 5
287
+ CASE s.category
288
+ WHEN 'component' THEN 1
289
+ WHEN 'hook' THEN 2
290
+ WHEN 'method' THEN 3
291
+ WHEN 'state' THEN 4
292
+ ELSE 5
219
293
  END ASC,
220
294
  s.parent_component IS NULL DESC,
221
295
  f.line_count DESC
222
296
  LIMIT 1
223
- `).get(e,`%${t}%`)),s}if(!((this.db.prepare(`
297
+ `).get(e,`%${t.toLowerCase()}%`)),s}if(!((this.db.prepare(`
224
298
  SELECT COUNT(DISTINCT f.path) as c
225
299
  FROM symbols s JOIN files f ON s.file_id = f.id
226
- WHERE s.name = ?
227
- `).get(e)?.c||0)>1))return this.db.prepare(`
300
+ WHERE s.name_lc = ?
301
+ `).get(e.toLowerCase())?.c||0)>1))return this.db.prepare(`
228
302
  SELECT s.*, f.path as file_path, f.abs_path
229
303
  FROM symbols s JOIN files f ON s.file_id = f.id
230
- WHERE s.name = ?
231
- ORDER BY
232
- CASE s.category
233
- WHEN 'component' THEN 1
234
- WHEN 'hook' THEN 2
235
- WHEN 'method' THEN 3
236
- WHEN 'state' THEN 4
237
- ELSE 5
304
+ WHERE s.name_lc = ?
305
+ ORDER BY
306
+ CASE s.category
307
+ WHEN 'component' THEN 1
308
+ WHEN 'hook' THEN 2
309
+ WHEN 'method' THEN 3
310
+ WHEN 'state' THEN 4
311
+ ELSE 5
238
312
  END ASC,
239
313
  s.parent_component IS NULL DESC,
240
314
  f.line_count DESC
241
315
  LIMIT 1
242
- `).get(e)}behaviorSearch(e,t,n,s,r){let o=`
316
+ `).get(e.toLowerCase())}behaviorSearch(e,t,n,s,r){let i=`
243
317
  SELECT b.*, s.name as symbol_name, s.start_line, s.end_line, s.category as symbol_category,
244
318
  f.path as file_path
245
319
  FROM behaviors b
246
320
  JOIN symbols s ON b.symbol_id = s.id
247
321
  JOIN files f ON b.file_id = f.id
248
322
  WHERE 1=1
249
- `,i=[];return e&&(o+=" AND b.category = ?",i.push(e)),t&&(o+=" AND LOWER(b.api_name) = LOWER(?)",i.push(t)),n&&(o+=" AND LOWER(b.operation) = LOWER(?)",i.push(n)),s&&(o+=" AND (LOWER(b.detail) LIKE LOWER(?) OR LOWER(b.api_name) LIKE LOWER(?))",i.push(`%${s}%`,`%${s}%`)),r&&(o+=" AND f.path LIKE ?",i.push(`%${r}%`)),o+=" ORDER BY f.path, b.line_number LIMIT 50",this.db.prepare(o).all(...i)}getCallers(e,t,n){let s=`
323
+ `,a=[];return e&&(i+=" AND b.category = ?",a.push(e)),t&&(i+=" AND b.api_name_lc = ?",a.push(t.toLowerCase())),n&&(i+=" AND b.operation_lc = ?",a.push(n.toLowerCase())),s&&(i+=" AND (b.detail_lc LIKE ? OR b.api_name_lc LIKE ?)",a.push(`%${s.toLowerCase()}%`,`%${s.toLowerCase()}%`)),r&&(i+=" AND f.path_lc LIKE ?",a.push(`%${r.toLowerCase()}%`)),i+=" ORDER BY f.path, b.line_number LIMIT 50",this.db.prepare(i).all(...a)}getCallers(e,t,n){let s=`
250
324
  SELECT r.*, s.name as caller_name, s.start_line, s.end_line, s.category,
251
325
  f.path as file_path
252
326
  FROM relations r
253
327
  JOIN symbols s ON r.caller_id = s.id
254
328
  JOIN files f ON s.file_id = f.id
255
- WHERE r.callee_name = ?
256
- `,r=[e];return t&&(s+=" AND f.path LIKE ?",r.push(`%${t}%`)),n&&(s+=" AND LOWER(COALESCE(r.args, '')) LIKE LOWER(?)",r.push(`%${n}%`)),s+=" ORDER BY f.path, r.line_number",this.db.prepare(s).all(...r)}getCallees(e){return this.db.prepare(`
329
+ WHERE r.callee_name_lc = ?
330
+ `,r=[e.toLowerCase()];return t&&(s+=" AND f.path_lc LIKE ?",r.push(`%${t.toLowerCase()}%`)),n&&(s+=" AND LOWER(COALESCE(r.args, '')) LIKE LOWER(?)",r.push(`%${n}%`)),s+=" ORDER BY f.path, r.line_number",this.db.prepare(s).all(...r)}getCallees(e){return this.db.prepare(`
257
331
  SELECT r.*, r.callee_name
258
332
  FROM relations r
259
333
  WHERE r.caller_id = ?
@@ -265,25 +339,77 @@ import H from'path';import'url';import nn,{createHash}from'crypto';import {creat
265
339
  JOIN symbols s ON r.caller_id = s.id
266
340
  JOIN files f ON s.file_id = f.id
267
341
  WHERE fts.args MATCH ?
268
- `,i=[`"${s.replace(/"/g,'""')}"`];t&&(r+=" AND f.path LIKE ?",i.push(`%${t}%`)),r+=" ORDER BY f.path, r.line_number LIMIT ?",i.push(n);let a=[],c=false,u=false;try{a=this.db.prepare(r).all(...i),a.length>0&&(c=!0);}catch{u=true;}let p=/[^a-zA-Z0-9_\u4e00-\u9fa5]/.test(s);if(!c&&(u||p)){let f=s.replace(/[\\%_]/g,"\\$&"),m=`
342
+ `,a=[`"${s.replace(/"/g,'""')}"`];t&&(r+=" AND f.path_lc LIKE ?",a.push(`%${t.toLowerCase()}%`)),r+=" ORDER BY f.path, r.line_number LIMIT ?",a.push(n);let c=[],l=false,u=false;try{c=this.db.prepare(r).all(...a),c.length>0&&(l=!0);}catch{u=true;}let p=/[^a-zA-Z0-9_\u4e00-\u9fa5]/.test(s);if(!l&&(u||p)){let h=s.replace(/[\\%_]/g,"\\$&"),f=`
269
343
  SELECT r.*, s.name as caller_name, s.start_line, s.end_line, s.category,
270
344
  f.path as file_path
271
345
  FROM relations r
272
346
  JOIN symbols s ON r.caller_id = s.id
273
347
  JOIN files f ON s.file_id = f.id
274
348
  WHERE LOWER(COALESCE(r.args, '')) LIKE LOWER(?) ESCAPE '\\'
275
- `,g=[`%${f}%`];t&&(m+=" AND f.path LIKE ?",g.push(`%${t}%`)),m+=" ORDER BY f.path, r.line_number LIMIT ?",g.push(n),a=this.db.prepare(m).all(...g);}return a}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,n=this.db.prepare("SELECT COUNT(*) as c FROM behaviors").get().c,s=this.db.prepare("SELECT COUNT(*) as c FROM relations").get().c,r=this.db.prepare(`
349
+ `,m=[`%${h}%`];t&&(f+=" AND f.path_lc LIKE ?",m.push(`%${t.toLowerCase()}%`)),f+=" ORDER BY f.path, r.line_number LIMIT ?",m.push(n),c=this.db.prepare(f).all(...m);}return c}getLastIndexedTime(){return this.db.prepare("SELECT MAX(last_indexed_at) as ts FROM files").get()?.ts??null}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,n=this.db.prepare("SELECT COUNT(*) as c FROM behaviors").get().c,s=this.db.prepare("SELECT COUNT(*) as c FROM relations").get().c,r=this.db.prepare(`
276
350
  SELECT framework, COUNT(*) as count FROM files GROUP BY framework
277
- `).all(),o=this.db.prepare(`
351
+ `).all(),i=this.db.prepare(`
278
352
  SELECT f.path, f.line_count, COUNT(s.id) as symbol_count
279
353
  FROM files f LEFT JOIN symbols s ON f.id = s.file_id
280
354
  GROUP BY f.id
281
355
  ORDER BY f.line_count DESC LIMIT 10
282
- `).all(),i=this.db.prepare(`
356
+ `).all(),a=this.db.prepare(`
283
357
  SELECT category, COUNT(*) as count FROM behaviors GROUP BY category ORDER BY count DESC
284
- `).all(),a=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:n,relationCount:s,frameworkBreakdown:r,topFiles:o,behaviorStats:i,dbSize:a}}close(){this.db.close();}};Y();var ln=8,pn=30,dn=14,un=360*60*1e3,ke=class{dbCache=new Map;accessTimes=new Map;dbPaths=new Map;watcherCleanups=new Map;lastProject=null;globalCacheDir;defaultProject;maxOpenProjects;maxIdleMs;dbTtlMs;lastDiskCleanupAt=0;constructor(){this.globalCacheDir=H.join(an.homedir(),".frontend-code-skimmer","databases"),F.mkdirSync(this.globalCacheDir,{recursive:true}),this.defaultProject=process.env.SKIMMER_PROJECT||null,this.defaultProject&&(this.defaultProject=H.resolve(this.defaultProject)),this.maxOpenProjects=this.parsePositiveInt(process.env.SKIMMER_MAX_OPEN_PROJECTS,ln);let e=this.parsePositiveInt(process.env.SKIMMER_DB_IDLE_MINUTES,pn),t=this.parsePositiveInt(process.env.SKIMMER_DB_TTL_DAYS,dn);this.maxIdleMs=e*60*1e3,this.dbTtlMs=t*24*60*60*1e3,this.maybeCleanupDiskCache(Date.now());}resolveProjectRoot(e){if(e){let t=H.resolve(e);if(!F.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=H.resolve(e),n=Date.now();if(this.evictIdleDatabases(n),this.maybeCleanupDiskCache(n),this.dbCache.has(t))return this.touchProject(t,n),this.dbCache.get(t);this.evictLruIfNeeded(n);let s=this.resolveDbPath(t),r=new Te(t,s);return this.dbCache.set(t,r),this.dbPaths.set(t,s),this.touchProject(t,n),this.lastProject=t,process.stderr.write(`[Frontend-Code-Skimmer] \u5DF2\u8FDE\u63A5\u9879\u76EE: ${t}
358
+ `).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:n,relationCount:s,frameworkBreakdown:r,topFiles:i,behaviorStats:a,dbSize:c}}getFileDependencies(e,t="both"){return t==="from"?this.db.prepare(`
359
+ SELECT * FROM file_dependencies WHERE from_file = ? ORDER BY dependency_kind, to_file
360
+ `).all(e):t==="to"?this.db.prepare(`
361
+ SELECT * FROM file_dependencies WHERE to_file = ? ORDER BY dependency_kind, from_file
362
+ `).all(e):this.db.prepare(`
363
+ SELECT * FROM file_dependencies WHERE from_file = ? OR to_file = ?
364
+ ORDER BY dependency_kind, from_file, to_file
365
+ `).all(e,e)}getAssignments(e,t,n=40){let s=`
366
+ SELECT a.*, f.path as file_path
367
+ FROM data_assignments a JOIN files f ON a.file_id = f.id
368
+ WHERE a.symbol_name_lc = ?
369
+ `,r=[e.toLowerCase()];return t&&(s+=" AND f.path_lc LIKE ?",r.push(`%${t.toLowerCase()}%`)),s+=" ORDER BY f.path, a.line_number LIMIT ?",r.push(n),this.db.prepare(s).all(...r)}getPropertyWrites(e,t,n,s=40){let r=`
370
+ SELECT pw.*, f.path as file_path
371
+ FROM property_writes pw JOIN files f ON pw.file_id = f.id
372
+ WHERE pw.object_name_lc = ?
373
+ `,i=[e.toLowerCase()];return t&&(r+=" AND pw.property_name_lc = ?",i.push(t.toLowerCase())),n&&(r+=" AND f.path_lc LIKE ?",i.push(`%${n.toLowerCase()}%`)),r+=" ORDER BY f.path, pw.line_number LIMIT ?",i.push(s),this.db.prepare(r).all(...i)}getCallersWithSourceKind(e,t,n){let s=`
374
+ SELECT r.*, s.name as caller_name, s.start_line, s.end_line, s.category,
375
+ f.path as file_path
376
+ FROM relations r
377
+ JOIN symbols s ON r.caller_id = s.id
378
+ JOIN files f ON s.file_id = f.id
379
+ WHERE r.callee_name_lc = ?
380
+ `,r=[e.toLowerCase()];return t&&(s+=" AND f.path_lc LIKE ?",r.push(`%${t.toLowerCase()}%`)),n&&(s+=" AND LOWER(COALESCE(r.args, '')) LIKE LOWER(?)",r.push(`%${n}%`)),s+=" ORDER BY f.path, r.line_number",this.db.prepare(s).all(...r)}close(){this.db.close();}};function Y(o,e,t,n=false){let s=[];return z(o,i=>{if(n&&i!==o&&(i.type==="FunctionDeclaration"||i.type==="ArrowFunctionExpression"||i.type==="FunctionExpression"||i.type==="ClassDeclaration"))return false;if(i.type==="CallExpression"){let c=Vn(i,e);c&&s.push(c);}if(i.type==="MemberExpression"){let a=Gn(i);a&&s.push(a);}}),es(s)}function Vn(o,e,t){let n=o.callee;if(!n)return null;let s=qe(o);if(n.type==="MemberExpression"){let r=qn(n);if(!r)return null;let{apiName:i,operation:a}=r,c=o.arguments,l=te(c?.[0]),u=Zn(i);return u?{symbolName:e,category:u,apiName:i,operation:a,detail:l,line:s}:i==="this"&&Ve(a)?{symbolName:e,category:"network",apiName:`this.${a}`,operation:"wrapped_call",detail:l||te(c?.[1]),line:s}:Jt(a)&&Qn(c)?{symbolName:e,category:"network",apiName:i,operation:a,detail:l||te(c?.[1]),line:s}:Ve(i)||Ve(`${i}.${a}`)?{symbolName:e,category:"network",apiName:i,operation:Jt(a)?a:"wrapped_call",detail:l||te(c?.[1]),line:s}:null}if(n.type==="Identifier"){let r=n.name,i=Jn(r),a=o.arguments,c=te(a?.[0]);return i?{symbolName:e,category:i.category,apiName:r,operation:i.operation,detail:c,line:s}:Ve(r)?{symbolName:e,category:"network",apiName:r,operation:"wrapped_call",detail:c||te(a?.[1]),line:s}:null}return null}function Gn(o,e,t){let n=o.object,s=o.property;if(!n||!s||n.type!=="MemberExpression"&&n.type!=="ThisExpression"&&n.type!=="Identifier")return null;let r=Yn(n);if(!r)return null;s.type==="Identifier"?s.name:"";if(r==="this"||r===""){n.type==="MemberExpression"?n.property?.name:"";return null}return null}function qn(o){let e=o.object,t=o.property;if(!e||!t||t.type!=="Identifier")return null;let n=t.name;if(e.type==="MemberExpression"){let s=e.property?.name;if(s)return {apiName:s,operation:n}}return e.type==="Identifier"?{apiName:e.name,operation:n}:e.type==="ThisExpression"?{apiName:"this",operation:n}:null}function Jn(o){let e={fetch:"network",setTimeout:"timer",setInterval:"timer",clearTimeout:"timer",clearInterval:"timer",requestAnimationFrame:"timer",navigate:"router"};return e[o]?{category:e[o],operation:o}:null}function qe(o){return o.loc?.start?.line??0}function Yn(o){return o.type==="Identifier"?o.name:o.type==="ThisExpression"?"this":null}function Zn(o){if(o==="this")return null;for(let[e,t]of Object.entries(Wt))if(o in t)return e;return null}function te(o,e){if(o){if(o.type==="Literal"||o.type==="StringLiteral"||o.type==="NumericLiteral"||o.type==="BooleanLiteral")return String(o.value);if(o.type==="NullLiteral")return "null";if(o.type==="TemplateLiteral"){let t=o.quasis,n=o.expressions||[],s=[];for(let i=0;i<t.length;i++){let a=t[i].value?.cooked||"";if(a&&s.push(a),i<n.length){let c=Ge(n[i])||"expr";s.push(`\${${c}}`);}}return s.join("")||"${expr}"}if(o.type==="Identifier")return `[\u53D8\u91CF: ${o.name}]`;if(o.type==="ObjectExpression"){let t=o.properties||[],n=["url","uri","path","api","endpoint"];for(let s of t){let r=s.key,i=s.value;if(!r||!i)continue;let a=r.type==="Identifier"?String(r.name):r.type==="Literal"?String(r.value):"";if(!n.includes(a))continue;let c=te(i);if(c)return `${a}:${c}`}return "{...}"}}}function Ge(o,e){if(!o)return;if(o.type==="Identifier")return o.name;if(o.type==="ThisExpression")return "this";if(o.type==="Literal"||o.type==="StringLiteral"||o.type==="NumericLiteral"||o.type==="BooleanLiteral")return String(o.value);if(o.type==="NullLiteral")return "null";if(o.type==="MemberExpression"){let n=Ge(o.object)||"obj",s=o.property,r=s?.type==="Identifier"?String(s.name):Ge(s)||"prop";return o.computed?`${n}[${r}]`:`${n}.${r}`}if(o.type==="CallExpression")return `${Ge(o.callee)||"fn"}(...)`;if(o.type==="TemplateLiteral")return te(o);let t=te(o);return t?.startsWith("[\u53D8\u91CF: ")?t.replace(/^\[变量: /,"").replace(/\]$/,""):t}function Ve(o){return /request|api|http|fetch|ajax|akscommonhandle|commonhandle/i.test(o)}function Jt(o){return ["get","post","put","delete","patch","request"].includes(o.toLowerCase())}function Qn(o,e){if(!o||o.length===0)return false;for(let t of o.slice(0,2)){let n=te(t);if(n&&(/https?:\/\//i.test(n)||n.includes("/")||/gw\d?\/|\/m\/|\/api\//i.test(n)))return true}return false}function es(o){let e=new Set;return o.filter(t=>{let n=`${t.apiName}:${t.operation}:${t.line}`;return e.has(n)?false:(e.add(n),true)})}function Je(o,e,t){let n=[];return z(o,s=>{if(s.type==="CallExpression"&&s.callee?.type==="MemberExpression"){let r=s.callee,i=r.object,a=r.property;if(i.type==="ThisExpression"&&a.type==="Identifier"){let c=a.name;if(!c.startsWith("$")&&c!==e){let l=s.arguments,u=Yt(l);n.push({calleeName:c,line:qe(s),args:u});}}}}),n}function de(o,e,t,n=false){let s=[];return z(o,i=>{if(n&&i!==o&&(i.type==="FunctionDeclaration"||i.type==="ArrowFunctionExpression"||i.type==="FunctionExpression"||i.type==="ClassDeclaration"))return false;if(i.type==="CallExpression"&&i.callee?.type==="Identifier"){let a=i.callee.name;if(a!==e&&!ts(a)){let c=i.arguments,l=Yt(c);s.push({calleeName:a,line:qe(i),args:l});}}}),s}function ts(o){return /^(useState|useEffect|useMemo|useCallback|useRef|useContext|useReducer|ref|reactive|computed|watch|watchEffect|console|setTimeout|setInterval|Math|Object|Array|JSON|String|Number|Boolean|Promise|require|import)$/.test(o)}function Yt(o,e){if(!o||o.length===0)return;let t=o.slice(0,3).map(n=>te(n)).filter(n=>!!n);return t.length>0?t.join(", "):void 0}function z(o,e){if(!(!o||typeof o!="object")&&e(o)!==false)for(let t of Object.keys(o)){if(t==="type"||t==="loc"||t==="start"||t==="end")continue;let n=o[t];if(Array.isArray(n))for(let s of n)s&&typeof s=="object"&&s.type&&z(s,e);else n&&typeof n=="object"&&n.type&&z(n,e);}}function Ye(o,e){let t=[],n=new Set,s=o.split(`
381
+ `);for(let r=0;r<s.length;r++){let i=/(?:@|v-on:)[a-z][a-z0-9-]*(?:\.[a-z-]+)*="([^"]+)"/g,a;for(;(a=i.exec(s[r]))!==null;){let l=a[1].trim().match(/^([a-zA-Z_$][a-zA-Z0-9_$]*)(?:\([^)]*\))?$/);if(!l)continue;let u=l[1];u.startsWith("$")||n.has(u)||(n.add(u),t.push({calleeName:u,line:e+r}));}}return t}function Zt(o,e){let t=[],n=new Set;return z(o,s=>{if(s.type!=="JSXAttribute")return;let r=s.name,i=s.value;if(!r||!i)return;let a=r.type==="JSXIdentifier"?String(r.name):"";if(!/^on[A-Z]/.test(a)||i.type!=="JSXExpressionContainer")return;let c=i.expression;if(!c)return;let l;if(c.type==="Identifier")l=c.name;else if(c.type==="MemberExpression"){let u=c.property?.name;u&&!/^\$/.test(u)&&(l=u);}!l||n.has(l)||(n.add(l),t.push({calleeName:l,line:qe(s)}));}),t}var ss=createRequire(import.meta.url),Qt=false;function rs(o){Qt||(Qt=true,process.stderr.write(`[Frontend-Code-Skimmer] precise import graph \u5DF2\u964D\u7EA7: ${String(o)}
382
+ `));}function en(o,e,t){let n={filePath:o,imports:[],exports:[]};try{let s=ss("typescript"),r=s.createSourceFile(o,e,s.ScriptTarget.Latest,!0);s.forEachChild(r,i=>{if(s.isImportDeclaration(i)){let a=i.moduleSpecifier;if(!a||!s.isStringLiteral(a))return;let c=a.text,l=Qe(o,c),u=i.importClause;if(!u){n.imports.push({localName:"",originalName:"",modulePath:c,resolvedFile:l,isDefault:!1,isReExport:!1});return}let p=u.namedBindings;if(p&&s.isNamedImports(p))for(let d of p.elements){let h=d.propertyName?d.propertyName.text:d.name.text;n.imports.push({localName:d.name.text,originalName:h,modulePath:c,resolvedFile:l,isDefault:!1,isReExport:!1});}p&&s.isNamespaceImport(p)&&n.imports.push({localName:p.name.text,originalName:"*",modulePath:c,resolvedFile:l,isDefault:!1,isReExport:!1}),u.name&&n.imports.push({localName:u.name.text,originalName:"default",modulePath:c,resolvedFile:l,isDefault:!0,isReExport:!1});}if(s.isExportDeclaration(i)){let a=i.moduleSpecifier;if(a&&s.isStringLiteral(a)){let c=a.text,l=i.exportClause;if(l&&s.isNamedExports(l))for(let u of l.elements)n.exports.push({name:u.name.text,isDefault:!1,source:"re_export",reExportFrom:c});}else if(i.exportClause){let c=i.exportClause;if(s.isNamedExports(c))for(let l of c.elements)n.exports.push({name:l.name.text,isDefault:!1,source:"local"});}}if(s.isExportAssignment(i)&&(i.isExportEquals||n.exports.push({name:"default",isDefault:!0,source:"local"})),(s.isFunctionDeclaration(i)||s.isVariableStatement(i)||s.isClassDeclaration(i))&&i.modifiers?.some(a=>a.kind===s.SyntaxKind.ExportKeyword)){if(s.isFunctionDeclaration(i)&&i.name)n.exports.push({name:i.name.text,isDefault:i.name.text==="default",source:"local"});else if(s.isClassDeclaration(i)&&i.name)n.exports.push({name:i.name.text,isDefault:i.name.text==="default",source:"local"});else if(s.isVariableStatement(i))for(let a of i.declarationList.declarations)s.isIdentifier(a.name)&&n.exports.push({name:a.name.text,isDefault:!1,source:"local"});}});}catch(s){rs(s);}return n}function Qe(o,e){let t=K.dirname(o);if(e.startsWith(".")){let n=K.resolve(t,e);return Ne(n)}return e.startsWith("@/")?is(o,e):e}function is(o,e){let t=K.dirname(o);for(let n=0;n<10;n++){let s=K.join(t,"src");if(J.existsSync(s)&&J.statSync(s).isDirectory()){let i=K.join(s,e.replace(/^@\//,""));return Ne(i)}let r=K.dirname(t);if(r===t)break;t=r;}return e}function X(o){return {callerName:o.callerName,callerLine:o.callerLine,callerKey:o.callerKey,calleeName:o.calleeName,callType:o.callType,line:o.line,args:o.args,sourceKind:He(o.callType),importSource:o.importSource,receiverToken:o.receiverToken,edgeKind:o.edgeKind||"heuristic"}}function Te(o,e){let t=[];for(let n of o){let s=n.type;if(s==="ImportDeclaration"){let r=n.source,i=n.loc;r?.value&&t.push({fromFile:e,toFile:Qe(e,r.value),dependencyKind:"import",line:i?.start?.line??1});}if(s==="ExportNamedDeclaration"||s==="ExportAllDeclaration"){let r=n.source,i=n.loc;r?.value&&t.push({fromFile:e,toFile:Qe(e,r.value),dependencyKind:"re_export",line:i?.start?.line??1});}}return t}var tn=createRequire(import.meta.url);var Re=class{name="Vue2Parser";canParse(e,t){return e.endsWith(".vue")}parse(e,t){let n={framework:"vue2",filePath:e,symbols:[],relations:[],behaviors:[],errors:[]};try{let r=tn("vue-template-compiler").parseComponent(t);if(!r.script?.content)return n;let i=r.script.content,a=this.getScriptStartLine(t,r.script.start),c=t.split(`
383
+ `),l;try{l=tn("@babel/parser").parse(i,{sourceType:"module",plugins:["jsx","typescript","decorators-legacy"],errorRecovery:!0});}catch(u){return n.errors?.push(`AST \u89E3\u6790\u5931\u8D25: ${String(u)}`),n}if(this.extractFromAST(l.program,i,c,a,n),r.template?.content){let u=this.getScriptStartLine(t,r.template.start),p=Ye(r.template.content,u);if(p.length>0){let d=r.template.content.split(`
384
+ `).length;n.symbols.push({name:"<template>",category:"lifecycle",framework:"vue2",startLine:u,endLine:u+d-1,camelWords:"template"});for(let h of p)n.relations.push(X({callerName:"<template>",callerLine:u,calleeName:h.calleeName,callType:"template_event",line:h.line}));}}}catch(s){n.errors?.push(`\u89E3\u6790\u5931\u8D25: ${String(s)}`);}return n}getScriptStartLine(e,t){let n=1;for(let s=0;s<t&&s<e.length;s++)e[s]===`
385
+ `&&n++;return n}extractFromAST(e,t,n,s,r){let i=t.split(`
386
+ `);r.fileDependencies=Te(e.body||[],r.filePath);let a=null;z(e,p=>{if(p.type==="ExportDefaultDeclaration"){let d=p.declaration;if(d?.type==="ObjectExpression")a=d;else if(d?.type==="CallExpression"){let h=d.arguments;h&&h.length>0&&h[0].type==="ObjectExpression"&&(a=h[0]);}else if(d?.type==="Identifier"){let h=d.name;z(e,f=>{if(f.type==="VariableDeclarator"&&f.id?.name===h){if(f.init?.type==="ObjectExpression")a=f.init;else if(f.init?.type==="CallExpression"){let m=f.init.arguments;m&&m.length>0&&m[0].type==="ObjectExpression"&&(a=m[0]);}}});}}});let l=false;if(!a&&(z(e,p=>{p.type==="ExportDefaultDeclaration"&&p.declaration?.type==="ClassDeclaration"&&(l=true,this.extractFromClassComponent(p.declaration,t,n,s,r));}),!l)){let p=null,d=0,h=["data","methods","computed","props","watch","components","created","mounted","mixins"];z(e,f=>{if(f.type==="ObjectExpression"){let m=f.properties||[],b=0;for(let g of m){let E=this.getPropKey(g);E&&h.includes(E)&&b++;}b>d&&(d=b,p=f);}}),d>=2&&p&&(a=p);}if(!a)return;let u=a.properties;for(let p of u||[]){let d=this.getPropKey(p);if(!d)continue;let h=p.type==="ObjectMethod"?p:p.value;if(!h)continue;let f=m=>m+s-1;switch(d){case "name":h?.type==="Literal"&&(String(h.value));break;case "data":this.extractData(h,i,f,r);break;case "props":this.extractProps(h,i,f,r);break;case "computed":this.extractComputedOrMethods(h,"computed",i,f,n,r);break;case "methods":this.extractComputedOrMethods(h,"method",i,f,n,r);break;case "watch":this.extractWatch(h,i,f,r);break;case "filters":this.extractComputedOrMethods(h,"filter",i,f,n,r);break;case "components":this.extractComponents(h,r);break;case "mixins":this.extractMixins(h,r);break;default:if(ht.includes(d)){let m=f(this.getStartLine(p)),b=f(this.getEndLine(p)),g=Q(n.join(`
387
+ `),m),E=r.symbols.length;r.symbols.push({name:d,category:"lifecycle",framework:"vue2",startLine:m,endLine:b,jsdoc:g,camelWords:w(d)});let y=Y(h,d);r.behaviors.push(...y);let N=Je(h,d);for(let T of N){if(T.args){let R=String(T.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");r.symbols[E].camelWords+=` ${w(R)} ${R}`;}r.relations.push(X({callerName:d,callerLine:m,calleeName:T.calleeName,callType:"this_method",line:f(T.line),args:T.args}));}}break}}}extractData(e,t,n,s){let r=null;if(e.type==="FunctionExpression"||e.type==="ArrowFunctionExpression"||e.type==="ObjectMethod"?z(e.body,i=>{i.type==="ReturnStatement"&&i.argument?.type==="ObjectExpression"&&(r=i.argument);}):e.type==="ObjectExpression"&&(r=e),!!r)for(let i of r.properties){let a=this.getPropKey(i);if(!a)continue;let c=n(this.getStartLine(i)),l=n(this.getEndLine(i)),u=this.getLiteralValue(i.value);s.symbols.push({name:a,category:"state",framework:"vue2",startLine:c,endLine:l,defaultValue:u,camelWords:w(a)});}}extractProps(e,t,n,s){if(e.type==="ArrayExpression"){for(let r of e.elements||[])if(r?.type==="Literal"){let i=String(r.value);s.symbols.push({name:i,category:"prop",framework:"vue2",startLine:n(this.getStartLine(r)),endLine:n(this.getEndLine(r)),camelWords:w(i)});}}else if(e.type==="ObjectExpression")for(let r of e.properties||[]){let i=this.getPropKey(r);if(!i)continue;let a=n(this.getStartLine(r)),c=n(this.getEndLine(r)),l;if(r.value?.type==="ObjectExpression"){let u=r.value.properties?.find(p=>this.getPropKey(p)==="default");u&&(l=this.getLiteralValue(u.value));}s.symbols.push({name:i,category:"prop",framework:"vue2",startLine:a,endLine:c,defaultValue:l,camelWords:w(i)});}}extractComputedOrMethods(e,t,n,s,r,i){if(e.type==="ObjectExpression")for(let a of e.properties||[]){let c=this.getPropKey(a);if(!c)continue;let l=a.type==="ObjectMethod"?a:a.value;if(!l)continue;let u=s(this.getStartLine(a)),p=s(this.getEndLine(a)),d=Q(r.join(`
388
+ `),u),h=this.extractParams(l),f=l.async===true,m=h?`${c}(${h.join(", ")})`:c;if(i.symbols.push({name:c,category:t,framework:"vue2",startLine:u,endLine:p,signature:m,params:h,isAsync:f,jsdoc:d,camelWords:w(c)}),t==="method"&&l){let b=Y(l,c);i.behaviors.push(...b);let g=Je(l,c);for(let E of g){if(E.args){let y=String(E.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");i.symbols[i.symbols.length-1].camelWords+=` ${w(y)} ${y}`;}i.relations.push(X({callerName:c,callerLine:u,calleeName:E.calleeName,callType:"this_method",line:s(E.line),args:E.args}));}}}}extractWatch(e,t,n,s){if(e.type==="ObjectExpression")for(let r of e.properties||[]){let i=this.getPropKey(r);if(!i)continue;let a=n(this.getStartLine(r)),c=n(this.getEndLine(r));s.symbols.push({name:i,category:"effect",framework:"vue2",startLine:a,endLine:c,camelWords:w(i)});}}extractComponents(e,t){if(e.type==="ObjectExpression")for(let n of e.properties||[]){let s=this.getPropKey(n);s&&t.symbols.push({name:s,category:"component",framework:"vue2",startLine:this.getStartLine(n),endLine:this.getEndLine(n),camelWords:w(s)});}}extractMixins(e,t){if(e.type==="ArrayExpression")for(let n of e.elements||[]){let s=n?.type==="Identifier"?n.name:null;s&&t.symbols.push({name:s,category:"mixin",framework:"vue2",startLine:this.getStartLine(n),endLine:this.getEndLine(n),camelWords:w(s)});}}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(n=>n.type==="Identifier"?n.name:n.type==="AssignmentPattern"?n.left?.name||"?":n.type==="RestElement"?`...${n.argument?.name||""}`:n.type==="TSParameterProperty"&&n.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,n,s,r){let i=c=>c+s-1,a=e.body;if(!(!a||a.type!=="ClassBody"))for(let c of a.body||[]){let l=this.getPropKey(c);if(!l)continue;let u=i(this.getStartLine(c)),p=i(this.getEndLine(c)),d=Q(n.join(`
389
+ `),u);if(c.type==="ClassMethod"){let f=ht.includes(l)?"lifecycle":"method",m=this.extractParams(c),b=c.async===true,g=m?`${l}(${m.join(", ")})`:l;r.symbols.push({name:l,category:f,framework:"vue2",startLine:u,endLine:p,signature:g,params:m,isAsync:b,jsdoc:d,camelWords:w(l)});let E=Y(c,l);r.behaviors.push(...E);let y=Je(c,l);for(let N of y){if(N.args){let T=String(N.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");r.symbols[r.symbols.length-1].camelWords+=` ${w(T)} ${T}`;}r.relations.push(X({callerName:l,callerLine:u,calleeName:N.calleeName,callType:"this_method",line:i(N.line),args:N.args}));}}else if(c.type==="ClassProperty"){let h=(c.decorators||[]).some(m=>m.expression?.callee?.name==="Prop"),f=this.getLiteralValue(c.value);r.symbols.push({name:l,category:h?"prop":"state",framework:"vue2",startLine:u,endLine:p,defaultValue:f,camelWords:w(l)});}}}};var _t=createRequire(import.meta.url),et=class{name="Vue3Parser";canParse(e,t){return e.endsWith(".vue")?this.looksLikeVue3File(t):false}parse(e,t){let n={framework:"vue3",filePath:e,symbols:[],relations:[],behaviors:[],errors:[]};try{let{parse:s}=_t("@vue/compiler-sfc"),{descriptor:r}=s(t),i=t.split(`
390
+ `),a=!!r.scriptSetup,c=!!r.script;if(a){let l=r.scriptSetup,u=l.loc.start.line;this.parseSetupContent(l.content,u,i,n);}else if(c){let l=r.script,u=l.loc.start.line;this.parseScriptContent(l.content,u,i,n)||this.populateFromOptionsApiFallback(e,t,n);}if(r.template?.content){let l=r.template.loc.start.line,u=Ye(r.template.content,l);if(u.length>0){let p=r.template.content.split(`
391
+ `).length;n.symbols.push({name:"<template>",category:"lifecycle",framework:"vue3",startLine:l,endLine:l+p-1,camelWords:"template"});for(let d of u)n.relations.push(X({callerName:"<template>",callerLine:l,calleeName:d.calleeName,callType:"template_event",line:d.line}));}}}catch(s){n.errors?.push(`Vue3 \u89E3\u6790\u5931\u8D25: ${String(s)}`);}return n}parseSetupContent(e,t,n,s){let r;try{r=_t("@babel/parser").parse(e,{sourceType:"module",plugins:["typescript","jsx","decorators-legacy"],errorRecovery:!0});}catch(l){s.errors?.push(`AST \u89E3\u6790\u5931\u8D25: ${String(l)}`);return}let i=l=>l+t-1,a=e.split(`
392
+ `),c=r.program.body;s.fileDependencies=Te(c,s.filePath);for(let l of c||[])this.processTopLevelStatement(l,i,n,a,s);}parseScriptContent(e,t,n,s){let r;try{r=_t("@babel/parser").parse(e,{sourceType:"module",plugins:["typescript","jsx","decorators-legacy"],errorRecovery:!0});}catch(l){return s.errors?.push(`AST \u89E3\u6790\u5931\u8D25: ${String(l)}`),false}let i=l=>l+t-1,a=e.split(`
393
+ `);s.fileDependencies=Te(r.program.body||[],s.filePath);let c=false;return z(r.program,l=>{if(l.type==="ExportDefaultDeclaration"&&l.declaration?.type==="ObjectExpression"){let u=l.declaration.properties?.find(p=>this.getPropKey(p)==="setup");if(u){c=true;let p=u.type==="ObjectMethod"?u:u.value;if(!p)return;let d=p.body;if(d?.type==="BlockStatement"){let h=d.body;for(let f of h||[])this.processTopLevelStatement(f,i,n,a,s);}}}}),c||z(r.program,l=>{if(!c&&l.type==="ObjectExpression"){let p=(l.properties||[]).find(d=>this.getPropKey(d)==="setup");if(p){c=true;let d=p.type==="ObjectMethod"?p:p.value;if(!d)return;let h=d.body;if(h?.type==="BlockStatement"){let f=h.body;for(let m of f||[])this.processTopLevelStatement(m,i,n,a,s);}}}}),c}processTopLevelStatement(e,t,n,s,r){let i=a=>{let c=a?.loc;return {start:c?.start?.line??1,end:c?.end?.line??1}};if(e.type==="VariableDeclaration")for(let a of e.declarations||[]){if(a.id?.type!=="Identifier"&&a.id?.type!=="ArrayPattern")continue;let c=a.init;if(c&&a.id.type==="Identifier"){let l=a.id.name;if(c.type==="ArrowFunctionExpression"||c.type==="FunctionExpression"){let{start:u,end:p}=i(e),d=Q(n.join(`
394
+ `),t(u)),h=this.extractParams(c),f=r.symbols.length;if(r.symbols.push({name:l,category:"method",framework:"vue3",startLine:t(u),endLine:t(p),signature:`${l}(${(h||[]).join(", ")})`,params:h,isAsync:c.async===true,jsdoc:d,camelWords:w(l)}),c.body){let m=Y(c.body,l);r.behaviors.push(...m);let b=de(c.body,l);for(let g of b){if(g.args){let E=String(g.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");r.symbols[f].camelWords+=` ${w(E)} ${E}`;}r.relations.push(X({callerName:l,callerLine:t(u),calleeName:g.calleeName,callType:"direct_call",line:t(g.line),args:g.args}));}}}else {let u=this.classifyVue3Declaration(l,c,t,i(e),n);u&&r.symbols.push(u);}}}if(e.type==="FunctionDeclaration"&&e.id?.type==="Identifier"){let a=e.id.name,{start:c,end:l}=i(e),u=Q(n.join(`
395
+ `),t(c)),p=this.extractParams(e),d=gt.includes(a);if(r.symbols.push({name:a,category:d?"lifecycle":ye(a)?"hook":"method",framework:"vue3",startLine:t(c),endLine:t(l),signature:`${a}(${(p||[]).join(", ")})`,params:p,isAsync:e.async===true,jsdoc:u,camelWords:w(a)}),e.body){let h=Y(e.body,a);r.behaviors.push(...h);let f=de(e.body,a);for(let m of f){if(m.args){let b=String(m.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");r.symbols[r.symbols.length-1].camelWords+=` ${w(b)} ${b}`;}r.relations.push(X({callerName:a,callerLine:t(c),calleeName:m.calleeName,callType:"direct_call",line:t(m.line),args:m.args}));}}}if(e.type==="ExpressionStatement"&&e.expression?.type==="CallExpression"){let c=e.expression.callee;if(c?.type==="Identifier"){let l=c.name;if(["defineProps","defineEmits","defineExpose"].includes(l)){let{start:u,end:p}=i(e);r.symbols.push({name:l,category:l==="defineProps"?"prop":l==="defineEmits"?"emit":"export",framework:"vue3",startLine:t(u),endLine:t(p),camelWords:w(l)});}}}if(e.type==="ExpressionStatement"&&e.expression?.type==="CallExpression"){let a=e.expression,c=a.callee;if(c?.type==="Identifier"){let l=c.name;if(gt.includes(l)){let{start:u,end:p}=i(e);r.symbols.push({name:l,category:"lifecycle",framework:"vue3",startLine:t(u),endLine:t(p),camelWords:w(l)});let d=a.arguments;if(d?.[0]){let h=Y(d[0],l);r.behaviors.push(...h);let f=de(d[0],l);for(let m of f){if(m.args){let b=String(m.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");r.symbols[r.symbols.length-1].camelWords+=` ${w(b)} ${b}`;}r.relations.push(X({callerName:l,callerLine:t(u),calleeName:m.calleeName,callType:"direct_call",line:t(m.line),args:m.args}));}}}}}}classifyVue3Declaration(e,t,n,s,r){if(t.type!=="CallExpression")return null;let i=t.callee;if(i?.type!=="Identifier")return null;let a=i.name,c=n(s.start),l=n(s.end),u=Q(r.join(`
396
+ `),c);if(Ht.includes(a)){let p=t.arguments,d=p?.[0]?this.getLiteralValue(p[0]):void 0;return {name:e,category:"state",framework:"vue3",startLine:c,endLine:l,defaultValue:d,jsdoc:u,camelWords:w(e)}}return Bt.includes(a)?{name:e,category:"computed",framework:"vue3",startLine:c,endLine:l,jsdoc:u,camelWords:w(e)}:Xt.includes(a)?{name:e,category:"effect",framework:"vue3",startLine:c,endLine:l,camelWords:w(e)}:a==="provide"||a==="inject"?{name:e,category:"provide",framework:"vue3",startLine:c,endLine:l,camelWords:w(e)}:ye(a)?{name:e,category:"hook",framework:"vue3",startLine:c,endLine:l,jsdoc:u,camelWords:w(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(n=>n.type==="Identifier"?n.name:n.type==="AssignmentPattern"?n.left?.name||"?":n.type==="RestElement"?`...${n.argument?.name||""}`:n.type==="ObjectPattern"?"{...}":n.type==="TSParameterProperty"&&n.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 "[]"}}looksLikeVue3File(e){return e.includes("<script setup")?true:/\bdefine(?:Props|Emits|Expose|Slots|Model)\s*\(/.test(e)||/\bwithDefaults\s*\(/.test(e)||/\bdefineComponent\s*\(/.test(e)||/\bsetup\s*\(/.test(e)||/\b(?:ref|reactive|shallowRef|shallowReactive|readonly|computed|watch|watchEffect|watchPostEffect|watchSyncEffect|provide|inject|nextTick|onBeforeMount|onMounted|onBeforeUpdate|onUpdated|onBeforeUnmount|onUnmounted|onActivated|onDeactivated|onErrorCaptured|onRenderTracked|onRenderTriggered|onServerPrefetch)\s*\(/.test(e)}populateFromOptionsApiFallback(e,t,n){let s=new Re().parse(e,t);n.symbols=s.symbols.map(r=>({...r,framework:"vue3"})),n.relations=s.relations,n.behaviors=s.behaviors,n.errors=[...n.errors||[],...s.errors||[]];}};var ls=createRequire(import.meta.url),ps=[...yt,...bt,...Et,...Kt],Pe=class{name="ReactParser";canParse(e,t){let n=e.split(".").pop()?.toLowerCase();return ["jsx","tsx","js","ts"].includes(n||"")?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 n={framework:"react",filePath:e,symbols:[],relations:[],behaviors:[],errors:[]};try{let r=ls("@babel/parser").parse(t,{sourceType:"module",plugins:["jsx","typescript","decorators-legacy"],errorRecovery:!0}),i=t.split(`
397
+ `);this.extractFromAST(r.program?r.program:r,i,n);}catch(s){n.errors?.push(`React \u89E3\u6790\u5931\u8D25: ${String(s)}`);}return n}extractFromAST(e,t,n){let s=e.body;n.fileDependencies=Te(s,n.filePath);for(let r of s||[]){if(r.type==="FunctionDeclaration"||r.type==="ExportDefaultDeclaration"&&r.declaration?.type==="FunctionDeclaration"||r.type==="ExportNamedDeclaration"&&r.declaration?.type==="FunctionDeclaration"){let i=r.type==="FunctionDeclaration"?r:r.declaration;i&&i.id?.type==="Identifier"&&this.processFunction(i,t,n);}if(r.type==="VariableDeclaration"||r.type==="ExportNamedDeclaration"&&r.declaration?.type==="VariableDeclaration"||r.type==="ExportDefaultDeclaration"&&r.declaration?.type==="VariableDeclaration"){let i=r.type==="VariableDeclaration"?r:r.declaration;if(i)for(let a of i.declarations||[]){let c=a.init;if(c&&(c.type==="ArrowFunctionExpression"||c.type==="FunctionExpression")&&a.id?.type==="Identifier"){let l={...c,id:a.id,loc:{start:i.loc?.start??c.loc?.start,end:c.loc?.end}};this.processFunction(l,t,n);}}}}}processFunction(e,t,n){let s=e.id?.name;if(!s)return;let r=e.loc,i=r?.start?.line??1,a=r?.end?.line??1,c=ye(s),l=!c&&/^[A-Z]/.test(s),u=Q(t.join(`
398
+ `),i),p=this.extractParams(e),d=this.buildSymbolKey(s,i,a);n.symbols.push({name:s,category:c?"hook":l?"component":"function",framework:"react",startLine:i,endLine:a,internalKey:d,signature:`${s}(${(p||[]).join(", ")})`,params:p,isAsync:e.async===true,jsdoc:u,parentComponent:l?s:void 0,camelWords:w(s)});let h=e.body;if(h?.type!=="BlockStatement")return;let f=h.body;for(let E of f||[])this.processComponentStatement(E,s,t,n);let m=Y(h,s,t,true);n.behaviors.push(...m);let b=de(h,s,t,true);for(let E of b){let y=n.symbols.findIndex(N=>N.name===s&&N.startLine===i);if(E.args&&y!==-1){let N=String(E.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");n.symbols[y].camelWords+=` ${w(N)} ${N}`;}n.relations.push(X({callerName:s,callerLine:i,callerKey:d,calleeName:E.calleeName,callType:"direct_call",line:E.line,args:E.args}));}let g=Zt(h);for(let E of g)n.relations.push(X({callerName:s,callerLine:i,callerKey:d,calleeName:E.calleeName,callType:"jsx_event",line:E.line}));}processComponentStatement(e,t,n,s){let r=i=>{let a=i?.loc;return {start:a?.start?.line??1,end:a?.end?.line??1}};if(e.type==="VariableDeclaration")for(let i of e.declarations||[]){let a=i.init;if(!a||a.type!=="CallExpression")continue;let c=a.callee;if(c?.type!=="Identifier")continue;let l=c.name,{start:u,end:p}=r(e),d=u,h=p;if(yt.includes(l)&&l!=="useRef"){if(i.id?.type==="ArrayPattern"){let f=i.id.elements,m=f[0]?.name,b=f[1]?.name;if(m){let g=a.arguments;s.symbols.push({name:m,category:"state",framework:"react",startLine:d,endLine:h,internalKey:this.buildSymbolKey(m,d,h,t),stateSetterName:b,defaultValue:this.getLiteralValue(g?.[0]),parentComponent:t,camelWords:w(m)});}}else if(i.id?.type==="Identifier"){let f=i.id.name;s.symbols.push({name:f,category:"state",framework:"react",startLine:d,endLine:h,internalKey:this.buildSymbolKey(f,d,h,t),parentComponent:t,camelWords:w(f)});}}if(l==="useRef"&&i.id?.type==="Identifier"){let f=i.id.name,m=a.arguments;s.symbols.push({name:f,category:"state",framework:"react",startLine:d,endLine:h,internalKey:this.buildSymbolKey(f,d,h,t),defaultValue:this.getLiteralValue(m?.[0]),parentComponent:t,camelWords:w(f)});}if(bt.includes(l)&&i.id?.type==="Identifier"){let f=i.id.name,b=a.arguments?.[1],g=this.extractDepsArray(b);s.symbols.push({name:f,category:"computed",framework:"react",startLine:d,endLine:h,internalKey:this.buildSymbolKey(f,d,h,t),hookDeps:g,parentComponent:t,camelWords:w(f)});}if(ye(l)&&!ps.includes(l)){let f=i.id?.type==="Identifier"?i.id.name:i.id?.type==="ObjectPattern"?"{...}":"?";s.symbols.push({name:f,category:"hook",framework:"react",startLine:d,endLine:h,internalKey:this.buildSymbolKey(f,d,h,t),parentComponent:t,camelWords:w(f)});}}if(e.type==="ExpressionStatement"&&e.expression?.type==="CallExpression"){let i=e.expression,a=i.callee;if(a?.type==="Identifier"){let c=a.name;if(Et.includes(c)){let{start:l,end:u}=r(e),p=i.arguments,d=p?.[1],h=this.extractDepsArray(d),f=this.buildSymbolKey(c,l,u,t),m=`${t}.${c}`;if(s.symbols.push({name:c,category:"effect",framework:"react",startLine:l,endLine:u,internalKey:f,hookDeps:h,parentComponent:t,camelWords:w(c)}),p?.[0]){let b=Y(p[0],m,n,true).map(E=>({...E,symbolKey:f}));s.behaviors.push(...b);let g=de(p[0],m,n,true);for(let E of g){let y=s.symbols.findIndex(N=>N.name===c&&N.startLine===l);if(E.args&&y!==-1){let N=String(E.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");s.symbols[y].camelWords+=` ${w(N)} ${N}`;}s.relations.push(X({callerName:m,callerLine:l,callerKey:f,calleeName:E.calleeName,callType:"direct_call",line:E.line,args:E.args}));}}}}}if(e.type==="FunctionDeclaration"&&e.id?.type==="Identifier"){let i=e.id.name;if(!ye(i)){let{start:a,end:c}=r(e),l=Q(n.join(`
399
+ `),a),u=this.extractParams(e);if(s.symbols.push({name:i,category:"method",framework:"react",startLine:a,endLine:c,internalKey:this.buildSymbolKey(i,a,c,t),signature:`${i}(${(u||[]).join(", ")})`,params:u,isAsync:e.async===true,jsdoc:l,parentComponent:t,camelWords:w(i)}),e.body){let p=Y(e.body,i,n,true);s.behaviors.push(...p);let d=de(e.body,i,n,true);for(let h of d){let f=s.symbols.findIndex(m=>m.name===i&&m.startLine===a);if(h.args&&f!==-1){let m=String(h.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");s.symbols[f].camelWords+=` ${w(m)} ${m}`;}s.relations.push(X({callerName:i,callerLine:a,callerKey:this.buildSymbolKey(i,a,c,t),calleeName:h.calleeName,callType:"direct_call",line:h.line,args:h.args}));}}}}if(e.type==="VariableDeclaration")for(let i of e.declarations||[]){let a=i.init;if(!a)continue;let c=a.type==="ArrowFunctionExpression"||a.type==="FunctionExpression";if(!c||i.id?.type!=="Identifier")continue;let l=i.id.name,u=a.type==="CallExpression"?a.callee:null;if(u?.type==="Identifier"&&ye(u.name))continue;if(a.type==="CallExpression"&&a.callee?.name==="useCallback"){let g=a.arguments?.[1],E=this.extractDepsArray(g),{start:y,end:N}=r(e);s.symbols.push({name:l,category:"computed",framework:"react",startLine:y,endLine:N,internalKey:this.buildSymbolKey(l,y,N,t),hookDeps:E,parentComponent:t,camelWords:w(l)});continue}if(!c)continue;let{start:d,end:h}=r(e),f=Q(n.join(`
400
+ `),d),m=this.extractParams(a);if(s.symbols.push({name:l,category:"method",framework:"react",startLine:d,endLine:h,internalKey:this.buildSymbolKey(l,d,h,t),signature:`${l}(${(m||[]).join(", ")})`,params:m,isAsync:a.async===true,jsdoc:f,parentComponent:t,camelWords:w(l)}),a.body){let b=Y(a.body,l,n,true);s.behaviors.push(...b);let g=de(a.body,l,n,true);for(let E of g){let y=s.symbols.findIndex(N=>N.name===l&&N.startLine===d);if(E.args&&y!==-1){let N=String(E.args).replace(/[^a-zA-Z0-9_\u4e00-\u9fa5]/g," ");s.symbols[y].camelWords+=` ${w(N)} ${N}`;}s.relations.push(X({callerName:l,callerLine:d,callerKey:this.buildSymbolKey(l,d,h,t),calleeName:E.calleeName,callType:"direct_call",line:E.line,args:E.args}));}}}}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(n=>n.type==="Identifier"?n.name:n.type==="ObjectPattern"?"{...}":n.type==="ArrayPattern"?"[...]":n.type==="AssignmentPattern"?n.left?.name||"?":n.type==="RestElement"?`...${n.argument?.name||""}`:n.type==="TSParameterProperty"&&n.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"}}buildSymbolKey(e,t,n,s){return `${s||"root"}:${e}:${t}:${n}`}};function q(o){let e=o.property;return e?e.type==="Identifier"?String(e.name||""):e.type==="Literal"||e.type==="StringLiteral"?String(e.value||""):null:null}function re(o){let e=o.object;return e?e.type==="Identifier"?String(e.name||""):e.type==="ThisExpression"?q(o):e.type==="MemberExpression"?e.object?.type==="ThisExpression"?q(e):re(e):null:null}function ee(o,e){let t=o||"";return /created|mounted|beforeMount|setup\s*\(|\bdata\s*\(/.test(t)?"init":/getItem|localStorage|sessionStorage|\bfetch\b|\bload[A-Z]|\bget[A-Z]/.test(t)?"cache":/@click|@change|@input|onClick|onChange|handle[A-Z]|\bwatch\b/.test(t)?"user":e<=30?"init":"unknown"}var ds=new Set(["FunctionDeclaration","ArrowFunctionExpression","FunctionExpression","ObjectMethod","ClassMethod","ClassProperty"]);function nn(o,e){return !!e?.skipNestedFunctions&&ds.has(String(o.type||""))}function fe(o,e,t){if(!(!o||typeof o!="object")){e(o);for(let n of Object.keys(o)){if(n==="type"||n==="loc"||n==="start"||n==="end")continue;let s=o[n];if(Array.isArray(s)){for(let r of s){if(!r||typeof r!="object"||!r.type)continue;let i=r;nn(i,t)||fe(i,e,t);}continue}if(s&&typeof s=="object"&&s.type){let r=s;if(nn(r,t))continue;fe(r,e,t);}}}}function sn(o,e,t=true,n){let s=[],r=[],i=(a,c=120)=>us(a,n,c);return fe(o,a=>{if(a.type==="VariableDeclarator"){let c=a.id;if(!c)return;let l=tt(c),u=i(a);for(let p of l)s.push({symbolName:p,kind:"declaration",line:ke(a),text:u,sourceLayer:ee(u,ke(a))});}if(a.type==="AssignmentExpression"){let c=a.left;if(!c)return;let l=i(a),u=ke(a);if(c.type==="Identifier"&&s.push({symbolName:c.name,kind:"assignment",line:u,text:l,sourceLayer:ee(l,u)}),c.type==="MemberExpression"&&c.object?.type==="ThisExpression"){let d=q(c);if(d){s.push({symbolName:d,kind:"assignment",line:u,text:l,sourceLayer:ee(l,u)});return}}if(c.type==="MemberExpression"){let p=re(c);if(p&&Nt(p)){let d=q(c);r.push({objectName:p,propertyName:d||void 0,line:u,text:l,kind:c.computed?"bracket":"dot",sourceLayer:ee(l,u)});}}}if(a.type==="UpdateExpression"){let c=a.argument;if(!c)return;let l=i(a),u=ke(a);if(c.type==="Identifier"&&s.push({symbolName:c.name,kind:"update",line:u,text:l,sourceLayer:ee(l,u)}),c.type==="MemberExpression"&&c.object?.type==="ThisExpression"){let d=q(c);if(d){s.push({symbolName:d,kind:"update",line:u,text:l,sourceLayer:ee(l,u)});return}}if(c.type==="MemberExpression"){let p=re(c);if(p&&Nt(p)){let d=q(c);r.push({objectName:p,propertyName:d||void 0,line:u,text:l,kind:c.computed?"bracket":"dot",sourceLayer:ee(l,u)});}}}if(a.type==="UnaryExpression"&&a.operator==="delete"){let c=a.argument;if(c?.type==="MemberExpression"){let l=re(c);if(l&&Nt(l)){let u=q(c);r.push({objectName:l,propertyName:u||void 0,line:ke(a),text:i(a),kind:"delete",sourceLayer:ee(i(a),ke(a))});}}}},{skipNestedFunctions:t}),{assignments:s,propertyWrites:r}}function tt(o){return o.type==="Identifier"?[o.name]:o.type==="ObjectPattern"?(o.properties||[]).flatMap(t=>{let n=t.type==="ObjectProperty"||t.type==="Property"?t.value:t;return n?tt(n):[]}):o.type==="ArrayPattern"?(o.elements||[]).flatMap(t=>t?tt(t):[]):o.type==="AssignmentPattern"?tt(o.left):[]}function Nt(o){return !(/^[A-Z][A-Z]/.test(o)||/^(document|window|console|localStorage|sessionStorage|navigator|process|global|globalThis)$/.test(o))}function ke(o){return o.loc?.start?.line??1}function us(o,e,t=120){if(e){let s=o.loc;if(s?.start?.line&&s?.end?.line){let r=s.start.line-1,i=Math.min(s.end.line-1,r+5);return e.slice(r,i+1).map(c=>c.trim()).filter(c=>c).join(" ").slice(0,t)}}let n=o.loc;return n?.start?.line?`L${n.start.line}`:String(o.type||"?")}function Tt(o,e){let t={files:new Map,resolutionCache:new Map};for(let{path:n,content:s}of o){let r=en(n,s);t.files.set(n,r);let i=new Map;for(let a of r.imports)a.localName&&i.set(a.localName,`${a.resolvedFile}::${a.originalName}`);t.resolutionCache.set(n,i);}return t}function St(o,e,t,n){if(t.files.size===0)return o;let s=t.resolutionCache.get(e);return !s||s.size===0||!t.files.get(e)?o:o.map(a=>{let c=s.get(a.calleeName);return c?{...a,edgeKind:"precise",importSource:a.importSource||c}:a})}var rn=createRequire(import.meta.url);function on(o,e){let t=o.errors||[];t.includes(e)||(o.errors=[...t,e]);}var xt=class extends Pe{name="JsTsFallbackParser";canParse(e){let t=e.split(".").pop()?.toLowerCase();return ["js","ts","jsx","tsx"].includes(t||"")}parse(e,t){let n=super.parse(e,t);return n.framework=e.endsWith(".ts")||e.endsWith(".tsx")?"ts":"js",n}},ms=[new et,new Re,new Pe,new xt];function Me(o,e){for(let t of ms)if(t.canParse(o,e)){let n=t.parse(o,e);return gs(n),hs(n,e),n}return {framework:"js",filePath:o,symbols:[],relations:[],behaviors:[],errors:[`\u6CA1\u6709\u627E\u5230\u9002\u5408\u7684\u89E3\u6790\u5668: ${o}`]}}function hs(o,e){if(o.symbols.length!==0)try{let t=e,n=o.filePath.endsWith(".vue"),s=0;if(n)try{let{parse:d}=rn("@vue/compiler-sfc"),{descriptor:h}=d(e);if(h.scriptSetup?.content)t=h.scriptSetup.content,s=h.scriptSetup.loc.start.line-1;else if(h.script?.content)t=h.script.content,s=h.script.loc.start.line-1;else return}catch(d){on(o,`\u751F\u547D\u5468\u671F\u63D0\u53D6\u8DF3\u8FC7: Vue SFC \u89E3\u6790\u5931\u8D25 - ${String(d)}`);return}let a=rn("@babel/parser").parse(t,{sourceType:"module",plugins:["jsx","typescript","decorators-legacy"],errorRecovery:!0}).program.body;if(!a?.length)return;let c=t.split(`
401
+ `),{assignments:l,propertyWrites:u}=sn({type:"Program",body:a},o.filePath,!1,c);if(s>0){for(let d of l)d.line+=s;for(let d of u)d.line+=s;}let p=new Set(o.symbols.map(d=>d.name));o.assignments=l.filter(d=>p.has(d.symbolName)),o.propertyWrites=u.filter(d=>p.has(d.objectName));}catch(t){on(o,`\u751F\u547D\u5468\u671F\u63D0\u53D6\u8DF3\u8FC7: AST \u89E3\u6790\u5931\u8D25 - ${String(t)}`);}}function gs(o){if(!o.relations.length||!o.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(o.behaviors.filter(s=>s.category==="network").map(s=>s.symbolName));if(t.size===0)return;let n=new Set(o.behaviors.map(s=>`${s.symbolName}:${s.category}:${s.apiName}:${s.operation}:${s.line}`));for(let s of o.relations){if(!t.has(s.calleeName)||t.has(s.callerName)||e.has(s.callerName))continue;let r={symbolName:s.callerName,symbolKey:s.callerKey,category:"network",apiName:"wrapped_network",operation:s.calleeName,detail:s.args,line:s.line},i=`${r.symbolName}:${r.category}:${r.apiName}:${r.operation}:${r.line}`;n.has(i)||(n.add(i),o.behaviors.push(r));}}function Fe(o,e){let t=ys(e),n=[];for(let a of o.symbols)if(a.isExported){let c=a.signature||"";n.push(`${a.name}:${c}`);}n.sort();let s=n.length>0?an(n.join(`
402
+ `)):"",r=[];if(o.fileDependencies&&o.fileDependencies.length>0)for(let a of o.fileDependencies)a.dependencyKind==="import"&&r.push(a.toFile);r.sort();let i=r.length>0?an(r.join(`
403
+ `)):"";return {contentHash:t,exportSignatureHash:s,importSignatureHash:i}}function ln(o,e){if(!o)return "full_changed";if(o.contentHash===e.contentHash)return "unchanged";let t=o.exportSignatureHash!==e.exportSignatureHash,n=o.importSignatureHash!==e.importSignatureHash;return t&&n?"full_changed":t?"export_changed":n?"import_changed":"body_only"}function pn(o,e,t){if(e==="unchanged")return [];if(e==="body_only")return [o];if(e==="import_changed")return [o];let n=new Set([o]),s=[o];for(;s.length>0;){let r=s.shift(),i=t.get(r)||[];for(let a of i)n.has(a)||n.add(a);}return Array.from(n)}function ys(o){return createHash("sha256").update(o,"utf-8").digest("hex").slice(0,16)}function an(o){return createHash("sha256").update(o,"utf-8").digest("hex").slice(0,12)}var bs={maxFiles:20,maxTimeMs:1500},nt=class{pending=[];options;constructor(e){this.options={...bs,...e};}configure(e){this.options={...this.options,...e};}enqueue(e,t){let n=this.pending.find(s=>s.relPath===e);if(n){let s={high:3,normal:2,low:1};s[t]>s[n.priority]&&(n.priority=t);return}this.pending.push({relPath:e,priority:t,addedAt:Date.now()});}dequeueBatch(){if(this.pending.length===0)return {tasks:[],exceededBudget:false,remainingPending:0};let e={high:0,normal:1,low:2};this.pending.sort((r,i)=>{let a=e[r.priority],c=e[i.priority];return a!==c?a-c:r.addedAt-i.addedAt});let t=[],n=this.pending.length>this.options.maxFiles;for(let r=0;r<Math.min(this.options.maxFiles,this.pending.length);r++)t.push(this.pending[r]);let s=new Set(t.map(r=>r.relPath));return this.pending=this.pending.filter(r=>!s.has(r.relPath)),{tasks:t,exceededBudget:n,remainingPending:this.pending.length}}requeue(e){if(e.length===0)return;let t=new Set(this.pending.map(s=>s.relPath)),n=e.filter(s=>!t.has(s.relPath));this.pending=[...n,...this.pending];}clear(){this.pending=[];}get pendingCount(){return this.pending.length}get budget(){return this.options}summary(){return this.pending.map(e=>({relPath:e.relPath,priority:e.priority}))}};var st=class{projectRoot;db;scheduler;constructor(e,t){this.projectRoot=e,this.db=t,this.scheduler=new nt;}getScheduler(){return this.scheduler}enhancePreciseRelations(e){try{let t=e.filter(({absPath:s})=>/\.(ts|tsx)$/i.test(s)).map(({absPath:s,content:r})=>({path:s,content:r})),n=Tt(t,"precise");if(n.files.size===0)return;for(let s of e){if(s.result.relations.length===0)continue;let r=new Set(s.result.symbols.map(i=>i.name));s.result.relations=St(s.result.relations,s.result.filePath,n,r);}}catch(t){let n=`precise enhancement \u5931\u8D25\uFF0C\u5DF2\u56DE\u9000\u5230\u672C\u5730 relations: ${String(t)}`;process.stderr.write(`[Frontend-Code-Skimmer] ${n}
404
+ `);for(let s of e){let r=s.result.errors||[];r.includes(n)||(s.result.errors=[...r,n]);}}}async indexProject(e){let t=Date.now(),n=e?.include||[...mt],s=e?.exclude||[...ft],r=e?.force||false,i=Date.now(),a=await Es(n,{cwd:this.projectRoot,ignore:s,absolute:true,onlyFiles:true}),c=Date.now()-i,l={totalFiles:a.length,indexedFiles:0,skippedFiles:0,totalSymbols:0,durationMs:0,phaseTimings:{discoverFilesMs:c,readFilesMs:0,parseMs:0,saveToDbMs:0,totalMs:0},errors:[]},u=0,p=0,d=0;if((e?.precisionMode||"heuristic")==="precise"){let f=[];for(let m=0;m<a.length;m++){let b=a[m],g=pe(b,this.projectRoot);e?.onProgress?.(m+1,a.length,g);try{let E=J__default.statSync(b).mtimeMs,y=Date.now(),N=J__default.readFileSync(b,"utf-8"),T=Date.now()-y,R=Date.now(),_=Me(b,N),x=Date.now()-R;u+=T,p+=x,f.push({absPath:b,relPath:g,result:_,parseMs:x,readMs:T,content:N,mtime:E});}catch(E){l.errors.push({file:g,error:String(E)});}}this.enhancePreciseRelations(f);for(let m of f){let b=Date.now();try{let g=Ce(m.content),E=Xe(m.content),y=Buffer.byteLength(m.content,"utf-8"),N=Fe(m.result,m.content);this.db.saveParseResult(m.result,m.absPath,m.relPath,g,y,E,m.mtime,N.exportSignatureHash,N.importSignatureHash),l.indexedFiles++,l.totalSymbols+=m.result.symbols.length,m.result.errors?.length&&l.errors.push(...m.result.errors.map(T=>({file:m.relPath,error:T}))),d+=Date.now()-b;}catch(g){l.errors.push({file:m.relPath,error:String(g)});}}}else for(let f=0;f<a.length;f++){let m=a[f],b=pe(m,this.projectRoot);e?.onProgress?.(f+1,a.length,b);try{let g=await this.indexFile(m,b,r);g.skipped?l.skippedFiles++:(l.indexedFiles++,l.totalSymbols+=g.symbolCount,u+=g.readMs||0,p+=g.parseMs||0,d+=g.saveMs||0,g.errors?.length&&l.errors.push(...g.errors.map(E=>({file:b,error:E}))));}catch(g){l.errors.push({file:b,error:String(g)});}}return l.phaseTimings.readFilesMs=u,l.phaseTimings.parseMs=p,l.phaseTimings.saveToDbMs=d,l.phaseTimings.totalMs=Date.now()-t,l.durationMs=l.phaseTimings.totalMs,l}async selectivePrecise(e){let t=Date.now(),n=e?.maxFiles??20,s=e?.maxTimeMs??1500;this.scheduler.configure({maxFiles:n,maxTimeMs:s});let r=this.db.getAllFilePaths(),i=this.db.getReverseDependencyMap(),a=new Set;for(let b of r){let g=this.fileAbsPath(b);if(!J__default.existsSync(g))continue;let E=this.db.getFileSignatures(b);if(!E){this.scheduler.enqueue(b,"low");continue}let y;try{y=J__default.statSync(g);let I=this.db.getFileHashAndMtime(b);if(I&&I.mtime===y.mtimeMs&&I.contentHash)continue}catch{continue}let N=J__default.readFileSync(g,"utf-8"),T=Ce(N);if(E.contentHash===T){this.db.updateFileMtime(b,y.mtimeMs);continue}let R=Me(g,N),_=Fe(R,N),x=ln(E,_);if(x==="unchanged")continue;let A=pn(b,x,i);for(let I of A)a.add(I);let k=x==="export_changed"||x==="full_changed"?"high":x==="import_changed"?"normal":"low";for(let I of A)this.scheduler.enqueue(I,k);}let{tasks:c,exceededBudget:l,remainingPending:u}=this.scheduler.dequeueBatch(),p=[],d=[],h=0;for(let b=0;b<c.length;b++){let E=c[b].relPath;if(a.add(E),Date.now()-t>=s){d.push(...c.slice(b));break}let y=this.fileAbsPath(E);if(!J__default.existsSync(y)){this.removeFile(E);continue}try{let N=J__default.readFileSync(y,"utf-8"),T=Me(y,N),R=Ce(N),_=Xe(N),x=Buffer.byteLength(N,"utf-8");p.push({absPath:y,relPath:E,result:T,content:N,hash:R,lineCount:_,fileSize:x,mtime:J__default.statSync(y).mtimeMs});}catch(N){process.stderr.write(`[Frontend-Code-Skimmer] Selective precise \u5931\u8D25: ${E} - ${String(N)}
405
+ `);}}d.length>0&&this.scheduler.requeue(d),this.enhancePreciseRelations(p);for(let b of p)try{let g=Fe(b.result,b.content);this.db.saveParseResult(b.result,b.absPath,b.relPath,b.hash,b.fileSize,b.lineCount,b.mtime,g.exportSignatureHash,g.importSignatureHash),h++;}catch(g){process.stderr.write(`[Frontend-Code-Skimmer] Selective precise \u843D\u5E93\u5931\u8D25: ${b.relPath} - ${String(g)}
406
+ `);}let f=Date.now()-t,m=u+d.length;return process.stderr.write(`[Frontend-Code-Skimmer] Selective precise: ${h}/${a.size} affected, ${f}ms, pending: ${m}${l||d.length>0?" (budget limited)":""}
407
+ `),{reindexedFiles:h,affectedFiles:Array.from(a),skippedByBudget:m}}async indexFile(e,t,n=false){let s=0,r=0,i=null;if(!n){try{let y=J__default.statSync(e);s=y.mtimeMs,r=y.size;}catch{}if(i=this.db.getFileMeta(t),i&&i.mtime>0&&i.mtime===s&&!(i.fileSize>0&&i.fileSize!==r))return {skipped:true,symbolCount:0,readMs:0,parseMs:0,saveMs:0}}let a=Date.now(),c=J__default.readFileSync(e,"utf-8"),l=Date.now()-a,u=Ce(c);if(!n&&i&&i.hash===u)return s>0&&i.mtime!==s&&this.db.updateFileMtime(t,s),{skipped:true,symbolCount:0,readMs:l,parseMs:0,saveMs:0};let p=Xe(c),d=Buffer.byteLength(c,"utf-8"),h=Date.now(),f=Me(e,c),m=Date.now()-h,b=Fe(f,c),g=Date.now();this.db.saveParseResult(f,e,t,u,d,p,s,b.exportSignatureHash,b.importSignatureHash);let E=Date.now()-g;return {skipped:false,symbolCount:f.symbols.length,readMs:l,parseMs:m,saveMs:E,errors:f.errors}}removeFile(e){this.db.deleteFile(e);}fileAbsPath(e){return K__default.join(this.projectRoot,e)}async startWatcher(){let{default:e}=await import('chokidar'),t=e.watch([...mt].map(s=>K__default.posix.join(this.projectRoot,s)),{cwd:this.projectRoot,ignored:[...ft],persistent:true,ignoreInitial:true,awaitWriteFinish:{stabilityThreshold:Gt}}),n=async s=>{let r=pe(s,this.projectRoot);try{await this.indexFile(s,r),this.scheduler.enqueue(r,"normal"),process.stderr.write(`[Frontend-Code-Skimmer] \u5DF2\u66F4\u65B0\u7D22\u5F15: ${r}
408
+ `);}catch(i){process.stderr.write(`[Frontend-Code-Skimmer] \u66F4\u65B0\u5931\u8D25: ${r} - ${String(i)}
409
+ `);}};return t.on("add",n).on("change",n).on("unlink",s=>{let r=pe(s,this.projectRoot);this.removeFile(r),process.stderr.write(`[Frontend-Code-Skimmer] \u5DF2\u5220\u9664\u7D22\u5F15: ${r}
410
+ `);}),()=>t.close()}};var Ts=8,Ss=30,xs=14,As=360*60*1e3,rt=class{dbCache=new Map;accessTimes=new Map;indexerCache=new Map;dbPaths=new Map;watcherCleanups=new Map;lastProject=null;globalCacheDir;defaultProject;maxOpenProjects;maxIdleMs;dbTtlMs;lastDiskCleanupAt=0;constructor(){this.globalCacheDir=K__default.join(_s.homedir(),".frontend-code-skimmer","databases"),J__default.mkdirSync(this.globalCacheDir,{recursive:true}),this.defaultProject=process.env.SKIMMER_PROJECT||null,this.defaultProject&&(this.defaultProject=K__default.resolve(this.defaultProject)),this.maxOpenProjects=this.parsePositiveInt(process.env.SKIMMER_MAX_OPEN_PROJECTS,Ts);let e=this.parsePositiveInt(process.env.SKIMMER_DB_IDLE_MINUTES,Ss),t=this.parsePositiveInt(process.env.SKIMMER_DB_TTL_DAYS,xs);this.maxIdleMs=e*60*1e3,this.dbTtlMs=t*24*60*60*1e3,this.maybeCleanupDiskCache(Date.now());}resolveProjectRoot(e){if(e){let t=K__default.resolve(e);if(!J__default.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=K__default.resolve(e),n=Date.now();if(this.evictIdleDatabases(n),this.maybeCleanupDiskCache(n),this.dbCache.has(t))return this.touchProject(t,n),this.dbCache.get(t);this.evictLruIfNeeded(n);let s=this.resolveDbPath(t),r=new ze(t,s);return this.dbCache.set(t,r),this.dbPaths.set(t,s),this.touchProject(t,n),this.lastProject=t,process.stderr.write(`[Frontend-Code-Skimmer] \u5DF2\u8FDE\u63A5\u9879\u76EE: ${t}
285
411
  `),process.stderr.write(`[Frontend-Code-Skimmer] \u6570\u636E\u5E93: ${s}
286
- `),r}getContext(e){let t=this.resolveProjectRoot(e),n=this.getDatabase(t);return this.lastProject=t,{db:n,projectRoot:t}}setLastProject(e){this.lastProject=H.resolve(e);}listProjects(){return Array.from(this.dbCache.entries()).map(([e])=>({root:e,dbPath:this.dbPaths.get(e)||this.resolveDbPath(e)}))}registerWatcher(e,t){let n=H.resolve(e),s=this.watcherCleanups.get(n);if(s)try{s();}catch{}this.watcherCleanups.set(n,t);}closeProject(e){let t=H.resolve(e),n=this.watcherCleanups.get(t);if(n){try{n();}catch{}this.watcherCleanups.delete(t);}let s=this.dbCache.get(t);s&&(s.close(),this.dbCache.delete(t),this.accessTimes.delete(t),this.dbPaths.delete(t),this.lastProject===t&&(this.lastProject=null));}closeAll(){for(let e of this.watcherCleanups.values())try{e();}catch{}this.watcherCleanups.clear();for(let e of this.dbCache.values())e.close();this.dbCache.clear(),this.accessTimes.clear(),this.dbPaths.clear(),this.lastProject=null;}resolveDbPath(e){if(process.env.SKIMMER_DB&&this.dbCache.size===0)return H.resolve(process.env.SKIMMER_DB);let t=H.join(e,".agent","skimmer_find_symbol"),n=H.join(t,$e);try{return F.mkdirSync(t,{recursive:!0}),F.accessSync(e,F.constants.W_OK),n}catch{let s=createHash("md5").update(e).digest("hex").slice(0,8),r=e.replace(/[/\\:]/g,"_").replace(/^_+/,"").slice(-40);return H.join(this.globalCacheDir,`${s}_${r}.db`)}}parsePositiveInt(e,t){let n=Number.parseInt(String(e||""),10);return Number.isFinite(n)&&n>0?n:t}touchProject(e,t){this.accessTimes.set(e,t);}evictLruIfNeeded(e){for(;this.dbCache.size>=this.maxOpenProjects;){let t=null,n=Number.POSITIVE_INFINITY;for(let s of this.dbCache.keys()){let r=this.accessTimes.get(s)??e;r<n&&(n=r,t=s);}if(!t)break;this.closeProject(t);}}evictIdleDatabases(e){let t=[];for(let n of this.dbCache.keys()){if(n===this.lastProject)continue;let s=this.accessTimes.get(n)??e;e-s>this.maxIdleMs&&t.push(n);}for(let n of t)this.closeProject(n);}maybeCleanupDiskCache(e){if(e-this.lastDiskCleanupAt<un)return;this.lastDiskCleanupAt=e;let t=[];try{t=F.readdirSync(this.globalCacheDir,{withFileTypes:!0});}catch{return}let n=new Set;for(let r of this.dbPaths.values())r.startsWith(this.globalCacheDir)&&n.add(H.resolve(r));let s=e-this.dbTtlMs;for(let r of t){if(!r.isFile()||!r.name.endsWith(".db"))continue;let o=H.join(this.globalCacheDir,r.name);if(n.has(H.resolve(o)))continue;let i;try{i=F.statSync(o);}catch{continue}i.mtimeMs>=s||(this.safeUnlink(o),this.safeUnlink(`${o}-wal`),this.safeUnlink(`${o}-shm`));}}safeUnlink(e){try{F.existsSync(e)&&F.unlinkSync(e);}catch{}}};w();tt();function Ct(l,e){l.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
412
+ `),r}getContext(e){let t=this.resolveProjectRoot(e),n=this.getDatabase(t);return this.lastProject=t,{db:n,projectRoot:t}}getIndexer(e){let t=this.resolveProjectRoot(e),n=K__default.resolve(t),s=Date.now();if(this.evictIdleDatabases(s),this.maybeCleanupDiskCache(s),this.indexerCache.has(n))return this.touchProject(n,s),this.lastProject=n,this.indexerCache.get(n);let r=this.getDatabase(n),i=new st(n,r);return this.indexerCache.set(n,i),this.touchProject(n,s),this.lastProject=n,i}setLastProject(e){this.lastProject=K__default.resolve(e);}listProjects(){return Array.from(this.dbCache.entries()).map(([e])=>({root:e,dbPath:this.dbPaths.get(e)||this.resolveDbPath(e)}))}registerWatcher(e,t){let n=K__default.resolve(e),s=this.watcherCleanups.get(n);if(s)try{s();}catch{}this.watcherCleanups.set(n,t);}hasWatcher(e){let t=K__default.resolve(e);return this.watcherCleanups.has(t)}closeProject(e){let t=K__default.resolve(e),n=this.watcherCleanups.get(t);if(n){try{n();}catch{}this.watcherCleanups.delete(t);}let s=this.dbCache.get(t);s&&(s.close(),this.dbCache.delete(t),this.accessTimes.delete(t),this.indexerCache.delete(t),this.dbPaths.delete(t),this.lastProject===t&&(this.lastProject=null));}closeAll(){for(let e of this.watcherCleanups.values())try{e();}catch{}this.watcherCleanups.clear();for(let e of this.dbCache.values())e.close();this.dbCache.clear(),this.indexerCache.clear(),this.accessTimes.clear(),this.dbPaths.clear(),this.lastProject=null;}resolveDbPath(e){if(process.env.SKIMMER_DB&&this.dbCache.size===0)return K__default.resolve(process.env.SKIMMER_DB);let t=K__default.join(e,".agent","skimmer_find_symbol"),n=K__default.join(t,Ke);try{return J__default.mkdirSync(t,{recursive:!0}),J__default.accessSync(e,J__default.constants.W_OK),n}catch{let s=createHash("md5").update(e).digest("hex").slice(0,8),r=e.replace(/[/\\:]/g,"_").replace(/^_+/,"").slice(-40);return K__default.join(this.globalCacheDir,`${s}_${r}.db`)}}parsePositiveInt(e,t){let n=Number.parseInt(String(e||""),10);return Number.isFinite(n)&&n>0?n:t}touchProject(e,t){this.accessTimes.set(e,t);}evictLruIfNeeded(e){for(;this.dbCache.size>=this.maxOpenProjects;){let t=null,n=Number.POSITIVE_INFINITY;for(let s of this.dbCache.keys()){let r=this.accessTimes.get(s)??e;r<n&&(n=r,t=s);}if(!t)break;this.closeProject(t);}}evictIdleDatabases(e){let t=[];for(let n of this.dbCache.keys()){if(n===this.lastProject)continue;let s=this.accessTimes.get(n)??e;e-s>this.maxIdleMs&&t.push(n);}for(let n of t)this.closeProject(n);}maybeCleanupDiskCache(e){if(e-this.lastDiskCleanupAt<As)return;this.lastDiskCleanupAt=e;let t=[];try{t=J__default.readdirSync(this.globalCacheDir,{withFileTypes:!0});}catch{return}let n=new Set;for(let r of this.dbPaths.values())r.startsWith(this.globalCacheDir)&&n.add(K__default.resolve(r));let s=e-this.dbTtlMs;for(let r of t){if(!r.isFile()||!r.name.endsWith(".db"))continue;let i=K__default.join(this.globalCacheDir,r.name);if(n.has(K__default.resolve(i)))continue;let a;try{a=J__default.statSync(i);}catch{continue}a.mtimeMs>=s||(this.safeUnlink(i),this.safeUnlink(`${i}-wal`),this.safeUnlink(`${i}-shm`));}}safeUnlink(e){try{J__default.existsSync(e)&&J__default.unlinkSync(e);}catch{}}};var At=createRequire(import.meta.url);function un(o,e){let t=[];if(o==="heuristic")return {effective:"heuristic",warnings:t};let n=At("fs"),r=At("path").join(e,"tsconfig.json");if(!n.existsSync(r))return t.push(`precise \u6A21\u5F0F\u964D\u7EA7\u4E3A heuristic: \u9879\u76EE\u6839\u76EE\u5F55\u672A\u627E\u5230 tsconfig.json (${r})`),{effective:"heuristic",warnings:t};try{At.resolve("typescript");}catch{return t.push("precise \u6A21\u5F0F\u964D\u7EA7\u4E3A heuristic: typescript \u5305\u4E0D\u53EF\u7528\uFF08\u53EF\u80FD\u9700\u8981 npm install\uFF09"),{effective:"heuristic",warnings:t}}return {effective:"precise",warnings:t}}function fn(o,e){o.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
287
413
  \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
288
414
  \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
289
415
  \u591A\u4E2A\u9879\u76EE\u4F1A\u5E76\u884C\u7F13\u5B58\uFF0C\u5207\u6362\u65E0\u9700\u91CD\u542F\u3002
@@ -292,92 +418,122 @@ import H from'path';import'url';import nn,{createHash}from'crypto';import {creat
292
418
  - \u9996\u6B21\u5206\u6790\u9879\u76EE: project_path="/Users/xxx/projects/my-app"
293
419
  - \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
294
420
  - \u5F3A\u5236\u5168\u91CF\u91CD\u5EFA: force=true
421
+ - \u7CBE\u786E\u7CBE\u5EA6\u6A21\u5F0F: precision_mode="precise"\uFF08\u57FA\u4E8E TypeScript Compiler API \u505A\u8DE8\u6587\u4EF6 import/export \u7ED1\u5B9A\uFF09
295
422
 
296
- \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:n,include:s,exclude:r})=>{let{db:o,projectRoot:i}=e.getContext(t),a=new he(i,o),c=await a.indexProject({include:s,exclude:r,force:n,onProgress:(h,y)=>{(h%20===0||h===y)&&process.stderr.write(`[Frontend-Code-Skimmer] \u8FDB\u5EA6: ${h}/${y}
297
- `);}});e.setLastProject(i);try{let h=await a.startWatcher();e.registerWatcher(i,h),process.stderr.write(`[Frontend-Code-Skimmer] \u6587\u4EF6\u76D1\u542C\u5DF2\u542F\u52A8: ${i}
298
- `);}catch(h){process.stderr.write(`[Frontend-Code-Skimmer] \u6587\u4EF6\u76D1\u542C\u542F\u52A8\u5931\u8D25\uFF08\u7D22\u5F15\u4ECD\u53EF\u7528\uFF09: ${String(h)}
299
- `);}let u=c.indexedFiles>0||c.totalFiles>0,p=c.totalSymbols>0,d=u?"\u2705 \u53EF\u7528":"\u274C \u65E0\u53EF\u67E5\u8BE2\u6587\u4EF6",f=p?"\u2705 \u53EF\u7528":"\u26A0\uFE0F \u7B26\u53F7\u6570\u4E3A0\uFF08\u89E3\u6790\u53EF\u80FD\u672A\u63D0\u53D6\u5230\u7B26\u53F7\uFF0C\u4F46\u6587\u4EF6\u641C\u7D22\u4ECD\u53EF\u7528\uFF09",m=u?"\u2705 \u53EF\u7528":"\u274C \u65E0\u53EF\u67E5\u8BE2\u6587\u4EF6",g=u?"\u2705 \u53EF\u7528\uFF08\u57FA\u4E8E\u6B63\u5219\u626B\u63CF\u6587\u4EF6\uFF09":"\u274C \u65E0\u53EF\u67E5\u8BE2\u6587\u4EF6",E=[`\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{1F4CA} \u3010\u7EDF\u8BA1\u6570\u91CF\u3011\uFF08\u6CE8\u610F\uFF1A\u7B26\u53F7\u65700\u53EF\u80FD\u662F\u89E3\u6790\u89C4\u5219\u672A\u547D\u4E2D\uFF0C\u4E0D\u4EE3\u8868\u7D22\u5F15\u5931\u8D25\uFF09",` \u{1F4C1} \u603B\u6587\u4EF6\u6570: ${c.totalFiles}`,` \u{1F504} \u5DF2\u7D22\u5F15: ${c.indexedFiles}`,` \u23E9 \u5DF2\u8DF3\u8FC7: ${c.skippedFiles} (\u5185\u5BB9\u672A\u53D8)`,` \u{1F523} \u603B\u7B26\u53F7\u6570: ${c.totalSymbols}`,` \u23F1\uFE0F \u8017\u65F6: ${c.durationMs}ms`,"","\u{1F50C} \u3010\u53EF\u67E5\u8BE2\u80FD\u529B\u72B6\u6001\u3011\uFF08\u4E0E\u7B26\u53F7\u6570\u65E0\u5173\uFF0C\u53EA\u8981\u6587\u4EF6\u626B\u63CF\u5B8C\u6210\u5373\u53EF\u7528\uFF09",` skimmer_find_symbol ${f}`,` skimmer_get_component_outline ${f}`,` skimmer_find_by_behavior ${m}`,` skimmer_trace_data_lifecycle ${g}`,` skimmer_trace_assignments ${g}`,` skimmer_get_code_slice ${d}`,"","\u{1F4A1} \u540E\u7EED\u5DE5\u5177\u8C03\u7528\u53EF\u7701\u7565 project_path\uFF08\u81EA\u52A8\u4F7F\u7528\u6B64\u9879\u76EE\uFF09"," \u5982\u7B26\u53F7\u6570\u4E3A0\u4F46\u5DE5\u5177\u4ECD\u8FD4\u56DE\u7ED3\u679C\uFF0C\u5C5E\u6B63\u5E38\u73B0\u8C61\uFF08\u6B63\u5219\u626B\u63CF\u8DEF\u5F84\u4E0D\u4F9D\u8D56\u7B26\u53F7\u7D22\u5F15\uFF09","\u{1F441}\uFE0F \u6587\u4EF6\u76D1\u542C\u5DF2\u542F\u52A8 \u2014 \u4EE3\u7801\u53D8\u66F4\u5C06\u81EA\u52A8\u589E\u91CF\u66F4\u65B0\u7D22\u5F15\uFF08\u65E0\u9700\u624B\u52A8\u91CD\u65B0\u7D22\u5F15\uFF09"];if(c.errors.length>0){E.push(`
300
- \u26A0\uFE0F \u89E3\u6790\u5931\u8D25 (${c.errors.length} \u4E2A):`);for(let h of c.errors.slice(0,5))E.push(` - ${h.file}: ${h.error}`);c.errors.length>5&&E.push(` ... \u8FD8\u6709 ${c.errors.length-5} \u4E2A`);}return {content:[{type:"text",text:E.join(`
301
- `)}]}});}w();G();function Pt(l,e){l.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
423
+ \u8FD4\u56DE: \u7D22\u5F15\u7EDF\u8BA1\uFF08\u6587\u4EF6\u6570\u3001\u7B26\u53F7\u6570\u3001\u8017\u65F6\u3001\u7CBE\u5EA6\u6A21\u5F0F\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"),precision_mode:z$1.enum(["heuristic","precise"]).optional().default("heuristic").describe("\u5206\u6790\u7CBE\u5EA6\u6A21\u5F0F: heuristic(\u5FEB\u901F\uFF0C\u9ED8\u8BA4) | precise(\u8DE8\u6587\u4EF6 import/export \u7ED1\u5B9A\uFF0C\u9700\u8981 tsconfig.json)"),selective_precise:z$1.boolean().optional().default(false).describe("Phase 5: \u662F\u5426\u5728\u7D22\u5F15\u540E\u6267\u884C\u9009\u62E9\u6027 precise \u91CD\u7B97\uFF08\u4EC5\u91CD\u7B97\u53D8\u66F4\u6587\u4EF6+\u53D7\u5F71\u54CD\u6587\u4EF6\uFF09"),max_precise_files:z$1.number().optional().default(20).describe("\u9009\u62E9\u6027 precise \u5355\u6B21\u6700\u5927\u6587\u4EF6\u6570\uFF08\u9ED8\u8BA4 20\uFF09")}),annotations:{readOnlyHint:false,destructiveHint:false,idempotentHint:true}},async({project_path:t,force:n,include:s,exclude:r,precision_mode:i,selective_precise:a,max_precise_files:c})=>{let{projectRoot:l}=e.getContext(t),u=i||"heuristic",{effective:p,warnings:d}=un(u,l),h=e.getIndexer(l),f=await h.indexProject({include:s,exclude:r,force:n,precisionMode:p,onProgress:(k,I)=>{(k%20===0||k===I)&&process.stderr.write(`[Frontend-Code-Skimmer] \u8FDB\u5EA6: ${k}/${I}
424
+ `);}});e.setLastProject(l);let m=0;try{let k=Date.now(),I=await h.startWatcher();m=Date.now()-k,e.registerWatcher(l,I),process.stderr.write(`[Frontend-Code-Skimmer] \u6587\u4EF6\u76D1\u542C\u5DF2\u542F\u52A8: ${l}
425
+ `);}catch(k){process.stderr.write(`[Frontend-Code-Skimmer] \u6587\u4EF6\u76D1\u542C\u542F\u52A8\u5931\u8D25\uFF08\u7D22\u5F15\u4ECD\u53EF\u7528\uFF09: ${String(k)}
426
+ `);}let b=null;if(a)try{let k=await h.selectivePrecise({maxFiles:c||20});b={reindexedFiles:k.reindexedFiles,affectedFiles:k.affectedFiles.length,skippedByBudget:k.skippedByBudget};}catch(k){process.stderr.write(`[Frontend-Code-Skimmer] Selective precise \u5931\u8D25: ${String(k)}
427
+ `);}let g=f.indexedFiles>0||f.totalFiles>0,E=f.totalSymbols>0,y=g?"\u2705 \u53EF\u7528":"\u274C \u65E0\u53EF\u67E5\u8BE2\u6587\u4EF6",N=E?"\u2705 \u53EF\u7528":"\u26A0\uFE0F \u7B26\u53F7\u6570\u4E3A0\uFF08\u89E3\u6790\u53EF\u80FD\u672A\u63D0\u53D6\u5230\u7B26\u53F7\uFF0C\u4F46\u6587\u4EF6\u641C\u7D22\u4ECD\u53EF\u7528\uFF09",T=g?"\u2705 \u53EF\u7528":"\u274C \u65E0\u53EF\u67E5\u8BE2\u6587\u4EF6",R=g?"\u2705 \u53EF\u7528\uFF08\u57FA\u4E8E\u6B63\u5219\u626B\u63CF\u6587\u4EF6\uFF09":"\u274C \u65E0\u53EF\u67E5\u8BE2\u6587\u4EF6",_=f.phaseTimings,x=_?["","\u23F1\uFE0F \u3010\u9636\u6BB5\u8017\u65F6\u3011",` \u{1F50D} \u6587\u4EF6\u53D1\u73B0: ${_.discoverFilesMs}ms`,` \u{1F4D6} \u6587\u4EF6\u8BFB\u53D6: ${_.readFilesMs}ms`,` \u{1F52C} \u89E3\u6790: ${_.parseMs}ms`,` \u{1F4BE} \u6570\u636E\u5E93\u5199\u5165: ${_.saveToDbMs}ms`,` \u{1F4CA} \u603B\u8BA1: ${_.totalMs}ms`,` \u{1F4E1} \u6587\u4EF6\u76D1\u542C: ${m}ms`]:[],A=[`\u2705 \u7D22\u5F15\u5B8C\u6210 \u2014 ${l}`,"\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{1F4CA} \u3010\u7EDF\u8BA1\u6570\u91CF\u3011\uFF08\u6CE8\u610F\uFF1A\u7B26\u53F7\u65700\u53EF\u80FD\u662F\u89E3\u6790\u89C4\u5219\u672A\u547D\u4E2D\uFF0C\u4E0D\u4EE3\u8868\u7D22\u5F15\u5931\u8D25\uFF09",` \u{1F4C1} \u603B\u6587\u4EF6\u6570: ${f.totalFiles}`,` \u{1F504} \u5DF2\u7D22\u5F15: ${f.indexedFiles}`,` \u23E9 \u5DF2\u8DF3\u8FC7: ${f.skippedFiles} (\u5185\u5BB9\u672A\u53D8)`,` \u{1F523} \u603B\u7B26\u53F7\u6570: ${f.totalSymbols}`,` \u{1F3AF} \u7CBE\u5EA6\u6A21\u5F0F: ${p}`,` \u23F1\uFE0F \u8017\u65F6: ${f.durationMs}ms`,...x,"","\u{1F50C} \u3010\u53EF\u67E5\u8BE2\u80FD\u529B\u72B6\u6001\u3011\uFF08\u4E0E\u7B26\u53F7\u6570\u65E0\u5173\uFF0C\u53EA\u8981\u6587\u4EF6\u626B\u63CF\u5B8C\u6210\u5373\u53EF\u7528\uFF09",` skimmer_find_symbol ${N}`,` skimmer_get_component_outline ${N}`,` skimmer_find_by_behavior ${T}`,` skimmer_trace_data_lifecycle ${R}`,` skimmer_trace_assignments ${R}`,` skimmer_get_code_slice ${y}`," skimmer_index_health \u2705 \u53EF\u7528","","\u{1F4A1} \u540E\u7EED\u5DE5\u5177\u8C03\u7528\u53EF\u7701\u7565 project_path\uFF08\u81EA\u52A8\u4F7F\u7528\u6B64\u9879\u76EE\uFF09"," \u5982\u7B26\u53F7\u6570\u4E3A0\u4F46\u5DE5\u5177\u4ECD\u8FD4\u56DE\u7ED3\u679C\uFF0C\u5C5E\u6B63\u5E38\u73B0\u8C61\uFF08\u6B63\u5219\u626B\u63CF\u8DEF\u5F84\u4E0D\u4F9D\u8D56\u7B26\u53F7\u7D22\u5F15\uFF09","\u{1F441}\uFE0F \u6587\u4EF6\u76D1\u542C\u5DF2\u542F\u52A8 \u2014 \u4EE3\u7801\u53D8\u66F4\u5C06\u81EA\u52A8\u589E\u91CF\u66F4\u65B0\u7D22\u5F15\uFF08\u65E0\u9700\u624B\u52A8\u91CD\u65B0\u7D22\u5F15\uFF09"];if(f.errors.length>0){A.push(`
428
+ \u26A0\uFE0F \u89E3\u6790\u5931\u8D25 (${f.errors.length} \u4E2A):`);for(let k of f.errors.slice(0,5))A.push(` - ${k.file}: ${k.error}`);f.errors.length>5&&A.push(` ... \u8FD8\u6709 ${f.errors.length-5} \u4E2A`);}if(d.length>0){A.push(""),A.push("\u26A0\uFE0F \u7CBE\u5EA6\u964D\u7EA7:");for(let k of d)A.push(` - ${k}`);}if(b){A.push(""),A.push("\u{1F3AF} \u9009\u62E9\u6027 Precise \u91CD\u7B97:"),A.push(` \u{1F4CA} \u91CD\u7B97\u6587\u4EF6: ${b.reindexedFiles}`),A.push(` \u{1F517} \u5F71\u54CD\u6587\u4EF6: ${b.affectedFiles} (\u5019\u9009\u6570)`),b.skippedByBudget>0&&(A.push(` \u23F8\uFE0F \u8D85\u9884\u7B97\u8DF3\u8FC7\u7684\u6587\u4EF6: ${b.skippedByBudget}`),A.push(" \u{1F4A1} \u540E\u7EED watcher \u89E6\u53D1\u6216\u518D\u6B21\u8C03\u7528 selective_precise=true \u7EE7\u7EED"));let k=h.getScheduler().pendingCount;k>0&&A.push(` \u{1F4CB} Pending queue: ${k} \u6587\u4EF6\u5F85\u91CD\u7B97`);}return {content:[{type:"text",text:A.join(`
429
+ `)}]}});}function Rt(o,e,t){try{if(!e||!J__default.existsSync(e))return {stale:!1};let n=J__default.statSync(e),s=o.getFileMeta(t);if(!s)return {stale:!1};let r=s.mtime>0&&n.mtimeMs>s.mtime,i=s.fileSize>0&&n.size!==s.fileSize;return r||i?{stale:!0,reason:i?`\u6587\u4EF6\u5927\u5C0F\u5DEE\u5F02 ${n.size-s.fileSize>0?"+":""}${n.size-s.fileSize} \u5B57\u8282`:"\u6587\u4EF6\u4FEE\u6539\u65F6\u95F4\u66F4\u65B0"}:{stale:!1}}catch{return {stale:false}}}function mn(o,e,t=5){let n=e.slice(0,t),s=[],r=0;for(let i of n){if(!i.abs_path||!J__default.existsSync(i.abs_path))continue;r++;let{stale:a}=Rt(o,i.abs_path,i.path);a&&s.push(i.path);}return {stale:s.length>0,reason:s.length>0?`${s.length}/${r} \u6587\u4EF6\u5DF2\u4FEE\u6539\u4F46\u7D22\u5F15\u672A\u66F4\u65B0`:void 0,checkedFiles:r,staleFiles:s.length,staleFilePaths:s.slice(0,5)}}function W(o){return {duration_ms:o.durationMs,result_count:o.resultCount,backend:o.backend,index_freshness:o.indexFreshness,project_count:o.projectCount??1,debug:o.debug,precision_mode_requested:o.precisionRequested,precision_mode_effective:o.precisionEffective,precision_warnings:o.precisionWarnings}}function U(o){let e=[`\u23F1\uFE0F \u8017\u65F6: ${o.duration_ms}ms | \u{1F4CA} \u7ED3\u679C\u6570: ${o.result_count} | \u{1F527} \u540E\u7AEF: ${o.backend}`];if(o.precision_mode_effective){let t=o.precision_mode_effective==="precise"?"\u{1F3AF} \u7CBE\u786E":"\u26A1 \u542F\u53D1\u5F0F",n=o.precision_mode_requested!==o.precision_mode_effective?` (\u8BF7\u6C42: ${o.precision_mode_requested})`:"";e.push(`\u{1F4D0} \u7CBE\u5EA6\u6A21\u5F0F: ${t}${n}`);}if(o.precision_warnings&&o.precision_warnings.length>0)for(let t of o.precision_warnings)e.push(`\u26A0\uFE0F \u7CBE\u5EA6\u8B66\u544A: ${t}`);if(o.index_freshness){let t=o.index_freshness;t.stale?(e.push(`\u26A0\uFE0F \u7D22\u5F15\u65B0\u9C9C\u5EA6: \u5DF2\u8FC7\u671F (${t.staleFiles}/${t.checkedFiles} \u6587\u4EF6) \u2014 ${t.reason||""}`),t.staleFilePaths.length>0&&e.push(` \u8FC7\u671F\u6587\u4EF6: ${t.staleFilePaths.join(", ")}`)):e.push(`\u2705 \u7D22\u5F15\u65B0\u9C9C\u5EA6: \u6700\u65B0 (\u5DF2\u68C0\u67E5 ${t.checkedFiles} \u6587\u4EF6)`);}if(o.debug){if(e.push("\u2500\u2500 \u8C03\u8BD5\u4FE1\u606F \u2500\u2500"),o.debug.phase_timings){e.push("\u9636\u6BB5\u8017\u65F6:");for(let[t,n]of Object.entries(o.debug.phase_timings))e.push(` ${t}: ${n}ms`);}o.debug.query_plan&&e.push(`\u67E5\u8BE2\u8BA1\u5212: ${o.debug.query_plan}`),o.debug.candidate_count!==void 0&&e.push(`\u5019\u9009\u6570: ${o.debug.candidate_count}`),o.debug.scanned_files!==void 0&&e.push(`\u626B\u63CF\u6587\u4EF6\u6570: ${o.debug.scanned_files}`),o.debug.fallback_reason&&e.push(`\u964D\u7EA7\u539F\u56E0: ${o.debug.fallback_reason}`);}return e.join(`
430
+ `)}function hn(o,e){o.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
302
431
  \u5305\u542B: props\u3001data/state\u3001computed\u3001methods/functions\u3001watch/effect\u3001lifecycle\u3001\u884C\u4E3A\u6807\u7B7E\u3002
303
432
  \u884C\u4E3A\u6807\u7B7E\u81EA\u52A8\u6807\u51FA: [storage:localStorage.setItem] [network:axios.get] \u7B49\u3002
304
433
 
305
434
  project_path \u53EF\u7701\u7565\uFF08\u4F7F\u7528\u4E0A\u6B21 skimmer_index_project \u6307\u5B9A\u7684\u9879\u76EE\uFF09\u3002
306
- 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:n})=>{let{db:s}=e.getContext(n),{file:r,symbols:o,behaviors:i}=s.getFileOutline(t);if(!r)return {content:[{type:"text",text:`\u274C \u6587\u4EF6\u672A\u7D22\u5F15: ${t}
435
+ 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"),debug:z$1.boolean().optional().default(false).describe("\u662F\u5426\u8F93\u51FA\u8C03\u8BD5\u5143\u4FE1\u606F")}),annotations:{readOnlyHint:true,destructiveHint:false}},async({file_path:t,project_path:n,debug:s})=>{let r=performance.now(),{db:i}=e.getContext(n),{file:a,symbols:c,behaviors:l}=i.getFileOutline(t);if(!a){let N=Math.round((performance.now()-r)*100)/100,T=W({durationMs:N,resultCount:0,backend:"indexed"});return {content:[{type:"text",text:`\u274C \u6587\u4EF6\u672A\u7D22\u5F15: ${t}
307
436
 
308
437
  \u8BF7\u5148\u8FD0\u884C:
309
- skimmer_index_project({ project_path: "${n||"<\u9879\u76EE\u8DEF\u5F84>"}" })`}]};let a="";try{let f=r.abs_path;if(f&&F.existsSync(f)){let m=F.statSync(f),g=r.file_mtime??0,E=r.file_size??0,h=g>0&&m.mtimeMs>g,y=E>0&&m.size!==E;(h||y)&&(a=`
310
- \u26A0\uFE0F [\u7D22\u5F15\u5DF2\u8FC7\u671F] ${y?`\u6587\u4EF6\u5927\u5C0F\u5DEE\u5F02 ${m.size-E>0?"+":""}${m.size-E} \u5B57\u8282`:"\u6587\u4EF6\u4FEE\u6539\u65F6\u95F4\u66F4\u65B0"}\uFF0C\u884C\u53F7\u53EF\u80FD\u504F\u79FB\uFF08\u7D22\u5F15\u8BB0\u5F55 ${r.line_count} \u884C\uFF0C\u5B9E\u9645\u53EF\u80FD\u5DF2\u53D8\u5316\uFF09
438
+ skimmer_index_project({ project_path: "${n||"<\u9879\u76EE\u8DEF\u5F84>"}" })
439
+
440
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
441
+ ${U(T)}`}]}}let u="",p=a.abs_path,{stale:d,reason:h}=Rt(i,p,t);d&&(u=`
442
+ \u26A0\uFE0F [\u7D22\u5F15\u5DF2\u8FC7\u671F] ${h||""}\uFF0C\u884C\u53F7\u53EF\u80FD\u504F\u79FB\uFF08\u7D22\u5F15\u8BB0\u5F55 ${a.line_count} \u884C\uFF0C\u5B9E\u9645\u53EF\u80FD\u5DF2\u53D8\u5316\uFF09
311
443
  \u7ACB\u5373\u91CD\u5EFA: skimmer_index_project({ force: true })
312
- `);}}catch{}let c=new Map;for(let f of i){let m=f.symbol_id;c.has(m)||c.set(m,[]);let g=`[${f.category}:${f.api_name}.${f.operation}${f.detail?`("${f.detail}")`:""}]`,E=c.get(m);E.includes(g)||E.push(g);}let u=[];u.push(`\u{1F4C4} ${t} (${r.line_count} \u884C, ${r.framework})`),u.push(`${"\u2501".repeat(50)}`),a&&u.push(a);let p={};for(let f of o){if(f.name==="<template>")continue;let m=f.category;p[m]||(p[m]=[]),p[m].push(f);}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:f,icon:m,label:g}of d){let E=p[f];if(E?.length){u.push(`
313
- ${m} ${g} (${E.length}):`);for(let h of E){let y=h.name,S=le(h.start_line,h.end_line),b=me(h.params_json,[]),T=b.length>0?`(${b.join(", ")})`:"",v=h.default_value?` = ${h.default_value}`:"",C=h.is_async?"async ":"",P=c.get(h.id),O=P?.length?` ${P.slice(0,3).join(" ")}`:"",M=h.state_setter_name?` \u2192 ${h.state_setter_name}`:"",ae=h.hook_deps_json?` [deps:${me(h.hook_deps_json,[]).join(",")}]`:"";u.push(` \u2022 ${C}${y}${T}${v}${M}${ae} ${S}${O}`);}}}return u.push(`
314
- ${"\u2500".repeat(50)}`),u.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:u.join(`
315
- `)}]}});}w();w();G();Y();var ye=class{constructor(e){this.db=e;}db;search(e,t){let{category:n,framework:s,filePath:r,limit:o=Et,fuzzy:i=true}=t||{},a=new Map,c=this.db.exactSearch(e,n,s,r);for(let g of c){let E=g.id;a.set(E,{symbol:g,filePath:g.file_path,score:100,matchReason:"\u7CBE\u786E\u5339\u914D"});}if(a.size>=o)return this.rankResults(a,o);let u=A(e),p=[e,u,...u.split(" ")].filter(Boolean);for(let g of p){if(g.length<2)continue;let E=this.db.ftsSearch(g,n,s,r,o);for(let h of E){let y=h.id;if(a.has(y))continue;let S=this.calcFtsScore(e,h.name);a.set(y,{symbol:h,filePath:h.file_path,score:S,matchReason:`FTS5 \u5168\u6587\u5339\u914D (${g})`});}}if(!i||a.size>=o)return this.rankResults(a,o);let d=this.db.getAllSymbolNames(r),f=e.toLowerCase(),m=A(e).split(" ");for(let{name:g,file_path:E,id:h}of d){if(a.has(h))continue;let y=Ae(f,g.toLowerCase()),S=Math.max(f.length,g.length),b=Math.min(Nt,Math.max(1,Math.floor(S*.28)));if(y<=b){let C=Math.max(0,80-y*15),P=this.db.getSymbolById(h);if(!P||n&&P.category!==n||s&&P.framework!==s)continue;let O=ft(e,g,y);a.set(h,{symbol:P,filePath:E,score:C,matchReason:`\u6A21\u7CCA\u5339\u914D (\u7F16\u8F91\u8DDD\u79BB=${y})`,spellingSuggestion:O});continue}let T=A(g).split(" "),v=m.filter(C=>T.some(P=>ut(C,P)>=75));if(v.length>0&&v.length>=Math.ceil(m.length*.5)){let C=50+v.length*10,P=this.db.getSymbolById(h);if(!P||n&&P.category!==n||s&&P.framework!==s)continue;a.set(h,{symbol:P,filePath:E,score:C,matchReason:`\u5355\u8BCD\u5339\u914D (${v.join(", ")})`});}}return this.rankResults(a,o)}searchByBehavior(e){return this.db.behaviorSearch(e.category,e.apiName,e.operation,e.keyword,e.filePath).map(n=>({symbolName:n.symbol_name,category:n.category,apiName:n.api_name,operation:n.operation,detail:n.detail,line:n.line_number,filePath:n.file_path,startLine:n.start_line,endLine:n.end_line}))}calcFtsScore(e,t){let n=e.toLowerCase(),s=t.toLowerCase();if(s===n)return 98;if(s.startsWith(n))return 91;if(s.includes(n))return 80;let r=A(e).split(" "),o=A(t).split(" "),i=r.some(c=>o[0]?.startsWith(c))?8:0,a=r.filter(c=>o.some(u=>u.startsWith(c))).length;return Math.min(88,58+a*8+i)}rankResults(e,t){return Array.from(e.values()).sort((n,s)=>s.score-n.score).slice(0,t)}};G();var Ut=createRequire(import.meta.url),Q="\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 be(l){return l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function de(l,e,t){let n=[];for(let s of l){if(!s?.abs_path||!F.existsSync(s.abs_path))continue;let r=F.readFileSync(s.abs_path,"utf-8").split(`
316
- `);for(let o=0;o<r.length;o++){let i=r[o];for(let a of e)if(a.regex.test(i)){n.push({filePath:s.path,line:o+1,kind:a.kind,text:i.trim()});break}if(n.length>=t)return n}}return n}function Ot(l,e){let t=be(l),n="(?:=|\\+=|-=|\\*=|/=|%=|\\|=|&=|\\^=|&&=|\\|\\|=|\\?\\?=)",s=[{kind:"declaration",regex:new RegExp(`\\b(?:const|let|var)\\s+${t}\\b`)},{kind:"assignment",regex:new RegExp(`\\b${t}\\b\\s*${n}`)},{kind:"update",regex:new RegExp(`(?:\\+\\+|--)\\s*\\b${t}\\b|\\b${t}\\b\\s*(?:\\+\\+|--)`)}];return e&&s.push({kind:"property_assignment",regex:new RegExp(`\\b${t}\\.[A-Za-z_$][\\w$]*\\s*${n}`)},{kind:"indexed_assignment",regex:new RegExp(`\\b${t}\\s*\\[[^\\]]+\\]\\s*${n}`)}),s}function ie(l,e){if(!(!l||typeof l!="object")){e(l);for(let t of Object.keys(l)){if(t==="type"||t==="loc"||t==="start"||t==="end")continue;let n=l[t];if(Array.isArray(n))for(let s of n)s&&typeof s=="object"&&s.type&&ie(s,e);else n&&typeof n=="object"&&n.type&&ie(n,e);}}}function De(l){try{return Ut("@babel/parser").parse(l,{sourceType:"module",plugins:["typescript","jsx","decorators-legacy"],errorRecovery:!0})}catch{return null}}function We(l,e){if(!l.endsWith(".vue"))return [{content:e,lineOffset:1}];try{let{parse:r}=Ut("@vue/compiler-sfc"),{descriptor:o}=r(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 s=e.slice(0,t.index||0).split(`
317
- `).length;return [{content:t[1],lineOffset:s}]}function te(l,e){return (l.loc?.start?.line??1)+e-1}function oe(l){let e=l.property;return e?e.type==="Identifier"?String(e.name||""):e.type==="Literal"?String(e.value||""):null:null}function Ft(l,e){if(l.type!=="MemberExpression")return false;let t=l.object;return !t||t.type!=="ThisExpression"?false:oe(l)===e}function st(l,e){return !!l&&l.type==="Identifier"&&String(l.name||"")===e}function je(l){let e=l.object;return e?e.type==="Identifier"?String(e.name||""):e.type==="MemberExpression"&&e.object?.type==="ThisExpression"&&oe(e)||null:null}function Ht(l){let e=new Set;return l.filter(t=>{let n=`${t.filePath}:${t.line}:${t.kind}:${t.text}`;return e.has(n)?false:(e.add(n),true)})}function rt(l,e,t=2){if(!F.existsSync(l))return {snippet:"",startLine:e};let n=F.readFileSync(l,"utf-8").split(`
318
- `),s=Math.max(0,e-1-t),r=Math.min(n.length-1,e-1+t);return {snippet:n.slice(s,r+1).map((i,a)=>{let c=s+a+1;return ` ${c===e?"\u25B6":" "} ${String(c).padStart(4)} \u2502 ${i}`}).join(`
319
- `),startLine:s+1}}function Oe(l,e=false){let n=Math.max(50,({declaration:95,assignment:85,update:80,property_assignment:75,indexed_assignment:75,dot:75,bracket:75,delete:70,direct_storage:90,alias_ref:70,regex_fallback:60}[l]??65)-(e?5:0)),s=n>=90?"\u25CF\u25CF\u25CF\u25CF\u25CF":n>=80?"\u25CF\u25CF\u25CF\u25CF\u25CB":n>=70?"\u25CF\u25CF\u25CF\u25CB\u25CB":n>=60?"\u25CF\u25CF\u25CB\u25CB\u25CB":"\u25CF\u25CB\u25CB\u25CB\u25CB";return `[\u7F6E\u4FE1\u5EA6 ${n}% ${s}]`}function jt(l,e){let t=l;return /created|mounted|beforeMount|setup\s*\(|\bdata\s*\(/.test(t)?"init":/getItem|localStorage|sessionStorage|\bfetch\b|\bload[A-Z]|\bget[A-Z]/.test(t)?"cache":/@click|@change|@input|onClick|onChange|handle[A-Z]|\bwatch\b/.test(t)?"user":e<=30?"init":"unknown"}var Mt={init:"\u{1F331} \u521D\u59CB\u5316\u6765\u6E90",cache:"\u{1F4BE} \u7F13\u5B58\u56DE\u663E",user:"\u{1F5B1}\uFE0F \u7528\u6237\u4EA4\u4E92",unknown:"\u2753 \u672A\u77E5\u6765\u6E90"};function Dt(l,e,t){let n=[];for(let s of l){if(!s.abs_path||!F.existsSync(s.abs_path))continue;let r=F.readFileSync(s.abs_path,"utf-8"),o=r.split(`
320
- `),i=We(s.path||H.basename(s.abs_path),r);for(let a of i){let c=De(a.content);c&&ie(c,u=>{if(n.length>=t||u.type!=="VariableDeclarator")return;let p=u.id;if(!p||p.type!=="Identifier")return;let d=String(p.name||"");if(!d||d===e)return;let f=u.init;if(!f)return;let m=false;if(f.type==="Identifier"&&String(f.name||"")===e&&(m=true),!m&&f.type==="MemberExpression"&&oe(f)===e&&(m=true),m||ie(f,h=>{m||(h.type==="Identifier"&&String(h.name||"")===e&&(m=true),h.type==="MemberExpression"&&oe(h)===e&&(m=true));}),!m)return;let g=te(u,a.lineOffset),E=o[g-1]?.trim()||"";n.push({alias:d,filePath:s.path,abs_path:s.abs_path,line:g,text:E});});}}return n}function Wt(l,e,t){let n=[];for(let s of l){if(!s.abs_path||!F.existsSync(s.abs_path))continue;let r=F.readFileSync(s.abs_path,"utf-8"),o=r.split(`
321
- `),i=We(s.path||H.basename(s.abs_path),r);for(let a of i){let c=De(a.content);c&&ie(c,u=>{if(n.length>=t||u.type!=="VariableDeclarator")return;let p=u.id;if(!p||p.type!=="ObjectPattern")return;let d=p.properties||[];for(let f of d){if(f.type!=="ObjectProperty"&&f.type!=="Property")continue;let m=f.key,g=f.value,E=m?.type==="Identifier"?String(m.name||""):null;if(E!==e)continue;let h=g?.type==="Identifier"?String(g.name||""):E;if(!h)continue;let y=te(u,a.lineOffset),S=o[y-1]?.trim()||"";n.push({alias:h,filePath:s.path,line:y,text:S});}});}}return n}function ot(l,e,t,n){let s=[];for(let r of l){if(!r.abs_path||!F.existsSync(r.abs_path))continue;let o=F.readFileSync(r.abs_path,"utf-8"),i=o.split(`
322
- `),a=We(r.path||H.basename(r.abs_path),o);for(let c of a){let u=De(c.content);if(u&&(ie(u,p=>{if(!(s.length>=n)){if(p.type==="VariableDeclarator"){let d=p.id;if(st(d,e)){let f=te(p,c.lineOffset);s.push({filePath:r.path,line:f,kind:"declaration",text:i[f-1]?.trim()||""});}}if(p.type==="AssignmentExpression"){let d=p.left;if(!d)return;let f=te(p,c.lineOffset);if(st(d,e)||Ft(d,e)){s.push({filePath:r.path,line:f,kind:"assignment",text:i[f-1]?.trim()||""});return}t&&d.type==="MemberExpression"&&je(d)===e&&s.push({filePath:r.path,line:f,kind:d.computed?"indexed_assignment":"property_assignment",text:i[f-1]?.trim()||""});}if(p.type==="UpdateExpression"){let d=p.argument;if(!d)return;if(st(d,e)||Ft(d,e)){let f=te(p,c.lineOffset);s.push({filePath:r.path,line:f,kind:"update",text:i[f-1]?.trim()||""});}}}}),s.length>=n))break}if(s.length>=n)break}return Ht(s).slice(0,n)}function Fe(l,e,t,n){let s=[];for(let r of l){if(!r.abs_path||!F.existsSync(r.abs_path))continue;let o=F.readFileSync(r.abs_path,"utf-8"),i=o.split(`
323
- `),a=We(r.path||H.basename(r.abs_path),o);for(let c of a){let u=De(c.content);if(u&&(ie(u,p=>{if(!(s.length>=n)){if(p.type==="AssignmentExpression"){let d=p.left;if(!d||d.type!=="MemberExpression"||je(d)!==e)return;let m=oe(d);if(t&&m!==t)return;let g=te(p,c.lineOffset);s.push({filePath:r.path,line:g,kind:d.computed?"bracket":"dot",text:i[g-1]?.trim()||""});}if(p.type==="UpdateExpression"){let d=p.argument;if(!d||d.type!=="MemberExpression"||je(d)!==e)return;let m=oe(d);if(t&&m!==t)return;let g=te(p,c.lineOffset);s.push({filePath:r.path,line:g,kind:d.computed?"bracket":"dot",text:i[g-1]?.trim()||""});}if(p.type==="UnaryExpression"&&p.operator==="delete"){let d=p.argument;if(!d||d.type!=="MemberExpression"||je(d)!==e)return;let m=oe(d);if(t&&m!==t)return;let g=te(p,c.lineOffset);s.push({filePath:r.path,line:g,kind:"delete",text:i[g-1]?.trim()||""});}}}),s.length>=n))break}if(s.length>=n)break}return Ht(s).slice(0,n)}function Bt(l,e){l.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
444
+ `);let f=new Map;for(let N of l){let T=N.symbol_id;f.has(T)||f.set(T,[]);let R=`[${N.category}:${N.api_name}.${N.operation}${N.detail?`("${N.detail}")`:""}]`,_=f.get(T);_.includes(R)||_.push(R);}let m=[];m.push(`\u{1F4C4} ${t} (${a.line_count} \u884C, ${a.framework})`),m.push(`${"\u2501".repeat(50)}`),u&&m.push(u);let b={};for(let N of c){if(N.name==="<template>")continue;let T=N.category;b[T]||(b[T]=[]),b[T].push(N);}let g=[{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:N,icon:T,label:R}of g){let _=b[N];if(_?.length){m.push(`
445
+ ${T} ${R} (${_.length}):`);for(let x of _){let A=x.name,k=Le(x.start_line,x.end_line),I=Ie(x.params_json,[]),j=I.length>0?`(${I.join(", ")})`:"",H=x.default_value?` = ${x.default_value}`:"",ae=x.is_async?"async ":"",ge=f.get(x.id),Se=ge?.length?` ${ge.slice(0,3).join(" ")}`:"",V=x.state_setter_name?` \u2192 ${x.state_setter_name}`:"",ce=x.hook_deps_json?` [deps:${Ie(x.hook_deps_json,[]).join(",")}]`:"";m.push(` \u2022 ${ae}${A}${j}${H}${V}${ce} ${k}${Se}`);}}}m.push(`
446
+ ${"\u2500".repeat(50)}`),m.push(`\u{1F4A1} \u67E5\u770B\u5177\u4F53\u4EE3\u7801: skimmer_get_code_slice({ file_path: "${t}", symbol_name: "\u65B9\u6CD5\u540D" })`);let E=Math.round((performance.now()-r)*100)/100,y=W({durationMs:E,resultCount:c.length,backend:"indexed"});return s&&(y.debug={scanned_files:1}),m.push(`
447
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
448
+ ${U(y)}`),{content:[{type:"text",text:m.join(`
449
+ `)}]}});}var De=class{constructor(e){this.db=e;}db;search(e,t){let{category:n,framework:s,filePath:r,limit:i=zt,fuzzy:a=true,allowFallbackScan:c=false,debug:l=false}=t||{},u=e.trim(),p=new Map,d={},h=performance.now(),f=this.db.exactSearch(u,n,s,r);for(let R of f)p.set(R.id,{symbol:R,filePath:R.file_path,score:100,matchReason:"\u7CBE\u786E\u5339\u914D"});if(d["1_exact"]=Math.round((performance.now()-h)*100)/100,p.size>=i)return {results:this.rankResults(p,i)};let m=performance.now(),b=0,g=w(u),E=[u,g,...g.split(" ")].filter(Boolean).filter((R,_,x)=>x.indexOf(R)===_);for(let R of E){if(R.length<2)continue;let _=this.db.ftsSearch(R,n,s,r,i);b+=_.length;for(let x of _){let A=x.id;if(p.has(A))continue;let k=this.calcFtsScore(u,x.name);p.set(A,{symbol:x,filePath:x.file_path,score:k,matchReason:`FTS5 \u524D\u7F00\u5339\u914D ("${R}")`});}}if(d["2_fts"]=Math.round((performance.now()-m)*100)/100,p.size>=i)return {results:this.rankResults(p,i),debug:l?{phase_timings:d,candidate_count:b}:void 0};let y=a&&u.length>=3,N=0;if(y){let R=performance.now(),_=this.db.getAllSymbolNames(r),x=u.toLowerCase(),A=w(u).split(" ");for(let{name:k,file_path:I,id:j}of _){if(p.has(j))continue;N++;let H=Be(x,k.toLowerCase()),ae=Math.max(x.length,k.length),ge=Math.min(Vt,Math.max(1,Math.floor(ae*.28)));if(H<=ge){let ce=Math.max(0,80-H*15),B=this.db.getSymbolById(j);if(!B||n&&B.category!==n||s&&B.framework!==s)continue;let ne=jt(u,k,H);p.set(j,{symbol:B,filePath:I,score:ce,matchReason:`\u6A21\u7CCA\u5339\u914D (\u7F16\u8F91\u8DDD\u79BB=${H})`,spellingSuggestion:ne});continue}let Se=w(k).split(" "),V=A.filter(ce=>Se.some(B=>Dt(ce,B)>=75));if(V.length>0&&V.length>=Math.ceil(A.length*.5)){let ce=50+V.length*10,B=this.db.getSymbolById(j);if(!B||n&&B.category!==n||s&&B.framework!==s)continue;p.set(j,{symbol:B,filePath:I,score:ce,matchReason:`\u5355\u8BCD\u5339\u914D (${V.join(", ")})`});}}d["3_fuzzy"]=Math.round((performance.now()-R)*100)/100;}if(p.size===0&&c){let R=performance.now(),_=this.db.ftsSearchWithFallback(u,n,s,r,i);for(let x of _){let A=x.id;p.has(A)||p.set(A,{symbol:x,filePath:x.file_path,score:50,matchReason:"LIKE \u5168\u8868\u626B\u63CF fallback"});}d["4_fallback"]=Math.round((performance.now()-R)*100)/100;}let T=l?{phase_timings:d,candidate_count:b+N,fallback_reason:!y&&u.length<3?"\u67E5\u8BE2\u8FC7\u77ED (<3\u5B57\u7B26)\uFF0C\u8DF3\u8FC7\u6A21\u7CCA\u5339\u914D":void 0}:void 0;return {results:this.rankResults(p,i),debug:T}}calcFtsScore(e,t){let n=e.toLowerCase(),s=t.toLowerCase();if(s===n)return 98;if(s.startsWith(n))return 91;if(s.includes(n))return 80;let r=w(e).split(" "),i=w(t).split(" "),a=r.some(l=>i[0]?.startsWith(l))?8:0,c=r.filter(l=>i.some(u=>u.startsWith(l))).length;return Math.min(88,58+c*8+a)}rankResults(e,t){return Array.from(e.values()).sort((n,s)=>s.score-n.score).slice(0,t)}searchByBehavior(e){return this.db.behaviorSearch(e.category,e.apiName,e.operation,e.keyword,e.filePath).map(n=>({symbolName:n.symbol_name,category:n.category,apiName:n.api_name,operation:n.operation,detail:n.detail,line:n.line_number,filePath:n.file_path,startLine:n.start_line,endLine:n.end_line}))}};var _n=createRequire(import.meta.url),be="\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 je(o){return o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function we(o,e,t){let n=[];for(let s of o){if(!s?.abs_path||!J__default.existsSync(s.abs_path))continue;let r=J__default.readFileSync(s.abs_path,"utf-8").split(`
450
+ `);for(let i=0;i<r.length;i++){let a=r[i];for(let c of e)if(c.regex.test(a)){n.push({filePath:s.path,line:i+1,kind:c.kind,text:a.trim()});break}if(n.length>=t)return n}}return n}function gn(o,e){let t=je(o),n="(?:=|\\+=|-=|\\*=|/=|%=|\\|=|&=|\\^=|&&=|\\|\\|=|\\?\\?=)",s=[{kind:"declaration",regex:new RegExp(`\\b(?:const|let|var)\\s+${t}\\b`)},{kind:"assignment",regex:new RegExp(`\\b${t}\\b\\s*${n}`)},{kind:"update",regex:new RegExp(`(?:\\+\\+|--)\\s*\\b${t}\\b|\\b${t}\\b\\s*(?:\\+\\+|--)`)}];return e&&s.push({kind:"property_assignment",regex:new RegExp(`\\b${t}\\.[A-Za-z_$][\\w$]*\\s*${n}`)},{kind:"indexed_assignment",regex:new RegExp(`\\b${t}\\s*\\[[^\\]]+\\]\\s*${n}`)}),s}function lt(o){try{return _n("@babel/parser").parse(o,{sourceType:"module",plugins:["typescript","jsx","decorators-legacy"],errorRecovery:!0})}catch{return null}}function pt(o,e){if(!o.endsWith(".vue"))return [{content:e,lineOffset:1}];try{let{parse:r}=_n("@vue/compiler-sfc"),{descriptor:i}=r(e),a=[];if(i.script?.content&&a.push({content:i.script.content,lineOffset:i.script.loc.start.line}),i.scriptSetup?.content&&a.push({content:i.scriptSetup.content,lineOffset:i.scriptSetup.loc.start.line}),a.length>0)return a}catch{}let t=e.match(/<script\b[^>]*>([\s\S]*?)<\/script>/i);if(!t||!t[1])return [];let s=e.slice(0,t.index||0).split(`
451
+ `).length;return [{content:t[1],lineOffset:s}]}function Ee(o,e){return (o.loc?.start?.line??1)+e-1}function $t(o,e){if(o.type!=="MemberExpression")return false;let t=o.object;return !t||t.type!=="ThisExpression"?false:q(o)===e}function kt(o,e){return !!o&&o.type==="Identifier"&&String(o.name||"")===e}function Nn(o){let e=new Set;return o.filter(t=>{let n=`${t.filePath}:${t.line}:${t.kind}:${t.text}`;return e.has(n)?false:(e.add(n),true)})}function wt(o,e,t=2){if(!J__default.existsSync(o))return {snippet:"",startLine:e};let n=J__default.readFileSync(o,"utf-8").split(`
452
+ `),s=Math.max(0,e-1-t),r=Math.min(n.length-1,e-1+t);return {snippet:n.slice(s,r+1).map((a,c)=>{let l=s+c+1;return ` ${l===e?"\u25B6":" "} ${String(l).padStart(4)} \u2502 ${a}`}).join(`
453
+ `),startLine:s+1}}function ot(o,e=false){let n=Math.max(50,({declaration:95,assignment:85,update:80,property_assignment:75,indexed_assignment:75,dot:75,bracket:75,delete:70,direct_storage:90,alias_ref:70,regex_fallback:60}[o]??65)-(e?5:0)),s=n>=90?"\u25CF\u25CF\u25CF\u25CF\u25CF":n>=80?"\u25CF\u25CF\u25CF\u25CF\u25CB":n>=70?"\u25CF\u25CF\u25CF\u25CB\u25CB":n>=60?"\u25CF\u25CF\u25CB\u25CB\u25CB":"\u25CF\u25CB\u25CB\u25CB\u25CB";return `[\u7F6E\u4FE1\u5EA6 ${n}% ${s}]`}var yn={init:"\u{1F331} \u521D\u59CB\u5316\u6765\u6E90",cache:"\u{1F4BE} \u7F13\u5B58\u56DE\u663E",user:"\u{1F5B1}\uFE0F \u7528\u6237\u4EA4\u4E92",unknown:"\u2753 \u672A\u77E5\u6765\u6E90"};function bn(o,e,t){let n=[];for(let s of o){if(!s.abs_path||!J__default.existsSync(s.abs_path))continue;let r=J__default.readFileSync(s.abs_path,"utf-8"),i=r.split(`
454
+ `),a=pt(s.path||K__default.basename(s.abs_path),r);for(let c of a){let l=lt(c.content);l&&fe(l,u=>{if(n.length>=t||u.type!=="VariableDeclarator")return;let p=u.id;if(!p||p.type!=="Identifier")return;let d=String(p.name||"");if(!d||d===e)return;let h=u.init;if(!h)return;let f=false;if(h.type==="Identifier"&&String(h.name||"")===e?f=true:h.type==="MemberExpression"&&(f=$t(h,e)||q(h)===e),!f)return;let m=Ee(u,c.lineOffset),b=i[m-1]?.trim()||"";n.push({alias:d,filePath:s.path,abs_path:s.abs_path,line:m,text:b});});}}return n}function En(o,e,t){let n=[];for(let s of o){if(!s.abs_path||!J__default.existsSync(s.abs_path))continue;let r=J__default.readFileSync(s.abs_path,"utf-8"),i=r.split(`
455
+ `),a=pt(s.path||K__default.basename(s.abs_path),r);for(let c of a){let l=lt(c.content);l&&fe(l,u=>{if(n.length>=t||u.type!=="VariableDeclarator")return;let p=u.id;if(!p||p.type!=="ObjectPattern")return;let d=p.properties||[];for(let h of d){if(h.type!=="ObjectProperty"&&h.type!=="Property")continue;let f=h.key,m=h.value,b=f?.type==="Identifier"?String(f.name||""):null;if(b!==e)continue;let g=m?.type==="Identifier"?String(m.name||""):b;if(!g)continue;let E=Ee(u,c.lineOffset),y=i[E-1]?.trim()||"";n.push({alias:g,filePath:s.path,line:E,text:y});}});}}return n}function vt(o,e,t,n){let s=[];for(let r of o){if(!r.abs_path||!J__default.existsSync(r.abs_path))continue;let i=J__default.readFileSync(r.abs_path,"utf-8"),a=i.split(`
456
+ `),c=pt(r.path||K__default.basename(r.abs_path),i);for(let l of c){let u=lt(l.content);if(u&&(fe(u,p=>{if(!(s.length>=n)){if(p.type==="VariableDeclarator"){let d=p.id;if(kt(d,e)){let h=Ee(p,l.lineOffset);s.push({filePath:r.path,line:h,kind:"declaration",text:a[h-1]?.trim()||""});}}if(p.type==="AssignmentExpression"){let d=p.left;if(!d)return;let h=Ee(p,l.lineOffset);if(kt(d,e)||$t(d,e)){s.push({filePath:r.path,line:h,kind:"assignment",text:a[h-1]?.trim()||""});return}t&&d.type==="MemberExpression"&&re(d)===e&&s.push({filePath:r.path,line:h,kind:d.computed?"indexed_assignment":"property_assignment",text:a[h-1]?.trim()||""});}if(p.type==="UpdateExpression"){let d=p.argument;if(!d)return;if(kt(d,e)||$t(d,e)){let h=Ee(p,l.lineOffset);s.push({filePath:r.path,line:h,kind:"update",text:a[h-1]?.trim()||""});}}}}),s.length>=n))break}if(s.length>=n)break}return Nn(s).slice(0,n)}function at(o,e,t,n){let s=[];for(let r of o){if(!r.abs_path||!J__default.existsSync(r.abs_path))continue;let i=J__default.readFileSync(r.abs_path,"utf-8"),a=i.split(`
457
+ `),c=pt(r.path||K__default.basename(r.abs_path),i);for(let l of c){let u=lt(l.content);if(u&&(fe(u,p=>{if(!(s.length>=n)){if(p.type==="AssignmentExpression"){let d=p.left;if(!d||d.type!=="MemberExpression"||re(d)!==e)return;let f=q(d);if(t&&f!==t)return;let m=Ee(p,l.lineOffset);s.push({filePath:r.path,line:m,kind:d.computed?"bracket":"dot",text:a[m-1]?.trim()||""});}if(p.type==="UpdateExpression"){let d=p.argument;if(!d||d.type!=="MemberExpression"||re(d)!==e)return;let f=q(d);if(t&&f!==t)return;let m=Ee(p,l.lineOffset);s.push({filePath:r.path,line:m,kind:d.computed?"bracket":"dot",text:a[m-1]?.trim()||""});}if(p.type==="UnaryExpression"&&p.operator==="delete"){let d=p.argument;if(!d||d.type!=="MemberExpression"||re(d)!==e)return;let f=q(d);if(t&&f!==t)return;let m=Ee(p,l.lineOffset);s.push({filePath:r.path,line:m,kind:"delete",text:a[m-1]?.trim()||""});}}}),s.length>=n))break}if(s.length>=n)break}return Nn(s).slice(0,n)}function Tn(o,e){o.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
324
458
  \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
325
459
  \u9A7C\u5CF0\u62C6\u8BCD\uFF1A\u641C "change cache" \u4E5F\u80FD\u627E\u5230 "changeCacheValue"\u3002
326
460
  \u6846\u67B6\u611F\u77E5\uFF1A\u53EF\u6309 vue2/vue3/react \u8FC7\u6EE4\u3002
327
- 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(Q),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:n,category:s,framework:r,file_path:o,fuzzy:i,limit:a})=>{let{db:c}=e.getContext(n),p=new ye(c).search(t,{category:s==="all"?void 0:s,framework:r==="all"?void 0:r,filePath:o,fuzzy:i,limit:a});if(p.length===0)return {content:[{type:"text",text:`\u{1F50D} \u641C\u7D22 "${t}" \u65E0\u7ED3\u679C
461
+ 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(be),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\uFF0C\u77ED\u67E5\u8BE2\u81EA\u52A8\u7981\u7528\uFF09"),allow_fallback_scan:z$1.boolean().optional().default(false).describe("0\u547D\u4E2D\u65F6\u662F\u5426\u5141\u8BB8 LIKE \u5168\u8868\u626B\u63CF\uFF08\u9ED8\u8BA4\u4E0D\u542F\u7528\uFF0C\u6602\u8D35\u64CD\u4F5C\uFF09"),debug:z$1.boolean().optional().default(false).describe("\u662F\u5426\u8F93\u51FA\u5404\u9636\u6BB5\u8017\u65F6\u548C\u5019\u9009\u6570"),limit:z$1.number().optional().default(15)}),annotations:{readOnlyHint:true,destructiveHint:false}},async({query:t,project_path:n,category:s,framework:r,file_path:i,fuzzy:a,allow_fallback_scan:c,debug:l,limit:u})=>{let p=performance.now(),{db:d}=e.getContext(n),h=new De(d),{results:f,debug:m}=h.search(t,{category:s==="all"?void 0:s,framework:r==="all"?void 0:r,filePath:i,fuzzy:a,limit:u,allowFallbackScan:c,debug:l}),b=Math.round((performance.now()-p)*100)/100,g=W({durationMs:b,resultCount:f.length,backend:"indexed",debug:l?m:void 0});if(f.length===0)return {content:[{type:"text",text:`\u{1F50D} \u641C\u7D22 "${t}" \u65E0\u7ED3\u679C
328
462
 
329
463
  \u{1F4A1} \u5C1D\u8BD5:
330
464
  skimmer_find_by_behavior \u6309\u884C\u4E3A\u641C\u7D22
331
- \u4F8B\u5982: skimmer_find_by_behavior({ category: "storage" })`}]};let d=[`\u{1F50D} \u641C\u7D22 "${t}" \u2014 \u627E\u5230 ${p.length} \u4E2A\u7ED3\u679C
332
- `];return p.forEach((f,m)=>{let g=f.symbol,E=me(g.params_json,[]),h=E.length>0?`(${E.join(", ")})`:"",y=le(g.start_line,g.end_line);d.push(`${m+1}. ${g.name}${h} [${g.category}/${g.framework}] \u5339\u914D\u5EA6: ${f.score}%`),d.push(` \u{1F4C4} ${f.filePath}:${y}`),d.push(` \u{1F3AF} ${f.matchReason}`),f.spellingSuggestion&&d.push(` \u{1F4A1} ${f.spellingSuggestion}`),g.default_value&&d.push(` \u{1F4CC} \u9ED8\u8BA4\u503C: ${g.default_value}`),d.push("");}),{content:[{type:"text",text:d.join(`
333
- `)}]}}),l.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
465
+ \u4F8B\u5982: skimmer_find_by_behavior({ category: "storage" })${c?"":`
466
+ \u{1F4A1} \u5C1D\u8BD5: skimmer_find_symbol({ allow_fallback_scan: true }) \u542F\u7528\u5168\u8868\u626B\u63CF`}
467
+
468
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
469
+ ${U(g)}`}]};let E=[`\u{1F50D} \u641C\u7D22 "${t}" \u2014 \u627E\u5230 ${f.length} \u4E2A\u7ED3\u679C
470
+ `];return f.forEach((y,N)=>{let T=y.symbol,R=Ie(T.params_json,[]),_=R.length>0?`(${R.join(", ")})`:"",x=Le(T.start_line,T.end_line);E.push(`${N+1}. ${T.name}${_} [${T.category}/${T.framework}] \u5339\u914D\u5EA6: ${y.score}%`),E.push(` \u{1F4C4} ${y.filePath}:${x}`),E.push(` \u{1F3AF} ${y.matchReason}`),y.spellingSuggestion&&E.push(` \u{1F4A1} ${y.spellingSuggestion}`),T.default_value&&E.push(` \u{1F4CC} \u9ED8\u8BA4\u503C: ${T.default_value}`),E.push("");}),E.push(`\u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
471
+ ${U(g)}`),{content:[{type:"text",text:E.join(`
472
+ `)}]}}),o.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
334
473
  \u540C\u65F6\u8FD4\u56DE\u8BE5\u7B26\u53F7\u7684\u884C\u4E3A\u6807\u7B7E\uFF08\u64CD\u4F5C\u4E86\u54EA\u4E9B\u5916\u90E8 API\uFF09\u3002
335
- 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(Q),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:n,project_path:s,context_lines:r})=>{let{db:o}=e.getContext(s),i=o.getSymbolByName(n,t);if(!i)return {content:[{type:"text",text:`\u274C \u672A\u627E\u5230: ${n}
474
+ 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(be),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:n,project_path:s,context_lines:r})=>{let i=performance.now(),{db:a}=e.getContext(s),c=a.getSymbolByName(n,t);if(!c){let x=Math.round((performance.now()-i)*100)/100,A=W({durationMs:x,resultCount:0,backend:"indexed"});return {content:[{type:"text",text:`\u274C \u672A\u627E\u5230: ${n}
336
475
  \u{1F4C4} \u6587\u4EF6: ${t}
337
476
 
338
- \u{1F4A1} \u8BD5\u8BD5: skimmer_find_symbol({ query: "${n}" })`}]};let a=i.abs_path;if(!F.existsSync(a))return {content:[{type:"text",text:`\u274C \u6587\u4EF6\u4E0D\u5B58\u5728: ${a}`}]};let u=F.readFileSync(a,"utf-8").split(`
339
- `),p=Math.max(1,i.start_line-r)-1,d=Math.min(u.length,i.end_line+r),f=u.slice(p,d).join(`
340
- `),g=f.includes(n)?"":`
341
- \u26A0\uFE0F [\u884C\u53F7\u504F\u79FB] \u7D22\u5F15\u8BB0\u5F55 ${n} \u5728 L${i.start_line}\uFF0C\u4F46\u8BE5\u4F4D\u7F6E\u672A\u627E\u5230\u6B64\u7B26\u53F7\u3002
342
- \u6587\u4EF6\u5DF2\u88AB\u4FEE\u6539\u4F46\u7D22\u5F15\u672A\u66F4\u65B0\uFF0C\u884C\u53F7\u53EF\u80FD\u504F\u79FB ${u.length-i.end_line} \u884C\u5DE6\u53F3\u3002
477
+ \u{1F4A1} \u8BD5\u8BD5: skimmer_find_symbol({ query: "${n}" })
478
+
479
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
480
+ ${U(A)}`}]}}let l=c.abs_path;if(!J__default.existsSync(l))return {content:[{type:"text",text:`\u274C \u6587\u4EF6\u4E0D\u5B58\u5728: ${l}`}]};let p=J__default.readFileSync(l,"utf-8").split(`
481
+ `),d=Math.max(1,c.start_line-r)-1,h=Math.min(p.length,c.end_line+r),f=p.slice(d,h).join(`
482
+ `),b=f.includes(n)?"":`
483
+ \u26A0\uFE0F [\u884C\u53F7\u504F\u79FB] \u7D22\u5F15\u8BB0\u5F55 ${n} \u5728 L${c.start_line}\uFF0C\u4F46\u8BE5\u4F4D\u7F6E\u672A\u627E\u5230\u6B64\u7B26\u53F7\u3002
484
+ \u6587\u4EF6\u5DF2\u88AB\u4FEE\u6539\u4F46\u7D22\u5F15\u672A\u66F4\u65B0\uFF0C\u884C\u53F7\u53EF\u80FD\u504F\u79FB ${p.length-c.end_line} \u884C\u5DE6\u53F3\u3002
343
485
  \u5EFA\u8BAE: skimmer_index_project({ force: true })
344
- `,{behaviors:E}=o.getFileOutline(t),h=E.filter(T=>T.symbol_id===i.id),y=a.split(".").pop()||"js",S=["tsx","jsx"].includes(y)?"jsx":["ts"].includes(y)?"typescript":"javascript",b=[`\u{1F4CD} ${i.name} [${i.category}/${i.framework}]`,`\u{1F4C4} ${t}:${le(i.start_line,i.end_line)}`];if(g&&b.push(g),i.jsdoc&&b.push(`\u{1F4DD} ${i.jsdoc}`),h.length>0){let T=[...new Set(h.map(v=>`[${v.category}:${v.api_name}.${v.operation}${v.detail?`("${v.detail}")`:""}]`))];b.push(`\u{1F3F7}\uFE0F \u884C\u4E3A: ${T.join(" ")}`);}return b.push(`
345
- \`\`\`${S}`),b.push(f),b.push("```"),{content:[{type:"text",text:b.join(`
346
- `)}]}}),l.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
486
+ `,{behaviors:g}=a.getFileOutline(t),E=g.filter(x=>x.symbol_id===c.id),y=l.split(".").pop()||"js",N=["tsx","jsx"].includes(y)?"jsx":["ts"].includes(y)?"typescript":"javascript",T=[`\u{1F4CD} ${c.name} [${c.category}/${c.framework}]`,`\u{1F4C4} ${t}:${Le(c.start_line,c.end_line)}`];if(b&&T.push(b),c.jsdoc&&T.push(`\u{1F4DD} ${c.jsdoc}`),E.length>0){let x=[...new Set(E.map(A=>`[${A.category}:${A.api_name}.${A.operation}${A.detail?`("${A.detail}")`:""}]`))];T.push(`\u{1F3F7}\uFE0F \u884C\u4E3A: ${x.join(" ")}`);}T.push(`
487
+ \`\`\`${N}`),T.push(f),T.push("```");let R=Math.round((performance.now()-i)*100)/100,_=W({durationMs:R,resultCount:1,backend:"indexed"});return T.push(`
488
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
489
+ ${U(_)}`),{content:[{type:"text",text:T.join(`
490
+ `)}]}}),o.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
347
491
  \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
348
492
  \u2705 \u672C\u5DE5\u5177\u9002\u5408\uFF1Aloading / errorMsg / count \u8FD9\u7C7B\u7B80\u5355 flag \u7684\u8D4B\u503C\u8FFD\u8E2A\u3002
349
- \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(Q),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:n,file_path:s,include_properties:r,limit:o})=>{let{db:i}=e.getContext(n),a=i.listFiles(s),c=Math.min(300,Math.max(1,o||80)),u=r??true,p=i.exactSearch(t,"state",void 0,s||void 0),d={vue2:"Vue2 data()",vue3:"Vue3 ref/reactive",react:"React useState/useRef"},f=p.filter(y=>y.default_value!=null).map(y=>({filePath:y.file_path,line:y.start_line,kind:`data_init(${d[y.framework]||y.framework})`,text:`${y.name}: ${y.default_value} \u2190 \u58F0\u660E\u521D\u59CB\u5316`})),m=ot(a,t,u,c);if(m.length===0){let y=Ot(t,u);m=de(a,y,c);}let g=new Map;for(let y of [...f,...m]){let S=`${y.filePath}:${y.line}`;g.has(S)||g.set(S,y);}let E=[...g.values()];if(E.length===0)return {content:[{type:"text",text:`\u{1F9E9} \u53D8\u91CF\u8D4B\u503C\u8FFD\u8E2A: "${t}"
493
+ \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(be),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:n,file_path:s,include_properties:r,limit:i})=>{let a=performance.now(),{db:c}=e.getContext(n),l=c.listFiles(s),u=Math.min(300,Math.max(1,i||80)),p=r??true,d=c.exactSearch(t,"state",void 0,s||void 0),h={vue2:"Vue2 data()",vue3:"Vue3 ref/reactive",react:"React useState/useRef"},f=d.filter(T=>T.default_value!=null).map(T=>({filePath:T.file_path,line:T.start_line,kind:`data_init(${h[T.framework]||T.framework})`,text:`${T.name}: ${T.default_value} \u2190 \u58F0\u660E\u521D\u59CB\u5316`})),m=vt(l,t,p,u);if(m.length===0){let T=gn(t,p);m=we(l,T,u);}let b=new Map;for(let T of [...f,...m]){let R=`${T.filePath}:${T.line}`;b.has(R)||b.set(R,T);}let g=[...b.values()],E=Math.round((performance.now()-a)*100)/100;if(g.length===0){let T=W({durationMs:E,resultCount:0,backend:"ast_scan"});return {content:[{type:"text",text:`\u{1F9E9} \u53D8\u91CF\u8D4B\u503C\u8FFD\u8E2A: "${t}"
350
494
  \u672A\u627E\u5230\u5339\u914D\u8D4B\u503C\u8BED\u53E5\uFF08\u5305\u62EC\u58F0\u660E\u521D\u59CB\u5316\uFF09
351
- \u8FC7\u6EE4: file_path=${s||"*"} include_properties=${u}`}]};let h=[`\u{1F9E9} \u53D8\u91CF\u8D4B\u503C\u8FFD\u8E2A: "${t}"`,`\u8FC7\u6EE4: file_path=${s||"*"} include_properties=${u}`,`\u547D\u4E2D: ${E.length} \u5904${f.length>0?`\uFF08\u542B ${f.length} \u5904\u58F0\u660E\u521D\u59CB\u5316\uFF09`:""}`,""];return E.forEach((y,S)=>{h.push(`${S+1}. [${y.kind}] \u{1F4C4} ${y.filePath}:L${y.line}`),h.push(` ${y.text}`);}),{content:[{type:"text",text:h.join(`
352
- `)}]}}),l.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
495
+ \u8FC7\u6EE4: file_path=${s||"*"} include_properties=${p}
496
+
497
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
498
+ ${U(T)}`}]}}let y=[`\u{1F9E9} \u53D8\u91CF\u8D4B\u503C\u8FFD\u8E2A: "${t}"`,`\u8FC7\u6EE4: file_path=${s||"*"} include_properties=${p}`,`\u547D\u4E2D: ${g.length} \u5904${f.length>0?`\uFF08\u542B ${f.length} \u5904\u58F0\u660E\u521D\u59CB\u5316\uFF09`:""}`,""];g.forEach((T,R)=>{y.push(`${R+1}. [${T.kind}] \u{1F4C4} ${T.filePath}:L${T.line}`),y.push(` ${T.text}`);});let N=W({durationMs:E,resultCount:g.length,backend:"ast_scan"});return y.push(`
499
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
500
+ ${U(N)}`),{content:[{type:"text",text:y.join(`
501
+ `)}]}}),o.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
353
502
  \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
354
503
  \u2705 \u672C\u5DE5\u5177\u9002\u5408\uFF1Aobject.specificProp \u7684\u5355\u5B57\u6BB5\u7EA7\u522B\u7CBE\u786E\u8FFD\u8E2A\u3002
355
- \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(Q),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:n,project_path:s,file_path:r,limit:o})=>{let{db:i}=e.getContext(s),a=i.listFiles(r),c=Math.min(300,Math.max(1,o||80)),u=Dt(a,t,20),p=Wt(a,t,20),d=[...new Set([...u.map(E=>E.alias),...p.map(E=>E.alias)].filter(E=>E!==t))],f=[t,...d],m=Fe(a,t,n,c);for(let E of d)m.push(...Fe(a,E,n,Math.floor(c/2)));if(m.length===0){let E="(?:=|\\+=|-=|\\*=|/=|%=|\\|=|&=|\\^=|&&=|\\|\\|=|\\?\\?=)",h=[];for(let y of f){let S=be(y);if(n){let b=be(n);h.push({kind:"dot",regex:new RegExp(`\\b${S}\\.${b}\\s*${E}`)},{kind:"bracket",regex:new RegExp(`\\b${S}\\s*\\[(?:'${b}'|"${b}")\\]\\s*${E}`)},{kind:"delete",regex:new RegExp(`\\bdelete\\s+${S}\\.(?:${b})\\b`)});}else h.push({kind:"dot",regex:new RegExp(`\\b${S}\\.[A-Za-z_$][\\w$]*\\s*${E}`)},{kind:"bracket",regex:new RegExp(`\\b${S}\\s*\\[(?:'[^']+'|"[^"]+")\\]\\s*${E}`)},{kind:"delete",regex:new RegExp(`\\bdelete\\s+${S}\\.[A-Za-z_$][\\w$]*\\b`)});}m=de(a,h,c);}if(m.length===0){let E=d.length>0?`
356
- \u522B\u540D\u5C55\u5F00: ${d.join(", ")}\uFF08\u5747\u672A\u547D\u4E2D\uFF09`:"";return {content:[{type:"text",text:`\u{1F9ED} \u5C5E\u6027\u4FEE\u6539\u8FFD\u8E2A: ${t}${n?`.${n}`:".*"}
357
- \u672A\u627E\u5230\u5339\u914D\u8BED\u53E5${E}
358
- \u8FC7\u6EE4: file_path=${r||"*"}`}]}}let g=[`\u{1F9ED} \u5C5E\u6027\u4FEE\u6539\u8FFD\u8E2A: ${t}${n?`.${n}`:".*"}`,`\u8FC7\u6EE4: file_path=${r||"*"}`];if(d.length>0){let E=u.map(y=>y.alias).filter(y=>y!==t).join(", "),h=p.map(y=>y.alias).filter(y=>y!==t).join(", ");E&&g.push(`\u26A1 \u5F15\u7528\u522B\u540D: ${E}\uFF08\u901A\u8FC7 let alias = this.${t} \u5C55\u5F00\uFF09`),h&&g.push(`\u26A1 \u89E3\u6784\u522B\u540D: ${h}\uFF08\u901A\u8FC7 const { ${t}: alias } \u5C55\u5F00\uFF09`);}return g.push(`\u547D\u4E2D: ${m.length} \u5904`,""),m.forEach((E,h)=>{g.push(`${h+1}. [${E.kind}] \u{1F4C4} ${E.filePath}:L${E.line}`),g.push(` ${E.text}`);}),{content:[{type:"text",text:g.join(`
359
- `)}]}}),l.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
504
+ \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(be),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:n,project_path:s,file_path:r,limit:i})=>{let a=performance.now(),{db:c}=e.getContext(s),l=c.listFiles(r),u=Math.min(300,Math.max(1,i||80)),p=bn(l,t,20),d=En(l,t,20),h=[...new Set([...p.map(y=>y.alias),...d.map(y=>y.alias)].filter(y=>y!==t))],f=[t,...h],m=at(l,t,n,u);for(let y of h)m.push(...at(l,y,n,Math.floor(u/2)));if(m.length===0){let y="(?:=|\\+=|-=|\\*=|/=|%=|\\|=|&=|\\^=|&&=|\\|\\|=|\\?\\?=)",N=[];for(let T of f){let R=je(T);if(n){let _=je(n);N.push({kind:"dot",regex:new RegExp(`\\b${R}\\.${_}\\s*${y}`)},{kind:"bracket",regex:new RegExp(`\\b${R}\\s*\\[(?:'${_}'|"${_}")\\]\\s*${y}`)},{kind:"delete",regex:new RegExp(`\\bdelete\\s+${R}\\.(?:${_})\\b`)});}else N.push({kind:"dot",regex:new RegExp(`\\b${R}\\.[A-Za-z_$][\\w$]*\\s*${y}`)},{kind:"bracket",regex:new RegExp(`\\b${R}\\s*\\[(?:'[^']+'|"[^"]+")\\]\\s*${y}`)},{kind:"delete",regex:new RegExp(`\\bdelete\\s+${R}\\.[A-Za-z_$][\\w$]*\\b`)});}m=we(l,N,u);}let b=Math.round((performance.now()-a)*100)/100;if(m.length===0){let y=h.length>0?`
505
+ \u522B\u540D\u5C55\u5F00: ${h.join(", ")}\uFF08\u5747\u672A\u547D\u4E2D\uFF09`:"",N=W({durationMs:b,resultCount:0,backend:"ast_scan"});return {content:[{type:"text",text:`\u{1F9ED} \u5C5E\u6027\u4FEE\u6539\u8FFD\u8E2A: ${t}${n?`.${n}`:".*"}
506
+ \u672A\u627E\u5230\u5339\u914D\u8BED\u53E5${y}
507
+ \u8FC7\u6EE4: file_path=${r||"*"}
508
+
509
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
510
+ ${U(N)}`}]}}let g=[`\u{1F9ED} \u5C5E\u6027\u4FEE\u6539\u8FFD\u8E2A: ${t}${n?`.${n}`:".*"}`,`\u8FC7\u6EE4: file_path=${r||"*"}`];if(h.length>0){let y=p.map(T=>T.alias).filter(T=>T!==t).join(", "),N=d.map(T=>T.alias).filter(T=>T!==t).join(", ");y&&g.push(`\u26A1 \u5F15\u7528\u522B\u540D: ${y}\uFF08\u901A\u8FC7 let alias = this.${t} \u5C55\u5F00\uFF09`),N&&g.push(`\u26A1 \u89E3\u6784\u522B\u540D: ${N}\uFF08\u901A\u8FC7 const { ${t}: alias } \u5C55\u5F00\uFF09`);}g.push(`\u547D\u4E2D: ${m.length} \u5904`,""),m.forEach((y,N)=>{g.push(`${N+1}. [${y.kind}] \u{1F4C4} ${y.filePath}:L${y.line}`),g.push(` ${y.text}`);});let E=W({durationMs:b,resultCount:m.length,backend:"ast_scan"});return g.push(`
511
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
512
+ ${U(E)}`),{content:[{type:"text",text:g.join(`
513
+ `)}]}}),o.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
360
514
  \u793A\u4F8B:
361
515
  - \u627E\u6240\u6709\u64CD\u4F5C localStorage \u7684\u51FD\u6570: { category: "storage" }
362
516
  - \u627E\u5199\u5165 localStorage \u7684: { api_name: "localStorage", operation: "setItem" }
363
517
  - \u627E\u53D1\u8BF7\u6C42\u7684: { category: "network" }
364
518
  - \u627E\u8DEF\u7531\u8DF3\u8F6C\u7684: { category: "router" }
365
519
  - \u6309 key \u540D\u641C\u7D22: { keyword: "cacheData" }
366
- project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({project_path:z$1.string().optional().describe(Q),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:n,api_name:s,operation:r,keyword:o,file_path:i})=>{let{db:a}=e.getContext(t),u=new ye(a).searchByBehavior({category:n,apiName:s,operation:r,keyword:o,filePath:i}),p=new Set(["localStorage","sessionStorage","cookie"]);if(s||(u=u.filter(m=>m.category!=="storage"||p.has(m.apiName.toLowerCase()))),u.length===0)return {content:[{type:"text",text:`\u{1F3F7}\uFE0F \u672A\u627E\u5230\u5339\u914D\u7684\u884C\u4E3A
367
- \u8FC7\u6EE4\u6761\u4EF6: ${JSON.stringify({category:n,api_name:s,operation:r,keyword:o,file_path:i})}`}]};let d=new Map;for(let m of u){let g=`${m.category}:${m.apiName}`;d.has(g)||d.set(g,[]),d.get(g).push(m);}let f=[`\u{1F3F7}\uFE0F \u884C\u4E3A\u641C\u7D22\u7ED3\u679C \u2014 ${u.length} \u6761
368
- `];for(let[m,g]of d){let[E,h]=m.split(":"),y=new Map;for(let S of g)y.has(S.operation)||y.set(S.operation,[]),y.get(S.operation).push(S);f.push(`\u{1F4C2} ${E} \u2192 ${h}:`);for(let[S,b]of y){f.push(` ${S}:`);let T=new Map;for(let v of b){let C=`${v.symbolName}|${v.filePath}`;T.has(C)||T.set(C,{item:v,callLines:[]}),T.get(C).callLines.push(v.line);}for(let{item:v,callLines:C}of T.values()){let P=v.detail?` key="${v.detail}"`:"",O=C.length>1?` \xD7${C.length} (L${C.join(", L")})`:` L${C[0]||v.startLine}`;f.push(` \u2022 ${v.symbolName}${P}${O} \u{1F4C4} ${v.filePath}:${le(v.startLine,v.endLine)}`);}}f.push("");}return {content:[{type:"text",text:f.join(`
369
- `)}]}}),l.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(Q),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:n,file_path:s,direction:r,arg_keyword:o})=>{let{db:i}=e.getContext(n),a=i.getSymbolByName(t,s),c=[`\u{1F4CA} ${t} \u7684\u8C03\u7528\u56FE\u8C31
370
- `];if(r==="callers"||r==="both"){let u=i.getCallers(t,s,o);if(c.push(`\u2B06\uFE0F \u88AB\u8C03\u7528 (${u.length} \u5904):`),u.length===0)c.push(" \uFF08\u672A\u627E\u5230\u8C03\u7528\u8005\uFF09");else for(let p of u){let d=p.args?` \u53C2\u6570: "${p.args}"`:"",f=p.call_type==="template_event"?" \u{1F5BC}\uFE0F [\u6A21\u677F\u4E8B\u4EF6\u5165\u53E3]":p.call_type==="jsx_event"?" \u269B\uFE0F [JSX\u4E8B\u4EF6\u5165\u53E3]":"";c.push(` \u2022 ${p.caller_name} [${p.category}]${f} \u{1F4C4} ${p.file_path}:L${p.start_line}${d}`);}c.push("");}if((r==="callees"||r==="both")&&a){let u=i.getCallees(a.id);if(c.push(`\u2B07\uFE0F \u8C03\u7528\u4E86 (${u.length} \u4E2A):`),u.length===0)c.push(" \uFF08\u672A\u5206\u6790\u5230\u8C03\u7528\u5173\u7CFB\uFF09");else for(let p of u){let d=p.args?`("${p.args}")`:"";c.push(` \u2022 ${p.callee_name}${d} [${p.call_type}] L${p.line_number}`);}c.push("");}if(a){let{behaviors:u}=i.getFileOutline(a.file_path),p=u.filter(d=>d.symbol_id===a.id);if(p.length>0){c.push("\u{1F4E6} \u5916\u90E8\u72B6\u6001\u64CD\u4F5C:");for(let d of p){let f=d.detail?` ("${d.detail}")`:"";c.push(` \u2022 ${d.api_name}.${d.operation}${f} [${d.category}] L${d.line_number}`);}}}return {content:[{type:"text",text:c.join(`
371
- `)}]}}),l.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(Q),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:n,file_path:s})=>{let{db:r}=e.getContext(n),o=r.getCallers(t,s),i=r.getSymbolByName(t,s),{behaviors:a}=i?r.getFileOutline(i.file_path):{behaviors:[]},c=i?a.filter(f=>f.symbol_id===i.id):[],u=o.length===0?"\u{1F7E2}":o.length<=3?"\u{1F7E1}":"\u{1F534}",p=o.length===0?"\u4F4E":o.length<=3?"\u4E2D":"\u9AD8",d=[`\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: ${p} (${o.length} \u5904\u76F4\u63A5\u8C03\u7528)`,""];if(o.length>0?(d.push("\u{1F534} \u76F4\u63A5\u5F71\u54CD:"),o.forEach((f,m)=>{let g=f.call_type==="template_event"?" \u{1F5BC}\uFE0F [\u6A21\u677F\u4E8B\u4EF6\u5165\u53E3]":f.call_type==="jsx_event"?" \u269B\uFE0F [JSX\u4E8B\u4EF6\u5165\u53E3]":"";d.push(` ${m+1}. ${f.caller_name} [${f.category}]${g} \u{1F4C4} ${f.file_path}:L${f.start_line}`);}),d.push("")):d.push(`\u2705 \u65E0\u8C03\u7528\u8005\uFF0C\u5F71\u54CD\u8303\u56F4\u53EF\u63A7
372
- `),c.length>0){d.push("\u{1F4E6} \u5916\u90E8\u72B6\u6001\u5F71\u54CD:");for(let f of c)d.push(` \u2022 ${f.api_name}.${f.operation}${f.detail?` key="${f.detail}"`:""} [${f.category}]`);d.push(`
373
- \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:d.join(`
374
- `)}]}}),l.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
375
- \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(Q),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:n})=>{if(n){let p=e.listProjects();if(p.length===0)return {content:[{type:"text",text:`\u{1F4CB} \u5F53\u524D\u6CA1\u6709\u5DF2\u7D22\u5F15\u7684\u9879\u76EE
376
-
377
- \u4F7F\u7528 skimmer_index_project({ project_path: "/your/project" }) \u5F00\u59CB\u7D22\u5F15`}]};let d=[`\u{1F4CB} \u5DF2\u7D22\u5F15\u7684\u9879\u76EE (${p.length} \u4E2A):
378
- `];return p.forEach((f,m)=>{d.push(`${m+1}. ${f.root}`),d.push(` \u6570\u636E\u5E93: ${f.dbPath}`);}),{content:[{type:"text",text:d.join(`
379
- `)}]}}let{db:s,projectRoot:r}=e.getContext(t),o=s.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} ${r}`,"",`\u{1F4C8} \u6574\u4F53: \u6587\u4EF6 ${o.fileCount} | \u7B26\u53F7 ${o.symbolCount} | \u884C\u4E3A\u6807\u7B7E ${o.behaviorCount} | \u8C03\u7528\u5173\u7CFB ${o.relationCount}`,""],a=o.frameworkBreakdown;if(a?.length){let p={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 d of a)i.push(` ${p[d.framework]||d.framework}: ${d.count} \u4E2A`);i.push("");}let c=o.topFiles;c?.length&&(i.push("\u{1F5C2}\uFE0F Top 10 \u6700\u5927\u6587\u4EF6:"),c.forEach((p,d)=>i.push(` ${d+1}. ${p.path} (${p.line_count} \u884C, ${p.symbol_count} \u7B26\u53F7)`)),i.push(""));let u=o.behaviorStats;if(u?.length){let p={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 d of u)i.push(` ${p[d.category]||d.category}: ${d.count} \u5904`);i.push("");}return i.push(`\u{1F4BD} \u6570\u636E\u5E93: ${Math.round(o.dbSize/1024)} KB`),{content:[{type:"text",text:i.join(`
380
- `)}]}}),l.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
520
+ project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({project_path:z$1.string().optional().describe(be),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:n,api_name:s,operation:r,keyword:i,file_path:a})=>{let c=performance.now(),{db:l}=e.getContext(t),p=new De(l).searchByBehavior({category:n,apiName:s,operation:r,keyword:i,filePath:a}),d=new Set(["localStorage","sessionStorage","cookie"]);s||(p=p.filter(g=>g.category!=="storage"||d.has(g.apiName.toLowerCase())));let h=Math.round((performance.now()-c)*100)/100,f=W({durationMs:h,resultCount:p.length,backend:"indexed"});if(p.length===0)return {content:[{type:"text",text:`\u{1F3F7}\uFE0F \u672A\u627E\u5230\u5339\u914D\u7684\u884C\u4E3A
521
+ \u8FC7\u6EE4\u6761\u4EF6: ${JSON.stringify({category:n,api_name:s,operation:r,keyword:i,file_path:a})}
522
+
523
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
524
+ ${U(f)}`}]};let m=new Map;for(let g of p){let E=`${g.category}:${g.apiName}`;m.has(E)||m.set(E,[]),m.get(E).push(g);}let b=[`\u{1F3F7}\uFE0F \u884C\u4E3A\u641C\u7D22\u7ED3\u679C \u2014 ${p.length} \u6761
525
+ `];for(let[g,E]of m){let[y,N]=g.split(":"),T=new Map;for(let R of E)T.has(R.operation)||T.set(R.operation,[]),T.get(R.operation).push(R);b.push(`\u{1F4C2} ${y} \u2192 ${N}:`);for(let[R,_]of T){b.push(` ${R}:`);let x=new Map;for(let A of _){let k=`${A.symbolName}|${A.filePath}`;x.has(k)||x.set(k,{item:A,callLines:[]}),x.get(k).callLines.push(A.line);}for(let{item:A,callLines:k}of x.values()){let I=A.detail?` key="${A.detail}"`:"",j=k.length>1?` \xD7${k.length} (L${k.join(", L")})`:` L${k[0]||A.startLine}`;b.push(` \u2022 ${A.symbolName}${I}${j} \u{1F4C4} ${A.filePath}:${Le(A.startLine,A.endLine)}`);}}b.push("");}return b.push(`\u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
526
+ ${U(f)}`),{content:[{type:"text",text:b.join(`
527
+ `)}]}}),o.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(be),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:n,file_path:s,direction:r,arg_keyword:i})=>{let a=performance.now(),{db:c}=e.getContext(n),l=c.getSymbolByName(t,s),u=[`\u{1F4CA} ${t} \u7684\u8C03\u7528\u56FE\u8C31
528
+ `],p=0,d=0,h=[],f=[];if(r==="callers"||r==="both"){if(h=c.getCallers(t,s,i),p+=h.length,d+=h.filter(y=>y.edge_kind==="precise").length,u.push(`\u2B06\uFE0F \u88AB\u8C03\u7528 (${h.length} \u5904):`),h.length===0)u.push(" \uFF08\u672A\u627E\u5230\u8C03\u7528\u8005\uFF09");else {let y={method_call:"",template_event:"\u{1F5BC}\uFE0F",jsx_event:"\u269B\uFE0F",hook_call:"\u{1FA9D}",import_call:"\u{1F4E5}",router_call:"\u{1F6E3}\uFE0F",store_dispatch:"\u{1F4E6}",store_commit:"\u{1F4E6}"};for(let N of h){let T=N.args?` \u53C2\u6570: "${N.args}"`:"",R=N.source_kind||"",_=N.edge_kind||"",x=y[R]?` ${y[R]}`:"",A=_==="precise"?" [\u{1F3AF}precise]":"";u.push(` \u2022 ${N.caller_name} [${N.category}]${x}${A} \u{1F4C4} ${N.file_path}:L${N.start_line}${T}`);}}u.push("");}if((r==="callees"||r==="both")&&l){if(f=c.getCallees(l.id),p+=f.length,d+=f.filter(y=>y.edge_kind==="precise").length,u.push(`\u2B07\uFE0F \u8C03\u7528\u4E86 (${f.length} \u4E2A):`),f.length===0)u.push(" \uFF08\u672A\u5206\u6790\u5230\u8C03\u7528\u5173\u7CFB\uFF09");else for(let y of f){let N=y.args?`("${y.args}")`:"",R=(y.edge_kind||"")==="precise"?" [\u{1F3AF}precise]":"";u.push(` \u2022 ${y.callee_name}${N} [${y.call_type}]${R} L${y.line_number}`);}u.push("");}if(l){let{behaviors:y}=c.getFileOutline(l.file_path),N=y.filter(T=>T.symbol_id===l.id);if(N.length>0){u.push("\u{1F4E6} \u5916\u90E8\u72B6\u6001\u64CD\u4F5C:");for(let T of N){let R=T.detail?` ("${T.detail}")`:"";u.push(` \u2022 ${T.api_name}.${T.operation}${R} [${T.category}] L${T.line_number}`);}}}let m=Math.round((performance.now()-a)*100)/100,b=d>0?"precise":"heuristic",g=[];b==="heuristic"&&p>0&&g.push('\u5F53\u524D\u7ED3\u679C\u5747\u4E3A\u542F\u53D1\u5F0F\u5206\u6790\uFF0C\u4F7F\u7528 skimmer_index_project({ precision_mode: "precise" }) \u53EF\u83B7\u5F97\u8DE8\u6587\u4EF6 import/export \u7CBE\u786E\u7ED1\u5B9A');let E=W({durationMs:m,resultCount:p,backend:"indexed",precisionEffective:b,precisionWarnings:g.length>0?g:void 0});return u.push(`
529
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
530
+ ${U(E)}`),{content:[{type:"text",text:u.join(`
531
+ `)}]}}),o.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(be),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:n,file_path:s})=>{let r=performance.now(),{db:i}=e.getContext(n),a=i.getCallers(t,s),c=i.getSymbolByName(t,s),{behaviors:l}=c?i.getFileOutline(c.file_path):{behaviors:[]},u=c?l.filter(g=>g.symbol_id===c.id):[],p=a.length===0?"\u{1F7E2}":a.length<=3?"\u{1F7E1}":"\u{1F534}",d=a.length===0?"\u4F4E":a.length<=3?"\u4E2D":"\u9AD8",h=[`\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",`${p} \u98CE\u9669\u7B49\u7EA7: ${d} (${a.length} \u5904\u76F4\u63A5\u8C03\u7528)`,""],f={method_call:"\u{1F4DE} \u65B9\u6CD5\u8C03\u7528",template_event:"\u{1F5BC}\uFE0F \u6A21\u677F\u4E8B\u4EF6",jsx_event:"\u269B\uFE0F JSX\u4E8B\u4EF6",hook_call:"\u{1FA9D} Hook\u8C03\u7528",import_call:"\u{1F4E5} \u5BFC\u5165\u8C03\u7528",router_call:"\u{1F6E3}\uFE0F \u8DEF\u7531",store_dispatch:"\u{1F4E6} Store",store_commit:"\u{1F4E6} Commit"};if(a.length>0?(h.push("\u{1F534} \u76F4\u63A5\u5F71\u54CD:"),a.forEach((g,E)=>{let y=g.source_kind||"",N=f[y]?` ${f[y]}`:"";h.push(` ${E+1}. ${g.caller_name} [${g.category}]${N} \u{1F4C4} ${g.file_path}:L${g.start_line}`);}),h.push("")):h.push(`\u2705 \u65E0\u8C03\u7528\u8005\uFF0C\u5F71\u54CD\u8303\u56F4\u53EF\u63A7
532
+ `),c){let g=i.getFileDependencies(c.file_path,"to");if(g.length>0){h.push(`\u{1F4C2} \u6587\u4EF6\u4F9D\u8D56 (${g.length} \u4E2A\u6587\u4EF6 import \u4E86\u6B64\u6587\u4EF6):`);let E={import:"\u{1F4E5}",re_export:"\u{1F504}",component_ref:"\u{1F9E9}",store_ref:"\u{1F4E6}",api_ref:"\u{1F310}"};g.slice(0,10).forEach(y=>{h.push(` ${E[y.dependency_kind]||"\u2022"} ${y.from_file} (${y.dependency_kind})`);}),h.push("");}}if(u.length>0){h.push("\u{1F4E6} \u5916\u90E8\u72B6\u6001\u5F71\u54CD:");for(let g of u)h.push(` \u2022 ${g.api_name}.${g.operation}${g.detail?` key="${g.detail}"`:""} [${g.category}]`);h.push(`
533
+ \u26A0\uFE0F \u4FEE\u6539\u65F6\u6CE8\u610F\u5916\u90E8\u72B6\u6001\u7684\u8BFB\u5199\u683C\u5F0F\u4FDD\u6301\u4E00\u81F4`);}let m=Math.round((performance.now()-r)*100)/100,b=W({durationMs:m,resultCount:a.length,backend:"indexed"});return h.push(`
534
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
535
+ ${U(b)}`),{content:[{type:"text",text:h.join(`
536
+ `)}]}}),o.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
381
537
 
382
538
  \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
383
539
  - "xxx \u662F\u4ECE\u54EA\u91CC\u6765\u7684\uFF1F" / "xxx \u662F\u600E\u4E48\u8D4B\u503C\u7684\uFF1F"
@@ -395,20 +551,39 @@ project_path \u53EF\u7701\u7565\u3002`,inputSchema:z$1.object({project_path:z$1.
395
551
  \u65E7\u65B9\u5F0F: trace_assignments \u2192 find_symbol \u2192 get_code_slice \u2192 find_by_behavior \u2192 trace_key_flow
396
552
  \u65B0\u65B9\u5F0F: skimmer_trace_data_lifecycle({ variable: "xxx" }) \u2190 \u76F4\u63A5\u5F97\u5230\u5168\u90E8
397
553
 
398
- 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(Q),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:n,file_path:s,storage_api:r,max_depth:o,limit:i})=>{let{db:a}=e.getContext(n),c=Math.min(5,Math.max(1,o||2)),u=Math.min(120,Math.max(1,i||40)),p=a.listFiles(s),d="";try{let N=s?p:p.slice(0,5),k=[];for(let _ of N){if(!_.abs_path||!F.existsSync(_.abs_path))continue;let L=F.statSync(_.abs_path),R=a.getFileMeta(_.path);if(!R)continue;(R.mtime>0&&L.mtimeMs>R.mtime||R.fileSize>0&&L.size!==R.fileSize)&&k.push(_.path);}k.length>0&&(d=`\u26A0\uFE0F [\u7D22\u5F15\u5DF2\u8FC7\u671F] \u4EE5\u4E0B\u6587\u4EF6\u5DF2\u4FEE\u6539\u4F46\u7D22\u5F15\u672A\u66F4\u65B0\uFF0C\u2462 \u53C2\u6570\u4F20\u9012 \u548C \u2464 storage \u94FE\u8DEF\u7684\u884C\u53F7\u53EF\u80FD\u504F\u79FB:
399
- `+k.slice(0,3).map(_=>` \u2022 ${_}`).join(`
554
+ 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(be),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:n,file_path:s,storage_api:r,max_depth:i,limit:a})=>{let c=performance.now(),{db:l}=e.getContext(n),u=Math.min(5,Math.max(1,i||2)),p=Math.min(120,Math.max(1,a||40)),d=l.listFiles(s),h="",f=mn(l,d,s?d.length:5);f.stale&&(h=`\u26A0\uFE0F [\u7D22\u5F15\u5DF2\u8FC7\u671F] \u4EE5\u4E0B\u6587\u4EF6\u5DF2\u4FEE\u6539\u4F46\u7D22\u5F15\u672A\u66F4\u65B0\uFF0C\u2462 \u53C2\u6570\u4F20\u9012 \u548C \u2464 storage \u94FE\u8DEF\u7684\u884C\u53F7\u53EF\u80FD\u504F\u79FB:
555
+ `+f.staleFilePaths.slice(0,3).map(S=>` \u2022 ${S}`).join(`
400
556
  `)+`
401
557
  \u5EFA\u8BAE: skimmer_index_project({ force: true })
402
- `);}catch{}let f=Wt(p,t,20),m=[...new Set(f.map(N=>N.alias).filter(N=>N!==t))],g=Dt(p,t,20),E=[...new Set(g.map(N=>N.alias).filter(N=>N!==t))],h=[...new Set([...m,...E])],S=[t,...h],b=a.exactSearch(t,"state",void 0,s||void 0),T={vue2:"Vue2 data()",vue3:"Vue3 ref/reactive",react:"React useState/useRef"},v=b.filter(N=>N.default_value!=null).map(N=>({filePath:N.file_path,line:N.start_line,kind:`data_init(${T[N.framework]||N.framework})`,text:`${N.name}: ${N.default_value} \u2190 \u58F0\u660E\u521D\u59CB\u5316`})),C=ot(p,t,false,u);for(let N of h)C.push(...ot(p,N,false,Math.floor(u/2)));let P=C.length===0?de(p,Ot(t,false),u):[],O=new Map;for(let N of [...v,...C.length>0?C:P]){let k=`${N.filePath}:${N.line}`;O.has(k)||O.set(k,N);}let M=[...O.values()],ae=Fe(p,t,void 0,u);for(let N of h)ae.push(...Fe(p,N,void 0,Math.floor(u/2)));let Kt=ae.length===0?de(p,[{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):[],Ee=ae.length>0?ae:Kt,ne=a.findRelationsByArgKeyword(t,s,u);for(let N of h)ne.push(...a.findRelationsByArgKeyword(N,s,Math.floor(u/2)));let it=[],at=[],ct=[];for(let N of S){let k=be(N),_=/^[a-zA-Z_$][\w$]*$/.test(N)?"\\b":"";it.push({kind:"template",regex:new RegExp(`(?::\\w+|v-model|v-if|v-show|@\\w+)="[^"]*${_}${k}${_}|\\{\\{[^}]*${_}${k}${_}[^}]*\\}\\}`)},{kind:"return",regex:new RegExp(`\\breturn\\b[^=]*${_}${k}${_}`)},{kind:"watch",regex:new RegExp(`watch[^(]*['"]\\.?${k}['"]`)},{kind:"computed_read",regex:new RegExp(`=>[^=]*${_}${k}${_}|return[^=]*${_}${k}${_}`)},{kind:"arg_usage",regex:new RegExp(`\\(\\s*[^)]*${_}${k}${_}[^)]*\\)`)}),at.push(`${_}${k}${_}\\s*(?:=|\\+=|-=|\\*=|\\/=)(?!=)|\\b(?:const|let|var)\\s+${k}\\b`),ct.push(`${_}${k}${_}\\.\\w+\\s*(?:=|\\+=|-=)(?!=)|${_}${k}${_}\\s*\\[`);}let Vt=de(p,it,u),zt=new RegExp(at.join("|")),Xt=new RegExp(ct.join("|")),Ne=Vt.filter(N=>!zt.test(N.text)&&!Xt.test(N.text)),He=new Map,Jt=(N,k)=>{if(!He.has(N)){let{behaviors:L}=a.getFileOutline(N),R=new Map;for(let I of L){let K=String(I.symbol_name||"");R.has(K)||R.set(K,[]),R.get(K).push(I);}He.set(N,R);}return (He.get(N)?.get(k)||[]).filter(L=>String(L.category||"")!=="storage"?false:r==="all"?true:String(L.api_name||"").toLowerCase()===r.toLowerCase())},Gt=(N,k)=>{let _=[],L=[{name:N,filePath:k,path:[N],level:0}],R=new Set([`${k}::${N}`]);for(;L.length>0;){let I=L.shift(),K=Jt(I.filePath,I.name);if(K.length>0){_.push({path:I.path,file:I.filePath,behaviors:K});continue}if(I.level>=c)continue;let D=a.getSymbolByName(I.name,I.filePath);if(D||(D=a.getSymbolByName(I.name)),!D)continue;let se=String(D.file_path||D.abs_path||I.filePath),Se=a.getCallees(D.id);for(let Be of Se){let X=String(Be.callee_name||"");if(!X||X.startsWith("$"))continue;let lt=`${se}::${X}`;R.has(lt)||(R.add(lt),L.push({name:X,filePath:se,path:[...I.path,X],level:I.level+1}));}}return _},Yt=h.length>0?`
403
- \u{1F517} \u53D1\u73B0\u522B\u540D: ${h.map(N=>`"${N}"`).join(", ")}\uFF08\u5DF2\u4E00\u5E76\u8FFD\u8E2A\u5C5E\u6027\u4FEE\u6539\uFF09`:"",ce=[];g.length>0&&(ce.push(` \u{1F517} \u5F15\u7528\u522B\u540D\u4F20\u64AD (${g.length} \u5904) \u2014 \u8FD9\u4E9B\u5C40\u90E8\u53D8\u91CF\u662F "${t}" \u7684\u5F15\u7528\uFF0C\u5176\u5C5E\u6027\u4FEE\u6539\u4E5F\u88AB\u8FFD\u8E2A:`),g.slice(0,10).forEach(N=>{let _=p.find(I=>I.path===N.filePath)?.abs_path||N.abs_path,L=Oe("alias_ref"),R=_?rt(_,N.line,2):{snippet:""};ce.push(` \u{1F4C4} ${N.filePath}:L${N.line} "${N.alias}" = ... ${L}`),ce.push(` ${N.text}`),R.snippet&&ce.push(R.snippet);}));let $=[`\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=${s||"*"} storage_api=${r} depth=${c}${Yt}`,""];if(d&&$.push(d),$.push(`\u2460 \u58F0\u660E & \u6574\u4F53\u8D4B\u503C (${M.length} \u5904)`),M.length===0)$.push(" \uFF08\u672A\u627E\u5230\uFF09");else {let N={init:[],cache:[],user:[],unknown:[]};for(let _ of M){let L=jt(_.text,_.line);N[L].push(_);}let k=["init","cache","user","unknown"];for(let _ of k){let L=N[_];!L||L.length===0||($.push(` \u25B8 ${Mt[_]} (${L.length} \u5904)`),L.slice(0,8).forEach(R=>{let I=h.includes(R.text.split("=")[0]?.trim().replace(/^(?:const|let|var)\s+/,"")||""),K=Oe(R.kind,I);$.push(` \u{1F4C4} ${R.filePath}:L${R.line} [${R.kind}] ${K}`),$.push(` ${R.text}`);}));}ce.length>0&&($.push(""),$.push(...ce));}if($.push(""),$.push(`\u2461 \u5C5E\u6027\u4FEE\u6539 (${Ee.length} \u5904)`),Ee.length===0)$.push(' \uFF08\u672A\u627E\u5230 object.prop \u6216 object["prop"] \u5199\u5165\uFF09'),h.length>0&&$.push(` \u2139\uFE0F \u5DF2\u8FFD\u8E2A\u522B\u540D: ${h.map(N=>`"${N}"`).join(", ")} \u7684\u5C5E\u6027\u4FEE\u6539\uFF08\u5982\u4ECD\u672A\u627E\u5230\uFF0C\u8868\u793A\u771F\u6B63\u65E0\u95F4\u63A5\u5199\u5165\uFF09`);else {let N={init:[],cache:[],user:[],unknown:[]};for(let _ of Ee){let L=jt(_.text,_.line);N[L].push(_);}let k=["init","cache","user","unknown"];for(let _ of k){let L=N[_];!L||L.length===0||($.push(` \u25B8 ${Mt[_]} (${L.length} \u5904)`),L.slice(0,8).forEach(R=>{let I=h.some(X=>R.text.startsWith(X)),K=Oe(R.kind,I),se=p.find(X=>X.path===R.filePath)?.abs_path||"",Se=se?rt(se,R.line,2):{snippet:""},Be=I?" \u{1F517}(via alias)":"";$.push(` \u{1F4C4} ${R.filePath}:L${R.line} [${R.kind}] ${K}${Be}`),Se.snippet&&$.push(Se.snippet);}));}}if($.push(""),$.push(`\u2462 \u4F5C\u4E3A\u53C2\u6570\u88AB\u4F20\u5165\u8C03\u7528 (${ne.length} \u5904)`),ne.length===0?$.push(" \uFF08\u672A\u53D1\u73B0\u4EE5\u8BE5\u53D8\u91CF\u4F5C\u4E3A\u53C2\u6570\u7684\u51FD\u6570\u8C03\u7528\uFF09"):ne.slice(0,20).forEach(N=>{let k=String(N.args||"");$.push(` \u{1F4C4} ${N.file_path}:L${N.line_number} ${N.caller_name} \u2192 ${N.callee_name} \u53C2\u6570: "${k}"`);}),$.push(""),$.push(`\u2463 \u8BFB\u53D6/\u4F7F\u7528 (${Ne.length} \u5904)`),Ne.length===0)$.push(" \uFF08\u672A\u53D1\u73B0 template \u7ED1\u5B9A / watch / computed / return \u4E2D\u7684\u5F15\u7528\uFF09");else {let N=new Map;for(let _ of Ne)N.has(_.kind)||N.set(_.kind,[]),N.get(_.kind).push(_);let k={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[_,L]of N)$.push(` \u25B8 ${k[_]||_}`),L.slice(0,8).forEach(R=>$.push(` \u{1F4C4} ${R.filePath}:L${R.line} ${R.text}`));}$.push("");let fe=0;$.push(`\u2464 Storage \u843D\u70B9\u8FFD\u8E2A (storage_api=${r}, depth=${c})`);let qt=r==="localStorage"?"localStorage":r==="sessionStorage"?"sessionStorage":"(?:localStorage|sessionStorage)",Zt=S.map(N=>({kind:"direct_storage",regex:new RegExp(`${qt}\\.(?:setItem|getItem|removeItem|clear)\\(.*?\\b${be(N)}\\b`)})),_e=de(p,Zt,u);if(_e.length>0&&(fe+=1,$.push(` \u843D\u70B9 [\u76F4\u63A5\u547D\u4E2D\u5B58\u50A8] ${Oe("direct_storage")}:`),_e.slice(0,15).forEach(N=>{let _=p.find(R=>R.path===N.filePath)?.abs_path||"",L=_?rt(_,N.line,2):{snippet:""};$.push(` \u{1F4C4} ${N.filePath}:L${N.line} ${N.text.trim()}`),L.snippet&&$.push(L.snippet);})),ne.length===0&&_e.length===0)$.push(" \uFF08\u672A\u53D1\u73B0\u76F4\u63A5 Storage \u64CD\u4F5C\uFF0C\u4E14\u65E0\u8C03\u7528\u5165\u53E3\u5C55\u5F00\u8FFD\u8E2A\uFF09");else {let N=new Map;for(let k of ne){let _=`${k.file_path}::${k.callee_name}`;N.has(_)||N.set(_,k);}for(let[,k]of N){let _=String(k.callee_name||""),L=String(k.file_path||""),R=Gt(_,L);R.length!==0&&(fe+=1,R.slice(0,3).forEach(I=>{let K=I.file!==L?` \u2197 \u8DE8\u6587\u4EF6: ${I.file}`:"";$.push(` \u94FE\u8DEF: ${I.path.join(" \u2192 ")}${K}`),I.behaviors.forEach(D=>{let se=D.detail?`("${String(D.detail)}")`:"";$.push(` \u843D\u70B9: ${D.api_name}.${D.operation}${se} [${D.category}] L${D.line_number}`);});}));}fe===0&&_e.length===0&&$.push(` \uFF08\u5728 depth=${c} \u5C42\u5185\u672A\u627E\u5230 storage \u5199\u5165\u94FE\u8DEF\uFF09`);}$.push(""),$.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");let Qt=h.length>0?` (\u542B ${h.length} \u4E2A\u522B\u540D: ${h.slice(0,3).map(N=>`"${N}"`).join(", ")})`:"";return $.push(`\u2705 \u6C47\u603B${Qt}:`),$.push(` \u2460 \u58F0\u660E/\u8D4B\u503C: ${M.length} \u5904`),$.push(` \u2461 \u5C5E\u6027\u4FEE\u6539: ${Ee.length} \u5904 (\u5DF2\u8FFD\u8E2A\u522B\u540D: ${h.map(N=>`"${N}"`).join(", ")||"\u65E0"})`),$.push(` \u2462 \u53C2\u6570\u4F20\u9012: ${ne.length} \u5904`),$.push(` \u2463 \u8BFB\u53D6\u5F15\u7528: ${Ne.length} \u5904`),$.push(` \u2464 storage: ${fe>0?`\u2713 \u53D1\u73B0\u5199\u5165\u94FE\u8DEF (${fe} \u6761)`:"\u2717 \u672A\u53D1\u73B0"}`),$.push(""),$.push("\u{1F4A1} \u6765\u6E90\u5206\u5C42\u8BF4\u660E: \u{1F331}\u521D\u59CB\u5316 = lifecycle/data | \u{1F4BE}\u7F13\u5B58\u56DE\u663E = storage\u8BFB/fetch | \u{1F5B1}\uFE0F\u7528\u6237\u4EA4\u4E92 = \u4E8B\u4EF6/watch"),$.push("\u{1F4CA} \u7F6E\u4FE1\u5EA6: \u25CF\u25CF\u25CF\u25CF\u25CF \u226590% \u25CF\u25CF\u25CF\u25CF\u25CB \u226580% \u25CF\u25CF\u25CF\u25CB\u25CB \u226570% \u25CF\u25CF\u25CB\u25CB\u25CB \u226560% \u9700\u4EBA\u5DE5\u9A8C\u8BC1\u884C\u53F7\u786E\u8BA4"),{content:[{type:"text",text:$.join(`
404
- `)}]}});}var ue=new ke,Ue=new McpServer({name:"frontend-code-skimmer",version:"0.1.0"});Ct(Ue,ue);Pt(Ue,ue);Bt(Ue,ue);async function Pn(){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}
405
- `);try{let{Indexer:n}=await Promise.resolve().then(()=>(tt(),wt)),{db:s,projectRoot:r}=ue.getContext(process.env.SKIMMER_PROJECT),o=new n(r,s),i=await o.indexProject();process.stderr.write(`[Frontend-Code-Skimmer] \u5B8C\u6210: ${i.indexedFiles} \u6587\u4EF6, ${i.totalSymbols} \u7B26\u53F7
406
- `);let a=await o.startWatcher();ue.registerWatcher(r,a),process.stderr.write(`[Frontend-Code-Skimmer] \u6587\u4EF6\u76D1\u542C\u5DF2\u542F\u52A8: ${r}
558
+ `);let m=En(d,t,20),b=[...new Set(m.map(S=>S.alias).filter(S=>S!==t))],g=bn(d,t,20),E=[...new Set(g.map(S=>S.alias).filter(S=>S!==t))],y=[...new Set([...b,...E])],T=[t,...y],R=l.exactSearch(t,"state",void 0,s||void 0),_={vue2:"Vue2 data()",vue3:"Vue3 ref/reactive",react:"React useState/useRef"},x=R.filter(S=>S.default_value!=null).map(S=>({filePath:S.file_path,line:S.start_line,kind:`data_init(${_[S.framework]||S.framework})`,text:`${S.name}: ${S.default_value} \u2190 \u58F0\u660E\u521D\u59CB\u5316`})),A=false,k=l.getAssignments(t,s,p),I=[];k.length>0?(I=k.map(S=>({filePath:S.file_path,line:S.line_number,kind:S.kind,text:S.text_snippet||"",sourceLayer:S.source_layer||void 0})),A=true):I=vt(d,t,false,p);for(let S of y){let C=l.getAssignments(S,s,Math.floor(p/2));C.length>0?I.push(...C.map(L=>({filePath:L.file_path,line:L.line_number,kind:L.kind,text:L.text_snippet||"",sourceLayer:L.source_layer||void 0}))):I.push(...vt(d,S,false,Math.floor(p/2)));}let j=I.length===0?we(d,gn(t,false),p):[],H=new Map;for(let S of [...x,...I.length>0?I:j]){let C=`${S.filePath}:${S.line}`;H.has(C)||H.set(C,S);}let ae=[...H.values()],ge=false,Se=l.getPropertyWrites(t,void 0,s,p),V=[];Se.length>0?(V=Se.map(S=>({filePath:S.file_path,line:S.line_number,kind:S.kind,text:S.text_snippet||"",sourceLayer:S.source_layer||void 0})),ge=true):V=at(d,t,void 0,p);for(let S of y){let C=l.getPropertyWrites(S,void 0,s,Math.floor(p/2));C.length>0?V.push(...C.map(L=>({filePath:L.file_path,line:L.line_number,kind:L.kind,text:L.text_snippet||"",sourceLayer:L.source_layer||void 0}))):V.push(...at(d,S,void 0,Math.floor(p/2)));}let ce=V.length===0?we(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`)}],p):[],B=V.length>0?V:ce,ne=l.findRelationsByArgKeyword(t,s,p);for(let S of y)ne.push(...l.findRelationsByArgKeyword(S,s,Math.floor(p/2)));let It=[],Ot=[],Pt=[];for(let S of T){let C=je(S),L=/^[a-zA-Z_$][\w$]*$/.test(S)?"\\b":"";It.push({kind:"template",regex:new RegExp(`(?::\\w+|v-model|v-if|v-show|@\\w+)="[^"]*${L}${C}${L}|\\{\\{[^}]*${L}${C}${L}[^}]*\\}\\}`)},{kind:"return",regex:new RegExp(`\\breturn\\b[^=]*${L}${C}${L}`)},{kind:"watch",regex:new RegExp(`watch[^(]*['"]\\.?${C}['"]`)},{kind:"computed_read",regex:new RegExp(`=>[^=]*${L}${C}${L}|return[^=]*${L}${C}${L}`)},{kind:"arg_usage",regex:new RegExp(`\\(\\s*[^)]*${L}${C}${L}[^)]*\\)`)}),Ot.push(`${L}${C}${L}\\s*(?:=|\\+=|-=|\\*=|\\/=)(?!=)|\\b(?:const|let|var)\\s+${C}\\b`),Pt.push(`${L}${C}${L}\\.\\w+\\s*(?:=|\\+=|-=)(?!=)|${L}${C}${L}\\s*\\[`);}let Ln=we(d,It,p),Rn=new RegExp(Ot.join("|")),kn=new RegExp(Pt.join("|")),$e=Ln.filter(S=>!Rn.test(S.text)&&!kn.test(S.text)),dt=new Map,wn=(S,C)=>{if(!dt.has(S)){let{behaviors:P}=l.getFileOutline(S),O=new Map;for(let D of P){let Z=String(D.symbol_name||"");O.has(Z)||O.set(Z,[]),O.get(Z).push(D);}dt.set(S,O);}return (dt.get(S)?.get(C)||[]).filter(P=>String(P.category||"")!=="storage"?false:r==="all"?true:String(P.api_name||"").toLowerCase()===r.toLowerCase())},vn=(S,C)=>{let L=[],P=[{name:S,filePath:C,path:[S],level:0}],O=new Set([`${C}::${S}`]);for(;P.length>0;){let D=P.shift(),Z=wn(D.filePath,D.name);if(Z.length>0){L.push({path:D.path,file:D.filePath,behaviors:Z});continue}if(D.level>=u)continue;let G=l.getSymbolByName(D.name,D.filePath);if(G||(G=l.getSymbolByName(D.name)),!G)continue;let _e=String(G.file_path||G.abs_path||D.filePath),We=l.getCallees(G.id);for(let ut of We){let le=String(ut.callee_name||"");if(!le||le.startsWith("$"))continue;let Ft=`${_e}::${le}`;O.has(Ft)||(O.add(Ft),P.push({name:le,filePath:_e,path:[...D.path,le],level:D.level+1}));}}return L},$n=y.length>0?`
559
+ \u{1F517} \u53D1\u73B0\u522B\u540D: ${y.map(S=>`"${S}"`).join(", ")}\uFF08\u5DF2\u4E00\u5E76\u8FFD\u8E2A\u5C5E\u6027\u4FEE\u6539\uFF09`:"",xe=[];g.length>0&&(xe.push(` \u{1F517} \u5F15\u7528\u522B\u540D\u4F20\u64AD (${g.length} \u5904) \u2014 \u8FD9\u4E9B\u5C40\u90E8\u53D8\u91CF\u662F "${t}" \u7684\u5F15\u7528\uFF0C\u5176\u5C5E\u6027\u4FEE\u6539\u4E5F\u88AB\u8FFD\u8E2A:`),g.slice(0,10).forEach(S=>{let L=d.find(D=>D.path===S.filePath)?.abs_path||S.abs_path,P=ot("alias_ref"),O=L?wt(L,S.line,2):{snippet:""};xe.push(` \u{1F4C4} ${S.filePath}:L${S.line} "${S.alias}" = ... ${P}`),xe.push(` ${S.text}`),O.snippet&&xe.push(O.snippet);}));let $=[`\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=${s||"*"} storage_api=${r} depth=${u}${$n}`,""];if(h&&$.push(h),$.push(`\u2460 \u58F0\u660E & \u6574\u4F53\u8D4B\u503C (${ae.length} \u5904)`),ae.length===0)$.push(" \uFF08\u672A\u627E\u5230\uFF09");else {let S={init:[],cache:[],user:[],unknown:[]};for(let L of ae){let P=L.sourceLayer||ee(L.text,L.line);S[P].push(L);}let C=["init","cache","user","unknown"];for(let L of C){let P=S[L];!P||P.length===0||($.push(` \u25B8 ${yn[L]} (${P.length} \u5904)`),P.slice(0,8).forEach(O=>{let D=y.includes(O.text.split("=")[0]?.trim().replace(/^(?:const|let|var)\s+/,"")||""),Z=ot(O.kind,D);$.push(` \u{1F4C4} ${O.filePath}:L${O.line} [${O.kind}] ${Z}`),$.push(` ${O.text}`);}));}xe.length>0&&($.push(""),$.push(...xe));}if($.push(""),$.push(`\u2461 \u5C5E\u6027\u4FEE\u6539 (${B.length} \u5904)`),B.length===0)$.push(' \uFF08\u672A\u627E\u5230 object.prop \u6216 object["prop"] \u5199\u5165\uFF09'),y.length>0&&$.push(` \u2139\uFE0F \u5DF2\u8FFD\u8E2A\u522B\u540D: ${y.map(S=>`"${S}"`).join(", ")} \u7684\u5C5E\u6027\u4FEE\u6539\uFF08\u5982\u4ECD\u672A\u627E\u5230\uFF0C\u8868\u793A\u771F\u6B63\u65E0\u95F4\u63A5\u5199\u5165\uFF09`);else {let S={init:[],cache:[],user:[],unknown:[]};for(let L of B){let P=L.sourceLayer||ee(L.text,L.line);S[P].push(L);}let C=["init","cache","user","unknown"];for(let L of C){let P=S[L];!P||P.length===0||($.push(` \u25B8 ${yn[L]} (${P.length} \u5904)`),P.slice(0,8).forEach(O=>{let D=y.some(le=>O.text.startsWith(le)),Z=ot(O.kind,D),_e=d.find(le=>le.path===O.filePath)?.abs_path||"",We=_e?wt(_e,O.line,2):{snippet:""},ut=D?" \u{1F517}(via alias)":"";$.push(` \u{1F4C4} ${O.filePath}:L${O.line} [${O.kind}] ${Z}${ut}`),We.snippet&&$.push(We.snippet);}));}}if($.push(""),$.push(`\u2462 \u4F5C\u4E3A\u53C2\u6570\u88AB\u4F20\u5165\u8C03\u7528 (${ne.length} \u5904)`),ne.length===0?$.push(" \uFF08\u672A\u53D1\u73B0\u4EE5\u8BE5\u53D8\u91CF\u4F5C\u4E3A\u53C2\u6570\u7684\u51FD\u6570\u8C03\u7528\uFF09"):ne.slice(0,20).forEach(S=>{let C=String(S.args||"");$.push(` \u{1F4C4} ${S.file_path}:L${S.line_number} ${S.caller_name} \u2192 ${S.callee_name} \u53C2\u6570: "${C}"`);}),$.push(""),$.push(`\u2463 \u8BFB\u53D6/\u4F7F\u7528 (${$e.length} \u5904)`),$e.length===0)$.push(" \uFF08\u672A\u53D1\u73B0 template \u7ED1\u5B9A / watch / computed / return \u4E2D\u7684\u5F15\u7528\uFF09");else {let S=new Map;for(let L of $e)S.has(L.kind)||S.set(L.kind,[]),S.get(L.kind).push(L);let C={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[L,P]of S)$.push(` \u25B8 ${C[L]||L}`),P.slice(0,8).forEach(O=>$.push(` \u{1F4C4} ${O.filePath}:L${O.line} ${O.text}`));}$.push("");let Ae=0;$.push(`\u2464 Storage \u843D\u70B9\u8FFD\u8E2A (storage_api=${r}, depth=${u})`);let Cn=r==="localStorage"?"localStorage":r==="sessionStorage"?"sessionStorage":"(?:localStorage|sessionStorage)",In=T.map(S=>({kind:"direct_storage",regex:new RegExp(`${Cn}\\.(?:setItem|getItem|removeItem|clear)\\(.*?\\b${je(S)}\\b`)})),Ue=we(d,In,p);if(Ue.length>0&&(Ae+=1,$.push(` \u843D\u70B9 [\u76F4\u63A5\u547D\u4E2D\u5B58\u50A8] ${ot("direct_storage")}:`),Ue.slice(0,15).forEach(S=>{let L=d.find(O=>O.path===S.filePath)?.abs_path||"",P=L?wt(L,S.line,2):{snippet:""};$.push(` \u{1F4C4} ${S.filePath}:L${S.line} ${S.text.trim()}`),P.snippet&&$.push(P.snippet);})),ne.length===0&&Ue.length===0)$.push(" \uFF08\u672A\u53D1\u73B0\u76F4\u63A5 Storage \u64CD\u4F5C\uFF0C\u4E14\u65E0\u8C03\u7528\u5165\u53E3\u5C55\u5F00\u8FFD\u8E2A\uFF09");else {let S=new Map;for(let C of ne){let L=`${C.file_path}::${C.callee_name}`;S.has(L)||S.set(L,C);}for(let[,C]of S){let L=String(C.callee_name||""),P=String(C.file_path||""),O=vn(L,P);O.length!==0&&(Ae+=1,O.slice(0,3).forEach(D=>{let Z=D.file!==P?` \u2197 \u8DE8\u6587\u4EF6: ${D.file}`:"";$.push(` \u94FE\u8DEF: ${D.path.join(" \u2192 ")}${Z}`),D.behaviors.forEach(G=>{let _e=G.detail?`("${String(G.detail)}")`:"";$.push(` \u843D\u70B9: ${G.api_name}.${G.operation}${_e} [${G.category}] L${G.line_number}`);});}));}Ae===0&&Ue.length===0&&$.push(` \uFF08\u5728 depth=${u} \u5C42\u5185\u672A\u627E\u5230 storage \u5199\u5165\u94FE\u8DEF\uFF09`);}$.push(""),$.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");let On=y.length>0?` (\u542B ${y.length} \u4E2A\u522B\u540D: ${y.slice(0,3).map(S=>`"${S}"`).join(", ")})`:"";$.push(`\u2705 \u6C47\u603B${On}:`),$.push(` \u2460 \u58F0\u660E/\u8D4B\u503C: ${ae.length} \u5904`),$.push(` \u2461 \u5C5E\u6027\u4FEE\u6539: ${B.length} \u5904 (\u5DF2\u8FFD\u8E2A\u522B\u540D: ${y.map(S=>`"${S}"`).join(", ")||"\u65E0"})`),$.push(` \u2462 \u53C2\u6570\u4F20\u9012: ${ne.length} \u5904`),$.push(` \u2463 \u8BFB\u53D6\u5F15\u7528: ${$e.length} \u5904`),$.push(` \u2464 storage: ${Ae>0?`\u2713 \u53D1\u73B0\u5199\u5165\u94FE\u8DEF (${Ae} \u6761)`:"\u2717 \u672A\u53D1\u73B0"}`),$.push(""),$.push("\u{1F4A1} \u6765\u6E90\u5206\u5C42\u8BF4\u660E: \u{1F331}\u521D\u59CB\u5316 = lifecycle/data | \u{1F4BE}\u7F13\u5B58\u56DE\u663E = storage\u8BFB/fetch | \u{1F5B1}\uFE0F\u7528\u6237\u4EA4\u4E92 = \u4E8B\u4EF6/watch"),$.push("\u{1F4CA} \u7F6E\u4FE1\u5EA6: \u25CF\u25CF\u25CF\u25CF\u25CF \u226590% \u25CF\u25CF\u25CF\u25CF\u25CB \u226580% \u25CF\u25CF\u25CF\u25CB\u25CB \u226570% \u25CF\u25CF\u25CB\u25CB\u25CB \u226560% \u9700\u4EBA\u5DE5\u9A8C\u8BC1\u884C\u53F7\u786E\u8BA4");let Pn=Math.round((performance.now()-c)*100)/100,Mn=ae.length+B.length+ne.length+$e.length+Ae,Mt=W({durationMs:Pn,resultCount:Mn,backend:A&&ge?"indexed":A||ge?"hybrid":"fallback_scan"});return f.stale&&(Mt.index_freshness=f),$.push(`
560
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
561
+ ${U(Mt)}`),{content:[{type:"text",text:$.join(`
562
+ `)}]}});}function xn(o,e){o.registerTool("skimmer_index_health",{title:"\u7D22\u5F15\u5065\u5EB7\u68C0\u67E5",description:`\u68C0\u67E5\u5F53\u524D\u9879\u76EE\u7D22\u5F15\u7684\u5065\u5EB7\u72B6\u6001\u3002
563
+ \u8FD4\u56DE: \u7D22\u5F15\u6587\u4EF6\u6570\u3001\u7B26\u53F7\u6570\u3001\u5173\u7CFB\u6570\u3001\u884C\u4E3A\u6570\u3001\u6700\u540E\u66F4\u65B0\u65F6\u95F4\u3001\u5931\u8D25\u6587\u4EF6\u3001watcher \u72B6\u6001\u3001\u6570\u636E\u5E93\u5927\u5C0F\u3002
564
+ project_path \u53EF\u7701\u7565\uFF08\u81EA\u52A8\u4F7F\u7528\u4E0A\u6B21\u7D22\u5F15\u7684\u9879\u76EE\uFF09\u3002`,inputSchema:z$1.object({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({project_path:t})=>{let n=performance.now(),{db:s,projectRoot:r}=e.getContext(t),i=s.getProjectStats(),a=(()=>{try{let y=s.getLastIndexedTime();return y?new Date(y).toISOString():"\u6682\u65E0\u7D22\u5F15\u6570\u636E"}catch{return "\u6682\u65E0\u7D22\u5F15\u6570\u636E"}})(),c=i.fileCount||0,l=i.symbolCount||0,u=e.hasWatcher(r),h=e.listProjects().find(y=>y.root===r)?.dbPath||"",f=i.dbSize||0,m={dbPath:h,indexedFiles:c,totalSymbols:l,totalRelations:i.relationCount||0,totalBehaviors:i.behaviorCount||0,lastIndexedAt:a,watcherActive:u,dbSizeBytes:f},b=Math.round((performance.now()-n)*100)/100,g=W({durationMs:b,resultCount:1,backend:"indexed"}),E=[`\u{1F3E5} \u7D22\u5F15\u5065\u5EB7\u68C0\u67E5 \u2014 ${r}`,"\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{1F4CA} \u7D22\u5F15\u7EDF\u8BA1:",` \u{1F4C1} \u5DF2\u7D22\u5F15\u6587\u4EF6: ${m.indexedFiles}`,` \u{1F523} \u7B26\u53F7\u6570: ${m.totalSymbols}`,` \u{1F517} \u8C03\u7528\u5173\u7CFB: ${m.totalRelations}`,` \u{1F3F7}\uFE0F \u884C\u4E3A\u6807\u7B7E: ${m.totalBehaviors}`,` \u{1F4C5} \u6700\u540E\u7D22\u5F15\u65F6\u95F4: ${m.lastIndexedAt}`,"","\u{1F50C} \u8FD0\u884C\u65F6\u72B6\u6001:",` \u{1F4C2} \u6587\u4EF6\u76D1\u542C: ${m.watcherActive?"\u2705 \u6D3B\u8DC3":"\u274C \u672A\u542F\u52A8"}`,` \u{1F4BE} \u6570\u636E\u5E93\u5927\u5C0F: ${Math.round(m.dbSizeBytes/1024)} KB`,` \u{1F4CD} \u6570\u636E\u5E93\u8DEF\u5F84: ${m.dbPath||"\uFF08\u5185\u5B58\uFF09"}`,"","\u{1F4A1} \u5EFA\u8BAE:"];return m.totalSymbols===0&&m.indexedFiles>0?E.push(" \u26A0\uFE0F \u6709\u6587\u4EF6\u4F46\u7B26\u53F7\u6570\u4E3A0 \u2014 \u53EF\u80FD\u9700\u8981\u8C03\u6574\u89E3\u6790\u89C4\u5219\u6216\u5F3A\u5236\u91CD\u5EFA"):m.indexedFiles===0?E.push(" \u274C \u5C1A\u672A\u7D22\u5F15 \u2014 \u8FD0\u884C skimmer_index_project \u5F00\u59CB\u7D22\u5F15"):E.push(" \u2705 \u7D22\u5F15\u72B6\u6001\u6B63\u5E38"),!m.watcherActive&&m.indexedFiles>0&&E.push(" \u{1F4A1} \u6587\u4EF6\u76D1\u542C\u672A\u542F\u52A8 \u2014 \u8FD0\u884C skimmer_index_project \u53EF\u81EA\u52A8\u5F00\u542F"),E.push(""),E.push("\u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500"),E.push(U(g)),{content:[{type:"text",text:E.join(`
565
+ `)}]}});}var ks="\u9879\u76EE\u6839\u76EE\u5F55\uFF08\u53EF\u7701\u7565\uFF0C\u4F7F\u7528\u4E0A\u6B21\u7D22\u5F15\u7684\u9879\u76EE\uFF09";function An(o,e){o.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
566
+ \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(ks),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:n})=>{let s=performance.now();if(n){let f=e.listProjects(),m=Math.round((performance.now()-s)*100)/100,b=W({durationMs:m,resultCount:f.length,backend:"indexed"});if(f.length===0)return {content:[{type:"text",text:`\u{1F4CB} \u5F53\u524D\u6CA1\u6709\u5DF2\u7D22\u5F15\u7684\u9879\u76EE
567
+
568
+ \u4F7F\u7528 skimmer_index_project({ project_path: "/your/project" }) \u5F00\u59CB\u7D22\u5F15
569
+
570
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
571
+ ${U(b)}`}]};let g=[`\u{1F4CB} \u5DF2\u7D22\u5F15\u7684\u9879\u76EE (${f.length} \u4E2A):
572
+ `];return f.forEach((E,y)=>{g.push(`${y+1}. ${E.root}`),g.push(` \u6570\u636E\u5E93: ${E.dbPath}`);}),g.push(`
573
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
574
+ ${U(b)}`),{content:[{type:"text",text:g.join(`
575
+ `)}]}}let{db:r,projectRoot:i}=e.getContext(t),a=r.getProjectStats(),c=["\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} ${i}`,"",`\u{1F4C8} \u6574\u4F53: \u6587\u4EF6 ${a.fileCount} | \u7B26\u53F7 ${a.symbolCount} | \u884C\u4E3A\u6807\u7B7E ${a.behaviorCount} | \u8C03\u7528\u5173\u7CFB ${a.relationCount}`,""],l=a.frameworkBreakdown;if(l?.length){let f={vue2:"\u{1F7E2} Vue2",vue3:"\u{1F535} Vue3",react:"\u269B\uFE0F React",js:"\u{1F4DC} JS",ts:"\u{1F4D8} TS"};c.push("\u{1F527} \u6846\u67B6\u5206\u5E03:");for(let m of l)c.push(` ${f[m.framework]||m.framework}: ${m.count} \u4E2A`);c.push("");}let u=a.topFiles;u?.length&&(c.push("\u{1F5C2}\uFE0F Top 10 \u6700\u5927\u6587\u4EF6:"),u.forEach((f,m)=>{c.push(` ${m+1}. ${f.path} (${f.line_count} \u884C, ${f.symbol_count} \u7B26\u53F7)`);}),c.push(""));let p=a.behaviorStats;if(p?.length){let f={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"};c.push("\u{1F3F7}\uFE0F \u884C\u4E3A\u7EDF\u8BA1:");for(let m of p)c.push(` ${f[m.category]||m.category}: ${m.count} \u5904`);c.push("");}c.push(`\u{1F4BD} \u6570\u636E\u5E93: ${Math.round(a.dbSize/1024)} KB`);let d=Math.round((performance.now()-s)*100)/100,h=W({durationMs:d,resultCount:1,backend:"indexed"});return c.push(`
576
+ \u2500\u2500 \u5143\u4FE1\u606F \u2500\u2500
577
+ ${U(h)}`),{content:[{type:"text",text:c.join(`
578
+ `)}]}});}var he=new rt,ve=new McpServer({name:"frontend-code-skimmer",version:"0.4.1"});fn(ve,he);hn(ve,he);Tn(ve,he);xn(ve,he);An(ve,he);async function $s(){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}
579
+ `);try{let{projectRoot:n}=he.getContext(process.env.SKIMMER_PROJECT),s=he.getIndexer(n),r=await s.indexProject();process.stderr.write(`[Frontend-Code-Skimmer] \u5B8C\u6210: ${r.indexedFiles} \u6587\u4EF6, ${r.totalSymbols} \u7B26\u53F7
580
+ `);let i=await s.startWatcher();he.registerWatcher(n,i),process.stderr.write(`[Frontend-Code-Skimmer] \u6587\u4EF6\u76D1\u542C\u5DF2\u542F\u52A8: ${n}
407
581
  `);}catch(n){process.stderr.write(`[Frontend-Code-Skimmer] \u7D22\u5F15\u5931\u8D25: ${String(n)}
408
- `);}}let e=new StdioServerTransport;await Ue.connect(e),process.stderr.write(`[Frontend-Code-Skimmer MCP] \u5DF2\u542F\u52A8
582
+ `);}}let e=new StdioServerTransport;await ve.connect(e),process.stderr.write(`[Frontend-Code-Skimmer MCP] \u5DF2\u542F\u52A8 (v0.4.1)
409
583
  `),process.stderr.write(`[Frontend-Code-Skimmer MCP] \u652F\u6301\u6846\u67B6: Vue 2 / Vue 3 / React Hooks
584
+ `),process.stderr.write(`[Frontend-Code-Skimmer MCP] \u652F\u6301\u7CBE\u5EA6: heuristic / precise (\u8DE8\u6587\u4EF6 import \u7ED1\u5B9A)
410
585
  `),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
411
586
  `),process.env.SKIMMER_PROJECT?process.stderr.write(`[Frontend-Code-Skimmer MCP] \u9ED8\u8BA4\u9879\u76EE: ${process.env.SKIMMER_PROJECT}
412
587
  `):process.stderr.write(`[Frontend-Code-Skimmer MCP] \u63D0\u793A: \u672A\u8BBE\u7F6E SKIMMER_PROJECT\uFF0C\u6BCF\u6B21\u8C03\u7528\u5DE5\u5177\u65F6\u8BF7\u4F20\u5165 project_path
413
- `);let t=()=>{ue.closeAll(),process.exit(0);};process.on("SIGINT",t),process.on("SIGTERM",t);}Pn().catch(l=>{process.stderr.write(`[Frontend-Code-Skimmer MCP] \u542F\u52A8\u5931\u8D25: ${String(l)}
588
+ `);let t=()=>{he.closeAll(),process.exit(0);};process.on("SIGINT",t),process.on("SIGTERM",t);}$s().catch(o=>{process.stderr.write(`[Frontend-Code-Skimmer MCP] \u542F\u52A8\u5931\u8D25: ${String(o)}
414
589
  `),process.exit(1);});