@devflow-tools/devflow 0.8.3 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,46 +1,43 @@
1
1
  #!/usr/bin/env node
2
- import Vo,{existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,unlinkSync,statSync,cpSync,symlinkSync,readdirSync,lstatSync}from'fs';import Ot,{dirname,join,resolve}from'path';import {homedir}from'os';import {createRequire}from'module';import Ae 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 Yo=Object.defineProperty;var xe=(e,o)=>()=>(e&&(o=e(e=0)),o);var Xo=(e,o)=>{for(var n in o)Yo(e,n,{get:o[n],enumerable:true});};function Fe(){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 Oe(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[Pe]!==true&&(n[Pe]=true,o.enabledPlugins=n,writeFileSync(e,JSON.stringify(o,null,2)));}function je(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 Te(e,o,n,t){let r=join(o,nn,tn,n);mkdirSync(r,{recursive:true});let s=join(e,"hooks");existsSync(s)&&L(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)&&L(a,join(r,"dist")),t){let d=join(e,"dist","skills");existsSync(d)&&L(d,t);}rn(r);}function L(e,o){mkdirSync(o,{recursive:true});for(let n of readdirSync(e)){let t=join(e,n),r=join(o,n);statSync(t).isDirectory()?L(t,r):cpSync(t,r,{force:true});}}function rn(e){let o=join(e,"..");if(!existsSync(o))return;let n=e.split("/").pop()??"";for(let t of readdirSync(o))if(t!==n){let r=join(o,t);statSync(r).isDirectory()&&rmSync(r,{recursive:true,force:true});}}var Pe,nn,tn,Ee=xe(()=>{Pe="@devflow-tools/claude-code-plugin@devflow-local",nn="devflow-local",tn="@devflow-tools/claude-code-plugin";});var Ue={};Xo(Ue,{initProject:()=>te,renderInitReport:()=>Le});async function te(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(ne.isInitialized(e)||await ne.init(e,{index:o.scan!==false}),o.scan!==false)try{let{indexer:i,graph:a}=await createEngines(e),{files:d,symbols:g,imports:p}=await i.indexAll(e),h=await a.build(g,p);s.indexed={files:d.length,symbols:g.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=ne.openSync(e),g=await buildOnboardingPack(e,d,i,a),p=join(n,"onboarding-pack.json");writeFileSync(p,JSON.stringify(g,null,2),"utf-8"),t.push(".devflow/onboarding-pack.json");let h=join(n,"init-report.md");writeFileSync(h,Le(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=Fe(),a=homedir(),d=join(a,".claude","plugins","cache"),g=join(a,".claude","skills"),p=join(i,"package.json"),h=existsSync(p)?JSON.parse(readFileSync(p,"utf-8")).version:"0.0.0";Te(i,d,h,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");Oe(a),s.pluginEnabled=!0;}catch(i){console.warn(`Warning: Plugin enablement skipped \u2014 ${i.message}`);}try{let i;try{i=dn.resolve("@devflow-tools/mcp-server/bin/devflow-mcp.cjs");}catch{i="devflow-mcp";}je(e,i),s.mcpConfigured=!0;}catch(i){console.warn(`Warning: MCP config skipped \u2014 ${i.message}`);}return s}function Le(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 ne,dn,re=xe(()=>{Ee();ne=Ae.default??Ae,dn=createRequire(import.meta.url);});function X(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"}re();var fn=fileURLToPath(import.meta.url),hn=dirname(fn);function R(){let e=[join(process.cwd(),"plugin-registry.json"),join(hn,"../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 We(){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 bn(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 Sn(e){let o=e.trim();return o.startsWith("@devflow-tools/")?o:`@devflow-tools/${o}`}async function Je(e){let o=e.split(",").map(Sn).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 Ge(e){let o=R();if(o.plugins.length===0)return console.log(`
2
+ import Jo,{unlinkSync,existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,statSync,cpSync,readdirSync}from'fs';import $t,{dirname,join,resolve}from'path';import {homedir}from'os';import {createRequire}from'module';import Oe 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 qo=Object.defineProperty;var ve=(e,o)=>()=>(e&&(o=e(e=0)),o);var Ko=(e,o)=>{for(var n in o)qo(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 Ce(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[Se]!==true&&(n[Se]=true,o.enabledPlugins=n,writeFileSync(e,JSON.stringify(o,null,2)));}function De(e,o){let n=join(e,".claude"),t=join(n,"mcp.json"),r={};if(existsSync(t))try{r=JSON.parse(readFileSync(t,"utf-8"));}catch{console.warn("Warning: Could not parse existing mcp.json, skipping MCP config");return}else mkdirSync(n,{recursive:true});let i=r.mcpServers??{};i.devflow||(i.devflow={command:o,args:[],env:{}},r.mcpServers=i,writeFileSync(t,JSON.stringify(r,null,2)));}function Fe(e,o,n,t){let r=join(o,Yo,Xo,n);mkdirSync(r,{recursive:true});let i=join(e,"hooks");existsSync(i)&&j(i,join(r,"hooks"));for(let d of ["hooks.json","CLAUDE.md","package.json"]){let u=join(e,d);existsSync(u)&&cpSync(u,join(r,d),{force:true});}let s=join(e,".claude-plugin","plugin.json");existsSync(s)&&(mkdirSync(join(r,".claude-plugin"),{recursive:true}),cpSync(s,join(r,".claude-plugin","plugin.json"),{force:true}));let a=join(e,"dist");if(existsSync(a)&&j(a,join(r,"dist")),t){let d=join(e,"dist","skills");existsSync(d)&&j(d,t);}Qo(r);}function j(e,o){mkdirSync(o,{recursive:true});for(let n of readdirSync(e)){let t=join(e,n),r=join(o,n);statSync(t).isDirectory()?j(t,r):cpSync(t,r,{force:true});}}function Qo(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 Se,Yo,Xo,Re=ve(()=>{Se="@devflow-tools/claude-code-plugin@devflow-local",Yo="devflow-local",Xo="@devflow-tools/claude-code-plugin";});var Te={};Ko(Te,{initProject:()=>Y,renderInitReport:()=>Ee});async function Y(e,o={}){let n=join(e,".devflow"),t=[];existsSync(n)||(mkdirSync(n,{recursive:true}),t.push(".devflow/"));let r=join(n,"config.json");(!existsSync(r)||o.force)&&(writeFileSync(r,JSON.stringify({version:"0.1.0",initialized:new Date().toISOString()},null,2),"utf-8"),t.push(".devflow/config.json"));let i={created:t,pluginDeployed:false,pluginEnabled:false,mcpConfigured:false};if(H.isInitialized(e)||await H.init(e,{index:o.scan!==false}),o.scan!==false)try{let{indexer:s,graph:a}=await createEngines(e),{files:d,symbols:u,imports:p}=await s.indexAll(e),w=await a.build(u,p);i.indexed={files:d.length,symbols:u.length,graphNodes:w.nodes.length};}catch{i.indexed={files:0,symbols:0,graphNodes:0};}if(o.scan!==false)try{let{indexer:s,graph:a}=await createEngines(e),d=H.openSync(e),u=await buildOnboardingPack(e,d,s,a),p=join(n,"onboarding-pack.json");writeFileSync(p,JSON.stringify(u,null,2),"utf-8"),t.push(".devflow/onboarding-pack.json");let w=join(n,"init-report.md");writeFileSync(w,Ee(u),"utf-8"),t.push(".devflow/init-report.md"),i.onboardingPack=u;}catch(s){console.warn(`Warning: Onboarding pack generation skipped \u2014 ${s.message}`);}try{let s=Pe(),a=homedir(),d=join(a,".claude","plugins","cache"),u=join(a,".claude","skills"),p=join(s,"package.json"),w=existsSync(p)?JSON.parse(readFileSync(p,"utf-8")).version:"0.0.0";Fe(s,d,w,u),i.pluginDeployed=!0;}catch(s){console.warn(`Warning: Plugin deployment skipped \u2014 ${s.message}`);}try{let s=homedir(),a=join(s,".claude","settings.json");Ce(a),i.pluginEnabled=!0;}catch(s){console.warn(`Warning: Plugin enablement skipped \u2014 ${s.message}`);}try{let s;try{s=tn.resolve("@devflow-tools/mcp-server/bin/devflow-mcp.cjs");}catch{s="devflow-mcp";}De(e,s),i.mcpConfigured=!0;}catch(s){console.warn(`Warning: MCP config skipped \u2014 ${s.message}`);}return i}function Ee(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 H,tn,X=ve(()=>{Re();H=Oe.default??Oe,tn=createRequire(import.meta.url);});function q(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"}X();var cn=fileURLToPath(import.meta.url),dn=dirname(cn);function P(){let e=[join(process.cwd(),"plugin-registry.json"),join(dn,"../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 Ne(){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 mn(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 fn(e){let o=e.trim();return o.startsWith("@devflow-tools/")?o:`@devflow-tools/${o}`}async function Ae(e){let o=e.split(",").map(fn).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 Me(e){let o=P();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=bn(e);n.length>0&&console.log(`Detected tech stack: ${n.join(", ")}
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
- `);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(`
7
+ `);let n=mn(e);n.length>0&&console.log(`Detected tech stack: ${n.join(", ")}
8
+ `);let t=new Set(o.plugins.filter(s=>s.compatibleStacks.some(a=>n.includes(a))).map(s=>s.name));if(!process.stdout.isTTY){console.log(`Non-interactive terminal detected. Installing recommended plugins...
9
+ `);let s=[...t];for(let a of s)try{execSync(`npm install -g ${a}`,{stdio:"inherit"}),console.log(`\u2713 ${a}`);}catch{console.error(`\u2717 Failed to install ${a}`);}return s}let r=o.plugins.map(s=>({name:`${s.name.replace("@devflow-tools/","")} - ${s.description.substring(0,50)}`,value:s.name,checked:t.has(s.name)})),i;try{i=await checkbox({message:"Select plugins to install (space to select, enter to confirm):",choices:r});}catch{return console.log(`
10
10
  Plugin installation cancelled.
11
- `),[]}if(s.length>0){console.log(`
11
+ `),[]}if(i.length>0){console.log(`
12
12
  Installing selected plugins...
13
- `);for(let i of s)try{execSync(`npm install -g ${i}`,{stdio:"inherit"}),console.log(`\u2713 ${i}
14
- `);}catch{console.error(`\u2717 Failed to install ${i}
13
+ `);for(let s of i)try{execSync(`npm install -g ${s}`,{stdio:"inherit"}),console.log(`\u2713 ${s}
14
+ `);}catch{console.error(`\u2717 Failed to install ${s}
15
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 U(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 _e(){return listAdapters()}var Pn=process.env.DEVFLOW_SERVER_URL??"http://localhost:13337",Ke=new Map,Cn=3e4;async function m(e,o,n,t={}){let r=t.serverUrl??Pn;if(t.skipServer)return n();let s=false,i=Ke.get(r);if(i&&Date.now()-i.ts<Cn?s=i.result:(s=await new DevFlowApiClient({baseUrl:r,projectRoot:e}).ping(),Ke.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 He(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 Be(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 ze(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 Ye(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 Xe(e){return m(process.cwd(),o=>o.listWorkflows(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.list()},{skipServer:e})}async function Qe(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 Ze(e){return ae(e)}async function ae(e){return m(process.cwd(),o=>o.getWorkflowRuns(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.listRuns()},{skipServer:e})}async function eo(e){return m(process.cwd(),o=>o.getMemory(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getAll()},{skipServer:e})}async function oo(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 no(e){return m(process.cwd(),o=>o.reviewCandidates(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getCandidates()},{skipServer:e})}async function to(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 de(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 lo(e,o){let n=await de(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 W=join(process.env.HOME??"~",".devflow","skills");function ao(e){let o=join(e,".devflow","config.json");return existsSync(o)?JSON.parse(readFileSync(o,"utf-8")):{plugins:[]}}function co(e,o){let n=join(e,".devflow","config.json");writeFileSync(n,JSON.stringify(o,null,2),"utf-8");}async function go(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(W,{recursive:true});try{execSync(`npm install --prefix "${W}" ${t}`,{stdio:"pipe",timeout:6e4});}catch{}let s=ao(o);s.plugins||(s.plugins=[]),s.plugins.includes(r)||(s.plugins.push(r),co(o,s));let i=[];try{i=JSON.parse(readFileSync(join(W,"node_modules",t,"package.json"),"utf-8"))?.devflow?.templates??[];}catch{}return {name:r,version:"0.1.0",templates:i}},{skipServer:n})}async function uo(e,o=process.cwd(),n){return m(o,async t=>{await t.uninstallPlugin(e);},async()=>{let t=e.replace(/^@devflow-tools\/plugin-/,""),r=ao(o);r.plugins&&(r.plugins=r.plugins.filter(i=>i!==t),co(o,r));let s=e.startsWith("@devflow-tools/plugin-")?e:`@devflow-tools/plugin-${e}`;try{let i=join(W,"node_modules",s);existsSync(i)&&rmSync(i,{recursive:!0,force:!0});}catch{}},{skipServer:n})}var Ln=createRequire(import.meta.url);function pe(e){let o=join(e,".devflow");return existsSync(o)||mkdirSync(o,{recursive:true}),join(o,"server.pid")}function Un(){try{return Ln.resolve("@devflow-tools/server/dist/main.js")}catch{return join(process.cwd(),"apps","server","dist","main.js")}}var me=13337;function fe(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 I(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 J(e){let o=Un(),n=pe(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 F(){let e=pe(process.cwd()),o=I(e);if(o===null)return false;try{return process.kill(o),unlinkSync(e),!0}catch{return unlinkSync(e),false}}async function O(){let e=pe(process.cwd()),o=fe(e)??me,{DevFlowApiClient:n}=await import('@devflow-tools/sdk');return await new n({baseUrl:`http://localhost:${o}`,projectRoot:process.cwd()}).ping()?{running:true,pid:I(e)??void 0,port:o}:{running:false,port:o}}async function ho(){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,p=0;try{let P=await n.getAll();g=!!P?.project;let v=P?.user??{};p=Object.keys(v).length;}catch{}let h=0;try{h=(await t.getSources()).length;}catch{}let j={total:0,byTool:{}};try{j=await s.getToolCallStats();}catch{}let T=await O(),y=0;return i.fileCount>0&&(y+=25),i.nodeCount>0&&(y+=15),a.nodes.length>0&&(y+=20),g&&(y+=15),h>0&&(y+=10),d>0&&(y+=5),T.running&&(y+=10),j.total>0&&(y+=5),{index:{totalFiles:i.fileCount,totalSymbols:i.nodeCount,indexing:e.isIndexing()},graph:{nodes:a.nodes.length,edges:a.edges.length},memory:{projectReady:g,userPrefs:p},knowledge:{sources:h},plugins:{installed:0,names:[]},workflows:{registered:d},server:{running:T.running},toolCalls:j,readyScore:y}}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){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 yo(){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 vo(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 bo(){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 So(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 ko(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 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 xo(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 zn=createRequire(import.meta.url),Yn="shilongfeicool/dev-flow";function ve(){return join(homedir(),".devflow","dashboard")}function Xn(){try{return zn("../../package.json").version??"0.0.0"}catch{return "0.0.0"}}function _(){let e=ve(),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 Qn(e,o){let n=ve(),t=join(n,"versions",e),r=existsSync(join(t,"server.js")),s=existsSync(join(t,"apps","dashboard","server.js"));if(existsSync(t)&&(r||s))return Co(n,t,e),join(n,"current");let i=`https://github.com/${Yn}/releases/download/v${e}/dashboard-standalone.tar.gz`;o?.(`Downloading Dashboard v${e} ...`);let a=join(n,"temp");mkdirSync(a,{recursive:true});try{let d=join(a,"dashboard.tar.gz"),g=await fetch(i);if(!g.ok)throw new Error(`Download failed: HTTP ${g.status} ${g.statusText}
23
- URL: ${i}
24
- The Dashboard asset may not have been published for v${e}.`);if(!g.body)throw new Error("Download failed: empty response body");let p=g.body.getReader(),h=[];for(;;){let{done:v,value:Y}=await p.read();if(v)break;h.push(Y);}let j=h.reduce((v,Y)=>v+Y.length,0),T=new Uint8Array(j),y=0;for(let v of h)T.set(v,y),y+=v.length;writeFileSync(d,T),mkdirSync(t,{recursive:!0});try{execSync(`tar -xzf "${d}" -C "${t}"`,{stdio:"pipe"});}catch(v){throw new Error(`Failed to extract Dashboard archive: ${v.message}
25
- Ensure 'tar' is available on your system.`)}Co(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(a,{recursive:true,force:true});}}function Co(e,o,n){let t=join(e,"current");(existsSync(t)||Zn(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 Zn(e){try{return lstatSync(e).isSymbolicLink()}catch{return false}}async function A(e){let o=Xn(),n=_();if(n&&n.version===o&&!e?.force)return n.path;if(e?.force&&n){let t=join(ve(),"versions",n.version);existsSync(t)&&rmSync(t,{recursive:true,force:true});}return Qn(o,t=>{console.log(t);})}function D(){return join(process.cwd(),".devflow","dashboard.pid")}function it(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 lt(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 Oo(e){console.log(l.blue("Starting DevFlow server..."));let{pid:o}=await J({port:e.port});console.log(l.green(` Server started (PID: ${o})`)),console.log(l.blue(" Waiting for server..."));let n=await lt(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=_();if(!t){console.log(l.blue(" Dashboard not found, downloading..."));try{await A(),console.log(l.green(" Dashboard download complete")),t=_();}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 A(),s=join(r,"server.js");if(existsSync(s)){let i=spawn("node",[s],{env:{...process.env,PORT:String(e.dashboardPort)},cwd:r,stdio:"ignore",detached:!0});if(i.pid){let a=D(),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{it(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=D();if(existsSync(i))try{let a=readFileSync(i,"utf-8").trim().split(`
28
- `),d=a.length>=2?a[1]:a[0],g=parseInt(d,10);process.kill(g),unlinkSync(i);}catch{}await F(),console.log(l.green("All services stopped.")),t();};process.on("SIGINT",s),process.on("SIGTERM",s);});}async function To(){let e=false,o=D();if(existsSync(o))try{let t=I(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 F()&&(console.log(l.green("Server stopped")),e=true),e||console.log(l.dim("No DevFlow services running"));}function gt(){return join(process.cwd(),".devflow","devflow.db")}async function No(){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 O(),o=e.port??me;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=D();if(existsSync(n)){let r=fe(n),s=I(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=gt();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 yt=createRequire(import.meta.url);function vt(){let e=[resolve(dirname(yt.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 bt(e,o){let n={};if(existsSync(e))try{n=JSON.parse(readFileSync(e,"utf-8"));}catch{n={};}let t={...n,...o};writeFileSync(e,JSON.stringify(t,null,2));}async function Lo(e){if(console.log(l.blue("DevFlow Setup")),console.log(l.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),!e.skipMcp)try{let o=await U({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=vt();if(o){let n=join(homedir(),".claude","plugins");mkdirSync(n,{recursive:true});let t=join(n,"known_marketplaces.json");bt(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 Uo=new Command("list").description("List available plugins").option("-i, --installed","Show only installed plugins").action(async e=>{let o=R();if(e.installed){let n=We();if(n.length===0){console.log("No plugins installed."),console.log(`
17
+ `);return i}async function E(e){let o=[],n;e.sseUrl?n={url:e.sseUrl}:n={command:e.command??"devflow-mcp",args:["--mode","stdio"]};let t=e.agent?[e.agent]:await import('@devflow-tools/adapters').then(r=>r.detectAll());for(let r of t){let i=await connect(r,n);o.push(`${r}: ${i.configPath} (${i.written?"written":"skipped"})`);}return o}function Le(){return listAdapters()}var vn=process.env.DEVFLOW_SERVER_URL??"http://localhost:13337",Ue=new Map,Sn=3e4;async function m(e,o,n,t={}){let r=t.serverUrl??vn;if(t.skipServer)return n();let i=false,s=Ue.get(r);if(s&&Date.now()-s.ts<Sn?i=s.result:(i=await new DevFlowApiClient({baseUrl:r,projectRoot:e}).ping(),Ue.set(r,{result:i,ts:Date.now()})),i){let a=new DevFlowApiClient({baseUrl:r,projectRoot:e});return o(a)}return console.error(l.dim(" (server not running, using local engine \u2014 telemetry disabled)")),n()}async function Je(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 Ge(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 qe(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 Ke(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 Ve(e){return m(process.cwd(),o=>o.listWorkflows(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.list()},{skipServer:e})}async function ze(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 Be(e){return oe(e)}async function oe(e){return m(process.cwd(),o=>o.getWorkflowRuns(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.listRuns()},{skipServer:e})}async function He(e){return m(process.cwd(),o=>o.getMemory(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getAll()},{skipServer:e})}async function Ye(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 Xe(e){return m(process.cwd(),o=>o.reviewCandidates(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getCandidates()},{skipServer:e})}async function Qe(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 te(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 no(e,o){let n=await te(o),t=e.toLowerCase();return n.filter(r=>r.name.toLowerCase().includes(t)||r.description.toLowerCase().includes(t)||r.tags.some(i=>i.toLowerCase().includes(t)))}var T=join(process.env.HOME??"~",".devflow","skills");function to(e){let o=join(e,".devflow","config.json");return existsSync(o)?JSON.parse(readFileSync(o,"utf-8")):{plugins:[]}}function ro(e,o){let n=join(e,".devflow","config.json");writeFileSync(n,JSON.stringify(o,null,2),"utf-8");}async function so(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(T,{recursive:true});try{execSync(`npm install --prefix "${T}" ${t}`,{stdio:"pipe",timeout:6e4});}catch{}let i=to(o);i.plugins||(i.plugins=[]),i.plugins.includes(r)||(i.plugins.push(r),ro(o,i));let s=[];try{s=JSON.parse(readFileSync(join(T,"node_modules",t,"package.json"),"utf-8"))?.devflow?.templates??[];}catch{}return {name:r,version:"0.1.0",templates:s}},{skipServer:n})}async function io(e,o=process.cwd(),n){return m(o,async t=>{await t.uninstallPlugin(e);},async()=>{let t=e.replace(/^@devflow-tools\/plugin-/,""),r=to(o);r.plugins&&(r.plugins=r.plugins.filter(s=>s!==t),ro(o,r));let i=e.startsWith("@devflow-tools/plugin-")?e:`@devflow-tools/plugin-${e}`;try{let s=join(T,"node_modules",i);existsSync(s)&&rmSync(s,{recursive:!0,force:!0});}catch{}},{skipServer:n})}var jn=createRequire(import.meta.url);function ie(e){let o=join(e,".devflow");return existsSync(o)||mkdirSync(o,{recursive:true}),join(o,"server.pid")}function En(){try{return jn.resolve("@devflow-tools/server/dist/main.js")}catch{return join(process.cwd(),"apps","server","dist","main.js")}}var le=13337;function ae(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 $(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 N(e){let o=En(),n=ie(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 C(){let e=ie(process.cwd()),o=$(e);if(o===null)return false;try{return process.kill(o),unlinkSync(e),!0}catch{return unlinkSync(e),false}}async function D(){let e=ie(process.cwd()),o=ae(e)??le,{DevFlowApiClient:n}=await import('@devflow-tools/sdk');return await new n({baseUrl:`http://localhost:${o}`,projectRoot:process.cwd()}).ping()?{running:true,pid:$(e)??void 0,port:o}:{running:false,port:o}}async function go(){let{codegraph:e,graph:o,memory:n,knowledge:t,workflow:r,data:i}=await createEngines(process.cwd()),s=e.getStats(),a=o.export(),d=0;try{d=(await r.list()).length;}catch{}let u=false,p=0;try{let O=await n.getAll();u=!!O?.project;let _o=O?.user??{};p=Object.keys(_o).length;}catch{}let w=0;try{w=(await t.getSources()).length;}catch{}let _={total:0,byTool:{}};try{_=await i.getToolCallStats();}catch{}let ye=await D(),S=0;return s.fileCount>0&&(S+=25),s.nodeCount>0&&(S+=15),a.nodes.length>0&&(S+=20),u&&(S+=15),w>0&&(S+=10),d>0&&(S+=5),ye.running&&(S+=10),_.total>0&&(S+=5),{index:{totalFiles:s.fileCount,totalSymbols:s.nodeCount,indexing:e.isIndexing()},graph:{nodes:a.nodes.length,edges:a.edges.length},memory:{projectReady:u,userPrefs:p},knowledge:{sources:w},plugins:{installed:0,names:[]},workflows:{registered:d},server:{running:ye.running},toolCalls:_,readyScore:S}}async function uo(){let{data:e}=await createEngines(process.cwd()),o=await e.auditGetSecret(),n=await e.auditGetAll(),t=createHash("sha256").update("genesis").digest("hex");for(let r of n){if(r.prevHash!==t)return {valid:false,brokenAt:r.seq,entryCount:n.length};let i=`${r.seq}|${r.ts}|${r.tool}|${r.argsHash}|${r.decision}|${r.ruleId??""}|${r.sessionId}|${t}`,s=createHmac("sha256",o).update(i).digest("hex");if(r.signature!==s)return {valid:false,brokenAt:r.seq,entryCount:n.length};t=r.signature;}return {valid:true,brokenAt:null,entryCount:n.length}}async function po(){let{data:e}=await createEngines(process.cwd()),o=await e.auditGetSecret(),n=await e.auditGetAll(),t=createHash("sha256").update("genesis").digest("hex");for(let r of n){let i=`${r.seq}|${r.ts}|${r.tool}|${r.argsHash}|${r.decision}|${r.ruleId??""}|${r.sessionId}|${t}`,s=createHmac("sha256",o).update(i).digest("hex");await e.sqlExecute("UPDATE devflow_audit_chain SET prev_hash = ?, signature = ? WHERE seq = ?",[t,s,r.seq]),t=s;}return {rebuilt:true}}async function mo(e){let{data:o}=await createEngines(process.cwd()),t=(await o.auditGetAll()).filter(r=>r.decision!=="allow");if(e){let r=e.match(/^(\d+)([dh])$/);if(r){let i=parseInt(r[1],10),a=r[2]==="d"?i*864e5:i*36e5,d=Date.now()-a;t=t.filter(u=>u.ts>d);}}return {violations:t.map(r=>({tool:r.tool,decision:r.decision,ruleId:r.ruleId,ts:r.ts,sessionId:r.sessionId}))}}function fo(){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 wo(e,o=3600){let n=Buffer.from(JSON.stringify({alg:"HS256",typ:"JWT"})).toString("base64url"),t=Math.floor(Date.now()/1e3),r={sub:`devflow-session-${Date.now().toString(36)}`,project:e.split("/").pop()??"unknown",iat:t,exp:t+o,scope:["context","knowledge","memory","workflow","graph"]},i=Buffer.from(JSON.stringify(r)).toString("base64url"),a=createHmac("sha256","devflow-local-mcp-secret-v1").update(`${n}.${i}`).digest("base64url");return {token:`${n}.${i}.${a}`,expiresAt:r.exp,scope:r.scope}}async function ho(e,o){let n=new BenchmarkEngine,t=n.getTasks(),r=o.iterations??5,i=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 s=performance.now()-i;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: ${(s/1e3).toFixed(1)}s`,`Avg per task: ${(s/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 vo(e){let o,n;if(e.prUrl){let p=e.prUrl.match(/pull\/(\d+)/);n=`PR: ${p?`#${p[1]}`:e.prUrl}`;try{o=execSync(`gh pr diff ${e.prUrl}`,{encoding:"utf-8",maxBuffer:10*1024*1024});}catch{o=`Could not fetch PR diff from ${e.prUrl}. Ensure 'gh' CLI is installed and authenticated.`;}}else {n="Current branch vs main";try{o=execSync("git diff main...HEAD",{encoding:"utf-8",maxBuffer:10*1024*1024});}catch{o="Could not compute diff. Ensure you're on a feature branch.";}}let t=(o.match(/^diff --git/gm)??[]).length,r=(o.match(/^\+[^+]/gm)??[]).length,i=(o.match(/^-[^-]/gm)??[]).length,s=[],a=[],d=[];return o.includes("console.log")&&a.push("Contains console.log statements \u2014 remove before merge"),(o.includes(".only(")||o.includes("it.only"))&&s.push("Contains .only() test filters \u2014 remove before merge"),(o.includes("TODO")||o.includes("FIXME"))&&a.push("Contains TODO/FIXME comments \u2014 track or resolve"),(o.match(/^\+.*TODO/gm)||o.match(/^\+.*FIXME/gm))&&a.push("New code introduces TODO/FIXME comments"),o.includes("process.exit")&&a.push("Contains process.exit() \u2014 consider throwing instead"),o.includes(": any")&&o.match(/^\+.*: any/gm)&&d.push("New code uses `any` type \u2014 use explicit types instead"),[l.blue("\u25C9 Code Review"),"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",n,`Files changed: ${t}`,`+${r} / -${i}`,"",s.length>0?l.red(`Critical (${s.length})`):"",...s.map(p=>` ${l.red("\u25CF")} ${p}`),"",a.length>0?l.yellow(`Warning (${a.length})`):"",...a.map(p=>` ${l.yellow("\u25CB")} ${p}`),"",d.length>0?l.green(`Suggestion (${d.length})`):"",...d.map(p=>` ${l.green("\u25CB")} ${p}`),"",s.length>0?l.red("Overall: Need changes"):a.length>0?l.yellow("Overall: Approve with comments"):l.green("Overall: LGTM")].join(`
22
+ `)}var So=createRequire(import.meta.url);function ue(e){return join(e,".devflow","dashboard")}function bo(e){return join(ue(e),"version.txt")}function ko(){try{return So("../../package.json").version??"0.0.0"}catch{return "0.0.0"}}function qn(){return So.resolve("@devflow-tools/devflow/dist/dashboard-standalone.tar.gz")}function Kn(e){let o=bo(e);if(!existsSync(o))return false;try{return readFileSync(o,"utf-8").trim()===ko()&&existsSync(join(ue(e),"apps","dashboard","server.js"))}catch{return false}}function M(e){let o=ue(e),n=bo(e),t=ko();if(Kn(e))return o;existsSync(o)&&rmSync(o,{recursive:true,force:true}),mkdirSync(o,{recursive:true});let r=qn();return execSync(`tar -xzf "${r}" -C "${o}"`,{stdio:"pipe"}),writeFileSync(n,t),o}function x(){return join(process.cwd(),".devflow","dashboard.pid")}async function Xn(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 Po(e){let o=x();if(existsSync(o)){try{let r=$(o);if(r!==null)try{process.kill(r);}catch{}}catch{}try{unlinkSync(o);}catch{}}console.log(l.blue("Starting DevFlow server..."));let{pid:n}=await N({port:e.port});console.log(l.green(` Server started (PID: ${n})`)),console.log(l.blue(" Waiting for server..."));let t=await Xn(e.port);if(console.log(t?l.green(" Server ready"):l.yellow(" Server started but health check timed out")),!e.noDashboard){console.log(l.blue("Preparing Dashboard..."));try{let r=M(process.cwd()),i=join(r,"apps","dashboard","server.js"),s=spawn("node",[i],{env:{...process.env,PORT:String(e.dashboardPort)},cwd:r,stdio:"ignore",detached:!0});if(s.pid){let a=x(),d=join(process.cwd(),".devflow");existsSync(d)||mkdirSync(d,{recursive:!0}),writeFileSync(a,`${e.dashboardPort}
23
+ ${s.pid}`),s.unref(),console.log(l.green(` Dashboard started (PID: ${s.pid})`));}}catch{console.log(l.red(" Dashboard failed to start")),console.log(l.yellow(` You can still use the API at http://localhost:${e.port}`));}}console.log(""),console.log(l.green("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")),console.log(l.green("\u2551")+" \u{1F680} DevFlow Started! "+l.green("\u2551")),console.log(l.green("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563")),console.log(l.green("\u2551")+` \u{1F5A5}\uFE0F Server: http://localhost:${e.port}`.padEnd(57)+l.green("\u2551")),console.log(l.green("\u2551")+` \u{1F3A8} Dashboard: http://localhost:${e.dashboardPort}`.padEnd(57)+l.green("\u2551")),console.log(l.green("\u2551")+" "+l.green("\u2551")),console.log(l.green("\u2551")+" Press Ctrl+C to stop all services "+l.green("\u2551")),console.log(l.green("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")),e.background||await new Promise(r=>{let i=false,s=async()=>{if(i)return;i=true,console.log(l.blue(`
24
+ Shutting down...`));let a=x();if(existsSync(a))try{let d=readFileSync(a,"utf-8").trim().split(`
25
+ `),u=d.length>=2?d[1]:d[0],p=parseInt(u,10);process.kill(p),unlinkSync(a);}catch{}await C(),console.log(l.green("All services stopped.")),r();};process.on("SIGINT",s),process.on("SIGTERM",s);});}async function Do(){let e=false,o=x();if(existsSync(o))try{let t=$(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 C()&&(console.log(l.green("Server stopped")),e=true),e||console.log(l.dim("No DevFlow services running"));}function ot(){return join(process.cwd(),".devflow","devflow.db")}async function Ro(){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 D(),o=e.port??le;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=x();if(existsSync(n)){let r=ae(n),i=$(n);if(i!==null)try{process.kill(i,0);let s=r!==null?`port ${r}`:"port 17788";console.log(`Dashboard: ${l.green("\u2713")} running (${s}, PID ${i})`);}catch{console.log(`Dashboard: ${l.red("\u2717")} PID ${i} not found (stale PID file)`);}else console.log(`Dashboard: ${l.yellow("\u25CB")} not running (unreadable PID file)`);}else console.log(`Dashboard: ${l.yellow("\u25CB")} not running`);let t=ot();if(existsSync(t)){let i=(statSync(t).size/1024/1024).toFixed(1);console.log(`Data: .devflow/devflow.db (${i} MB)`);}else console.log(`Data: ${l.dim("no database")}`);}var at=createRequire(import.meta.url);function ct(){let e=[resolve(dirname(at.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 dt(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 jo(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 E({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=ct();if(o){let n=join(homedir(),".claude","plugins");mkdirSync(n,{recursive:true});let t=join(n,"known_marketplaces.json");dt(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 Eo=new Command("list").description("List available plugins").option("-i, --installed","Show only installed plugins").action(async e=>{let o=P();if(e.installed){let n=Ne();if(n.length===0){console.log("No plugins installed."),console.log(`
29
26
  Run "devflow plugin list" to see available plugins.`);return}console.log(`Installed plugins:
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}):
27
+ `),n.forEach(t=>{let r=o.plugins.find(i=>i.name===t);r?(console.log(` ${l.green(r.name)}@${r.version}`),console.log(` ${r.description}`)):console.log(` ${l.green(t)}`);});}else {if(o.plugins.length===0){console.log("No plugins available.");return}console.log(`Available plugins (${o.plugins.length}):
31
28
  `);let n=Math.max(...o.plugins.map(t=>t.name.length));o.plugins.forEach(t=>{let r=" ".repeat(n-t.name.length+2);console.log(` ${l.green(t.name)}${r}v${t.version}`),console.log(` ${" ".repeat(n)}${t.description.substring(0,60)}`),t.tags.length>0&&console.log(` ${" ".repeat(n)}Tags: ${t.tags.join(", ")}`),console.log("");}),console.log(`
32
- Install a plugin: devflow plugin install <name>`);}});var Wo=new Command("search").description("Search for plugins").argument("<keyword>","Search keyword").action(async e=>{let o=R(),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(`
29
+ Install a plugin: devflow plugin install <name>`);}});var To=new Command("search").description("Search for plugins").argument("<keyword>","Search keyword").action(async e=>{let o=P(),n=e.toLowerCase(),t=o.plugins.filter(r=>r.name.toLowerCase().includes(n)||r.description.toLowerCase().includes(n)||r.tags.some(i=>i.toLowerCase().includes(n)));if(t.length===0){console.log(`No plugins found matching "${e}"`),console.log(`
33
30
  Try: devflow plugin list`);return}console.log(`Found ${t.length} plugin(s) matching "${e}":
34
- `),t.forEach(r=>{console.log(` ${l.green(r.name)}@${r.version}`),console.log(` ${r.description}`),r.tags.length>0&&console.log(` Tags: ${r.tags.join(", ")}`),console.log(` Size: ${r.size}`),console.log("");});});var Go=new Command("install").description("Install a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let o=e.startsWith("@devflow-tools/")?e:`@devflow-tools/${e}`;console.log(`Installing ${o}...`);try{execSync(`npm install -g ${o}`,{stdio:"inherit"}),console.log(`
31
+ `),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 Ao=new Command("install").description("Install a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let o=e.startsWith("@devflow-tools/")?e:`@devflow-tools/${e}`;console.log(`Installing ${o}...`);try{execSync(`npm install -g ${o}`,{stdio:"inherit"}),console.log(`
35
32
  ${l.green("\u2713")} ${o} installed successfully`),console.log(`
36
33
  Run "devflow plugin list --installed" to verify.`);}catch(n){console.error(`
37
- ${l.red("\u2717")} Installation failed: ${n.message}`),process.exit(1);}});var qo=new Command("uninstall").description("Uninstall a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let o=e.startsWith("@devflow-tools/")?e:`@devflow-tools/${e}`;console.log(`Uninstalling ${o}...`);try{execSync(`npm uninstall -g ${o}`,{stdio:"inherit"}),console.log(`
34
+ ${l.red("\u2717")} Installation failed: ${n.message}`),process.exit(1);}});var Lo=new Command("uninstall").description("Uninstall a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let o=e.startsWith("@devflow-tools/")?e:`@devflow-tools/${e}`;console.log(`Uninstalling ${o}...`);try{execSync(`npm uninstall -g ${o}`,{stdio:"inherit"}),console.log(`
38
35
  ${l.green("\u2713")} ${o} uninstalled successfully`);}catch(n){console.error(`
39
- ${l.red("\u2717")} Uninstallation failed: ${n.message}`),process.exit(1);}});var Bo=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 A({force:e.force}),n=join(o,"apps","dashboard","server.js"),t=existsSync(n)?n:join(o,"server.js");existsSync(t)||(console.error(l.red(`Dashboard server.js not found at: ${t}
40
- The downloaded archive may be corrupted. Try: devflow dashboard --force`)),process.exit(1)),console.log(l.green(`
36
+ ${l.red("\u2717")} Uninstallation failed: ${n.message}`),process.exit(1);}});var Uo=new Command("dashboard").description("Start DevFlow Dashboard").option("-p, --port <port>","Port to run on","17788").option("--force","Force re-extract Dashboard from npm package").action(async e=>{try{if(e.force){let r=join(process.cwd(),".devflow","dashboard","version.txt");try{unlinkSync(r);}catch{}}console.log(l.blue("Preparing Dashboard..."));let o=M(process.cwd()),n=join(o,"apps","dashboard","server.js");existsSync(n)||(console.error(l.red(`Dashboard server.js not found at: ${n}
37
+ The archive may be corrupted. Try: devflow dashboard --force`)),process.exit(1)),console.log(l.green(`
41
38
  Starting Dashboard: http://localhost:${e.port}
42
- `));let r=spawn("node",[t],{stdio:"inherit",env:{...process.env,PORT:e.port}});r.on("error",s=>{console.error(l.red("Failed to start Dashboard:"),s),process.exit(1);}),r.on("exit",s=>{process.exit(s||0);});}catch(o){console.error(l.red("Failed to start Dashboard:"),o.message),process.exit(1);}});var zo=createRequire(import.meta.url),H="0.0.0";try{H=zo("../package.json").version;}catch{try{H=zo("../../package.json").version;}catch{}}var c=new Command;c.name("devflow").description("Developer Intelligence Platform for AI Coding Agents").version(H).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=Ot.join(o,s);Vo.existsSync(i)&&(console.log(l.dim(` Removing ${s}/...`)),Vo.rmSync(i,{recursive:true,force:true}));}console.log(l.green(`\u2705 Existing directories removed
43
- `));}let n=X(o);console.error(l.blue(`DevFlow init \u2014 mode: ${n}`));let t=await te(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(()=>(re(),Ue));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 Je(e.plugins):e.plugins!==false&&await Ge(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=X(n);if(console.log(l.blue(`DevFlow connect \u2014 mode: ${t}`)),e){let r=_e();r.includes(e)||(console.log(l.red(`Unknown agent: ${e}`)),console.log(`Available: ${r.join(", ")}`),process.exit(1));}try{let r=await U({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 He(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 Be({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 Ye({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 ze({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 B=c.command("workflow").description("Workflow management");B.command("list").description("List available workflows").action(async()=>{let e=await Xe(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)`);});B.command("run <type> [input]").description("Run a workflow").action(async(e,o)=>{let n=await Qe(e,{input:o??""},c.opts().local);console.log(`Run: ${n.runId}`),console.log(`Status: ${n.status}`),console.log(`Duration: ${n.duration}ms`);});B.command("status").description("Show running workflows").action(async()=>{let e=await Ze(c.opts().local);console.log(`${e.length} run(s)`);for(let o of e)console.log(` ${o.runId} \u2014 ${o.status}`);});B.command("runs").description("Show workflow history").action(async()=>{let e=await ae(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 ke=c.command("memory").description("Memory management");ke.command("show").description("Show current project memory").action(async()=>{let e=await eo(c.opts().local);console.log(JSON.stringify(e,null,2));});ke.command("set <key> <value>").description("Set a memory key").action(async(e,o)=>{await oo(e,o,c.opts().local),console.log(l.green(`Memory set: ${e} = ${o}`));});ke.command("review").description("Review memory candidates").action(async()=>{let e=await no(c.opts().local);console.log(JSON.stringify(e,null,2));});c.command("knowledge <query>").description("Search knowledge base").action(async e=>{let o=await to(e,void 0,c.opts().local);console.log(l.blue(`Knowledge: "${e}"`)),console.log(` Results: ${o.length}`);for(let n of o.slice(0,5))console.log(` \u2014 ${n.title}`);});c.command("docs sync [plugin-name]").description("Sync documentation for plugins").action(async e=>{console.log(l.blue(`\u25C9 Syncing docs${e?` for ${e} plugin`:""}`));let o=new KnowledgeEngine({projectRoot:process.cwd()});if(e){let n=await o.syncDocs(e);for(let t of n)t.added>0?console.log(` ${l.green("\u2713")} ${t.source} \u2192 ${t.added} chunks`):console.log(` ${l.red("\u2717")} ${t.source} \u2014 ${t.errors.join(", ")||"no content"}`);console.log(l.green(`
44
- ${e} docs synced to .devflow/knowledge/${e}/`));}else {let n=await o.getSources();for(let t of n){let r=await o.syncDocs(t.source.name);for(let 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(`
45
- All docs synced.`));}});var V=c.command("skill").description("Plugin/Skill management");V.command("list").description("List installed skills").action(async()=>{let e=await de(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}`);});V.command("search <query>").description("Search available plugins").action(async e=>{let o=await lo(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}`);});V.command("install <name>").description("Install a plugin/skill").action(async e=>{try{let o=await go(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);}});V.command("uninstall <name>").description("Uninstall a plugin/skill").action(async e=>{try{await uo(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 wo();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 yo();console.log(e.json?JSON.stringify(t):"Audit chain rebuilt.");return}if(e.violations){let t=await vo(e.last);console.log(e.json?JSON.stringify(t):JSON.stringify(t,null,2));return}if(e.receipts){let t=bo();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 ho();if(e.json){console.log(JSON.stringify(o));return}if(console.log(l.blue(`DevFlow Doctor v${H}
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 So(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 ko(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 xo({prUrl:e,agent:o.agent});console.log(n);});var $e=c.command("server").description("Manage DevFlow server");$e.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 J({port:parseInt(e.port,10)});console.log(l.green(`Server started (pid: ${o.pid}) on port ${e.port}`));});$e.command("stop").description("Stop the DevFlow REST server").action(async()=>{let e=await F();console.log(e?l.green("Server stopped"):l.dim("No server running"));});$e.command("status").description("Show server status").action(async()=>{let e=await O();e.running?console.log(l.green(`Running (pid: ${e.pid})`)):console.log(l.yellow("Not running"));});c.addCommand(Bo);c.command("start").description("Start DevFlow server and dashboard").option("--port <n>","Server port","13337").option("--dashboard-port <n>","Dashboard port","17788").option("--no-dashboard","Start server only, no dashboard").option("-d, --background","Run in background (detached)").action(async e=>{await Oo({port:parseInt(e.port,10),dashboardPort:parseInt(e.dashboardPort,10),noDashboard:!e.dashboard,background:!!e.background});});c.command("stop").description("Stop DevFlow server and dashboard").action(async()=>{await To();});c.command("status").description("Show DevFlow services status").action(async()=>{await No();});c.command("setup").description("Configure Claude Code integration (MCP + plugin)").option("--agent <agent>","Target agent (claude/cursor/cline)").option("--skip-mcp","Skip MCP configuration").option("--skip-plugin","Skip plugin registration").action(async e=>{await Lo({agent:e.agent,skipMcp:!!e.skipMcp,skipPlugin:!!e.skipPlugin});});var z=c.command("plugin").description("Manage DevFlow plugins");z.addCommand(Uo);z.addCommand(Wo);z.addCommand(Go);z.addCommand(qo);c.parse();
39
+ `));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 Go=createRequire(import.meta.url),W="0.0.0";try{W=Go("../package.json").version;}catch{try{W=Go("../../package.json").version;}catch{}}var c=new Command;c.name("devflow").description("Developer Intelligence Platform for AI Coding Agents").version(W).option("--local","Force local engine, skip server");c.command("init").description("Initialize .devflow/ in the current project").option("--force","Overwrite existing config").option("--abort","Force delete .codegraph and .devflow directories before reinitializing").option("--report","Output onboarding markdown report to stdout").option("--json","Output onboarding pack as JSON to stdout").option("--plugins <names>","Comma-separated list of plugins to install (non-interactive)").option("--no-plugins","Skip plugin installation guide").action(async e=>{let o=process.cwd();if(e.abort){console.log(l.yellow("\u{1F5D1}\uFE0F --abort flag detected, removing existing directories..."));let r=[".codegraph",".devflow"];for(let i of r){let s=$t.join(o,i);Jo.existsSync(s)&&(console.log(l.dim(` Removing ${i}/...`)),Jo.rmSync(s,{recursive:true,force:true}));}console.log(l.green(`\u2705 Existing directories removed
40
+ `));}let n=q(o);console.error(l.blue(`DevFlow init \u2014 mode: ${n}`));let t=await Y(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(()=>(X(),Te));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 Ae(e.plugins):e.plugins!==false&&await Me(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=q(n);if(console.log(l.blue(`DevFlow connect \u2014 mode: ${t}`)),e){let r=Le();r.includes(e)||(console.log(l.red(`Unknown agent: ${e}`)),console.log(`Available: ${r.join(", ")}`),process.exit(1));}try{let r=await E({agent:e,command:o.command,sseUrl:o.sse});for(let i of r)console.log(l.green(`\u2713 ${i}`));}catch(r){console.error(l.red(`Error: ${r.message}`)),process.exit(1);}});c.command("index").description("Show index status").option("--watch","Start file watcher for hot updates (stub)").action(async e=>{let o=await Je(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 Ge({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 Ke({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 qe({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 U=c.command("workflow").description("Workflow management");U.command("list").description("List available workflows").action(async()=>{let e=await Ve(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)`);});U.command("run <type> [input]").description("Run a workflow").action(async(e,o)=>{let n=await ze(e,{input:o??""},c.opts().local);console.log(`Run: ${n.runId}`),console.log(`Status: ${n.status}`),console.log(`Duration: ${n.duration}ms`);});U.command("status").description("Show running workflows").action(async()=>{let e=await Be(c.opts().local);console.log(`${e.length} run(s)`);for(let o of e)console.log(` ${o.runId} \u2014 ${o.status}`);});U.command("runs").description("Show workflow history").action(async()=>{let e=await oe(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 we=c.command("memory").description("Memory management");we.command("show").description("Show current project memory").action(async()=>{let e=await He(c.opts().local);console.log(JSON.stringify(e,null,2));});we.command("set <key> <value>").description("Set a memory key").action(async(e,o)=>{await Ye(e,o,c.opts().local),console.log(l.green(`Memory set: ${e} = ${o}`));});we.command("review").description("Review memory candidates").action(async()=>{let e=await Xe(c.opts().local);console.log(JSON.stringify(e,null,2));});c.command("knowledge <query>").description("Search knowledge base").action(async e=>{let o=await Qe(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(`
41
+ ${e} docs synced to .devflow/knowledge/${e}/`));}else {let n=await o.getSources();for(let t of n){let r=await o.syncDocs(t.source.name);for(let i of r)i.added>0?console.log(` ${l.green("\u2713")} ${i.source} \u2192 ${i.added} chunks`):console.log(` ${l.red("\u2717")} ${i.source} \u2014 ${i.errors.join(", ")||"no content"}`);}console.log(l.green(`
42
+ All docs synced.`));}});var J=c.command("skill").description("Plugin/Skill management");J.command("list").description("List installed skills").action(async()=>{let e=await te(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}`);});J.command("search <query>").description("Search available plugins").action(async e=>{let o=await no(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}`);});J.command("install <name>").description("Install a plugin/skill").action(async e=>{try{let o=await so(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);}});J.command("uninstall <name>").description("Uninstall a plugin/skill").action(async e=>{try{await io(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 uo();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 po();console.log(e.json?JSON.stringify(t):"Audit chain rebuilt.");return}if(e.violations){let t=await mo(e.last);console.log(e.json?JSON.stringify(t):JSON.stringify(t,null,2));return}if(e.receipts){let t=fo();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 go();if(e.json){console.log(JSON.stringify(o));return}if(console.log(l.blue(`DevFlow Doctor v${W}
43
+ `)),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 wo(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 ho(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 vo({prUrl:e,agent:o.agent});console.log(n);});var he=c.command("server").description("Manage DevFlow server");he.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 N({port:parseInt(e.port,10)});console.log(l.green(`Server started (pid: ${o.pid}) on port ${e.port}`));});he.command("stop").description("Stop the DevFlow REST server").action(async()=>{let e=await C();console.log(e?l.green("Server stopped"):l.dim("No server running"));});he.command("status").description("Show server status").action(async()=>{let e=await D();e.running?console.log(l.green(`Running (pid: ${e.pid})`)):console.log(l.yellow("Not running"));});c.addCommand(Uo);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 Po({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 Do();});c.command("status").description("Show DevFlow services status").action(async()=>{await Ro();});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 jo({agent:e.agent,skipMcp:!!e.skipMcp,skipPlugin:!!e.skipPlugin});});var G=c.command("plugin").description("Manage DevFlow plugins");G.addCommand(Eo);G.addCommand(To);G.addCommand(Ao);G.addCommand(Lo);c.parse();
Binary file
@@ -6,62 +6,49 @@ required_mcp_tools: []
6
6
 
7
7
  # DevFlow Start
8
8
 
9
- 启动 DevFlow 开发环境,包括服务端和前端。
9
+ 启动 DevFlow 开发环境,包括服务端和前端。使用 `npx devflow start` 命令,无论在哪个目录下调用都能正确启动 DevFlow 服务。
10
10
 
11
11
  ## 执行步骤
12
12
 
13
- 1. **检查环境**
14
- - 确认当前在项目根目录
15
- - 检查是否已安装依赖(node_modules 存在)
16
- - 如果未安装,提示运行 `npm install`
17
-
18
- 2. **构建项目**(如果 dist 目录不存在或过时)
19
- ```bash
20
- devflow build
21
- ```
22
-
23
- 3. **启动服务**
24
- 运行以下命令同时启动服务端和前端:
13
+ 1. **使用 npx devflow start 启动**
25
14
  ```bash
26
- devflow start
15
+ npx devflow start
27
16
  ```
17
+
18
+ 这会自动启动:
19
+ - DevFlow REST 服务端(默认端口 13337)
20
+ - DevFlow Dashboard(默认端口 17788)
28
21
 
29
- 4. **显示启动信息**
30
- 服务启动后,显示以下信息(用清晰的框格式):
22
+ 2. **显示启动信息**
23
+ 服务启动后,显示以下信息:
31
24
 
32
25
  ```
33
26
  ╔═══════════════════════════════════════════════════════════╗
34
- ║ 🚀 DevFlow Development Server Started! ║
27
+ ║ 🚀 DevFlow Started! ║
35
28
  ╠═══════════════════════════════════════════════════════════╣
36
29
  ║ ║
37
30
  ║ 🖥️ Server: http://localhost:13337 ║
38
31
  ║ 🎨 Dashboard: http://localhost:17788 ║
39
32
  ║ ║
40
- ║ 📁 Data Dir: ./.devflow/ ║
41
- ║ 🗄️ Database: ./.devflow/devflow.db ║
42
- ║ ║
43
- ║ 📊 API Docs: http://localhost:13337/api ║
44
- ║ 📡 SSE: http://localhost:13337/sse ║
45
- ║ ║
46
33
  ║ Press Ctrl+C to stop all services ║
47
34
  ╚═══════════════════════════════════════════════════════════╝
48
35
  ```
49
36
 
50
- 5. **保持运行**
51
- - 服务会持续运行,直到用户按 Ctrl+C
52
- - 使用 devflow start 同时管理两个进程
37
+ 3. **保持运行**
38
+ - `devflow start` 会持续运行直到 Ctrl+C
39
+ - 服务端和 Dashboard 由 CLI 统一管理生命周期
53
40
 
54
41
  ## 注意事项
55
42
 
56
43
  - 端口 13337:服务端(NestJS)
57
- - 端口 17788:前端(Next.js)
58
- - 数据持久化在 `.devflow/devflow.db`
59
- - 如果端口被占用,提示用户检查并释放端口
44
+ - 端口 17788:前端(Next.js Dashboard)
45
+ - 使用 `npx devflow start` 从任意目录启动,不依赖当前工作目录
46
+ - 如果端口被占用,提示用户 `lsof -i :13337` 或 `lsof -i :17788` 检查
60
47
 
61
48
  ## 故障排除
62
49
 
63
50
  如果启动失败:
64
51
  1. 检查端口是否被占用:`lsof -i :13337` 和 `lsof -i :17788`
65
- 2. 重新安装依赖:`npm install`
66
- 3. 重新构建:`devflow build`
67
- 4. 检查数据库文件权限:`ls -la .devflow/`
52
+ 2. 确认 devflow 已安装:`npx devflow --version`
53
+ 3. 如需后台运行:`npx devflow start -d`
54
+ 4. 仅启动服务端(不要 Dashboard):`npx devflow start --no-dashboard`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/devflow",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "type": "module",
5
5
  "description": "DevFlow - Developer Intelligence Platform (Distribution Package)",
6
6
  "bin": {
@@ -15,16 +15,16 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@colbymchenry/codegraph": "^1.1.1",
18
- "@devflow-tools/adapters": "^0.8.3",
19
- "@devflow-tools/benchmark": "^0.8.3",
20
- "@devflow-tools/context-engine": "^0.8.3",
21
- "@devflow-tools/database": "^0.8.3",
22
- "@devflow-tools/knowledge-engine": "^0.8.3",
23
- "@devflow-tools/mcp-server": "^0.8.3",
24
- "@devflow-tools/memory-engine": "^0.8.3",
25
- "@devflow-tools/sdk": "^0.8.3",
26
- "@devflow-tools/telemetry": "^0.8.3",
27
- "@devflow-tools/workflow-engine": "^0.8.3",
18
+ "@devflow-tools/adapters": "^0.8.5",
19
+ "@devflow-tools/benchmark": "^0.8.5",
20
+ "@devflow-tools/context-engine": "^0.8.5",
21
+ "@devflow-tools/database": "^0.8.5",
22
+ "@devflow-tools/knowledge-engine": "^0.8.5",
23
+ "@devflow-tools/mcp-server": "^0.8.5",
24
+ "@devflow-tools/memory-engine": "^0.8.5",
25
+ "@devflow-tools/sdk": "^0.8.5",
26
+ "@devflow-tools/telemetry": "^0.8.5",
27
+ "@devflow-tools/workflow-engine": "^0.8.5",
28
28
  "@inquirer/prompts": "^7.10.1",
29
29
  "@modelcontextprotocol/sdk": "^1.0.0",
30
30
  "@nestjs/common": "^10.4.0",
@@ -1,172 +1,172 @@
1
1
  {
2
2
  "version": "1.0.0",
3
- "lastUpdated": "2026-07-06T09:45:30.485Z",
3
+ "lastUpdated": "2026-07-08T10:33:32.824Z",
4
4
  "plugins": [
5
5
  {
6
6
  "name": "@devflow-tools/plugin-animation",
7
- "version": "0.7.3",
7
+ "version": "0.8.5",
8
8
  "description": "",
9
9
  "tags": [],
10
10
  "compatibleStacks": [
11
11
  "animation"
12
12
  ],
13
- "size": "776K",
13
+ "size": "824K",
14
14
  "author": "DevFlow Team",
15
15
  "homepage": ""
16
16
  },
17
17
  {
18
18
  "name": "@devflow-tools/plugin-css",
19
- "version": "0.7.3",
19
+ "version": "0.8.5",
20
20
  "description": "",
21
21
  "tags": [],
22
22
  "compatibleStacks": [
23
23
  "css"
24
24
  ],
25
- "size": "744K",
25
+ "size": "792K",
26
26
  "author": "DevFlow Team",
27
27
  "homepage": ""
28
28
  },
29
29
  {
30
30
  "name": "@devflow-tools/plugin-docker",
31
- "version": "0.7.3",
31
+ "version": "0.8.5",
32
32
  "description": "",
33
33
  "tags": [],
34
34
  "compatibleStacks": [
35
35
  "docker"
36
36
  ],
37
- "size": "820K",
37
+ "size": "916K",
38
38
  "author": "DevFlow Team",
39
39
  "homepage": ""
40
40
  },
41
41
  {
42
42
  "name": "@devflow-tools/plugin-electron",
43
- "version": "0.7.3",
43
+ "version": "0.8.5",
44
44
  "description": "",
45
45
  "tags": [],
46
46
  "compatibleStacks": [
47
47
  "electron"
48
48
  ],
49
- "size": "836K",
49
+ "size": "932K",
50
50
  "author": "DevFlow Team",
51
51
  "homepage": ""
52
52
  },
53
53
  {
54
54
  "name": "@devflow-tools/plugin-git",
55
- "version": "0.7.3",
55
+ "version": "0.8.5",
56
56
  "description": "",
57
57
  "tags": [],
58
58
  "compatibleStacks": [
59
59
  "git"
60
60
  ],
61
- "size": "776K",
61
+ "size": "824K",
62
62
  "author": "DevFlow Team",
63
63
  "homepage": ""
64
64
  },
65
65
  {
66
66
  "name": "@devflow-tools/plugin-graphql",
67
- "version": "0.7.3",
67
+ "version": "0.8.5",
68
68
  "description": "",
69
69
  "tags": [],
70
70
  "compatibleStacks": [
71
71
  "graphql"
72
72
  ],
73
- "size": "768K",
73
+ "size": "864K",
74
74
  "author": "DevFlow Team",
75
75
  "homepage": ""
76
76
  },
77
77
  {
78
78
  "name": "@devflow-tools/plugin-nest",
79
- "version": "0.7.3",
79
+ "version": "0.8.5",
80
80
  "description": "",
81
81
  "tags": [],
82
82
  "compatibleStacks": [
83
83
  "nest"
84
84
  ],
85
- "size": "844K",
85
+ "size": "964K",
86
86
  "author": "DevFlow Team",
87
87
  "homepage": ""
88
88
  },
89
89
  {
90
90
  "name": "@devflow-tools/plugin-nextjs",
91
- "version": "0.7.3",
91
+ "version": "0.8.5",
92
92
  "description": "",
93
93
  "tags": [],
94
94
  "compatibleStacks": [
95
95
  "nextjs"
96
96
  ],
97
- "size": "748K",
97
+ "size": "864K",
98
98
  "author": "DevFlow Team",
99
99
  "homepage": ""
100
100
  },
101
101
  {
102
102
  "name": "@devflow-tools/plugin-performance",
103
- "version": "0.7.3",
103
+ "version": "0.8.5",
104
104
  "description": "",
105
105
  "tags": [],
106
106
  "compatibleStacks": [
107
107
  "performance"
108
108
  ],
109
- "size": "864K",
109
+ "size": "960K",
110
110
  "author": "DevFlow Team",
111
111
  "homepage": ""
112
112
  },
113
113
  {
114
114
  "name": "@devflow-tools/plugin-react",
115
- "version": "0.7.3",
115
+ "version": "0.8.5",
116
116
  "description": "",
117
117
  "tags": [],
118
118
  "compatibleStacks": [
119
119
  "react"
120
120
  ],
121
- "size": "852K",
121
+ "size": "1.2M",
122
122
  "author": "DevFlow Team",
123
123
  "homepage": ""
124
124
  },
125
125
  {
126
126
  "name": "@devflow-tools/plugin-tailwind",
127
- "version": "0.7.3",
127
+ "version": "0.8.5",
128
128
  "description": "",
129
129
  "tags": [],
130
130
  "compatibleStacks": [
131
131
  "tailwind"
132
132
  ],
133
- "size": "780K",
133
+ "size": "828K",
134
134
  "author": "DevFlow Team",
135
135
  "homepage": ""
136
136
  },
137
137
  {
138
138
  "name": "@devflow-tools/plugin-taro",
139
- "version": "0.7.3",
139
+ "version": "0.8.5",
140
140
  "description": "",
141
141
  "tags": [],
142
142
  "compatibleStacks": [
143
143
  "taro"
144
144
  ],
145
- "size": "804K",
145
+ "size": "852K",
146
146
  "author": "DevFlow Team",
147
147
  "homepage": ""
148
148
  },
149
149
  {
150
150
  "name": "@devflow-tools/plugin-ui-layout",
151
- "version": "0.7.3",
151
+ "version": "0.8.5",
152
152
  "description": "",
153
153
  "tags": [],
154
154
  "compatibleStacks": [
155
155
  "ui-layout"
156
156
  ],
157
- "size": "744K",
157
+ "size": "792K",
158
158
  "author": "DevFlow Team",
159
159
  "homepage": ""
160
160
  },
161
161
  {
162
162
  "name": "@devflow-tools/plugin-vue",
163
- "version": "0.7.3",
163
+ "version": "0.8.5",
164
164
  "description": "",
165
165
  "tags": [],
166
166
  "compatibleStacks": [
167
167
  "vue"
168
168
  ],
169
- "size": "788K",
169
+ "size": "908K",
170
170
  "author": "DevFlow Team",
171
171
  "homepage": ""
172
172
  }