@devflow-tools/devflow 0.8.10 → 0.9.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.
Files changed (33) hide show
  1. package/README.md +34 -21
  2. package/dist/hooks/post-tool-use.js +2 -0
  3. package/dist/hooks/pre-tool-use.js +2 -2
  4. package/dist/hooks/stop.js +2 -0
  5. package/package.json +14 -14
  6. package/plugin-registry.json +40 -24
  7. package/dist/cli.js +0 -46
  8. package/dist/fallback.html +0 -106
  9. package/dist/mcp-server.js +0 -2
  10. package/dist/plugin/hooks.json +0 -40
  11. package/dist/plugin/skills/devflow/SKILL.md +0 -20
  12. package/dist/plugin/skills/devflow:animation/SKILL.md +0 -39
  13. package/dist/plugin/skills/devflow:context/SKILL.md +0 -44
  14. package/dist/plugin/skills/devflow:css/SKILL.md +0 -39
  15. package/dist/plugin/skills/devflow:docker/SKILL.md +0 -62
  16. package/dist/plugin/skills/devflow:doctor/SKILL.md +0 -17
  17. package/dist/plugin/skills/devflow:electron/SKILL.md +0 -62
  18. package/dist/plugin/skills/devflow:git/SKILL.md +0 -43
  19. package/dist/plugin/skills/devflow:graph/SKILL.md +0 -37
  20. package/dist/plugin/skills/devflow:graphql/SKILL.md +0 -63
  21. package/dist/plugin/skills/devflow:knowledge/SKILL.md +0 -37
  22. package/dist/plugin/skills/devflow:memory/SKILL.md +0 -36
  23. package/dist/plugin/skills/devflow:nest/SKILL.md +0 -63
  24. package/dist/plugin/skills/devflow:nextjs/SKILL.md +0 -60
  25. package/dist/plugin/skills/devflow:performance/SKILL.md +0 -62
  26. package/dist/plugin/skills/devflow:react/SKILL.md +0 -80
  27. package/dist/plugin/skills/devflow:start/SKILL.md +0 -54
  28. package/dist/plugin/skills/devflow:tailwind/SKILL.md +0 -58
  29. package/dist/plugin/skills/devflow:taro/SKILL.md +0 -61
  30. package/dist/plugin/skills/devflow:ui-layout/SKILL.md +0 -39
  31. package/dist/plugin/skills/devflow:vue/SKILL.md +0 -69
  32. package/dist/plugin/skills/devflow:workflow/SKILL.md +0 -37
  33. package/dist/server.js +0 -10
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @devflow-tools/devflow
2
2
 
3
- DevFlow 主发行包 - 开发者智能平台
3
+ DevFlow 主发行包 — 开发者智能平台,一键安装所有核心能力。
4
4
 
5
5
  ## 安装
6
6
 
@@ -11,40 +11,53 @@ npm install -g @devflow-tools/devflow
11
11
  ## 使用
12
12
 
13
13
  ```bash
14
- # 初始化项目
14
+ # 初始化项目(自动生成 Onboarding Pack)
15
+ cd your-project
15
16
  devflow init
16
17
 
17
18
  # 启动服务
18
19
  devflow start
19
20
 
20
- # 查看可用插件
21
- devflow plugin list
21
+ # 连接 AI Agent
22
+ devflow connect claude
22
23
 
23
- # 安装插件
24
- devflow plugin install @devflow-tools/plugin-react
25
- ```
24
+ # 查看索引状态
25
+ devflow index
26
26
 
27
- ## 系统要求
27
+ # 依赖图谱
28
+ devflow graph src/App.tsx --depth 3
28
29
 
29
- - Node.js >= 22.0.0
30
+ # 上下文检索
31
+ devflow context "fix the login bug"
30
32
 
31
- ## 插件
33
+ # 工作流管理
34
+ devflow workflow list
35
+ devflow workflow run bugfix
32
36
 
33
- DevFlow 支持丰富的插件生态,可以通过以下命令管理插件:
37
+ # 查看记忆
38
+ devflow memory show
34
39
 
35
- ```bash
36
- # 列出所有可用插件
37
- devflow plugin list
40
+ # 搜索知识库
41
+ devflow knowledge useState
42
+ ```
38
43
 
39
- # 搜索插件
40
- devflow plugin search react
44
+ ## 包含的包
41
45
 
42
- # 安装插件
43
- devflow plugin install @devflow-tools/plugin-react
46
+ 此发行包聚合了以下 DevFlow 核心模块:
44
47
 
45
- # 卸载插件
46
- devflow plugin uninstall @devflow-tools/plugin-react
47
- ```
48
+ - `@devflow-tools/server` — REST API 服务端 (NestJS + Fastify)
49
+ - `@devflow-tools/cli` — CLI 命令行工具
50
+ - `@devflow-tools/mcp-server` — MCP 协议服务端
51
+ - `@devflow-tools/context-engine` — 上下文构建引擎
52
+ - `@devflow-tools/memory-engine` — 项目记忆引擎
53
+ - `@devflow-tools/knowledge-engine` — 知识库引擎
54
+ - `@devflow-tools/workflow-engine` — 工作流引擎
55
+ - `@devflow-tools/telemetry` — 遥测与追踪
56
+ - `@devflow-tools/database` — SQLite 持久化存储
57
+
58
+ ## 系统要求
59
+
60
+ - Node.js >= 18
48
61
 
49
62
  ## 许可证
50
63
 
@@ -0,0 +1,2 @@
1
+ import {request}from'http';import {existsSync,readFileSync,writeFileSync}from'fs';import {join}from'path';import {homedir}from'os';var k=process.env.DEVFLOW_SERVER_URL||"http://127.0.0.1:13337",P=process.env.DEVFLOW_API_KEY||"dev-key-000000",y=process.env.CLAUDE_PROJECT_DIR||process.cwd(),h=join(homedir(),".devflow","session-id"),_=join(homedir(),".devflow","event-map.json");function f(m,i){return new Promise(e=>{let n=JSON.stringify(i),t=new URL(m,k),o=request({hostname:t.hostname,port:t.port,path:t.pathname,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":P,"Content-Length":Buffer.byteLength(n)},timeout:5e3},()=>e());o.on("error",()=>e()),o.write(n),o.end();})}function N(){try{if(existsSync(h))return readFileSync(h,"utf-8").trim()}catch{}return null}function x(m,i){try{if(!existsSync(_))return null;let e=JSON.parse(readFileSync(_,"utf-8")),n=e.filter(c=>c.toolName===m);if(n.length===0)return null;let t=i??Date.now();n.sort((c,p)=>Math.abs(c.timestamp-t)-Math.abs(p.timestamp-t));let o=n[0],s=e.findIndex(c=>c.eventId===o.eventId);return s!==-1&&e.splice(s,1),writeFileSync(_,JSON.stringify(e)),{eventId:o.eventId,timestamp:o.timestamp}}catch{return null}}async function C(m){if(!m)return;let i;try{i=JSON.parse(m);}catch{return}let e=i.tool_name||"",n=i.tool_input||{},t=i.tool_response||{},o=N(),s=x(e,Date.now());if(s&&o){let r=typeof t=="string"?t:JSON.stringify(t),d=r.length>5e3?{_truncated:true,_originalSize:r.length,text:r.slice(0,5e3)}:t,a=Date.now()-s.timestamp;f("/api/telemetry/tool-call/output",{eventId:s.eventId,sessionId:o,output:d,duration:a,completedAt:Date.now()}).catch(()=>{});}let c=typeof n=="object"&&n.command?n.command:"",p=typeof t=="object"&&t!==null?t:null,g=p?.exitCode,S=p?.stderr;if(e==="Bash"&&g!==void 0&&g!==0){let r={id:`evt:${Date.now()}:${Math.random().toString(36).slice(2,7)}`,sessionId:o??`session:${y.split("/").pop()||"default"}`,tool:e,command:c||e,exitCode:g,stderr:S??null,durationMs:0,createdAt:Date.now()};f(`/api/memory/events?rootPath=${encodeURIComponent(y)}`,r).catch(()=>{});}let E=["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"],l=e.replace("mcp__devflow__","");if(e.startsWith("mcp__devflow__")&&E.includes(l)){let r=typeof t=="object"&&t!==null?t:null,d=r?.data??r,a=0;if(Array.isArray(d))a=d.length;else if(typeof d=="object"&&d!==null){let u=d;Array.isArray(u.files)?a=u.files.length:Array.isArray(u.results)?a=u.results.length:Array.isArray(u.data)?a=u.data.length:Object.keys(u).length>0&&(a=1);}let O=JSON.stringify(t),R=Buffer.byteLength(O,"utf8"),A={id:`metric:${Date.now()}:${Math.random().toString(36).slice(2,11)}`,toolCallEventId:s?.eventId??`unknown:${Date.now()}`,sessionId:o??"",toolName:l,query:typeof n=="object"&&n.query?n.query:void 0,status:r?.error?"error":a===0?"empty":"success",resultCount:a,resultSizeBytes:R,latencyMs:s?Date.now()-s.timestamp:0,engine:l.startsWith("get_project_context")||l==="search_symbol"||l==="get_dependency_graph"?"codegraph":l==="get_knowledge"?"knowledge":l==="get_memory"?"memory":void 0};f("/api/telemetry/tool-metrics",A).catch(()=>{});}}(process.argv[1]?.endsWith("post-tool-use")||process.argv[1]?.endsWith("post-tool-use.js"))&&C(process.argv[2]||"").catch(()=>process.exit(0));
2
+ export{C as handlePostToolUse};
@@ -1,2 +1,2 @@
1
- import {existsSync,readFileSync,mkdirSync,writeFileSync,unlinkSync,readdirSync}from'fs';import {request}from'http';import {join}from'path';import {homedir}from'os';var k=1e4,M=300*1e3;function g(r,t,e){return new Promise(n=>{try{let o=new URL(r),i=request({hostname:o.hostname,port:o.port||80,path:o.pathname+o.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":e,"Content-Length":Buffer.byteLength(t)},timeout:5e3},s=>{s.resume(),n(s.statusCode!=null&&s.statusCode>=200&&s.statusCode<300);});i.on("error",()=>n(!1)),i.on("timeout",()=>{i.destroy(),n(!1);}),i.write(t),i.end();}catch{n(false);}})}var l=class{constructor(t){this.retryScheduled=false;this.apiUrl=t?.apiUrl??process.env.DEVFLOW_API_URL??"http://127.0.0.1:13337",this.apiKey=t?.apiKey??process.env.DEVFLOW_API_KEY??"dev-key-000000",this.cacheDir=t?.cacheDir??join(homedir(),".devflow","telemetry-cache");}async sendEvent(t){let e=this.truncateInput(t.input),n={...t,input:e},o=`${this.apiUrl}/api/telemetry/tool-call`;await g(o,JSON.stringify(n),this.apiKey)||this.cacheEvent({type:"tool_call",payload:n});}async sendExecutionStart(t,e,n){let o={executionId:t,skillName:e,startedAt:n},i=`${this.apiUrl}/api/telemetry/skill-execution/start`;await g(i,JSON.stringify(o),this.apiKey)||this.cacheEvent({type:"execution_start",payload:o});}async flushCache(){if(!existsSync(this.cacheDir))return;let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json"));for(let e of t)try{let n=join(this.cacheDir,e),o=readFileSync(n,"utf8"),i=JSON.parse(o),s=i.type==="execution_start"?"/api/telemetry/skill-execution/start":"/api/telemetry/tool-call",a=`${this.apiUrl}${s}`;await g(a,JSON.stringify(i.payload),this.apiKey)&&unlinkSync(n);}catch{}}cacheEvent(t){try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let e=join(this.cacheDir,`${Date.now()}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(e,JSON.stringify(t,null,2)),this.scheduleRetry();}catch{}}scheduleRetry(){this.retryScheduled||(this.retryScheduled=true,setTimeout(()=>{this.retryScheduled=false,this.flushCache().catch(()=>{});},M).unref());}truncateInput(t){let e=JSON.stringify(t);return e.length<=k?t:{_truncated:true,_original_size:e.length,_preview:e.substring(0,k)+"..."}}};var $=1800*1e3;function J(){return process.env.DEVFLOW_STATE_DIR??join(homedir(),".devflow")}var h=class{constructor(t){this.stateDir=J();}detect(){let t=join(this.stateDir,"current-skill.json");if(!existsSync(t))return null;try{let e=readFileSync(t,"utf8"),n=JSON.parse(e);return !n.registeredAt||Date.now()-n.registeredAt>$?(this.endExecution(),null):n}catch{return null}}startExecution(t,e){existsSync(this.stateDir)||mkdirSync(this.stateDir,{recursive:true});let n=this.getCurrentExecutionId();if(n)return n;let o=`exec_${Date.now()}_${Math.random().toString(36).slice(2,11)}`;return writeFileSync(join(this.stateDir,"current-execution-id"),o),writeFileSync(join(this.stateDir,"current-skill.json"),JSON.stringify({name:t,required_mcp_tools:e?.required_mcp_tools??[],registeredAt:Date.now()})),o}getCurrentExecutionId(){let t=join(this.stateDir,"current-execution-id");if(!existsSync(t))return null;try{return readFileSync(t,"utf8").trim()}catch{return null}}endExecution(){let t=join(this.stateDir,"current-skill.json"),e=join(this.stateDir,"current-execution-id");try{existsSync(t)&&unlinkSync(t);}catch{}try{existsSync(e)&&unlinkSync(e);}catch{}}};function p(){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}function j(r){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:r}}}async function A(r){try{if(!r||r.trim()==="")return p();let t=JSON.parse(r),e=new h;if(t.tool_name==="Skill"){let d=t.tool_input?.skill;if(d&&d.startsWith("devflow:")){let I=e.startExecution(d);new l().sendExecutionStart(I,d,Date.now()).catch(()=>{});}}let n=e.detect(),o=t.tool_name.startsWith("mcp__devflow__"),i=o?t.tool_name.replace("mcp__devflow__",""):void 0,s=n?.required_mcp_tools??[],a=s.length>0,y=a&&!o,m;y?m=j(`Skill "${n?.name||"unknown"}" requires MCP tools. Use one of: ${s.join(", ")}`):m=p();let D=e.getCurrentExecutionId()??`exec_orphan_${Date.now()}`,w=new l,E={eventId:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,executionId:D,timestamp:Date.now(),toolName:t.tool_name,toolType:o?"mcp":t.tool_name==="Agent"?"subagent":"direct",isMcpTool:o,mcpToolName:i,mcpEnforced:o&&a,mcpFallback:!o&&a,input:t.tool_input,tokensUsed:0,duration:0,blocked:!1};return w.sendEvent(E).catch(()=>{}),m}catch{return p()}}if(process.argv[1]?.endsWith("pre-tool-use")||process.argv[1]?.endsWith("pre-tool-use.js")){let r="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{r+=t;}),process.stdin.on("end",async()=>{let t=await A(r);console.log(JSON.stringify(t));}),process.stdin.on("error",()=>{console.log(JSON.stringify(p())),process.exit(0);}),setTimeout(()=>{console.log(JSON.stringify(p())),process.exit(0);},4e3).unref();}
2
- export{A as handlePreToolUse};
1
+ import {existsSync,readdirSync,readFileSync,unlinkSync,mkdirSync,writeFileSync}from'fs';import {join}from'path';import {homedir}from'os';import {request}from'http';var I=1e4,q=3e4,W=300*1e3;function m(o,t,e){return new Promise(n=>{try{let r=new URL(o),i=request({hostname:r.hostname,port:r.port||80,path:r.pathname+r.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":e,"Content-Length":Buffer.byteLength(t)},timeout:5e3},s=>{let c=[];s.on("data",a=>c.push(a)),s.on("end",()=>{let a=Buffer.concat(c).toString();n(s.statusCode!=null&&s.statusCode>=200&&s.statusCode<300?a:null);});});i.on("error",()=>n(null)),i.on("timeout",()=>{i.destroy(),n(null);}),i.write(t),i.end();}catch{n(null);}})}var f=class{constructor(t){this.retryScheduled=false;this.retryAttempts=0;this.apiUrl=t?.apiUrl??process.env.DEVFLOW_API_URL??"http://127.0.0.1:13337",this.apiKey=t?.apiKey??process.env.DEVFLOW_API_KEY??"dev-key-000000",this.cacheDir=t?.cacheDir??join(homedir(),".devflow","telemetry-cache");}async sendEvent(t){let e=this.truncateInput(t.input),n={...t,input:e},r=`${this.apiUrl}/api/telemetry/tool-call`,i=await m(r,JSON.stringify(n),this.apiKey);if(i)try{let s=JSON.parse(i),c=s.data?.eventId??s.eventId??null;if(c)return c}catch{}return this.cacheEvent({type:"tool_call",payload:n}),null}async sendExecutionStart(t,e,n,r){let i={executionId:t,sessionId:e,skillName:n,startedAt:r},s=`${this.apiUrl}/api/telemetry/skill-execution/start`;await m(s,JSON.stringify(i),this.apiKey)||this.cacheEvent({type:"execution_start",payload:i});}async sendSessionStart(t,e,n){let r={id:t,projectRoot:e,startedAt:n,label:e.split("/").pop()??"unknown"},i=`${this.apiUrl}/api/telemetry/sessions`;return await m(i,JSON.stringify(r),this.apiKey)!==null}async flushCache(){if(!existsSync(this.cacheDir))return;let t=readdirSync(this.cacheDir).filter(e=>e.endsWith(".json"));for(let e of t)try{let n=join(this.cacheDir,e),r=readFileSync(n,"utf8"),i=JSON.parse(r),s=i.type==="execution_start"?"/api/telemetry/skill-execution/start":"/api/telemetry/tool-call",c=`${this.apiUrl}${s}`;await m(c,JSON.stringify(i.payload),this.apiKey)&&unlinkSync(n);}catch{}}cacheEvent(t){try{existsSync(this.cacheDir)||mkdirSync(this.cacheDir,{recursive:!0});let e=join(this.cacheDir,`${Date.now()}_${Math.random().toString(36).slice(2,11)}.json`);writeFileSync(e,JSON.stringify(t,null,2)),this.scheduleRetry();}catch{}}scheduleRetry(){if(this.retryScheduled)return;this.retryScheduled=true;let t=Math.min(q*Math.pow(2,this.retryAttempts),W);setTimeout(()=>{this.retryScheduled=false,this.flushCache().then(()=>{this.retryAttempts=0;}).catch(()=>{this.retryAttempts++;});},t).unref();}truncateInput(t){let e=JSON.stringify(t);return e.length<=I?t:{_truncated:true,_original_size:e.length,_preview:e.substring(0,I)+"..."}}};var V=1800*1e3;function X(){return process.env.DEVFLOW_STATE_DIR??join(homedir(),".devflow")}var g=class{constructor(t){this.stateDir=X();}detect(){let t=join(this.stateDir,"current-skill.json");if(!existsSync(t))return null;try{let e=readFileSync(t,"utf8"),n=JSON.parse(e);return !n.registeredAt||Date.now()-n.registeredAt>V?(this.endExecution(),null):n}catch{return null}}startExecution(t,e){existsSync(this.stateDir)||mkdirSync(this.stateDir,{recursive:true});let n=this.getCurrentExecutionId();if(n)return n;let r=`exec_${Date.now()}_${Math.random().toString(36).slice(2,11)}`;return writeFileSync(join(this.stateDir,"current-execution-id"),r),writeFileSync(join(this.stateDir,"current-skill.json"),JSON.stringify({name:t,required_mcp_tools:e?.required_mcp_tools??[],registeredAt:Date.now()})),r}getCurrentExecutionId(){let t=join(this.stateDir,"current-execution-id");if(!existsSync(t))return null;try{return readFileSync(t,"utf8").trim()}catch{return null}}endExecution(){let t=join(this.stateDir,"current-skill.json"),e=join(this.stateDir,"current-execution-id");try{existsSync(t)&&unlinkSync(t);}catch{}try{existsSync(e)&&unlinkSync(e);}catch{}}};function d(){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}}function G(o){return {hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:o}}}var h=join(homedir(),".devflow");function A(){existsSync(h)||mkdirSync(h,{recursive:true});}function Z(){try{let o=join(h,"session-id");if(existsSync(o))return readFileSync(o,"utf-8").trim()}catch{}return null}function Q(o){A(),writeFileSync(join(h,"session-id"),o);}function tt(o,t,e){A();let n=join(h,"event-map.json"),r=[];try{existsSync(n)&&(r=JSON.parse(readFileSync(n,"utf-8")));}catch{}r.push({toolName:o,eventId:t,timestamp:e}),writeFileSync(n,JSON.stringify(r));}function et(o){switch(o){case "Read":case "Glob":return "file_read";case "Write":case "Edit":case "NotebookEdit":return "file_write";case "Bash":return "bash_command";case "Agent":return "subagent";case "Skill":return "skill_invoke";default:return "tool_use"}}async function nt(o){try{if(!o||o.trim()==="")return d();let t=JSON.parse(o),e=process.env.CLAUDE_PROJECT_DIR||process.cwd(),n=e.split("/").pop()||"unknown",r=new f,i=Z();i||(i=`session:${n}:${Date.now().toString(36)}`,Q(i),r.sendSessionStart(i,e,Date.now()).catch(()=>{}));let s=new g;if(t.tool_name==="Skill"){let l=t.tool_input?.skill;if(l&&l.startsWith("devflow:")){let C=s.startExecution(l);r.sendExecutionStart(C,i,l,Date.now()).catch(()=>{});}}let c=s.detect(),a=t.tool_name.startsWith("mcp__devflow__"),M=a?t.tool_name.replace("mcp__devflow__",""):void 0,w=c?.required_mcp_tools??[],_=w.length>0,D=_&&!a,S;D?S=G(`Skill "${c?.name||"unknown"}" requires MCP tools. Use one of: ${w.join(", ")}`):S=d();let R=s.getCurrentExecutionId()??i,E={eventId:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,executionId:R,sessionId:i,timestamp:Date.now(),toolName:t.tool_name,toolType:a?"mcp":t.tool_name==="Agent"?"subagent":"direct",isMcpTool:a,mcpToolName:M,mcpEnforced:a&&_,mcpFallback:!a&&_,kind:et(t.tool_name),input:t.tool_input,duration:0,blocked:D};return r.sendEvent(E).then(l=>{l&&tt(t.tool_name,l,E.timestamp);}).catch(()=>{}),S}catch{return d()}}if(process.argv[1]?.endsWith("pre-tool-use")||process.argv[1]?.endsWith("pre-tool-use.js")){let o="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{o+=t;}),process.stdin.on("end",async()=>{let t=await nt(o);console.log(JSON.stringify(t));}),process.stdin.on("error",()=>{console.log(JSON.stringify(d())),process.exit(0);}),setTimeout(()=>{console.log(JSON.stringify(d())),process.exit(0);},4e3).unref();}
2
+ export{nt as handlePreToolUse};
@@ -0,0 +1,2 @@
1
+ import {get,request}from'http';import {existsSync,readFileSync,unlinkSync}from'fs';import {join}from'path';import {homedir}from'os';var I=process.env.DEVFLOW_SERVER_URL||"http://127.0.0.1:13337",x=process.env.DEVFLOW_API_KEY||"dev-key-000000",D=process.env.CLAUDE_PROJECT_DIR||process.cwd();function b(t){return new Promise(r=>{let e=new URL(t,I);get(e.toString(),{headers:{"X-API-Key":x},timeout:5e3},n=>{let c=[];n.on("data",g=>c.push(g)),n.on("end",()=>{try{r(JSON.parse(Buffer.concat(c).toString()));}catch{r(null);}});}).on("error",()=>r(null));})}function d(t,r){return new Promise(e=>{let s=JSON.stringify(r),n=new URL(t,I),c=request({hostname:n.hostname,port:n.port,path:n.pathname,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":x,"Content-Length":Buffer.byteLength(s)},timeout:5e3},()=>e());c.on("error",()=>e()),c.write(s),c.end();})}var p=join(homedir(),".devflow"),E=join(p,"session-id"),T=join(p,"current-execution-id"),M=join(p,"current-skill.json"),O=join(p,"event-map.json");function A(){for(let t of [E,T,M,O])try{existsSync(t)&&unlinkSync(t);}catch{}}async function F(){let t=(()=>{try{if(existsSync(E))return readFileSync(E,"utf-8").trim()}catch{}return null})();if(t){let e=(await b(`/api/telemetry/sessions/${t}/events`))?.data||[];e.length;e.filter(o=>o.isMcpTool).length;e.filter(o=>o.toolType==="subagent").length;let u=e.map(o=>o.timestamp).filter(Boolean);u.length>=2?Math.max(...u)-Math.min(...u):0;if(existsSync(T)){let o="";try{o=readFileSync(T,"utf-8").trim();}catch{}if(o){let l=e.filter(a=>a.executionId===o),m=l.length,h=l.filter(a=>a.isMcpTool).length,S=m-h,R=l.filter(a=>a.toolType==="subagent").length,f=l.map(a=>a.timestamp).filter(Boolean),_=f.length>=2?Math.max(...f)-Math.min(...f):0;try{await d("/api/telemetry/skill-execution/complete",{executionId:o,finishedAt:Date.now(),status:"completed",summary:{totalToolCalls:m,mcpToolCalls:h,directToolCalls:S,subagentCount:R,totalDuration:_,mcpComplianceRate:m>0?Math.round(h/m*1e4)/100:0}});}catch{}}}await d(`/api/telemetry/sessions/${t}/close`,{finishedAt:Date.now()});}d(`/api/memory/process?rootPath=${encodeURIComponent(D)}`,{}).catch(()=>{}),A();}(process.argv[1]?.endsWith("stop")||process.argv[1]?.endsWith("stop.js"))&&F().catch(()=>process.exit(0));
2
+ export{F as handleStop};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/devflow",
3
- "version": "0.8.10",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "description": "DevFlow - Developer Intelligence Platform (Distribution Package)",
6
6
  "bin": {
@@ -10,22 +10,22 @@
10
10
  "build": "tsup",
11
11
  "build:watch": "tsup --watch",
12
12
  "clean": "rm -rf dist",
13
- "postbuild": "cp ../../apps/server/public/fallback.html dist/fallback.html && npx tsx scripts/bundle-plugin.ts && mkdir -p ../../plugins/claude-code/dist/hooks && cp dist/hooks/pre-tool-use.js ../../plugins/claude-code/dist/hooks/pre-tool-use.js",
13
+ "postbuild": "cp ../../apps/server/public/fallback.html dist/fallback.html && npx tsx scripts/bundle-plugin.ts && mkdir -p ../../plugins/claude-code/dist/hooks && cp dist/hooks/*.js ../../plugins/claude-code/dist/hooks/",
14
14
  "postinstall": "node scripts/postinstall.js"
15
15
  },
16
16
  "dependencies": {
17
17
  "@colbymchenry/codegraph": "^1.1.1",
18
- "@devflow-tools/adapters": "^0.8.10",
19
- "@devflow-tools/benchmark": "^0.8.10",
20
- "@devflow-tools/context-engine": "^0.8.10",
21
- "@devflow-tools/database": "^0.8.10",
22
- "@devflow-tools/knowledge-engine": "^0.8.10",
23
- "@devflow-tools/mcp-server": "^0.8.10",
24
- "@devflow-tools/memory-engine": "^0.8.10",
25
- "@devflow-tools/sdk": "^0.8.10",
26
- "@devflow-tools/server": "^0.8.10",
27
- "@devflow-tools/telemetry": "^0.8.10",
28
- "@devflow-tools/workflow-engine": "^0.8.10",
18
+ "@devflow-tools/adapters": "^0.9.0",
19
+ "@devflow-tools/benchmark": "^0.9.0",
20
+ "@devflow-tools/context-engine": "^0.9.0",
21
+ "@devflow-tools/database": "^0.9.0",
22
+ "@devflow-tools/knowledge-engine": "^0.9.0",
23
+ "@devflow-tools/mcp-server": "^0.9.0",
24
+ "@devflow-tools/memory-engine": "^0.9.0",
25
+ "@devflow-tools/sdk": "^0.9.0",
26
+ "@devflow-tools/server": "^0.9.0",
27
+ "@devflow-tools/telemetry": "^0.9.0",
28
+ "@devflow-tools/workflow-engine": "^0.9.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": "ac4f93d6a52fa40b4126b514e899eee581f8f46e"
55
+ "gitHead": "7872bccedbacd09cc92b983f30b3702db6878125"
56
56
  }
@@ -1,34 +1,50 @@
1
1
  {
2
2
  "version": "1.0.0",
3
- "lastUpdated": "2026-07-09T03:37:54.077Z",
3
+ "lastUpdated": "2026-07-10T02:47:16.762Z",
4
4
  "plugins": [
5
5
  {
6
6
  "name": "@devflow-tools/plugin-animation",
7
- "version": "0.8.8",
7
+ "version": "0.8.10",
8
8
  "description": "",
9
9
  "tags": [],
10
10
  "compatibleStacks": [
11
11
  "animation"
12
12
  ],
13
- "size": "776K",
13
+ "size": "820K",
14
+ "author": "DevFlow Team",
15
+ "homepage": ""
16
+ },
17
+ {
18
+ "name": "@devflow-tools/claude-code-plugin",
19
+ "version": "0.8.10",
20
+ "description": "DevFlow — Developer Intelligence Platform for Claude Code",
21
+ "tags": [
22
+ "pi-package",
23
+ "skills",
24
+ "development",
25
+ "context",
26
+ "knowledge-base"
27
+ ],
28
+ "compatibleStacks": [],
29
+ "size": "276K",
14
30
  "author": "DevFlow Team",
15
31
  "homepage": ""
16
32
  },
17
33
  {
18
34
  "name": "@devflow-tools/plugin-css",
19
- "version": "0.8.8",
35
+ "version": "0.8.10",
20
36
  "description": "",
21
37
  "tags": [],
22
38
  "compatibleStacks": [
23
39
  "css"
24
40
  ],
25
- "size": "744K",
41
+ "size": "792K",
26
42
  "author": "DevFlow Team",
27
43
  "homepage": ""
28
44
  },
29
45
  {
30
46
  "name": "@devflow-tools/plugin-docker",
31
- "version": "0.8.8",
47
+ "version": "0.8.10",
32
48
  "description": "",
33
49
  "tags": [],
34
50
  "compatibleStacks": [
@@ -40,31 +56,31 @@
40
56
  },
41
57
  {
42
58
  "name": "@devflow-tools/plugin-electron",
43
- "version": "0.8.8",
59
+ "version": "0.8.10",
44
60
  "description": "",
45
61
  "tags": [],
46
62
  "compatibleStacks": [
47
63
  "electron"
48
64
  ],
49
- "size": "880K",
65
+ "size": "888K",
50
66
  "author": "DevFlow Team",
51
67
  "homepage": ""
52
68
  },
53
69
  {
54
70
  "name": "@devflow-tools/plugin-git",
55
- "version": "0.8.8",
71
+ "version": "0.8.10",
56
72
  "description": "",
57
73
  "tags": [],
58
74
  "compatibleStacks": [
59
75
  "git"
60
76
  ],
61
- "size": "776K",
77
+ "size": "820K",
62
78
  "author": "DevFlow Team",
63
79
  "homepage": ""
64
80
  },
65
81
  {
66
82
  "name": "@devflow-tools/plugin-graphql",
67
- "version": "0.8.8",
83
+ "version": "0.8.10",
68
84
  "description": "",
69
85
  "tags": [],
70
86
  "compatibleStacks": [
@@ -76,31 +92,31 @@
76
92
  },
77
93
  {
78
94
  "name": "@devflow-tools/plugin-nest",
79
- "version": "0.8.8",
95
+ "version": "0.8.10",
80
96
  "description": "",
81
97
  "tags": [],
82
98
  "compatibleStacks": [
83
99
  "nest"
84
100
  ],
85
- "size": "912K",
101
+ "size": "920K",
86
102
  "author": "DevFlow Team",
87
103
  "homepage": ""
88
104
  },
89
105
  {
90
106
  "name": "@devflow-tools/plugin-nextjs",
91
- "version": "0.8.8",
107
+ "version": "0.8.10",
92
108
  "description": "",
93
109
  "tags": [],
94
110
  "compatibleStacks": [
95
111
  "nextjs"
96
112
  ],
97
- "size": "812K",
113
+ "size": "820K",
98
114
  "author": "DevFlow Team",
99
115
  "homepage": ""
100
116
  },
101
117
  {
102
118
  "name": "@devflow-tools/plugin-performance",
103
- "version": "0.8.8",
119
+ "version": "0.8.10",
104
120
  "description": "",
105
121
  "tags": [],
106
122
  "compatibleStacks": [
@@ -112,7 +128,7 @@
112
128
  },
113
129
  {
114
130
  "name": "@devflow-tools/plugin-react",
115
- "version": "0.8.8",
131
+ "version": "0.8.10",
116
132
  "description": "",
117
133
  "tags": [],
118
134
  "compatibleStacks": [
@@ -124,43 +140,43 @@
124
140
  },
125
141
  {
126
142
  "name": "@devflow-tools/plugin-tailwind",
127
- "version": "0.8.8",
143
+ "version": "0.8.10",
128
144
  "description": "",
129
145
  "tags": [],
130
146
  "compatibleStacks": [
131
147
  "tailwind"
132
148
  ],
133
- "size": "780K",
149
+ "size": "848K",
134
150
  "author": "DevFlow Team",
135
151
  "homepage": ""
136
152
  },
137
153
  {
138
154
  "name": "@devflow-tools/plugin-taro",
139
- "version": "0.8.8",
155
+ "version": "0.8.10",
140
156
  "description": "",
141
157
  "tags": [],
142
158
  "compatibleStacks": [
143
159
  "taro"
144
160
  ],
145
- "size": "804K",
161
+ "size": "856K",
146
162
  "author": "DevFlow Team",
147
163
  "homepage": ""
148
164
  },
149
165
  {
150
166
  "name": "@devflow-tools/plugin-ui-layout",
151
- "version": "0.8.8",
167
+ "version": "0.8.10",
152
168
  "description": "",
153
169
  "tags": [],
154
170
  "compatibleStacks": [
155
171
  "ui-layout"
156
172
  ],
157
- "size": "744K",
173
+ "size": "788K",
158
174
  "author": "DevFlow Team",
159
175
  "homepage": ""
160
176
  },
161
177
  {
162
178
  "name": "@devflow-tools/plugin-vue",
163
- "version": "0.8.8",
179
+ "version": "0.8.10",
164
180
  "description": "",
165
181
  "tags": [],
166
182
  "compatibleStacks": [
package/dist/cli.js DELETED
@@ -1,46 +0,0 @@
1
- #!/usr/bin/env node
2
- import zo,{unlinkSync,existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,statSync,cpSync,readdirSync}from'fs';import xt,{dirname,join,resolve}from'path';import {homedir}from'os';import {createRequire}from'module';import Ee from'@colbymchenry/codegraph';import {createEngines,buildOnboardingPack}from'@devflow-tools/context-engine';import {Command}from'commander';import l from'chalk';import {execSync,spawn}from'child_process';import {checkbox}from'@inquirer/prompts';import {fileURLToPath}from'url';import {listAdapters,connect}from'@devflow-tools/adapters';import {DevFlowApiClient,loadPlugins}from'@devflow-tools/sdk';import'readline';import {KnowledgeEngine}from'@devflow-tools/knowledge-engine';import {createHash,createHmac}from'crypto';import {BenchmarkEngine}from'@devflow-tools/benchmark';var Yo=Object.defineProperty;var be=(e,o)=>()=>(e&&(o=e(e=0)),o);var Xo=(e,o)=>{for(var n in o)Yo(e,n,{get:o[n],enumerable:true});};function De(){let e=join(dirname(new URL(import.meta.url).pathname),"../../plugin-files");if(existsSync(e))return e;let o=join(dirname(new URL(import.meta.url).pathname),"../../../../plugins/claude-code");if(existsSync(o))return o;throw new Error("Plugin files not found. Run `npm run build` first.")}function Re(e){let o={};if(existsSync(e))try{o=JSON.parse(readFileSync(e,"utf-8"));}catch{console.warn("Warning: Could not parse settings.json, skipping plugin enablement");return}else mkdirSync(dirname(e),{recursive:true});let n=o.enabledPlugins??{};n[ke]!==true&&(n[ke]=true,o.enabledPlugins=n,writeFileSync(e,JSON.stringify(o,null,2)));}function Fe(e,o){let n=join(e,".claude"),t=join(n,"mcp.json"),r={};if(existsSync(t))try{r=JSON.parse(readFileSync(t,"utf-8"));}catch{console.warn("Warning: Could not parse existing mcp.json, skipping MCP config");return}else mkdirSync(n,{recursive:true});let i=r.mcpServers??{};i.devflow||(i.devflow={command:o,args:[],env:{}},r.mcpServers=i,writeFileSync(t,JSON.stringify(r,null,2)));}function Ie(e,o,n,t){let r=join(o,nn,tn,n);mkdirSync(r,{recursive:true});let i=join(e,"hooks");existsSync(i)&&N(i,join(r,"hooks"));for(let d of ["hooks.json","CLAUDE.md","package.json"]){let u=join(e,d);existsSync(u)&&cpSync(u,join(r,d),{force:true});}let s=join(e,".claude-plugin","plugin.json");existsSync(s)&&(mkdirSync(join(r,".claude-plugin"),{recursive:true}),cpSync(s,join(r,".claude-plugin","plugin.json"),{force:true}));let a=join(e,"dist");if(existsSync(a)&&N(a,join(r,"dist")),t){let d=join(e,"dist","skills");existsSync(d)&&N(d,t);}rn(r);}function N(e,o){mkdirSync(o,{recursive:true});for(let n of readdirSync(e)){let t=join(e,n),r=join(o,n);statSync(t).isDirectory()?N(t,r):cpSync(t,r,{force:true});}}function rn(e){let o=join(e,"..");if(!existsSync(o))return;let n=e.split("/").pop()??"";for(let t of readdirSync(o))if(t!==n){let r=join(o,t);statSync(r).isDirectory()&&rmSync(r,{recursive:true,force:true});}}var ke,nn,tn,Oe=be(()=>{ke="@devflow-tools/claude-code-plugin@devflow-local",nn="devflow-local",tn="@devflow-tools/claude-code-plugin";});var Ae={};Xo(Ae,{initProject:()=>Z,renderInitReport:()=>Te});async function Z(e,o={}){let n=join(e,".devflow"),t=[];existsSync(n)||(mkdirSync(n,{recursive:true}),t.push(".devflow/"));let r=join(n,"config.json");(!existsSync(r)||o.force)&&(writeFileSync(r,JSON.stringify({version:"0.1.0",initialized:new Date().toISOString()},null,2),"utf-8"),t.push(".devflow/config.json"));let i={created:t,pluginDeployed:false,pluginEnabled:false,mcpConfigured:false};if(Q.isInitialized(e)||await Q.init(e,{index:o.scan!==false}),o.scan!==false)try{let{indexer:s,graph:a}=await createEngines(e),{files:d,symbols:u,imports:p}=await s.indexAll(e),w=await a.build(u,p);i.indexed={files:d.length,symbols:u.length,graphNodes:w.nodes.length};}catch{i.indexed={files:0,symbols:0,graphNodes:0};}if(o.scan!==false)try{let{indexer:s,graph:a}=await createEngines(e),d=Q.openSync(e),u=await buildOnboardingPack(e,d,s,a),p=join(n,"onboarding-pack.json");writeFileSync(p,JSON.stringify(u,null,2),"utf-8"),t.push(".devflow/onboarding-pack.json");let w=join(n,"init-report.md");writeFileSync(w,Te(u),"utf-8"),t.push(".devflow/init-report.md"),i.onboardingPack=u;}catch(s){console.warn(`Warning: Onboarding pack generation skipped \u2014 ${s.message}`);}try{let s=De(),a=homedir(),d=join(a,".claude","plugins","cache"),u=join(a,".claude","skills"),p=join(s,"package.json"),w=existsSync(p)?JSON.parse(readFileSync(p,"utf-8")).version:"0.0.0";Ie(s,d,w,u),i.pluginDeployed=!0;}catch(s){console.warn(`Warning: Plugin deployment skipped \u2014 ${s.message}`);}try{let s=homedir(),a=join(s,".claude","settings.json");Re(a),i.pluginEnabled=!0;}catch(s){console.warn(`Warning: Plugin enablement skipped \u2014 ${s.message}`);}try{let s;try{s=dn.resolve("@devflow-tools/mcp-server/bin/devflow-mcp.cjs");}catch{s="devflow-mcp";}Fe(e,s),i.mcpConfigured=!0;}catch(s){console.warn(`Warning: MCP config skipped \u2014 ${s.message}`);}return i}function Te(e){return [`# ${e.projectName} \u2014 DevFlow Onboarding Report`,`Generated: ${e.createdAt}`,"","## Project Stats",`- Files: ${e.stats.files}`,`- Symbols: ${e.stats.symbols}`,`- Graph Nodes: ${e.stats.graphNodes}`,"","## Tech Stack",`- Languages: ${e.stack.languages.join(", ")||"unknown"}`,`- Frameworks: ${e.stack.frameworks.join(", ")||"none detected"}`,`- Build Tools: ${e.stack.buildTools.join(", ")||"none detected"}`,`- Test Tools: ${e.stack.testTools.join(", ")||"none detected"}`,"","## Architecture Layers",...e.architectureLayers.map(n=>`- **${n.name}**: ${n.files} files`),"","## Key Modules",...e.keyModules.slice(0,10).map(n=>`- \`${n.name}\` \u2014 ${n.reason}`),"","## Key Symbols",...e.keySymbols.slice(0,20).map(n=>`- \`${n.name}\` (${n.kind}) in \`${n.file}\``),"","## Recommended Next Steps",...e.recommendedPlugins.map(n=>`- Install plugin: \`${n}\``),...e.recommendedWorkflows.map(n=>`- Run workflow: \`devflow workflow ${n}\``),`- Try: \`devflow context "${e.recommendedQueries[0]??"\u9879\u76EE\u67B6\u6784"}"\``].join(`
3
- `)}var Q,dn,ee=be(()=>{Oe();Q=Ee.default??Ee,dn=createRequire(import.meta.url);});function z(e){let o=join(e,".devflow","config.json");if(existsSync(o))try{let n=readFileSync(o,"utf-8");if(JSON.parse(n).serverUrl)return "server"}catch{}return "local"}ee();var fn=fileURLToPath(import.meta.url),wn=dirname(fn);function D(){let e=[join(process.cwd(),"plugin-registry.json"),join(wn,"../plugin-registry.json"),join(process.cwd(),"packages/devflow/plugin-registry.json")];for(let o of e)try{let n=readFileSync(o,"utf-8");return JSON.parse(n)}catch{continue}return {version:"0.0.0",lastUpdated:new Date().toISOString(),plugins:[]}}function Me(){try{let e=execSync("npm list -g --depth=0 --json",{encoding:"utf-8"}),o=JSON.parse(e);return Object.keys(o.dependencies||{}).filter(n=>n.startsWith("@devflow-tools/plugin-"))}catch{return []}}function Sn(e){let o=[];try{let n=JSON.parse(readFileSync(join(e,"package.json"),"utf-8")),t={...n.dependencies??{},...n.devDependencies??{}};t.react&&o.push("react"),t.next&&o.push("nextjs"),t.vue&&o.push("vue"),t.tailwindcss&&o.push("tailwind"),(t.nest||t["@nestjs/core"])&&o.push("nest"),t.express&&o.push("express"),t.typescript&&o.push("typescript");}catch{}return o}function bn(e){let o=e.trim();return o.startsWith("@devflow-tools/")?o:`@devflow-tools/${o}`}async function Le(e){let o=e.split(",").map(bn).filter(Boolean);if(o.length!==0)for(let n of o){console.log(`Installing ${n}...`);try{execSync(`npm install -g ${n}`,{stdio:"inherit"}),console.log(`\u2713 ${n}`);}catch{console.error(`\u2717 Failed to install ${n}`);}}}async function We(e){let o=D();if(o.plugins.length===0)return console.log(`
4
- No plugins available. You can install plugins later with:`),console.log(" devflow plugin list"),console.log(` devflow plugin install <name>
5
- `),[];console.log(`
6
- \u{1F50C} Plugin Installation Guide
7
- `);let n=Sn(e);n.length>0&&console.log(`Detected tech stack: ${n.join(", ")}
8
- `);let t=new Set(o.plugins.filter(s=>s.compatibleStacks.some(a=>n.includes(a))).map(s=>s.name));if(!process.stdout.isTTY){console.log(`Non-interactive terminal detected. Installing recommended plugins...
9
- `);let s=[...t];for(let a of s)try{execSync(`npm install -g ${a}`,{stdio:"inherit"}),console.log(`\u2713 ${a}`);}catch{console.error(`\u2717 Failed to install ${a}`);}return s}let r=o.plugins.map(s=>({name:`${s.name.replace("@devflow-tools/","")} - ${s.description.substring(0,50)}`,value:s.name,checked:t.has(s.name)})),i;try{i=await checkbox({message:"Select plugins to install (space to select, enter to confirm):",choices:r});}catch{return console.log(`
10
- Plugin installation cancelled.
11
- `),[]}if(i.length>0){console.log(`
12
- Installing selected plugins...
13
- `);for(let s of i)try{execSync(`npm install -g ${s}`,{stdio:"inherit"}),console.log(`\u2713 ${s}
14
- `);}catch{console.error(`\u2717 Failed to install ${s}
15
- `);}}else console.log(`
16
- Skipping plugin installation. You can install plugins later with:`),console.log(" devflow plugin list"),console.log(` devflow plugin install <name>
17
- `);return i}async function T(e){let o=[],n;e.sseUrl?n={url:e.sseUrl}:n={command:e.command??"devflow-mcp",args:["--mode","stdio"]};let t=e.agent?[e.agent]:await import('@devflow-tools/adapters').then(r=>r.detectAll());for(let r of t){let i=await connect(r,n);o.push(`${r}: ${i.configPath} (${i.written?"written":"skipped"})`);}return o}function Ue(){return listAdapters()}var Pn=process.env.DEVFLOW_SERVER_URL??"http://localhost:13337",Ge=new Map,Cn=3e4;async function m(e,o,n,t={}){let r=t.serverUrl??Pn;if(t.skipServer)return n();let i=false,s=Ge.get(r);if(s&&Date.now()-s.ts<Cn?i=s.result:(i=await new DevFlowApiClient({baseUrl:r,projectRoot:e}).ping(),Ge.set(r,{result:i,ts:Date.now()})),i){let a=new DevFlowApiClient({baseUrl:r,projectRoot:e});return o(a)}return console.error(l.dim(" (server not running, using local engine \u2014 telemetry disabled)")),n()}async function _e(e){return m(process.cwd(),o=>o.getIndexStatus(),async()=>{let{codegraph:o}=await createEngines(process.cwd()),n=o.getStats();return {totalFiles:n.fileCount,totalSymbols:n.nodeCount,lastIndexTime:n.lastUpdated,indexing:o.isIndexing()}},{skipServer:e})}async function qe(e={}){let o=e.target??"all",n=e.depth??2;return m(process.cwd(),t=>t.getGraph(o,n),async()=>{let{graph:t}=await createEngines(process.cwd());if(o==="all")return t.export();let r=t.getSubGraph(o,n);return {nodes:r.nodes,edges:r.edges}},{skipServer:e.skipServer})}async function Ve(e){return m(process.cwd(),o=>o.buildContext(e.query,e.mode??"fast",e.maxTokens),async()=>{let{context:o}=await createEngines(process.cwd());return o.build({query:e.query,mode:e.mode??"fast",maxTokens:e.maxTokens??8e3})},{skipServer:e.skipServer})}async function ze(e){let o=process.cwd(),n={mode:e.mode??"fast",maxTokens:e.maxTokens??8e3};return m(o,t=>t.buildTaskContext(e.query,o,n),async()=>{let{context:t}=await createEngines(o);return t.buildTaskContext(e.query,n)},{skipServer:e.skipServer})}async function Be(e){return m(process.cwd(),o=>o.listWorkflows(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.list()},{skipServer:e})}async function He(e,o,n){return m(process.cwd(),t=>t.runWorkflow(e,o),async()=>{let{workflow:t}=await createEngines(process.cwd());return t.run(e,o)},{skipServer:n})}async function Ye(e){return re(e)}async function re(e){return m(process.cwd(),o=>o.getWorkflowRuns(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.listRuns()},{skipServer:e})}async function Xe(e){return m(process.cwd(),o=>o.getMemory(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getAll()},{skipServer:e})}async function Qe(e,o,n){return m(process.cwd(),async t=>{await t.setMemory("project",e,o);},async()=>{let{memory:t}=await createEngines(process.cwd());await t.updateUserPreference(e,o);},{skipServer:n})}async function Ze(e){return m(process.cwd(),o=>o.reviewCandidates(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getCandidates()},{skipServer:e})}async function eo(e,o,n){return m(process.cwd(),t=>t.searchKnowledge(e,o),()=>new KnowledgeEngine({projectRoot:process.cwd()}).search(e,{sources:void 0}),{skipServer:n})}async function ie(e){return m(process.cwd(),async o=>(await o.listPlugins()).map(t=>({name:t.name,version:t.version,description:t.description,icon:t.icon,tags:t.tags??[],installed:true})),async()=>{let o=await loadPlugins();return Array.from(o.values()).map(n=>({name:n.meta.name,version:n.meta.version,description:n.meta.description,icon:n.meta.icon,tags:n.meta.tags,installed:true}))},{skipServer:e})}async function ro(e,o){let n=await ie(o),t=e.toLowerCase();return n.filter(r=>r.name.toLowerCase().includes(t)||r.description.toLowerCase().includes(t)||r.tags.some(i=>i.toLowerCase().includes(t)))}var A=join(process.env.HOME??"~",".devflow","skills");function so(e){let o=join(e,".devflow","config.json");return existsSync(o)?JSON.parse(readFileSync(o,"utf-8")):{plugins:[]}}function io(e,o){let n=join(e,".devflow","config.json");writeFileSync(n,JSON.stringify(o,null,2),"utf-8");}async function lo(e,o=process.cwd(),n){return m(o,async t=>await t.installPlugin(e),async()=>{let t=e.startsWith("@devflow-tools/plugin-")?e:`@devflow-tools/plugin-${e}`,r=e.replace(/^@devflow-tools\/plugin-/,"");mkdirSync(A,{recursive:true});try{execSync(`npm install --prefix "${A}" ${t}`,{stdio:"pipe",timeout:6e4});}catch{}let i=so(o);i.plugins||(i.plugins=[]),i.plugins.includes(r)||(i.plugins.push(r),io(o,i));let s=[];try{s=JSON.parse(readFileSync(join(A,"node_modules",t,"package.json"),"utf-8"))?.devflow?.templates??[];}catch{}return {name:r,version:"0.1.0",templates:s}},{skipServer:n})}async function ao(e,o=process.cwd(),n){return m(o,async t=>{await t.uninstallPlugin(e);},async()=>{let t=e.replace(/^@devflow-tools\/plugin-/,""),r=so(o);r.plugins&&(r.plugins=r.plugins.filter(s=>s!==t),io(o,r));let i=e.startsWith("@devflow-tools/plugin-")?e:`@devflow-tools/plugin-${e}`;try{let s=join(A,"node_modules",i);existsSync(s)&&rmSync(s,{recursive:!0,force:!0});}catch{}},{skipServer:n})}var go=createRequire(import.meta.url);function ce(e){let o=join(e,".devflow");return existsSync(o)||mkdirSync(o,{recursive:true}),join(o,"server.pid")}function Ln(){try{return go.resolve("./server.js")}catch{try{return go.resolve("@devflow-tools/server/dist/main.js")}catch{return join(process.cwd(),"apps","server","dist","main.js")}}}var de=13337;function ge(e){if(!existsSync(e))return null;let o=readFileSync(e,"utf-8").trim().split(`
18
- `);if(o.length>=2){let n=parseInt(o[0],10);if(!isNaN(n))return n}return null}function x(e){if(!existsSync(e))return null;let o=readFileSync(e,"utf-8").trim().split(`
19
- `),n=o.length>=2?o[1]:o[0],t=parseInt(n,10);return isNaN(t)?null:t}async function M(e){let o=Ln(),n=ce(process.cwd()),t=spawn("node",[o],{env:{...process.env,PORT:String(e.port)},stdio:"ignore",detached:true});return writeFileSync(n,`${e.port}
20
- ${t.pid??0}`),t.unref(),{pid:t.pid??0}}async function R(){let e=ce(process.cwd()),o=x(e);if(o===null)return false;try{return process.kill(o),unlinkSync(e),!0}catch{return unlinkSync(e),false}}async function F(){let e=ce(process.cwd()),o=ge(e)??de,{DevFlowApiClient:n}=await import('@devflow-tools/sdk');return await new n({baseUrl:`http://localhost:${o}`,projectRoot:process.cwd()}).ping()?{running:true,pid:x(e)??void 0,port:o}:{running:false,port:o}}async function mo(){let{codegraph:e,graph:o,memory:n,knowledge:t,workflow:r,data:i}=await createEngines(process.cwd()),s=e.getStats(),a=o.export(),d=0;try{d=(await r.list()).length;}catch{}let u=false,p=0;try{let E=await n.getAll();u=!!E?.project;let Ho=E?.user??{};p=Object.keys(Ho).length;}catch{}let w=0;try{w=(await t.getSources()).length;}catch{}let V={total:0,byTool:{}};try{V=await i.getToolCallStats();}catch{}let Se=await F(),b=0;return s.fileCount>0&&(b+=25),s.nodeCount>0&&(b+=15),a.nodes.length>0&&(b+=20),u&&(b+=15),w>0&&(b+=10),d>0&&(b+=5),Se.running&&(b+=10),V.total>0&&(b+=5),{index:{totalFiles:s.fileCount,totalSymbols:s.nodeCount,indexing:e.isIndexing()},graph:{nodes:a.nodes.length,edges:a.edges.length},memory:{projectReady:u,userPrefs:p},knowledge:{sources:w},plugins:{installed:0,names:[]},workflows:{registered:d},server:{running:Se.running},toolCalls:V,readyScore:b}}async function fo(){let{data:e}=await createEngines(process.cwd()),o=await e.auditGetSecret(),n=await e.auditGetAll(),t=createHash("sha256").update("genesis").digest("hex");for(let r of n){if(r.prevHash!==t)return {valid:false,brokenAt:r.seq,entryCount:n.length};let i=`${r.seq}|${r.ts}|${r.tool}|${r.argsHash}|${r.decision}|${r.ruleId??""}|${r.sessionId}|${t}`,s=createHmac("sha256",o).update(i).digest("hex");if(r.signature!==s)return {valid:false,brokenAt:r.seq,entryCount:n.length};t=r.signature;}return {valid:true,brokenAt:null,entryCount:n.length}}async function wo(){let{data:e}=await createEngines(process.cwd()),o=await e.auditGetSecret(),n=await e.auditGetAll(),t=createHash("sha256").update("genesis").digest("hex");for(let r of n){let i=`${r.seq}|${r.ts}|${r.tool}|${r.argsHash}|${r.decision}|${r.ruleId??""}|${r.sessionId}|${t}`,s=createHmac("sha256",o).update(i).digest("hex");await e.sqlExecute("UPDATE devflow_audit_chain SET prev_hash = ?, signature = ? WHERE seq = ?",[t,s,r.seq]),t=s;}return {rebuilt:true}}async function ho(e){let{data:o}=await createEngines(process.cwd()),t=(await o.auditGetAll()).filter(r=>r.decision!=="allow");if(e){let r=e.match(/^(\d+)([dh])$/);if(r){let i=parseInt(r[1],10),a=r[2]==="d"?i*864e5:i*36e5,d=Date.now()-a;t=t.filter(u=>u.ts>d);}}return {violations:t.map(r=>({tool:r.tool,decision:r.decision,ruleId:r.ruleId,ts:r.ts,sessionId:r.sessionId}))}}function yo(){let e=`${process.env.TMPDIR??"/tmp"}/.devflow-receipts`,o=createHash("sha256").update(process.cwd()).digest("hex").slice(0,16),n=`${e}/${o}.json`;try{let t=readFileSync(n,"utf-8");return {sessionId:o,data:JSON.parse(t)}}catch{return {sessionId:o,data:null}}}async function vo(e,o=3600){let n=Buffer.from(JSON.stringify({alg:"HS256",typ:"JWT"})).toString("base64url"),t=Math.floor(Date.now()/1e3),r={sub:`devflow-session-${Date.now().toString(36)}`,project:e.split("/").pop()??"unknown",iat:t,exp:t+o,scope:["context","knowledge","memory","workflow","graph"]},i=Buffer.from(JSON.stringify(r)).toString("base64url"),a=createHmac("sha256","devflow-local-mcp-secret-v1").update(`${n}.${i}`).digest("base64url");return {token:`${n}.${i}.${a}`,expiresAt:r.exp,scope:r.scope}}async function So(e,o){let t=new BenchmarkEngine().getTasks();return [l.blue("\u25C9 DevFlow Benchmark"),"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",`Available tasks: ${t.length}`,"","Benchmark requires a real runner implementation.","No fake data or estimated scores are shown.","","Setup: devflow benchmark --runner <path-to-runner>"].join(`
21
- `)}async function ko(e){let o,n;if(e.prUrl){let p=e.prUrl.match(/pull\/(\d+)/);n=`PR: ${p?`#${p[1]}`:e.prUrl}`;try{o=execSync(`gh pr diff ${e.prUrl}`,{encoding:"utf-8",maxBuffer:10*1024*1024});}catch{o=`Could not fetch PR diff from ${e.prUrl}. Ensure 'gh' CLI is installed and authenticated.`;}}else {n="Current branch vs main";try{o=execSync("git diff main...HEAD",{encoding:"utf-8",maxBuffer:10*1024*1024});}catch{o="Could not compute diff. Ensure you're on a feature branch.";}}let t=(o.match(/^diff --git/gm)??[]).length,r=(o.match(/^\+[^+]/gm)??[]).length,i=(o.match(/^-[^-]/gm)??[]).length,s=[],a=[],d=[];return o.includes("console.log")&&a.push("Contains console.log statements \u2014 remove before merge"),(o.includes(".only(")||o.includes("it.only"))&&s.push("Contains .only() test filters \u2014 remove before merge"),(o.includes("TODO")||o.includes("FIXME"))&&a.push("Contains TODO/FIXME comments \u2014 track or resolve"),(o.match(/^\+.*TODO/gm)||o.match(/^\+.*FIXME/gm))&&a.push("New code introduces TODO/FIXME comments"),o.includes("process.exit")&&a.push("Contains process.exit() \u2014 consider throwing instead"),o.includes(": any")&&o.match(/^\+.*: any/gm)&&d.push("New code uses `any` type \u2014 use explicit types instead"),[l.blue("\u25C9 Code Review"),"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",n,`Files changed: ${t}`,`+${r} / -${i}`,"",s.length>0?l.red(`Critical (${s.length})`):"",...s.map(p=>` ${l.red("\u25CF")} ${p}`),"",a.length>0?l.yellow(`Warning (${a.length})`):"",...a.map(p=>` ${l.yellow("\u25CB")} ${p}`),"",d.length>0?l.green(`Suggestion (${d.length})`):"",...d.map(p=>` ${l.green("\u25CB")} ${p}`),"",s.length>0?l.red("Overall: Need changes"):a.length>0?l.yellow("Overall: Approve with comments"):l.green("Overall: LGTM")].join(`
22
- `)}var pe=createRequire(import.meta.url);function me(e){return join(e,".devflow","dashboard")}function Do(e){return join(me(e),"version.txt")}function Ro(){try{return pe("../package.json").version??"0.0.0"}catch{return "0.0.0"}}function Kn(){try{let e=pe.resolve("@devflow-tools/devflow/package.json"),o=join(dirname(e),"dist","dashboard-standalone.tar.gz");if(existsSync(o))return o}catch{}return null}function Vn(e){let o=Do(e);if(!existsSync(o))return false;try{return readFileSync(o,"utf-8").trim()===Ro()&&existsSync(join(me(e),"apps","dashboard","server.js"))}catch{return false}}function U(e){let o=me(e),n=Do(e),t=Ro();if(Vn(e))return o;existsSync(o)&&rmSync(o,{recursive:true,force:true}),mkdirSync(o,{recursive:true});let r=Kn();if(r)return execSync(`tar -xzf "${r}" -C "${o}"`,{stdio:"pipe"}),writeFileSync(n,t),o;try{let i=pe.resolve("@devflow-tools/devflow/package.json"),s=join(dirname(i),"..",".."),a=join(s,"apps","dashboard",".next","standalone"),d=join(s,"apps","dashboard",".next","static"),u=join(s,"apps","dashboard","public"),p=join(a,"apps","dashboard","server.js");if(!existsSync(p))throw new Error(`Dashboard build not found.
23
- Expected: ${p}
24
- Run: npm run build:dist (requires Node >= 18)
25
- Or install from npm: npm install @devflow-tools/devflow@${t}`);if(execSync(`cp -r "${a}/"* "${o}/"`,{stdio:"pipe"}),existsSync(d)){let w=join(o,"apps","dashboard",".next");mkdirSync(w,{recursive:!0}),execSync(`cp -r "${d}" "${w}/"`,{stdio:"pipe"});}return existsSync(u)&&execSync(`cp -r "${u}" "${o}/"`,{stdio:"pipe"}),writeFileSync(n,t),o}catch(i){throw existsSync(o)&&rmSync(o,{recursive:true,force:true}),i}}function C(){return join(process.cwd(),".devflow","dashboard.pid")}async function Qn(e,o=15e3){let n=Date.now();for(;Date.now()-n<o;){try{if((await fetch(`http://localhost:${e}/api/health`)).ok)return !0}catch{}await new Promise(t=>setTimeout(t,500));}return false}async function Oo(e){let o=C();if(existsSync(o)){try{let r=x(o);if(r!==null)try{process.kill(r);}catch{}}catch{}try{unlinkSync(o);}catch{}}console.log(l.blue("Starting DevFlow server..."));let{pid:n}=await M({port:e.port});console.log(l.green(` Server started (PID: ${n})`)),console.log(l.blue(" Waiting for server..."));let t=await Qn(e.port);if(console.log(t?l.green(" Server ready"):l.yellow(" Server started but health check timed out")),!e.noDashboard){console.log(l.blue("Preparing Dashboard..."));try{let r=U(process.cwd()),i=join(r,"apps","dashboard","server.js"),s=spawn("node",[i],{env:{...process.env,PORT:String(e.dashboardPort)},cwd:r,stdio:"ignore",detached:!0});if(s.pid){let a=C(),d=join(process.cwd(),".devflow");existsSync(d)||mkdirSync(d,{recursive:!0}),writeFileSync(a,`${e.dashboardPort}
26
- ${s.pid}`),s.unref(),console.log(l.green(` Dashboard started (PID: ${s.pid})`));}}catch{console.log(l.red(" Dashboard failed to start")),console.log(l.yellow(` You can still use the API at http://localhost:${e.port}`));}}console.log(""),console.log(l.green("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")),console.log(l.green("\u2551")+" \u{1F680} DevFlow Started! "+l.green("\u2551")),console.log(l.green("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563")),console.log(l.green("\u2551")+` \u{1F5A5}\uFE0F Server: http://localhost:${e.port}`.padEnd(57)+l.green("\u2551")),console.log(l.green("\u2551")+` \u{1F3A8} Dashboard: http://localhost:${e.dashboardPort}`.padEnd(57)+l.green("\u2551")),console.log(l.green("\u2551")+" "+l.green("\u2551")),console.log(l.green("\u2551")+" Press Ctrl+C to stop all services "+l.green("\u2551")),console.log(l.green("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")),e.background||await new Promise(r=>{let i=false,s=async()=>{if(i)return;i=true,console.log(l.blue(`
27
- Shutting down...`));let a=C();if(existsSync(a))try{let d=readFileSync(a,"utf-8").trim().split(`
28
- `),u=d.length>=2?d[1]:d[0],p=parseInt(u,10);process.kill(p),unlinkSync(a);}catch{}await R(),console.log(l.green("All services stopped.")),r();};process.on("SIGINT",s),process.on("SIGTERM",s);});}async function Eo(){let e=false,o=C();if(existsSync(o))try{let t=x(o);t!==null&&(process.kill(t),console.log(l.green(`Dashboard stopped (PID: ${t})`))),unlinkSync(o),e=!0;}catch{unlinkSync(o),console.log(l.yellow("Dashboard process not found, cleaned up PID file"));}await R()&&(console.log(l.green("Server stopped")),e=true),e||console.log(l.dim("No DevFlow services running"));}function nt(){return join(process.cwd(),".devflow","devflow.db")}async function To(){console.log(l.blue("DevFlow Status")),console.log(l.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));let e=await F(),o=e.port??de;e.running?console.log(`Server: ${l.green("\u2713")} running (port ${o}${e.pid?`, PID ${e.pid}`:""})`):console.log(`Server: ${l.yellow("\u25CB")} not running`);let n=C();if(existsSync(n)){let r=ge(n),i=x(n);if(i!==null)try{process.kill(i,0);let s=r!==null?`port ${r}`:"port 17788";console.log(`Dashboard: ${l.green("\u2713")} running (${s}, PID ${i})`);}catch{console.log(`Dashboard: ${l.red("\u2717")} PID ${i} not found (stale PID file)`);}else console.log(`Dashboard: ${l.yellow("\u25CB")} not running (unreadable PID file)`);}else console.log(`Dashboard: ${l.yellow("\u25CB")} not running`);let t=nt();if(existsSync(t)){let i=(statSync(t).size/1024/1024).toFixed(1);console.log(`Data: .devflow/devflow.db (${i} MB)`);}else console.log(`Data: ${l.dim("no database")}`);}var ct=createRequire(import.meta.url);function dt(){let e=[resolve(dirname(ct.resolve("../../package.json")),"dist","plugin"),resolve(process.cwd(),"plugins","claude-code")];for(let o of e)if(existsSync(join(o,".claude-plugin","plugin.json")))return o;return null}function gt(e,o){let n={};if(existsSync(e))try{n=JSON.parse(readFileSync(e,"utf-8"));}catch{n={};}let t={...n,...o};writeFileSync(e,JSON.stringify(t,null,2));}async function Lo(e){if(console.log(l.blue("DevFlow Setup")),console.log(l.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),!e.skipMcp)try{let o=await T({agent:e.agent,command:"devflow-mcp"});for(let n of o)console.log(l.green(` \u2713 MCP: ${n}`));}catch(o){console.log(l.yellow(` \u26A0 MCP setup failed: ${o.message}`)),console.log(l.dim(" You can configure MCP manually with: devflow connect"));}if(!e.skipPlugin){let o=dt();if(o){let n=join(homedir(),".claude","plugins");mkdirSync(n,{recursive:true});let t=join(n,"known_marketplaces.json");gt(t,{devflow:{source:{directory:o}}}),console.log(l.green(` \u2713 Plugin registered: ${o}`));}else console.log(l.yellow(" \u26A0 Plugin directory not found")),console.log(l.dim(" The Claude Code plugin may not be available."));}console.log(""),console.log(l.green("Setup complete!")),console.log(l.dim("Restart Claude Code to use /devflow:* commands"));}var Wo=new Command("list").description("List available plugins").option("-i, --installed","Show only installed plugins").action(async e=>{let o=D();if(e.installed){let n=Me();if(n.length===0){console.log("No plugins installed."),console.log(`
29
- Run "devflow plugin list" to see available plugins.`);return}console.log(`Installed plugins:
30
- `),n.forEach(t=>{let r=o.plugins.find(i=>i.name===t);r?(console.log(` ${l.green(r.name)}@${r.version}`),console.log(` ${r.description}`)):console.log(` ${l.green(t)}`);});}else {if(o.plugins.length===0){console.log("No plugins available.");return}console.log(`Available plugins (${o.plugins.length}):
31
- `);let n=Math.max(...o.plugins.map(t=>t.name.length));o.plugins.forEach(t=>{let r=" ".repeat(n-t.name.length+2);console.log(` ${l.green(t.name)}${r}v${t.version}`),console.log(` ${" ".repeat(n)}${t.description.substring(0,60)}`),t.tags.length>0&&console.log(` ${" ".repeat(n)}Tags: ${t.tags.join(", ")}`),console.log("");}),console.log(`
32
- Install a plugin: devflow plugin install <name>`);}});var Uo=new Command("search").description("Search for plugins").argument("<keyword>","Search keyword").action(async e=>{let o=D(),n=e.toLowerCase(),t=o.plugins.filter(r=>r.name.toLowerCase().includes(n)||r.description.toLowerCase().includes(n)||r.tags.some(i=>i.toLowerCase().includes(n)));if(t.length===0){console.log(`No plugins found matching "${e}"`),console.log(`
33
- Try: devflow plugin list`);return}console.log(`Found ${t.length} plugin(s) matching "${e}":
34
- `),t.forEach(r=>{console.log(` ${l.green(r.name)}@${r.version}`),console.log(` ${r.description}`),r.tags.length>0&&console.log(` Tags: ${r.tags.join(", ")}`),console.log(` Size: ${r.size}`),console.log("");});});var Go=new Command("install").description("Install a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let o=e.startsWith("@devflow-tools/")?e:`@devflow-tools/${e}`;console.log(`Installing ${o}...`);try{execSync(`npm install -g ${o}`,{stdio:"inherit"}),console.log(`
35
- ${l.green("\u2713")} ${o} installed successfully`),console.log(`
36
- Run "devflow plugin list --installed" to verify.`);}catch(n){console.error(`
37
- ${l.red("\u2717")} Installation failed: ${n.message}`),process.exit(1);}});var qo=new Command("uninstall").description("Uninstall a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let o=e.startsWith("@devflow-tools/")?e:`@devflow-tools/${e}`;console.log(`Uninstalling ${o}...`);try{execSync(`npm uninstall -g ${o}`,{stdio:"inherit"}),console.log(`
38
- ${l.green("\u2713")} ${o} uninstalled successfully`);}catch(n){console.error(`
39
- ${l.red("\u2717")} Uninstallation failed: ${n.message}`),process.exit(1);}});var Vo=new Command("dashboard").description("Start DevFlow Dashboard").option("-p, --port <port>","Port to run on","17788").option("--force","Force re-extract Dashboard from npm package").action(async e=>{try{if(e.force){let r=join(process.cwd(),".devflow","dashboard","version.txt");try{unlinkSync(r);}catch{}}console.log(l.blue("Preparing Dashboard..."));let o=U(process.cwd()),n=join(o,"apps","dashboard","server.js");existsSync(n)||(console.error(l.red(`Dashboard server.js not found at: ${n}
40
- The archive may be corrupted. Try: devflow dashboard --force`)),process.exit(1)),console.log(l.green(`
41
- Starting Dashboard: http://localhost:${e.port}
42
- `));let t=spawn("node",[n],{stdio:"inherit",env:{...process.env,PORT:e.port}});t.on("error",r=>{console.error(l.red("Failed to start Dashboard:"),r),process.exit(1);}),t.on("exit",r=>{process.exit(r||0);});}catch(o){console.error(l.red("Failed to start Dashboard:"),o.message),process.exit(1);}});var Bo=createRequire(import.meta.url),G="0.0.0";try{G=Bo("../package.json").version;}catch{try{G=Bo("../../package.json").version;}catch{}}var c=new Command;c.name("devflow").description("Developer Intelligence Platform for AI Coding Agents").version(G).option("--local","Force local engine, skip server");c.command("init").description("Initialize .devflow/ in the current project").option("--force","Overwrite existing config").option("--abort","Force delete .codegraph and .devflow directories before reinitializing").option("--report","Output onboarding markdown report to stdout").option("--json","Output onboarding pack as JSON to stdout").option("--plugins <names>","Comma-separated list of plugins to install (non-interactive)").option("--no-plugins","Skip plugin installation guide").action(async e=>{let o=process.cwd();if(e.abort){console.log(l.yellow("\u{1F5D1}\uFE0F --abort flag detected, removing existing directories..."));let r=[".codegraph",".devflow"];for(let i of r){let s=xt.join(o,i);zo.existsSync(s)&&(console.log(l.dim(` Removing ${i}/...`)),zo.rmSync(s,{recursive:true,force:true}));}console.log(l.green(`\u2705 Existing directories removed
43
- `));}let n=z(o);console.error(l.blue(`DevFlow init \u2014 mode: ${n}`));let t=await Z(o,{force:e.force});if(e.json&&t.onboardingPack)console.log(JSON.stringify(t.onboardingPack,null,2));else if(e.report&&t.onboardingPack){let{renderInitReport:r}=await Promise.resolve().then(()=>(ee(),Ae));console.log(r(t.onboardingPack));}else {if(t.created.length>0){console.log(l.green("Created:"));for(let r of t.created)console.log(` ${l.dim("+")} ${r}`);}else console.log(l.dim("Already initialized. Use --force to overwrite config."));if(t.indexed&&console.log(l.green(`\u2705 CodeGraph initialized (${t.indexed.files} files, ${t.indexed.symbols} symbols)`)),t.onboardingPack){let r=t.onboardingPack;console.log(l.green("\u2705 Onboarding pack generated")),console.log(l.dim(` ${r.stats.files} files, ${r.stack.frameworks.join(", ")||"no framework"}`));}t.pluginDeployed&&console.log(l.green("\u2705 Plugin deployed to ~/.claude/plugins/cache/")),t.pluginEnabled&&console.log(l.green("\u2705 Plugin enabled in ~/.claude/settings.json")),t.mcpConfigured&&console.log(l.green("\u2705 MCP config written to .claude/mcp.json")),t.pluginDeployed&&t.pluginEnabled&&t.mcpConfigured&&console.log(l.green("\nDevFlow is ready! Run `claude` to start.")),typeof e.plugins=="string"?await Le(e.plugins):e.plugins!==false&&await We(o);}});c.command("connect [agent]").description("Configure MCP connection for AI coding agents").option("--command <cmd>","MCP server command","devflow-mcp").option("--sse <url>","SSE server URL (instead of stdio)").action(async(e,o)=>{let n=process.cwd(),t=z(n);if(console.log(l.blue(`DevFlow connect \u2014 mode: ${t}`)),e){let r=Ue();r.includes(e)||(console.log(l.red(`Unknown agent: ${e}`)),console.log(`Available: ${r.join(", ")}`),process.exit(1));}try{let r=await T({agent:e,command:o.command,sseUrl:o.sse});for(let i of r)console.log(l.green(`\u2713 ${i}`));}catch(r){console.error(l.red(`Error: ${r.message}`)),process.exit(1);}});c.command("index").description("Show index status").option("--watch","Start file watcher for hot updates (stub)").action(async e=>{let o=await _e(c.opts().local);console.log(l.blue("Index Status")),console.log(` Files: ${o.totalFiles}`),console.log(` Symbols: ${o.totalSymbols}`),console.log(` Indexing: ${o.indexing?"active":"idle"}`),e.watch&&console.log(l.dim(" (watch mode not yet implemented)"));});c.command("graph [target]").description("Show dependency graph").option("--depth <n>","Expansion depth","2").action(async(e,o)=>{let n=await qe({target:e,depth:parseInt(o.depth,10),skipServer:c.opts().local});console.log(l.blue("Dependency Graph")),console.log(` Nodes: ${n.nodes.length}`),console.log(` Edges: ${n.edges.length}`);});c.command("context <query>").description("Retrieve project context for a query").option("--mode <mode>","fast | deep","fast").option("--max-tokens <n>","Max token budget","4000").option("--task","Use task-oriented mode with risk hints and next actions").option("--why","Show reasoning for file selection").action(async(e,o)=>{if(o.task){let n=await ze({query:e,mode:o.mode,maxTokens:parseInt(o.maxTokens,10),skipServer:c.opts().local});console.log(JSON.stringify({requiredFiles:n.requiredFiles,optionalFiles:n.optionalFiles,riskHints:n.riskHints,nextActions:n.nextActions,reasoning:o.why?n.reasoning:void 0},null,2));}else {let n=await Ve({query:e,mode:o.mode,maxTokens:parseInt(o.maxTokens,10),skipServer:c.opts().local});console.log(l.blue(`Context: "${e}"`)),console.log(` Files: ${n.files.length}`),console.log(` Confidence: ${(n.confidence*100).toFixed(0)}%`),console.log(` Tokens: ${n.tokenCount}`);}});var _=c.command("workflow").description("Workflow management");_.command("list").description("List available workflows").action(async()=>{let e=await Be(c.opts().local);if(e.length===0){console.log(l.dim("No workflows registered."));return}for(let o of e)console.log(`${l.green(o.name)} \u2014 ${o.description} (${o.stepCount} steps)`);});_.command("run <type> [input]").description("Run a workflow").action(async(e,o)=>{let n=await He(e,{input:o??""},c.opts().local);console.log(`Run: ${n.runId}`),console.log(`Status: ${n.status}`),console.log(`Duration: ${n.duration}ms`);});_.command("status").description("Show running workflows").action(async()=>{let e=await Ye(c.opts().local);console.log(`${e.length} run(s)`);for(let o of e)console.log(` ${o.runId} \u2014 ${o.status}`);});_.command("runs").description("Show workflow history").action(async()=>{let e=await re(c.opts().local);if(e.length===0){console.log(l.dim("No runs yet."));return}for(let o of e){let n=o.finishedAt?`${o.finishedAt-o.startedAt}ms`:"running";console.log(` ${o.runId} ${l.yellow(o.status)} ${n}`);}});var ye=c.command("memory").description("Memory management");ye.command("show").description("Show current project memory").action(async()=>{let e=await Xe(c.opts().local);console.log(JSON.stringify(e,null,2));});ye.command("set <key> <value>").description("Set a memory key").action(async(e,o)=>{await Qe(e,o,c.opts().local),console.log(l.green(`Memory set: ${e} = ${o}`));});ye.command("review").description("Review memory candidates").action(async()=>{let e=await Ze(c.opts().local);console.log(JSON.stringify(e,null,2));});c.command("knowledge <query>").description("Search knowledge base").action(async e=>{let o=await eo(e,void 0,c.opts().local);console.log(l.blue(`Knowledge: "${e}"`)),console.log(` Results: ${o.length}`);for(let n of o.slice(0,5))console.log(` \u2014 ${n.title}`);});c.command("docs sync [plugin-name]").description("Sync documentation for plugins").action(async e=>{console.log(l.blue(`\u25C9 Syncing docs${e?` for ${e} plugin`:""}`));let o=new KnowledgeEngine({projectRoot:process.cwd()});if(e){let n=await o.syncDocs(e);for(let t of n)t.added>0?console.log(` ${l.green("\u2713")} ${t.source} \u2192 ${t.added} chunks`):console.log(` ${l.red("\u2717")} ${t.source} \u2014 ${t.errors.join(", ")||"no content"}`);console.log(l.green(`
44
- ${e} docs synced to .devflow/knowledge/${e}/`));}else {let n=await o.getSources();for(let t of n){let r=await o.syncDocs(t.source.name);for(let i of r)i.added>0?console.log(` ${l.green("\u2713")} ${i.source} \u2192 ${i.added} chunks`):console.log(` ${l.red("\u2717")} ${i.source} \u2014 ${i.errors.join(", ")||"no content"}`);}console.log(l.green(`
45
- All docs synced.`));}});var q=c.command("skill").description("Plugin/Skill management");q.command("list").description("List installed skills").action(async()=>{let e=await ie(c.opts().local);if(e.length===0){console.log(l.dim("No skills installed. Use 'devflow skill search' to find plugins."));return}for(let o of e)console.log(` ${l.green(o.name)} @ ${o.version} \u2014 ${o.description}`);});q.command("search <query>").description("Search available plugins").action(async e=>{let o=await ro(e,c.opts().local);if(console.log(l.blue(`Search: "${e}"`)),o.length===0){console.log(l.dim(" No matching plugins found."));return}for(let n of o)console.log(` ${l.green(n.name)} @ ${n.version} \u2014 ${n.description}`);});q.command("install <name>").description("Install a plugin/skill").action(async e=>{try{let o=await lo(e,process.cwd(),c.opts().local);console.log(l.green(`\u2713 Installed @devflow-tools/plugin-${o.name}@${o.version}`)),o.templates.length>0&&console.log(` Templates: ${o.templates.join(", ")}`);}catch(o){console.log(l.red(`Error: ${o.message}`)),process.exit(1);}});q.command("uninstall <name>").description("Uninstall a plugin/skill").action(async e=>{try{await ao(e,process.cwd(),c.opts().local),console.log(l.green(`\u2713 Uninstalled ${e}`));}catch(o){console.log(l.red(`Error: ${o.message}`)),process.exit(1);}});c.command("doctor").description("Run project health check").option("--json","Output as JSON").option("--audit","Verify audit chain integrity").option("--audit-fix","Rebuild audit chain signatures").option("--violations","Show violation records").option("--last <period>","Filter violations by time (e.g. 7d, 24h)").option("--receipts","Show current session receipt status").action(async e=>{if(e.audit){let t=await fo();console.log(e.json?JSON.stringify(t):`Audit chain: ${t.valid?"VALID":`BROKEN at seq ${t.brokenAt}`} (${t.entryCount} entries)`);return}if(e.auditFix){let t=await wo();console.log(e.json?JSON.stringify(t):"Audit chain rebuilt.");return}if(e.violations){let t=await ho(e.last);console.log(e.json?JSON.stringify(t):JSON.stringify(t,null,2));return}if(e.receipts){let t=yo();e.json?console.log(JSON.stringify(t)):t.data?console.log(JSON.stringify(t.data,null,2)):console.log(`No active receipt found for session ${t.sessionId}.`);return}let o=await mo();if(e.json){console.log(JSON.stringify(o));return}if(console.log(l.blue(`DevFlow Doctor v${G}
46
- `)),console.log(l.bold("\u25C9 Index Status")),console.log(` Files ${o.index.totalFiles.toLocaleString()}`),console.log(` Symbols ${o.index.totalSymbols.toLocaleString()}`),console.log(` Graph (${o.graph.edges.toLocaleString()} edges)`),console.log(` Status ${o.index.indexing?"indexing":"idle"}`),console.log(),console.log(l.bold("\u25C9 Memory")),console.log(` Project ${o.memory.projectReady?"ready":"not set"}`),console.log(` Preferences ${o.memory.userPrefs} set`),console.log(),console.log(l.bold("\u25C9 Knowledge")),console.log(` Sources ${o.knowledge.sources}`),console.log(),console.log(l.bold("\u25C9 Server")),o.server.running?console.log(` ${l.green("\u2714")} Running on http://localhost:13337`):console.log(` ${l.yellow("\u25CB")} Not running \u2014 run \`devflow server start\` for telemetry`),console.log(),console.log(l.bold("\u25C9 Plugins")),o.plugins.installed===0)console.log(` ${l.dim("No plugins installed")}`);else for(let t of o.plugins.names)console.log(` ${t}`);console.log(),console.log(l.bold("\u25C9 Workflows")),console.log(` Registered ${o.workflows.registered}`),console.log();let n=o.readyScore>=70?l.green:o.readyScore>=40?l.yellow:l.red;console.log(`AI Ready: ${n(o.readyScore+"%")}`);});c.command("session token").description("Generate a session token for MCP Gateway authentication").option("--expires <seconds>","Token TTL in seconds","3600").action(async e=>{let o=await vo(process.cwd(),parseInt(e.expires,10));console.log(JSON.stringify(o,null,2));});c.command("benchmark [target]").description("Run benchmark on engines").option("--iterations <n>","Number of iterations","5").option("--output <format>","json | text","text").action(async(e,o)=>{let n=await So(e??"all",{iterations:parseInt(o.iterations,10),output:o.output});console.log(n);});c.command("review [pr-url]").description("Review a PR or current branch diff").option("--agent <agent>","AI agent to use","claude").action(async(e,o)=>{let n=await ko({prUrl:e,agent:o.agent});console.log(n);});var ve=c.command("server").description("Manage DevFlow server");ve.command("start").description("Start the DevFlow REST server").option("--port <n>","Port number","13337").action(async e=>{console.log(l.blue("Starting DevFlow server..."));let o=await M({port:parseInt(e.port,10)});console.log(l.green(`Server started (pid: ${o.pid}) on port ${e.port}`));});ve.command("stop").description("Stop the DevFlow REST server").action(async()=>{let e=await R();console.log(e?l.green("Server stopped"):l.dim("No server running"));});ve.command("status").description("Show server status").action(async()=>{let e=await F();e.running?console.log(l.green(`Running (pid: ${e.pid})`)):console.log(l.yellow("Not running"));});c.addCommand(Vo);c.command("start").description("Start DevFlow server and dashboard").option("--port <n>","Server port","13337").option("--dashboard-port <n>","Dashboard port","17788").option("--no-dashboard","Start server only, no dashboard").option("-d, --background","Run in background (detached)").action(async e=>{await Oo({port:parseInt(e.port,10),dashboardPort:parseInt(e.dashboardPort,10),noDashboard:!e.dashboard,background:!!e.background});});c.command("stop").description("Stop DevFlow server and dashboard").action(async()=>{await Eo();});c.command("status").description("Show DevFlow services status").action(async()=>{await To();});c.command("setup").description("Configure Claude Code integration (MCP + plugin)").option("--agent <agent>","Target agent (claude/cursor/cline)").option("--skip-mcp","Skip MCP configuration").option("--skip-plugin","Skip plugin registration").action(async e=>{await Lo({agent:e.agent,skipMcp:!!e.skipMcp,skipPlugin:!!e.skipPlugin});});var K=c.command("plugin").description("Manage DevFlow plugins");K.addCommand(Wo);K.addCommand(Uo);K.addCommand(Go);K.addCommand(qo);c.parse();