@devflow-tools/claude-code-plugin 0.13.0 → 0.13.2

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.
@@ -64,11 +64,11 @@
64
64
  "devflow:react": {
65
65
  "mcpTools": [
66
66
  "react_diagnose_bug",
67
+ "react_new_feature",
67
68
  "react_audit_performance",
68
- "react_new_component",
69
69
  "react_review_hooks",
70
70
  "react_refactor_component",
71
- "react_new_feature"
71
+ "react_new_component"
72
72
  ],
73
73
  "blockedNative": [
74
74
  "grep",
@@ -85,8 +85,8 @@
85
85
  "devflow:vue": {
86
86
  "mcpTools": [
87
87
  "vue_diagnose_bug",
88
- "vue_debug_reactivity",
89
- "vue_new_component"
88
+ "vue_new_component",
89
+ "vue_debug_reactivity"
90
90
  ],
91
91
  "blockedNative": [
92
92
  "grep",
@@ -102,8 +102,8 @@
102
102
  },
103
103
  "devflow:nest": {
104
104
  "mcpTools": [
105
- "nest_diagnose_bug",
106
- "nest_new_module"
105
+ "nest_new_module",
106
+ "nest_diagnose_bug"
107
107
  ],
108
108
  "blockedNative": [
109
109
  "grep",
@@ -119,8 +119,8 @@
119
119
  },
120
120
  "devflow:nextjs": {
121
121
  "mcpTools": [
122
- "nextjs_diagnose_bug",
123
- "nextjs_new_page"
122
+ "nextjs_new_page",
123
+ "nextjs_diagnose_bug"
124
124
  ],
125
125
  "blockedNative": [
126
126
  "grep",
@@ -136,8 +136,8 @@
136
136
  },
137
137
  "devflow:graphql": {
138
138
  "mcpTools": [
139
- "graphql_diagnose_bug",
140
- "graphql_new_graphql_type"
139
+ "graphql_new_graphql_type",
140
+ "graphql_diagnose_bug"
141
141
  ],
142
142
  "blockedNative": [
143
143
  "grep",
@@ -249,8 +249,7 @@
249
249
  },
250
250
  "devflow:tailwind": {
251
251
  "mcpTools": [
252
- "tailwind_new_component",
253
- "tailwind_optimize_classes"
252
+ "tailwind_new_component"
254
253
  ],
255
254
  "blockedNative": [
256
255
  "grep",
@@ -1,2 +1,2 @@
1
- import {request}from'http';import {existsSync,readFileSync,writeFileSync,mkdirSync}from'fs';import {join,dirname}from'path';import {homedir}from'os';import {createHash}from'crypto';import {fileURLToPath}from'url';var W=process.env.DEVFLOW_SERVER_URL||"http://127.0.0.1:13337",$=process.env.DEVFLOW_API_KEY||"dev-key-000000",I=process.env.CLAUDE_PROJECT_DIR||process.cwd(),D=join(homedir(),".devflow","session-id"),b=join(homedir(),".devflow","event-map.json"),F=new Set(["Agent","Bash","Glob","Grep","WebSearch","WebFetch"]);function R(e,n){return new Promise(t=>{let o=JSON.stringify(n),s=new URL(e,W),i=request({hostname:s.hostname,port:s.port,path:s.pathname,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":$,"Content-Length":Buffer.byteLength(o)},timeout:5e3},()=>t());i.on("error",()=>t()),i.write(o),i.end();})}function q(){try{if(existsSync(D))return readFileSync(D,"utf-8").trim()}catch{}return null}function B(e,n){try{if(!existsSync(b))return null;let t=JSON.parse(readFileSync(b,"utf-8")),o=t.filter(u=>u.toolName===e);if(o.length===0)return null;let s=n??Date.now();o.sort((u,f)=>Math.abs(u.timestamp-s)-Math.abs(f.timestamp-s));let i=o[0],a=t.findIndex(u=>u.eventId===i.eventId);return a!==-1&&t.splice(a,1),writeFileSync(b,JSON.stringify(t)),{eventId:i.eventId,timestamp:i.timestamp}}catch{return null}}var _=join(homedir(),".devflow");function K(){existsSync(_)||mkdirSync(_,{recursive:true});}function V(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{let e=fileURLToPath(import.meta.url);return join(dirname(e),"..","..")}catch{return process.cwd()}}function G(){let e=V(),n=[join(e,"dist","command-registry.json"),join(e,"command-registry.json")];for(let t of n)try{if(existsSync(t)){let o=JSON.parse(readFileSync(t,"utf8")).commands;if(o)return o}}catch{}return null}function Y(e){let n=G();return n?n[e]?.mcpTools??[]:[]}function z(e){K();let n=join(_,"current-execution-id");if(existsSync(n))return;let t=`exec_${Date.now()}_${Math.random().toString(36).slice(2,11)}`;writeFileSync(n,t),writeFileSync(join(_,"current-skill.json"),JSON.stringify({name:e,required_mcp_tools:Y(e),registeredAt:Date.now()}));}function P(){let e=createHash("sha256").update(I).digest("hex").slice(0,16);return join(process.env.TMPDIR||"/tmp",".devflow-receipts",`${e}.json`)}function H(){try{let e=P();return existsSync(e)?JSON.parse(readFileSync(e,"utf-8")):{}}catch{return {}}}function O(e){try{let n=P(),t=join(process.env.TMPDIR||"/tmp",".devflow-receipts");existsSync(t)||mkdirSync(t,{recursive:!0}),writeFileSync(n,JSON.stringify(e));}catch{}}function X(e){if(!F.has(e))return null;let n=H(),t=(n.bypassCount??0)+1;return O({...n,bypassCount:t}),t>20&&t%10===0?`MCP \u5DE5\u5177\u4F7F\u7528\u7387\u4F4E\uFF1A${t} \u6B21\u76F4\u63A5\u5DE5\u5177\u8C03\u7528\u3002\u5EFA\u8BAE\u4F7F\u7528 get_project_context \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`:null}async function Q(e){if(!e)return null;let n;try{n=JSON.parse(e);}catch{return null}let t=n.tool_name||"",o=n.tool_input||{},s=n.tool_response||{},i=q();if(t==="Skill"){let r=typeof o=="object"&&o.skill?o.skill:"";r&&r.startsWith("devflow:")&&(z(r),O({lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}t.startsWith("mcp__")&&O({lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});let a=B(t,Date.now());if(a&&i){let r=typeof s=="string"?s:JSON.stringify(s),v=r.length>5e3?{_truncated:true,_originalSize:r.length,text:r.slice(0,5e3)}:s,l=Date.now()-a.timestamp;R("/api/telemetry/tool-call/output",{eventId:a.eventId,sessionId:i,output:v,duration:l,completedAt:Date.now()}).catch(()=>{});}let u=typeof o=="object"&&o.command?o.command:"",f=typeof s=="object"&&s!==null?s:null,h=f?.exitCode,C=f?.stderr;if(t==="Bash"&&h!==void 0&&h!==0){let r={id:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:i??`session:${I.split("/").pop()||"default"}`,tool:t,command:u||t,exitCode:h,stderr:C??null,durationMs:0,createdAt:Date.now()};R(`/api/memory/events?rootPath=${encodeURIComponent(I)}`,r).catch(()=>{});}let T=["get_project_context","get_knowledge","get_memory","search_symbol","get_dependency_graph","react_diagnose_bug","react_new_component","react_audit_performance","vue_diagnose_bug","nest_diagnose_bug","nextjs_diagnose_bug","electron_diagnose_bug","graphql_diagnose_bug","run_workflow"],d=t.replace("mcp__devflow__","");if(t.startsWith("mcp__devflow__")&&T.includes(d)){let r=typeof s=="object"&&s!==null?s:null,v=["files","results","data","result","memories","nodes","chunks"],l=0,m=r?.data??r;if(Array.isArray(m))l=m.length;else if(typeof m=="object"&&m!==null){let S=m;for(let E of v)Array.isArray(S[E])&&(l+=S[E].length);l===0&&Object.keys(S).length>0&&(l=1);}let j=JSON.stringify(s),x=Buffer.byteLength(j,"utf8"),M={id:`metric:${Date.now()}:${Math.random().toString(36).slice(2,11)}`,toolCallEventId:a?.eventId??`unknown:${Date.now()}`,sessionId:i??"",toolName:d,query:typeof o=="object"&&o.query?o.query:void 0,status:r?.error?"error":l===0?"empty":"success",resultCount:l,resultSizeBytes:x,latencyMs:a?Date.now()-a.timestamp:0,engine:d.startsWith("get_project_context")||d==="search_symbol"||d==="get_dependency_graph"?"codegraph":d==="get_knowledge"?"knowledge":d==="get_memory"?"memory":void 0};R("/api/telemetry/tool-metrics",M).catch(()=>{});}let w=X(t);return w&&console.error("[devflow] Enforcement:",w),w}if(process.argv[1]?.endsWith("post-tool-use")||process.argv[1]?.endsWith("post-tool-use.js")){let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n;}),process.stdin.on("end",async()=>{let n=await Q(e.trim()||process.argv[2]||"");if(n){let t=JSON.stringify(n);console.log(JSON.stringify({hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:t}}));}}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),5e3).unref();}
2
- export{Q as handlePostToolUse};
1
+ import {request}from'http';import {existsSync,readFileSync,writeFileSync,mkdirSync}from'fs';import {join,dirname}from'path';import {homedir}from'os';import {createHash}from'crypto';import {fileURLToPath}from'url';import {getLogWriter}from'@devflow-tools/telemetry';var J=process.env.DEVFLOW_SERVER_URL||"http://127.0.0.1:13337",W=process.env.DEVFLOW_API_KEY||"dev-key-000000",g=process.env.CLAUDE_PROJECT_DIR||process.cwd(),O=join(homedir(),".devflow","session-id"),v=join(homedir(),".devflow","event-map.json"),F=new Set(["Agent","Bash","Glob","Grep","WebSearch","WebFetch"]);function S(e,n){return new Promise(t=>{let r=JSON.stringify(n),o=new URL(e,J),c=request({hostname:o.hostname,port:o.port,path:o.pathname,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":W,"Content-Length":Buffer.byteLength(r)},timeout:5e3},()=>t());c.on("error",()=>t()),c.write(r),c.end();})}function U(){try{if(existsSync(O))return readFileSync(O,"utf-8").trim()}catch{}return null}function $(e,n){try{if(!existsSync(v))return null;let t=JSON.parse(readFileSync(v,"utf-8")),r=t.filter(s=>s.toolName===e);if(r.length===0)return null;let o=n??Date.now();r.sort((s,d)=>Math.abs(s.timestamp-o)-Math.abs(d.timestamp-o));let c=r[0],a=t.findIndex(s=>s.eventId===c.eventId);return a!==-1&&t.splice(a,1),writeFileSync(v,JSON.stringify(t)),{eventId:c.eventId,timestamp:c.timestamp}}catch{return null}}function D(e){if(!e)return 0;let n=e;if(typeof e=="string")try{n=JSON.parse(e);}catch{return 1}let t=n,r=["files","results","data","result","memories","nodes","chunks","findings","symbols"],o=t.data??t.structuredContent??t;if(Array.isArray(o))return o.length;if(typeof o=="object"&&o!==null){let c=o,a=0;for(let s of r)Array.isArray(c[s])&&(a+=c[s].length);for(let[,s]of Object.entries(c))s&&typeof s=="object"&&!Array.isArray(s)&&(a+=D(s));return a>0?a:Object.keys(c).length>0?1:0}return 0}var p=join(homedir(),".devflow");function q(){existsSync(p)||mkdirSync(p,{recursive:true});}function B(){if(process.env.CLAUDE_PLUGIN_ROOT)return process.env.CLAUDE_PLUGIN_ROOT;try{let e=fileURLToPath(import.meta.url);return join(dirname(e),"..","..")}catch{return process.cwd()}}function K(){let e=B(),n=[join(e,"dist","command-registry.json"),join(e,"command-registry.json")];for(let t of n)try{if(existsSync(t)){let r=JSON.parse(readFileSync(t,"utf8")).commands;if(r)return r}}catch{}return null}function V(e){let n=K();return n?n[e]?.mcpTools??[]:[]}function G(e){q();let n=join(p,"current-execution-id");if(existsSync(n))return;let t=`exec_${Date.now()}_${Math.random().toString(36).slice(2,11)}`;writeFileSync(n,t),writeFileSync(join(p,"current-skill.json"),JSON.stringify({name:e,required_mcp_tools:V(e),registeredAt:Date.now()}));}function E(){let e=createHash("sha256").update(g).digest("hex").slice(0,16);return join(process.env.TMPDIR||"/tmp",".devflow-receipts",`${e}.json`)}function Y(){try{let e=E();return existsSync(e)?JSON.parse(readFileSync(e,"utf-8")):{}}catch{return {}}}function R(e){try{let n=E(),t=join(process.env.TMPDIR||"/tmp",".devflow-receipts");existsSync(t)||mkdirSync(t,{recursive:!0}),writeFileSync(n,JSON.stringify(e));}catch{}}function z(e){if(!F.has(e))return null;let n=Y(),t=(n.bypassCount??0)+1;return R({...n,bypassCount:t}),t>20&&t%10===0?`MCP \u5DE5\u5177\u4F7F\u7528\u7387\u4F4E\uFF1A${t} \u6B21\u76F4\u63A5\u5DE5\u5177\u8C03\u7528\u3002\u5EFA\u8BAE\u4F7F\u7528 get_project_context \u83B7\u53D6\u66F4\u7CBE\u786E\u7684\u4E0A\u4E0B\u6587\u3002`:null}async function H(e){if(!e)return null;let n;try{n=JSON.parse(e);}catch{return null}let t=n.tool_name||"",r=n.tool_input||{},o=n.tool_response||{},c=U();if(t==="Skill"){let i=typeof r=="object"&&r.skill?r.skill:"";i&&i.startsWith("devflow:")&&(G(i),R({lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0}));}t.startsWith("mcp__")&&R({lastMcpCall:Math.floor(Date.now()/1e3),bypassCount:0});let a=join(p,"current-execution-id"),s=$(t,Date.now()),d=typeof o=="object"&&o!==null?o:null,N=JSON.stringify(o),b=Buffer.byteLength(N,"utf8"),h=D(o);if(existsSync(a)||t.startsWith("mcp__devflow__")||t==="Skill"){let i=getLogWriter(g),f=existsSync(a)?readFileSync(a,"utf-8").trim():`auto-${Date.now()}`;i.toolCall({tool:t,runId:f,stepId:`step-${f}`,input:r,output:o,duration:s?Date.now()-s.timestamp:0,success:!d?.error,resultCount:h,resultSizeBytes:b,error:d?.error});}if(s&&c){let i=typeof o=="string"?o:JSON.stringify(o),f=i.length>5e3?{_truncated:true,_originalSize:i.length,text:i.slice(0,5e3)}:o,T=Date.now()-s.timestamp;S("/api/telemetry/tool-call/output",{eventId:s.eventId,sessionId:c,output:f,duration:T,completedAt:Date.now()}).catch(()=>{});}if(t.startsWith("mcp__devflow__")){let i=t.replace("mcp__devflow__","");S("/api/telemetry/tool-metrics",{id:`metric:${Date.now()}:${Math.random().toString(36).slice(2,11)}`,toolCallEventId:s?.eventId??`unknown:${Date.now()}`,sessionId:c??"",toolName:i,query:typeof r=="object"&&r.query?r.query:void 0,status:d?.error?"error":h===0?"empty":"success",resultCount:h,resultSizeBytes:b,latencyMs:s?Date.now()-s.timestamp:0,engine:i.startsWith("get_project_context")||i==="search_symbol"||i==="get_dependency_graph"?"codegraph":i==="get_knowledge"?"knowledge":i==="get_memory"?"memory":void 0}).catch(()=>{});}let C=typeof r=="object"&&r.command?r.command:"",w=d?.exitCode,P=d?.stderr;if(t==="Bash"&&w!==void 0&&w!==0){let i={id:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:c??`session:${g.split("/").pop()||"default"}`,tool:t,command:C||t,exitCode:w,stderr:P??null,durationMs:0,createdAt:Date.now()};S(`/api/memory/events?rootPath=${encodeURIComponent(g)}`,i).catch(()=>{});}let _=z(t);return _&&console.error("[devflow] Enforcement:",_),_}if(process.argv[1]?.endsWith("post-tool-use")||process.argv[1]?.endsWith("post-tool-use.js")){let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n;}),process.stdin.on("end",async()=>{let n=await H(e.trim()||process.argv[2]||"");if(n){let t=JSON.stringify(n);console.log(JSON.stringify({hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:t}}));}}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),5e3).unref();}
2
+ export{H as handlePostToolUse};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/claude-code-plugin",
3
- "version": "0.13.0",
3
+ "version": "0.13.2",
4
4
  "description": "DevFlow — Developer Intelligence Platform for Claude Code",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -8,7 +8,7 @@
8
8
  "deploy": "npx tsx scripts/inject-gates.ts --deploy"
9
9
  },
10
10
  "devDependencies": {
11
- "@devflow-tools/mcp-server": "^0.13.0"
11
+ "@devflow-tools/mcp-server": "^0.13.1"
12
12
  },
13
13
  "keywords": [
14
14
  "pi-package",
@@ -28,5 +28,5 @@
28
28
  "hooks.json",
29
29
  "skills"
30
30
  ],
31
- "gitHead": "6e5878a1ab2bba3a21bd42a5f7e236d4f7375d4f"
31
+ "gitHead": "5faddeb8fb94ca2720ff5574daf6fb3d7cdb7546"
32
32
  }