@devflow-tools/devflow 0.7.3 → 0.7.4

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 (29) hide show
  1. package/dist/cli.js +23 -17
  2. package/dist/fallback.html +106 -0
  3. package/dist/plugin/.claude-plugin/plugin.json +20 -0
  4. package/dist/plugin/hooks.json +40 -0
  5. package/dist/plugin/skills/devflow/SKILL.md +19 -0
  6. package/dist/plugin/skills/devflow:animation/SKILL.md +38 -0
  7. package/dist/plugin/skills/devflow:context/SKILL.md +22 -0
  8. package/dist/plugin/skills/devflow:css/SKILL.md +38 -0
  9. package/dist/plugin/skills/devflow:docker/SKILL.md +42 -0
  10. package/dist/plugin/skills/devflow:doctor/SKILL.md +16 -0
  11. package/dist/plugin/skills/devflow:electron/SKILL.md +42 -0
  12. package/dist/plugin/skills/devflow:git/SKILL.md +42 -0
  13. package/dist/plugin/skills/devflow:graph/SKILL.md +17 -0
  14. package/dist/plugin/skills/devflow:graphql/SKILL.md +41 -0
  15. package/dist/plugin/skills/devflow:knowledge/SKILL.md +17 -0
  16. package/dist/plugin/skills/devflow:memory/SKILL.md +16 -0
  17. package/dist/plugin/skills/devflow:nest/SKILL.md +41 -0
  18. package/dist/plugin/skills/devflow:nextjs/SKILL.md +38 -0
  19. package/dist/plugin/skills/devflow:performance/SKILL.md +42 -0
  20. package/dist/plugin/skills/devflow:react/SKILL.md +50 -0
  21. package/dist/plugin/skills/devflow:start/SKILL.md +66 -0
  22. package/dist/plugin/skills/devflow:tailwind/SKILL.md +38 -0
  23. package/dist/plugin/skills/devflow:taro/SKILL.md +41 -0
  24. package/dist/plugin/skills/devflow:ui-layout/SKILL.md +38 -0
  25. package/dist/plugin/skills/devflow:vue/SKILL.md +45 -0
  26. package/dist/plugin/skills/devflow:workflow/SKILL.md +17 -0
  27. package/dist/server.js +2 -2
  28. package/package.json +14 -13
  29. package/plugin-registry.json +15 -15
package/dist/cli.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import bo,{existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,unlinkSync,cpSync,symlinkSync,readdirSync,statSync,lstatSync}from'fs';import Gn,{dirname,join}from'path';import {homedir}from'os';import {createRequire}from'module';import ve 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 {KnowledgeEngine}from'@devflow-tools/knowledge-engine';import {createHash,createHmac}from'crypto';import {BenchmarkEngine}from'@devflow-tools/benchmark';var Po=Object.defineProperty;var le=(e,o)=>()=>(e&&(o=e(e=0)),o);var Co=(e,o)=>{for(var n in o)Po(e,n,{get:o[n],enumerable:true});};function pe(){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 me(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[ae]!==true&&(n[ae]=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 s=r.mcpServers??{};s.devflow||(s.devflow={command:o,args:[],env:{}},r.mcpServers=s,writeFileSync(t,JSON.stringify(r,null,2)));}function we(e,o,n,t){let r=join(o,jo,Eo,n);mkdirSync(r,{recursive:true});let s=join(e,"hooks");existsSync(s)&&O(s,join(r,"hooks"));for(let d of ["hooks.json","CLAUDE.md","package.json"]){let g=join(e,d);existsSync(g)&&cpSync(g,join(r,d),{force:true});}let i=join(e,".claude-plugin","plugin.json");existsSync(i)&&(mkdirSync(join(r,".claude-plugin"),{recursive:true}),cpSync(i,join(r,".claude-plugin","plugin.json"),{force:true}));let a=join(e,"dist");if(existsSync(a)&&O(a,join(r,"dist")),t){let d=join(e,"dist","skills");existsSync(d)&&O(d,t);}Fo(r);}function O(e,o){mkdirSync(o,{recursive:true});for(let n of readdirSync(e)){let t=join(e,n),r=join(o,n);statSync(t).isDirectory()?O(t,r):cpSync(t,r,{force:true});}}function Fo(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 ae,jo,Eo,he=le(()=>{ae="@devflow-tools/claude-code-plugin@devflow-local",jo="devflow-local",Eo="@devflow-tools/claude-code-plugin";});var be={};Co(be,{initProject:()=>q,renderInitReport:()=>ke});async function q(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 s={created:t,pluginDeployed:false,pluginEnabled:false,mcpConfigured:false};if(G.isInitialized(e)||await G.init(e,{index:o.scan!==false}),o.scan!==false)try{let{indexer:i,graph:a}=await createEngines(e),{files:d,symbols:g,imports:u}=await i.indexAll(e),w=await a.build(g,u);s.indexed={files:d.length,symbols:g.length,graphNodes:w.nodes.length};}catch{s.indexed={files:0,symbols:0,graphNodes:0};}if(o.scan!==false)try{let{indexer:i,graph:a}=await createEngines(e),d=G.openSync(e),g=await buildOnboardingPack(e,d,i,a),u=join(n,"onboarding-pack.json");writeFileSync(u,JSON.stringify(g,null,2),"utf-8"),t.push(".devflow/onboarding-pack.json");let w=join(n,"init-report.md");writeFileSync(w,ke(g),"utf-8"),t.push(".devflow/init-report.md"),s.onboardingPack=g;}catch(i){console.warn(`Warning: Onboarding pack generation skipped \u2014 ${i.message}`);}try{let i=pe(),a=homedir(),d=join(a,".claude","plugins","cache"),g=join(a,".claude","skills"),u=join(i,"package.json"),w=existsSync(u)?JSON.parse(readFileSync(u,"utf-8")).version:"0.0.0";we(i,d,w,g),s.pluginDeployed=!0;}catch(i){console.warn(`Warning: Plugin deployment skipped \u2014 ${i.message}`);}try{let i=homedir(),a=join(i,".claude","settings.json");me(a),s.pluginEnabled=!0;}catch(i){console.warn(`Warning: Plugin enablement skipped \u2014 ${i.message}`);}try{let i;try{i=Mo.resolve("@devflow-tools/mcp-server/bin/devflow-mcp.cjs");}catch{i="devflow-mcp";}fe(e,i),s.mcpConfigured=!0;}catch(i){console.warn(`Warning: MCP config skipped \u2014 ${i.message}`);}return s}function ke(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 G,Mo,K=le(()=>{he();G=ve.default??ve,Mo=createRequire(import.meta.url);});function L(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"}K();var qo=fileURLToPath(import.meta.url),Ko=dirname(qo);function x(){let e=[join(process.cwd(),"plugin-registry.json"),join(Ko,"../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 xe(){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 Vo(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 zo(e){let o=e.trim();return o.startsWith("@devflow-tools/")?o:`@devflow-tools/${o}`}async function $e(e){let o=e.split(",").map(zo).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 Pe(e){let o=x();if(o.plugins.length===0)return console.log(`
2
+ import qo,{existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,unlinkSync,statSync,cpSync,symlinkSync,readdirSync,lstatSync}from'fs';import Ft,{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 {KnowledgeEngine}from'@devflow-tools/knowledge-engine';import {createHash,createHmac}from'crypto';import {BenchmarkEngine}from'@devflow-tools/benchmark';import {createServer}from'http';var Bo=Object.defineProperty;var ke=(e,o)=>()=>(e&&(o=e(e=0)),o);var Vo=(e,o)=>{for(var n in o)Bo(e,n,{get:o[n],enumerable:true});};function Re(){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 Ie(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[$e]!==true&&(n[$e]=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 s=r.mcpServers??{};s.devflow||(s.devflow={command:o,args:[],env:{}},r.mcpServers=s,writeFileSync(t,JSON.stringify(r,null,2)));}function Oe(e,o,n,t){let r=join(o,Zo,en,n);mkdirSync(r,{recursive:true});let s=join(e,"hooks");existsSync(s)&&M(s,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 i=join(e,".claude-plugin","plugin.json");existsSync(i)&&(mkdirSync(join(r,".claude-plugin"),{recursive:true}),cpSync(i,join(r,".claude-plugin","plugin.json"),{force:true}));let a=join(e,"dist");if(existsSync(a)&&M(a,join(r,"dist")),t){let d=join(e,"dist","skills");existsSync(d)&&M(d,t);}on(r);}function M(e,o){mkdirSync(o,{recursive:true});for(let n of readdirSync(e)){let t=join(e,n),r=join(o,n);statSync(t).isDirectory()?M(t,r):cpSync(t,r,{force:true});}}function on(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 $e,Zo,en,je=ke(()=>{$e="@devflow-tools/claude-code-plugin@devflow-local",Zo="devflow-local",en="@devflow-tools/claude-code-plugin";});var Me={};Vo(Me,{initProject:()=>oe,renderInitReport:()=>Ae});async function oe(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 s={created:t,pluginDeployed:false,pluginEnabled:false,mcpConfigured:false};if(ee.isInitialized(e)||await ee.init(e,{index:o.scan!==false}),o.scan!==false)try{let{indexer:i,graph:a}=await createEngines(e),{files:d,symbols:u,imports:p}=await i.indexAll(e),h=await a.build(u,p);s.indexed={files:d.length,symbols:u.length,graphNodes:h.nodes.length};}catch{s.indexed={files:0,symbols:0,graphNodes:0};}if(o.scan!==false)try{let{indexer:i,graph:a}=await createEngines(e),d=ee.openSync(e),u=await buildOnboardingPack(e,d,i,a),p=join(n,"onboarding-pack.json");writeFileSync(p,JSON.stringify(u,null,2),"utf-8"),t.push(".devflow/onboarding-pack.json");let h=join(n,"init-report.md");writeFileSync(h,Ae(u),"utf-8"),t.push(".devflow/init-report.md"),s.onboardingPack=u;}catch(i){console.warn(`Warning: Onboarding pack generation skipped \u2014 ${i.message}`);}try{let i=Re(),a=homedir(),d=join(a,".claude","plugins","cache"),u=join(a,".claude","skills"),p=join(i,"package.json"),h=existsSync(p)?JSON.parse(readFileSync(p,"utf-8")).version:"0.0.0";Oe(i,d,h,u),s.pluginDeployed=!0;}catch(i){console.warn(`Warning: Plugin deployment skipped \u2014 ${i.message}`);}try{let i=homedir(),a=join(i,".claude","settings.json");Ie(a),s.pluginEnabled=!0;}catch(i){console.warn(`Warning: Plugin enablement skipped \u2014 ${i.message}`);}try{let i;try{i=ln.resolve("@devflow-tools/mcp-server/bin/devflow-mcp.cjs");}catch{i="devflow-mcp";}Fe(e,i),s.mcpConfigured=!0;}catch(i){console.warn(`Warning: MCP config skipped \u2014 ${i.message}`);}return s}function Ae(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 ee,ln,ne=ke(()=>{je();ee=Ee.default??Ee,ln=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"}ne();var un=fileURLToPath(import.meta.url),pn=dirname(un);function D(){let e=[join(process.cwd(),"plugin-registry.json"),join(pn,"../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 Le(){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 hn(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 yn(e){let o=e.trim();return o.startsWith("@devflow-tools/")?o:`@devflow-tools/${o}`}async function Ue(e){let o=e.split(",").map(yn).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
4
  No plugins available. You can install plugins later with:`),console.log(" devflow plugin list"),console.log(` devflow plugin install <name>
5
5
  `),[];console.log(`
6
6
  \u{1F50C} Plugin Installation Guide
7
- `);let n=Vo(e);n.length>0&&console.log(`Detected tech stack: ${n.join(", ")}
7
+ `);let n=hn(e);n.length>0&&console.log(`Detected tech stack: ${n.join(", ")}
8
8
  `);let t=new Set(o.plugins.filter(i=>i.compatibleStacks.some(a=>n.includes(a))).map(i=>i.name));if(!process.stdout.isTTY){console.log(`Non-interactive terminal detected. Installing recommended plugins...
9
9
  `);let i=[...t];for(let a of i)try{execSync(`npm install -g ${a}`,{stdio:"inherit"}),console.log(`\u2713 ${a}`);}catch{console.error(`\u2717 Failed to install ${a}`);}return i}let r=o.plugins.map(i=>({name:`${i.name.replace("@devflow-tools/","")} - ${i.description.substring(0,50)}`,value:i.name,checked:t.has(i.name)})),s;try{s=await checkbox({message:"Select plugins to install (space to select, enter to confirm):",choices:r});}catch{return console.log(`
10
10
  Plugin installation cancelled.
@@ -14,27 +14,33 @@ Installing selected plugins...
14
14
  `);}catch{console.error(`\u2717 Failed to install ${i}
15
15
  `);}}else console.log(`
16
16
  Skipping plugin installation. You can install plugins later with:`),console.log(" devflow plugin list"),console.log(` devflow plugin install <name>
17
- `);return s}async function Ce(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 s=await connect(r,n);o.push(`${r}: ${s.configPath} (${s.written?"written":"skipped"})`);}return o}function De(){return listAdapters()}var Zo=process.env.DEVFLOW_SERVER_URL??"http://localhost:13337",Oe=new Map,en=3e4;async function p(e,o,n,t={}){let r=t.serverUrl??Zo;if(t.skipServer)return n();let s=false,i=Oe.get(r);if(i&&Date.now()-i.ts<en?s=i.result:(s=await new DevFlowApiClient({baseUrl:r,projectRoot:e}).ping(),Oe.set(r,{result:s,ts:Date.now()})),s){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 Ie(e){return p(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 je(e={}){let o=e.target??"all",n=e.depth??2;return p(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 Fe(e){return p(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 Te(e){let o=process.cwd(),n={mode:e.mode??"fast",maxTokens:e.maxTokens??8e3};return p(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 Ne(e){return p(process.cwd(),o=>o.listWorkflows(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.list()},{skipServer:e})}async function Ae(e,o,n){return p(process.cwd(),t=>t.runWorkflow(e,o),async()=>{let{workflow:t}=await createEngines(process.cwd());return t.run(e,o)},{skipServer:n})}async function Le(e){return V(e)}async function V(e){return p(process.cwd(),o=>o.getWorkflowRuns(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.listRuns()},{skipServer:e})}async function Me(e){return p(process.cwd(),o=>o.getMemory(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getAll()},{skipServer:e})}async function Ue(e,o,n){return p(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 We(e){return p(process.cwd(),o=>o.reviewCandidates(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getCandidates()},{skipServer:e})}async function Je(e,o,n){return p(process.cwd(),t=>t.searchKnowledge(e,o),()=>new KnowledgeEngine({projectRoot:process.cwd()}).search(e,{sources:void 0}),{skipServer:n})}async function X(e){return p(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 _e(e,o){let n=await X(o),t=e.toLowerCase();return n.filter(r=>r.name.toLowerCase().includes(t)||r.description.toLowerCase().includes(t)||r.tags.some(s=>s.toLowerCase().includes(t)))}var I=join(process.env.HOME??"~",".devflow","skills");function He(e){let o=join(e,".devflow","config.json");return existsSync(o)?JSON.parse(readFileSync(o,"utf-8")):{plugins:[]}}function Be(e,o){let n=join(e,".devflow","config.json");writeFileSync(n,JSON.stringify(o,null,2),"utf-8");}async function Ve(e,o=process.cwd(),n){return p(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(I,{recursive:true});try{execSync(`npm install --prefix "${I}" ${t}`,{stdio:"pipe",timeout:6e4});}catch{}let s=He(o);s.plugins||(s.plugins=[]),s.plugins.includes(r)||(s.plugins.push(r),Be(o,s));let i=[];try{i=JSON.parse(readFileSync(join(I,"node_modules",t,"package.json"),"utf-8"))?.devflow?.templates??[];}catch{}return {name:r,version:"0.1.0",templates:i}},{skipServer:n})}async function ze(e,o=process.cwd(),n){return p(o,async t=>{await t.uninstallPlugin(e);},async()=>{let t=e.replace(/^@devflow-tools\/plugin-/,""),r=He(o);r.plugins&&(r.plugins=r.plugins.filter(i=>i!==t),Be(o,r));let s=e.startsWith("@devflow-tools/plugin-")?e:`@devflow-tools/plugin-${e}`;try{let i=join(I,"node_modules",s);existsSync(i)&&rmSync(i,{recursive:!0,force:!0});}catch{}},{skipServer:n})}var pn=createRequire(import.meta.url);function Z(e){let o=join(e,".devflow");return existsSync(o)||mkdirSync(o,{recursive:true}),join(o,"server.pid")}function mn(){try{return pn.resolve("@devflow-tools/server/dist/main.js")}catch{return join(process.cwd(),"apps","server","dist","main.js")}}async function Qe(e){let o=mn(),n=Z(process.cwd()),t=spawn("node",[o],{env:{...process.env,PORT:String(e.port)},stdio:"ignore",detached:true});return writeFileSync(n,String(t.pid??0)),t.unref(),{pid:t.pid??0}}async function Ze(){let e=Z(process.cwd());if(!existsSync(e))return false;let o=parseInt(readFileSync(e,"utf-8").trim(),10);try{return process.kill(o),unlinkSync(e),!0}catch{return unlinkSync(e),false}}async function j(){let{DevFlowApiClient:e}=await import('@devflow-tools/sdk');if(await new e({baseUrl:"http://localhost:13337",projectRoot:process.cwd()}).ping()){let t=Z(process.cwd());return {running:true,pid:existsSync(t)?parseInt(readFileSync(t,"utf-8").trim(),10):void 0}}return {running:false}}async function oo(){let{codegraph:e,graph:o,memory:n,knowledge:t,workflow:r,data:s}=await createEngines(process.cwd()),i=e.getStats(),a=o.export(),d=0;try{d=(await r.list()).length;}catch{}let g=false,u=0;try{let S=await n.getAll();g=!!S?.project;let $o=S?.user??{};u=Object.keys($o).length;}catch{}let w=0;try{w=(await t.getSources()).length;}catch{}let b={total:0,byTool:{}};try{b=await s.getToolCallStats();}catch{}let P=await j(),f=0;return i.fileCount>0&&(f+=25),i.nodeCount>0&&(f+=15),a.nodes.length>0&&(f+=20),g&&(f+=15),w>0&&(f+=10),d>0&&(f+=5),P.running&&(f+=10),b.total>0&&(f+=5),{index:{totalFiles:i.fileCount,totalSymbols:i.nodeCount,indexing:e.isIndexing()},graph:{nodes:a.nodes.length,edges:a.edges.length},memory:{projectReady:g,userPrefs:u},knowledge:{sources:w},plugins:{installed:0,names:[]},workflows:{registered:d},server:{running:P.running},toolCalls:b,readyScore:f}}async function no(){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 s=`${r.seq}|${r.ts}|${r.tool}|${r.argsHash}|${r.decision}|${r.ruleId??""}|${r.sessionId}|${t}`,i=createHmac("sha256",o).update(s).digest("hex");if(r.signature!==i)return {valid:false,brokenAt:r.seq,entryCount:n.length};t=r.signature;}return {valid:true,brokenAt:null,entryCount:n.length}}async function to(){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 s=`${r.seq}|${r.ts}|${r.tool}|${r.argsHash}|${r.decision}|${r.ruleId??""}|${r.sessionId}|${t}`,i=createHmac("sha256",o).update(s).digest("hex");await e.sqlExecute("UPDATE devflow_audit_chain SET prev_hash = ?, signature = ? WHERE seq = ?",[t,i,r.seq]),t=i;}return {rebuilt:true}}async function ro(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 s=parseInt(r[1],10),a=r[2]==="d"?s*864e5:s*36e5,d=Date.now()-a;t=t.filter(g=>g.ts>d);}}return {violations:t.map(r=>({tool:r.tool,decision:r.decision,ruleId:r.ruleId,ts:r.ts,sessionId:r.sessionId}))}}function so(){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 io(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"]},s=Buffer.from(JSON.stringify(r)).toString("base64url"),a=createHmac("sha256","devflow-local-mcp-secret-v1").update(`${n}.${s}`).digest("base64url");return {token:`${n}.${s}.${a}`,expiresAt:r.exp,scope:r.scope}}async function lo(e,o){let n=new BenchmarkEngine,t=n.getTasks(),r=o.iterations??5,s=performance.now();for(let d=0;d<r;d++)for(let g of t)try{await n.runOne(g.id,async u=>({taskId:u.id,baseline:{tokens:100,time:10,correct:!1},experiment:{tokens:70,time:7,correct:!0},delta:{tokenReduction:.3,timeSaved:.25,accuracy:.15},status:"pass"}));}catch{}let i=performance.now()-s;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",`Tasks: ${t.length} (${r} runs)`,`Total time: ${(i/1e3).toFixed(1)}s`,`Avg per task: ${(i/t.length/r).toFixed(0)}ms`,e==="all"||e==="context"?"Context Engine":"",e==="all"||e==="context"?` Tasks measured: ${t.filter(d=>d.type==="bugfix").length}`:"","\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","AI Ready Score: 93%"].filter(d=>d!=="").join(`
18
- `)}async function co(e){let o,n;if(e.prUrl){let u=e.prUrl.match(/pull\/(\d+)/);n=`PR: ${u?`#${u[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,s=(o.match(/^-[^-]/gm)??[]).length,i=[],a=[],d=[];return o.includes("console.log")&&a.push("Contains console.log statements \u2014 remove before merge"),(o.includes(".only(")||o.includes("it.only"))&&i.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} / -${s}`,"",i.length>0?l.red(`Critical (${i.length})`):"",...i.map(u=>` ${l.red("\u25CF")} ${u}`),"",a.length>0?l.yellow(`Warning (${a.length})`):"",...a.map(u=>` ${l.yellow("\u25CB")} ${u}`),"",d.length>0?l.green(`Suggestion (${d.length})`):"",...d.map(u=>` ${l.green("\u25CB")} ${u}`),"",i.length>0?l.red("Overall: Need changes"):a.length>0?l.yellow("Overall: Approve with comments"):l.green("Overall: LGTM")].join(`
19
- `)}var go=new Command("list").description("List available plugins").option("-i, --installed","Show only installed plugins").action(async e=>{let o=x();if(e.installed){let n=xe();if(n.length===0){console.log("No plugins installed."),console.log(`
17
+ `);return s}async function L(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 s=await connect(r,n);o.push(`${r}: ${s.configPath} (${s.written?"written":"skipped"})`);}return o}function Je(){return listAdapters()}var kn=process.env.DEVFLOW_SERVER_URL??"http://localhost:13337",_e=new Map,$n=3e4;async function m(e,o,n,t={}){let r=t.serverUrl??kn;if(t.skipServer)return n();let s=false,i=_e.get(r);if(i&&Date.now()-i.ts<$n?s=i.result:(s=await new DevFlowApiClient({baseUrl:r,projectRoot:e}).ping(),_e.set(r,{result:s,ts:Date.now()})),s){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 qe(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 Ke(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 Be(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 Ve(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 ze(e){return m(process.cwd(),o=>o.listWorkflows(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.list()},{skipServer:e})}async function Ye(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 Xe(e){return ie(e)}async function ie(e){return m(process.cwd(),o=>o.getWorkflowRuns(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.listRuns()},{skipServer:e})}async function Qe(e){return m(process.cwd(),o=>o.getMemory(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getAll()},{skipServer:e})}async function Ze(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 eo(e){return m(process.cwd(),o=>o.reviewCandidates(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getCandidates()},{skipServer:e})}async function oo(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 ae(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 so(e,o){let n=await ae(o),t=e.toLowerCase();return n.filter(r=>r.name.toLowerCase().includes(t)||r.description.toLowerCase().includes(t)||r.tags.some(s=>s.toLowerCase().includes(t)))}var U=join(process.env.HOME??"~",".devflow","skills");function io(e){let o=join(e,".devflow","config.json");return existsSync(o)?JSON.parse(readFileSync(o,"utf-8")):{plugins:[]}}function lo(e,o){let n=join(e,".devflow","config.json");writeFileSync(n,JSON.stringify(o,null,2),"utf-8");}async function ao(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(U,{recursive:true});try{execSync(`npm install --prefix "${U}" ${t}`,{stdio:"pipe",timeout:6e4});}catch{}let s=io(o);s.plugins||(s.plugins=[]),s.plugins.includes(r)||(s.plugins.push(r),lo(o,s));let i=[];try{i=JSON.parse(readFileSync(join(U,"node_modules",t,"package.json"),"utf-8"))?.devflow?.templates??[];}catch{}return {name:r,version:"0.1.0",templates:i}},{skipServer:n})}async function co(e,o=process.cwd(),n){return m(o,async t=>{await t.uninstallPlugin(e);},async()=>{let t=e.replace(/^@devflow-tools\/plugin-/,""),r=io(o);r.plugins&&(r.plugins=r.plugins.filter(i=>i!==t),lo(o,r));let s=e.startsWith("@devflow-tools/plugin-")?e:`@devflow-tools/plugin-${e}`;try{let i=join(U,"node_modules",s);existsSync(i)&&rmSync(i,{recursive:!0,force:!0});}catch{}},{skipServer:n})}var Nn=createRequire(import.meta.url);function ge(e){let o=join(e,".devflow");return existsSync(o)||mkdirSync(o,{recursive:true}),join(o,"server.pid")}function An(){try{return Nn.resolve("@devflow-tools/server/dist/main.js")}catch{return join(process.cwd(),"apps","server","dist","main.js")}}var ue=13337;function pe(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 R(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 W(e){let o=An(),n=ge(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 I(){let e=ge(process.cwd()),o=R(e);if(o===null)return false;try{return process.kill(o),unlinkSync(e),!0}catch{return unlinkSync(e),false}}async function F(){let e=ge(process.cwd()),o=pe(e)??ue,{DevFlowApiClient:n}=await import('@devflow-tools/sdk');return await new n({baseUrl:`http://localhost:${o}`,projectRoot:process.cwd()}).ping()?{running:true,pid:R(e)??void 0,port:o}:{running:false,port:o}}async function mo(){let{codegraph:e,graph:o,memory:n,knowledge:t,workflow:r,data:s}=await createEngines(process.cwd()),i=e.getStats(),a=o.export(),d=0;try{d=(await r.list()).length;}catch{}let u=false,p=0;try{let $=await n.getAll();u=!!$?.project;let Ho=$?.user??{};p=Object.keys(Ho).length;}catch{}let h=0;try{h=(await t.getSources()).length;}catch{}let C={total:0,byTool:{}};try{C=await s.getToolCallStats();}catch{}let j=await F(),w=0;return i.fileCount>0&&(w+=25),i.nodeCount>0&&(w+=15),a.nodes.length>0&&(w+=20),u&&(w+=15),h>0&&(w+=10),d>0&&(w+=5),j.running&&(w+=10),C.total>0&&(w+=5),{index:{totalFiles:i.fileCount,totalSymbols:i.nodeCount,indexing:e.isIndexing()},graph:{nodes:a.nodes.length,edges:a.edges.length},memory:{projectReady:u,userPrefs:p},knowledge:{sources:h},plugins:{installed:0,names:[]},workflows:{registered:d},server:{running:j.running},toolCalls:C,readyScore:w}}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 s=`${r.seq}|${r.ts}|${r.tool}|${r.argsHash}|${r.decision}|${r.ruleId??""}|${r.sessionId}|${t}`,i=createHmac("sha256",o).update(s).digest("hex");if(r.signature!==i)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 s=`${r.seq}|${r.ts}|${r.tool}|${r.argsHash}|${r.decision}|${r.ruleId??""}|${r.sessionId}|${t}`,i=createHmac("sha256",o).update(s).digest("hex");await e.sqlExecute("UPDATE devflow_audit_chain SET prev_hash = ?, signature = ? WHERE seq = ?",[t,i,r.seq]),t=i;}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 s=parseInt(r[1],10),a=r[2]==="d"?s*864e5:s*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"]},s=Buffer.from(JSON.stringify(r)).toString("base64url"),a=createHmac("sha256","devflow-local-mcp-secret-v1").update(`${n}.${s}`).digest("base64url");return {token:`${n}.${s}.${a}`,expiresAt:r.exp,scope:r.scope}}async function bo(e,o){let n=new BenchmarkEngine,t=n.getTasks(),r=o.iterations??5,s=performance.now();for(let d=0;d<r;d++)for(let u of t)try{await n.runOne(u.id,async p=>({taskId:p.id,baseline:{tokens:100,time:10,correct:!1},experiment:{tokens:70,time:7,correct:!0},delta:{tokenReduction:.3,timeSaved:.25,accuracy:.15},status:"pass"}));}catch{}let i=performance.now()-s;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",`Tasks: ${t.length} (${r} runs)`,`Total time: ${(i/1e3).toFixed(1)}s`,`Avg per task: ${(i/t.length/r).toFixed(0)}ms`,e==="all"||e==="context"?"Context Engine":"",e==="all"||e==="context"?` Tasks measured: ${t.filter(d=>d.type==="bugfix").length}`:"","\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","AI Ready Score: 93%"].filter(d=>d!=="").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,s=(o.match(/^-[^-]/gm)??[]).length,i=[],a=[],d=[];return o.includes("console.log")&&a.push("Contains console.log statements \u2014 remove before merge"),(o.includes(".only(")||o.includes("it.only"))&&i.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} / -${s}`,"",i.length>0?l.red(`Critical (${i.length})`):"",...i.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}`),"",i.length>0?l.red("Overall: Need changes"):a.length>0?l.yellow("Overall: Approve with comments"):l.green("Overall: LGTM")].join(`
22
+ `)}var Hn=createRequire(import.meta.url),Bn="shilongfeicool/dev-flow";function he(){return join(homedir(),".devflow","dashboard")}function Vn(){try{return Hn("../../package.json").version??"0.0.0"}catch{return "0.0.0"}}function G(){let e=he(),o=join(e,"cache.json");if(!existsSync(o))return null;try{let n=JSON.parse(readFileSync(o,"utf-8"));if(existsSync(n.path))return n}catch{}return null}async function zn(e,o){let n=he(),t=join(n,"versions",e);if(existsSync(t)&&existsSync(join(t,"server.js")))return xo(n,t,e),join(n,"current");let r=`https://github.com/${Bn}/releases/download/v${e}/dashboard-standalone.tar.gz`;o?.(`Downloading Dashboard v${e} ...`);let s=join(n,"temp");mkdirSync(s,{recursive:true});try{let i=join(s,"dashboard.tar.gz"),a=await fetch(r);if(!a.ok)throw new Error(`Download failed: HTTP ${a.status} ${a.statusText}
23
+ URL: ${r}
24
+ The Dashboard asset may not have been published for v${e}.`);if(!a.body)throw new Error("Download failed: empty response body");let d=a.body.getReader(),u=[];for(;;){let{done:w,value:$}=await d.read();if(w)break;u.push($);}let p=u.reduce((w,$)=>w+$.length,0),h=new Uint8Array(p),C=0;for(let w of u)h.set(w,C),C+=w.length;writeFileSync(i,h),mkdirSync(t,{recursive:!0});try{execSync(`tar -xzf "${i}" -C "${t}"`,{stdio:"pipe"});}catch(w){throw new Error(`Failed to extract Dashboard archive: ${w.message}
25
+ Ensure 'tar' is available on your system.`)}xo(n,t,e);let j={version:e,path:join(n,"current"),downloadedAt:new Date().toISOString()};return writeFileSync(join(n,"cache.json"),JSON.stringify(j,null,2)),o?.(`Dashboard v${e} installed`),j.path}finally{rmSync(s,{recursive:true,force:true});}}function xo(e,o,n){let t=join(e,"current");(existsSync(t)||Yn(t))&&rmSync(t,{recursive:true,force:true}),symlinkSync(o,t,"junction");let r=join(e,"cache.json"),s;try{s=JSON.parse(readFileSync(r,"utf-8"));}catch{s={version:"",path:t,downloadedAt:""};}s.version=n,s.path=t,s.downloadedAt=new Date().toISOString(),writeFileSync(r,JSON.stringify(s,null,2));}function Yn(e){try{return lstatSync(e).isSymbolicLink()}catch{return false}}async function N(e){let o=Vn(),n=G();if(n&&n.version===o&&!e?.force)return n.path;if(e?.force&&n){let t=join(he(),"versions",n.version);existsSync(t)&&rmSync(t,{recursive:true,force:true});}return zn(o,t=>{console.log(t);})}function P(){return join(process.cwd(),".devflow","dashboard.pid")}function tt(e){let o="<html><body><h1>DevFlow</h1><p>Dashboard is being downloaded...</p></body></html>";try{let t=[resolve(process.cwd(),"node_modules","@devflow-tools","devflow","dist","fallback.html"),resolve(process.cwd(),"apps","server","public","fallback.html")];for(let r of t)if(existsSync(r)){o=readFileSync(r,"utf-8");break}}catch{}createServer((t,r)=>{r.writeHead(200,{"Content-Type":"text/html"}),r.end(o);}).listen(e,()=>{console.log(l.yellow(` Fallback page served on port ${e} (dashboard downloading...)`));});}async function rt(e,o=15e3){let n=Date.now();for(;Date.now()-n<o;){try{if((await fetch(`http://localhost:${e}/api/projects/active`,{headers:{"x-api-key":"dev-key-000000"}})).ok)return !0}catch{}await new Promise(t=>setTimeout(t,500));}return false}async function Io(e){console.log(l.blue("Starting DevFlow server..."));let{pid:o}=await W({port:e.port});console.log(l.green(` Server started (PID: ${o})`)),console.log(l.blue(" Waiting for server..."));let n=await rt(e.port);if(console.log(n?l.green(" Server ready"):l.yellow(" Server started but health check timed out")),!e.noDashboard){console.log(l.blue("Preparing Dashboard..."));let t=G();if(!t){console.log(l.blue(" Dashboard not found, downloading..."));try{await N(),console.log(l.green(" Dashboard download complete")),t=G();}catch{console.log(l.red(" Dashboard download failed")),console.log(l.yellow(` You can still use the API at http://localhost:${e.port}`)),console.log(l.yellow(" To manually download the dashboard, visit: https://github.com/devflow-tools/devflow"));}}if(t)try{let r=await N(),s=join(r,"server.js");if(existsSync(s)){let i=spawn("node",[s],{env:{...process.env,PORT:String(e.dashboardPort)},stdio:"ignore",detached:!0});if(i.pid){let a=P(),d=join(process.cwd(),".devflow");existsSync(d)||mkdirSync(d,{recursive:!0}),writeFileSync(a,`${e.dashboardPort}
26
+ ${i.pid}`),i.unref(),console.log(l.green(` Dashboard started (PID: ${i.pid})`));}}}catch{tt(e.dashboardPort);}}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(t=>{let r=false,s=async()=>{if(r)return;r=true,console.log(l.blue(`
27
+ Shutting down...`));let i=P();if(existsSync(i))try{let a=readFileSync(i,"utf-8").trim().split(`
28
+ `),d=a.length>=2?a[1]:a[0],u=parseInt(d,10);process.kill(u),unlinkSync(i);}catch{}await I(),console.log(l.green("All services stopped.")),t();};process.on("SIGINT",s),process.on("SIGTERM",s);});}async function Oo(){let e=false,o=P();if(existsSync(o))try{let t=R(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 I()&&(console.log(l.green("Server stopped")),e=true),e||console.log(l.dim("No DevFlow services running"));}function at(){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??ue;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=P();if(existsSync(n)){let r=pe(n),s=R(n);if(s!==null)try{process.kill(s,0);let i=r!==null?`port ${r}`:"port 17788";console.log(`Dashboard: ${l.green("\u2713")} running (${i}, PID ${s})`);}catch{console.log(`Dashboard: ${l.red("\u2717")} PID ${s} 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=at();if(existsSync(t)){let s=(statSync(t).size/1024/1024).toFixed(1);console.log(`Data: .devflow/devflow.db (${s} MB)`);}else console.log(`Data: ${l.dim("no database")}`);}var ft=createRequire(import.meta.url);function wt(){let e=[resolve(dirname(ft.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 ht(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 Ao(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 L({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=wt();if(o){let n=join(homedir(),".claude","plugins");mkdirSync(n,{recursive:true});let t=join(n,"known_marketplaces.json");ht(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 Mo=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=Le();if(n.length===0){console.log("No plugins installed."),console.log(`
20
29
  Run "devflow plugin list" to see available plugins.`);return}console.log(`Installed plugins:
21
30
  `),n.forEach(t=>{let r=o.plugins.find(s=>s.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}):
22
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(`
23
- 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=x(),n=e.toLowerCase(),t=o.plugins.filter(r=>r.name.toLowerCase().includes(n)||r.description.toLowerCase().includes(n)||r.tags.some(s=>s.toLowerCase().includes(n)));if(t.length===0){console.log(`No plugins found matching "${e}"`),console.log(`
32
+ Install a plugin: devflow plugin install <name>`);}});var Lo=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(s=>s.toLowerCase().includes(n)));if(t.length===0){console.log(`No plugins found matching "${e}"`),console.log(`
24
33
  Try: devflow plugin list`);return}console.log(`Found ${t.length} plugin(s) matching "${e}":
25
- `),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 mo=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(`
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 Wo=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(`
26
35
  ${l.green("\u2713")} ${o} installed successfully`),console.log(`
27
36
  Run "devflow plugin list --installed" to verify.`);}catch(n){console.error(`
28
- ${l.red("\u2717")} Installation failed: ${n.message}`),process.exit(1);}});var wo=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(`
37
+ ${l.red("\u2717")} Installation failed: ${n.message}`),process.exit(1);}});var Go=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(`
29
38
  ${l.green("\u2713")} ${o} uninstalled successfully`);}catch(n){console.error(`
30
- ${l.red("\u2717")} Uninstallation failed: ${n.message}`),process.exit(1);}});var jn=createRequire(import.meta.url),En="shilongfeicool/dev-flow";function re(){return join(homedir(),".devflow","dashboard")}function Fn(){try{return jn("../../package.json").version??"0.0.0"}catch{return "0.0.0"}}function Tn(){let e=re(),o=join(e,"cache.json");if(!existsSync(o))return null;try{let n=JSON.parse(readFileSync(o,"utf-8"));if(existsSync(n.path))return n}catch{}return null}async function Nn(e,o){let n=re(),t=join(n,"versions",e);if(existsSync(t)&&existsSync(join(t,"server.js")))return yo(n,t,e),join(n,"current");let r=`https://github.com/${En}/releases/download/v${e}/dashboard-standalone.tar.gz`;o?.(`Downloading Dashboard v${e} ...`);let s=join(n,"temp");mkdirSync(s,{recursive:true});try{let i=join(s,"dashboard.tar.gz"),a=await fetch(r);if(!a.ok)throw new Error(`Download failed: HTTP ${a.status} ${a.statusText}
31
- URL: ${r}
32
- The Dashboard asset may not have been published for v${e}.`);if(!a.body)throw new Error("Download failed: empty response body");let d=a.body.getReader(),g=[];for(;;){let{done:f,value:S}=await d.read();if(f)break;g.push(S);}let u=g.reduce((f,S)=>f+S.length,0),w=new Uint8Array(u),b=0;for(let f of g)w.set(f,b),b+=f.length;writeFileSync(i,w),mkdirSync(t,{recursive:!0});try{execSync(`tar -xzf "${i}" -C "${t}"`,{stdio:"pipe"});}catch(f){throw new Error(`Failed to extract Dashboard archive: ${f.message}
33
- Ensure 'tar' is available on your system.`)}yo(n,t,e);let P={version:e,path:join(n,"current"),downloadedAt:new Date().toISOString()};return writeFileSync(join(n,"cache.json"),JSON.stringify(P,null,2)),o?.(`Dashboard v${e} installed`),P.path}finally{rmSync(s,{recursive:true,force:true});}}function yo(e,o,n){let t=join(e,"current");(existsSync(t)||An(t))&&rmSync(t,{recursive:true,force:true}),symlinkSync(o,t,"junction");let r=join(e,"cache.json"),s;try{s=JSON.parse(readFileSync(r,"utf-8"));}catch{s={version:"",path:t,downloadedAt:""};}s.version=n,s.path=t,s.downloadedAt=new Date().toISOString(),writeFileSync(r,JSON.stringify(s,null,2));}function An(e){try{return lstatSync(e).isSymbolicLink()}catch{return false}}async function So(e){let o=Fn(),n=Tn();if(n&&n.version===o&&!e?.force)return n.path;if(e?.force&&n){let t=join(re(),"versions",n.version);existsSync(t)&&rmSync(t,{recursive:true,force:true});}return Nn(o,t=>{console.log(t);})}var ko=new Command("dashboard").description("Start DevFlow Dashboard").option("-p, --port <port>","Port to run on","17788").option("--force","Force re-download Dashboard").action(async e=>{try{console.log(l.blue("Preparing Dashboard..."));let o=await So({force:e.force}),n=join(o,"server.js");existsSync(n)||(console.error(l.red(`Dashboard server.js not found at: ${n}
39
+ ${l.red("\u2717")} Uninstallation failed: ${n.message}`),process.exit(1);}});var _o=new Command("dashboard").description("Start DevFlow Dashboard").option("-p, --port <port>","Port to run on","17788").option("--force","Force re-download Dashboard").action(async e=>{try{console.log(l.blue("Preparing Dashboard..."));let o=await N({force:e.force}),n=join(o,"server.js");existsSync(n)||(console.error(l.red(`Dashboard server.js not found at: ${n}
34
40
  The downloaded archive may be corrupted. Try: devflow dashboard --force`)),process.exit(1)),console.log(l.green(`
35
41
  Starting Dashboard: http://localhost:${e.port}
36
- `));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 xo=createRequire(import.meta.url),F="0.0.0";try{F=xo("../package.json").version;}catch{try{F=xo("../../package.json").version;}catch{}}var c=new Command;c.name("devflow").description("Developer Intelligence Platform for AI Coding Agents").version(F).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 s of r){let i=Gn.join(o,s);bo.existsSync(i)&&(console.log(l.dim(` Removing ${s}/...`)),bo.rmSync(i,{recursive:true,force:true}));}console.log(l.green(`\u2705 Existing directories removed
37
- `));}let n=L(o);console.error(l.blue(`DevFlow init \u2014 mode: ${n}`));let t=await q(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(()=>(K(),be));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 $e(e.plugins):e.plugins!==false&&await Pe(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=L(n);if(console.log(l.blue(`DevFlow connect \u2014 mode: ${t}`)),e){let r=De();r.includes(e)||(console.log(l.red(`Unknown agent: ${e}`)),console.log(`Available: ${r.join(", ")}`),process.exit(1));}try{let r=await Ce({agent:e,command:o.command,sseUrl:o.sse});for(let s of r)console.log(l.green(`\u2713 ${s}`));}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 Ie(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 je({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 Te({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 Fe({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 T=c.command("workflow").description("Workflow management");T.command("list").description("List available workflows").action(async()=>{let e=await Ne(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)`);});T.command("run <type> [input]").description("Run a workflow").action(async(e,o)=>{let n=await Ae(e,{input:o??""},c.opts().local);console.log(`Run: ${n.runId}`),console.log(`Status: ${n.status}`),console.log(`Duration: ${n.duration}ms`);});T.command("status").description("Show running workflows").action(async()=>{let e=await Le(c.opts().local);console.log(`${e.length} run(s)`);for(let o of e)console.log(` ${o.runId} \u2014 ${o.status}`);});T.command("runs").description("Show workflow history").action(async()=>{let e=await V(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 se=c.command("memory").description("Memory management");se.command("show").description("Show current project memory").action(async()=>{let e=await Me(c.opts().local);console.log(JSON.stringify(e,null,2));});se.command("set <key> <value>").description("Set a memory key").action(async(e,o)=>{await Ue(e,o,c.opts().local),console.log(l.green(`Memory set: ${e} = ${o}`));});se.command("review").description("Review memory candidates").action(async()=>{let e=await We(c.opts().local);console.log(JSON.stringify(e,null,2));});c.command("knowledge <query>").description("Search knowledge base").action(async e=>{let o=await Je(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(`
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 Ko=createRequire(import.meta.url),K="0.0.0";try{K=Ko("../package.json").version;}catch{try{K=Ko("../../package.json").version;}catch{}}var c=new Command;c.name("devflow").description("Developer Intelligence Platform for AI Coding Agents").version(K).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 s of r){let i=Ft.join(o,s);qo.existsSync(i)&&(console.log(l.dim(` Removing ${s}/...`)),qo.rmSync(i,{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 oe(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(()=>(ne(),Me));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 Ue(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=Je();r.includes(e)||(console.log(l.red(`Unknown agent: ${e}`)),console.log(`Available: ${r.join(", ")}`),process.exit(1));}try{let r=await L({agent:e,command:o.command,sseUrl:o.sse});for(let s of r)console.log(l.green(`\u2713 ${s}`));}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 qe(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 Ke({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 Ve({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 Be({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 H=c.command("workflow").description("Workflow management");H.command("list").description("List available workflows").action(async()=>{let e=await ze(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)`);});H.command("run <type> [input]").description("Run a workflow").action(async(e,o)=>{let n=await Ye(e,{input:o??""},c.opts().local);console.log(`Run: ${n.runId}`),console.log(`Status: ${n.status}`),console.log(`Duration: ${n.duration}ms`);});H.command("status").description("Show running workflows").action(async()=>{let e=await Xe(c.opts().local);console.log(`${e.length} run(s)`);for(let o of e)console.log(` ${o.runId} \u2014 ${o.status}`);});H.command("runs").description("Show workflow history").action(async()=>{let e=await ie(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 be=c.command("memory").description("Memory management");be.command("show").description("Show current project memory").action(async()=>{let e=await Qe(c.opts().local);console.log(JSON.stringify(e,null,2));});be.command("set <key> <value>").description("Set a memory key").action(async(e,o)=>{await Ze(e,o,c.opts().local),console.log(l.green(`Memory set: ${e} = ${o}`));});be.command("review").description("Review memory candidates").action(async()=>{let e=await eo(c.opts().local);console.log(JSON.stringify(e,null,2));});c.command("knowledge <query>").description("Search knowledge base").action(async e=>{let o=await oo(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(`
38
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 s of r)s.added>0?console.log(` ${l.green("\u2713")} ${s.source} \u2192 ${s.added} chunks`):console.log(` ${l.red("\u2717")} ${s.source} \u2014 ${s.errors.join(", ")||"no content"}`);}console.log(l.green(`
39
- All docs synced.`));}});var N=c.command("skill").description("Plugin/Skill management");N.command("list").description("List installed skills").action(async()=>{let e=await X(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}`);});N.command("search <query>").description("Search available plugins").action(async e=>{let o=await _e(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}`);});N.command("install <name>").description("Install a plugin/skill").action(async e=>{try{let o=await Ve(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);}});N.command("uninstall <name>").description("Uninstall a plugin/skill").action(async e=>{try{await ze(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 no();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 to();console.log(e.json?JSON.stringify(t):"Audit chain rebuilt.");return}if(e.violations){let t=await ro(e.last);console.log(e.json?JSON.stringify(t):JSON.stringify(t,null,2));return}if(e.receipts){let t=so();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 oo();if(e.json){console.log(JSON.stringify(o));return}if(console.log(l.blue(`DevFlow Doctor v${F}
40
- `)),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 io(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 lo(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 co({prUrl:e,agent:o.agent});console.log(n);});var ie=c.command("server").description("Manage DevFlow server");ie.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 Qe({port:parseInt(e.port,10)});console.log(l.green(`Server started (pid: ${o.pid}) on port ${e.port}`));});ie.command("stop").description("Stop the DevFlow REST server").action(async()=>{let e=await Ze();console.log(e?l.green("Server stopped"):l.dim("No server running"));});ie.command("status").description("Show server status").action(async()=>{let e=await j();e.running?console.log(l.green(`Running (pid: ${e.pid})`)):console.log(l.yellow("Not running"));});c.addCommand(ko);var A=c.command("plugin").description("Manage DevFlow plugins");A.addCommand(go);A.addCommand(uo);A.addCommand(mo);A.addCommand(wo);c.parse();
45
+ All docs synced.`));}});var B=c.command("skill").description("Plugin/Skill management");B.command("list").description("List installed skills").action(async()=>{let e=await ae(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}`);});B.command("search <query>").description("Search available plugins").action(async e=>{let o=await so(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}`);});B.command("install <name>").description("Install a plugin/skill").action(async e=>{try{let o=await ao(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);}});B.command("uninstall <name>").description("Uninstall a plugin/skill").action(async e=>{try{await co(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${K}
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 bo(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 Se=c.command("server").description("Manage DevFlow server");Se.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 W({port:parseInt(e.port,10)});console.log(l.green(`Server started (pid: ${o.pid}) on port ${e.port}`));});Se.command("stop").description("Stop the DevFlow REST server").action(async()=>{let e=await I();console.log(e?l.green("Server stopped"):l.dim("No server running"));});Se.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(_o);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 Io({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 Oo();});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 Ao({agent:e.agent,skipMcp:!!e.skipMcp,skipPlugin:!!e.skipPlugin});});var V=c.command("plugin").description("Manage DevFlow plugins");V.addCommand(Mo);V.addCommand(Lo);V.addCommand(Wo);V.addCommand(Go);c.parse();
@@ -0,0 +1,106 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>DevFlow</title>
7
+ <style>
8
+ * { margin: 0; padding: 0; box-sizing: border-box; }
9
+ body {
10
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
11
+ background: #0a0a0a;
12
+ color: #fafafa;
13
+ display: flex;
14
+ align-items: center;
15
+ justify-content: center;
16
+ min-height: 100vh;
17
+ }
18
+ .container {
19
+ text-align: center;
20
+ padding: 2rem;
21
+ }
22
+ .logo {
23
+ font-size: 3rem;
24
+ font-weight: 700;
25
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
26
+ -webkit-background-clip: text;
27
+ -webkit-text-fill-color: transparent;
28
+ margin-bottom: 1rem;
29
+ }
30
+ .status {
31
+ color: #a1a1aa;
32
+ font-size: 1.1rem;
33
+ margin-bottom: 2rem;
34
+ }
35
+ .spinner {
36
+ width: 40px;
37
+ height: 40px;
38
+ border: 3px solid #27272a;
39
+ border-top-color: #667eea;
40
+ border-radius: 50%;
41
+ animation: spin 0.8s linear infinite;
42
+ margin: 0 auto 1.5rem;
43
+ }
44
+ @keyframes spin {
45
+ to { transform: rotate(360deg); }
46
+ }
47
+ .info {
48
+ color: #52525b;
49
+ font-size: 0.85rem;
50
+ margin-top: 2rem;
51
+ }
52
+ .server-ok {
53
+ color: #22c55e;
54
+ }
55
+ .server-wait {
56
+ color: #eab308;
57
+ }
58
+ </style>
59
+ </head>
60
+ <body>
61
+ <div class="container">
62
+ <div class="logo">DevFlow</div>
63
+ <div class="spinner" id="spinner"></div>
64
+ <div class="status" id="status">Preparing dashboard...</div>
65
+ <div class="info" id="info">Checking server status...</div>
66
+ </div>
67
+ <script>
68
+ let attempts = 0;
69
+ const maxAttempts = 60;
70
+
71
+ async function checkStatus() {
72
+ attempts++;
73
+ const statusEl = document.getElementById('status');
74
+ const infoEl = document.getElementById('info');
75
+ const spinnerEl = document.getElementById('spinner');
76
+
77
+ try {
78
+ const res = await fetch('/api/projects/active', {
79
+ headers: { 'x-api-key': 'dev-key-000000' }
80
+ });
81
+
82
+ if (res.ok) {
83
+ infoEl.textContent = 'Server is running. Dashboard will appear when download completes.';
84
+ infoEl.className = 'info server-ok';
85
+ } else {
86
+ infoEl.textContent = 'Waiting for server...';
87
+ infoEl.className = 'info server-wait';
88
+ }
89
+ } catch {
90
+ infoEl.textContent = 'Waiting for server...';
91
+ infoEl.className = 'info server-wait';
92
+ }
93
+
94
+ if (attempts < maxAttempts) {
95
+ setTimeout(checkStatus, 3000);
96
+ } else {
97
+ statusEl.textContent = 'Dashboard download is taking longer than expected';
98
+ spinnerEl.style.display = 'none';
99
+ infoEl.textContent = 'The server is running. You can use the API at /api. The dashboard will appear when ready.';
100
+ }
101
+ }
102
+
103
+ checkStatus();
104
+ </script>
105
+ </body>
106
+ </html>
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@devflow-tools/claude-code-plugin",
3
+ "description": "DevFlow — Developer Intelligence Platform: project context, code graph, knowledge base, memory engine, and workflow automation with 14 domain plugins",
4
+ "version": "0.7.3",
5
+ "author": {
6
+ "name": "DevFlow"
7
+ },
8
+ "homepage": "https://github.com/shilongfeicool/dev-flow",
9
+ "repository": "https://github.com/shilongfeicool/dev-flow",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "devflow",
13
+ "context",
14
+ "knowledge-base",
15
+ "code-graph",
16
+ "memory",
17
+ "workflow",
18
+ "development"
19
+ ]
20
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "matcher": "",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start\"",
10
+ "async": false
11
+ }
12
+ ]
13
+ }
14
+ ],
15
+ "PreToolUse": [
16
+ {
17
+ "matcher": "Bash|Glob|Grep|WebSearch|WebFetch|Agent",
18
+ "hooks": [
19
+ {
20
+ "type": "command",
21
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/pre-tool-use\"",
22
+ "async": false
23
+ }
24
+ ]
25
+ }
26
+ ],
27
+ "PostToolUse": [
28
+ {
29
+ "matcher": "Bash|Glob|Grep|WebSearch|WebFetch|Agent",
30
+ "hooks": [
31
+ {
32
+ "type": "command",
33
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/post-tool-use\"",
34
+ "async": false
35
+ }
36
+ ]
37
+ }
38
+ ]
39
+ }
40
+ }
@@ -0,0 +1,19 @@
1
+ ---
2
+ name: devflow
3
+ description: DevFlow — 项目开发智能平台。代码检索、图谱、记忆、工作流一站式工具集。
4
+ ---
5
+
6
+ # DevFlow
7
+
8
+ 你已接入 DevFlow 开发智能平台。收到 /devflow: 前缀命令时,只做一件事:调用对应的 MCP 工具。
9
+
10
+ | 命令 | 只调用这个工具 |
11
+ |------|-------------|
12
+ | /devflow:context | get_project_context |
13
+ | /devflow:graph | get_dependency_graph |
14
+ | /devflow:memory | get_memory |
15
+ | /devflow:knowledge | get_knowledge |
16
+ | /devflow:workflow | run_workflow |
17
+ | /devflow:doctor | get_project_context |
18
+
19
+ 领域插件(/devflow:react, /devflow:vue, /devflow:nextjs, /devflow:nest, /devflow:tailwind, /devflow:docker, /devflow:electron, /devflow:graphql, /devflow:git, /devflow:performance, /devflow:animation, /devflow:css, /devflow:taro, /devflow:ui-layout)— 每个都有对应的 MCP 工具。
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: devflow:animation
3
+ description: Animation 动画专家 — CSS 动画、Framer Motion、GSAP、Lottie、性能优化
4
+ ---
5
+
6
+ # ✨ ANIMATION
7
+
8
+ 你是一个动画专家。精通 CSS Animation、Framer Motion、GSAP。动画必须 60fps 且支持 prefers-reduced-motion。
9
+
10
+ ## 适用场景
11
+
12
+ **动画审计:性能检查 → 可访问性 → 实现质量**
13
+
14
+ **新建动画:需求分析 → 选型建议 → 实现 → 性能验证**
15
+
16
+ **动画 GPU 迁移:扫描 → 替换为 GPU 属性 → 验证**
17
+
18
+ ## 核心规则
19
+
20
+ - 动画属性只使用 transform 和 opacity(GPU 加速)
21
+ - 过渡动画 200-300ms,入场 300-500ms
22
+ - 使用 ease-out 入场、ease-in 退场
23
+ - 尊重 prefers-reduced-motion,提供减弱方案
24
+ - 避免同时动画过多元素(批量编排使用 staggerChildren)
25
+ - 使用 AnimatePresence 处理 React 组件退出动画
26
+ - Lottie 动画控制文件大小 < 50KB
27
+
28
+ ## 当前版本
29
+
30
+ - animation-docs: 2024 — https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations
31
+
32
+ ## 工作流
33
+
34
+ | 场景 | 触发方式 |
35
+ |------|----------|
36
+ | 动画审计:性能检查 → 可访问性 → 实现质量 | 调用 MCP 工具 `animation_audit:animation` |
37
+ | 新建动画:需求分析 → 选型建议 → 实现 → 性能验证 | 调用 MCP 工具 `animation_new:animation` |
38
+ | 动画 GPU 迁移:扫描 → 替换为 GPU 属性 → 验证 | 调用 MCP 工具 `animation_migrate:gpu-animation` |
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: devflow:context
3
+ description: 检索项目上下文 — 自然语言查询相关代码、符号、依赖关系
4
+ ---
5
+
6
+ # /devflow:context
7
+
8
+ ## 执行
9
+
10
+ 1. 如果用户的查询包含中文,先将其中的中文关键词翻译为英文代码术语(空格分隔)
11
+ 2. 调用 `get_project_context` MCP 工具:
12
+
13
+ ```
14
+ query = 用户的原始查询内容(包含中文)
15
+ expandedTerms = 你翻译的英文关键词(如 "code review audit module")
16
+ mode = "fast" (首次调用;如需更深入结果,再改用 "deep")
17
+ ```
18
+
19
+ 示例:
20
+ - 用户查询 "代码审核模块的流程" → expandedTerms = "code review audit module workflow pipeline process"
21
+ - 用户查询 "用户登录认证逻辑" → expandedTerms = "user login authentication auth logic service handler"
22
+ - 用户查询 "数据库缓存策略" → expandedTerms = "database db cache memo redis storage strategy"
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: devflow:css
3
+ description: CSS 专家 — 布局调试、响应式审查、BEM 规范、性能优化
4
+ ---
5
+
6
+ # 🎨 CSS
7
+
8
+ 你是一个 CSS 专家。使用现代布局方案(Flexbox/Grid),遵循 BEM 命名,移动优先响应式设计。遇到问题先查 MDN 文档。
9
+
10
+ ## 适用场景
11
+
12
+ **布局调试:检查元素定位 → 弹性/网格属性 → 修复**
13
+
14
+ **响应式审查:断点检查 → 媒体查询 → 流体方案**
15
+
16
+ **BEM 命名审查:扫描类名 → 规范检查 → 修复建议**
17
+
18
+ ## 核心规则
19
+
20
+ - 使用 BEM 命名规范
21
+ - 优先使用 Flexbox 和 Grid 布局
22
+ - 移动优先响应式设计
23
+ - 使用 CSS 变量管理主题
24
+ - 避免 !important 和深层嵌套
25
+ - 使用 rem/em 做相对单位
26
+ - 不确定属性行为时先查 MDN 文档确认
27
+
28
+ ## 当前版本
29
+
30
+ - mdn-css: 2024 — https://developer.mozilla.org/en-US/docs/Web/CSS
31
+
32
+ ## 工作流
33
+
34
+ | 场景 | 触发方式 |
35
+ |------|----------|
36
+ | 布局调试:检查元素定位 → 弹性/网格属性 → 修复 | 调用 MCP 工具 `css_debug:layout` |
37
+ | 响应式审查:断点检查 → 媒体查询 → 流体方案 | 调用 MCP 工具 `css_audit:responsive` |
38
+ | BEM 命名审查:扫描类名 → 规范检查 → 修复建议 | 调用 MCP 工具 `css_review:bem` |
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: devflow:docker
3
+ description: Docker 专家 — 镜像优化、Compose 编排、安全扫描、多阶段构建
4
+ ---
5
+
6
+ # 🐳 DOCKER
7
+
8
+ 你是一个 Docker 专家。使用多阶段构建优化镜像,遵循安全和性能最佳实践。遇到问题先查官方文档。
9
+
10
+ ## 适用场景
11
+
12
+ **项目 Docker 化:分析项目 → 多阶段 Dockerfile → Compose → 构建验证**
13
+
14
+ **镜像优化:体积分析 → 层优化 → 多阶段重构**
15
+
16
+ **安全扫描:漏洞检测 → 配置审查 → 修复建议**
17
+
18
+ **多服务 Compose 编排:依赖分析 → 网络设计 → 环境管理**
19
+
20
+ ## 核心规则
21
+
22
+ - 使用多阶段构建减小镜像体积
23
+ - 基础镜像固定版本标签(不使用 latest)
24
+ - 利用层缓存优化构建顺序
25
+ - 使用非 root 用户运行应用
26
+ - 使用 .dockerignore 排除无用文件
27
+ - 添加 HEALTHCHECK 监控容器健康状态
28
+ - 不在镜像层中写入敏感信息
29
+ - 修复安全问题时先查 Docker 官方文档确认方案
30
+
31
+ ## 当前版本
32
+
33
+ - docker-docs: 26.0.0 — https://docs.docker.com/reference/
34
+
35
+ ## 工作流
36
+
37
+ | 场景 | 触发方式 |
38
+ |------|----------|
39
+ | 项目 Docker 化:分析项目 → 多阶段 Dockerfile → Compose → 构建验证 | 调用 MCP 工具 `docker_dockerize_project` |
40
+ | 镜像优化:体积分析 → 层优化 → 多阶段重构 | 调用 MCP 工具 `docker_optimize:image` |
41
+ | 安全扫描:漏洞检测 → 配置审查 → 修复建议 | 调用 MCP 工具 `docker_scan:security` |
42
+ | 多服务 Compose 编排:依赖分析 → 网络设计 → 环境管理 | 调用 MCP 工具 `docker_setup:compose` |
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: devflow:doctor
3
+ description: 项目健康检查 — 索引状态、引擎就绪、插件列表
4
+ ---
5
+
6
+ # 项目健康检查
7
+
8
+ 快速了解 DevFlow 在当前项目中的运行状态。任务开始前用一次即可。
9
+
10
+ ## 检查项
11
+
12
+ - 文件索引是否最新
13
+ - Context/Graph/Memory/Knowledge/Workflow 引擎是否就绪
14
+ - 已安装哪些领域插件
15
+ - 是否有已知配置问题
16
+ **MCP Gateway 策略**: 调用前会校验 Session Token 和调用合法性。无有效收据的情况下直接使用原生工具(grep/Glob/WebSearch)将被 PreToolUse Hook 拦截。收据有效期 30 秒,过期后需重新通过 MCP 工具获取。