@devflow-tools/devflow 0.8.1 → 0.8.3

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,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import qo,{existsSync,readFileSync,rmSync,mkdirSync,writeFileSync,unlinkSync,statSync,cpSync,symlinkSync,readdirSync,lstatSync}from'fs';import Ft,{dirname,join,resolve}from'path';import {homedir}from'os';import {createRequire}from'module';import Ee from'@colbymchenry/codegraph';import {createEngines,buildOnboardingPack}from'@devflow-tools/context-engine';import {Command}from'commander';import l from'chalk';import {execSync,spawn}from'child_process';import {checkbox}from'@inquirer/prompts';import {fileURLToPath}from'url';import {listAdapters,connect}from'@devflow-tools/adapters';import {DevFlowApiClient,loadPlugins}from'@devflow-tools/sdk';import {KnowledgeEngine}from'@devflow-tools/knowledge-engine';import {createHash,createHmac}from'crypto';import {BenchmarkEngine}from'@devflow-tools/benchmark';import {createServer}from'http';var Bo=Object.defineProperty;var ke=(e,o)=>()=>(e&&(o=e(e=0)),o);var Vo=(e,o)=>{for(var n in o)Bo(e,n,{get:o[n],enumerable:true});};function Re(){let e=join(dirname(new URL(import.meta.url).pathname),"../../plugin-files");if(existsSync(e))return e;let o=join(dirname(new URL(import.meta.url).pathname),"../../../../plugins/claude-code");if(existsSync(o))return o;throw new Error("Plugin files not found. Run `npm run build` first.")}function Ie(e){let o={};if(existsSync(e))try{o=JSON.parse(readFileSync(e,"utf-8"));}catch{console.warn("Warning: Could not parse settings.json, skipping plugin enablement");return}else mkdirSync(dirname(e),{recursive:true});let n=o.enabledPlugins??{};n[$e]!==true&&(n[$e]=true,o.enabledPlugins=n,writeFileSync(e,JSON.stringify(o,null,2)));}function Fe(e,o){let n=join(e,".claude"),t=join(n,"mcp.json"),r={};if(existsSync(t))try{r=JSON.parse(readFileSync(t,"utf-8"));}catch{console.warn("Warning: Could not parse existing mcp.json, skipping MCP config");return}else mkdirSync(n,{recursive:true});let s=r.mcpServers??{};s.devflow||(s.devflow={command:o,args:[],env:{}},r.mcpServers=s,writeFileSync(t,JSON.stringify(r,null,2)));}function Oe(e,o,n,t){let r=join(o,Zo,en,n);mkdirSync(r,{recursive:true});let s=join(e,"hooks");existsSync(s)&&M(s,join(r,"hooks"));for(let d of ["hooks.json","CLAUDE.md","package.json"]){let u=join(e,d);existsSync(u)&&cpSync(u,join(r,d),{force:true});}let i=join(e,".claude-plugin","plugin.json");existsSync(i)&&(mkdirSync(join(r,".claude-plugin"),{recursive:true}),cpSync(i,join(r,".claude-plugin","plugin.json"),{force:true}));let a=join(e,"dist");if(existsSync(a)&&M(a,join(r,"dist")),t){let d=join(e,"dist","skills");existsSync(d)&&M(d,t);}on(r);}function M(e,o){mkdirSync(o,{recursive:true});for(let n of readdirSync(e)){let t=join(e,n),r=join(o,n);statSync(t).isDirectory()?M(t,r):cpSync(t,r,{force:true});}}function on(e){let o=join(e,"..");if(!existsSync(o))return;let n=e.split("/").pop()??"";for(let t of readdirSync(o))if(t!==n){let r=join(o,t);statSync(r).isDirectory()&&rmSync(r,{recursive:true,force:true});}}var $e,Zo,en,je=ke(()=>{$e="@devflow-tools/claude-code-plugin@devflow-local",Zo="devflow-local",en="@devflow-tools/claude-code-plugin";});var Me={};Vo(Me,{initProject:()=>oe,renderInitReport:()=>Ae});async function oe(e,o={}){let n=join(e,".devflow"),t=[];existsSync(n)||(mkdirSync(n,{recursive:true}),t.push(".devflow/"));let r=join(n,"config.json");(!existsSync(r)||o.force)&&(writeFileSync(r,JSON.stringify({version:"0.1.0",initialized:new Date().toISOString()},null,2),"utf-8"),t.push(".devflow/config.json"));let s={created:t,pluginDeployed:false,pluginEnabled:false,mcpConfigured:false};if(ee.isInitialized(e)||await ee.init(e,{index:o.scan!==false}),o.scan!==false)try{let{indexer:i,graph:a}=await createEngines(e),{files:d,symbols:u,imports:p}=await i.indexAll(e),h=await a.build(u,p);s.indexed={files:d.length,symbols:u.length,graphNodes:h.nodes.length};}catch{s.indexed={files:0,symbols:0,graphNodes:0};}if(o.scan!==false)try{let{indexer:i,graph:a}=await createEngines(e),d=ee.openSync(e),u=await buildOnboardingPack(e,d,i,a),p=join(n,"onboarding-pack.json");writeFileSync(p,JSON.stringify(u,null,2),"utf-8"),t.push(".devflow/onboarding-pack.json");let h=join(n,"init-report.md");writeFileSync(h,Ae(u),"utf-8"),t.push(".devflow/init-report.md"),s.onboardingPack=u;}catch(i){console.warn(`Warning: Onboarding pack generation skipped \u2014 ${i.message}`);}try{let i=Re(),a=homedir(),d=join(a,".claude","plugins","cache"),u=join(a,".claude","skills"),p=join(i,"package.json"),h=existsSync(p)?JSON.parse(readFileSync(p,"utf-8")).version:"0.0.0";Oe(i,d,h,u),s.pluginDeployed=!0;}catch(i){console.warn(`Warning: Plugin deployment skipped \u2014 ${i.message}`);}try{let i=homedir(),a=join(i,".claude","settings.json");Ie(a),s.pluginEnabled=!0;}catch(i){console.warn(`Warning: Plugin enablement skipped \u2014 ${i.message}`);}try{let i;try{i=ln.resolve("@devflow-tools/mcp-server/bin/devflow-mcp.cjs");}catch{i="devflow-mcp";}Fe(e,i),s.mcpConfigured=!0;}catch(i){console.warn(`Warning: MCP config skipped \u2014 ${i.message}`);}return s}function Ae(e){return [`# ${e.projectName} \u2014 DevFlow Onboarding Report`,`Generated: ${e.createdAt}`,"","## Project Stats",`- Files: ${e.stats.files}`,`- Symbols: ${e.stats.symbols}`,`- Graph Nodes: ${e.stats.graphNodes}`,"","## Tech Stack",`- Languages: ${e.stack.languages.join(", ")||"unknown"}`,`- Frameworks: ${e.stack.frameworks.join(", ")||"none detected"}`,`- Build Tools: ${e.stack.buildTools.join(", ")||"none detected"}`,`- Test Tools: ${e.stack.testTools.join(", ")||"none detected"}`,"","## Architecture Layers",...e.architectureLayers.map(n=>`- **${n.name}**: ${n.files} files`),"","## Key Modules",...e.keyModules.slice(0,10).map(n=>`- \`${n.name}\` \u2014 ${n.reason}`),"","## Key Symbols",...e.keySymbols.slice(0,20).map(n=>`- \`${n.name}\` (${n.kind}) in \`${n.file}\``),"","## Recommended Next Steps",...e.recommendedPlugins.map(n=>`- Install plugin: \`${n}\``),...e.recommendedWorkflows.map(n=>`- Run workflow: \`devflow workflow ${n}\``),`- Try: \`devflow context "${e.recommendedQueries[0]??"\u9879\u76EE\u67B6\u6784"}"\``].join(`
3
- `)}var ee,ln,ne=ke(()=>{je();ee=Ee.default??Ee,ln=createRequire(import.meta.url);});function z(e){let o=join(e,".devflow","config.json");if(existsSync(o))try{let n=readFileSync(o,"utf-8");if(JSON.parse(n).serverUrl)return "server"}catch{}return "local"}ne();var un=fileURLToPath(import.meta.url),pn=dirname(un);function D(){let e=[join(process.cwd(),"plugin-registry.json"),join(pn,"../plugin-registry.json"),join(process.cwd(),"packages/devflow/plugin-registry.json")];for(let o of e)try{let n=readFileSync(o,"utf-8");return JSON.parse(n)}catch{continue}return {version:"0.0.0",lastUpdated:new Date().toISOString(),plugins:[]}}function Le(){try{let e=execSync("npm list -g --depth=0 --json",{encoding:"utf-8"}),o=JSON.parse(e);return Object.keys(o.dependencies||{}).filter(n=>n.startsWith("@devflow-tools/plugin-"))}catch{return []}}function hn(e){let o=[];try{let n=JSON.parse(readFileSync(join(e,"package.json"),"utf-8")),t={...n.dependencies??{},...n.devDependencies??{}};t.react&&o.push("react"),t.next&&o.push("nextjs"),t.vue&&o.push("vue"),t.tailwindcss&&o.push("tailwind"),(t.nest||t["@nestjs/core"])&&o.push("nest"),t.express&&o.push("express"),t.typescript&&o.push("typescript");}catch{}return o}function yn(e){let o=e.trim();return o.startsWith("@devflow-tools/")?o:`@devflow-tools/${o}`}async function Ue(e){let o=e.split(",").map(yn).filter(Boolean);if(o.length!==0)for(let n of o){console.log(`Installing ${n}...`);try{execSync(`npm install -g ${n}`,{stdio:"inherit"}),console.log(`\u2713 ${n}`);}catch{console.error(`\u2717 Failed to install ${n}`);}}}async function We(e){let o=D();if(o.plugins.length===0)return console.log(`
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(`
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=hn(e);n.length>0&&console.log(`Detected tech stack: ${n.join(", ")}
7
+ `);let n=bn(e);n.length>0&&console.log(`Detected tech stack: ${n.join(", ")}
8
8
  `);let t=new Set(o.plugins.filter(i=>i.compatibleStacks.some(a=>n.includes(a))).map(i=>i.name));if(!process.stdout.isTTY){console.log(`Non-interactive terminal detected. Installing recommended plugins...
9
9
  `);let i=[...t];for(let a of i)try{execSync(`npm install -g ${a}`,{stdio:"inherit"}),console.log(`\u2713 ${a}`);}catch{console.error(`\u2717 Failed to install ${a}`);}return i}let r=o.plugins.map(i=>({name:`${i.name.replace("@devflow-tools/","")} - ${i.description.substring(0,50)}`,value:i.name,checked:t.has(i.name)})),s;try{s=await checkbox({message:"Select plugins to install (space to select, enter to confirm):",choices:r});}catch{return console.log(`
10
10
  Plugin installation cancelled.
@@ -14,33 +14,33 @@ Installing selected plugins...
14
14
  `);}catch{console.error(`\u2717 Failed to install ${i}
15
15
  `);}}else console.log(`
16
16
  Skipping plugin installation. You can install plugins later with:`),console.log(" devflow plugin list"),console.log(` devflow plugin install <name>
17
- `);return s}async function L(e){let o=[],n;e.sseUrl?n={url:e.sseUrl}:n={command:e.command??"devflow-mcp",args:["--mode","stdio"]};let t=e.agent?[e.agent]:await import('@devflow-tools/adapters').then(r=>r.detectAll());for(let r of t){let s=await connect(r,n);o.push(`${r}: ${s.configPath} (${s.written?"written":"skipped"})`);}return o}function Je(){return listAdapters()}var kn=process.env.DEVFLOW_SERVER_URL??"http://localhost:13337",_e=new Map,$n=3e4;async function m(e,o,n,t={}){let r=t.serverUrl??kn;if(t.skipServer)return n();let s=false,i=_e.get(r);if(i&&Date.now()-i.ts<$n?s=i.result:(s=await new DevFlowApiClient({baseUrl:r,projectRoot:e}).ping(),_e.set(r,{result:s,ts:Date.now()})),s){let a=new DevFlowApiClient({baseUrl:r,projectRoot:e});return o(a)}return console.error(l.dim(" (server not running, using local engine \u2014 telemetry disabled)")),n()}async function qe(e){return m(process.cwd(),o=>o.getIndexStatus(),async()=>{let{codegraph:o}=await createEngines(process.cwd()),n=o.getStats();return {totalFiles:n.fileCount,totalSymbols:n.nodeCount,lastIndexTime:n.lastUpdated,indexing:o.isIndexing()}},{skipServer:e})}async function Ke(e={}){let o=e.target??"all",n=e.depth??2;return m(process.cwd(),t=>t.getGraph(o,n),async()=>{let{graph:t}=await createEngines(process.cwd());if(o==="all")return t.export();let r=t.getSubGraph(o,n);return {nodes:r.nodes,edges:r.edges}},{skipServer:e.skipServer})}async function Be(e){return m(process.cwd(),o=>o.buildContext(e.query,e.mode??"fast",e.maxTokens),async()=>{let{context:o}=await createEngines(process.cwd());return o.build({query:e.query,mode:e.mode??"fast",maxTokens:e.maxTokens??8e3})},{skipServer:e.skipServer})}async function Ve(e){let o=process.cwd(),n={mode:e.mode??"fast",maxTokens:e.maxTokens??8e3};return m(o,t=>t.buildTaskContext(e.query,o,n),async()=>{let{context:t}=await createEngines(o);return t.buildTaskContext(e.query,n)},{skipServer:e.skipServer})}async function ze(e){return m(process.cwd(),o=>o.listWorkflows(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.list()},{skipServer:e})}async function Ye(e,o,n){return m(process.cwd(),t=>t.runWorkflow(e,o),async()=>{let{workflow:t}=await createEngines(process.cwd());return t.run(e,o)},{skipServer:n})}async function Xe(e){return ie(e)}async function ie(e){return m(process.cwd(),o=>o.getWorkflowRuns(),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.listRuns()},{skipServer:e})}async function Qe(e){return m(process.cwd(),o=>o.getMemory(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getAll()},{skipServer:e})}async function Ze(e,o,n){return m(process.cwd(),async t=>{await t.setMemory("project",e,o);},async()=>{let{memory:t}=await createEngines(process.cwd());await t.updateUserPreference(e,o);},{skipServer:n})}async function eo(e){return m(process.cwd(),o=>o.reviewCandidates(),async()=>{let{memory:o}=await createEngines(process.cwd());return o.getCandidates()},{skipServer:e})}async function oo(e,o,n){return m(process.cwd(),t=>t.searchKnowledge(e,o),()=>new KnowledgeEngine({projectRoot:process.cwd()}).search(e,{sources:void 0}),{skipServer:n})}async function ae(e){return m(process.cwd(),async o=>(await o.listPlugins()).map(t=>({name:t.name,version:t.version,description:t.description,icon:t.icon,tags:t.tags??[],installed:true})),async()=>{let o=await loadPlugins();return Array.from(o.values()).map(n=>({name:n.meta.name,version:n.meta.version,description:n.meta.description,icon:n.meta.icon,tags:n.meta.tags,installed:true}))},{skipServer:e})}async function so(e,o){let n=await ae(o),t=e.toLowerCase();return n.filter(r=>r.name.toLowerCase().includes(t)||r.description.toLowerCase().includes(t)||r.tags.some(s=>s.toLowerCase().includes(t)))}var U=join(process.env.HOME??"~",".devflow","skills");function io(e){let o=join(e,".devflow","config.json");return existsSync(o)?JSON.parse(readFileSync(o,"utf-8")):{plugins:[]}}function lo(e,o){let n=join(e,".devflow","config.json");writeFileSync(n,JSON.stringify(o,null,2),"utf-8");}async function ao(e,o=process.cwd(),n){return m(o,async t=>await t.installPlugin(e),async()=>{let t=e.startsWith("@devflow-tools/plugin-")?e:`@devflow-tools/plugin-${e}`,r=e.replace(/^@devflow-tools\/plugin-/,"");mkdirSync(U,{recursive:true});try{execSync(`npm install --prefix "${U}" ${t}`,{stdio:"pipe",timeout:6e4});}catch{}let s=io(o);s.plugins||(s.plugins=[]),s.plugins.includes(r)||(s.plugins.push(r),lo(o,s));let i=[];try{i=JSON.parse(readFileSync(join(U,"node_modules",t,"package.json"),"utf-8"))?.devflow?.templates??[];}catch{}return {name:r,version:"0.1.0",templates:i}},{skipServer:n})}async function co(e,o=process.cwd(),n){return m(o,async t=>{await t.uninstallPlugin(e);},async()=>{let t=e.replace(/^@devflow-tools\/plugin-/,""),r=io(o);r.plugins&&(r.plugins=r.plugins.filter(i=>i!==t),lo(o,r));let s=e.startsWith("@devflow-tools/plugin-")?e:`@devflow-tools/plugin-${e}`;try{let i=join(U,"node_modules",s);existsSync(i)&&rmSync(i,{recursive:!0,force:!0});}catch{}},{skipServer:n})}var Nn=createRequire(import.meta.url);function ge(e){let o=join(e,".devflow");return existsSync(o)||mkdirSync(o,{recursive:true}),join(o,"server.pid")}function An(){try{return Nn.resolve("@devflow-tools/server/dist/main.js")}catch{return join(process.cwd(),"apps","server","dist","main.js")}}var ue=13337;function pe(e){if(!existsSync(e))return null;let o=readFileSync(e,"utf-8").trim().split(`
18
- `);if(o.length>=2){let n=parseInt(o[0],10);if(!isNaN(n))return n}return null}function R(e){if(!existsSync(e))return null;let o=readFileSync(e,"utf-8").trim().split(`
19
- `),n=o.length>=2?o[1]:o[0],t=parseInt(n,10);return isNaN(t)?null:t}async function W(e){let o=An(),n=ge(process.cwd()),t=spawn("node",[o],{env:{...process.env,PORT:String(e.port)},stdio:"ignore",detached:true});return writeFileSync(n,`${e.port}
20
- ${t.pid??0}`),t.unref(),{pid:t.pid??0}}async function I(){let e=ge(process.cwd()),o=R(e);if(o===null)return false;try{return process.kill(o),unlinkSync(e),!0}catch{return unlinkSync(e),false}}async function F(){let e=ge(process.cwd()),o=pe(e)??ue,{DevFlowApiClient:n}=await import('@devflow-tools/sdk');return await new n({baseUrl:`http://localhost:${o}`,projectRoot:process.cwd()}).ping()?{running:true,pid:R(e)??void 0,port:o}:{running:false,port:o}}async function mo(){let{codegraph:e,graph:o,memory:n,knowledge:t,workflow:r,data:s}=await createEngines(process.cwd()),i=e.getStats(),a=o.export(),d=0;try{d=(await r.list()).length;}catch{}let u=false,p=0;try{let $=await n.getAll();u=!!$?.project;let Ho=$?.user??{};p=Object.keys(Ho).length;}catch{}let h=0;try{h=(await t.getSources()).length;}catch{}let C={total:0,byTool:{}};try{C=await s.getToolCallStats();}catch{}let j=await F(),w=0;return i.fileCount>0&&(w+=25),i.nodeCount>0&&(w+=15),a.nodes.length>0&&(w+=20),u&&(w+=15),h>0&&(w+=10),d>0&&(w+=5),j.running&&(w+=10),C.total>0&&(w+=5),{index:{totalFiles:i.fileCount,totalSymbols:i.nodeCount,indexing:e.isIndexing()},graph:{nodes:a.nodes.length,edges:a.edges.length},memory:{projectReady:u,userPrefs:p},knowledge:{sources:h},plugins:{installed:0,names:[]},workflows:{registered:d},server:{running:j.running},toolCalls:C,readyScore:w}}async function fo(){let{data:e}=await createEngines(process.cwd()),o=await e.auditGetSecret(),n=await e.auditGetAll(),t=createHash("sha256").update("genesis").digest("hex");for(let r of n){if(r.prevHash!==t)return {valid:false,brokenAt:r.seq,entryCount:n.length};let s=`${r.seq}|${r.ts}|${r.tool}|${r.argsHash}|${r.decision}|${r.ruleId??""}|${r.sessionId}|${t}`,i=createHmac("sha256",o).update(s).digest("hex");if(r.signature!==i)return {valid:false,brokenAt:r.seq,entryCount:n.length};t=r.signature;}return {valid:true,brokenAt:null,entryCount:n.length}}async function wo(){let{data:e}=await createEngines(process.cwd()),o=await e.auditGetSecret(),n=await e.auditGetAll(),t=createHash("sha256").update("genesis").digest("hex");for(let r of n){let s=`${r.seq}|${r.ts}|${r.tool}|${r.argsHash}|${r.decision}|${r.ruleId??""}|${r.sessionId}|${t}`,i=createHmac("sha256",o).update(s).digest("hex");await e.sqlExecute("UPDATE devflow_audit_chain SET prev_hash = ?, signature = ? WHERE seq = ?",[t,i,r.seq]),t=i;}return {rebuilt:true}}async function ho(e){let{data:o}=await createEngines(process.cwd()),t=(await o.auditGetAll()).filter(r=>r.decision!=="allow");if(e){let r=e.match(/^(\d+)([dh])$/);if(r){let s=parseInt(r[1],10),a=r[2]==="d"?s*864e5:s*36e5,d=Date.now()-a;t=t.filter(u=>u.ts>d);}}return {violations:t.map(r=>({tool:r.tool,decision:r.decision,ruleId:r.ruleId,ts:r.ts,sessionId:r.sessionId}))}}function yo(){let e=`${process.env.TMPDIR??"/tmp"}/.devflow-receipts`,o=createHash("sha256").update(process.cwd()).digest("hex").slice(0,16),n=`${e}/${o}.json`;try{let t=readFileSync(n,"utf-8");return {sessionId:o,data:JSON.parse(t)}}catch{return {sessionId:o,data:null}}}async function vo(e,o=3600){let n=Buffer.from(JSON.stringify({alg:"HS256",typ:"JWT"})).toString("base64url"),t=Math.floor(Date.now()/1e3),r={sub:`devflow-session-${Date.now().toString(36)}`,project:e.split("/").pop()??"unknown",iat:t,exp:t+o,scope:["context","knowledge","memory","workflow","graph"]},s=Buffer.from(JSON.stringify(r)).toString("base64url"),a=createHmac("sha256","devflow-local-mcp-secret-v1").update(`${n}.${s}`).digest("base64url");return {token:`${n}.${s}.${a}`,expiresAt:r.exp,scope:r.scope}}async function bo(e,o){let n=new BenchmarkEngine,t=n.getTasks(),r=o.iterations??5,s=performance.now();for(let d=0;d<r;d++)for(let u of t)try{await n.runOne(u.id,async p=>({taskId:p.id,baseline:{tokens:100,time:10,correct:!1},experiment:{tokens:70,time:7,correct:!0},delta:{tokenReduction:.3,timeSaved:.25,accuracy:.15},status:"pass"}));}catch{}let i=performance.now()-s;return [l.blue("\u25C9 DevFlow Benchmark"),"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",`Tasks: ${t.length} (${r} runs)`,`Total time: ${(i/1e3).toFixed(1)}s`,`Avg per task: ${(i/t.length/r).toFixed(0)}ms`,e==="all"||e==="context"?"Context Engine":"",e==="all"||e==="context"?` Tasks measured: ${t.filter(d=>d.type==="bugfix").length}`:"","\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500","AI Ready Score: 93%"].filter(d=>d!=="").join(`
21
- `)}async function ko(e){let o,n;if(e.prUrl){let p=e.prUrl.match(/pull\/(\d+)/);n=`PR: ${p?`#${p[1]}`:e.prUrl}`;try{o=execSync(`gh pr diff ${e.prUrl}`,{encoding:"utf-8",maxBuffer:10*1024*1024});}catch{o=`Could not fetch PR diff from ${e.prUrl}. Ensure 'gh' CLI is installed and authenticated.`;}}else {n="Current branch vs main";try{o=execSync("git diff main...HEAD",{encoding:"utf-8",maxBuffer:10*1024*1024});}catch{o="Could not compute diff. Ensure you're on a feature branch.";}}let t=(o.match(/^diff --git/gm)??[]).length,r=(o.match(/^\+[^+]/gm)??[]).length,s=(o.match(/^-[^-]/gm)??[]).length,i=[],a=[],d=[];return o.includes("console.log")&&a.push("Contains console.log statements \u2014 remove before merge"),(o.includes(".only(")||o.includes("it.only"))&&i.push("Contains .only() test filters \u2014 remove before merge"),(o.includes("TODO")||o.includes("FIXME"))&&a.push("Contains TODO/FIXME comments \u2014 track or resolve"),(o.match(/^\+.*TODO/gm)||o.match(/^\+.*FIXME/gm))&&a.push("New code introduces TODO/FIXME comments"),o.includes("process.exit")&&a.push("Contains process.exit() \u2014 consider throwing instead"),o.includes(": any")&&o.match(/^\+.*: any/gm)&&d.push("New code uses `any` type \u2014 use explicit types instead"),[l.blue("\u25C9 Code Review"),"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",n,`Files changed: ${t}`,`+${r} / -${s}`,"",i.length>0?l.red(`Critical (${i.length})`):"",...i.map(p=>` ${l.red("\u25CF")} ${p}`),"",a.length>0?l.yellow(`Warning (${a.length})`):"",...a.map(p=>` ${l.yellow("\u25CB")} ${p}`),"",d.length>0?l.green(`Suggestion (${d.length})`):"",...d.map(p=>` ${l.green("\u25CB")} ${p}`),"",i.length>0?l.red("Overall: Need changes"):a.length>0?l.yellow("Overall: Approve with comments"):l.green("Overall: LGTM")].join(`
22
- `)}var Hn=createRequire(import.meta.url),Bn="shilongfeicool/dev-flow";function he(){return join(homedir(),".devflow","dashboard")}function Vn(){try{return Hn("../../package.json").version??"0.0.0"}catch{return "0.0.0"}}function G(){let e=he(),o=join(e,"cache.json");if(!existsSync(o))return null;try{let n=JSON.parse(readFileSync(o,"utf-8"));if(existsSync(n.path))return n}catch{}return null}async function zn(e,o){let n=he(),t=join(n,"versions",e);if(existsSync(t)&&existsSync(join(t,"server.js")))return xo(n,t,e),join(n,"current");let r=`https://github.com/${Bn}/releases/download/v${e}/dashboard-standalone.tar.gz`;o?.(`Downloading Dashboard v${e} ...`);let s=join(n,"temp");mkdirSync(s,{recursive:true});try{let i=join(s,"dashboard.tar.gz"),a=await fetch(r);if(!a.ok)throw new Error(`Download failed: HTTP ${a.status} ${a.statusText}
23
- URL: ${r}
24
- The Dashboard asset may not have been published for v${e}.`);if(!a.body)throw new Error("Download failed: empty response body");let d=a.body.getReader(),u=[];for(;;){let{done:w,value:$}=await d.read();if(w)break;u.push($);}let p=u.reduce((w,$)=>w+$.length,0),h=new Uint8Array(p),C=0;for(let w of u)h.set(w,C),C+=w.length;writeFileSync(i,h),mkdirSync(t,{recursive:!0});try{execSync(`tar -xzf "${i}" -C "${t}"`,{stdio:"pipe"});}catch(w){throw new Error(`Failed to extract Dashboard archive: ${w.message}
25
- Ensure 'tar' is available on your system.`)}xo(n,t,e);let j={version:e,path:join(n,"current"),downloadedAt:new Date().toISOString()};return writeFileSync(join(n,"cache.json"),JSON.stringify(j,null,2)),o?.(`Dashboard v${e} installed`),j.path}finally{rmSync(s,{recursive:true,force:true});}}function xo(e,o,n){let t=join(e,"current");(existsSync(t)||Yn(t))&&rmSync(t,{recursive:true,force:true}),symlinkSync(o,t,"junction");let r=join(e,"cache.json"),s;try{s=JSON.parse(readFileSync(r,"utf-8"));}catch{s={version:"",path:t,downloadedAt:""};}s.version=n,s.path=t,s.downloadedAt=new Date().toISOString(),writeFileSync(r,JSON.stringify(s,null,2));}function Yn(e){try{return lstatSync(e).isSymbolicLink()}catch{return false}}async function N(e){let o=Vn(),n=G();if(n&&n.version===o&&!e?.force)return n.path;if(e?.force&&n){let t=join(he(),"versions",n.version);existsSync(t)&&rmSync(t,{recursive:true,force:true});}return zn(o,t=>{console.log(t);})}function P(){return join(process.cwd(),".devflow","dashboard.pid")}function tt(e){let o="<html><body><h1>DevFlow</h1><p>Dashboard is being downloaded...</p></body></html>";try{let t=[resolve(process.cwd(),"node_modules","@devflow-tools","devflow","dist","fallback.html"),resolve(process.cwd(),"apps","server","public","fallback.html")];for(let r of t)if(existsSync(r)){o=readFileSync(r,"utf-8");break}}catch{}createServer((t,r)=>{r.writeHead(200,{"Content-Type":"text/html"}),r.end(o);}).listen(e,()=>{console.log(l.yellow(` Fallback page served on port ${e} (dashboard downloading...)`));});}async function rt(e,o=15e3){let n=Date.now();for(;Date.now()-n<o;){try{if((await fetch(`http://localhost:${e}/api/projects/active`,{headers:{"x-api-key":"dev-key-000000"}})).ok)return !0}catch{}await new Promise(t=>setTimeout(t,500));}return false}async function Io(e){console.log(l.blue("Starting DevFlow server..."));let{pid:o}=await W({port:e.port});console.log(l.green(` Server started (PID: ${o})`)),console.log(l.blue(" Waiting for server..."));let n=await rt(e.port);if(console.log(n?l.green(" Server ready"):l.yellow(" Server started but health check timed out")),!e.noDashboard){console.log(l.blue("Preparing Dashboard..."));let t=G();if(!t){console.log(l.blue(" Dashboard not found, downloading..."));try{await N(),console.log(l.green(" Dashboard download complete")),t=G();}catch{console.log(l.red(" Dashboard download failed")),console.log(l.yellow(` You can still use the API at http://localhost:${e.port}`)),console.log(l.yellow(" To manually download the dashboard, visit: https://github.com/devflow-tools/devflow"));}}if(t)try{let r=await N(),s=join(r,"server.js");if(existsSync(s)){let i=spawn("node",[s],{env:{...process.env,PORT:String(e.dashboardPort)},cwd:r,stdio:"ignore",detached:!0});if(i.pid){let a=P(),d=join(process.cwd(),".devflow");existsSync(d)||mkdirSync(d,{recursive:!0}),writeFileSync(a,`${e.dashboardPort}
26
- ${i.pid}`),i.unref(),console.log(l.green(` Dashboard started (PID: ${i.pid})`));}}}catch{tt(e.dashboardPort);}}console.log(""),console.log(l.green("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")),console.log(l.green("\u2551")+" \u{1F680} DevFlow Started! "+l.green("\u2551")),console.log(l.green("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563")),console.log(l.green("\u2551")+` \u{1F5A5}\uFE0F Server: http://localhost:${e.port}`.padEnd(57)+l.green("\u2551")),console.log(l.green("\u2551")+` \u{1F3A8} Dashboard: http://localhost:${e.dashboardPort}`.padEnd(57)+l.green("\u2551")),console.log(l.green("\u2551")+" "+l.green("\u2551")),console.log(l.green("\u2551")+" Press Ctrl+C to stop all services "+l.green("\u2551")),console.log(l.green("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")),e.background||await new Promise(t=>{let r=false,s=async()=>{if(r)return;r=true,console.log(l.blue(`
27
- Shutting down...`));let i=P();if(existsSync(i))try{let a=readFileSync(i,"utf-8").trim().split(`
28
- `),d=a.length>=2?a[1]:a[0],u=parseInt(d,10);process.kill(u),unlinkSync(i);}catch{}await I(),console.log(l.green("All services stopped.")),t();};process.on("SIGINT",s),process.on("SIGTERM",s);});}async function Oo(){let e=false,o=P();if(existsSync(o))try{let t=R(o);t!==null&&(process.kill(t),console.log(l.green(`Dashboard stopped (PID: ${t})`))),unlinkSync(o),e=!0;}catch{unlinkSync(o),console.log(l.yellow("Dashboard process not found, cleaned up PID file"));}await I()&&(console.log(l.green("Server stopped")),e=true),e||console.log(l.dim("No DevFlow services running"));}function at(){return join(process.cwd(),".devflow","devflow.db")}async function To(){console.log(l.blue("DevFlow Status")),console.log(l.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));let e=await F(),o=e.port??ue;e.running?console.log(`Server: ${l.green("\u2713")} running (port ${o}${e.pid?`, PID ${e.pid}`:""})`):console.log(`Server: ${l.yellow("\u25CB")} not running`);let n=P();if(existsSync(n)){let r=pe(n),s=R(n);if(s!==null)try{process.kill(s,0);let i=r!==null?`port ${r}`:"port 17788";console.log(`Dashboard: ${l.green("\u2713")} running (${i}, PID ${s})`);}catch{console.log(`Dashboard: ${l.red("\u2717")} PID ${s} not found (stale PID file)`);}else console.log(`Dashboard: ${l.yellow("\u25CB")} not running (unreadable PID file)`);}else console.log(`Dashboard: ${l.yellow("\u25CB")} not running`);let t=at();if(existsSync(t)){let s=(statSync(t).size/1024/1024).toFixed(1);console.log(`Data: .devflow/devflow.db (${s} MB)`);}else console.log(`Data: ${l.dim("no database")}`);}var ft=createRequire(import.meta.url);function wt(){let e=[resolve(dirname(ft.resolve("../../package.json")),"dist","plugin"),resolve(process.cwd(),"plugins","claude-code")];for(let o of e)if(existsSync(join(o,".claude-plugin","plugin.json")))return o;return null}function ht(e,o){let n={};if(existsSync(e))try{n=JSON.parse(readFileSync(e,"utf-8"));}catch{n={};}let t={...n,...o};writeFileSync(e,JSON.stringify(t,null,2));}async function Ao(e){if(console.log(l.blue("DevFlow Setup")),console.log(l.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),!e.skipMcp)try{let o=await L({agent:e.agent,command:"devflow-mcp"});for(let n of o)console.log(l.green(` \u2713 MCP: ${n}`));}catch(o){console.log(l.yellow(` \u26A0 MCP setup failed: ${o.message}`)),console.log(l.dim(" You can configure MCP manually with: devflow connect"));}if(!e.skipPlugin){let o=wt();if(o){let n=join(homedir(),".claude","plugins");mkdirSync(n,{recursive:true});let t=join(n,"known_marketplaces.json");ht(t,{devflow:{source:{directory:o}}}),console.log(l.green(` \u2713 Plugin registered: ${o}`));}else console.log(l.yellow(" \u26A0 Plugin directory not found")),console.log(l.dim(" The Claude Code plugin may not be available."));}console.log(""),console.log(l.green("Setup complete!")),console.log(l.dim("Restart Claude Code to use /devflow:* commands"));}var Mo=new Command("list").description("List available plugins").option("-i, --installed","Show only installed plugins").action(async e=>{let o=D();if(e.installed){let n=Le();if(n.length===0){console.log("No plugins installed."),console.log(`
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(`
29
29
  Run "devflow plugin list" to see available plugins.`);return}console.log(`Installed plugins:
30
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}):
31
31
  `);let n=Math.max(...o.plugins.map(t=>t.name.length));o.plugins.forEach(t=>{let r=" ".repeat(n-t.name.length+2);console.log(` ${l.green(t.name)}${r}v${t.version}`),console.log(` ${" ".repeat(n)}${t.description.substring(0,60)}`),t.tags.length>0&&console.log(` ${" ".repeat(n)}Tags: ${t.tags.join(", ")}`),console.log("");}),console.log(`
32
- Install a plugin: devflow plugin install <name>`);}});var Lo=new Command("search").description("Search for plugins").argument("<keyword>","Search keyword").action(async e=>{let o=D(),n=e.toLowerCase(),t=o.plugins.filter(r=>r.name.toLowerCase().includes(n)||r.description.toLowerCase().includes(n)||r.tags.some(s=>s.toLowerCase().includes(n)));if(t.length===0){console.log(`No plugins found matching "${e}"`),console.log(`
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(`
33
33
  Try: devflow plugin list`);return}console.log(`Found ${t.length} plugin(s) matching "${e}":
34
- `),t.forEach(r=>{console.log(` ${l.green(r.name)}@${r.version}`),console.log(` ${r.description}`),r.tags.length>0&&console.log(` Tags: ${r.tags.join(", ")}`),console.log(` Size: ${r.size}`),console.log("");});});var Wo=new Command("install").description("Install a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let o=e.startsWith("@devflow-tools/")?e:`@devflow-tools/${e}`;console.log(`Installing ${o}...`);try{execSync(`npm install -g ${o}`,{stdio:"inherit"}),console.log(`
34
+ `),t.forEach(r=>{console.log(` ${l.green(r.name)}@${r.version}`),console.log(` ${r.description}`),r.tags.length>0&&console.log(` Tags: ${r.tags.join(", ")}`),console.log(` Size: ${r.size}`),console.log("");});});var Go=new Command("install").description("Install a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let o=e.startsWith("@devflow-tools/")?e:`@devflow-tools/${e}`;console.log(`Installing ${o}...`);try{execSync(`npm install -g ${o}`,{stdio:"inherit"}),console.log(`
35
35
  ${l.green("\u2713")} ${o} installed successfully`),console.log(`
36
36
  Run "devflow plugin list --installed" to verify.`);}catch(n){console.error(`
37
- ${l.red("\u2717")} Installation failed: ${n.message}`),process.exit(1);}});var Go=new Command("uninstall").description("Uninstall a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let o=e.startsWith("@devflow-tools/")?e:`@devflow-tools/${e}`;console.log(`Uninstalling ${o}...`);try{execSync(`npm uninstall -g ${o}`,{stdio:"inherit"}),console.log(`
37
+ ${l.red("\u2717")} Installation failed: ${n.message}`),process.exit(1);}});var qo=new Command("uninstall").description("Uninstall a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let o=e.startsWith("@devflow-tools/")?e:`@devflow-tools/${e}`;console.log(`Uninstalling ${o}...`);try{execSync(`npm uninstall -g ${o}`,{stdio:"inherit"}),console.log(`
38
38
  ${l.green("\u2713")} ${o} uninstalled successfully`);}catch(n){console.error(`
39
- ${l.red("\u2717")} Uninstallation failed: ${n.message}`),process.exit(1);}});var _o=new Command("dashboard").description("Start DevFlow Dashboard").option("-p, --port <port>","Port to run on","17788").option("--force","Force re-download Dashboard").action(async e=>{try{console.log(l.blue("Preparing Dashboard..."));let o=await N({force:e.force}),n=join(o,"server.js");existsSync(n)||(console.error(l.red(`Dashboard server.js not found at: ${n}
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
40
  The downloaded archive may be corrupted. Try: devflow dashboard --force`)),process.exit(1)),console.log(l.green(`
41
41
  Starting Dashboard: http://localhost:${e.port}
42
- `));let t=spawn("node",[n],{stdio:"inherit",env:{...process.env,PORT:e.port}});t.on("error",r=>{console.error(l.red("Failed to start Dashboard:"),r),process.exit(1);}),t.on("exit",r=>{process.exit(r||0);});}catch(o){console.error(l.red("Failed to start Dashboard:"),o.message),process.exit(1);}});var Ko=createRequire(import.meta.url),K="0.0.0";try{K=Ko("../package.json").version;}catch{try{K=Ko("../../package.json").version;}catch{}}var c=new Command;c.name("devflow").description("Developer Intelligence Platform for AI Coding Agents").version(K).option("--local","Force local engine, skip server");c.command("init").description("Initialize .devflow/ in the current project").option("--force","Overwrite existing config").option("--abort","Force delete .codegraph and .devflow directories before reinitializing").option("--report","Output onboarding markdown report to stdout").option("--json","Output onboarding pack as JSON to stdout").option("--plugins <names>","Comma-separated list of plugins to install (non-interactive)").option("--no-plugins","Skip plugin installation guide").action(async e=>{let o=process.cwd();if(e.abort){console.log(l.yellow("\u{1F5D1}\uFE0F --abort flag detected, removing existing directories..."));let r=[".codegraph",".devflow"];for(let s of r){let i=Ft.join(o,s);qo.existsSync(i)&&(console.log(l.dim(` Removing ${s}/...`)),qo.rmSync(i,{recursive:true,force:true}));}console.log(l.green(`\u2705 Existing directories removed
43
- `));}let n=z(o);console.error(l.blue(`DevFlow init \u2014 mode: ${n}`));let t=await oe(o,{force:e.force});if(e.json&&t.onboardingPack)console.log(JSON.stringify(t.onboardingPack,null,2));else if(e.report&&t.onboardingPack){let{renderInitReport:r}=await Promise.resolve().then(()=>(ne(),Me));console.log(r(t.onboardingPack));}else {if(t.created.length>0){console.log(l.green("Created:"));for(let r of t.created)console.log(` ${l.dim("+")} ${r}`);}else console.log(l.dim("Already initialized. Use --force to overwrite config."));if(t.indexed&&console.log(l.green(`\u2705 CodeGraph initialized (${t.indexed.files} files, ${t.indexed.symbols} symbols)`)),t.onboardingPack){let r=t.onboardingPack;console.log(l.green("\u2705 Onboarding pack generated")),console.log(l.dim(` ${r.stats.files} files, ${r.stack.frameworks.join(", ")||"no framework"}`));}t.pluginDeployed&&console.log(l.green("\u2705 Plugin deployed to ~/.claude/plugins/cache/")),t.pluginEnabled&&console.log(l.green("\u2705 Plugin enabled in ~/.claude/settings.json")),t.mcpConfigured&&console.log(l.green("\u2705 MCP config written to .claude/mcp.json")),t.pluginDeployed&&t.pluginEnabled&&t.mcpConfigured&&console.log(l.green("\nDevFlow is ready! Run `claude` to start.")),typeof e.plugins=="string"?await Ue(e.plugins):e.plugins!==false&&await We(o);}});c.command("connect [agent]").description("Configure MCP connection for AI coding agents").option("--command <cmd>","MCP server command","devflow-mcp").option("--sse <url>","SSE server URL (instead of stdio)").action(async(e,o)=>{let n=process.cwd(),t=z(n);if(console.log(l.blue(`DevFlow connect \u2014 mode: ${t}`)),e){let r=Je();r.includes(e)||(console.log(l.red(`Unknown agent: ${e}`)),console.log(`Available: ${r.join(", ")}`),process.exit(1));}try{let r=await L({agent:e,command:o.command,sseUrl:o.sse});for(let s of r)console.log(l.green(`\u2713 ${s}`));}catch(r){console.error(l.red(`Error: ${r.message}`)),process.exit(1);}});c.command("index").description("Show index status").option("--watch","Start file watcher for hot updates (stub)").action(async e=>{let o=await qe(c.opts().local);console.log(l.blue("Index Status")),console.log(` Files: ${o.totalFiles}`),console.log(` Symbols: ${o.totalSymbols}`),console.log(` Indexing: ${o.indexing?"active":"idle"}`),e.watch&&console.log(l.dim(" (watch mode not yet implemented)"));});c.command("graph [target]").description("Show dependency graph").option("--depth <n>","Expansion depth","2").action(async(e,o)=>{let n=await Ke({target:e,depth:parseInt(o.depth,10),skipServer:c.opts().local});console.log(l.blue("Dependency Graph")),console.log(` Nodes: ${n.nodes.length}`),console.log(` Edges: ${n.edges.length}`);});c.command("context <query>").description("Retrieve project context for a query").option("--mode <mode>","fast | deep","fast").option("--max-tokens <n>","Max token budget","4000").option("--task","Use task-oriented mode with risk hints and next actions").option("--why","Show reasoning for file selection").action(async(e,o)=>{if(o.task){let n=await Ve({query:e,mode:o.mode,maxTokens:parseInt(o.maxTokens,10),skipServer:c.opts().local});console.log(JSON.stringify({requiredFiles:n.requiredFiles,optionalFiles:n.optionalFiles,riskHints:n.riskHints,nextActions:n.nextActions,reasoning:o.why?n.reasoning:void 0},null,2));}else {let n=await Be({query:e,mode:o.mode,maxTokens:parseInt(o.maxTokens,10),skipServer:c.opts().local});console.log(l.blue(`Context: "${e}"`)),console.log(` Files: ${n.files.length}`),console.log(` Confidence: ${(n.confidence*100).toFixed(0)}%`),console.log(` Tokens: ${n.tokenCount}`);}});var H=c.command("workflow").description("Workflow management");H.command("list").description("List available workflows").action(async()=>{let e=await ze(c.opts().local);if(e.length===0){console.log(l.dim("No workflows registered."));return}for(let o of e)console.log(`${l.green(o.name)} \u2014 ${o.description} (${o.stepCount} steps)`);});H.command("run <type> [input]").description("Run a workflow").action(async(e,o)=>{let n=await Ye(e,{input:o??""},c.opts().local);console.log(`Run: ${n.runId}`),console.log(`Status: ${n.status}`),console.log(`Duration: ${n.duration}ms`);});H.command("status").description("Show running workflows").action(async()=>{let e=await Xe(c.opts().local);console.log(`${e.length} run(s)`);for(let o of e)console.log(` ${o.runId} \u2014 ${o.status}`);});H.command("runs").description("Show workflow history").action(async()=>{let e=await ie(c.opts().local);if(e.length===0){console.log(l.dim("No runs yet."));return}for(let o of e){let n=o.finishedAt?`${o.finishedAt-o.startedAt}ms`:"running";console.log(` ${o.runId} ${l.yellow(o.status)} ${n}`);}});var be=c.command("memory").description("Memory management");be.command("show").description("Show current project memory").action(async()=>{let e=await Qe(c.opts().local);console.log(JSON.stringify(e,null,2));});be.command("set <key> <value>").description("Set a memory key").action(async(e,o)=>{await Ze(e,o,c.opts().local),console.log(l.green(`Memory set: ${e} = ${o}`));});be.command("review").description("Review memory candidates").action(async()=>{let e=await eo(c.opts().local);console.log(JSON.stringify(e,null,2));});c.command("knowledge <query>").description("Search knowledge base").action(async e=>{let o=await oo(e,void 0,c.opts().local);console.log(l.blue(`Knowledge: "${e}"`)),console.log(` Results: ${o.length}`);for(let n of o.slice(0,5))console.log(` \u2014 ${n.title}`);});c.command("docs sync [plugin-name]").description("Sync documentation for plugins").action(async e=>{console.log(l.blue(`\u25C9 Syncing docs${e?` for ${e} plugin`:""}`));let o=new KnowledgeEngine({projectRoot:process.cwd()});if(e){let n=await o.syncDocs(e);for(let t of n)t.added>0?console.log(` ${l.green("\u2713")} ${t.source} \u2192 ${t.added} chunks`):console.log(` ${l.red("\u2717")} ${t.source} \u2014 ${t.errors.join(", ")||"no content"}`);console.log(l.green(`
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
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 B=c.command("skill").description("Plugin/Skill management");B.command("list").description("List installed skills").action(async()=>{let e=await ae(c.opts().local);if(e.length===0){console.log(l.dim("No skills installed. Use 'devflow skill search' to find plugins."));return}for(let o of e)console.log(` ${l.green(o.name)} @ ${o.version} \u2014 ${o.description}`);});B.command("search <query>").description("Search available plugins").action(async e=>{let o=await so(e,c.opts().local);if(console.log(l.blue(`Search: "${e}"`)),o.length===0){console.log(l.dim(" No matching plugins found."));return}for(let n of o)console.log(` ${l.green(n.name)} @ ${n.version} \u2014 ${n.description}`);});B.command("install <name>").description("Install a plugin/skill").action(async e=>{try{let o=await ao(e,process.cwd(),c.opts().local);console.log(l.green(`\u2713 Installed @devflow-tools/plugin-${o.name}@${o.version}`)),o.templates.length>0&&console.log(` Templates: ${o.templates.join(", ")}`);}catch(o){console.log(l.red(`Error: ${o.message}`)),process.exit(1);}});B.command("uninstall <name>").description("Uninstall a plugin/skill").action(async e=>{try{await co(e,process.cwd(),c.opts().local),console.log(l.green(`\u2713 Uninstalled ${e}`));}catch(o){console.log(l.red(`Error: ${o.message}`)),process.exit(1);}});c.command("doctor").description("Run project health check").option("--json","Output as JSON").option("--audit","Verify audit chain integrity").option("--audit-fix","Rebuild audit chain signatures").option("--violations","Show violation records").option("--last <period>","Filter violations by time (e.g. 7d, 24h)").option("--receipts","Show current session receipt status").action(async e=>{if(e.audit){let t=await fo();console.log(e.json?JSON.stringify(t):`Audit chain: ${t.valid?"VALID":`BROKEN at seq ${t.brokenAt}`} (${t.entryCount} entries)`);return}if(e.auditFix){let t=await wo();console.log(e.json?JSON.stringify(t):"Audit chain rebuilt.");return}if(e.violations){let t=await ho(e.last);console.log(e.json?JSON.stringify(t):JSON.stringify(t,null,2));return}if(e.receipts){let t=yo();e.json?console.log(JSON.stringify(t)):t.data?console.log(JSON.stringify(t.data,null,2)):console.log(`No active receipt found for session ${t.sessionId}.`);return}let o=await mo();if(e.json){console.log(JSON.stringify(o));return}if(console.log(l.blue(`DevFlow Doctor v${K}
46
- `)),console.log(l.bold("\u25C9 Index Status")),console.log(` Files ${o.index.totalFiles.toLocaleString()}`),console.log(` Symbols ${o.index.totalSymbols.toLocaleString()}`),console.log(` Graph (${o.graph.edges.toLocaleString()} edges)`),console.log(` Status ${o.index.indexing?"indexing":"idle"}`),console.log(),console.log(l.bold("\u25C9 Memory")),console.log(` Project ${o.memory.projectReady?"ready":"not set"}`),console.log(` Preferences ${o.memory.userPrefs} set`),console.log(),console.log(l.bold("\u25C9 Knowledge")),console.log(` Sources ${o.knowledge.sources}`),console.log(),console.log(l.bold("\u25C9 Server")),o.server.running?console.log(` ${l.green("\u2714")} Running on http://localhost:13337`):console.log(` ${l.yellow("\u25CB")} Not running \u2014 run \`devflow server start\` for telemetry`),console.log(),console.log(l.bold("\u25C9 Plugins")),o.plugins.installed===0)console.log(` ${l.dim("No plugins installed")}`);else for(let t of o.plugins.names)console.log(` ${t}`);console.log(),console.log(l.bold("\u25C9 Workflows")),console.log(` Registered ${o.workflows.registered}`),console.log();let n=o.readyScore>=70?l.green:o.readyScore>=40?l.yellow:l.red;console.log(`AI Ready: ${n(o.readyScore+"%")}`);});c.command("session token").description("Generate a session token for MCP Gateway authentication").option("--expires <seconds>","Token TTL in seconds","3600").action(async e=>{let o=await vo(process.cwd(),parseInt(e.expires,10));console.log(JSON.stringify(o,null,2));});c.command("benchmark [target]").description("Run benchmark on engines").option("--iterations <n>","Number of iterations","5").option("--output <format>","json | text","text").action(async(e,o)=>{let n=await bo(e??"all",{iterations:parseInt(o.iterations,10),output:o.output});console.log(n);});c.command("review [pr-url]").description("Review a PR or current branch diff").option("--agent <agent>","AI agent to use","claude").action(async(e,o)=>{let n=await ko({prUrl:e,agent:o.agent});console.log(n);});var Se=c.command("server").description("Manage DevFlow server");Se.command("start").description("Start the DevFlow REST server").option("--port <n>","Port number","13337").action(async e=>{console.log(l.blue("Starting DevFlow server..."));let o=await W({port:parseInt(e.port,10)});console.log(l.green(`Server started (pid: ${o.pid}) on port ${e.port}`));});Se.command("stop").description("Stop the DevFlow REST server").action(async()=>{let e=await I();console.log(e?l.green("Server stopped"):l.dim("No server running"));});Se.command("status").description("Show server status").action(async()=>{let e=await F();e.running?console.log(l.green(`Running (pid: ${e.pid})`)):console.log(l.yellow("Not running"));});c.addCommand(_o);c.command("start").description("Start DevFlow server and dashboard").option("--port <n>","Server port","13337").option("--dashboard-port <n>","Dashboard port","17788").option("--no-dashboard","Start server only, no dashboard").option("-d, --background","Run in background (detached)").action(async e=>{await Io({port:parseInt(e.port,10),dashboardPort:parseInt(e.dashboardPort,10),noDashboard:!e.dashboard,background:!!e.background});});c.command("stop").description("Stop DevFlow server and dashboard").action(async()=>{await Oo();});c.command("status").description("Show DevFlow services status").action(async()=>{await To();});c.command("setup").description("Configure Claude Code integration (MCP + plugin)").option("--agent <agent>","Target agent (claude/cursor/cline)").option("--skip-mcp","Skip MCP configuration").option("--skip-plugin","Skip plugin registration").action(async e=>{await Ao({agent:e.agent,skipMcp:!!e.skipMcp,skipPlugin:!!e.skipPlugin});});var V=c.command("plugin").description("Manage DevFlow plugins");V.addCommand(Mo);V.addCommand(Lo);V.addCommand(Wo);V.addCommand(Go);c.parse();
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();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@devflow-tools/claude-code-plugin",
3
3
  "description": "DevFlow — Developer Intelligence Platform: project context, code graph, knowledge base, memory engine, and workflow automation with 14 domain plugins",
4
- "version": "0.8.0",
4
+ "version": "0.8.1",
5
5
  "author": {
6
6
  "name": "DevFlow"
7
7
  },
package/dist/server.js CHANGED
@@ -1,10 +1,10 @@
1
- import'reflect-metadata';import {Reflector,APP_GUARD,APP_INTERCEPTOR,NestFactory}from'@nestjs/core';import {FastifyAdapter}from'@nestjs/platform-fastify';import {Injectable,Inject,Global,Module,Optional,Get,Query,Param,Post,Body,Delete,Controller,Headers,Res,Put,Catch,UnauthorizedException,NotFoundException,BadRequestException,SetMetadata,Logger,HttpException,HttpStatus}from'@nestjs/common';import {existsSync,readFileSync}from'fs';import {join}from'path';import {createEngines}from'@devflow-tools/context-engine';import {TelemetryEngine}from'@devflow-tools/telemetry';import {WorkflowEngine}from'@devflow-tools/workflow-engine';import {loadPlugins}from'@devflow-tools/sdk';import {Subject}from'rxjs';import {KnowledgeEngine}from'@devflow-tools/knowledge-engine';import {BenchmarkEngine}from'@devflow-tools/benchmark';import {DevFlowDatabase}from'@devflow-tools/database';import {map}from'rxjs/operators';var be=Object.defineProperty;var Pe=Object.getOwnPropertyDescriptor;var i=(c,t,e,r)=>{for(var s=r>1?void 0:r?Pe(t,e):t,n=c.length-1,a;n>=0;n--)(a=c[n])&&(s=(r?a(t,e,s):a(s))||s);return r&&s&&be(t,e,s),s},o=(c,t)=>(e,r)=>t(e,r,c);var Tt="isPublic",Qt=()=>SetMetadata(Tt,true);var At={MISSING_API_KEY:"AUTH_MISSING_API_KEY",INVALID_API_KEY:"AUTH_INVALID_API_KEY"};var Ie=(process.env.DEVFLOW_API_KEYS??"dev-key-000000").split(",").map(c=>c.trim()).filter(Boolean),V=class{constructor(t){this.reflector=t;}canActivate(t){if(this.reflector.getAllAndOverride(Tt,[t.getHandler(),t.getClass()]))return true;let s=t.switchToHttp().getRequest().headers["x-api-key"];if(!s)throw new UnauthorizedException({error:{code:At.MISSING_API_KEY,message:"X-API-Key header is required",details:{}}});if(!Ie.includes(s))throw new UnauthorizedException({error:{code:At.INVALID_API_KEY,message:"Invalid API key",details:{}}});return true}};V=i([Injectable(),o(0,Inject(Reflector))],V);var X=class{};X=i([Global(),Module({providers:[V,{provide:APP_GUARD,useClass:V}]})],X);var f={WORKFLOW_NOT_FOUND:"WORKFLOW_NOT_FOUND",RUN_NOT_FOUND:"RUN_NOT_FOUND",MEMORY_KEY_NOT_FOUND:"MEMORY_KEY_NOT_FOUND",PROJECT_NOT_FOUND:"PROJECT_NOT_FOUND",NODE_NOT_FOUND:"NODE_NOT_FOUND",PLUGIN_NOT_FOUND:"PLUGIN_NOT_FOUND",INTERNAL_ERROR:"INTERNAL_ERROR"};var y=class{constructor(t){this.database=t;this.projects=new Map;this.activeProjectRoot=process.env.DEVFLOW_PROJECT_ROOT??null;}onModuleInit(){if(!process.env.DEVFLOW_PROJECT_ROOT&&this.database){let t=this.database.getSetting("activeProjectRoot");t&&(this.activeProjectRoot=t);}}setActiveProject(t){this.activeProjectRoot=t,this.database&&this.database.setSetting("activeProjectRoot",t);}disconnectProject(){this.activeProjectRoot=null,this.database&&this.database.deleteSetting("activeProjectRoot");}getActiveProjectRoot(){return this.activeProjectRoot}async list(){return Array.from(this.projects.values())}async getById(t){let e=this.projects.get(t);if(!e)throw new NotFoundException({error:{code:f.PROJECT_NOT_FOUND,message:`Project "${t}" not found`,details:{}}});return e}async create(t){let e=`proj_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,r={id:e,name:t.name,rootPath:t.rootPath,stack:t.stack,createdAt:Date.now()};return this.projects.set(e,r),this.activeProjectRoot||this.setActiveProject(t.rootPath),r}async delete(t){if(!this.projects.has(t))throw new NotFoundException({error:{code:f.PROJECT_NOT_FOUND,message:`Project "${t}" not found`,details:{}}});this.projects.delete(t);}async getOnboardingPack(t){let e=join(t,".devflow","onboarding-pack.json");if(!existsSync(e))throw new NotFoundException({error:{code:f.PROJECT_NOT_FOUND,message:"Onboarding pack not found. Run `devflow init` first.",details:{}}});return JSON.parse(readFileSync(e,"utf-8"))}async getOnboardingPackByRoot(t){let e=join(t,".devflow","onboarding-pack.json");try{return existsSync(e)?JSON.parse(readFileSync(e,"utf-8")):null}catch{return null}}};y=i([Injectable(),o(0,Optional()),o(0,Inject("DATABASE"))],y);var b=class{constructor(t){this.service=t;}async list(){return this.service.list()}async getOnboardingPackByRoot(t){if(!t)throw new BadRequestException("rootPath is required");return this.service.getOnboardingPackByRoot(t)}async getById(t){return this.service.getById(t)}async getOnboardingPack(t){let e=await this.service.getById(t);return this.service.getOnboardingPack(e.rootPath)}async create(t){return this.service.create(t)}async connect(t){return this.service.setActiveProject(t.rootPath),{rootPath:t.rootPath}}async switchProject(t){return this.service.setActiveProject(t.rootPath),{rootPath:t.rootPath}}async getActive(){return {rootPath:this.service.getActiveProjectRoot()}}async disconnect(){return this.service.disconnectProject(),{ok:true}}async delete(t){return this.service.delete(t)}};i([Get()],b.prototype,"list",1),i([Get("onboarding-pack"),o(0,Query("rootPath"))],b.prototype,"getOnboardingPackByRoot",1),i([Get(":id"),o(0,Param("id"))],b.prototype,"getById",1),i([Get(":id/onboarding-pack"),o(0,Param("id"))],b.prototype,"getOnboardingPack",1),i([Post(),o(0,Body())],b.prototype,"create",1),i([Post("connect"),o(0,Body())],b.prototype,"connect",1),i([Post("switch"),o(0,Body())],b.prototype,"switchProject",1),i([Get("active")],b.prototype,"getActive",1),i([Delete("active")],b.prototype,"disconnect",1),i([Delete(":id"),o(0,Param("id"))],b.prototype,"delete",1),b=i([Controller("projects"),o(0,Inject(y))],b);var P=class{};P=i([Module({controllers:[b],providers:[y],exports:[y]})],P);var S=class{constructor(t){this.engine=new TelemetryEngine;this.db=t??null;}async recordEvent(t){await this.engine.recordEvent(t);}async listRuns(t,e,r){let s=Array.from(this.engine.runs.values()),n=s;return r&&(n=s.filter(a=>a.meta?.source===r)),n.slice(e,e+t).map(a=>({id:a.meta?.runId??"",agent:a.meta?.agent??"",mode:a.meta?.mode??"",source:a.meta?.source??"unknown",status:a.status,startedAt:a.startedAt,tokenUsed:a.tokenUsed}))}async getRun(t){let e=this.engine.runs.get(t);if(!e)throw new NotFoundException({error:{code:f.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});return e}async getTimeline(t,e){return Array.from(this.engine.runs.values()).filter(s=>!(t&&s.startedAt<Number(t)||e&&s.startedAt>Number(e))).flatMap(s=>s.steps?.map(n=>({runId:s.meta?.runId,stepId:n.stepId,type:n.type,duration:n.duration,timestamp:n.timestamp}))??[])}async getRunEvents(t){return this.engine.listEvents(t)}async getRunStats(t){return this.engine.getRunStats(t)}async getFeedbackStats(t,e){let r=this.collectAllEvents(),s=e!=null?Date.now()-e*24*60*60*1e3:void 0,n=r.filter(m=>!(m.data?.toolName!=="context_feedback"||t&&m.data?.toolInput?.projectRoot!==t||s!=null&&(m.timestamp??0)<s)),a=n.length,u=n.filter(m=>m.data?.toolInput?.feedback==="hit").length,l=n.filter(m=>m.data?.toolInput?.feedback==="partial").length,g=n.filter(m=>m.data?.toolInput?.feedback==="miss").length;return {total:a,hits:u,partials:l,misses:g,hitRate:a>0?u/a:0,partialRate:a>0?l/a:0,missRate:a>0?g/a:0}}collectAllEvents(){let t=this.engine.events;if(!t)return [];let e=[];for(let r of t.values())Array.isArray(r)&&e.push(...r);return e}async getStats(t=7){let e=Array.from(this.engine.runs.values()),r=Date.now(),s=r-t*24*60*60*1e3,n=e.filter(p=>p.startedAt>=s),a={};for(let p of n){let R=new Date(p.startedAt).toISOString().slice(0,10);a[R]||(a[R]={runs:0,tokens:0}),a[R].runs++,a[R].tokens+=p.tokenUsed??0;}let u=0,l=0,g=0;for(let p of n){let R=this.engine.events.get(p.meta?.runId)??[];u+=p.tokenUsed??0,l+=R.filter(K=>K.kind==="llm_call").length,g+=R.filter(K=>K.kind==="tool_use").length;}let m=new Date(s).toISOString().slice(0,10),I=new Date(r).toISOString().slice(0,10);return {period:{from:m,to:I},summary:{totalRuns:n.length,completedRuns:n.filter(p=>p.status==="completed").length,failedRuns:n.filter(p=>p.status==="failed").length,totalTokens:u,totalLlmCalls:l,totalToolUses:g,avgRunDuration:n.length>0?Math.round(n.reduce((p,R)=>p+((R.finishedAt??r)-R.startedAt),0)/n.length):0},byDay:Object.entries(a).map(([p,R])=>({date:p,...R})).sort((p,R)=>p.date.localeCompare(R.date)),byWorkflow:this.buildWorkflowBreakdown(n,r),byPlugin:this.buildPluginBreakdown(n)}}buildWorkflowBreakdown(t,e){let r={};for(let s of t){let n=s.workflowName??s.meta?.workflowName??"unknown";r[n]||(r[n]={runs:0,completed:0,failed:0,avgDuration:0}),r[n].runs++,s.status==="completed"?r[n].completed++:r[n].failed++,r[n].avgDuration+=(s.finishedAt??e)-s.startedAt;}for(let s of Object.keys(r))r[s].avgDuration=r[s].runs>0?Math.round(r[s].avgDuration/r[s].runs):0;return Object.entries(r).map(([s,n])=>({name:s,runs:n.runs,successRate:n.runs>0?n.completed/n.runs:0,avgDuration:n.avgDuration}))}buildPluginBreakdown(t){let e={};for(let r of t){let s=r.pluginName??r.meta?.pluginName??"none";e[s]||(e[s]={runs:0,completed:0,failed:0}),e[s].runs++,r.status==="completed"?e[s].completed++:e[s].failed++;}return Object.entries(e).map(([r,s])=>({name:r,runs:s.runs,successRate:s.runs>0?s.completed/s.runs:0}))}async getOpsRoiSummary(){let t=Array.from(this.engine.runs.values()),e=Date.now(),r=t.length,s=t.filter(k=>k.status==="completed").length,n=r>0?s/r:0,a=t.reduce((k,J)=>k+(J.tokenUsed??0),0),u=r>0?a/r:0,l=t.reduce((k,J)=>{let jt=J.startedAt??0,Nt=J.finishedAt??e;return k+(Nt-jt)},0),g=r>0?l/r:0,m=t.filter(k=>k.relevanceFeedback==="hit"||k.meta?.relevanceFeedback==="hit").length,I=t.filter(k=>k.relevanceFeedback!==void 0||k.meta?.relevanceFeedback!==void 0).length,p=await this.getFeedbackStats(),R=m+p.hits,K=I+p.total,Rt=K>0?R/K:0;return {period:"all-time",totalRuns:r,successfulRuns:s,successRate:n,avgTokenUsage:u,avgDuration:g,feedbackHitRate:Rt,trend:"stable"}}async getExperimentalRoiSummary(){return {totalScenarios:0,avgTimeSavedRate:0,avgTokenReductionRate:0,avgFirstPassLift:0,avgReworkReductionRate:0,conclusion:"No experimental data available yet"}}async getRoiSummary(t=7){let e=Array.from(this.engine.runs.values()),r=Date.now(),s=r-t*24*60*60*1e3,n=e.filter(d=>d.startedAt>=s),a=n.length,u=n.filter(d=>d.status==="completed").length,l=n.filter(d=>d.status!=="completed").length,g=a>0?Math.round(n.reduce((d,h)=>d+((h.finishedAt??r)-h.startedAt),0)/a):0,m=a>0?Math.round(n.reduce((d,h)=>d+(h.tokenUsed??0),0)/a):0,I=n.filter(d=>d.firstPassSuccess===true||d.meta?.firstPassSuccess===true).length,p=a>0?I/a:0,R=n.filter(d=>d.relevanceFeedback==="hit"||d.meta?.relevanceFeedback==="hit").length,K=n.filter(d=>d.relevanceFeedback!==void 0||d.meta?.relevanceFeedback!==void 0).length,Rt=await this.getFeedbackStats(void 0,t),k=R+Rt.hits,J=K+Rt.total,jt=J>0?k/J:0,Nt=n.reduce((d,h)=>d+(h.retryCount??h.meta?.retryCount??0),0),ye=a>0?Nt/a:0,Re=g,mt={context_insufficient:0,knowledge_missing:0,workflow_design_issue:0,tool_error:0,agent_override:0,unknown:0};for(let d of n)if(d.status!=="completed"){let h=d.meta?.runId;if(h)try{let Vt=await this.engine.classifyFailure(h);mt[Vt]=(mt[Vt]??0)+1;}catch{mt.unknown++;}else mt.unknown++;}let z={};for(let d of n){let h=new Date(d.startedAt).toISOString().slice(0,10);z[h]||(z[h]={runs:0,tokens:0,failures:0}),z[h].runs++,z[h].tokens+=d.tokenUsed??0,d.status!=="completed"&&z[h].failures++;}return {period:{from:new Date(s).toISOString().slice(0,10),to:new Date(r).toISOString().slice(0,10)},overview:{totalRuns:a,completedRuns:u,failedRuns:l,avgDuration:g,avgTokens:m,firstPassSuccessRate:p,feedbackHitRate:jt},efficiency:{totalTokensSaved:0,avgTimePerTask:Re,avgRetryCount:ye},failures:{total:l,breakdown:mt},workflows:this.buildWorkflowBreakdown(n,r),plugins:this.buildPluginBreakdown(n),byDay:Object.entries(z).map(([d,h])=>({date:d,...h})).sort((d,h)=>d.date.localeCompare(h.date))}}async getPluginEffectiveness(t,e){await this.getPluginUsageStats(t);let n=Array.from(this.engine.runs.values()).filter(g=>!((g.pluginName??g.meta?.pluginName)!==t||e&&g.meta?.projectRoot!==e)),a=n.length,u=n.filter(g=>g.status==="completed").length,l=a>0?n.reduce((g,m)=>g+((m.finishedAt??Date.now())-m.startedAt),0)/a:0;return {name:t,installCount:1,activeRate:a>0?1:0,successRate:a>0?u/a:0,avgTokenImpact:-l*.1,lastUsedAt:n.length>0?new Date(Math.max(...n.map(g=>g.startedAt))).toISOString():void 0,recommendation:this.getRecommendation(a>0?u/a:0,a)}}async getPluginUsageStats(t){let r=Array.from(this.engine.runs.values()).filter(m=>(m.pluginName??m.meta?.pluginName)===t),s=r.length,n=r.filter(m=>m.status==="completed").length,a=new Set;for(let m of r){let I=m.meta?.projectRoot;I&&a.add(I);}let u=s>0?r.reduce((m,I)=>m+((I.finishedAt??Date.now())-I.startedAt),0)/s:0,l=r.map(m=>m.startedAt).filter(m=>typeof m=="number"),g=l.length>0?new Date(Math.max(...l)).toISOString():void 0;return {activeProjects:a.size,totalRuns:s,successfulRuns:n,avgTokenImpact:-u*.1,lastUsedAt:g}}getRecommendation(t,e){return e===0?"remove":t>.8?"install":t>.5?"optimize":"remove"}async classifyFailure(t){let e=await this.getRun(t).catch(()=>null);if(!e||e.status!=="failed")return {};let r=e.steps?.find(n=>n.status==="failed");if(!r)return {};let s=r.error?.toLowerCase()??"";return s.includes("context")||s.includes("insufficient")?{failureCategory:"context_insufficient",failureReason:"Context provided was insufficient for the task",suggestedActions:[{action:"Supplement task context",priority:"high"},{action:"View graph roots",priority:"medium"},{action:"Add related memory",priority:"medium"}]}:s.includes("knowledge")||s.includes("docs")?{failureCategory:"knowledge_missing",failureReason:"Required knowledge was not available",suggestedActions:[{action:"Sync knowledge source",priority:"high"},{action:"Add docs source",priority:"medium"}]}:s.includes("workflow")||s.includes("step")?{failureCategory:"workflow_design_issue",failureReason:"Workflow design issue detected",suggestedActions:[{action:"Adjust specific step",priority:"high"},{action:"Split workflow",priority:"medium"}]}:s.includes("tool")||s.includes("connection")?{failureCategory:"tool_error",failureReason:"Tool execution error",suggestedActions:[{action:"Check tool connectivity",priority:"high"},{action:"Retry or fallback",priority:"medium"}]}:{failureCategory:"agent_override",failureReason:"Agent override detected",suggestedActions:[{action:"Enable/strengthen enforcer",priority:"high"}]}}async cleanup(t){let e=this.engine.runs,r=Date.now()-t*24*60*60*1e3,s=0;for(let[n,a]of e)a.startedAt&&a.startedAt<r&&(e.delete(n),s++);return s}async recordExecutionStart(t){this.db&&this.db.insertSkillExecution({executionId:t.executionId,skillName:t.skillName,startedAt:t.startedAt,status:"running"});}async recordToolCall(t){this.db&&this.db.insertToolCallEvent({eventId:t.eventId,executionId:t.executionId,timestamp:t.timestamp,toolName:t.toolName,toolType:t.toolType,isMcpTool:t.isMcpTool,mcpToolName:t.mcpToolName,mcpEnforced:t.mcpEnforced,mcpFallback:t.mcpFallback,input:t.input,tokensUsed:t.tokensUsed,duration:t.duration,parentToolCallId:t.parentToolCallId,subagentId:t.subagentId,error:t.error,blocked:t.blocked,blockReason:t.blockReason});}async recordExecutionComplete(t){this.db&&this.db.updateSkillExecution(t.executionId,{status:t.status,finishedAt:t.finishedAt,totalDuration:t.summary.totalDuration,totalTokens:t.summary.totalTokens,mcpComplianceRate:t.summary.mcpComplianceRate});}async getExecutions(t,e){return this.db?this.db.listSkillExecutions(t,e):[]}async getExecutionEvents(t){return this.db?this.db.listToolCallEvents(t):[]}async getMcpCompliance(){return this.db?this.db.getMcpCompliance():{overall:0,bySkill:{},missedTools:[]}}};S=i([Injectable(),o(0,Optional()),o(0,Inject("DATABASE"))],S);var N=class{constructor(t,e){this.telemetryService=t;this.database=e;this.projectStats=new Map;this.benchmarkResults=[];}async recordTelemetryEvent(t){let e=`evt_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,r=t.toolName?"tool_use":"step_end",s={id:e,runId:t.metadata?.runId??`event_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,stepId:e,kind:r,timestamp:Date.now(),duration:t.durationMs,data:{toolName:t.toolName,toolInput:t.args,errorMessage:t.error},metadata:{source:"claude-code"}};return await this.telemetryService.recordEvent(s),{eventId:e}}async getProjectStats(t){return this.database?this.database.getProjectStats(t):this.projectStats.get(t)??null}async updateProjectStats(t,e){if(this.database){let a={...await this.getProjectStats(t)??{projectRoot:t,totalRuns:0,successfulRuns:0,totalTokens:0,lastActiveAt:Date.now(),topTools:[]},...e,lastActiveAt:Date.now()};return await this.database.upsertProjectStats(a),a}let s={...this.projectStats.get(t)??{projectRoot:t,totalRuns:0,successfulRuns:0,totalTokens:0,lastActiveAt:Date.now(),topTools:[]},...e,lastActiveAt:Date.now()};return this.projectStats.set(t,s),s}recordBenchmarkResult(t){this.benchmarkResults.push(t);}getBenchmarkResults(t){return t?this.benchmarkResults.filter(e=>this.projectStats.get(e.scenarioId)?.projectRoot===t):this.benchmarkResults}async getPluginEffectiveness(t){return []}};N=i([Injectable(),o(0,Inject(S)),o(1,Optional()),o(1,Inject("DATABASE"))],N);var F=class{constructor(t){this.dataService=t;this.feedbackEntries=[];}async indexProject(t){let{context:e,codegraph:r}=await createEngines(t);await e.index(t);let s=r.getStats();return {totalFiles:s.fileCount,totalSymbols:s.nodeCount,lastIndexTime:s.lastUpdated,indexing:r.isIndexing()}}async getStatus(t){try{let{codegraph:e}=await createEngines(t),r=e.getStats();return {totalFiles:r.fileCount,totalSymbols:r.nodeCount,lastIndexTime:r.lastUpdated,indexing:e.isIndexing()}}catch{return {totalFiles:0,totalSymbols:0,lastIndexTime:0,indexing:false}}}async buildContext(t,e,r,s){let{context:n}=await createEngines(t);return n.build({query:e,mode:r,maxTokens:s??8e3,includeGraph:r==="deep"})}async buildTaskContext(t,e,r,s){let{context:n}=await createEngines(t);return n.buildTaskContext(e,{mode:r,maxTokens:s??8e3})}async findSymbol(t,e){let{indexer:r}=await createEngines(t);return r.findSymbol(e)}async recordFeedback(t,e,r,s){let n={query:e,feedback:r,timestamp:Date.now(),projectRoot:t};return this.feedbackEntries.push(n),this.dataService&&await this.dataService.recordTelemetryEvent({toolName:"context_feedback",args:{query:e,feedback:r,taskType:s?.taskType,contextMode:s?.contextMode,projectRoot:t},durationMs:0,success:true,metadata:{projectRoot:t,query:e,taskType:s?.taskType}}),n}async getFeedbackSummaries(){let t=this.feedbackEntries.length,e=this.feedbackEntries.filter(n=>n.feedback==="hit").length,r=this.feedbackEntries.filter(n=>n.feedback==="partial").length,s=this.feedbackEntries.filter(n=>n.feedback==="miss").length;return {total:t,hits:e,partials:r,misses:s,hitRate:t>0?e/t:0}}};F=i([Injectable(),o(0,Optional()),o(0,Inject(N))],F);var x=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let r=t??e??this.projects.getActiveProjectRoot();if(!r)throw new BadRequestException("rootPath is required \u2014 no active project connected");return r}async status(t,e){return this.service.getStatus(this.resolveRootPath(t,e))}async index(t,e){return this.service.indexProject(this.resolveRootPath(t.rootPath,e))}async build(t,e){return this.service.buildContext(this.resolveRootPath(t.rootPath,e),t.query,t.mode??"fast",t.maxTokens)}async buildTask(t,e){return this.service.buildTaskContext(this.resolveRootPath(t.rootPath,e),t.query,t.mode??"fast",t.maxTokens)}async feedback(t,e){return this.service.recordFeedback(this.resolveRootPath(t.rootPath,e),t.query,t.feedback,{taskType:t.taskType,contextMode:t.contextMode,runId:t.runId,tokenCount:t.tokenCount})}async feedbackSummary(){return this.service.getFeedbackSummaries()}async findSymbol(t,e,r){return this.service.findSymbol(this.resolveRootPath(e,r),t)}};i([Get("status"),o(0,Query("rootPath")),o(1,Headers("x-devflow-project"))],x.prototype,"status",1),i([Post("index"),o(0,Body()),o(1,Headers("x-devflow-project"))],x.prototype,"index",1),i([Post("build"),o(0,Body()),o(1,Headers("x-devflow-project"))],x.prototype,"build",1),i([Post("build-task"),o(0,Body()),o(1,Headers("x-devflow-project"))],x.prototype,"buildTask",1),i([Post("feedback"),o(0,Body()),o(1,Headers("x-devflow-project"))],x.prototype,"feedback",1),i([Get("feedback-summary")],x.prototype,"feedbackSummary",1),i([Get("symbol/:name"),o(0,Param("name")),o(1,Query("rootPath")),o(2,Headers("x-devflow-project"))],x.prototype,"findSymbol",1),x=i([Controller("context"),o(0,Inject(F)),o(1,Inject(y))],x);var T=class{constructor(t){this.dataService=t;}async recordTelemetryEvent(t){return {success:true,...await this.dataService.recordTelemetryEvent(t)}}async getProjectStats(t){return this.dataService.getProjectStats(t)}async updateProjectStats(t){return this.dataService.updateProjectStats(t.projectRoot,t.stats)}recordBenchmarkResult(t){return this.dataService.recordBenchmarkResult(t),{success:true}}getBenchmarkResults(t){return this.dataService.getBenchmarkResults(t)}};i([Post("telemetry/event"),o(0,Body())],T.prototype,"recordTelemetryEvent",1),i([Get("project/stats"),o(0,Query("rootPath"))],T.prototype,"getProjectStats",1),i([Post("project/stats"),o(0,Body())],T.prototype,"updateProjectStats",1),i([Post("benchmark/result"),o(0,Body())],T.prototype,"recordBenchmarkResult",1),i([Get("benchmark/results"),o(0,Query("projectRoot"))],T.prototype,"getBenchmarkResults",1),T=i([Controller("data"),o(0,Inject(N))],T);var v=class{constructor(t){this.service=t;}async listRuns(t,e,r){return this.service.listRuns(Number(t)||20,Number(e)||0,r)}async getRun(t){let e=await this.service.getRun(t),r=await this.service.classifyFailure(t);return {...e,...r}}async getTimeline(t,e){return this.service.getTimeline(t,e)}async getRunEvents(t){return this.service.getRunEvents(t)}async getRunStats(t){return this.service.getRunStats(t)}async getStats(t){return this.service.getStats(Number(t)||7)}async getRoiSummary(t){return this.service.getRoiSummary(Number(t)||7)}async cleanup(t){return {ok:true,data:{removedRuns:await this.service.cleanup(t.olderThanDays??30)}}}async startSkillExecution(t){return await this.service.recordExecutionStart(t),{executionId:t.executionId}}async recordToolCall(t){return await this.service.recordToolCall(t),{eventId:t.eventId}}async completeSkillExecution(t){return await this.service.recordExecutionComplete(t),{}}async getExecutions(t,e){return {data:await this.service.getExecutions(Number(t)||20,e)}}async getExecutionEvents(t){return {data:await this.service.getExecutionEvents(t)}}async getMcpCompliance(){return await this.service.getMcpCompliance()}};i([Get("runs"),o(0,Query("limit")),o(1,Query("offset")),o(2,Query("source"))],v.prototype,"listRuns",1),i([Get("runs/:id"),o(0,Param("id"))],v.prototype,"getRun",1),i([Get("timeline"),o(0,Query("from")),o(1,Query("to"))],v.prototype,"getTimeline",1),i([Get("runs/:runId/events"),o(0,Param("runId"))],v.prototype,"getRunEvents",1),i([Get("runs/:runId/stats"),o(0,Param("runId"))],v.prototype,"getRunStats",1),i([Get("stats"),o(0,Query("days"))],v.prototype,"getStats",1),i([Get("roi-summary"),o(0,Query("days"))],v.prototype,"getRoiSummary",1),i([Post("cleanup"),o(0,Body())],v.prototype,"cleanup",1),i([Post("skill-execution/start"),o(0,Body())],v.prototype,"startSkillExecution",1),i([Post("tool-call"),o(0,Body())],v.prototype,"recordToolCall",1),i([Post("skill-execution/complete"),o(0,Body())],v.prototype,"completeSkillExecution",1),i([Get("executions"),o(0,Query("limit")),o(1,Query("skillName"))],v.prototype,"getExecutions",1),i([Get("executions/:id/events"),o(0,Param("id"))],v.prototype,"getExecutionEvents",1),i([Get("mcp-compliance")],v.prototype,"getMcpCompliance",1),v=i([Controller("telemetry"),o(0,Inject(S))],v);var _=class{};_=i([Module({controllers:[v],providers:[S],exports:[S]})],_);var Y=class{};Y=i([Module({imports:[_],controllers:[T],providers:[N],exports:[N]})],Y);var E=class{};E=i([Module({imports:[P,Y],controllers:[x],providers:[F],exports:[F]})],E);var U=class{async getFullGraph(t){let{graph:e}=await createEngines(t);return e.export()}async getLayeredGraph(t){let{graph:e}=await createEngines(t);return e.getLayeredGraph()}async getNode(t,e){let{codegraph:r}=await createEngines(t),s=r.getNode(e);if(!s)throw new NotFoundException({error:{code:f.NODE_NOT_FOUND,message:`Node "${e}" not found`,details:{}}});return s}async expandNode(t,e,r,s){let{graph:n}=await createEngines(t),a=n.expand([e],{depth:r,direction:s});return {node:a.nodes.find(u=>u.id===e),subGraph:a}}};U=i([Injectable()],U);var C=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let r=t??e??this.projects.getActiveProjectRoot();if(!r)throw new BadRequestException("rootPath is required \u2014 no active project connected");return r}async getFullGraph(t,e,r){return e==="layered"?this.service.getLayeredGraph(this.resolveRootPath(t,r)):this.service.getFullGraph(this.resolveRootPath(t,r))}async getNode(t,e,r){return this.service.getNode(this.resolveRootPath(t,r),e)}async expandNode(t,e,r,s,n){return this.service.expandNode(this.resolveRootPath(t,n),e,Number(r)||2,s||"both")}};i([Get(),o(0,Query("rootPath")),o(1,Query("view")),o(2,Headers("x-devflow-project"))],C.prototype,"getFullGraph",1),i([Get(":nodeId"),o(0,Query("rootPath")),o(1,Param("nodeId")),o(2,Headers("x-devflow-project"))],C.prototype,"getNode",1),i([Get(":nodeId/expand"),o(0,Query("rootPath")),o(1,Param("nodeId")),o(2,Query("depth")),o(3,Query("direction")),o(4,Headers("x-devflow-project"))],C.prototype,"expandNode",1),C=i([Controller("graph"),o(0,Inject(U)),o(1,Inject(y))],C);var et=class{};et=i([Module({imports:[E,P],controllers:[C],providers:[U],exports:[U]})],et);var B=class{constructor(){this.engine=new WorkflowEngine;this.events=new Map;this.engineRunIds=new Map;}async onModuleInit(){try{let t=await loadPlugins(),e=Array.from(t.values());for(let s of e)for(let n of s.workflow?.templates??[])this.engine.register(n);let r=await this.engine.list();console.log(`[WorkflowService] Loaded ${e.length} plugins with ${r.length} workflows`);}catch(t){console.error("[WorkflowService] Failed to load plugins:",t);}}async list(){return this.engine.list()}async run(t,e){if(!(await this.engine.list()).find(a=>a.name===t))throw new NotFoundException({error:{code:f.WORKFLOW_NOT_FOUND,message:`Workflow "${t}" not found`,details:{}}});let s=`run_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,n=new Subject;return this.events.set(s,n),this.engine.run(t,e).then(a=>{this.engineRunIds.set(s,a.runId);let u=this.engine.getRun(a.runId);if(u){for(let l of u.steps)n.next({runId:s,stepId:l.stepId,status:l.status==="success"?"completed":l.status==="failed"?"failed":"started",output:l.output,error:l.error,timestamp:Date.now()});a.status!=="running"&&n.complete();}a.status==="running"&&this.engine.onEvent(a.runId,l=>{n.next({runId:s,stepId:l.stepId,status:l.type==="step-done"?"completed":l.type==="step-error"?"failed":"started",output:"output"in l?l.output:void 0,error:"error"in l?l.error:void 0,timestamp:Date.now()});});}).catch(a=>{n.next({runId:s,stepId:"engine",status:"failed",error:a.message,timestamp:Date.now()}),n.complete();}),{runId:s}}async listRuns(t,e){return (await this.engine.listRuns()).map(n=>({runId:Array.from(this.engineRunIds.entries()).find(([,u])=>u===n.runId)?.[0]??n.runId,workflowName:n.type,status:n.status,steps:n.steps.map(u=>({stepId:u.stepId,status:u.status,output:u.output,error:u.error,startedAt:0})),startedAt:n.startedAt,finishedAt:n.finishedAt})).slice(e,e+t)}async getRun(t){let e=this.engineRunIds.get(t)??t,r=this.engine.getRun(e);if(!r)throw new NotFoundException({error:{code:f.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});return {runId:t,workflowName:r.type,status:r.status,steps:r.steps.map(s=>({stepId:s.stepId,status:s.status,output:s.output,error:s.error})),startedAt:r.startedAt,finishedAt:r.finishedAt}}streamRun(t){let e=this.events.get(t);if(!e)throw new NotFoundException({error:{code:f.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});return e}async approveRun(t){let e=this.engineRunIds.get(t)??t,r=this.engine.getRun(e);if(!r)throw new NotFoundException({error:{code:f.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});let s=r.steps.find(n=>n.status==="awaiting_approval");s&&await this.engine.approve(e,s.stepId);}async rejectRun(t,e){let r=this.engineRunIds.get(t)??t,s=this.engine.getRun(r);if(!s)throw new NotFoundException({error:{code:f.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});let n=s.steps.find(a=>a.status==="awaiting_approval");n&&await this.engine.reject(r,n.stepId,e??"Rejected");}async getNextStep(t){if(!t){(await this.engine.list())[0];return null}let e=this.engineRunIds.get(t)??t,r=this.engine.getRun(e);return r?(Array.isArray(r.steps)?r.steps:[]).find(n=>n.status==="pending")??null:null}};B=i([Injectable()],B);var w=class{constructor(t){this.service=t;}async list(){return this.service.list()}async run(t,e){return this.service.run(t,e.input??{})}async listRuns(t,e){return this.service.listRuns(Number(t)||20,Number(e)||0)}async getRun(t){return this.service.getRun(t)}async stream(t,e){e.raw.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let s=this.service.streamRun(t).subscribe({next:n=>{e.raw.write(`event: step-${n.status}
2
- data: ${JSON.stringify(n)}
1
+ import'reflect-metadata';import {Reflector,APP_GUARD,APP_INTERCEPTOR,NestFactory}from'@nestjs/core';import {FastifyAdapter}from'@nestjs/platform-fastify';import {Injectable,Inject,Global,Module,Optional,Get,Query,Param,Post,Body,Delete,Controller,Headers,Put,Res,Catch,UnauthorizedException,NotFoundException,BadRequestException,SetMetadata,Logger,HttpException,HttpStatus}from'@nestjs/common';import {existsSync,readFileSync}from'fs';import {join}from'path';import {createEngines}from'@devflow-tools/context-engine';import {TelemetryEngine}from'@devflow-tools/telemetry';import {MemoryEngine,checkOllama,getOllamaInfoMessage}from'@devflow-tools/memory-engine';import {WorkflowEngine}from'@devflow-tools/workflow-engine';import {loadPlugins}from'@devflow-tools/sdk';import {Subject}from'rxjs';import {KnowledgeEngine}from'@devflow-tools/knowledge-engine';import {BenchmarkEngine}from'@devflow-tools/benchmark';import {DevFlowDatabase}from'@devflow-tools/database';import {map}from'rxjs/operators';var Se=Object.defineProperty;var xe=Object.getOwnPropertyDescriptor;var i=(c,t,e,s)=>{for(var r=s>1?void 0:s?xe(t,e):t,o=c.length-1,a;o>=0;o--)(a=c[o])&&(r=(s?a(t,e,r):a(r))||r);return s&&r&&Se(t,e,r),r},n=(c,t)=>(e,s)=>t(e,s,c);var Nt="isPublic",Zt=()=>SetMetadata(Nt,true);var Ot={MISSING_API_KEY:"AUTH_MISSING_API_KEY",INVALID_API_KEY:"AUTH_INVALID_API_KEY"};var je=(process.env.DEVFLOW_API_KEYS??"dev-key-000000").split(",").map(c=>c.trim()).filter(Boolean),X=class{constructor(t){this.reflector=t;}canActivate(t){if(this.reflector.getAllAndOverride(Nt,[t.getHandler(),t.getClass()]))return true;let r=t.switchToHttp().getRequest().headers["x-api-key"];if(!r)throw new UnauthorizedException({error:{code:Ot.MISSING_API_KEY,message:"X-API-Key header is required",details:{}}});if(!je.includes(r))throw new UnauthorizedException({error:{code:Ot.INVALID_API_KEY,message:"Invalid API key",details:{}}});return true}};X=i([Injectable(),n(0,Inject(Reflector))],X);var et=class{};et=i([Global(),Module({providers:[X,{provide:APP_GUARD,useClass:X}]})],et);var b={WORKFLOW_NOT_FOUND:"WORKFLOW_NOT_FOUND",RUN_NOT_FOUND:"RUN_NOT_FOUND",PROJECT_NOT_FOUND:"PROJECT_NOT_FOUND",NODE_NOT_FOUND:"NODE_NOT_FOUND",PLUGIN_NOT_FOUND:"PLUGIN_NOT_FOUND",INTERNAL_ERROR:"INTERNAL_ERROR"};var h=class{constructor(t){this.database=t;this.projects=new Map;this.activeProjectRoot=process.env.DEVFLOW_PROJECT_ROOT??null;}onModuleInit(){if(!process.env.DEVFLOW_PROJECT_ROOT&&this.database){let t=this.database.getSetting("activeProjectRoot");t&&(this.activeProjectRoot=t);}}setActiveProject(t){this.activeProjectRoot=t,this.database&&this.database.setSetting("activeProjectRoot",t);}disconnectProject(){this.activeProjectRoot=null,this.database&&this.database.deleteSetting("activeProjectRoot");}getActiveProjectRoot(){return this.activeProjectRoot}async list(){return Array.from(this.projects.values())}async getById(t){let e=this.projects.get(t);if(!e)throw new NotFoundException({error:{code:b.PROJECT_NOT_FOUND,message:`Project "${t}" not found`,details:{}}});return e}async create(t){let e=`proj_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,s={id:e,name:t.name,rootPath:t.rootPath,stack:t.stack,createdAt:Date.now()};return this.projects.set(e,s),this.activeProjectRoot||this.setActiveProject(t.rootPath),s}async delete(t){if(!this.projects.has(t))throw new NotFoundException({error:{code:b.PROJECT_NOT_FOUND,message:`Project "${t}" not found`,details:{}}});this.projects.delete(t);}async getOnboardingPack(t){let e=join(t,".devflow","onboarding-pack.json");if(!existsSync(e))throw new NotFoundException({error:{code:b.PROJECT_NOT_FOUND,message:"Onboarding pack not found. Run `devflow init` first.",details:{}}});return JSON.parse(readFileSync(e,"utf-8"))}async getOnboardingPackByRoot(t){let e=join(t,".devflow","onboarding-pack.json");try{return existsSync(e)?JSON.parse(readFileSync(e,"utf-8")):null}catch{return null}}};h=i([Injectable(),n(0,Optional()),n(0,Inject("DATABASE"))],h);var P=class{constructor(t){this.service=t;}async list(){return this.service.list()}async getOnboardingPackByRoot(t){if(!t)throw new BadRequestException("rootPath is required");return this.service.getOnboardingPackByRoot(t)}async getById(t){return this.service.getById(t)}async getOnboardingPack(t){let e=await this.service.getById(t);return this.service.getOnboardingPack(e.rootPath)}async create(t){return this.service.create(t)}async connect(t){return this.service.setActiveProject(t.rootPath),{rootPath:t.rootPath}}async switchProject(t){return this.service.setActiveProject(t.rootPath),{rootPath:t.rootPath}}async getActive(){return {rootPath:this.service.getActiveProjectRoot()}}async disconnect(){return this.service.disconnectProject(),{ok:true}}async delete(t){return this.service.delete(t)}};i([Get()],P.prototype,"list",1),i([Get("onboarding-pack"),n(0,Query("rootPath"))],P.prototype,"getOnboardingPackByRoot",1),i([Get(":id"),n(0,Param("id"))],P.prototype,"getById",1),i([Get(":id/onboarding-pack"),n(0,Param("id"))],P.prototype,"getOnboardingPack",1),i([Post(),n(0,Body())],P.prototype,"create",1),i([Post("connect"),n(0,Body())],P.prototype,"connect",1),i([Post("switch"),n(0,Body())],P.prototype,"switchProject",1),i([Get("active")],P.prototype,"getActive",1),i([Delete("active")],P.prototype,"disconnect",1),i([Delete(":id"),n(0,Param("id"))],P.prototype,"delete",1),P=i([Controller("projects"),n(0,Inject(h))],P);var w=class{};w=i([Module({controllers:[P],providers:[h],exports:[h]})],w);var E=class{constructor(t){this.engine=new TelemetryEngine;this.db=t??null;}async recordEvent(t){await this.engine.recordEvent(t);}async listRuns(t,e,s){let r=Array.from(this.engine.runs.values()),o=r;s&&(o=r.filter(u=>u.meta?.source===s));let a=o.slice(e,e+t).map(u=>({id:u.meta?.runId??"",agent:u.meta?.agent??"",mode:u.meta?.mode??"",source:u.meta?.source??"unknown",status:u.status,startedAt:u.startedAt,tokenUsed:u.tokenUsed}));if(this.db)try{let d=this.db.listSkillExecutions(t,0).map(p=>({id:p.executionId,agent:"claude-code",mode:"hook",source:"hook",status:p.status,startedAt:p.startedAt,tokenUsed:p.totalTokens,skillName:p.skillName,totalToolCalls:p.totalToolCalls,mcpToolCalls:p.mcpToolCalls,mcpComplianceRate:p.mcpComplianceRate})),g=new Set;return [...d,...a].filter(p=>g.has(p.id)?!1:(g.add(p.id),!0)).slice(e,e+t)}catch{}return a}async getRun(t){let e=this.engine.runs.get(t);if(e)return e;if(this.db)try{let s=this.db.getSkillExecution(t);if(s)return {meta:{runId:s.executionId,agent:"claude-code",mode:"hook",source:"hook"},status:s.status,startedAt:s.startedAt,finishedAt:s.finishedAt,tokenUsed:s.totalTokens,steps:[],skillName:s.skillName,totalToolCalls:s.totalToolCalls,mcpToolCalls:s.mcpToolCalls,directToolCalls:s.directToolCalls,mcpComplianceRate:s.mcpComplianceRate}}catch{}throw new NotFoundException({error:{code:b.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}})}async getTimeline(t,e){return Array.from(this.engine.runs.values()).filter(r=>!(t&&r.startedAt<Number(t)||e&&r.startedAt>Number(e))).flatMap(r=>r.steps?.map(o=>({runId:r.meta?.runId,stepId:o.stepId,type:o.type,duration:o.duration,timestamp:o.timestamp}))??[])}async getRunEvents(t){let e=await this.engine.listEvents(t);if(e&&e.length>0)return e;if(this.db)try{let s=this.db.listToolCallEvents(t);if(s&&s.length>0)return s.map(r=>({eventId:r.eventId,runId:t,stepId:r.eventId,type:r.isMcpTool?"mcp_tool":r.toolType==="subagent"?"subagent":"tool_use",timestamp:r.timestamp,duration:r.duration,toolName:r.toolName,toolType:r.toolType,isMcpTool:r.isMcpTool,mcpToolName:r.mcpToolName,mcpEnforced:r.mcpEnforced,mcpFallback:r.mcpFallback,tokensUsed:r.tokensUsed,blocked:r.blocked,blockReason:r.blockReason,error:r.error}))}catch{}return e??[]}async getRunStats(t){let e=await this.engine.getRunStats(t);if(e&&e.totalEvents>0)return e;if(this.db)try{let s=this.db.getSkillExecution(t),r=this.db.listToolCallEvents(t);if(s){let o=r?.reduce((a,u)=>a+(u.tokensUsed??0),0)??0;return {totalEvents:r?.length??0,llmCalls:0,totalTokens:s.totalTokens||o,toolUses:s.totalToolCalls,fileReads:0,fileWrites:0,bashCommands:0,errors:r?.filter(a=>a.error).length??0,totalDuration:s.totalDuration,mcpToolCalls:s.mcpToolCalls,directToolCalls:s.directToolCalls,mcpComplianceRate:s.mcpComplianceRate}}}catch{}return e}async endRun(t,e){await this.engine.endRun(t,e);}async getFeedbackStats(t,e){let s=this.collectAllEvents(),r=e!=null?Date.now()-e*24*60*60*1e3:void 0,o=s.filter(l=>!(l.data?.toolName!=="context_feedback"||t&&l.data?.toolInput?.projectRoot!==t||r!=null&&(l.timestamp??0)<r)),a=o.length,u=o.filter(l=>l.data?.toolInput?.feedback==="hit").length,d=o.filter(l=>l.data?.toolInput?.feedback==="partial").length,g=o.filter(l=>l.data?.toolInput?.feedback==="miss").length;return {total:a,hits:u,partials:d,misses:g,hitRate:a>0?u/a:0,partialRate:a>0?d/a:0,missRate:a>0?g/a:0}}collectAllEvents(){let t=this.engine.events;if(!t)return [];let e=[];for(let s of t.values())Array.isArray(s)&&e.push(...s);return e}async getStats(t=7){let e=Array.from(this.engine.runs.values()),s=Date.now(),r=s-t*24*60*60*1e3,o=e.filter(f=>f.startedAt>=r),a={};for(let f of o){let R=new Date(f.startedAt).toISOString().slice(0,10);a[R]||(a[R]={runs:0,tokens:0}),a[R].runs++,a[R].tokens+=f.tokenUsed??0;}let u=0,d=0,g=0;for(let f of o){let R=this.engine.events.get(f.meta?.runId)??[];u+=f.tokenUsed??0,d+=R.filter(Y=>Y.kind==="llm_call").length,g+=R.filter(Y=>Y.kind==="tool_use").length;}let l=new Date(r).toISOString().slice(0,10),p=new Date(s).toISOString().slice(0,10);return {period:{from:l,to:p},summary:{totalRuns:o.length,completedRuns:o.filter(f=>f.status==="completed").length,failedRuns:o.filter(f=>f.status==="failed").length,totalTokens:u,totalLlmCalls:d,totalToolUses:g,avgRunDuration:o.length>0?Math.round(o.reduce((f,R)=>f+((R.finishedAt??s)-R.startedAt),0)/o.length):0},byDay:Object.entries(a).map(([f,R])=>({date:f,...R})).sort((f,R)=>f.date.localeCompare(R.date)),byWorkflow:this.buildWorkflowBreakdown(o,s),byPlugin:this.buildPluginBreakdown(o)}}buildWorkflowBreakdown(t,e){let s={};for(let r of t){let o=r.workflowName??r.meta?.workflowName??"unknown";s[o]||(s[o]={runs:0,completed:0,failed:0,avgDuration:0}),s[o].runs++,r.status==="completed"?s[o].completed++:s[o].failed++,s[o].avgDuration+=(r.finishedAt??e)-r.startedAt;}for(let r of Object.keys(s))s[r].avgDuration=s[r].runs>0?Math.round(s[r].avgDuration/s[r].runs):0;return Object.entries(s).map(([r,o])=>({name:r,runs:o.runs,successRate:o.runs>0?o.completed/o.runs:0,avgDuration:o.avgDuration}))}buildPluginBreakdown(t){let e={};for(let s of t){let r=s.pluginName??s.meta?.pluginName??"none";e[r]||(e[r]={runs:0,completed:0,failed:0}),e[r].runs++,s.status==="completed"?e[r].completed++:e[r].failed++;}return Object.entries(e).map(([s,r])=>({name:s,runs:r.runs,successRate:r.runs>0?r.completed/r.runs:0}))}async getOpsRoiSummary(){let t=Array.from(this.engine.runs.values()),e=Date.now(),s=t.length,r=t.filter(x=>x.status==="completed").length,o=s>0?r/s:0,a=t.reduce((x,z)=>x+(z.tokenUsed??0),0),u=s>0?a/s:0,d=t.reduce((x,z)=>{let At=z.startedAt??0,jt=z.finishedAt??e;return x+(jt-At)},0),g=s>0?d/s:0,l=t.filter(x=>x.relevanceFeedback==="hit"||x.meta?.relevanceFeedback==="hit").length,p=t.filter(x=>x.relevanceFeedback!==void 0||x.meta?.relevanceFeedback!==void 0).length,f=await this.getFeedbackStats(),R=l+f.hits,Y=p+f.total,wt=Y>0?R/Y:0;return {period:"all-time",totalRuns:s,successfulRuns:r,successRate:o,avgTokenUsage:u,avgDuration:g,feedbackHitRate:wt,trend:"stable"}}async getExperimentalRoiSummary(){return {totalScenarios:0,avgTimeSavedRate:0,avgTokenReductionRate:0,avgFirstPassLift:0,avgReworkReductionRate:0,conclusion:"No experimental data available yet"}}async getRoiSummary(t=7){let e=Array.from(this.engine.runs.values()),s=Date.now(),r=s-t*24*60*60*1e3,o=e.filter(m=>m.startedAt>=r),a=o.length,u=o.filter(m=>m.status==="completed").length,d=o.filter(m=>m.status!=="completed").length,g=a>0?Math.round(o.reduce((m,v)=>m+((v.finishedAt??s)-v.startedAt),0)/a):0,l=a>0?Math.round(o.reduce((m,v)=>m+(v.tokenUsed??0),0)/a):0,p=o.filter(m=>m.firstPassSuccess===true||m.meta?.firstPassSuccess===true).length,f=a>0?p/a:0,R=o.filter(m=>m.relevanceFeedback==="hit"||m.meta?.relevanceFeedback==="hit").length,Y=o.filter(m=>m.relevanceFeedback!==void 0||m.meta?.relevanceFeedback!==void 0).length,wt=await this.getFeedbackStats(void 0,t),x=R+wt.hits,z=Y+wt.total,At=z>0?x/z:0,jt=o.reduce((m,v)=>m+(v.retryCount??v.meta?.retryCount??0),0),Pe=a>0?jt/a:0,we=g,gt={context_insufficient:0,knowledge_missing:0,workflow_design_issue:0,tool_error:0,agent_override:0,unknown:0};for(let m of o)if(m.status!=="completed"){let v=m.meta?.runId;if(v)try{let Xt=await this.engine.classifyFailure(v);gt[Xt]=(gt[Xt]??0)+1;}catch{gt.unknown++;}else gt.unknown++;}let tt={};for(let m of o){let v=new Date(m.startedAt).toISOString().slice(0,10);tt[v]||(tt[v]={runs:0,tokens:0,failures:0}),tt[v].runs++,tt[v].tokens+=m.tokenUsed??0,m.status!=="completed"&&tt[v].failures++;}return {period:{from:new Date(r).toISOString().slice(0,10),to:new Date(s).toISOString().slice(0,10)},overview:{totalRuns:a,completedRuns:u,failedRuns:d,avgDuration:g,avgTokens:l,firstPassSuccessRate:f,feedbackHitRate:At},efficiency:{totalTokensSaved:0,avgTimePerTask:we,avgRetryCount:Pe},failures:{total:d,breakdown:gt},workflows:this.buildWorkflowBreakdown(o,s),plugins:this.buildPluginBreakdown(o),byDay:Object.entries(tt).map(([m,v])=>({date:m,...v})).sort((m,v)=>m.date.localeCompare(v.date))}}async getPluginEffectiveness(t,e){await this.getPluginUsageStats(t);let o=Array.from(this.engine.runs.values()).filter(g=>!((g.pluginName??g.meta?.pluginName)!==t||e&&g.meta?.projectRoot!==e)),a=o.length,u=o.filter(g=>g.status==="completed").length,d=a>0?o.reduce((g,l)=>g+((l.finishedAt??Date.now())-l.startedAt),0)/a:0;return {name:t,installCount:1,activeRate:a>0?1:0,successRate:a>0?u/a:0,avgTokenImpact:-d*.1,lastUsedAt:o.length>0?new Date(Math.max(...o.map(g=>g.startedAt))).toISOString():void 0,recommendation:this.getRecommendation(a>0?u/a:0,a)}}async getPluginUsageStats(t){let s=Array.from(this.engine.runs.values()).filter(l=>(l.pluginName??l.meta?.pluginName)===t),r=s.length,o=s.filter(l=>l.status==="completed").length,a=new Set;for(let l of s){let p=l.meta?.projectRoot;p&&a.add(p);}let u=r>0?s.reduce((l,p)=>l+((p.finishedAt??Date.now())-p.startedAt),0)/r:0,d=s.map(l=>l.startedAt).filter(l=>typeof l=="number"),g=d.length>0?new Date(Math.max(...d)).toISOString():void 0;return {activeProjects:a.size,totalRuns:r,successfulRuns:o,avgTokenImpact:-u*.1,lastUsedAt:g}}getRecommendation(t,e){return e===0?"remove":t>.8?"install":t>.5?"optimize":"remove"}async classifyFailure(t){let e=await this.getRun(t).catch(()=>null);if(!e||e.status!=="failed")return {};let s=e.steps?.find(o=>o.status==="failed");if(!s)return {};let r=s.error?.toLowerCase()??"";return r.includes("context")||r.includes("insufficient")?{failureCategory:"context_insufficient",failureReason:"Context provided was insufficient for the task",suggestedActions:[{action:"Supplement task context",priority:"high"},{action:"View graph roots",priority:"medium"},{action:"Add related memory",priority:"medium"}]}:r.includes("knowledge")||r.includes("docs")?{failureCategory:"knowledge_missing",failureReason:"Required knowledge was not available",suggestedActions:[{action:"Sync knowledge source",priority:"high"},{action:"Add docs source",priority:"medium"}]}:r.includes("workflow")||r.includes("step")?{failureCategory:"workflow_design_issue",failureReason:"Workflow design issue detected",suggestedActions:[{action:"Adjust specific step",priority:"high"},{action:"Split workflow",priority:"medium"}]}:r.includes("tool")||r.includes("connection")?{failureCategory:"tool_error",failureReason:"Tool execution error",suggestedActions:[{action:"Check tool connectivity",priority:"high"},{action:"Retry or fallback",priority:"medium"}]}:{failureCategory:"agent_override",failureReason:"Agent override detected",suggestedActions:[{action:"Enable/strengthen enforcer",priority:"high"}]}}async cleanup(t){let e=this.engine.runs,s=Date.now()-t*24*60*60*1e3,r=0;for(let[o,a]of e)a.startedAt&&a.startedAt<s&&(e.delete(o),r++);return r}async recordExecutionStart(t){this.db&&this.db.insertSkillExecution({executionId:t.executionId,skillName:t.skillName,startedAt:t.startedAt,status:"running"});}async recordToolCall(t){if(!this.db)return;this.db.getSkillExecution(t.executionId)||this.db.insertSkillExecution({executionId:t.executionId,skillName:t.mcpToolName??t.toolName,startedAt:t.timestamp,status:"running"}),this.db.insertToolCallEvent({eventId:t.eventId,executionId:t.executionId,timestamp:t.timestamp,toolName:t.toolName,toolType:t.toolType,isMcpTool:t.isMcpTool,mcpToolName:t.mcpToolName,mcpEnforced:t.mcpEnforced,mcpFallback:t.mcpFallback,input:t.input,tokensUsed:t.tokensUsed,duration:t.duration,parentToolCallId:t.parentToolCallId,subagentId:t.subagentId,error:t.error,blocked:t.blocked,blockReason:t.blockReason});}async recordExecutionComplete(t){this.db&&this.db.updateSkillExecution(t.executionId,{status:t.status,finishedAt:t.finishedAt,totalDuration:t.summary.totalDuration,totalTokens:t.summary.totalTokens,mcpComplianceRate:t.summary.mcpComplianceRate});}async getExecutions(t,e){return this.db?this.db.listSkillExecutions(t,e):[]}async getExecutionEvents(t){return this.db?this.db.listToolCallEvents(t):[]}async getMcpCompliance(){return this.db?this.db.getMcpCompliance():{overall:0,bySkill:{},missedTools:[]}}};E=i([Injectable(),n(0,Optional()),n(0,Inject("DATABASE"))],E);var j=class{constructor(t,e){this.telemetryService=t;this.database=e;this.projectStats=new Map;this.benchmarkResults=[];}async recordTelemetryEvent(t){let e=`evt_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,s=t.toolName?"tool_use":"step_end",r={id:e,runId:t.metadata?.runId??`event_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,stepId:e,kind:s,timestamp:Date.now(),duration:t.durationMs,data:{toolName:t.toolName,toolInput:t.args,errorMessage:t.error},metadata:{source:"claude-code"}};return await this.telemetryService.recordEvent(r),{eventId:e}}async getProjectStats(t){return this.database?this.database.getProjectStats(t):this.projectStats.get(t)??null}async updateProjectStats(t,e){if(this.database){let a={...await this.getProjectStats(t)??{projectRoot:t,totalRuns:0,successfulRuns:0,totalTokens:0,lastActiveAt:Date.now(),topTools:[]},...e,lastActiveAt:Date.now()};return await this.database.upsertProjectStats(a),a}let r={...this.projectStats.get(t)??{projectRoot:t,totalRuns:0,successfulRuns:0,totalTokens:0,lastActiveAt:Date.now(),topTools:[]},...e,lastActiveAt:Date.now()};return this.projectStats.set(t,r),r}recordBenchmarkResult(t){this.benchmarkResults.push(t);}getBenchmarkResults(t){return t?this.benchmarkResults.filter(e=>this.projectStats.get(e.scenarioId)?.projectRoot===t):this.benchmarkResults}async getPluginEffectiveness(t){return []}};j=i([Injectable(),n(0,Inject(E)),n(1,Optional()),n(1,Inject("DATABASE"))],j);var C=class{constructor(t){this.dataService=t;this.feedbackEntries=[];}async indexProject(t){let{context:e,codegraph:s}=await createEngines(t);await e.index(t);let r=s.getStats();return {totalFiles:r.fileCount,totalSymbols:r.nodeCount,lastIndexTime:r.lastUpdated,indexing:s.isIndexing()}}async getStatus(t){try{let{codegraph:e}=await createEngines(t),s=e.getStats();return {totalFiles:s.fileCount,totalSymbols:s.nodeCount,lastIndexTime:s.lastUpdated,indexing:e.isIndexing()}}catch{return {totalFiles:0,totalSymbols:0,lastIndexTime:0,indexing:false}}}async buildContext(t,e,s,r){let{context:o}=await createEngines(t);return o.build({query:e,mode:s,maxTokens:r??8e3,includeGraph:s==="deep"})}async buildTaskContext(t,e,s,r){let{context:o}=await createEngines(t);return o.buildTaskContext(e,{mode:s,maxTokens:r??8e3})}async findSymbol(t,e){let{indexer:s}=await createEngines(t);return s.findSymbol(e)}async recordFeedback(t,e,s,r){let o={query:e,feedback:s,timestamp:Date.now(),projectRoot:t};return this.feedbackEntries.push(o),this.dataService&&await this.dataService.recordTelemetryEvent({toolName:"context_feedback",args:{query:e,feedback:s,taskType:r?.taskType,contextMode:r?.contextMode,projectRoot:t},durationMs:0,success:true,metadata:{projectRoot:t,query:e,taskType:r?.taskType}}),o}async getFeedbackSummaries(){let t=this.feedbackEntries.length,e=this.feedbackEntries.filter(o=>o.feedback==="hit").length,s=this.feedbackEntries.filter(o=>o.feedback==="partial").length,r=this.feedbackEntries.filter(o=>o.feedback==="miss").length;return {total:t,hits:e,partials:s,misses:r,hitRate:t>0?e/t:0}}};C=i([Injectable(),n(0,Optional()),n(0,Inject(j))],C);var I=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let s=t??e??this.projects.getActiveProjectRoot();if(!s)throw new BadRequestException("rootPath is required \u2014 no active project connected");return s}async status(t,e){let s=t??e??this.projects.getActiveProjectRoot();return s?this.service.getStatus(s):null}async index(t,e){return this.service.indexProject(this.resolveRootPath(t.rootPath,e))}async build(t,e){return this.service.buildContext(this.resolveRootPath(t.rootPath,e),t.query,t.mode??"fast",t.maxTokens)}async buildTask(t,e){return this.service.buildTaskContext(this.resolveRootPath(t.rootPath,e),t.query,t.mode??"fast",t.maxTokens)}async feedback(t,e){return this.service.recordFeedback(this.resolveRootPath(t.rootPath,e),t.query,t.feedback,{taskType:t.taskType,contextMode:t.contextMode,runId:t.runId,tokenCount:t.tokenCount})}async feedbackSummary(){return this.service.getFeedbackSummaries()}async findSymbol(t,e,s){return this.service.findSymbol(this.resolveRootPath(e,s),t)}};i([Get("status"),n(0,Query("rootPath")),n(1,Headers("x-devflow-project"))],I.prototype,"status",1),i([Post("index"),n(0,Body()),n(1,Headers("x-devflow-project"))],I.prototype,"index",1),i([Post("build"),n(0,Body()),n(1,Headers("x-devflow-project"))],I.prototype,"build",1),i([Post("build-task"),n(0,Body()),n(1,Headers("x-devflow-project"))],I.prototype,"buildTask",1),i([Post("feedback"),n(0,Body()),n(1,Headers("x-devflow-project"))],I.prototype,"feedback",1),i([Get("feedback-summary")],I.prototype,"feedbackSummary",1),i([Get("symbol/:name"),n(0,Param("name")),n(1,Query("rootPath")),n(2,Headers("x-devflow-project"))],I.prototype,"findSymbol",1),I=i([Controller("context"),n(0,Inject(C)),n(1,Inject(h))],I);var N=class{constructor(t){this.dataService=t;}async recordTelemetryEvent(t){return {success:true,...await this.dataService.recordTelemetryEvent(t)}}async getProjectStats(t){return this.dataService.getProjectStats(t)}async updateProjectStats(t){return this.dataService.updateProjectStats(t.projectRoot,t.stats)}recordBenchmarkResult(t){return this.dataService.recordBenchmarkResult(t),{success:true}}getBenchmarkResults(t){return this.dataService.getBenchmarkResults(t)}};i([Post("telemetry/event"),n(0,Body())],N.prototype,"recordTelemetryEvent",1),i([Get("project/stats"),n(0,Query("rootPath"))],N.prototype,"getProjectStats",1),i([Post("project/stats"),n(0,Body())],N.prototype,"updateProjectStats",1),i([Post("benchmark/result"),n(0,Body())],N.prototype,"recordBenchmarkResult",1),i([Get("benchmark/results"),n(0,Query("projectRoot"))],N.prototype,"getBenchmarkResults",1),N=i([Controller("data"),n(0,Inject(j))],N);var O=class{constructor(){this.engines=new Map;}getEngine(t){return this.engines.has(t)||this.engines.set(t,new MemoryEngine(t)),this.engines.get(t)}async getAll(t){let e=this.getEngine(t),[s,r]=await Promise.all([e.listMemories(),checkOllama()]);return {memories:s.map(o=>({id:o.id,category:o.category,content:o.content,originalText:o.originalText,source:o.source,status:o.status,confidence:o.confidence,scope:o.scope,createdAt:o.createdAt,approvedAt:o.approvedAt})),ollama:{installed:r.installed,running:r.running,modelAvailable:r.modelAvailable,modelName:r.modelName,infoMessage:getOllamaInfoMessage(r)}}}async add(t,e){return this.getEngine(t).addMemory({category:e.category,content:e.content,source:"manual",confidence:1,scope:e.scope??""})}async update(t,e,s){await this.getEngine(t).updateMemory(e,s);}async delete(t,e){await this.getEngine(t).deleteMemory(e);}async getCandidates(t){return this.getEngine(t).getPendingMemories()}async approveCandidate(t,e){await this.getEngine(t).approveMemory(e);}async rejectCandidate(t,e){await this.getEngine(t).rejectMemory(e);}async search(t,e,s){return (await this.getEngine(t).search(e,s)).map(o=>o.entry)}async extract(t,e){return this.getEngine(t).extractMemories(e)}async getOllamaStatus(){let t=await checkOllama();return {...t,infoMessage:getOllamaInfoMessage(t)}}async updateLegacy(t,e,s,r){e!=="user"&&await this.getEngine(t).addMemory({category:"project_knowledge",content:`${s}: ${JSON.stringify(r)}`,source:"manual",confidence:1,scope:s});}};O=i([Injectable()],O);var y=class{constructor(t,e,s){this.service=t;this.memoryService=e;this.projectsService=s;}async listRuns(t,e,s){return this.service.listRuns(Number(t)||20,Number(e)||0,s)}async getRun(t){let e=await this.service.getRun(t),s=await this.service.classifyFailure(t);return {...e,...s}}async getTimeline(t,e){return this.service.getTimeline(t,e)}async getRunEvents(t){return this.service.getRunEvents(t)}async getRunStats(t){return this.service.getRunStats(t)}async completeRun(t){await this.service.endRun(t,{status:"success",tokenUsed:0});let e=await this.service.getRunEvents(t),s=this.projectsService.getActiveProjectRoot(),r=await this.memoryService.extract(s??"",e);return {ok:true,extracted:Array.isArray(r)?r.length:0}}async getStats(t){return this.service.getStats(Number(t)||7)}async getRoiSummary(t){return this.service.getRoiSummary(Number(t)||7)}async cleanup(t){return {ok:true,data:{removedRuns:await this.service.cleanup(t.olderThanDays??30)}}}async startSkillExecution(t){return await this.service.recordExecutionStart(t),{executionId:t.executionId}}async recordToolCall(t){return await this.service.recordToolCall(t),{eventId:t.eventId}}async completeSkillExecution(t){return await this.service.recordExecutionComplete(t),{}}async getExecutions(t,e){return {data:await this.service.getExecutions(Number(t)||20,e)}}async getExecutionEvents(t){return {data:await this.service.getExecutionEvents(t)}}async getMcpCompliance(){return await this.service.getMcpCompliance()}};i([Get("runs"),n(0,Query("limit")),n(1,Query("offset")),n(2,Query("source"))],y.prototype,"listRuns",1),i([Get("runs/:id"),n(0,Param("id"))],y.prototype,"getRun",1),i([Get("timeline"),n(0,Query("from")),n(1,Query("to"))],y.prototype,"getTimeline",1),i([Get("runs/:runId/events"),n(0,Param("runId"))],y.prototype,"getRunEvents",1),i([Get("runs/:runId/stats"),n(0,Param("runId"))],y.prototype,"getRunStats",1),i([Post("runs/:id/complete"),n(0,Param("id"))],y.prototype,"completeRun",1),i([Get("stats"),n(0,Query("days"))],y.prototype,"getStats",1),i([Get("roi-summary"),n(0,Query("days"))],y.prototype,"getRoiSummary",1),i([Post("cleanup"),n(0,Body())],y.prototype,"cleanup",1),i([Post("skill-execution/start"),n(0,Body())],y.prototype,"startSkillExecution",1),i([Post("tool-call"),n(0,Body())],y.prototype,"recordToolCall",1),i([Post("skill-execution/complete"),n(0,Body())],y.prototype,"completeSkillExecution",1),i([Get("executions"),n(0,Query("limit")),n(1,Query("skillName"))],y.prototype,"getExecutions",1),i([Get("executions/:id/events"),n(0,Param("id"))],y.prototype,"getExecutionEvents",1),i([Get("mcp-compliance")],y.prototype,"getMcpCompliance",1),y=i([Controller("telemetry"),n(0,Inject(E)),n(1,Inject(O)),n(2,Inject(h))],y);var k=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let s=t??e??this.projects.getActiveProjectRoot();if(!s)throw new BadRequestException("rootPath is required \u2014 no active project connected");return s}async getAll(t,e){return this.service.getAll(this.resolveRootPath(t,e))}async add(t,e,s){return this.service.add(this.resolveRootPath(t,s),e)}async update(t,e,s,r){return await this.service.update(this.resolveRootPath(t,r),e,s),{ok:true}}async delete(t,e,s){return await this.service.delete(this.resolveRootPath(t,s),e),{ok:true}}async getCandidates(t,e){return this.service.getCandidates(this.resolveRootPath(t,e))}async approve(t,e,s){return await this.service.approveCandidate(this.resolveRootPath(t,s),e),{approved:true}}async reject(t,e,s){return await this.service.rejectCandidate(this.resolveRootPath(t,s),e),{rejected:true}}async search(t,e,s){return this.service.search(this.resolveRootPath(t,s),e.query,{limit:e.limit,categories:e.categories})}async extract(t,e,s){return this.service.extract(this.resolveRootPath(t,s),e.events)}async ollamaStatus(){return this.service.getOllamaStatus()}async updateLegacy(t,e,s,r,o){return await this.service.updateLegacy(this.resolveRootPath(t,o),e,s,r.value),{ok:true}}};i([Get(),n(0,Query("rootPath")),n(1,Headers("x-devflow-project"))],k.prototype,"getAll",1),i([Post(),n(0,Query("rootPath")),n(1,Body()),n(2,Headers("x-devflow-project"))],k.prototype,"add",1),i([Put(":id"),n(0,Query("rootPath")),n(1,Param("id")),n(2,Body()),n(3,Headers("x-devflow-project"))],k.prototype,"update",1),i([Delete(":id"),n(0,Query("rootPath")),n(1,Param("id")),n(2,Headers("x-devflow-project"))],k.prototype,"delete",1),i([Get("candidates"),n(0,Query("rootPath")),n(1,Headers("x-devflow-project"))],k.prototype,"getCandidates",1),i([Post("candidates/:id/approve"),n(0,Query("rootPath")),n(1,Param("id")),n(2,Headers("x-devflow-project"))],k.prototype,"approve",1),i([Post("candidates/:id/reject"),n(0,Query("rootPath")),n(1,Param("id")),n(2,Headers("x-devflow-project"))],k.prototype,"reject",1),i([Post("search"),n(0,Query("rootPath")),n(1,Body()),n(2,Headers("x-devflow-project"))],k.prototype,"search",1),i([Post("extract"),n(0,Query("rootPath")),n(1,Body()),n(2,Headers("x-devflow-project"))],k.prototype,"extract",1),i([Get("ollama/status")],k.prototype,"ollamaStatus",1),i([Put(":layer/:key"),n(0,Query("rootPath")),n(1,Param("layer")),n(2,Param("key")),n(3,Body()),n(4,Headers("x-devflow-project"))],k.prototype,"updateLegacy",1),k=i([Controller("memory"),n(0,Inject(O)),n(1,Inject(h))],k);var J=class{};J=i([Module({imports:[T,w],controllers:[k],providers:[O],exports:[O]})],J);var M=class{};M=i([Module({imports:[J,w],controllers:[y],providers:[E],exports:[E]})],M);var V=class{};V=i([Module({imports:[M],controllers:[N],providers:[j],exports:[j]})],V);var T=class{};T=i([Module({imports:[w,V],controllers:[I],providers:[C],exports:[C]})],T);var L=class{async getFullGraph(t){let{graph:e}=await createEngines(t);return e.export()}async getLayeredGraph(t){let{graph:e}=await createEngines(t);return e.getLayeredGraph()}async getNode(t,e){let{codegraph:s}=await createEngines(t),r=s.getNode(e);if(!r)throw new NotFoundException({error:{code:b.NODE_NOT_FOUND,message:`Node "${e}" not found`,details:{}}});return r}async expandNode(t,e,s,r){let{graph:o}=await createEngines(t),a=o.expand([e],{depth:s,direction:r});return {node:a.nodes.find(u=>u.id===e),subGraph:a}}};L=i([Injectable()],L);var q=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let s=t??e??this.projects.getActiveProjectRoot();if(!s)throw new BadRequestException("rootPath is required \u2014 no active project connected");return s}async getFullGraph(t,e,s){return e==="layered"?this.service.getLayeredGraph(this.resolveRootPath(t,s)):this.service.getFullGraph(this.resolveRootPath(t,s))}async getNode(t,e,s){return this.service.getNode(this.resolveRootPath(t,s),e)}async expandNode(t,e,s,r,o){return this.service.expandNode(this.resolveRootPath(t,o),e,Number(s)||2,r||"both")}};i([Get(),n(0,Query("rootPath")),n(1,Query("view")),n(2,Headers("x-devflow-project"))],q.prototype,"getFullGraph",1),i([Get(":nodeId"),n(0,Query("rootPath")),n(1,Param("nodeId")),n(2,Headers("x-devflow-project"))],q.prototype,"getNode",1),i([Get(":nodeId/expand"),n(0,Query("rootPath")),n(1,Param("nodeId")),n(2,Query("depth")),n(3,Query("direction")),n(4,Headers("x-devflow-project"))],q.prototype,"expandNode",1),q=i([Controller("graph"),n(0,Inject(L)),n(1,Inject(h))],q);var ot=class{};ot=i([Module({imports:[T,w],controllers:[q],providers:[L],exports:[L]})],ot);var $=class{constructor(){this.engine=new WorkflowEngine;this.events=new Map;this.engineRunIds=new Map;}async onModuleInit(){try{let t=await loadPlugins(),e=Array.from(t.values());for(let r of e)for(let o of r.workflow?.templates??[])this.engine.register(o);let s=await this.engine.list();console.log(`[WorkflowService] Loaded ${e.length} plugins with ${s.length} workflows`);}catch(t){console.error("[WorkflowService] Failed to load plugins:",t);}}async list(){return this.engine.list()}async run(t,e){if(!(await this.engine.list()).find(a=>a.name===t))throw new NotFoundException({error:{code:b.WORKFLOW_NOT_FOUND,message:`Workflow "${t}" not found`,details:{}}});let r=`run_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,o=new Subject;return this.events.set(r,o),this.engine.run(t,e).then(a=>{this.engineRunIds.set(r,a.runId);let u=this.engine.getRun(a.runId);if(u){for(let d of u.steps)o.next({runId:r,stepId:d.stepId,status:d.status==="success"?"completed":d.status==="failed"?"failed":"started",output:d.output,error:d.error,timestamp:Date.now()});a.status!=="running"&&o.complete();}a.status==="running"&&this.engine.onEvent(a.runId,d=>{o.next({runId:r,stepId:d.stepId,status:d.type==="step-done"?"completed":d.type==="step-error"?"failed":"started",output:"output"in d?d.output:void 0,error:"error"in d?d.error:void 0,timestamp:Date.now()});});}).catch(a=>{o.next({runId:r,stepId:"engine",status:"failed",error:a.message,timestamp:Date.now()}),o.complete();}),{runId:r}}async listRuns(t,e){return (await this.engine.listRuns()).map(o=>({runId:Array.from(this.engineRunIds.entries()).find(([,u])=>u===o.runId)?.[0]??o.runId,workflowName:o.type,status:o.status,steps:o.steps.map(u=>({stepId:u.stepId,status:u.status,output:u.output,error:u.error,startedAt:0})),startedAt:o.startedAt,finishedAt:o.finishedAt})).slice(e,e+t)}async getRun(t){let e=this.engineRunIds.get(t)??t,s=this.engine.getRun(e);if(!s)throw new NotFoundException({error:{code:b.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});return {runId:t,workflowName:s.type,status:s.status,steps:s.steps.map(r=>({stepId:r.stepId,status:r.status,output:r.output,error:r.error})),startedAt:s.startedAt,finishedAt:s.finishedAt}}streamRun(t){let e=this.events.get(t);if(!e)throw new NotFoundException({error:{code:b.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});return e}async approveRun(t){let e=this.engineRunIds.get(t)??t,s=this.engine.getRun(e);if(!s)throw new NotFoundException({error:{code:b.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});let r=s.steps.find(o=>o.status==="awaiting_approval");r&&await this.engine.approve(e,r.stepId);}async rejectRun(t,e){let s=this.engineRunIds.get(t)??t,r=this.engine.getRun(s);if(!r)throw new NotFoundException({error:{code:b.RUN_NOT_FOUND,message:`Run "${t}" not found`,details:{}}});let o=r.steps.find(a=>a.status==="awaiting_approval");o&&await this.engine.reject(s,o.stepId,e??"Rejected");}async getNextStep(t){if(!t){(await this.engine.list())[0];return null}let e=this.engineRunIds.get(t)??t,s=this.engine.getRun(e);return s?(Array.isArray(s.steps)?s.steps:[]).find(o=>o.status==="pending")??null:null}};$=i([Injectable()],$);var S=class{constructor(t){this.service=t;}async list(){return this.service.list()}async run(t,e){return this.service.run(t,e.input??{})}async listRuns(t,e){return this.service.listRuns(Number(t)||20,Number(e)||0)}async getRun(t){return this.service.getRun(t)}async stream(t,e){e.raw.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let r=this.service.streamRun(t).subscribe({next:o=>{e.raw.write(`event: step-${o.status}
2
+ data: ${JSON.stringify(o)}
3
3
 
4
- `);},error:n=>{e.raw.write(`event: error
5
- data: ${JSON.stringify({error:n.message})}
4
+ `);},error:o=>{e.raw.write(`event: error
5
+ data: ${JSON.stringify({error:o.message})}
6
6
 
7
7
  `),e.raw.end();},complete:()=>{e.raw.write(`event: done
8
8
  data: {}
9
9
 
10
- `),e.raw.end();}});e.raw.on("close",()=>s.unsubscribe());}async approve(t){return await this.service.approveRun(t),{approved:true}}async reject(t,e){return await this.service.rejectRun(t,e.reason),{rejected:true}}async nextStep(t){return this.service.getNextStep(t)}};i([Get()],w.prototype,"list",1),i([Post(":type/run"),o(0,Param("type")),o(1,Body())],w.prototype,"run",1),i([Get("runs"),o(0,Query("limit")),o(1,Query("offset"))],w.prototype,"listRuns",1),i([Get("runs/:id"),o(0,Param("id"))],w.prototype,"getRun",1),i([Get("runs/:id/stream"),o(0,Param("id")),o(1,Res())],w.prototype,"stream",1),i([Post("runs/:id/approve"),o(0,Param("id"))],w.prototype,"approve",1),i([Post("runs/:id/reject"),o(0,Param("id")),o(1,Body())],w.prototype,"reject",1),i([Get("next-step"),o(0,Query("runId"))],w.prototype,"nextStep",1),w=i([Controller("workflows"),o(0,Inject(B))],w);var rt=class{};rt=i([Module({controllers:[w],providers:[B],exports:[B]})],rt);var L=class{async getAll(t){let{memory:e}=await createEngines(t),r=await e.getProjectContext(),s=await e.getUserPreferences();return {project:{stack:r.stack,conventions:r.conventions,metadata:r.metadata},user:{preferences:s.preferences,stack:s.stack}}}async update(t,e,r,s){let{memory:n}=await createEngines(t);if(e==="user")await n.updateUserPreference(r,s);else if(e==="project"){let a=await n.getProjectContext();a.metadata[r]=s,await n.setProjectContext(a);}else throw new NotFoundException({error:{code:f.MEMORY_KEY_NOT_FOUND,message:`Layer "${e}" not found`,details:{}}})}async getCandidates(t){let{memory:e}=await createEngines(t);return e.getCandidates()}async approveCandidate(t,e){let{memory:r}=await createEngines(t);await r.approveCandidate(e);}async rejectCandidate(t,e){let{memory:r}=await createEngines(t);await r.rejectCandidate(e);}};L=i([Injectable()],L);var A=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let r=t??e??this.projects.getActiveProjectRoot();if(!r)throw new BadRequestException("rootPath is required \u2014 no active project connected");return r}async getAll(t,e){return this.service.getAll(this.resolveRootPath(t,e))}async update(t,e,r,s,n){return await this.service.update(this.resolveRootPath(t,n),e,r,s.value),{ok:true}}async getCandidates(t,e){return this.service.getCandidates(this.resolveRootPath(t,e))}async approve(t,e,r){return await this.service.approveCandidate(this.resolveRootPath(t,r),e),{approved:true}}async reject(t,e,r){return await this.service.rejectCandidate(this.resolveRootPath(t,r),e),{rejected:true}}};i([Get(),o(0,Query("rootPath")),o(1,Headers("x-devflow-project"))],A.prototype,"getAll",1),i([Put(":layer/:key"),o(0,Query("rootPath")),o(1,Param("layer")),o(2,Param("key")),o(3,Body()),o(4,Headers("x-devflow-project"))],A.prototype,"update",1),i([Get("candidates"),o(0,Query("rootPath")),o(1,Headers("x-devflow-project"))],A.prototype,"getCandidates",1),i([Post("candidates/:id/approve"),o(0,Query("rootPath")),o(1,Param("id")),o(2,Headers("x-devflow-project"))],A.prototype,"approve",1),i([Post("candidates/:id/reject"),o(0,Query("rootPath")),o(1,Param("id")),o(2,Headers("x-devflow-project"))],A.prototype,"reject",1),A=i([Controller("memory"),o(0,Inject(L)),o(1,Inject(y))],A);var st=class{};st=i([Module({imports:[E,P],controllers:[A],providers:[L],exports:[L]})],st);var q=class{constructor(t){this.projectsService=t;}getEngine(t){return new KnowledgeEngine({projectRoot:t})}async onModuleInit(){let t=this.projectsService.getActiveProjectRoot()??process.env.DEVFLOW_PROJECT_ROOT??process.cwd();try{let e=this.getEngine(t),r=await e.getSources(),s=Date.now()-10080*60*1e3;for(let n of r)(!n.lastSyncTime||n.lastSyncTime<s)&&await e.syncDocs(n.source.name);}catch{}}async search(t,e,r){return this.getEngine(t).search(e,{sources:r&&r!=="all"?[r]:void 0})}async sync(t,e){return this.getEngine(t).syncDocs(e??"")}async getSources(t){return this.getEngine(t).getSources()}};q=i([Injectable(),o(0,Inject(y))],q);var $=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let r=t??e??this.projects.getActiveProjectRoot();if(!r)throw new BadRequestException("rootPath is required \u2014 no active project connected");return r}async search(t,e,r,s){return this.service.search(this.resolveRootPath(t,s),e??"",r)}async sync(t,e){return this.service.sync(this.resolveRootPath(t.rootPath,e),t.pluginName)}async getSources(t,e){return {ok:true,data:await this.service.getSources(this.resolveRootPath(t,e))}}};i([Get("search"),o(0,Query("rootPath")),o(1,Query("q")),o(2,Query("scope")),o(3,Headers("x-devflow-project"))],$.prototype,"search",1),i([Post("sync"),o(0,Body()),o(1,Headers("x-devflow-project"))],$.prototype,"sync",1),i([Get("sources"),o(0,Query("rootPath")),o(1,Headers("x-devflow-project"))],$.prototype,"getSources",1),$=i([Controller("knowledge"),o(0,Inject(q)),o(1,Inject(y))],$);var nt=class{};nt=i([Module({imports:[E,P],controllers:[$],providers:[q],exports:[q]})],nt);var G=class{constructor(){this.results=[];this.scenarioIds=[];this.engine=new BenchmarkEngine,this.registerDefaultScenarios();}registerDefaultScenarios(){let t=[{id:"understand-codebase",category:"understand",desc:"\u7406\u89E3\u4EE3\u7801\u5E93\u67B6\u6784",expectedFiles:2},{id:"modify-component",category:"modify",desc:"\u4FEE\u6539 React \u7EC4\u4EF6",expectedFiles:1,expectedComponents:1},{id:"review-code",category:"review",desc:"\u4EE3\u7801\u5BA1\u67E5",expectedIssues:2}];for(let e of t)this.engine.registerScenario(e),this.scenarioIds.push(e.id);}async runScenarioSet(t){let e=async a=>({prepTimeMs:1e3+Math.random()*500,tokenCount:500+Math.floor(Math.random()*200),firstPassSuccess:Math.random()>.5,reworkCount:Math.floor(Math.random()*3),durationMs:5e3+Math.random()*3e3}),r=async a=>({prepTimeMs:500+Math.random()*300,tokenCount:300+Math.floor(Math.random()*100),firstPassSuccess:Math.random()>.2,reworkCount:Math.floor(Math.random()*2),durationMs:3e3+Math.random()*2e3}),s=t??this.scenarioIds,n=await this.engine.runScenarioBatch(s,e,r);return this.results=n,n}async getScenarioResults(){return this.results.length===0&&await this.runScenarioSet(),this.results}async getComparisonSummary(){let t=await this.getScenarioResults(),e=t.length;return {totalScenarios:e,avgTimeSavedRate:t.reduce((r,s)=>r+s.comparison.timeSavedRate,0)/e,avgTokenReductionRate:t.reduce((r,s)=>r+s.comparison.tokenReductionRate,0)/e,avgFirstPassLift:t.reduce((r,s)=>r+s.comparison.firstPassLift,0)/e,avgReworkReductionRate:t.reduce((r,s)=>r+s.comparison.reworkReductionRate,0)/e}}async getExperimentalRoiSummary(){let t=await this.getComparisonSummary();return {totalScenarios:t.totalScenarios,avgTimeSavedRate:t.avgTimeSavedRate,avgTokenReductionRate:t.avgTokenReductionRate,avgFirstPassLift:t.avgFirstPassLift,avgReworkReductionRate:t.avgReworkReductionRate,conclusion:"DevFlow shows significant improvement in all metrics"}}};G=i([Injectable()],G);var D=class{constructor(t){this.service=t;}async run(t){return this.service.runScenarioSet(t.scenarioIds)}async getResults(){return this.service.getScenarioResults()}async getComparisonSummary(){return this.service.getComparisonSummary()}async getExperimentalRoiSummary(){return this.service.getExperimentalRoiSummary()}};i([Post("run"),o(0,Body())],D.prototype,"run",1),i([Get("results")],D.prototype,"getResults",1),i([Get("summary")],D.prototype,"getComparisonSummary",1),i([Get("roi-summary")],D.prototype,"getExperimentalRoiSummary",1),D=i([Controller("benchmark"),o(0,Inject(G))],D);var ot=class{};ot=i([Module({controllers:[D],providers:[G],exports:[G]})],ot);var H=class{constructor(t){this.telemetryService=t;this.plugins=new Map;this.installRecords=[];}async list(t,e){let r=Array.from(this.plugins.values());if(t){let s=t.toLowerCase();r=r.filter(n=>n.name.toLowerCase().includes(s)||n.description.toLowerCase().includes(s));}return e&&(r=r.filter(s=>s.tags.includes(e))),r}async getByName(t){let e=this.plugins.get(t);if(!e)throw new NotFoundException({error:{code:f.PLUGIN_NOT_FOUND,message:`Plugin "${t}" not found`,details:{}}});return e}async publish(t){let e=t.npmPackage.replace(/^@devflow-tools\/plugin-/,""),r={name:e,npmPackage:t.npmPackage,version:t.version,description:t.description,tags:t.tags??[],createdAt:Date.now()};return this.plugins.set(e,r),r}async install(t,e){let r=t.startsWith("@devflow-tools/plugin-")?t:`@devflow-tools/plugin-${t}`,s=t.replace(/^@devflow-tools\/plugin-/,"");return this.plugins.set(s,{name:s,npmPackage:r,version:"0.1.0",description:"Installed plugin",tags:[],createdAt:Date.now()}),e&&await this.recordPluginInstall(s,e),{ok:true,name:s}}async uninstall(t,e){let r=t.replace(/^@devflow-tools\/plugin-/,"");return this.plugins.delete(r),e&&await this.recordPluginUninstall(r,e),{ok:true,name:r}}async recordPluginInstall(t,e){let r=this.installRecords.find(s=>s.pluginName===t&&s.projectRoot===e);r?r.uninstalledAt=void 0:this.installRecords.push({pluginName:t,projectRoot:e,installedAt:Date.now()});}async recordPluginUninstall(t,e){let r=this.installRecords.find(s=>s.pluginName===t&&s.projectRoot===e);r&&(r.uninstalledAt=Date.now());}async listInstalledProjects(t){return this.installRecords.filter(e=>e.pluginName===t&&!e.uninstalledAt).map(e=>e.projectRoot)}async buildPluginEffectiveness(t){let r=(await this.listInstalledProjects(t)).length,s=await this.telemetryService.getPluginUsageStats(t),n=r>0?s.activeProjects/r:0,a=s.totalRuns>0?s.successfulRuns/s.totalRuns:0,u="optimize";return n>.7&&a>.8?u="install":(n<.3||a<.5)&&(u="remove"),{name:t,installCount:r,usageCount:s.totalRuns,activeRate:n,successRate:a,avgTokenImpact:s.avgTokenImpact,lastUsedAt:s.lastUsedAt,recommendation:u}}async getPluginEffectiveness(t){let e=t?this.installRecords.filter(n=>n.projectRoot===t&&!n.uninstalledAt):this.installRecords.filter(n=>!n.uninstalledAt),r=[...new Set(e.map(n=>n.pluginName))],s=[];for(let n of r){let a=await this.buildPluginEffectiveness(n);s.push(a);}return s}};H=i([Injectable(),o(0,Inject(S))],H);var j=class{constructor(t){this.service=t;}async list(t,e){return this.service.list(t,e)}async getPluginEffectiveness(t){return this.service.getPluginEffectiveness(t)}async getByName(t){return this.service.getByName(t)}async publish(t){return this.service.publish(t)}async install(t,e){return this.service.install(t.name,t.rootPath??e)}async uninstall(t,e,r){return this.service.uninstall(t,e.rootPath??r)}};i([Get("plugins"),o(0,Query("search")),o(1,Query("tag"))],j.prototype,"list",1),i([Get("plugins/effectiveness"),o(0,Query("rootPath"))],j.prototype,"getPluginEffectiveness",1),i([Get("plugins/:name"),o(0,Param("name"))],j.prototype,"getByName",1),i([Post("plugins"),o(0,Body())],j.prototype,"publish",1),i([Post("plugins/install"),o(0,Body()),o(1,Headers("x-devflow-project"))],j.prototype,"install",1),i([Post("plugins/:name/uninstall"),o(0,Param("name")),o(1,Body()),o(2,Headers("x-devflow-project"))],j.prototype,"uninstall",1),j=i([Controller("registry"),o(0,Inject(H))],j);var it=class{};it=i([Module({imports:[_],controllers:[j],providers:[H],exports:[H]})],it);var ve={provide:"DATABASE",useFactory:()=>{let c=process.cwd();return new DevFlowDatabase(c)}},at=class{};at=i([Global(),Module({providers:[ve],exports:[ve]})],at);var ct=class{intercept(t,e){return e.handle().pipe(map(r=>r&&typeof r=="object"&&"error"in r?r:{ok:true,data:r??null}))}};ct=i([Injectable()],ct);var Q=class{constructor(){this.startTime=Date.now();}health(){return {version:"0.2.3",uptime:Date.now()-this.startTime}}};i([Qt(),Get("health")],Q.prototype,"health",1),Q=i([Controller()],Q);var ut=class{};ut=i([Module({imports:[at,X,P,E,et,rt,st,nt,_,ot,it,Y],controllers:[Q],providers:[{provide:APP_INTERCEPTOR,useClass:ct}]})],ut);var W=class{constructor(){this.logger=new Logger(W.name);}catch(t,e){let s=e.switchToHttp().getResponse();if(t instanceof HttpException){let n=t.getStatus(),a=t.getResponse();if(typeof a=="object"&&a!==null&&"error"in a){s.status(n).send(a);return}let u=typeof a=="string"?a:a.message??"Request failed";s.status(n).send({error:{code:f.INTERNAL_ERROR,message:u,details:{}}});return}this.logger.error("Unhandled exception",t instanceof Error?t.stack:String(t)),s.status(HttpStatus.INTERNAL_SERVER_ERROR).send({error:{code:f.INTERNAL_ERROR,message:"Internal server error",details:{}}});}};W=i([Catch()],W);async function is(){let c=await NestFactory.create(ut,new FastifyAdapter);return c.setGlobalPrefix("api"),c.useGlobalFilters(new W),c.enableCors({origin:true,credentials:true}),await c.listen({port:13337,host:"0.0.0.0"}),c}(process.argv[1]?.endsWith("main.js")||process.argv[1]?.endsWith("main.ts"))&&is();export{is as bootstrap};
10
+ `),e.raw.end();}});e.raw.on("close",()=>r.unsubscribe());}async approve(t){return await this.service.approveRun(t),{approved:true}}async reject(t,e){return await this.service.rejectRun(t,e.reason),{rejected:true}}async nextStep(t){return this.service.getNextStep(t)}};i([Get()],S.prototype,"list",1),i([Post(":type/run"),n(0,Param("type")),n(1,Body())],S.prototype,"run",1),i([Get("runs"),n(0,Query("limit")),n(1,Query("offset"))],S.prototype,"listRuns",1),i([Get("runs/:id"),n(0,Param("id"))],S.prototype,"getRun",1),i([Get("runs/:id/stream"),n(0,Param("id")),n(1,Res())],S.prototype,"stream",1),i([Post("runs/:id/approve"),n(0,Param("id"))],S.prototype,"approve",1),i([Post("runs/:id/reject"),n(0,Param("id")),n(1,Body())],S.prototype,"reject",1),i([Get("next-step"),n(0,Query("runId"))],S.prototype,"nextStep",1),S=i([Controller("workflows"),n(0,Inject($))],S);var it=class{};it=i([Module({controllers:[S],providers:[$],exports:[$]})],it);var G=class{constructor(t){this.projectsService=t;}getEngine(t){return new KnowledgeEngine({projectRoot:t})}async onModuleInit(){let t=this.projectsService.getActiveProjectRoot()??process.env.DEVFLOW_PROJECT_ROOT??process.cwd();try{let e=this.getEngine(t),s=await e.getSources(),r=Date.now()-10080*60*1e3;for(let o of s)(!o.lastSyncTime||o.lastSyncTime<r)&&await e.syncDocs(o.source.name);}catch{}}async search(t,e,s){return this.getEngine(t).search(e,{sources:s&&s!=="all"?[s]:void 0})}async sync(t,e){return this.getEngine(t).syncDocs(e??"")}async getSources(t){return this.getEngine(t).getSources()}};G=i([Injectable(),n(0,Inject(h))],G);var H=class{constructor(t,e){this.service=t;this.projects=e;}resolveRootPath(t,e){let s=t??e??this.projects.getActiveProjectRoot();if(!s)throw new BadRequestException("rootPath is required \u2014 no active project connected");return s}async search(t,e,s,r){return this.service.search(this.resolveRootPath(t,r),e??"",s)}async sync(t,e){return this.service.sync(this.resolveRootPath(t.rootPath,e),t.pluginName)}async getSources(t,e){return {ok:true,data:await this.service.getSources(this.resolveRootPath(t,e))}}};i([Get("search"),n(0,Query("rootPath")),n(1,Query("q")),n(2,Query("scope")),n(3,Headers("x-devflow-project"))],H.prototype,"search",1),i([Post("sync"),n(0,Body()),n(1,Headers("x-devflow-project"))],H.prototype,"sync",1),i([Get("sources"),n(0,Query("rootPath")),n(1,Headers("x-devflow-project"))],H.prototype,"getSources",1),H=i([Controller("knowledge"),n(0,Inject(G)),n(1,Inject(h))],H);var at=class{};at=i([Module({imports:[T,w],controllers:[H],providers:[G],exports:[G]})],at);var K=class{constructor(){this.results=[];this.scenarioIds=[];this.engine=new BenchmarkEngine,this.registerDefaultScenarios();}registerDefaultScenarios(){let t=[{id:"understand-codebase",category:"understand",desc:"\u7406\u89E3\u4EE3\u7801\u5E93\u67B6\u6784",expectedFiles:2},{id:"modify-component",category:"modify",desc:"\u4FEE\u6539 React \u7EC4\u4EF6",expectedFiles:1,expectedComponents:1},{id:"review-code",category:"review",desc:"\u4EE3\u7801\u5BA1\u67E5",expectedIssues:2}];for(let e of t)this.engine.registerScenario(e),this.scenarioIds.push(e.id);}async runScenarioSet(t){let e=async a=>({prepTimeMs:1e3+Math.random()*500,tokenCount:500+Math.floor(Math.random()*200),firstPassSuccess:Math.random()>.5,reworkCount:Math.floor(Math.random()*3),durationMs:5e3+Math.random()*3e3}),s=async a=>({prepTimeMs:500+Math.random()*300,tokenCount:300+Math.floor(Math.random()*100),firstPassSuccess:Math.random()>.2,reworkCount:Math.floor(Math.random()*2),durationMs:3e3+Math.random()*2e3}),r=t??this.scenarioIds,o=await this.engine.runScenarioBatch(r,e,s);return this.results=o,o}async getScenarioResults(){return this.results.length===0&&await this.runScenarioSet(),this.results}async getComparisonSummary(){let t=await this.getScenarioResults(),e=t.length;return {totalScenarios:e,avgTimeSavedRate:t.reduce((s,r)=>s+r.comparison.timeSavedRate,0)/e,avgTokenReductionRate:t.reduce((s,r)=>s+r.comparison.tokenReductionRate,0)/e,avgFirstPassLift:t.reduce((s,r)=>s+r.comparison.firstPassLift,0)/e,avgReworkReductionRate:t.reduce((s,r)=>s+r.comparison.reworkReductionRate,0)/e}}async getExperimentalRoiSummary(){let t=await this.getComparisonSummary();return {totalScenarios:t.totalScenarios,avgTimeSavedRate:t.avgTimeSavedRate,avgTokenReductionRate:t.avgTokenReductionRate,avgFirstPassLift:t.avgFirstPassLift,avgReworkReductionRate:t.avgReworkReductionRate,conclusion:"DevFlow shows significant improvement in all metrics"}}};K=i([Injectable()],K);var U=class{constructor(t){this.service=t;}async run(t){return this.service.runScenarioSet(t.scenarioIds)}async getResults(){return this.service.getScenarioResults()}async getComparisonSummary(){return this.service.getComparisonSummary()}async getExperimentalRoiSummary(){return this.service.getExperimentalRoiSummary()}};i([Post("run"),n(0,Body())],U.prototype,"run",1),i([Get("results")],U.prototype,"getResults",1),i([Get("summary")],U.prototype,"getComparisonSummary",1),i([Get("roi-summary")],U.prototype,"getExperimentalRoiSummary",1),U=i([Controller("benchmark"),n(0,Inject(K))],U);var ct=class{};ct=i([Module({controllers:[U],providers:[K],exports:[K]})],ct);var W=class{constructor(t){this.telemetryService=t;this.plugins=new Map;this.installRecords=[];}async list(t,e){let s=Array.from(this.plugins.values());if(t){let r=t.toLowerCase();s=s.filter(o=>o.name.toLowerCase().includes(r)||o.description.toLowerCase().includes(r));}return e&&(s=s.filter(r=>r.tags.includes(e))),s}async getByName(t){let e=this.plugins.get(t);if(!e)throw new NotFoundException({error:{code:b.PLUGIN_NOT_FOUND,message:`Plugin "${t}" not found`,details:{}}});return e}async publish(t){let e=t.npmPackage.replace(/^@devflow-tools\/plugin-/,""),s={name:e,npmPackage:t.npmPackage,version:t.version,description:t.description,tags:t.tags??[],createdAt:Date.now()};return this.plugins.set(e,s),s}async install(t,e){let s=t.startsWith("@devflow-tools/plugin-")?t:`@devflow-tools/plugin-${t}`,r=t.replace(/^@devflow-tools\/plugin-/,"");return this.plugins.set(r,{name:r,npmPackage:s,version:"0.1.0",description:"Installed plugin",tags:[],createdAt:Date.now()}),e&&await this.recordPluginInstall(r,e),{ok:true,name:r}}async uninstall(t,e){let s=t.replace(/^@devflow-tools\/plugin-/,"");return this.plugins.delete(s),e&&await this.recordPluginUninstall(s,e),{ok:true,name:s}}async recordPluginInstall(t,e){let s=this.installRecords.find(r=>r.pluginName===t&&r.projectRoot===e);s?s.uninstalledAt=void 0:this.installRecords.push({pluginName:t,projectRoot:e,installedAt:Date.now()});}async recordPluginUninstall(t,e){let s=this.installRecords.find(r=>r.pluginName===t&&r.projectRoot===e);s&&(s.uninstalledAt=Date.now());}async listInstalledProjects(t){return this.installRecords.filter(e=>e.pluginName===t&&!e.uninstalledAt).map(e=>e.projectRoot)}async buildPluginEffectiveness(t){let s=(await this.listInstalledProjects(t)).length,r=await this.telemetryService.getPluginUsageStats(t),o=s>0?r.activeProjects/s:0,a=r.totalRuns>0?r.successfulRuns/r.totalRuns:0,u="optimize";return o>.7&&a>.8?u="install":(o<.3||a<.5)&&(u="remove"),{name:t,installCount:s,usageCount:r.totalRuns,activeRate:o,successRate:a,avgTokenImpact:r.avgTokenImpact,lastUsedAt:r.lastUsedAt,recommendation:u}}async getPluginEffectiveness(t){let e=t?this.installRecords.filter(o=>o.projectRoot===t&&!o.uninstalledAt):this.installRecords.filter(o=>!o.uninstalledAt),s=[...new Set(e.map(o=>o.pluginName))],r=[];for(let o of s){let a=await this.buildPluginEffectiveness(o);r.push(a);}return r}};W=i([Injectable(),n(0,Inject(E))],W);var A=class{constructor(t){this.service=t;}async list(t,e){return this.service.list(t,e)}async getPluginEffectiveness(t){return this.service.getPluginEffectiveness(t)}async getByName(t){return this.service.getByName(t)}async publish(t){return this.service.publish(t)}async install(t,e){return this.service.install(t.name,t.rootPath??e)}async uninstall(t,e,s){return this.service.uninstall(t,e.rootPath??s)}};i([Get("plugins"),n(0,Query("search")),n(1,Query("tag"))],A.prototype,"list",1),i([Get("plugins/effectiveness"),n(0,Query("rootPath"))],A.prototype,"getPluginEffectiveness",1),i([Get("plugins/:name"),n(0,Param("name"))],A.prototype,"getByName",1),i([Post("plugins"),n(0,Body())],A.prototype,"publish",1),i([Post("plugins/install"),n(0,Body()),n(1,Headers("x-devflow-project"))],A.prototype,"install",1),i([Post("plugins/:name/uninstall"),n(0,Param("name")),n(1,Body()),n(2,Headers("x-devflow-project"))],A.prototype,"uninstall",1),A=i([Controller("registry"),n(0,Inject(W))],A);var ut=class{};ut=i([Module({imports:[M],controllers:[A],providers:[W],exports:[W]})],ut);var ke={provide:"DATABASE",useFactory:()=>{let c=process.cwd();return new DevFlowDatabase(c)}},lt=class{};lt=i([Global(),Module({providers:[ke],exports:[ke]})],lt);var dt=class{intercept(t,e){return e.handle().pipe(map(s=>s&&typeof s=="object"&&"error"in s?s:{ok:true,data:s??null}))}};dt=i([Injectable()],dt);var Z=class{constructor(){this.startTime=Date.now();}health(){return {version:"0.2.3",uptime:Date.now()-this.startTime}}};i([Zt(),Get("health")],Z.prototype,"health",1),Z=i([Controller()],Z);var mt=class{};mt=i([Module({imports:[lt,et,w,T,ot,it,J,at,M,ct,ut,V],controllers:[Z],providers:[{provide:APP_INTERCEPTOR,useClass:dt}]})],mt);var Q=class{constructor(){this.logger=new Logger(Q.name);}catch(t,e){let r=e.switchToHttp().getResponse();if(t instanceof HttpException){let o=t.getStatus(),a=t.getResponse();if(typeof a=="object"&&a!==null&&"error"in a){r.status(o).send(a);return}let u=typeof a=="string"?a:a.message??"Request failed";r.status(o).send({error:{code:b.INTERNAL_ERROR,message:u,details:{}}});return}this.logger.error("Unhandled exception",t instanceof Error?t.stack:String(t)),r.status(HttpStatus.INTERNAL_SERVER_ERROR).send({error:{code:b.INTERNAL_ERROR,message:"Internal server error",details:{}}});}};Q=i([Catch()],Q);async function cr(){let c=await NestFactory.create(mt,new FastifyAdapter);return c.setGlobalPrefix("api"),c.useGlobalFilters(new Q),c.enableCors({origin:true,credentials:true}),await c.listen({port:13337,host:"0.0.0.0"}),c}(process.argv[1]?.endsWith("main.js")||process.argv[1]?.endsWith("main.ts"))&&cr();export{cr as bootstrap};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/devflow",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
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.1",
19
- "@devflow-tools/benchmark": "^0.8.1",
20
- "@devflow-tools/context-engine": "^0.8.1",
21
- "@devflow-tools/database": "^0.8.1",
22
- "@devflow-tools/knowledge-engine": "^0.8.1",
23
- "@devflow-tools/mcp-server": "^0.8.1",
24
- "@devflow-tools/memory-engine": "^0.8.1",
25
- "@devflow-tools/sdk": "^0.8.1",
26
- "@devflow-tools/telemetry": "^0.8.1",
27
- "@devflow-tools/workflow-engine": "^0.8.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",
28
28
  "@inquirer/prompts": "^7.10.1",
29
29
  "@modelcontextprotocol/sdk": "^1.0.0",
30
30
  "@nestjs/common": "^10.4.0",
@@ -51,5 +51,5 @@
51
51
  "plugin-registry.json",
52
52
  "scripts/postinstall.js"
53
53
  ],
54
- "gitHead": "08e47047445ba2b8112669608264af9971627138"
54
+ "gitHead": "5c9a804d3c2e6e6822b516fde67d5b789dbdb5b3"
55
55
  }