@devflow-tools/devflow 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mcp-server.js +4 -4
- package/package.json +13 -13
- package/plugin-registry.json +17 -17
package/dist/mcp-server.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {createHmac,createHash}from'crypto';import {Server}from'@modelcontextprotocol/sdk/server/index.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {ListToolsRequestSchema,ListResourcesRequestSchema,ReadResourceRequestSchema,ListPromptsRequestSchema,GetPromptRequestSchema,CallToolRequestSchema}from'@modelcontextprotocol/sdk/types.js';import {FallbackLLMClient,CliSubAgentClient,DevFlowApiClient,loadPlugins}from'@devflow-tools/sdk';import {join}from'path';import {existsSync,mkdirSync,readFileSync,writeFileSync,statSync}from'fs';var Se=Object.defineProperty;var Re=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,o)=>(typeof require<"u"?require:e)[o]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var v=(t,e)=>()=>(t&&(e=t(t=0)),e);var K=(t,e)=>{for(var o in e)Se(t,o,{get:e[o],enumerable:true});};var B={};K(B,{TOOL_GROUPS:()=>Te,createPluginHandlers:()=>Pe,createToolHandlers:()=>Ee,getCoreTools:()=>O,getPluginTools:()=>I});function O(){return [{name:"get_project_context",description:"\u83B7\u53D6\u4E0E\u7F16\u7801\u4EFB\u52A1\u6700\u76F8\u5173\u7684\u6700\u5C0F\u4E0A\u4E0B\u6587",inputSchema:{type:"object",properties:{query:{type:"string",description:"\u81EA\u7136\u8BED\u8A00\u67E5\u8BE2"},mode:{type:"string",enum:["fast","deep"],default:"fast"},expandedTerms:{type:"string",description:"Agent \u9884\u7FFB\u8BD1\u7684\u82F1\u6587\u5173\u952E\u8BCD\uFF08\u7A7A\u683C\u5206\u9694\uFF09\uFF0C\u7528\u4E8E\u63D0\u5347\u4E2D\u6587\u67E5\u8BE2\u7684\u641C\u7D22\u6548\u679C"}},required:["query"]}},{name:"search_symbol",description:"\u6309\u7B26\u53F7\u540D\u641C\u7D22\u4EE3\u7801\u2014\u2014\u8BED\u4E49\u7EA7\u4EE3\u7801\u7ED3\u6784\u641C\u7D22",inputSchema:{type:"object",properties:{symbol:{type:"string",description:"\u7B26\u53F7\u540D\u79F0"}},required:["symbol"]}},{name:"get_dependency_graph",description:"\u83B7\u53D6\u6587\u4EF6/\u7EC4\u4EF6\u7684\u4F9D\u8D56\u5173\u7CFB",inputSchema:{type:"object",properties:{target:{type:"string",default:"all"},depth:{type:"number",default:2}}}},{name:"run_workflow",description:"\u6267\u884C\u6807\u51C6\u5316\u5F00\u53D1\u5DE5\u4F5C\u6D41",inputSchema:{type:"object",properties:{type:{type:"string",enum:["bugfix","feature","review"]},input:{type:"string"}},required:["type"]}},{name:"get_memory",description:"\u83B7\u53D6\u9879\u76EE\u8BB0\u5FC6\uFF1A\u6280\u672F\u6808\u3001\u7EA6\u5B9A\u3001\u504F\u597D\u3001\u5386\u53F2\u51B3\u7B56",inputSchema:{type:"object",properties:{}}},{name:"get_knowledge",description:"\u67E5\u8BE2\u6280\u672F\u6587\u6863\u77E5\u8BC6\u5E93",inputSchema:{type:"object",properties:{query:{type:"string"},scope:{type:"string",enum:["react","vue","nest","all"],default:"all"}},required:["query"]}},{name:"devflow_report_event",description:"Report fine-grained events within workflow steps (LLM calls, tool usage, file read/write etc.). Optional, for more granular observability.",inputSchema:{type:"object",properties:{runId:{type:"string"},stepId:{type:"string"},kind:{type:"string",enum:["llm_call","tool_use","memory_read","memory_write","file_read","file_write","bash_command","mcp_tool_call","error","user_input"]},duration:{type:"number"},model:{type:"string"},prompt:{type:"string"},response:{type:"string"},inputTokens:{type:"number"},outputTokens:{type:"number"},toolName:{type:"string"},toolInput:{type:"string"},toolOutput:{type:"string"},filePath:{type:"string"},command:{type:"string"},exitCode:{type:"number"},stdout:{type:"string"},stderr:{type:"string"},mcpToolName:{type:"string"},errorMessage:{type:"string"},errorStack:{type:"string"},memoryKey:{type:"string"},userMessage:{type:"string"}},required:["runId","stepId","kind"]}}]}function Ee(t){return {get_project_context:async({query:e,mode:o,expandedTerms:r})=>{let n=await t.context.buildTaskContext(e,{mode:o??"fast",sessionId:process.env.DEVFLOW_SESSION_ID??void 0});return {taskType:n.taskType,requiredFiles:n.requiredFiles,optionalFiles:n.optionalFiles,keySymbols:n.keySymbols,graphSummary:n.graphSummary,riskHints:n.riskHints,nextActions:n.nextActions,reasoning:n.reasoning,confidence:n.confidence,tokenCount:n.tokenCount,_devflow_unique:{search_method:"bm25_semantic",task_oriented:true,risk_aware:true,memory_injected:true,knowledge_injected:true,token_estimated:true,required_vs_optional:true}}},search_symbol:async({symbol:e})=>{let o=await t.indexer.findSymbol(e);return {result:Array.isArray(o)?o:[],_devflow_unique:{index_backed:true,kind_annotated:true,searched:e,match_count:Array.isArray(o)?o.length:0}}},get_dependency_graph:async({target:e,depth:o})=>{let r=e?.trim()??"all",n=o??2;if(r===""||r==="all")return {...t.graph.export(),_devflow_unique:{layer_annotated:true,architecture_grouped:true,query_depth:n}};let s=t.graph.getSubGraph(r,n);if(s.nodes.length===0){let a=t.graph.export();return {nodes:a.nodes.filter(i=>i.file.includes(r)),edges:a.edges.filter(i=>a.nodes.some(u=>u.id===i.from&&u.file.includes(r))||a.nodes.some(u=>u.id===i.to&&u.file.includes(r))),_fallback:"filename-filter",seeds:[r],depth:n}}return {...s,_devflow_unique:{layer_annotated:true,architecture_grouped:true,query_depth:n}}},run_workflow:async({type:e,input:o})=>({...await t.workflow.run(e,{input:o}),_devflow_unique:{dag_orchestrated:true,step_tracked:true,workflow_type:e}}),get_memory:async()=>({...await t.memory.getAll(),_devflow_unique:{memory_version:1,structured_storage:true,project_context_included:true}}),get_knowledge:async({query:e,scope:o})=>({...await t.knowledge.search(e,{sources:o==="all"?void 0:[o]}),_devflow_unique:{source_versioned:true,code_examples_included:true,search_scope:o}}),devflow_report_event:async e=>{let o=(p,f)=>!p||p.length<=f?{value:p??"",truncated:false}:{value:p.slice(0,f),truncated:true},r=o(e.prompt,500),n=o(e.response,500),s=o(e.stdout,1e3),a=o(e.stderr,500),i=r.truncated||n.truncated||s.truncated||a.truncated,u={id:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,runId:e.runId,stepId:e.stepId,kind:e.kind,timestamp:Date.now(),duration:e.duration,data:{model:e.model,prompt:r.value,response:n.value,inputTokens:e.inputTokens,outputTokens:e.outputTokens,toolName:e.toolName,toolInput:e.toolInput,toolOutput:e.toolOutput,filePath:e.filePath,command:e.command,exitCode:e.exitCode,stdout:s.value,stderr:a.value,mcpToolName:e.mcpToolName,errorMessage:e.errorMessage,errorStack:e.errorStack,memoryKey:e.memoryKey,userMessage:e.userMessage},metadata:{source:"manual"},...i&&{metadata:{truncated:true,source:"manual"}}};return await t.telemetry.recordEvent(u),{acknowledged:true,eventId:u.id}}}}function I(t){let e=[];for(let o of t){let r=o.meta.name;for(let s of o.tools??[])e.push({name:s.name,description:s.description,inputSchema:s.inputSchema});let n=new Set(e.map(s=>s.name));for(let s of o.workflow?.templates??[]){let a=s.triggers?.find(u=>u.type==="mcp");if(!a?.tool)continue;let i=`${r}_${a.tool}`;n.has(i)||e.push({name:i,description:s.description,inputSchema:{type:"object",properties:s.steps.filter(u=>u.inputSchema).reduce((u,p)=>({...u,...p.inputSchema??{}}),{}),required:[]}});}}return e}function Pe(t,e){let o={};for(let r of e){let n=r.meta.name;for(let s of r.tools??[])s.handler&&(o[s.name]=s.handler);for(let s of r.workflow?.templates??[]){let a=s.triggers?.find(u=>u.type==="mcp");if(!a?.tool)continue;let i=`${n}_${a.tool}`;o[i]||(o[i]=async u=>{let p=await t.workflow.run(s.name,u),f="";try{let g={id:p.runId??`run:${Date.now()}`,source:"mcp",tool:i,workflow:s.name,input:u,status:"running",startedAt:Date.now(),finishedAt:null,steps:[],metadata:{}};f=t.workflow.renderPlan(g,s);}catch{}return {...p,plan:f,_devflow_unique:{dag_orchestrated:true,step_tracked:true,plugin_name:n,template_name:s.name}}});}}return o}var Te,N=v(()=>{Te={get_project_context:{group:"context",cacheable:true,idempotent:true},search_symbol:{group:"context",cacheable:true,idempotent:true},get_dependency_graph:{group:"context",cacheable:true,idempotent:true},get_memory:{group:"memory",cacheable:false,idempotent:true},devflow_report_event:{group:"memory",cacheable:false,idempotent:false},get_knowledge:{group:"knowledge",cacheable:true,idempotent:true},run_workflow:{group:"workflow",cacheable:false,idempotent:false},react_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},nest_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},nextjs_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},vue_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},graphql_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},electron_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},react_new_component:{group:"workflow",cacheable:false,idempotent:false},react_refactor_component:{group:"workflow",cacheable:false,idempotent:false},react_review_hooks:{group:"workflow",cacheable:false,idempotent:false},react_audit_performance:{group:"workflow",cacheable:false,idempotent:false},nest_new_module:{group:"workflow",cacheable:false,idempotent:false},graphql_new_graphql_type:{group:"workflow",cacheable:false,idempotent:false},nextjs_new_page:{group:"workflow",cacheable:false,idempotent:false},taro_new_page:{group:"workflow",cacheable:false,idempotent:false},vue_new_component:{group:"workflow",cacheable:false,idempotent:false},tailwind_new_component:{group:"workflow",cacheable:false,idempotent:false},docker_dockerize_project:{group:"lifecycle",cacheable:false,idempotent:false},performance_audit_performance:{group:"lifecycle",cacheable:false,idempotent:false}};});var $,F=v(()=>{$=[{id:"C001",name:"\u5FC5\u987B\u643A\u5E26 Session Token",level:"constitutional",condition:{requireFields:["_devflow_token"]},action:"deny",message:"\u7F3A\u5C11 Session Token\u3002\u8BF7\u901A\u8FC7 /devflow: \u547D\u4EE4\u542F\u52A8\u4F1A\u8BDD\uFF0C\u6216\u8FD0\u884C devflow session token \u83B7\u53D6\u4EE4\u724C\u3002"},{id:"C002",name:"Token \u5DF2\u8FC7\u671F",level:"constitutional",condition:{},action:"deny",message:"Session Token \u5DF2\u8FC7\u671F\uFF08\u8D85\u8FC7 1 \u5C0F\u65F6\uFF09\u3002\u8BF7\u91CD\u65B0\u8FD0\u884C devflow session token \u83B7\u53D6\u65B0\u4EE4\u724C\u3002"},{id:"C003",name:"\u901F\u7387\u9650\u5236",level:"constitutional",condition:{maxCallsPerMinute:60},action:"warn",message:"\u8C03\u7528\u9891\u7387\u8FC7\u9AD8\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"}];});async function ee(t){let e=await t.ruleGetAll();return [...$,...e]}function je(t,e){let o=t.condition;if(o.tools&&!o.tools.includes("*")&&!o.tools.includes(e.toolName))return "allow";if(o.requireFields){for(let r of o.requireFields)if(!(r in e.args))return t.action}if(o.forbidPatterns){for(let r of o.forbidPatterns)for(let n of Object.values(e.args))if(typeof n=="string"&&new RegExp(r).test(n))return t.action}if(o.paramPatterns)for(let[r,n]of Object.entries(o.paramPatterns)){let s=String(e.args[r]??"");if(new RegExp(n).test(s))return t.action}if(o.maxCallsPerMinute){let r=`${e.toolName}:${e.sessionId??"anon"}`,n=Date.now(),s=Z.get(r);if((!s||n>s.resetAt)&&(s={count:0,resetAt:n+6e4},Z.set(r,s)),s.count++,s.count>o.maxCallsPerMinute)return t.action}return "allow"}function te(t,e){let o=[...t].sort((r,n)=>{let s={constitutional:0,project:1,session:2};return s[r.level]-s[n.level]});for(let r of o){let n=je(r,e);if(n!=="allow")return {decision:n,rule:r}}return {decision:"allow"}}var Z,oe=v(()=>{F();Z=new Map;});function x(t){let e=JSON.stringify(t,Object.keys(t).sort());return createHash("sha256").update(e).digest("hex")}async function L(t,e,o,r,n,s){let a=await t.auditGetSecret(),i=await t.auditGetAll(),u=i.length>0?i[i.length-1].signature:createHash("sha256").update("genesis").digest("hex"),p=Date.now(),f=i.length+1,g=`${f}|${p}|${e}|${o}|${r}|${n??""}|${s}|${u}`,l=createHmac("sha256",a).update(g).digest("hex");await t.auditAppend({seq:f,ts:p,tool:e,argsHash:o,decision:r,ruleId:n,sessionId:s,prevHash:u,signature:l});}async function ne(t){let e=await t.auditGetSecret(),o=await t.auditGetAll(),r=createHash("sha256").update("genesis").digest("hex");for(let n of o){if(n.prevHash!==r)return {valid:false,brokenAt:n.seq};let s=`${n.seq}|${n.ts}|${n.tool}|${n.argsHash}|${n.decision}|${n.ruleId??""}|${n.sessionId}|${r}`,a=createHmac("sha256",e).update(s).digest("hex");if(n.signature!==a)return {valid:false,brokenAt:n.seq};r=n.signature;}return {valid:true,brokenAt:null}}async function re(t){let e=await t.auditGetSecret(),o=await t.auditGetAll(),r=createHash("sha256").update("genesis").digest("hex");for(let n of o){let s=`${n.seq}|${n.ts}|${n.tool}|${n.argsHash}|${n.decision}|${n.ruleId??""}|${n.sessionId}|${r}`,a=createHmac("sha256",e).update(s).digest("hex");await t.sqlExecute("UPDATE devflow_audit_chain SET prev_hash = ?, signature = ? WHERE seq = ?",[r,a,n.seq]),r=a;}}var J=v(()=>{});function b(t,e,o){let r=Date.now(),n=r+$e,s=createHash("sha256").update(JSON.stringify(e)).digest("hex"),a=`${t}|${r}|${n}|${s}`,i=createHmac("sha256",o).update(a).digest("hex");return {tool:t,ts:r,exp:n,queryHash:s,hmac:i}}function ie(t,e,o,r){if(Date.now()>t.exp)return false;let n=createHash("sha256").update(JSON.stringify(o)).digest("hex");if(t.queryHash!==n)return false;let s=`${e}|${t.ts}|${t.exp}|${n}`,a=createHmac("sha256",r).update(s).digest("hex");return t.hmac===a}function ce(t){return Date.now()>t.exp}var $e,W=v(()=>{$e=3e4;});var ue={};K(ue,{CONSTITUTIONAL_RULES:()=>$,enforce:()=>De,hashArgs:()=>x,isReceiptExpired:()=>ce,issueReceipt:()=>b,parseJwtPayload:()=>le,rebuildAuditChain:()=>re,verifyAuditChain:()=>ne,verifyReceipt:()=>ie});function le(t){try{let e=t.split(".");if(e.length!==3)return null;let o=e[1],r=Buffer.from(o,"base64url").toString("utf-8");return JSON.parse(r)}catch{return null}}async function De(t,e,o){if(!e._devflow_token){let g=process.env.DEVFLOW_SESSION_TOKEN;if(g){let l=le(g);l&&(e={...e,_devflow_token:l});}}let r=e._devflow_token?.sub??"anon",n={toolName:t,args:e,sessionId:r,tokenPayload:e._devflow_token};if(n.tokenPayload){let g=Math.floor(Date.now()/1e3);if(n.tokenPayload.exp&&g>n.tokenPayload.exp){let l=x(e);return await L(o,t,l,"deny","C002",r),{result:{allowed:false,message:"Session Token \u5DF2\u8FC7\u671F\uFF08\u8D85\u8FC7 1 \u5C0F\u65F6\uFF09\u3002\u8BF7\u91CD\u65B0\u8FD0\u884C devflow session token \u83B7\u53D6\u65B0\u4EE4\u724C\u3002"}}}}let s=await ee(o),{decision:a,rule:i}=te(s,n),u=x(e);if(await L(o,t,u,a,i?.id??null,r),a==="deny"&&i)return {result:{allowed:false,rule:i,message:i.message}};if(a==="warn"&&i){let g=await o.auditGetSecret(),l=b(t,e,g);return {result:{allowed:true,warning:i.message,rule:i},receipt:l}}let p=await o.auditGetSecret(),f=b(t,e,p);return {result:{allowed:true},receipt:f}}var pe=v(()=>{oe();J();W();J();W();F();});N();async function V(t){let e=await t.memory.listMemories({status:"approved"}),o=await t.knowledge.getSources();return {resources:[{uri:"devflow://memory/recent",name:"Recent Memories",description:`${e.length} approved project memories`,mimeType:"application/json"},{uri:"devflow://memory/pending",name:"Pending Memories",description:"Memory candidates awaiting approval",mimeType:"application/json"},{uri:"devflow://code/{file}:{line}",name:"Code Context",description:"Source code at specific file and line",mimeType:"text/plain"},{uri:"devflow://knowledge/{source}",name:"Knowledge Base",description:`Technical documentation (${o.length} sources)`,mimeType:"application/json"}]}}async function z(t,e){if(t==="devflow://memory/recent"){let o=await e.memory.listMemories({status:"approved"});return {contents:[{uri:t,mimeType:"application/json",text:JSON.stringify(o.slice(0,20),null,2)}]}}if(t==="devflow://memory/pending"){let o=await e.memory.getPendingMemories();return {contents:[{uri:t,mimeType:"application/json",text:JSON.stringify(o,null,2)}]}}if(t.startsWith("devflow://knowledge/")){let o=t.replace("devflow://knowledge/",""),r=await e.knowledge.search("",{sources:[o],limit:20});return {contents:[{uri:t,mimeType:"application/json",text:JSON.stringify(r,null,2)}]}}return {contents:[{uri:t,mimeType:"text/plain",text:JSON.stringify({message:"Resource not found"})}]}}var Y={"debug-react":{name:"Debug React Component",description:"Load React knowledge + project memories + related code for debugging",arguments:[{name:"query",description:"Bug description or component name",required:true}]},"code-review":{name:"Code Review",description:"Load project conventions + dependency graph for code review",arguments:[{name:"file",description:"File to review",required:true}]},"new-feature":{name:"New Feature",description:"Load project structure + knowledge base for feature planning",arguments:[{name:"feature",description:"Feature description",required:true}]},"fix-bug":{name:"Fix Bug",description:"Load failure lessons + dependency graph for bug fixing",arguments:[{name:"bug",description:"Bug description",required:true}]}};async function X(){return {prompts:Object.entries(Y).map(([t,e])=>({name:t,description:e.description,arguments:e.arguments}))}}async function Q(t,e){let o=Y[t];if(!o)throw new Error(`Prompt "${t}" not found`);return {messages:[{role:"user",content:{type:"text",text:`You are working on: ${o.description}
|
|
2
|
+
import {createHmac,createHash}from'crypto';import {Server}from'@modelcontextprotocol/sdk/server/index.js';import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {ListToolsRequestSchema,ListResourcesRequestSchema,ReadResourceRequestSchema,ListPromptsRequestSchema,GetPromptRequestSchema,CallToolRequestSchema}from'@modelcontextprotocol/sdk/types.js';import {FallbackLLMClient,CliSubAgentClient,DevFlowApiClient,loadPlugins}from'@devflow-tools/sdk';import {join}from'path';import {existsSync,mkdirSync,readFileSync,writeFileSync,statSync}from'fs';var Se=Object.defineProperty;var Re=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(o,t)=>(typeof require<"u"?require:o)[t]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var k=(e,o)=>()=>(e&&(o=e(e=0)),o);var K=(e,o)=>{for(var t in o)Se(e,t,{get:o[t],enumerable:true});};var B={};K(B,{TOOL_GROUPS:()=>Te,createPluginHandlers:()=>Pe,createToolHandlers:()=>Ee,getCoreTools:()=>A,getPluginTools:()=>O});function A(){return [{name:"get_project_context",description:"\u83B7\u53D6\u4E0E\u7F16\u7801\u4EFB\u52A1\u6700\u76F8\u5173\u7684\u6700\u5C0F\u4E0A\u4E0B\u6587",inputSchema:{type:"object",properties:{query:{type:"string",description:"\u81EA\u7136\u8BED\u8A00\u67E5\u8BE2"},mode:{type:"string",enum:["fast","deep"],default:"fast"},expandedTerms:{type:"string",description:"Agent \u9884\u7FFB\u8BD1\u7684\u82F1\u6587\u5173\u952E\u8BCD\uFF08\u7A7A\u683C\u5206\u9694\uFF09\uFF0C\u7528\u4E8E\u63D0\u5347\u4E2D\u6587\u67E5\u8BE2\u7684\u641C\u7D22\u6548\u679C"}},required:["query"]}},{name:"search_symbol",description:"\u6309\u7B26\u53F7\u540D\u641C\u7D22\u4EE3\u7801\u2014\u2014\u8BED\u4E49\u7EA7\u4EE3\u7801\u7ED3\u6784\u641C\u7D22",inputSchema:{type:"object",properties:{symbol:{type:"string",description:"\u7B26\u53F7\u540D\u79F0"}},required:["symbol"]}},{name:"get_dependency_graph",description:"\u83B7\u53D6\u6587\u4EF6/\u7EC4\u4EF6\u7684\u4F9D\u8D56\u5173\u7CFB",inputSchema:{type:"object",properties:{target:{type:"string",default:"all"},depth:{type:"number",default:2}}}},{name:"run_workflow",description:"\u6267\u884C\u6807\u51C6\u5316\u5F00\u53D1\u5DE5\u4F5C\u6D41",inputSchema:{type:"object",properties:{type:{type:"string",enum:["bugfix","feature","review"]},input:{type:"string"}},required:["type"]}},{name:"get_memory",description:"\u83B7\u53D6\u9879\u76EE\u8BB0\u5FC6\uFF1A\u6280\u672F\u6808\u3001\u7EA6\u5B9A\u3001\u504F\u597D\u3001\u5386\u53F2\u51B3\u7B56",inputSchema:{type:"object",properties:{}}},{name:"get_knowledge",description:"\u67E5\u8BE2\u6280\u672F\u6587\u6863\u77E5\u8BC6\u5E93",inputSchema:{type:"object",properties:{query:{type:"string"},scope:{type:"string",enum:["react","vue","nest","all"],default:"all"}},required:["query"]}},{name:"devflow_report_event",description:"Report fine-grained events within workflow steps (LLM calls, tool usage, file read/write etc.). Optional, for more granular observability.",inputSchema:{type:"object",properties:{runId:{type:"string"},stepId:{type:"string"},kind:{type:"string",enum:["llm_call","tool_use","memory_read","memory_write","file_read","file_write","bash_command","mcp_tool_call","error","user_input"]},duration:{type:"number"},model:{type:"string"},prompt:{type:"string"},response:{type:"string"},inputTokens:{type:"number"},outputTokens:{type:"number"},toolName:{type:"string"},toolInput:{type:"string"},toolOutput:{type:"string"},filePath:{type:"string"},command:{type:"string"},exitCode:{type:"number"},stdout:{type:"string"},stderr:{type:"string"},mcpToolName:{type:"string"},errorMessage:{type:"string"},errorStack:{type:"string"},memoryKey:{type:"string"},userMessage:{type:"string"}},required:["runId","stepId","kind"]}}]}function Ee(e){function o(){try{let t=e.codegraph.getStats();return t.lastUpdated>0?Date.now()-t.lastUpdated:0}catch{return 0}}return {get_project_context:async({query:t,mode:r,expandedTerms:s})=>{let n=await e.context.buildTaskContext(t,{mode:r??"fast",sessionId:process.env.DEVFLOW_SESSION_ID??void 0});return {taskType:n.taskType,requiredFiles:n.requiredFiles,optionalFiles:n.optionalFiles,keySymbols:n.keySymbols,graphSummary:n.graphSummary,riskHints:n.riskHints,nextActions:n.nextActions,reasoning:n.reasoning,confidence:n.confidence,tokenCount:n.tokenCount,_timing:n._timing,_devflow_unique:{search_method:"bm25_semantic",task_oriented:true,risk_aware:true,memory_injected:true,knowledge_injected:true,token_estimated:true,required_vs_optional:true},_accuracy:{data_freshness_ms:o(),source_layer:"composite",degradation:n._devflow?.fallback?"fallback":"none"}}},search_symbol:async({symbol:t})=>{let r=await e.indexer.findSymbol(t);return {result:Array.isArray(r)?r:[],_devflow_unique:{index_backed:true,kind_annotated:true,searched:t,match_count:Array.isArray(r)?r.length:0}}},get_dependency_graph:async({target:t,depth:r,layer:s})=>{let n=t?.trim()||void 0,a=r??2,c=s??"auto",l=e.graph.query({target:n,depth:a,layer:c==="auto"?void 0:c});if(l.nodes.length===0&&n){let d=e.graph.export();return {nodes:d.nodes.filter(p=>p.file.includes(n)),edges:d.edges.filter(p=>d.nodes.some(u=>u.id===p.from&&u.file.includes(n))||d.nodes.some(u=>u.id===p.to&&u.file.includes(n))),_devflow_unique:{layer:l.layer,truncated:l.truncated,layer_annotated:true,architecture_grouped:true,query_depth:a,query_target:n},_fallback:"filename-filter",_accuracy:{data_freshness_ms:o(),source_layer:"codegraph",degradation:"fallback"},seeds:[n],depth:a}}return {nodes:l.nodes,edges:l.edges,_devflow_unique:{layer:l.layer,truncated:l.truncated,layer_annotated:true,architecture_grouped:true,query_depth:a,query_target:n??"all"},_accuracy:{data_freshness_ms:o(),source_layer:"codegraph",degradation:l.edges.length===0&&l.nodes.length>0?"partial":"none"}}},run_workflow:async({type:t,input:r})=>({...await e.workflow.run(t,{input:r}),_devflow_unique:{dag_orchestrated:true,step_tracked:true,workflow_type:t}}),get_memory:async()=>({...await e.memory.getAll(),_devflow_unique:{memory_version:1,structured_storage:true,project_context_included:true},_accuracy:{data_freshness_ms:o(),source_layer:"memory",degradation:"none"}}),get_knowledge:async({query:t,scope:r})=>({...await e.knowledge.search(t,{sources:r==="all"?void 0:[r]}),_devflow_unique:{source_versioned:true,code_examples_included:true,search_scope:r},_accuracy:{data_freshness_ms:o(),source_layer:"knowledge",degradation:"none"}}),devflow_report_event:async t=>{let r=(p,u)=>!p||p.length<=u?{value:p??"",truncated:false}:{value:p.slice(0,u),truncated:true},s=r(t.prompt,500),n=r(t.response,500),a=r(t.stdout,1e3),c=r(t.stderr,500),l=s.truncated||n.truncated||a.truncated||c.truncated,d={id:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,runId:t.runId,stepId:t.stepId,kind:t.kind,timestamp:Date.now(),duration:t.duration,data:{model:t.model,prompt:s.value,response:n.value,inputTokens:t.inputTokens,outputTokens:t.outputTokens,toolName:t.toolName,toolInput:t.toolInput,toolOutput:t.toolOutput,filePath:t.filePath,command:t.command,exitCode:t.exitCode,stdout:a.value,stderr:c.value,mcpToolName:t.mcpToolName,errorMessage:t.errorMessage,errorStack:t.errorStack,memoryKey:t.memoryKey,userMessage:t.userMessage},metadata:{source:"manual"},...l&&{metadata:{truncated:true,source:"manual"}}};return await e.telemetry.recordEvent(d),{acknowledged:true,eventId:d.id}}}}function O(e){let o=[];for(let t of e){let r=t.meta.name;for(let n of t.tools??[])o.push({name:n.name,description:n.description,inputSchema:n.inputSchema});let s=new Set(o.map(n=>n.name));for(let n of t.workflow?.templates??[]){let a=n.triggers?.find(l=>l.type==="mcp");if(!a?.tool)continue;let c=`${r}_${a.tool}`;s.has(c)||o.push({name:c,description:n.description,inputSchema:{type:"object",properties:n.steps.filter(l=>l.inputSchema).reduce((l,d)=>({...l,...d.inputSchema??{}}),{}),required:[]}});}}return o}function Pe(e,o){let t={};for(let r of o){let s=r.meta.name;for(let n of r.tools??[])n.handler&&(t[n.name]=n.handler);for(let n of r.workflow?.templates??[]){let a=n.triggers?.find(l=>l.type==="mcp");if(!a?.tool)continue;let c=`${s}_${a.tool}`;t[c]||(t[c]=async l=>{let d=await e.workflow.run(n.name,l),p="";try{let u={id:d.runId??`run:${Date.now()}`,source:"mcp",tool:c,workflow:n.name,input:l,status:"running",startedAt:Date.now(),finishedAt:null,steps:[],metadata:{}};p=e.workflow.renderPlan(u,n);}catch{}return {...d,plan:p,_devflow_unique:{dag_orchestrated:true,step_tracked:true,plugin_name:s,template_name:n.name}}});}}return t}var Te,I=k(()=>{Te={get_project_context:{group:"context",cacheable:true,idempotent:true},search_symbol:{group:"context",cacheable:true,idempotent:true},get_dependency_graph:{group:"context",cacheable:true,idempotent:true},get_memory:{group:"memory",cacheable:false,idempotent:true},devflow_report_event:{group:"memory",cacheable:false,idempotent:false},get_knowledge:{group:"knowledge",cacheable:true,idempotent:true},run_workflow:{group:"workflow",cacheable:false,idempotent:false},react_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},nest_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},nextjs_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},vue_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},graphql_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},electron_diagnose_bug:{group:"workflow",cacheable:false,idempotent:false},react_new_component:{group:"workflow",cacheable:false,idempotent:false},react_refactor_component:{group:"workflow",cacheable:false,idempotent:false},react_review_hooks:{group:"workflow",cacheable:false,idempotent:false},react_audit_performance:{group:"workflow",cacheable:false,idempotent:false},nest_new_module:{group:"workflow",cacheable:false,idempotent:false},graphql_new_graphql_type:{group:"workflow",cacheable:false,idempotent:false},nextjs_new_page:{group:"workflow",cacheable:false,idempotent:false},taro_new_page:{group:"workflow",cacheable:false,idempotent:false},vue_new_component:{group:"workflow",cacheable:false,idempotent:false},tailwind_new_component:{group:"workflow",cacheable:false,idempotent:false},docker_dockerize_project:{group:"lifecycle",cacheable:false,idempotent:false},performance_audit_performance:{group:"lifecycle",cacheable:false,idempotent:false}};});var $,N=k(()=>{$=[{id:"C001",name:"\u5FC5\u987B\u643A\u5E26 Session Token",level:"constitutional",condition:{requireFields:["_devflow_token"]},action:"deny",message:"\u7F3A\u5C11 Session Token\u3002\u8BF7\u901A\u8FC7 /devflow: \u547D\u4EE4\u542F\u52A8\u4F1A\u8BDD\uFF0C\u6216\u8FD0\u884C devflow session token \u83B7\u53D6\u4EE4\u724C\u3002"},{id:"C002",name:"Token \u5DF2\u8FC7\u671F",level:"constitutional",condition:{},action:"deny",message:"Session Token \u5DF2\u8FC7\u671F\uFF08\u8D85\u8FC7 1 \u5C0F\u65F6\uFF09\u3002\u8BF7\u91CD\u65B0\u8FD0\u884C devflow session token \u83B7\u53D6\u65B0\u4EE4\u724C\u3002"},{id:"C003",name:"\u901F\u7387\u9650\u5236",level:"constitutional",condition:{maxCallsPerMinute:60},action:"warn",message:"\u8C03\u7528\u9891\u7387\u8FC7\u9AD8\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"}];});async function ee(e){let o=await e.ruleGetAll();return [...$,...o]}function $e(e,o){let t=e.condition;if(t.tools&&!t.tools.includes("*")&&!t.tools.includes(o.toolName))return "allow";if(t.requireFields){for(let r of t.requireFields)if(!(r in o.args))return e.action}if(t.forbidPatterns){for(let r of t.forbidPatterns)for(let s of Object.values(o.args))if(typeof s=="string"&&new RegExp(r).test(s))return e.action}if(t.paramPatterns)for(let[r,s]of Object.entries(t.paramPatterns)){let n=String(o.args[r]??"");if(new RegExp(s).test(n))return e.action}if(t.maxCallsPerMinute){let r=`${o.toolName}:${o.sessionId??"anon"}`,s=Date.now(),n=Z.get(r);if((!n||s>n.resetAt)&&(n={count:0,resetAt:s+6e4},Z.set(r,n)),n.count++,n.count>t.maxCallsPerMinute)return e.action}return "allow"}function te(e,o){let t=[...e].sort((r,s)=>{let n={constitutional:0,project:1,session:2};return n[r.level]-n[s.level]});for(let r of t){let s=$e(r,o);if(s!=="allow")return {decision:s,rule:r}}return {decision:"allow"}}var Z,oe=k(()=>{N();Z=new Map;});function x(e){let o=JSON.stringify(e,Object.keys(e).sort());return createHash("sha256").update(o).digest("hex")}async function H(e,o,t,r,s,n){let a=await e.auditGetSecret(),c=await e.auditGetAll(),l=c.length>0?c[c.length-1].signature:createHash("sha256").update("genesis").digest("hex"),d=Date.now(),p=c.length+1,u=`${p}|${d}|${o}|${t}|${r}|${s??""}|${n}|${l}`,m=createHmac("sha256",a).update(u).digest("hex");await e.auditAppend({seq:p,ts:d,tool:o,argsHash:t,decision:r,ruleId:s,sessionId:n,prevHash:l,signature:m});}async function ne(e){let o=await e.auditGetSecret(),t=await e.auditGetAll(),r=createHash("sha256").update("genesis").digest("hex");for(let s of t){if(s.prevHash!==r)return {valid:false,brokenAt:s.seq};let n=`${s.seq}|${s.ts}|${s.tool}|${s.argsHash}|${s.decision}|${s.ruleId??""}|${s.sessionId}|${r}`,a=createHmac("sha256",o).update(n).digest("hex");if(s.signature!==a)return {valid:false,brokenAt:s.seq};r=s.signature;}return {valid:true,brokenAt:null}}async function re(e){let o=await e.auditGetSecret(),t=await e.auditGetAll(),r=createHash("sha256").update("genesis").digest("hex");for(let s of t){let n=`${s.seq}|${s.ts}|${s.tool}|${s.argsHash}|${s.decision}|${s.ruleId??""}|${s.sessionId}|${r}`,a=createHmac("sha256",o).update(n).digest("hex");await e.sqlExecute("UPDATE devflow_audit_chain SET prev_hash = ?, signature = ? WHERE seq = ?",[r,a,s.seq]),r=a;}}var L=k(()=>{});function S(e,o,t){let r=Date.now(),s=r+je,n=createHash("sha256").update(JSON.stringify(o)).digest("hex"),a=`${e}|${r}|${s}|${n}`,c=createHmac("sha256",t).update(a).digest("hex");return {tool:e,ts:r,exp:s,queryHash:n,hmac:c}}function ie(e,o,t,r){if(Date.now()>e.exp)return false;let s=createHash("sha256").update(JSON.stringify(t)).digest("hex");if(e.queryHash!==s)return false;let n=`${o}|${e.ts}|${e.exp}|${s}`,a=createHmac("sha256",r).update(n).digest("hex");return e.hmac===a}function ce(e){return Date.now()>e.exp}var je,J=k(()=>{je=3e4;});var ue={};K(ue,{CONSTITUTIONAL_RULES:()=>$,enforce:()=>De,hashArgs:()=>x,isReceiptExpired:()=>ce,issueReceipt:()=>S,parseJwtPayload:()=>le,rebuildAuditChain:()=>re,verifyAuditChain:()=>ne,verifyReceipt:()=>ie});function le(e){try{let o=e.split(".");if(o.length!==3)return null;let t=o[1],r=Buffer.from(t,"base64url").toString("utf-8");return JSON.parse(r)}catch{return null}}async function De(e,o,t){if(!o._devflow_token){let u=process.env.DEVFLOW_SESSION_TOKEN;if(u){let m=le(u);m&&(o={...o,_devflow_token:m});}}let r=o._devflow_token?.sub??"anon",s={toolName:e,args:o,sessionId:r,tokenPayload:o._devflow_token};if(s.tokenPayload){let u=Math.floor(Date.now()/1e3);if(s.tokenPayload.exp&&u>s.tokenPayload.exp){let m=x(o);return await H(t,e,m,"deny","C002",r),{result:{allowed:false,message:"Session Token \u5DF2\u8FC7\u671F\uFF08\u8D85\u8FC7 1 \u5C0F\u65F6\uFF09\u3002\u8BF7\u91CD\u65B0\u8FD0\u884C devflow session token \u83B7\u53D6\u65B0\u4EE4\u724C\u3002"}}}}let n=await ee(t),{decision:a,rule:c}=te(n,s),l=x(o);if(await H(t,e,l,a,c?.id??null,r),a==="deny"&&c)return {result:{allowed:false,rule:c,message:c.message}};if(a==="warn"&&c){let u=await t.auditGetSecret(),m=S(e,o,u);return {result:{allowed:true,warning:c.message,rule:c},receipt:m}}let d=await t.auditGetSecret(),p=S(e,o,d);return {result:{allowed:true},receipt:p}}var de=k(()=>{oe();L();J();L();J();N();});I();async function V(e){let o=await e.memory.listMemories({status:"approved"}),t=await e.knowledge.getSources();return {resources:[{uri:"devflow://memory/recent",name:"Recent Memories",description:`${o.length} approved project memories`,mimeType:"application/json"},{uri:"devflow://memory/pending",name:"Pending Memories",description:"Memory candidates awaiting approval",mimeType:"application/json"},{uri:"devflow://code/{file}:{line}",name:"Code Context",description:"Source code at specific file and line",mimeType:"text/plain"},{uri:"devflow://knowledge/{source}",name:"Knowledge Base",description:`Technical documentation (${t.length} sources)`,mimeType:"application/json"}]}}async function z(e,o){if(e==="devflow://memory/recent"){let t=await o.memory.listMemories({status:"approved"});return {contents:[{uri:e,mimeType:"application/json",text:JSON.stringify(t.slice(0,20),null,2)}]}}if(e==="devflow://memory/pending"){let t=await o.memory.getPendingMemories();return {contents:[{uri:e,mimeType:"application/json",text:JSON.stringify(t,null,2)}]}}if(e.startsWith("devflow://knowledge/")){let t=e.replace("devflow://knowledge/",""),r=await o.knowledge.search("",{sources:[t],limit:20});return {contents:[{uri:e,mimeType:"application/json",text:JSON.stringify(r,null,2)}]}}return {contents:[{uri:e,mimeType:"text/plain",text:JSON.stringify({message:"Resource not found"})}]}}var Y={"debug-react":{name:"Debug React Component",description:"Load React knowledge + project memories + related code for debugging",arguments:[{name:"query",description:"Bug description or component name",required:true}]},"code-review":{name:"Code Review",description:"Load project conventions + dependency graph for code review",arguments:[{name:"file",description:"File to review",required:true}]},"new-feature":{name:"New Feature",description:"Load project structure + knowledge base for feature planning",arguments:[{name:"feature",description:"Feature description",required:true}]},"fix-bug":{name:"Fix Bug",description:"Load failure lessons + dependency graph for bug fixing",arguments:[{name:"bug",description:"Bug description",required:true}]}};async function X(){return {prompts:Object.entries(Y).map(([e,o])=>({name:e,description:o.description,arguments:o.arguments}))}}async function Q(e,o){let t=Y[e];if(!t)throw new Error(`Prompt "${e}" not found`);return {messages:[{role:"user",content:{type:"text",text:`You are working on: ${t.description}
|
|
3
3
|
|
|
4
|
-
Context: ${JSON.stringify(
|
|
4
|
+
Context: ${JSON.stringify(o)}
|
|
5
5
|
|
|
6
|
-
Use available tools to complete this task.`}}]}}var
|
|
7
|
-
`)),{content:
|
|
6
|
+
Use available tools to complete this task.`}}]}}var P=class{constructor(o){this.server=o;this.name="mcp-sampling";}get isAvailable(){try{return this.server.getClientCapabilities()?.sampling!==void 0}catch{return false}}async chat(o){let t=await this.server.createMessage({messages:o.messages.map(n=>({role:n.role,content:{type:"text",text:n.content}})),maxTokens:o.maxTokens??4096,temperature:o.temperature,...o.systemPrompt?{systemPrompt:o.systemPrompt}:{}}),r=t.content,s="";return typeof r=="string"?s=r:"type"in r&&r.type==="text"?s=r.text:Array.isArray(r)&&(s=r.filter(n=>typeof n=="object"&&"type"in n&&n.type==="text").map(n=>n.text).join(`
|
|
7
|
+
`)),{content:s,model:t.model,usage:t.usage?{input:t.usage.inputTokens??0,output:t.usage.outputTokens??0}:void 0}}};async function fe(e){ze(e.projectRoot),Xe(e.projectRoot);let o=new Server({name:"devflow-mcp",version:"0.1.0"},{capabilities:{tools:{},resources:{},prompts:{}}}),t=new FallbackLLMClient(new P(o),new CliSubAgentClient),r=process.env.DEVFLOW_SERVER_URL??"http://127.0.0.1:13337",s=process.env.DEVFLOW_API_KEY??"dev-key-000000",n=new DevFlowApiClient({baseUrl:r,projectRoot:e.projectRoot,apiKey:s}),a=await n.ping(),c=await loadPlugins(),l=Array.from(c.values()),d=A(),p=O(l),u=[...d,...p];o.setRequestHandler(ListToolsRequestSchema,async()=>({tools:u})),o.setRequestHandler(ListResourcesRequestSchema,async()=>{if(a)return {resources:[]};let w=await C();return V(w)}),o.setRequestHandler(ReadResourceRequestSchema,async w=>{if(a)throw new Error("Resources not available in remote mode");let i=await C();return z(w.params.uri,i)}),o.setRequestHandler(ListPromptsRequestSchema,async()=>X()),o.setRequestHandler(GetPromptRequestSchema,async w=>Q(w.params.name,w.params.arguments??{}));let m=null;async function C(){if(m)return m;let[{createEngines:w}]=await Promise.all([import('@devflow-tools/context-engine')]),i=2;for(;i>0;)try{m=await w(e.projectRoot,t);break}catch(v){if(i--,i===0)throw v;console.error(`[devflow-mcp] createEngines failed, retrying... (${i} left):`,v.message),await new Promise(y=>setTimeout(y,1500));}for(let v of l)for(let y of v.workflow?.templates??[])m.workflow.register(y);return console.error(`[devflow-mcp] Warning: DevFlow server not reachable at ${r}`),console.error("[devflow-mcp] Running in local mode."),m}let we=new Set(d.map(w=>w.name));o.setRequestHandler(CallToolRequestSchema,async w=>{let{name:i,arguments:v}=w.params,y=v??{},M=Date.now(),g=0;try{let f;if(we.has(i)&&a){f=await et(n,i,y),pe(e.projectRoot,i),g=Date.now()-M;let h=i.split("_")[0];try{await n.recordTelemetryEvent({toolName:i,args:y,durationMs:g,success:!0,pluginName:h,metadata:{projectRoot:e.projectRoot}});}catch(b){console.error("[devflow-mcp] Failed to record telemetry:",b);}try{await n.recordMemoryEvent({id:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:`session:${e.projectRoot.split("/").pop()??"default"}`,tool:i,command:R(i)||i,exitCode:0,durationMs:g});}catch(b){console.error("[devflow-mcp] Failed to record memory event:",b);}}else {let h=await C(),{enforce:b}=await Promise.resolve().then(()=>(de(),ue)),_=await b(i,y,h.data);if(!_.result.allowed)return {content:[{type:"text",text:JSON.stringify({_devflow:{v:1,tool:i,ts:Date.now(),marker:"devflow-mcp-v1"},error:_.result.message,rule:_.result.rule?.id})}],isError:!0};let{createToolHandlers:_e,createPluginHandlers:ve}=await Promise.resolve().then(()=>(I(),B)),ke=_e(h),be=ve(h,l),U={...ke,...be}[i];if(!U)throw new Error(`Unknown tool: ${i}`);f=await U(y),pe(e.projectRoot,i),g=Date.now()-M;try{await h.data.recordToolCall(i,y,g);let G=i.startsWith("devflow_")||i.includes("_"),xe=i.split("_")[0],q=ge.has(xe);await h.telemetry.recordToolCall({eventId:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,executionId:`exec:${e.projectRoot.split("/").pop()??"default"}:${Date.now()}`,timestamp:Date.now(),toolName:i,toolType:G||q?"mcp":"direct",isMcpTool:G||q,mcpToolName:q?i:void 0,mcpEnforced:!0,mcpFallback:!1,input:y,output:Ye(f),tokensUsed:0,duration:g,blocked:!1});}catch{}try{await h.memory.recordEvent({id:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:`session:${e.projectRoot.split("/").pop()??"default"}`,tool:i,command:R(i)||i,exitCode:0,stderr:void 0,durationMs:g,createdAt:Date.now()}),h.memory.processSessionEvents().catch(()=>{});}catch{}_.receipt&&(f={...f,_receipt:_.receipt}),_.result.warning&&(f={...f,_warning:_.result.warning});}let he=Qe(i,f,g);return {content:[{type:"text",text:JSON.stringify(he,null,2)}]}}catch(f){if(g=Date.now()-M,a){try{await n.recordTelemetryEvent({toolName:i,args:y,durationMs:g,success:!1,error:f.message,pluginName:i.split("_")[0],metadata:{projectRoot:e.projectRoot}});}catch(E){console.error("[devflow-mcp] Failed to record error telemetry:",E);}try{await n.recordMemoryEvent({id:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:`session:${e.projectRoot.split("/").pop()??"default"}`,tool:i,command:R(i)||i,exitCode:1,stderr:f.message,durationMs:g});}catch(E){console.error("[devflow-mcp] Failed to record error memory event:",E);}}else if(m){try{await m.data.recordToolCall(i,y,g,f.message);}catch{}try{await m.memory.recordEvent({id:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:`session:${e.projectRoot.split("/").pop()??"default"}`,tool:i,command:R(i)||i,exitCode:1,stderr:f.message,durationMs:g,createdAt:Date.now()});}catch{}}return {content:[{type:"text",text:`Error: ${f.message}`}],isError:true}}});let ye=new StdioServerTransport;await o.connect(ye);}function ze(e){if(process.env.DEVFLOW_SESSION_TOKEN)return;let o=Buffer.from(JSON.stringify({alg:"HS256",typ:"JWT"})).toString("base64url"),t=Math.floor(Date.now()/1e3),r={sub:`devflow-mcp-${Date.now().toString(36)}`,project:e.split("/").pop()??"unknown",iat:t,exp:t+86400,scope:["context","knowledge","memory","workflow","graph"]},s=Buffer.from(JSON.stringify(r)).toString("base64url"),a=createHmac("sha256","devflow-local-mcp-secret-v1").update(`${o}.${s}`).digest("base64url");process.env.DEVFLOW_SESSION_TOKEN=`${o}.${s}.${a}`;let c=`session:${r.project}:${Date.now().toString(36)}`;process.env.DEVFLOW_SESSION_ID=c,console.error("[devflow-mcp] Auto-generated session token (no env token provided).");}var ge=new Set(["react","vue","nest","nextjs","graphql","docker","tailwind","taro","electron","performance"]);function R(e){let o={get_project_context:"context",search_symbol:"context",get_dependency_graph:"graph",get_knowledge:"knowledge",get_memory:"memory",run_workflow:"workflow"};if(o[e])return `devflow:${o[e]}`;let t=e.split("_")[0];return ge.has(t)?`devflow:${t}`:""}function pe(e,o){try{let t=process.env.TMPDIR||"/tmp",r=join(t,".devflow-receipts"),s=createHash("sha256").update(e).digest("hex").slice(0,16),n=join(r,`${s}.json`);existsSync(r)||mkdirSync(r,{recursive:!0});let a={};if(existsSync(n))try{a=JSON.parse(readFileSync(n,"utf-8"));}catch{}a.lastMcpCall=Date.now(),a.bypassCount=0;let c=R(o);c&&(a.activeCommand=c),writeFileSync(n,JSON.stringify(a));}catch{}}function Ye(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let{_devflow:o,_receipt:t,_warning:r,...s}=e;return Object.keys(s).length>0?s:e}return e}function Xe(e){try{let o=join(e,"apps/mcp-server/src"),t=join(e,"apps/mcp-server/dist");if(!existsSync(o)||!existsSync(t))return;let r=W(o),s=W(t);r>s&&console.error("[devflow-mcp] WARNING: dist/ is stale. Source files newer than build output. Run: npm run build --workspace=apps/mcp-server");}catch{}}function W(e){let o=0;try{let{readdirSync:t}=Re("fs"),r=t(e,{withFileTypes:!0});for(let s of r){let n=join(e,s.name);s.isDirectory()?o=Math.max(o,W(n)):o=Math.max(o,statSync(n).mtimeMs);}}catch{}return o}function Qe(e,o,t){let r={_devflow:{v:1,tool:e,ts:Date.now(),marker:"devflow-mcp-v1",...t!==void 0?{took_ms:t}:{}}};return o&&typeof o=="object"&&!Array.isArray(o)?{...o,...r}:{result:o,...r}}async function Ze(){let e=new Map,o=await loadPlugins(),t=Array.from(o.values());for(let r of t){let s=r.meta.name;for(let n of r.workflow?.templates??[]){let a=n.triggers?.find(c=>c.type==="mcp");if(a?.tool){let c=`${s}_${a.tool}`;e.set(c,n.name);}}}return e}async function et(e,o,t){switch(o){case "get_project_context":return e.buildContext(t.query,t.mode??"fast");case "search_symbol":return e.searchSymbol(t.symbol);case "get_dependency_graph":return e.getGraph(t.target??"all",t.depth??2);case "run_workflow":return e.runWorkflow(t.type,t.input);case "get_memory":return e.getMemory();case "get_knowledge":return e.searchKnowledge(t.query,t.scope??"all");case "devflow_report_event":return e.recordEvent(t);default:{let s=(await Ze()).get(o)??o;return e.runWorkflow(s,t)}}}async function tt(){let e=process.env.DEVFLOW_PROJECT_ROOT||process.cwd();await fe({mode:"stdio",projectRoot:e});}tt().catch(e=>{console.error("MCP Server error:",e),process.exit(1);});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devflow-tools/devflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "DevFlow - Developer Intelligence Platform (Distribution Package)",
|
|
6
6
|
"bin": {
|
|
@@ -15,17 +15,17 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@colbymchenry/codegraph": "^1.1.1",
|
|
18
|
-
"@devflow-tools/adapters": "^0.
|
|
19
|
-
"@devflow-tools/benchmark": "^0.
|
|
20
|
-
"@devflow-tools/context-engine": "^0.
|
|
21
|
-
"@devflow-tools/database": "^0.
|
|
22
|
-
"@devflow-tools/knowledge-engine": "^0.
|
|
23
|
-
"@devflow-tools/mcp-server": "^0.
|
|
24
|
-
"@devflow-tools/memory-engine": "^0.
|
|
25
|
-
"@devflow-tools/sdk": "^0.
|
|
26
|
-
"@devflow-tools/server": "^0.
|
|
27
|
-
"@devflow-tools/telemetry": "^0.
|
|
28
|
-
"@devflow-tools/workflow-engine": "^0.
|
|
18
|
+
"@devflow-tools/adapters": "^0.11.0",
|
|
19
|
+
"@devflow-tools/benchmark": "^0.11.0",
|
|
20
|
+
"@devflow-tools/context-engine": "^0.11.0",
|
|
21
|
+
"@devflow-tools/database": "^0.11.0",
|
|
22
|
+
"@devflow-tools/knowledge-engine": "^0.11.0",
|
|
23
|
+
"@devflow-tools/mcp-server": "^0.11.0",
|
|
24
|
+
"@devflow-tools/memory-engine": "^0.11.0",
|
|
25
|
+
"@devflow-tools/sdk": "^0.11.0",
|
|
26
|
+
"@devflow-tools/server": "^0.11.0",
|
|
27
|
+
"@devflow-tools/telemetry": "^0.11.0",
|
|
28
|
+
"@devflow-tools/workflow-engine": "^0.11.0",
|
|
29
29
|
"@inquirer/prompts": "^7.10.1",
|
|
30
30
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
31
31
|
"@nestjs/common": "^10.4.0",
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"plugin-registry.json",
|
|
53
53
|
"scripts/postinstall.js"
|
|
54
54
|
],
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "ff6ac69b0f3cc95cb32ffe8bcbf21b24767aa914"
|
|
56
56
|
}
|
package/plugin-registry.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1.0.0",
|
|
3
|
-
"lastUpdated": "2026-07-
|
|
3
|
+
"lastUpdated": "2026-07-11T08:12:49.883Z",
|
|
4
4
|
"plugins": [
|
|
5
5
|
{
|
|
6
6
|
"name": "@devflow-tools/plugin-animation",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.10.0",
|
|
8
8
|
"description": "",
|
|
9
9
|
"tags": [],
|
|
10
10
|
"compatibleStacks": [
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"name": "@devflow-tools/claude-code-plugin",
|
|
19
|
-
"version": "0.
|
|
19
|
+
"version": "0.10.0",
|
|
20
20
|
"description": "DevFlow — Developer Intelligence Platform for Claude Code",
|
|
21
21
|
"tags": [
|
|
22
22
|
"pi-package",
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
"knowledge-base"
|
|
27
27
|
],
|
|
28
28
|
"compatibleStacks": [],
|
|
29
|
-
"size": "
|
|
29
|
+
"size": "280K",
|
|
30
30
|
"author": "DevFlow Team",
|
|
31
31
|
"homepage": ""
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
"name": "@devflow-tools/plugin-css",
|
|
35
|
-
"version": "0.
|
|
35
|
+
"version": "0.10.0",
|
|
36
36
|
"description": "",
|
|
37
37
|
"tags": [],
|
|
38
38
|
"compatibleStacks": [
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
"name": "@devflow-tools/plugin-docker",
|
|
47
|
-
"version": "0.
|
|
47
|
+
"version": "0.10.0",
|
|
48
48
|
"description": "",
|
|
49
49
|
"tags": [],
|
|
50
50
|
"compatibleStacks": [
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"name": "@devflow-tools/plugin-electron",
|
|
59
|
-
"version": "0.
|
|
59
|
+
"version": "0.10.0",
|
|
60
60
|
"description": "",
|
|
61
61
|
"tags": [],
|
|
62
62
|
"compatibleStacks": [
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"name": "@devflow-tools/plugin-git",
|
|
71
|
-
"version": "0.
|
|
71
|
+
"version": "0.10.0",
|
|
72
72
|
"description": "",
|
|
73
73
|
"tags": [],
|
|
74
74
|
"compatibleStacks": [
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
82
|
"name": "@devflow-tools/plugin-graphql",
|
|
83
|
-
"version": "0.
|
|
83
|
+
"version": "0.10.0",
|
|
84
84
|
"description": "",
|
|
85
85
|
"tags": [],
|
|
86
86
|
"compatibleStacks": [
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
94
|
"name": "@devflow-tools/plugin-nest",
|
|
95
|
-
"version": "0.
|
|
95
|
+
"version": "0.10.0",
|
|
96
96
|
"description": "",
|
|
97
97
|
"tags": [],
|
|
98
98
|
"compatibleStacks": [
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
106
|
"name": "@devflow-tools/plugin-nextjs",
|
|
107
|
-
"version": "0.
|
|
107
|
+
"version": "0.10.0",
|
|
108
108
|
"description": "",
|
|
109
109
|
"tags": [],
|
|
110
110
|
"compatibleStacks": [
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
},
|
|
117
117
|
{
|
|
118
118
|
"name": "@devflow-tools/plugin-performance",
|
|
119
|
-
"version": "0.
|
|
119
|
+
"version": "0.10.0",
|
|
120
120
|
"description": "",
|
|
121
121
|
"tags": [],
|
|
122
122
|
"compatibleStacks": [
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
},
|
|
129
129
|
{
|
|
130
130
|
"name": "@devflow-tools/plugin-react",
|
|
131
|
-
"version": "0.
|
|
131
|
+
"version": "0.10.0",
|
|
132
132
|
"description": "",
|
|
133
133
|
"tags": [],
|
|
134
134
|
"compatibleStacks": [
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
},
|
|
141
141
|
{
|
|
142
142
|
"name": "@devflow-tools/plugin-tailwind",
|
|
143
|
-
"version": "0.
|
|
143
|
+
"version": "0.10.0",
|
|
144
144
|
"description": "",
|
|
145
145
|
"tags": [],
|
|
146
146
|
"compatibleStacks": [
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
},
|
|
153
153
|
{
|
|
154
154
|
"name": "@devflow-tools/plugin-taro",
|
|
155
|
-
"version": "0.
|
|
155
|
+
"version": "0.10.0",
|
|
156
156
|
"description": "",
|
|
157
157
|
"tags": [],
|
|
158
158
|
"compatibleStacks": [
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
},
|
|
165
165
|
{
|
|
166
166
|
"name": "@devflow-tools/plugin-ui-layout",
|
|
167
|
-
"version": "0.
|
|
167
|
+
"version": "0.10.0",
|
|
168
168
|
"description": "",
|
|
169
169
|
"tags": [],
|
|
170
170
|
"compatibleStacks": [
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
},
|
|
177
177
|
{
|
|
178
178
|
"name": "@devflow-tools/plugin-vue",
|
|
179
|
-
"version": "0.
|
|
179
|
+
"version": "0.10.0",
|
|
180
180
|
"description": "",
|
|
181
181
|
"tags": [],
|
|
182
182
|
"compatibleStacks": [
|