@devflow-tools/devflow 0.16.11 → 0.16.12
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 +60 -58
- package/dist/hooks/hook-daemon.js +32 -14
- package/dist/hooks/memory-snapshot-cache.js +11 -0
- package/dist/hooks/post-tool-use-failure.js +2 -2
- package/dist/hooks/post-tool-use.js +6 -3
- package/dist/hooks/pre-compact.js +2 -2
- package/dist/hooks/pre-tool-use.js +2 -2
- package/dist/hooks/session-end.js +2 -2
- package/dist/hooks/stop.js +15 -2
- package/dist/hooks/user-prompt-submit.js +14 -4
- package/dist/plugin/dist/hooks/hook-daemon.js +32 -14
- package/dist/plugin/dist/hooks/memory-snapshot-cache.js +11 -0
- package/dist/plugin/dist/hooks/post-tool-use-failure.js +2 -2
- package/dist/plugin/dist/hooks/post-tool-use.js +6 -3
- package/dist/plugin/dist/hooks/pre-compact.js +2 -2
- package/dist/plugin/dist/hooks/pre-tool-use.js +2 -2
- package/dist/plugin/dist/hooks/session-end.js +2 -2
- package/dist/plugin/dist/hooks/stop.js +15 -2
- package/dist/plugin/dist/hooks/user-prompt-submit.js +14 -4
- package/dist/plugin/dist/skills/devflow:react/SKILL.md +8 -0
- package/dist/plugin/hooks/session-start +12 -15
- package/dist/plugin/skills/react/SKILL.md +8 -0
- package/package.json +13 -13
- package/plugin-registry.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {existsSync as existsSync$1,mkdirSync as mkdirSync$1,renameSync,readFileSync as readFileSync$1,readdirSync,rmSync,cpSync,lstatSync,writeFileSync as writeFileSync$1,statSync as statSync$1,realpathSync,mkdtempSync,rmdirSync,openSync,constants,fstatSync,readSync,closeSync}from'node:fs';import {createHash,createHmac}from'node:crypto';import {homedir as homedir$1}from'node:os';import {join as join$1,resolve,basename,dirname,relative,sep,isAbsolute,extname}from'node:path';import {fileURLToPath}from'node:url';import {execFileSync,spawnSync}from'node:child_process';import
|
|
3
|
-
`,"utf-8"),a}function
|
|
4
|
-
`);}function
|
|
2
|
+
import {existsSync as existsSync$1,mkdirSync as mkdirSync$1,renameSync,readFileSync as readFileSync$1,readdirSync,rmSync,cpSync,lstatSync,writeFileSync as writeFileSync$1,statSync as statSync$1,realpathSync,mkdtempSync,rmdirSync,openSync,constants,fstatSync,readSync,closeSync}from'node:fs';import {createHash,createHmac}from'node:crypto';import {homedir as homedir$1}from'node:os';import {join as join$1,resolve,basename,dirname,relative,sep,isAbsolute,extname}from'node:path';import {fileURLToPath}from'node:url';import {execFileSync,spawnSync}from'node:child_process';import $s,{existsSync,readFileSync,mkdirSync,writeFileSync,unlinkSync,statSync,rmSync as rmSync$1,renameSync as renameSync$1}from'fs';import Du,{join,dirname as dirname$1}from'path';import {homedir}from'os';import {createRequire}from'module';import ro from'@colbymchenry/codegraph';import {createEngines,OnboardingPackBuilder,getProjectContextResult,getMemoryResult,getKnowledgeResult}from'@devflow-tools/context-engine';import {checkbox}from'@inquirer/prompts';import {MemoryGate,inspectEmbeddingModel,prepareEmbeddingModel,runMemoryMaintenance,EmbeddingProvider,MEMORY_MAINTENANCE_ACTIONS}from'@devflow-tools/memory-engine';import {loadPlugins,getPluginInstallRoot,DEVFLOW_SCHEMA_SQL,DEVFLOW_TABLE_NAMES,redactMcpInventory,readMcpInventory,checkMcpHealth,readCachedMcpHealth,DOCTOR_SCHEMA_VERSION,getLocalHmacSecret,createDefaultHostAdapterRegistry,DevFlowApiClient,selectHostAdapter,loadPluginsWithDiagnostics,readPluginInstallState,upsertPluginInstallRecord,extractPlugin,importPluginModule,removePluginInstallRecord}from'@devflow-tools/sdk';import {fileURLToPath as fileURLToPath$1}from'url';import S from'chalk';import {spawn,execSync,execFileSync as execFileSync$1}from'child_process';import {createRequire as createRequire$1,isBuiltin}from'node:module';import {DatabaseSync}from'node:sqlite';import {getGlobalDevFlowDbPath,DevFlowDatabase,openGlobalDevFlowDatabase}from'@devflow-tools/database';import {connect,listAdapters}from'@devflow-tools/adapters';import Ra from'node:readline';import {KnowledgeEngine}from'@devflow-tools/knowledge-engine';import {getBenchmarkSuite,BenchmarkEngine,renderBenchmarkReport}from'@devflow-tools/benchmark';import {Command}from'commander';var Ts=Object.defineProperty;var $=(e,t)=>()=>(e&&(t=e(e=0)),t);var x=(e,t)=>{for(var n in t)Ts(e,n,{get:t[n],enumerable:true});};function yt(){let e=dirname(fileURLToPath(import.meta.url)),t=[join$1(e,"..","plugin-files"),join$1(e,"plugin"),join$1(e,"..","..","dist","plugin-files"),join$1(e,"..","..","..","..","plugins","claude-code")];for(let n of t)if(existsSync$1(join$1(n,".claude-plugin","plugin.json")))return n;throw new Error("Plugin files not found. Run `npm run build` first.")}function Ee(e=homedir$1(),t={}){let n=t.installedPluginsPath??join$1(e,".claude","plugins","installed_plugins.json"),o=t.pluginCachePath??join$1(e,".claude","plugins","cache");for(let i of qs)try{let c=JSON.parse(readFileSync$1(n,"utf-8")).plugins?.[i];if(!Array.isArray(c))continue;for(let l of c){if(!de(l)||typeof l.installPath!="string"||!existsSync$1(l.installPath)||!statSync$1(l.installPath).isDirectory())continue;let u=typeof l.version=="string"?l.version:Gn(l.installPath);return {root:l.installPath,version:u??null}}}catch{}let r=[];for(let i of ["devflow-local","devflow"]){let a=join$1(o,i,Wt);try{for(let c of readdirSync(a,{withFileTypes:!0})){if(!c.isDirectory())continue;let l=join$1(a,c.name);existsSync$1(join$1(l,"skills"))&&r.push({root:l,version:Gn(l)??c.name,mtimeMs:statSync$1(l).mtimeMs});}}catch{}}r.sort((i,a)=>a.mtimeMs-i.mtimeMs);let s=r[0];return s?{root:s.root,version:s.version}:{root:null,version:null}}function Ve(e,t){let n=Ks(join$1(t,"skills"));if(n.size===0)return [];let o=join$1(e,".claude","skills"),r=[],s;try{s=readdirSync(o,{withFileTypes:!0});}catch{return []}for(let i of s){if(!i.isDirectory())continue;let a=join$1(o,i.name,"SKILL.md"),c=Qn(a);if(!c)continue;let l=n.get(c.name);if(!l)continue;let u=Ut(c.content),d=readFileSync$1(l,"utf-8"),g=Ut(d);r.push({skillName:c.name,globalPath:a,pluginPath:l,globalHash:u,pluginHash:g,isKnownDevFlowArtifact:u===g});}return r.sort((i,a)=>i.skillName.localeCompare(a.skillName))}function Zn(e,t,n,o=Date.now,r={}){let s=Ve(e,t).filter(c=>c.isKnownDevFlowArtifact||r.includeModified===true);if(s.length===0)return [];let i=join$1(e,".devflow","backups","global-skills",new Date(o()).toISOString().replace(/[:.]/g,"-")),a=[];for(let c of s){if(!existsSync$1(c.globalPath)||!lstatSync(c.globalPath).isFile()||Ut(readFileSync$1(c.globalPath,"utf-8"))!==c.globalHash)continue;let l=join$1(i,c.skillName.replaceAll("/","_"),"SKILL.md");mkdirSync$1(dirname(l),{recursive:true});try{renameSync(c.globalPath,l);}catch{continue}try{rmSync(dirname(c.globalPath),{recursive:!1,force:!1});}catch{}a.push({skillName:c.skillName,originalPath:c.globalPath,backupPath:l,hash:c.globalHash,pluginHash:c.pluginHash,contentChanged:!c.isKnownDevFlowArtifact,version:n});}return a.length>0&&writeFileSync$1(join$1(i,"manifest.json"),`${JSON.stringify({version:1,migratedAt:new Date(o()).toISOString(),skills:a},null,2)}
|
|
3
|
+
`,"utf-8"),a}function Ks(e){let t=new Map,n;try{n=readdirSync(e,{withFileTypes:!0});}catch{return t}for(let o of n){if(!o.isDirectory())continue;let r=join$1(e,o.name,"SKILL.md"),s=Qn(r);s&&t.set(s.name,r);}return t}function Qn(e){try{if(!lstatSync(e).isFile())return null;let t=readFileSync$1(e,"utf-8"),n=t.match(/^name:\s*([^\s]+)\s*$/m);return n?.[1]?{name:n[1],content:t}:null}catch{return null}}function Ut(e){return createHash("sha256").update(e).digest("hex")}function Gn(e){try{let t=JSON.parse(readFileSync$1(join$1(e,"package.json"),"utf-8"));return typeof t.version=="string"?t.version:null}catch{return null}}function Xn(e){let t={};if(existsSync$1(e))try{t=JSON.parse(readFileSync$1(e,"utf-8"));}catch{console.warn("Warning: Could not parse settings.json, skipping plugin enablement");return}else mkdirSync$1(dirname(e),{recursive:true});let n=de(t.enabledPlugins)?t.enabledPlugins:{};n[ft]=true,t.enabledPlugins=n;let o=join$1(dirname(e),"plugins","marketplaces",je),r=de(t.extraKnownMarketplaces)?t.extraKnownMarketplaces:{};r[je]={source:{source:"directory",path:o}},t.extraKnownMarketplaces=r,writeFileSync$1(e,`${JSON.stringify(t,null,2)}
|
|
4
|
+
`);}function eo(e,t){let n=join$1(e,".claude"),o=join$1(n,"mcp.json"),r={};if(existsSync$1(o))try{r=JSON.parse(readFileSync$1(o,"utf-8"));}catch{console.warn("Warning: Could not parse existing mcp.json, skipping MCP config");return}else mkdirSync$1(n,{recursive:true});let s=r.mcpServers??{};s.devflow||(s.devflow={command:t,args:[],env:{}},r.mcpServers=s,writeFileSync$1(o,JSON.stringify(r,null,2)));}function to(e,t,n){let o=join$1(t,je,Wt,n);rmSync(o,{recursive:true,force:true}),mkdirSync$1(o,{recursive:true});let r=join$1(e,"hooks");existsSync$1(r)&&mt(r,join$1(o,"hooks"));for(let c of ["CLAUDE.md","package.json"]){let l=join$1(e,c);existsSync$1(l)&&cpSync(l,join$1(o,c),{force:true});}let s=join$1(e,".claude-plugin","plugin.json");existsSync$1(s)&&(mkdirSync$1(join$1(o,".claude-plugin"),{recursive:true}),cpSync(s,join$1(o,".claude-plugin","plugin.json"),{force:true}));let i=join$1(e,"dist");existsSync$1(i)&&mt(i,join$1(o,"dist"));let a=join$1(e,"skills");existsSync$1(a)&&mt(a,join$1(o,"skills")),Vs(o,e),Gs(o),zs(t,o),Js(t,o,n);}function zs(e,t){let n=join$1(e,".."),o=join$1(n,"marketplaces",je),r=join$1(o,".claude-plugin");mkdirSync$1(r,{recursive:true});let s=relative(o,t).replaceAll("\\","/");s.startsWith(".")||(s=`./${s}`),writeFileSync$1(join$1(r,"marketplace.json"),`${JSON.stringify({name:je,description:"DevFlow local Claude Code plugin",owner:{name:"DevFlow"},plugins:[{name:Wt,source:s}]},null,2)}
|
|
5
5
|
`);let i=join$1(n,"known_marketplaces.json"),a={};if(existsSync$1(i)){let c;try{c=JSON.parse(readFileSync$1(i,"utf-8"));}catch{throw new Error(`Could not parse Claude marketplace registry: ${i}`)}if(!de(c))throw new Error(`Invalid Claude marketplace registry: ${i}`);a=c;}a[je]={source:{source:"directory",path:o},installLocation:o,lastUpdated:new Date().toISOString()},writeFileSync$1(i,`${JSON.stringify(a,null,2)}
|
|
6
|
-
`);}function
|
|
7
|
-
`);}function de(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function
|
|
8
|
-
`)}var
|
|
9
|
-
`,"utf-8"),renameSync$1(o,n);}async function Re(e,t=process.cwd(),n){return O(t,async o=>await o.installPlugin(e),async()=>{let o=
|
|
6
|
+
`);}function Js(e,t,n){let o=join$1(e,"..","installed_plugins.json"),r={version:2,plugins:{}};if(existsSync$1(o)){let f;try{f=JSON.parse(readFileSync$1(o,"utf-8"));}catch{throw new Error(`Could not parse Claude plugin registry: ${o}`)}if(!de(f))throw new Error(`Invalid Claude plugin registry: ${o}`);r=f;}else mkdirSync$1(dirname(o),{recursive:true});let s=r.plugins;if(s!==void 0&&!de(s))throw new Error(`Invalid Claude plugin registry plugins: ${o}`);let i=s??{},a=i[ft];if(a!==void 0&&!Array.isArray(a))throw new Error(`Invalid Claude plugin registration for ${ft}`);let c=a??[],l=c.find(f=>de(f)&&f.scope==="user"),u=new Date().toISOString(),d=de(l)&&typeof l.installedAt=="string"?l.installedAt:u,g=c.filter(f=>!de(f)||f.scope!=="user");i[ft]=[...g,{scope:"user",installPath:t,version:n,installedAt:d,lastUpdated:u}],r.version=2,r.plugins=i,writeFileSync$1(o,`${JSON.stringify(r,null,2)}
|
|
7
|
+
`);}function de(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Vs(e,t){let n=join$1(e,"package.json");if(!existsSync$1(n))return;let o=JSON.parse(readFileSync$1(n,"utf-8")),r=Object.keys(o.dependencies??{});if(r.length===0)return;let s={...process.env};delete s.npm_config_allow_scripts,delete s.NPM_CONFIG_ALLOW_SCRIPTS;let i=r.filter(l=>l.startsWith("@devflow-tools/")),a=i.map(l=>join$1(t,"../../packages",l.slice(15))).filter(l=>existsSync$1(join$1(l,"package.json"))),c=["install","--omit=dev","--no-audit","--no-fund","--package-lock=false"];if(i.length>0&&a.length===i.length){c.push("--no-save","--install-links",...a);for(let l of i)rmSync(join$1(e,"node_modules",...l.split("/")),{recursive:true,force:true});}execFileSync("npm",c,{cwd:e,env:s,stdio:"inherit",timeout:1800*1e3});}function mt(e,t){mkdirSync$1(t,{recursive:true});for(let n of readdirSync(e)){let o=join$1(e,n),r=join$1(t,n);statSync$1(o).isDirectory()?mt(o,r):cpSync(o,r,{force:true});}}function Gs(e){let t=join$1(e,"..");if(!existsSync$1(t))return;let n=e.split("/").pop()??"";for(let o of readdirSync(t))if(o!==n){let r=join$1(t,o);statSync$1(r).isDirectory()&&rmSync(r,{recursive:true,force:true});}}var ft,je,Wt,qs,Le=$(()=>{ft="devflow@devflow-local",je="devflow-local",Wt="devflow",qs=["devflow@devflow-local","devflow@devflow"];});var ao={};x(ao,{initProject:()=>ni,renderInitReport:()=>io});async function ni(e,t={}){let n=join(e,".devflow"),o=[];existsSync(n)||(mkdirSync(n,{recursive:true}),o.push(".devflow/"));let r=join(n,"config.json");(!existsSync(r)||t.force)&&(writeFileSync(r,JSON.stringify({version:"0.1.0",initialized:new Date().toISOString()},null,2),"utf-8"),o.push(".devflow/config.json"));let s={created:o,pluginDeployed:false,pluginEnabled:false,mcpConfigured:false,migratedLegacySkills:[]};if(so.isInitialized(e)||await so.init(e,{index:t.scan!==false}),t.scan!==false)try{let{indexer:i,graph:a}=await createEngines(e),{files:c,symbols:l,imports:u}=await i.indexAll(e),d=await a.build(l,u);s.indexed={files:c.length,symbols:l.length,graphNodes:d.nodes.length};}catch{s.indexed={files:0,symbols:0,graphNodes:0};}if(t.scan!==false)try{let i=await new OnboardingPackBuilder().build(e);o.push(".devflow/onboarding-pack.json");let a=join(n,"init-report.md");writeFileSync(a,io(i),"utf-8"),o.push(".devflow/init-report.md"),s.onboardingPack=i;}catch(i){console.warn(`Warning: Onboarding pack generation skipped \u2014 ${i.message}`);}try{let i=yt(),a=homedir(),c=join(a,".claude","plugins","cache"),l=join(i,"package.json"),u=existsSync(l)?JSON.parse(readFileSync(l,"utf-8")).version:"0.0.0";to(i,c,u),s.pluginDeployed=!0;let d=join(c,"devflow-local","devflow",u);try{s.migratedLegacySkills=Zn(a,d,u,Date.now,{includeModified:t.migrateLegacySkills}).map(g=>g.skillName);}catch(g){console.warn(`Warning: Legacy skill migration skipped \u2014 ${g.message}`);}}catch(i){console.warn(`Warning: Plugin deployment skipped \u2014 ${i.message}`);}try{let i=homedir(),a=join(i,".claude","settings.json");Xn(a),s.pluginEnabled=!0;}catch(i){console.warn(`Warning: Plugin enablement skipped \u2014 ${i.message}`);}try{let i;try{i=ti.resolve("@devflow-tools/mcp-server/bin/devflow-mcp.cjs");}catch{i="devflow-mcp";}eo(e,i),s.mcpConfigured=!0;}catch(i){console.warn(`Warning: MCP config skipped \u2014 ${i.message}`);}return s}function io(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(`
|
|
8
|
+
`)}var so,ti,co=$(()=>{Le();so=ro.default??ro,ti=createRequire(import.meta.url);});var lo={};x(lo,{reviewPluginMemoryHints:()=>ii});async function ii(e,t,n={}){let o=n.isTTY??!!process.stdout.isTTY,r=new Set(t.split(",").map(ai).filter(Boolean));if(!o||r.size===0)return {available:0,selected:0};let s=await(n.load??loadPlugins)(),i=[];for(let u of r){let d=s.get(u);for(let g of d?.memory?.project?.conventions??[])i.push({id:`${u}:${g.key}`,pluginName:u,convention:g});}if(i.length===0)return {available:0,selected:0};let a=i.map(u=>({name:`${u.pluginName}: ${u.convention.value}`,value:u.id,checked:false})),c=await(n.select??(u=>checkbox({message:"Select optional plugin memory hints to save",choices:u})))(a),l=i.filter(u=>c.includes(u.id));return l.length>0&&await(n.write??ci)(e,l),{available:i.length,selected:l.length}}function ai(e){return e.trim().replace(/^@devflow-tools\/plugin-/,"").replace(/^plugin-/,"").replace(/^devflow:/,"")}async function ci(e,t){let n=new MemoryGate(e);try{for(let o of t)await n.addMemory({category:"project_knowledge",content:`${o.convention.key}: ${o.convention.value}`,originalText:o.convention.value,source:"manual",confidence:o.convention.confidence,scope:`plugin:${o.pluginName}`});}finally{n.close();}}var uo=$(()=>{});function Fe(){let e=[join(process.cwd(),"plugin-registry.json"),join(mi,"../plugin-registry.json"),join(process.cwd(),"packages/devflow/plugin-registry.json")];for(let t of e)try{let n=readFileSync(t,"utf-8");return JSON.parse(n)}catch{continue}return {version:"0.0.0",lastUpdated:new Date().toISOString(),plugins:[]}}function go(){return Object.keys(readPluginInstallState().plugins).filter(e=>e.startsWith("@devflow-tools/plugin-"))}var fi,mi,vt=$(()=>{fi=fileURLToPath$1(import.meta.url),mi=dirname$1(fi);});async function O(e,t,n,o={}){let r=o.serverUrl??hi;if(o.skipServer)return n();let s=false,i=mo.get(r);if(i&&Date.now()-i.ts<yi?s=i.result:(s=await new DevFlowApiClient({baseUrl:r,projectRoot:e}).ping(),mo.set(r,{result:s,ts:Date.now()})),s){let a=new DevFlowApiClient({baseUrl:r,projectRoot:e});return t(a)}return console.error(S.dim(" (server not running, using local engine \u2014 telemetry disabled)")),n()}var hi,mo,yi,ye=$(()=>{hi=process.env.DEVFLOW_SERVER_URL??"http://127.0.0.1:13337",mo=new Map,yi=3e4;});var ho=$(()=>{});var Ye={};x(Ye,{installSkill:()=>Re,listSkills:()=>So,listSkillsSync:()=>_i,searchSkills:()=>Pi,uninstallSkill:()=>Vt});async function So(e){return O(process.cwd(),async t=>(await t.listPlugins()).map(o=>({name:o.name,version:o.version,description:o.description,icon:o.icon,tags:o.tags??[],installed:true})),async()=>{let t=await loadPlugins();return Array.from(t.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:true})}function _i(){return []}async function Pi(e,t){let n=await So(),o=e.toLowerCase();return n.filter(r=>r.name.toLowerCase().includes(o)||r.description.toLowerCase().includes(o)||r.tags.some(s=>s.toLowerCase().includes(o)))}function _o(e){let t=e.trim().replace(/^@devflow-tools\/(?:plugin-)?/,"");if(!/^[a-z0-9-]+$/.test(t))throw new Error(`Invalid plugin name: ${e}`);return `@devflow-tools/plugin-${t}`}function Po(e){let t=join(e,".devflow","config.json");return existsSync(t)?JSON.parse(readFileSync(t,"utf-8")):{plugins:[]}}function Eo(e,t){let n=join(e,".devflow","config.json");mkdirSync(join(e,".devflow"),{recursive:true});let o=`${n}.${process.pid}.${Date.now()}.tmp`;writeFileSync(o,`${JSON.stringify(t,null,2)}
|
|
9
|
+
`,"utf-8"),renameSync$1(o,n);}async function Re(e,t=process.cwd(),n){return O(t,async o=>await o.installPlugin(e),async()=>{let o=_o(e),r=o.replace(/^@devflow-tools\/plugin-/,"");mkdirSync(Ge,{recursive:true});let i=readPluginInstallState().plugins[o];execFileSync$1("npm",["install","--prefix",Ge,o],{stdio:"pipe",timeout:6e4});let a=Po(t);a.plugins||(a.plugins=[]),a.plugins.includes(r)||(a.plugins.push(r),Eo(t,a));let c=[],l="0.0.0",u=join(Ge,"node_modules",...o.split("/"));try{let d=JSON.parse(readFileSync(join(u,"package.json"),"utf-8"));c=d?.devflow?.templates??[],l=typeof d.version=="string"?d.version:l;}catch{throw new Error(`Installed plugin metadata is unreadable: ${u}`)}if(upsertPluginInstallRecord({packageName:o,pluginName:r,version:l,installPath:u,source:"npm",installedAt:i?.installedAt??new Date().toISOString(),updatedAt:new Date().toISOString(),projects:[...new Set([...i?.projects??[],t])]}),!i||i.version!==l)try{let d=extractPlugin(await importPluginModule({packageName:o,modulePath:u,source:"npm",installPath:u}),o);if(d){let g={projectRoot:t,memory:{getAll:async()=>[],upsertGlobal:async()=>{}},knowledge:{registerSource:async()=>{}},workflow:{registerStepHandler:()=>{}}};i&&d.onUpdate?await d.onUpdate(g,i.version):!i&&d.onInstall&&await d.onInstall(g);}}catch(d){let f=readPluginInstallState().plugins[o];throw f&&(f.lastLoad={status:"failed",checkedAt:new Date().toISOString(),reason:d.message},upsertPluginInstallRecord(f)),new Error(`Plugin lifecycle failed: ${d.message}`)}return {name:r,version:l,templates:c}},{skipServer:true})}async function Vt(e,t=process.cwd(),n){return O(t,async o=>{await o.uninstallPlugin(e);},async()=>{let o=_o(e),r=o.replace(/^@devflow-tools\/plugin-/,""),s=Po(t);s.plugins&&(s.plugins=s.plugins.filter(l=>l!==r),Eo(t,s));let a=readPluginInstallState().plugins[o],c=a?.projects.filter(l=>l!==t)??[];if(a&&c.length===0){let l=existsSync(a.installPath)?extractPlugin(await importPluginModule({packageName:o,modulePath:a.installPath,source:a.source,installPath:a.installPath}),o):null;l?.onUninstall&&await l.onUninstall({projectRoot:t,memory:{getAll:async()=>[],upsertGlobal:async()=>{}},knowledge:{registerSource:async()=>{}},workflow:{registerStepHandler:()=>{}}});}if(!a||c.length===0)try{execFileSync$1("npm",["uninstall","--prefix",Ge,o],{stdio:"pipe",timeout:6e4});}catch{let l=join(Ge,"node_modules",o);existsSync(l)&&rmSync$1(l,{recursive:true,force:true});}a&&(c.length>0?(a.projects=c,upsertPluginInstallRecord(a)):removePluginInstallRecord(o));},{skipServer:true})}var Ge,ve=$(()=>{ye();ho();Ge=getPluginInstallRoot();});var Gt={};x(Gt,{detectTechStack:()=>Co,guidePluginInstallation:()=>$i,installPluginsFromList:()=>Di,resolvePluginName:()=>Ro});function Co(e){let t=[];try{let n=JSON.parse(readFileSync(join(e,"package.json"),"utf-8")),o={...n.dependencies??{},...n.devDependencies??{}};o.react&&t.push("react"),o.next&&t.push("nextjs"),o.vue&&t.push("vue"),o.tailwindcss&&t.push("tailwind"),(o.nest||o["@nestjs/core"])&&t.push("nest"),o.express&&t.push("express"),o.typescript&&t.push("typescript");}catch{}return t}function Ro(e){let t=e.trim();return t?`@devflow-tools/plugin-${t.replace(/^@devflow-tools\/(?:plugin-)?/,"")}`:""}async function Di(e){let t=e.split(",").map(Ro).filter(Boolean);if(t.length!==0)for(let n of t){console.log(`Installing ${n}...`);try{await Re(n,process.cwd(),!0),console.log(`\u2713 ${n}`);}catch{console.error(`\u2717 Failed to install ${n}`);}}}async function $i(e){let t=Fe();if(t.plugins.length===0)return console.log(`
|
|
10
10
|
No plugins available. You can install plugins later with:`),console.log(" devflow plugin list"),console.log(` devflow plugin install <name>
|
|
11
11
|
`),[];console.log(`
|
|
12
12
|
\u{1F50C} Plugin Installation Guide
|
|
13
|
-
`);let n=
|
|
13
|
+
`);let n=Co(e);n.length>0&&console.log(`Detected tech stack: ${n.join(", ")}
|
|
14
14
|
`);let o=new Set(t.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...
|
|
15
15
|
`);let i=[...o];for(let a of i)try{await Re(a,e,!0),console.log(`\u2713 ${a}`);}catch{console.error(`\u2717 Failed to install ${a}`);}return i}let r=t.plugins.map(i=>({name:`${i.name.replace("@devflow-tools/","")} - ${i.description.substring(0,50)}`,value:i.name,checked:o.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(`
|
|
16
16
|
Plugin installation cancelled.
|
|
@@ -20,23 +20,24 @@ Installing selected plugins...
|
|
|
20
20
|
`);}catch{console.error(`\u2717 Failed to install ${i}
|
|
21
21
|
`);}}else console.log(`
|
|
22
22
|
Skipping plugin installation. You can install plugins later with:`),console.log(" devflow plugin list"),console.log(` devflow plugin install <name>
|
|
23
|
-
`);return s}var Yt
|
|
23
|
+
`);return s}var Yt=$(()=>{vt();ve();});var Lo={};x(Lo,{ResetExecutionError:()=>Ze,executeResetCommand:()=>Zi,formatResetResult:()=>tn,runReset:()=>Mo});function Wi(){if(kt)return kt;try{let e=createRequire$1(import.meta.url)("node:sqlite");if(typeof e.DatabaseSync!="function")throw new Error("DatabaseSync is unavailable");return kt=e.DatabaseSync,kt}catch{throw new Error("DevFlow reset requires Node.js >=22.13.0 to back up SQLite databases (node:sqlite is unavailable).")}}function tn(e){return [...e.backedUp.map(t=>`Backed up: ${t.source} -> ${t.destination}`),...e.removed.map(t=>`Removed: ${t}`)]}function Bi(e){return e==="all"||No.includes(e)}function le(e){try{return lstatSync(e)}catch(t){if(t.code==="ENOENT")return;throw t}}function Qt(e){let t=resolve(e),n=[];for(;!le(t);){let o=dirname(t);if(o===t)throw new Error(`Cannot resolve path: ${e}`);n.unshift(basename(t)),t=o;}return resolve(realpathSync(t),...n)}function nn(e,t){let n=relative(e,t);return n===""||!isAbsolute(n)&&n!==".."&&!n.startsWith(`..${sep}`)}function qi(e){if(typeof e!="string"||e.trim()==="")throw new Error("Project path must be an existing directory.");let t=resolve(e);try{if(!statSync$1(t).isDirectory())throw new Error("not a directory");return realpathSync(t)}catch{throw new Error(`Project path must be an existing directory: ${t}`)}}function To(e,t){let n=e;for(let o of relative(e,t).split(sep)){n=join$1(n,o);let r=le(n);if(!r)break;if(r.isSymbolicLink())throw new Error(`Refusing to reset a target path containing a symbolic link: ${n}`)}if(le(t)){let o=realpathSync(t);if(!nn(e,o))throw new Error(`Refusing to reset a target outside the project: ${t}`)}}function Ki(e,t){return (e==="all"?No:[e]).map(o=>({scope:o,path:join$1(t,...Oo[o])}))}function jo(e,t){let n=le(t);if(n)return To(e,t),{canonicalPath:realpathSync(t),device:n.dev,inode:n.ino}}function Io(e,t){let n=jo(e,t.path);if(!n||n.canonicalPath!==t.identity.canonicalPath||n.device!==t.identity.device||n.inode!==t.identity.inode)throw new Error(`Reset target changed after preflight: ${t.path}`)}function zi(e){let t=le(e);if(!t?.isFile()||t.size<Zt.length)return false;let n=Buffer.alloc(Zt.length),o=openSync(e,"r");try{return readSync(o,n,0,n.length,0)===n.length&&n.equals(Zt)}finally{closeSync(o);}}function Ji(e){let t=[];function n(o){let r=lstatSync(o);if(!r.isSymbolicLink()){if(r.isDirectory()){for(let s of readdirSync(o).sort())n(join$1(o,s));return}zi(o)&&t.push(o);}}return n(e),t}function Vi(e,t){mkdirSync$1(dirname(t),{recursive:true});let n=new(Wi())(e,{readOnly:true,timeout:1e3});try{n.prepare("VACUUM INTO ?").run(t);}finally{n.close();}}function Gi(e,t,n){let o=Ji(e),r=new Set;for(let s of o)r.add(s),r.add(`${s}-journal`),r.add(`${s}-shm`),r.add(`${s}-wal`);n(),cpSync(e,t,{recursive:true,filter:s=>!r.has(s)});for(let s of o){n();let i=join$1(t,relative(e,s));Vi(s,i);}}function Yi(e,t,n,o,r){let s=!!le(t),i,a=[];try{mkdirSync$1(t,{recursive:!0}),i=mkdtempSync(join$1(t,".devflow-reset-"));for(let c of n)r.beforeBackup(c.path),Gi(c.path,join$1(i,c.scope),()=>Io(e,c));for(let c of n){let l=join$1(i,c.scope),u=join$1(t,c.scope);if(le(u))throw new Error(`Backup destination already exists: ${u}`);r.renamePath(l,u),a.push(u),o.backedUp.push({source:c.path,destination:u});}}catch(c){for(let l of a.reverse())rmSync(l,{recursive:true,force:true});throw new Error(`Failed to prepare reset backup: ${c.message}`)}finally{if(i&&rmSync(i,{recursive:true,force:true}),!s&&le(t))try{rmdirSync(t);}catch{}}}function Mo(e,t={}){if(!Bi(e.scope))throw new Error(`Invalid reset scope: ${String(e.scope)}. Expected memory, knowledge, codegraph, or all.`);let n=qi(e.project??process.cwd()),o=Ki(e.scope,n);for(let c of o)To(n,c.path);if(!e.backupTo&&!e.force)throw new Error("Refusing to reset without a backup. Provide --backup-to <dir> or use --force.");let r=o.flatMap(c=>{let l=jo(n,c.path);return l?[{...c,identity:l}]:[]}),s=e.backupTo?Qt(e.backupTo):void 0;if(s){let c=le(s);if(c&&!c.isDirectory())throw new Error(`Backup path must be a directory: ${s}`);for(let l of r){let u=Qt(l.path),d=join$1(s,l.scope),g=Qt(d);if(nn(u,g)||nn(g,u))throw new Error(`Backup destination cannot be inside or contain a target being removed: ${g}`);if(le(d))throw new Error(`Backup destination already exists: ${d}`)}}let i={backedUp:[],removed:[]},a={beforeBackup:()=>{},beforeRemoval:()=>{},renamePath:(c,l)=>renameSync(c,l),removePath:c=>rmSync(c,{recursive:true,force:true}),...t};s&&r.length>0&&Yi(n,s,r,i,a);for(let c of r){try{a.beforeRemoval(c.path),Io(n,c),a.removePath(c.path);}catch(l){let u=l instanceof Error?`: ${l.message}`:"";throw new Ze(`Failed to remove reset target: ${c.path}${u}`,i,l)}i.removed.push(c.path);}return i}function Zi(e,t={},n=console){try{let o=Mo(e,t),r=tn(o);for(let s of r)n.log(s);return r.length===0&&n.log("Nothing to reset."),!0}catch(o){if(o instanceof Ze)for(let r of tn(o.result))n.log(r);return n.error(`Error: ${o.message}`),false}}var kt,Ze,Oo,No,Zt,Fo=$(()=>{Ze=class extends Error{constructor(t,n,o){super(t,{cause:o}),this.name="ResetExecutionError",this.result={backedUp:[...n.backedUp],removed:[...n.removed]};}};Oo={memory:[".devflow","memory"],knowledge:[".devflow","knowledge"],codegraph:[".codegraph"]},No=Object.keys(Oo),Zt=Buffer.from("SQLite format 3\0","binary");});var Vo={};x(Vo,{consolidateDatabases:()=>ta,formatConsolidateResult:()=>na});function ta(e){let t=resolve(e.project),n=e.globalDbPath??getGlobalDevFlowDbPath(),o=join$1(t,".devflow","devflow.db"),r=join$1(t,".codegraph","codegraph.db");if(resolve(n)===resolve(o))throw new Error("The global target database cannot be the project-local legacy database");let s=existsSync$1(n),i=[Uo("project",o,s?n:void 0),Uo("codegraph",r,s?n:void 0)],a={dryRun:!!e.dryRun,targetPath:n,sources:i,inserted:{},retired:[]};if(e.dryRun)return a;let c=i.filter(f=>f.exists&&Object.keys(f.tables).length>0),l=new Date(e.now??Date.now()).toISOString().replace(/[:.]/g,"-"),u=basename(dirname(n))==="global"?join$1(dirname(dirname(n)),"backup"):join$1(dirname(n),"backup"),d=join$1(e.backupRoot??u,l);mkdirSync$1(d,{recursive:true}),a.backupDir=d;let g=c.some(f=>f.kind==="project")?oa(o):null;try{let f=new Map;for(let y of c){let k=join$1(d,`${y.kind}-${basename(y.path)}.snapshot`);Wo(y.path,k),f.set(y.kind,k);}s&&Wo(n,join$1(d,"global-devflow.db.before"));let p=f.has("project")?sa(o,d):[];a.retired.push(...p.map(y=>y.destination));let m=null,h=!1;try{if(new DevFlowDatabase(t,{dbPath:n}).close(),m=new DatabaseSync(n),m.exec("PRAGMA busy_timeout = 10000"),m.exec(DEVFLOW_SCHEMA_SQL),f.has("project")&&m.prepare("ATTACH DATABASE ? AS project_source").run(f.get("project")),f.has("codegraph")&&m.prepare("ATTACH DATABASE ? AS codegraph_source").run(r),m.exec("BEGIN IMMEDIATE"),h=!0,f.has("project")&&Bo(m,"project_source",void 0,a.inserted),f.has("codegraph")){Bo(m,"codegraph_source",new Set(DEVFLOW_TABLE_NAMES),a.inserted);for(let k of et(m,"codegraph_source").filter(R=>R.startsWith("devflow_")))m.exec(`DROP TABLE codegraph_source.${M(k)}`);}m.exec("COMMIT"),h=!1;}catch(y){if(h)try{m?.exec("ROLLBACK");}catch{}throw Jo(p),y}finally{m?.close();}return a}finally{ra(g);}}function na(e){let t=[`${e.dryRun?"Dry run":"Consolidated"} target: ${e.targetPath}`];for(let n of e.sources){let o=Object.values(n.tables).reduce((s,i)=>s+i,0),r=Object.values(n.conflicts).reduce((s,i)=>s+i,0);t.push(`${n.kind}: ${n.exists?`${o} rows, ${r} conflicts`:"not found"} (${n.path})`);}if(!e.dryRun){let n=Object.values(e.inserted).reduce((o,r)=>o+r,0);t.push(`Inserted: ${n} rows`),e.backupDir&&t.push(`Backup: ${e.backupDir}`);}return t}function Uo(e,t,n){let o={kind:e,path:t,exists:existsSync$1(t),tables:{},conflicts:{}};if(!o.exists)return o;let r=new DatabaseSync(t,{readOnly:true}),s=n&&existsSync$1(n)?new DatabaseSync(n,{readOnly:true}):null;try{let i=e==="codegraph"?new Set(DEVFLOW_TABLE_NAMES):null;for(let a of et(r).filter(c=>!i||i.has(c)))o.tables[a]=an(r,a),o.conflicts[a]=s&&et(s).includes(a)?ia(r,s,a):0;}finally{r.close(),s?.close();}return o}function Wo(e,t){mkdirSync$1(dirname(t),{recursive:true});let n=new DatabaseSync(e,{readOnly:true,timeout:1e4});try{n.prepare("VACUUM INTO ?").run(t);}finally{n.close();}}function oa(e){let t=new DatabaseSync(e);t.exec("PRAGMA busy_timeout = 1000");try{return t.exec("BEGIN IMMEDIATE"),t}catch(n){throw t.close(),new Error(`Cannot lock legacy database for migration: ${n.message}`)}}function ra(e){if(e){try{e.exec("ROLLBACK");}catch{}e.close();}}function sa(e,t){let n=[];try{for(let o of ["","-wal","-shm"]){let r=`${e}${o}`;if(!existsSync$1(r))continue;let s=join$1(t,`project-devflow.db.retired${o}`);renameSync(r,s),n.push({source:r,destination:s});}}catch(o){throw Jo(n),o}return n}function Jo(e){for(let t of e.reverse())existsSync$1(t.destination)&&!existsSync$1(t.source)&&renameSync(t.destination,t.source);}function Bo(e,t,n,o){let r=new Set(et(e)),s=et(e,t).filter(i=>r.has(i)&&(!n||n.has(i)));for(let i of s){let a=bt(e,"main",i),c=new Set(bt(e,t,i).map(p=>p.name)),l=a.filter(p=>c.has(p.name));if(sn.has(i)&&(l=l.filter(p=>p.pk===0)),l.length===0)continue;let u=an(e,i),d=l.map(p=>M(p.name)).join(", "),g=l.map(p=>`s.${M(p.name)}`).join(", ");if(l.filter(p=>p.pk>0).length>0&&!sn.has(i))e.exec(`INSERT OR IGNORE INTO main.${M(i)} (${d}) SELECT ${g} FROM ${M(t)}.${M(i)} s`);else {let p=l.map(m=>`t.${M(m.name)} IS s.${M(m.name)}`).join(" AND ");e.exec(`
|
|
24
24
|
INSERT INTO main.${M(i)} (${d})
|
|
25
25
|
SELECT ${g} FROM ${M(t)}.${M(i)} s
|
|
26
26
|
WHERE NOT EXISTS (SELECT 1 FROM main.${M(i)} t WHERE ${p})
|
|
27
|
-
`);}o[i]=(o[i]??0)+(an(e,i)-u);}}function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
`)
|
|
32
|
-
|
|
27
|
+
`);}o[i]=(o[i]??0)+(an(e,i)-u);}}function ia(e,t,n){let o=new Set(bt(t,"main",n).map(l=>l.name)),r=bt(e,"main",n).filter(l=>l.pk>0&&o.has(l.name));if(r.length===0||sn.has(n))return 0;let s=r.map(l=>M(l.name)),i=e.prepare(`SELECT ${s.join(", ")} FROM ${M(n)}`).all(),a=r.map(l=>`${M(l.name)} IS ?`).join(" AND "),c=t.prepare(`SELECT 1 found FROM ${M(n)} WHERE ${a} LIMIT 1`);return i.reduce((l,u)=>l+(c.get(...r.map(d=>u[d.name]))?1:0),0)}function et(e,t="main"){return e.prepare(`SELECT name FROM ${M(t)}.sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name`).all().map(o=>o.name)}function bt(e,t,n){return e.prepare(`PRAGMA ${M(t)}.table_info(${M(n)})`).all()}function an(e,t){let n=e.prepare(`SELECT COUNT(*) count FROM ${M(t)}`).get();return Number(n.count)}function M(e){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new Error(`Unsafe SQLite identifier: ${e}`);return `"${e}"`}var sn,Go=$(()=>{sn=new Set(["run_steps","telemetry_events","devflow_tool_calls","devflow_audit_chain"]);});var Yo={};x(Yo,{connectAgent:()=>la,getAvailableAgents:()=>ua});async function la(e){let t=[],n={command:e.command??"devflow-mcp",args:["--mode","stdio"]},o=e.agent?[e.agent]:await import('@devflow-tools/adapters').then(r=>r.detectAll());for(let r of o){let s=await connect(r,n);t.push(`${r}: ${s.configPath} (${s.written?"written":"skipped"})`);}return t}function ua(){return listAdapters()}var Zo=$(()=>{});var Xo={};x(Xo,{getIndexStatus:()=>da,refreshIndex:()=>ga});async function da(e){return O(process.cwd(),t=>t.getIndexStatus(),async()=>{let{codegraph:t}=await createEngines(process.cwd()),n=t.getStats();return {totalFiles:n.fileCount,totalSymbols:n.nodeCount,lastIndexTime:n.lastUpdated,indexing:t.isIndexing()}},{skipServer:e})}async function ga(e){return O(process.cwd(),t=>t.triggerIndex(),async()=>{let{indexer:t}=await createEngines(process.cwd());return await t.reconcile(),t.getStatus()},{skipServer:e})}var er=$(()=>{ye();});var tr={};x(tr,{getGraph:()=>ma});async function ma(e={}){let t=e.target??"all",n=e.depth??2;return O(process.cwd(),o=>o.getGraph(t,n),async()=>{let{graph:o}=await createEngines(process.cwd());if(t==="all")return o.export();let r=o.getSubGraph(t,n);return {nodes:r.nodes,edges:r.edges}},{skipServer:e.skipServer})}var nr=$(()=>{ye();});var cn={};x(cn,{getContext:()=>ha,getTaskContext:()=>ya});async function ha(e){return O(process.cwd(),t=>t.buildContext(e.query,e.mode??"fast",e.maxTokens),async()=>{let{context:t}=await createEngines(process.cwd());return t.build({query:e.query,mode:e.mode??"fast",maxTokens:e.maxTokens??8e3})},{skipServer:e.skipServer})}async function ya(e){let t=process.cwd(),n={mode:e.mode??"fast",maxTokens:e.maxTokens??8e3};return O(t,o=>o.buildTaskContext(e.query,t,n),async()=>{let{context:o,codegraph:r}=await createEngines(t),s=r.getStats().lastUpdated,i=s>0?Date.now()-s:0;return getProjectContextResult(o,{query:e.query,...n},i)},{skipServer:e.skipServer})}var ln=$(()=>{ye();});var tt={};x(tt,{getWorkflowRuns:()=>rr,getWorkflowStatus:()=>wa,listWorkflows:()=>va,runWorkflow:()=>ka});async function va(e){return O(process.cwd(),t=>t.listWorkflows(),async()=>{let{workflow:t}=await createEngines(process.cwd());return t.list()},{skipServer:e})}async function ka(e,t,n){return O(process.cwd(),o=>o.runWorkflow(e,t),async()=>{let{workflow:o}=await createEngines(process.cwd());return o.run(e,t)},{skipServer:n})}async function wa(e){return rr(e)}async function rr(e){return O(process.cwd(),t=>t.getWorkflowRuns(),async()=>{let{workflow:t}=await createEngines(process.cwd());return t.listRuns()},{skipServer:e})}var nt=$(()=>{ye();});var dn={};x(dn,{getEmbeddingStatus:()=>_a,prepareEmbeddings:()=>Pa,renderEmbeddingStatus:()=>Ea});async function _a(){return inspectEmbeddingModel()}async function Pa(e={}){return prepareEmbeddingModel({endpoints:e.endpoints,timeoutMs:e.timeoutMs})}function Ea(e){let t=[`Embedding model: ${e.state}`,` model: ${e.modelId}`,` revision: ${e.revision}`,` cache: ${e.cacheRoot}`];return e.missingFiles.length>0&&t.push(` missing: ${e.missingFiles.join(", ")}`),e.corruptFiles.length>0&&t.push(` corrupt: ${e.corruptFiles.join(", ")}`),t.join(`
|
|
28
|
+
`)}var gn=$(()=>{});var De={};x(De,{backfillObservationVectors:()=>Oa,queryMemory:()=>$a,reviewCandidates:()=>xa,reviewMemories:()=>Ta,setMemory:()=>Aa,showMemory:()=>Da});async function Da(e,t){let n=await O(process.cwd(),r=>r.getMemory(t),async()=>{let{memory:r}=await createEngines(process.cwd());return r.getAll()},{skipServer:e});if(!t||!n||typeof n!="object")return n;let o=n;return Array.isArray(o.memories)?{...o,memories:o.memories.filter(r=>r?.source===t)}:n}async function $a(e={}){let t=process.cwd(),{skipServer:n,...o}=e;return O(t,r=>r.queryMemory(o),async()=>{let{memory:r}=await createEngines(t);return getMemoryResult(r,o)},{skipServer:n})}async function Aa(e,t,n){return O(process.cwd(),async o=>{await o.setMemory("project",e,t);},async()=>{let{memory:o}=await createEngines(process.cwd());await o.updateUserPreference(e,t);},{skipServer:n})}async function xa(e){return O(process.cwd(),t=>t.reviewCandidates(),async()=>{let{memory:t}=await createEngines(process.cwd());return t.getCandidates()},{skipServer:e})}async function Oa(e={}){let{memory:t}=await createEngines(e.projectRoot??process.cwd());return t.backfillObservationVectors({batchSize:e.batchSize,onProgress:e.onProgress})}function Na(e){let t=Ra.createInterface({input:process.stdin,output:process.stdout});return new Promise(n=>{t.question(e,o=>{t.close(),n(o.trim().toLowerCase());});})}async function Ta(){let t=await O(process.cwd(),async r=>(await r.getMemory()).memories?.filter(i=>i.status==="pending")??[],async()=>{let{memory:r}=await createEngines(process.cwd());return r.getPendingMemories()},{skipServer:false});if(t.length===0){console.log("No pending memories to review.");return}let n=[...t].sort((r,s)=>r.category==="failure_lesson"&&s.category!=="failure_lesson"?-1:s.category==="failure_lesson"&&r.category!=="failure_lesson"?1:0),o=0;for(let r of n){console.log(`
|
|
29
|
+
[${r.category}] (confidence: ${(r.confidence*100).toFixed(0)}%)`),console.log(` ${r.content}`);let s=await Na(" Approve? [y]es / [n]o / [s]kip: ");s==="y"?(await O(process.cwd(),async i=>{await i.approveMemory(r.id);},async()=>{},{skipServer:false}),console.log(" Approved"),o++):s==="n"?(await O(process.cwd(),async i=>{await i.rejectMemory(r.id);},async()=>{},{skipServer:false}),console.log(" Rejected"),o++):console.log(" -> Skipped");}console.log(`
|
|
30
|
+
Reviewed ${o}/${t.length} pending memories.`);}var $e=$(()=>{ye();});var ir={};x(ir,{getDocsStatus:()=>Ma,queryKnowledge:()=>sr,searchKnowledge:()=>Ia,syncDocs:()=>La});async function sr(e,t,n,o){return O(process.cwd(),r=>r.queryKnowledge(e,{scope:t,budgetTokens:n}),()=>{let r=new KnowledgeEngine({projectRoot:process.cwd(),embedder:new EmbeddingProvider});return getKnowledgeResult(r,{query:e,scope:t,budgetTokens:n})},{skipServer:o})}async function Ia(e,t,n){return (await sr(e,t,void 0,n)).results}async function Ma(e){return O(process.cwd(),t=>t.getKnowledgeSources(),()=>new KnowledgeEngine({projectRoot:process.cwd(),embedder:new EmbeddingProvider}).getSources(),{skipServer:e})}async function La(e,t){return O(process.cwd(),n=>n.syncDocs(e),()=>new KnowledgeEngine({projectRoot:process.cwd(),embedder:new EmbeddingProvider}).syncDocs(e),{skipServer:t})}var ar=$(()=>{ye();});var pn={};x(pn,{backfillKnowledgeVectors:()=>Wa,resyncKnowledgeDocs:()=>Ua});function cr(e){return new KnowledgeEngine({projectRoot:e,embedder:new EmbeddingProvider})}async function Ua(e){if(!e.withHeadings)throw new Error("Knowledge resync requires --with-headings");let t=cr(e.projectRoot??process.cwd());try{return await t.syncDocs(e.source,{withHeadings:!0,deferVectorBackfill:!0})}finally{t.close();}}async function Wa(e={}){let t=cr(e.projectRoot??process.cwd());try{return await t.backfillVectors({source:e.source,batchSize:e.batchSize,onProgress:e.onProgress})}finally{t.close();}}var hn=$(()=>{});var ur={};x(ur,{inspectSkillHealth:()=>St,showSkillHealth:()=>za});function Ka(e){let t=readFileSync$1(e,"utf8"),n=/^---\r?\n([\s\S]*?)\r?\n---/.exec(t);if(!n)return {};let o={};for(let r of n[1].split(/\r?\n/)){let s=r.indexOf(":");if(s<1)continue;let i=r.slice(0,s).trim(),a=r.slice(s+1).trim();(i==="name"||i==="description")&&(o[i]=a);}return o}function St(e){let t=e===void 0?Ee(homedir$1()).root:e;if(!t)return {pluginRoot:null,registryVersion:null,skills:0,commands:0,healthy:false,issues:[{category:"missing",reason:"No active DevFlow Claude plugin found"}]};let n=[],o=[join$1(t,"dist","command-registry.json"),join$1(t,"command-registry.json")].find(existsSync$1),r=null,s={};if(!o)n.push({category:"missing",reason:"command-registry.json is missing"});else try{let c=JSON.parse(readFileSync$1(o,"utf8"));r=typeof c.version=="number"?c.version:null,r!==1&&r!==2&&n.push({category:"unsupported",path:o,reason:`unsupported registry version ${String(c.version)}`}),c.commands&&typeof c.commands=="object"?s=c.commands:n.push({category:"malformed",path:o,reason:"commands object is missing"});}catch(c){n.push({category:"malformed",path:o,reason:c.message});}let i=join$1(t,"skills"),a=new Map;if(!existsSync$1(i))n.push({category:"missing",path:i,reason:"skills directory is missing"});else for(let c of readdirSync(i,{withFileTypes:true})){if(!c.isDirectory())continue;let l=join$1(i,c.name,"SKILL.md");if(!existsSync$1(l))continue;let u=Ka(l);if(!u.name||!u.description){n.push({category:"malformed",skill:c.name,path:l,reason:"frontmatter name and description are required"});continue}/^devflow(?::[a-z0-9-]+)?$/.test(u.name)||n.push({category:"unsupported",skill:u.name,path:l,reason:"skill name is outside the canonical DevFlow namespace"});let d=u.name.startsWith("devflow:")?u.name.slice(8):u.name;u.name!==c.name&&d!==c.name&&n.push({category:"stale",skill:u.name,path:l,reason:`directory name ${c.name} does not match frontmatter`});let g=a.get(u.name)??[];g.push(l),a.set(u.name,g);}for(let[c,l]of a)l.length>1&&n.push({category:"duplicate",skill:c,reason:l.join(", ")}),c!=="devflow"&&!s[c]&&!["devflow:doctor","devflow:start"].includes(c)&&n.push({category:"unbound",skill:c,path:l[0],reason:"skill has no command registry entry"});for(let[c,l]of Object.entries(s))if(a.has(c)||n.push({category:"missing",skill:c,reason:"registry command has no installed SKILL.md"}),(!Array.isArray(l.mcpTools)||l.mcpTools.some(u=>typeof u!="string"))&&n.push({category:"malformed",skill:c,reason:"mcpTools must be a string array"}),r===2&&typeof l.skillPath=="string"){let u=join$1(t,l.skillPath),d=join$1(t,l.skillPath.replace(/^skills\/devflow:/,"skills/"));!existsSync$1(u)&&!existsSync$1(d)&&n.push({category:"stale",skill:c,path:l.skillPath,reason:"registry skillPath does not exist"});}return {pluginRoot:t,registryVersion:r,skills:a.size,commands:Object.keys(s).length,issues:n,healthy:n.length===0}}function za(e={}){let t=St(e.root);if(e.json)console.log(JSON.stringify(t,null,2));else {console.log(`Skills: ${t.skills}, registry commands: ${t.commands}, version: ${t.registryVersion??"missing"}`);for(let n of t.issues)console.log(`${n.category.toUpperCase()} ${n.skill??"runtime"}: ${n.reason}`);}return t.healthy?0:1}var yn=$(()=>{Le();});var vn={};x(vn,{showMcpHealth:()=>Qa,showMcpInventory:()=>Za});async function Za(e={}){let t=redactMcpInventory(readMcpInventory(e.project??process.cwd()));if(e.json){console.log(JSON.stringify(t,null,2));return}for(let n of t.servers){let o=n.drift?.length?` [${n.drift.join(", ")}]`:"";console.log(`${n.name} ${n.transport} ${n.enabled?"enabled":"disabled"}${o}`),console.log(` sources: ${n.sourcePaths.join(", ")}`),console.log(` fingerprint: ${n.fingerprint}`);}t.duplicates.length&&console.log(`duplicates: ${t.duplicates.map(n=>n.name).join(", ")}`),t.unreadable.length&&console.error(`unreadable: ${t.unreadable.map(n=>n.path).join(", ")}`);}async function Qa(e={}){let t=e.refresh?await checkMcpHealth(readMcpInventory(e.project??process.cwd())):readCachedMcpHealth(homedir$1());if(e.json){console.log(JSON.stringify(t,null,2));return}for(let n of t.records){let o=n.failureCategory?` ${n.failureCategory}: ${n.lastError??""}`:"";console.log(`${n.status.toUpperCase()} ${n.name} failures=${n.failureCount}${o}`);}}var kn=$(()=>{});var Pt={};x(Pt,{DEFAULT_SERVER_PORT:()=>_t,readPidFromFile:()=>_n,readPortFromFile:()=>pr,serverStatus:()=>st,startServer:()=>Pn,stopServer:()=>rt});function Sn(e){let t=join(e,".devflow");return existsSync(t)||mkdirSync(t,{recursive:true}),join(t,"server.pid")}function oc(){try{return fr.resolve("./server.js")}catch{try{return fr.resolve("@devflow-tools/server/dist/main.js")}catch{return join(process.cwd(),"apps","server","dist","main.js")}}}function pr(e){if(!existsSync(e))return null;let t=readFileSync(e,"utf-8").trim().split(`
|
|
31
|
+
`);if(t.length>=2){let n=parseInt(t[0],10);if(!isNaN(n))return n}return null}function _n(e){if(!existsSync(e))return null;let t=readFileSync(e,"utf-8").trim().split(`
|
|
32
|
+
`),n=t.length>=2?t[1]:t[0],o=parseInt(n,10);return isNaN(o)?null:o}async function Pn(e){let t=oc(),n=Sn(process.cwd()),o=spawn("node",[t],{env:{...process.env,PORT:String(e.port)},stdio:"ignore",detached:true});return writeFileSync(n,`${e.port}
|
|
33
|
+
${o.pid??0}`),o.unref(),{pid:o.pid??0}}async function rt(){let e=Sn(process.cwd()),t=_n(e);if(t===null)return false;try{return process.kill(t),unlinkSync(e),!0}catch{return unlinkSync(e),false}}async function st(){let e=Sn(process.cwd()),t=pr(e)??_t,{DevFlowApiClient:n}=await import('@devflow-tools/sdk');return await new n({baseUrl:`http://127.0.0.1:${t}`,projectRoot:process.cwd()}).ping()?{running:true,pid:_n(e)??void 0,port:t}:{running:false,port:t}}var fr,_t,we=$(()=>{fr=createRequire(import.meta.url);_t=13337;});var Qr={};x(Qr,{renderDoctorText:()=>Yr,runDoctor:()=>Ml,runDoctorAudit:()=>Fl,runDoctorAuditFix:()=>Hl,runDoctorCommand:()=>Ll,runDoctorReceipts:()=>Wl,runDoctorViolations:()=>Ul,runLegacyDoctorReport:()=>Zr,runStructuredDoctor:()=>Un});function Nt(e){return createHash("sha256").update(e).digest("hex").slice(0,16)}function hr(e){return join$1(homedir$1(),".devflow","daemons",`${Nt(e)}.sock`)}function hc(){return join$1(homedir$1(),".devflow","daemons.json")}function Ir(){if(Ct)return Ct;try{let e=createRequire$1(import.meta.url)("node:sqlite");if(typeof e.DatabaseSync!="function")throw new Error("DatabaseSync is unavailable");return Ct=e.DatabaseSync,Ct}catch{throw new Error("DevFlow doctor requires Node.js >=22.13.0 to inspect SQLite memory data (node:sqlite is unavailable).")}}function T(e){return e.some(t=>!t.ok&&t.severity==="error")?"red":e.some(t=>!t.ok)?"yellow":"green"}async function yc(e,t){let n=t.homePath??homedir$1(),o=[],r=await selectHostAdapter({projectRoot:e,homeDir:n,env:t.env??process.env,explicitHost:(t.env??process.env).DEVFLOW_HOST_ADAPTER});if(o.push({key:"host_adapter",value:r.status==="selected"?{id:r.adapter.id,candidates:r.candidates,explicit:r.explicit}:{status:"failed",code:r.code,candidates:r.candidates,reason:r.reason,action:r.action},target:"one explicitly selected or uniquely detected host",ok:r.status==="selected",severity:"warning"}),r.status==="selected"){let d=await r.adapter.capabilities({projectRoot:e,homeDir:n,env:t.env??process.env});o.push({key:"host_capabilities",value:d,target:"unsupported capabilities have explicit degradation",ok:d.every(g=>g.status==="supported"||!!(g.reason&&g.fallback)),severity:"error"});}let s=await loadPluginsWithDiagnostics({projectRoot:e,homeDir:n}),i=s.diagnostics.filter(d=>d.status==="failed");o.push({key:"plugin_runtime",value:s.diagnostics,target:"configured plugins loadable with diagnostics",ok:i.length===0,severity:"warning"});let a=redactMcpInventory(readMcpInventory(e,n,{env:t.env??process.env}));o.push({key:"mcp_inventory",value:{servers:a.servers.length,duplicates:a.duplicates.length,unreadable:a.unreadable.length},target:{duplicates:0,unreadable:0},ok:a.unreadable.length===0,severity:a.unreadable.length>0?"error":"info"}),o.push({key:"mcp_configuration_drift",value:a.duplicates.filter(d=>d.fingerprints.length>1).map(d=>d.name),target:[],ok:a.duplicates.every(d=>d.fingerprints.length===1),severity:"warning"});let c=await checkMcpHealth(a,n),l=c.records.filter(d=>d.status==="unhealthy");o.push({key:"mcp_health",value:c.records,target:"no unhealthy enabled servers",ok:l.length===0,severity:"warning"});let u=t.activePluginRoot??Ee(n,{installedPluginsPath:t.installedPluginsPath,pluginCachePath:t.pluginCachePath}).root;if(u){let d=St(u);o.push({key:"skill_health",value:{root:d.pluginRoot,skills:d.skills,commands:d.commands,issues:d.issues},target:"valid and fully bound installed skills",ok:d.healthy,severity:"warning"});}return {name:"Contract",status:T(o),metrics:o}}function On(e){let t=resolve(e);try{return {path:realpathSync.native(t)}}catch(n){return {path:t,error:n.message}}}function vc(e){if(typeof e!="object"||e===null)return ["entry must be an object"];let t=e,n=[];return (typeof t.rootPath!="string"||t.rootPath.length===0)&&n.push("rootPath must be a nonempty string"),(typeof t.projectHash!="string"||t.projectHash.length===0)&&n.push("projectHash must be a nonempty string"),(typeof t.pid!="number"||!Number.isInteger(t.pid)||t.pid<=0)&&n.push("pid must be a positive integer"),(typeof t.startedAt!="number"||!Number.isFinite(t.startedAt)||t.startedAt<0)&&n.push("startedAt must be a finite nonnegative number"),typeof t.rootPath=="string"&&t.rootPath.length>0&&typeof t.projectHash=="string"&&t.projectHash.length>0&&t.projectHash!==Nt(t.rootPath)&&n.push("projectHash does not match rootPath"),n}function kc(e,t){let n=On(e),o=Nt(n.path),r=hr(n.path),s=[{key:"canonical_project",value:n.path,target:"existing canonical path",ok:n.error===void 0,severity:n.error?"error":"info"},{key:"project_hash",value:o,ok:true,severity:"info"},{key:"daemon_socket_path",value:r,target:`path containing ${o}`,ok:r.includes(o),severity:"error"}],i=t.registryPath??hc();if(!existsSync$1(i))s.push({key:"daemon_registry",value:"not found",target:"valid JSON when present",ok:true,severity:"info"}),s.push({key:"hook_daemon_registration",value:{activeProjectRegistrations:0},target:"0 when idle or 1 while active",ok:true,severity:"info"});else try{let a=JSON.parse(readFileSync$1(i,"utf8"));if(!Array.isArray(a))throw new Error("registry must be an array");let c=a.filter(g=>vc(g).length>0);s.push({key:"daemon_registry",value:c.length===0?"valid":"malformed",target:"valid daemon entry array",ok:c.length===0,severity:c.length===0?"info":"warning"}),s.push({key:"invalid_daemon_registry_entries",value:c.length,target:0,ok:c.length===0,severity:"warning"});let l=a.filter(g=>{if(typeof g!="object"||g===null)return !1;let f=g;return typeof f.rootPath!="string"||f.rootPath.length===0?!1:On(f.rootPath).path===n.path});s.push({key:"project_daemon_registrations",value:l.length,ok:!0,severity:"info"}),s.push({key:"hook_daemon_registration",value:{activeProjectRegistrations:l.length},target:"0 when idle or 1 while active",ok:l.length<=1,severity:"warning"});let u=l.map(g=>hr(g.rootPath));s.push({key:"registered_daemon_socket_paths",value:u,target:[r],ok:!0,severity:"info"});let d=l.filter((g,f)=>g.projectHash!==o||u[f]!==r).length;s.push({key:"daemon_identity_mismatches",value:d,target:0,ok:d===0,severity:"warning"});}catch{s.push({key:"daemon_registry",value:"malformed",target:"valid daemon entry array",ok:false,severity:"warning"}),s.push({key:"invalid_daemon_registry_entries",value:1,target:0,ok:false,severity:"warning"}),s.push({key:"hook_daemon_registration",value:"unreadable daemon registry",target:"valid project registration",ok:false,severity:"warning"});}return {name:"Isolation",status:T(s),metrics:s}}function bc(e){let t=e.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all(),n=new Set(t.map(r=>r.name)),o=[];for(let[r,s]of Object.entries(wc)){if(!n.has(r)){o.push(r);continue}let i=new Set(e.prepare(`PRAGMA table_info(${r})`).all().map(a=>a.name));for(let a of s)i.has(a)||o.push(`${r}.${a}`);}return o.sort()}function Mr(e){if(typeof e!="string")return null;try{let t=JSON.parse(e);return !Array.isArray(t)||!t.every(n=>typeof n=="string"&&n.trim().length>0)||new Set(t).size!==t.length?null:t}catch{return null}}function Sc(e){let t=Mr(e);return t&&t.length>0?t:null}function Cn(e){return typeof e=="bigint"?e>=0n&&e<=BigInt(Number.MAX_SAFE_INTEGER)?e:null:typeof e!="number"?null:Number.isSafeInteger(e)&&e>=0?e:null}function _c(e,t){return typeof e=="bigint"?e===BigInt(t):e===t}function yr(e,t){return typeof e=="bigint"?e>BigInt(Math.trunc(t)):e>t}function Ec(e,t){let n=[],o=join$1(e,".devflow","memory","memories.db");if(!existsSync$1(o))return n.push({key:"memories_db",value:"missing",target:`initialize ${o} with devflow init`,ok:false,severity:"error"}),{name:"Distill",status:T(n),metrics:n};n.push({key:"memories_db",value:o,target:"readable memory database",ok:true,severity:"info"});let r=t.openDatabase??(i=>new(Ir())(i,{readOnly:true})),s;try{let i=r(o);s=i;let a=bc(i);if(a.length>0)return n.push({key:"required_schema",value:a,target:[],ok:!1,severity:"error"}),{name:"Distill",status:T(n),metrics:n};let c=(t.now??Date.now)(),l=i.prepare(`
|
|
33
34
|
SELECT batch_id, event_ids, session_ids, event_count, created_at, expires_at, status
|
|
34
35
|
FROM distill_leases
|
|
35
|
-
`);l.setReadBigInts?.(!0);let u=l.all(),d=new Set,g=0,f=0;for(let _ of u){let j=
|
|
36
|
+
`);l.setReadBigInts?.(!0);let u=l.all(),d=new Set,g=0,f=0;for(let _ of u){let j=Sc(_.event_ids),Y=Mr(_.session_ids),oe=Cn(_.event_count),D=Cn(_.created_at),F=Cn(_.expires_at),X=typeof _.status=="string"&&Pc.has(_.status)?_.status:null,A=typeof _.batch_id=="string"&&_.batch_id.trim().length>0,I=j!==null&&oe!==null&&_c(oe,j.length);if(!A||!j||!Y||!I||D===null||F===null||X===null){g+=1,_.status==="pending"&&(F===null||yr(F,c))&&(f+=1);continue}if(!(X!=="pending"||!yr(F,c)))for(let H of j)d.add(H);}n.push({key:"malformed_distill_leases",value:g,target:0,ok:g===0,severity:f>0?"error":"warning"});let m=i.prepare(`
|
|
36
37
|
SELECT id
|
|
37
38
|
FROM session_events
|
|
38
39
|
WHERE processed = 0 AND created_at < ?
|
|
39
|
-
`).all(c-300*1e3).filter(_=>!d.has(_.id)).length;n.push({key:"unprocessed_stale_events",value:m,target:0,ok:m===0,severity:"error"});let h=B(i,"SELECT COUNT(*) count FROM session_events WHERE processed = 0");n.push({key:"pending_memory_events",value:h,target:"actively leased or younger than 5 minutes",ok:m===0,severity:"error"});let y=i.prepare("SELECT MIN(created_at) oldest FROM session_events WHERE processed = 0").get(),
|
|
40
|
+
`).all(c-300*1e3).filter(_=>!d.has(_.id)).length;n.push({key:"unprocessed_stale_events",value:m,target:0,ok:m===0,severity:"error"});let h=B(i,"SELECT COUNT(*) count FROM session_events WHERE processed = 0");n.push({key:"pending_memory_events",value:h,target:"actively leased or younger than 5 minutes",ok:m===0,severity:"error"});let y=i.prepare("SELECT MIN(created_at) oldest FROM session_events WHERE processed = 0").get(),k=y?.oldest==null?null:Number(y.oldest);n.push({key:"pending_memory_oldest_age_ms",value:k===null?0:Math.max(0,c-k),target:"<= 300000 when no active lease is present",ok:k===null||m===0,severity:"warning"});let R=B(i,`
|
|
40
41
|
SELECT COUNT(*) count
|
|
41
42
|
FROM session_events event
|
|
42
43
|
LEFT JOIN sessions session ON session.id = event.session_id
|
|
@@ -45,7 +46,7 @@ ${o.pid??0}`),o.unref(),{pid:o.pid??0}}async function ot(){let e=wn(process.cwd(
|
|
|
45
46
|
SELECT COUNT(*) count
|
|
46
47
|
FROM sessions
|
|
47
48
|
WHERE status = 'active' AND created_at < ?
|
|
48
|
-
`,c
|
|
49
|
+
`,c-Nn);n.push({key:"stale_memory_sessions",value:v,target:0,ok:v===0,severity:"error"});let b=i.prepare(`
|
|
49
50
|
SELECT COUNT(*) AS group_count, COALESCE(SUM(title_count), 0) AS row_count
|
|
50
51
|
FROM (
|
|
51
52
|
SELECT project, session_id, title, COUNT(*) AS title_count
|
|
@@ -53,39 +54,40 @@ ${o.pid??0}`),o.unref(),{pid:o.pid??0}}async function ot(){let e=wn(process.cwd(
|
|
|
53
54
|
GROUP BY project, session_id, title
|
|
54
55
|
HAVING COUNT(*) > 1
|
|
55
56
|
)
|
|
56
|
-
`).get();n.push({key:"duplicate_observation_title_groups",value:Number(b.group_count),target:0,ok:Number(b.group_count)===0,severity:"error"}),n.push({key:"duplicate_observation_title_rows",value:Number(b.row_count),target:0,ok:Number(b.row_count)===0,severity:"error"});}catch(i){n.push({key:"database_read",value:i.message,target:"readable Task 2 memory schema",ok:false,severity:"error"});}finally{s?.close();}return {name:"Distill",status:T(n),metrics:n}}function ie(e,t){return (t.openDatabase??(o=>new(
|
|
57
|
+
`).get();n.push({key:"duplicate_observation_title_groups",value:Number(b.group_count),target:0,ok:Number(b.group_count)===0,severity:"error"}),n.push({key:"duplicate_observation_title_rows",value:Number(b.row_count),target:0,ok:Number(b.row_count)===0,severity:"error"});}catch(i){n.push({key:"database_read",value:i.message,target:"readable Task 2 memory schema",ok:false,severity:"error"});}finally{s?.close();}return {name:"Distill",status:T(n),metrics:n}}function ie(e,t){return (t.openDatabase??(o=>new(Ir())(o,{readOnly:true})))(e)}function W(e,t){return !!e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ? LIMIT 1").get(t)}function qe(e,t){return W(e,t)?new Set(e.prepare(`PRAGMA table_info(${t})`).all().map(n=>n.name).filter(n=>typeof n=="string")):new Set}function B(e,t,...n){let o=e.prepare(t).get(...n);return Number(o?.count??0)}function Lr(e){if(typeof e!="string")return e;try{return JSON.parse(e)}catch{return}}function Tn(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0}function Cc(e){let t=Tn(Lr(e.output)),n=Tn(t?.data),o=typeof t?.status=="string"?t.status:void 0,r=typeof e.metric_status=="string"?e.metric_status:void 0,s=!!e.error||!!e.failure_category||t?.ok===false||t?.success===false||t?.isError===true||!!t?.error||o==="failed"||o==="rejected"||r==="error",i=!s&&(t?.degraded===true||!!t?.degradation||n?.degraded===true||o==="degraded"||r==="degraded");return {failed:s,degraded:i}}function Rc(e){let t=Lr(e);if(typeof t=="string"&&t.trim())return [t.trim()];if(Array.isArray(t))return t.filter(o=>typeof o=="string"&&o.trim().length>0).map(o=>o.trim());let n=Tn(t);return n?Object.entries(n).filter(([,o])=>typeof o=="number"&&o>0).map(([o])=>o):[]}function vr(e,t){return t===0?0:e/t}function Rn(e,t){return e===0?1:t/e}async function Dc(e,t){let n=[],o=null,r=null,s=join$1(e,".codegraph","codegraph.db");if(!existsSync$1(s))n.push({key:"codegraph_db",value:"missing",target:s,ok:false,severity:"warning"});else {let g;try{g=ie(s,t),W(g,"nodes")?(o=B(g,"SELECT COUNT(*) count FROM nodes"),n.push({key:"codegraph_nodes",value:o,ok:!0,severity:"info"})):n.push({key:"codegraph_nodes",value:"nodes table missing",target:">= 0",ok:!1,severity:"warning"});let f=Math.max(0,(t.now??Date.now)()-statSync$1(s).mtimeMs);n.push({key:"index_freshness_ms",value:f,target:"recently updated codegraph database",ok:!0,severity:"info"});}catch(f){n.push({key:"codegraph_db_read",value:f.message,target:"readable SQLite database",ok:false,severity:"error"});}finally{g?.close();}}let i=join$1(e,".devflow","symbols-vec.db");if(!existsSync$1(i))n.push({key:"symbols_vectors_db",value:"missing",target:i,ok:false,severity:"warning"});else {let g;try{g=ie(i,t);let f=W(g,"symbols_vec_rowids")?"symbols_vec_rowids":W(g,"symbol_sources")?"symbol_sources":null;f?(r=B(g,`SELECT COUNT(*) count FROM ${f}`),n.push({key:"symbols_vectors",value:r,ok:!0,severity:"info"})):n.push({key:"symbols_vectors",value:"vector metadata missing",target:">= 0",ok:!1,severity:"warning"});}catch(f){n.push({key:"symbols_vectors_read",value:f.message,target:"readable SQLite database",ok:false,severity:"error"});}finally{g?.close();}}if(o!==null&&r!==null){let g=Rn(o,r);n.push({key:"symbols_vector_coverage",value:g,target:">= 0.90",ok:g>=.9,severity:"warning"});}let a=join$1(e,".devflow","knowledge","knowledge.db");if(!existsSync$1(a))n.push({key:"knowledge_vectors_db",value:"missing",target:a,ok:false,severity:"warning"});else {let g;try{g=ie(a,t);let p=["knowledge_docs","knowledge_chunks","knowledge_vec_rowids"].filter(m=>!W(g,m));if(p.length>0)n.push({key:"knowledge_vector_schema",value:p,target:[],ok:!1,severity:"warning"});else {let m=B(g,"SELECT COUNT(*) count FROM knowledge_chunks"),h=B(g,"SELECT COUNT(*) count FROM knowledge_vec_rowids"),y=Rn(m,h),R=g.prepare(`
|
|
57
58
|
SELECT d.source source, COUNT(c.id) chunks,
|
|
58
59
|
SUM(CASE WHEN v.id IS NOT NULL THEN 1 ELSE 0 END) vectors
|
|
59
60
|
FROM knowledge_docs d
|
|
60
61
|
LEFT JOIN knowledge_chunks c ON c.doc_id = d.id
|
|
61
62
|
LEFT JOIN knowledge_vec_rowids v ON v.id = c.id
|
|
62
63
|
GROUP BY d.source ORDER BY d.source
|
|
63
|
-
`).all().map(v=>{let b=Number(v.chunks),_=Number(v.vectors);return {source:v.source,chunks:b,vectors:_,coverage:
|
|
64
|
+
`).all().map(v=>{let b=Number(v.chunks),_=Number(v.vectors);return {source:v.source,chunks:b,vectors:_,coverage:Rn(b,_)}});n.push({key:"knowledge_chunks",value:m,ok:!0,severity:"info"}),n.push({key:"knowledge_vectors",value:h,ok:!0,severity:"info"}),n.push({key:"knowledge_vector_coverage",value:y,target:">= 0.95",ok:y>=.95,severity:"warning"}),n.push({key:"knowledge_vector_coverage_by_source",value:R,target:"every source >= 0.95",ok:R.every(v=>v.coverage>=.95),severity:"warning"});}}catch(f){n.push({key:"knowledge_vectors_read",value:f.message,target:"readable SQLite database",ok:false,severity:"error"});}finally{g?.close();}}let c=join$1(e,".devflow","memory","memories.db");if(!existsSync$1(c))n.push({key:"observation_vectors_db",value:"missing",target:c,ok:false,severity:"warning"});else {let g;try{if(g=ie(c,t),!W(g,"observations")||!W(g,"embeddings"))n.push({key:"observation_vector_schema",value:"observations/embeddings missing",target:"Batch 2 vector schema",ok:!1,severity:"warning"});else {let f=qe(g,"observations"),p=f.has("quality_status")&&f.has("resolution_state"),h=B(g,`SELECT COUNT(*) count FROM observations ${p?"WHERE quality_status = 'accepted' AND resolution_state <> 'superseded'":""}`),y=B(g,`
|
|
64
65
|
SELECT COUNT(DISTINCT e.source_id) count
|
|
65
66
|
FROM embeddings e JOIN observations o ON o.id = e.source_id
|
|
66
67
|
WHERE e.source_type = 'observation'
|
|
67
|
-
|
|
68
|
-
`).
|
|
68
|
+
${p?"AND o.quality_status = 'accepted' AND o.resolution_state <> 'superseded'":""}
|
|
69
|
+
`),k=Math.max(0,h-y);n.push({key:"observations",value:h,ok:!0,severity:"info"}),n.push({key:"observation_vectors",value:y,ok:!0,severity:"info"}),n.push({key:"observation_vectors_missing",value:k,target:0,ok:k===0,severity:"warning"});}}catch(f){n.push({key:"observation_vectors_read",value:f.message,target:"readable SQLite database",ok:false,severity:"error"});}finally{g?.close();}}let l=(t.now??Date.now)(),u=join$1(t.homePath??homedir$1(),".devflow","errors","embedder.log"),d=0;if(existsSync$1(u))try{let g=l-864e5;d=readFileSync$1(u,"utf8").split(`
|
|
70
|
+
`).filter(f=>{let p=/^\[([^\]]+)\]/.exec(f);return p?Date.parse(p[1])>=g:!1}).length;}catch(g){n.push({key:"embedder_error_log_read",value:g.message,target:"readable error log",ok:false,severity:"error"});}n.push({key:"embedder_errors_24h",value:d,target:0,ok:d===0,severity:"warning"});try{let g=await(t.inspectEmbeddingModel??inspectEmbeddingModel)({homeDir:t.homePath,env:t.env??process.env});n.push({key:"embedding_model_state",value:{state:g.state,modelId:g.modelId,revision:g.revision},target:{state:"ready"},ok:g.ready,severity:"warning"}),n.push({key:"embedding_model_cache_root",value:g.cacheRoot,target:"stable shared DevFlow cache",ok:!0,severity:"info"}),n.push({key:"embedding_model_integrity",value:{missingFiles:g.missingFiles,corruptFiles:g.corruptFiles},target:{missingFiles:[],corruptFiles:[]},ok:g.missingFiles.length===0&&g.corruptFiles.length===0,severity:"warning"});}catch(g){n.push({key:"embedding_model_inspection",value:g.message,target:"readable verified shared model cache",ok:false,severity:"warning"});}return {name:"Vectors",status:T(n),metrics:n}}function $c(e,t,n){let o=[],r=n.homePath??homedir$1(),s=n.homePath?join$1(r,".devflow","global","devflow.db"):getGlobalDevFlowDbPath(r),i=(n.now??Date.now)()-1440*60*1e3,a=(n.now??Date.now)(),c=t?"error":"warning";if(!existsSync$1(s))o.push({key:"global_telemetry_db",value:"missing",target:s,ok:false,severity:"warning"});else {let m;try{m=ie(s,n),o.push({key:"global_telemetry_db",value:s,ok:!0,severity:"info"});for(let[A,I]of [["tool_metrics_24h","tool_metrics"],["feedback_24h","feedback"],["runs_24h","runs"]]){let H=W(m,I)?B(m,`SELECT COUNT(*) count FROM ${I} WHERE created_at >= ?`,i):0;o.push({key:A,value:H,ok:!0,severity:"info"});}let h=W(m,"telemetry_failures")?B(m,"SELECT COUNT(*) count FROM telemetry_failures WHERE created_at >= ?",i):0;o.push({key:"telemetry_failures_24h",value:h,target:0,ok:h===0,severity:c});let y=qe(m,"sessions"),k=qe(m,"tool_call_events"),R=qe(m,"skill_executions"),v=["id","project_root","started_at","status"].every(A=>y.has(A));if(o.push({key:"telemetry_session_schema",value:v?"canonical":"sessions table or identity columns missing",target:"canonical sessions table",ok:v,severity:"error"}),v){let A=B(m,`
|
|
69
71
|
SELECT COUNT(*) count FROM sessions
|
|
70
72
|
WHERE project_root = ? AND started_at >= ?
|
|
71
|
-
`,e,i);o.push({key:"session_start_evidence_24h",value:
|
|
73
|
+
`,e,i);o.push({key:"session_start_evidence_24h",value:A,target:"present after a Claude SessionStart",ok:!0,severity:"info"});let I=B(m,`
|
|
72
74
|
SELECT COUNT(*) count FROM sessions
|
|
73
75
|
WHERE project_root = ? AND status = 'running' AND started_at < ?
|
|
74
|
-
`,e,(n.now??Date.now)()
|
|
76
|
+
`,e,(n.now??Date.now)()-Nn);o.push({key:"stale_telemetry_sessions",value:I,target:0,ok:I===0,severity:"error"});let H=m.prepare(`
|
|
75
77
|
SELECT status, COUNT(*) count
|
|
76
78
|
FROM sessions
|
|
77
79
|
WHERE project_root = ?
|
|
78
80
|
GROUP BY status
|
|
79
|
-
`).all(e),N={running:0,completed:0,failed:0};for(let
|
|
81
|
+
`).all(e),N={running:0,completed:0,failed:0};for(let V of H)V.status in N&&(N[V.status]=Number(V.count));let re=N.running+N.completed+N.failed,Pe=N.completed+N.failed;if(o.push({key:"project_session_closure_state",value:{total:re,...N,closed:Pe,closureRate:re===0?1:Pe/re},target:"running sessions close through SessionEnd",ok:!0,severity:"info"}),W(m,"devflow_session_closures")){let V=m.prepare(`
|
|
80
82
|
SELECT state, COUNT(*) count
|
|
81
83
|
FROM devflow_session_closures
|
|
82
84
|
WHERE project_root = ?
|
|
83
85
|
GROUP BY state
|
|
84
|
-
`).all(e),G={active:0,closing:0,closed:0,closed_with_pending_work:0};for(let
|
|
86
|
+
`).all(e),G={active:0,closing:0,closed:0,closed_with_pending_work:0};for(let ze of V)ze.state in G&&(G[ze.state]=Number(ze.count));let Z=B(m,`
|
|
85
87
|
SELECT COUNT(*) count
|
|
86
88
|
FROM devflow_session_closures
|
|
87
89
|
WHERE project_root = ? AND state = 'closing' AND updated_at < ?
|
|
88
|
-
`,e,a
|
|
90
|
+
`,e,a-Nn);o.push({key:"durable_session_closure_state",value:{...G,staleClosing:Z},target:{active:0,closing:0,staleClosing:0},ok:G.active===0&&G.closing===0&&Z===0,severity:c});}else o.push({key:"durable_session_closure_state",value:"closure table missing",target:"active -> closing -> closed | closed_with_pending_work",ok:!1,severity:c});let ee=0;k.has("session_id")&&(ee=B(m,`
|
|
89
91
|
SELECT COUNT(*) count
|
|
90
92
|
FROM tool_call_events event
|
|
91
93
|
LEFT JOIN sessions session ON session.id = event.session_id
|
|
@@ -95,7 +97,7 @@ ${o.pid??0}`),o.unref(),{pid:o.pid??0}}async function ot(){let e=wn(process.cwd(
|
|
|
95
97
|
FROM skill_executions execution
|
|
96
98
|
LEFT JOIN sessions session ON session.id = execution.session_id
|
|
97
99
|
WHERE TRIM(COALESCE(execution.session_id, '')) = '' OR session.id IS NULL
|
|
98
|
-
`)),o.push({key:"orphan_telemetry_events",value:{toolCalls:ee,skillExecutions:se},target:{toolCalls:0,skillExecutions:0},ok:ee===0&&se===0,severity:"error"}),["session_id","status","started_at"].every(
|
|
100
|
+
`)),o.push({key:"orphan_telemetry_events",value:{toolCalls:ee,skillExecutions:se},target:{toolCalls:0,skillExecutions:0},ok:ee===0&&se===0,severity:"error"}),["session_id","status","started_at"].every(V=>R.has(V))){let V=a-18e5,G=m.prepare(`
|
|
99
101
|
SELECT
|
|
100
102
|
COUNT(*) total,
|
|
101
103
|
COALESCE(SUM(CASE WHEN execution.started_at < ? THEN 1 ELSE 0 END), 0) older_than_30m,
|
|
@@ -105,7 +107,7 @@ ${o.pid??0}`),o.unref(),{pid:o.pid??0}}async function ot(){let e=wn(process.cwd(
|
|
|
105
107
|
WHERE session.project_root = ?
|
|
106
108
|
AND execution.status = 'running'
|
|
107
109
|
AND (execution.started_at < ? OR session.status <> 'running')
|
|
108
|
-
`).get(
|
|
110
|
+
`).get(V,e,V),Z=Number(G?.total??0);o.push({key:"stale_skill_executions",value:{total:Z,olderThan30m:Number(G?.older_than_30m??0),attachedToNonRunningSession:Number(G?.non_running_session??0)},target:{total:0},ok:Z===0,severity:"error"});}else o.push({key:"skill_execution_schema",value:"status, started_at, or session_id column missing",target:"canonical Skill execution lifecycle schema",ok:!1,severity:"warning"});}if(!W(m,"devflow_work_items"))o.push({key:"work_queue_schema",value:"devflow_work_items table missing; queue diagnostics degraded",target:"canonical global work queue schema",ok:!1,severity:"error"});else {let A=qe(m,"devflow_work_items"),H=["project_root","state","lease_expires_at","created_at","completed_at"].filter(N=>!A.has(N));if(H.length>0)o.push({key:"work_queue_schema",value:{missingColumns:H,diagnostic:"queue diagnostics degraded"},target:"canonical global work queue schema",ok:!1,severity:"error"});else {let N=m.prepare(`
|
|
109
111
|
SELECT
|
|
110
112
|
COALESCE(SUM(CASE WHEN state IN ('pending', 'leased', 'failed') THEN 1 ELSE 0 END), 0) queue_depth,
|
|
111
113
|
COALESCE(SUM(CASE WHEN state = 'pending' THEN 1 ELSE 0 END), 0) pending,
|
|
@@ -117,50 +119,50 @@ ${o.pid??0}`),o.unref(),{pid:o.pid??0}}async function ot(){let e=wn(process.cwd(
|
|
|
117
119
|
MAX(CASE WHEN state = 'completed' THEN completed_at END) last_successful_drain_at
|
|
118
120
|
FROM devflow_work_items
|
|
119
121
|
WHERE project_root = ?
|
|
120
|
-
`).get(a,e),re=Number(N?.queue_depth??0),Pe=Number(N?.pending??0),ee=Number(N?.leased??0),se=Number(N?.failed??0),te=Number(N?.dead_letters??0),
|
|
122
|
+
`).get(a,e),re=Number(N?.queue_depth??0),Pe=Number(N?.pending??0),ee=Number(N?.leased??0),se=Number(N?.failed??0),te=Number(N?.dead_letters??0),V=Number(N?.expired_leases??0),G=N?.oldest_pending_at==null?void 0:Number(N.oldest_pending_at),Z=N?.last_successful_drain_at==null?void 0:Number(N.last_successful_drain_at);o.push({key:"work_queue_schema",value:"canonical",target:"canonical global work queue schema",ok:!0,severity:"info"}),o.push({key:"work_queue_depth",value:re,ok:!0,severity:"info"}),o.push({key:"work_queue_pending",value:Pe,ok:!0,severity:"info"}),o.push({key:"work_queue_leased",value:ee,ok:!0,severity:"info"}),o.push({key:"work_queue_failed",value:se,target:0,ok:se===0,severity:"warning"}),o.push({key:"work_queue_oldest_pending_age_ms",value:G===void 0?0:Math.max(0,a-G),ok:!0,severity:"info"}),o.push({key:"work_queue_dead_letters",value:te,target:0,ok:te===0,severity:"error"}),o.push({key:"work_queue_expired_leases",value:V,target:0,ok:V===0,severity:"error"}),o.push({key:"work_queue_last_successful_drain_at",value:Z??null,ok:!0,severity:"info"});}}let b=n.env?.DEVFLOW_STATE_DIR??join$1(r,".devflow","state",Nt(e)),j=Object.fromEntries(["session-start-pending","memory-turn-pending","session-finalize-pending"].map(A=>{let I=join$1(b,A),H=existsSync$1(I)?readdirSync(I).filter(N=>N.includes(".json")).length:0;return [A,H]})),Y=Object.values(j).reduce((A,I)=>A+I,0);if(o.push({key:"hook_spool_backlog",value:{total:Y,...j},target:{total:0},ok:Y===0,severity:c}),W(m,"tool_call_events")){let A=v&&k.has("session_id"),I=qe(m,"tool_metrics"),H=k.has("event_id")&&I.has("tool_call_event_id")&&I.has("status"),N=[k.has("error")?"event.error":"NULL error",k.has("failure_category")?"event.failure_category":"NULL failure_category",k.has("output")?"event.output":"NULL output",H?"metric.status metric_status":"NULL metric_status"].join(", "),re=m.prepare(`
|
|
121
123
|
SELECT ${N}
|
|
122
124
|
FROM tool_call_events event
|
|
123
125
|
${H?"LEFT JOIN tool_metrics metric ON metric.tool_call_event_id = event.event_id":""}
|
|
124
|
-
${
|
|
126
|
+
${A?"JOIN sessions event_session ON event_session.id = event.session_id":""}
|
|
125
127
|
WHERE event.timestamp >= ?
|
|
126
|
-
${
|
|
127
|
-
`).all(...
|
|
128
|
+
${A?"AND event_session.project_root = ?":""}
|
|
129
|
+
`).all(...A?[i,e]:[i]),Pe=re.map(Cc),ee=Pe.filter(te=>te.failed).length,se=Pe.filter(te=>te.degraded).length;if(o.push({key:"semantic_tool_calls_24h",value:re.length,ok:!0,severity:"info"}),o.push({key:"semantic_tool_failures_24h",value:ee,target:0,ok:ee===0,severity:c}),o.push({key:"semantic_tool_degradations_24h",value:se,target:0,ok:se===0,severity:c}),o.push({key:"semantic_tool_failure_rate_24h",value:vr(ee,re.length),target:0,ok:ee===0,severity:c}),o.push({key:"semantic_tool_degradation_rate_24h",value:vr(se,re.length),target:0,ok:se===0,severity:c}),o.push({key:"semantic_tool_project_scope",value:A?"project":"global fallback; session identity unavailable",target:"project",ok:A,severity:"warning"}),k.has("failure_category")){let te={};for(let Z of re)typeof Z.failure_category!="string"||!Z.failure_category.trim()||(te[Z.failure_category]=(te[Z.failure_category]??0)+1);let V=Object.values(te).reduce((Z,ze)=>Z+ze,0),G=ee===0?1:V/ee;o.push({key:"failure_categories_24h",value:te,ok:!0,severity:"info"}),o.push({key:"failure_category_coverage_24h",value:G,target:">= 0.80",ok:G>=.8,severity:c});}else o.push({key:"failure_category_schema",value:"failure_category column missing",target:"Batch 4G telemetry schema",ok:!1,severity:c});}let oe=v&&["session_id","started_at","fallback_count","fallback_reasons"].every(A=>R.has(A)),D=0,F={};if(oe){let A=m.prepare(`
|
|
128
130
|
SELECT execution.fallback_count, execution.fallback_reasons
|
|
129
131
|
FROM skill_executions execution
|
|
130
132
|
JOIN sessions session ON session.id = execution.session_id
|
|
131
133
|
WHERE session.project_root = ? AND execution.started_at >= ?
|
|
132
|
-
`).all(e,i);for(let I of
|
|
134
|
+
`).all(e,i);for(let I of A){D+=Number(I.fallback_count??0);for(let H of Rc(I.fallback_reasons))F[H]=(F[H]??0)+1;}}let X=0;if(W(m,"devflow_hook_fallbacks")){let A=m.prepare(`
|
|
133
135
|
SELECT reason, COUNT(*) count
|
|
134
136
|
FROM devflow_hook_fallbacks
|
|
135
137
|
WHERE project_root = ? AND created_at >= ?
|
|
136
138
|
GROUP BY reason ORDER BY reason
|
|
137
|
-
`).all(e,i);for(let I of
|
|
138
|
-
`))if(d.trim())try{let g=JSON.parse(d),f=
|
|
139
|
+
`).all(e,i);for(let I of A){let H=Number(I.count);X+=H,F[`hook:${I.reason}`]=H;}}o.push({key:"skill_fallbacks_24h",value:D,target:0,ok:D===0,severity:"warning"}),o.push({key:"hook_fallbacks_24h",value:X,target:0,ok:X===0,severity:"warning"}),o.push({key:"fallback_reasons_24h",value:F,target:{},ok:Object.keys(F).length===0,severity:"warning"});}catch(h){o.push({key:"global_telemetry_db_read",value:h.message,target:"readable SQLite database",ok:false,severity:"error"});}finally{m?.close();}}let l=[...new Set([join$1(dirname(s),"telemetry-cache"),join$1(r,".devflow","telemetry-cache")])],u=0;try{u=l.reduce((m,h)=>m+(existsSync$1(h)?readdirSync(h).filter(y=>y.endsWith(".json")).length:0),0),o.push({key:"telemetry_cache_files",value:u,target:0,ok:u===0,severity:c});}catch(m){o.push({key:"telemetry_cache_read",value:m.message,target:"readable cache directory",ok:false,severity:"error"});}let d=join$1(e,".devflow","devflow.db"),g=existsSync$1(d);o.push({key:"project_local_telemetry_db",value:g?d:"absent",target:"absent",ok:!g,severity:c});let f=join$1(e,".codegraph","codegraph.db"),p=[];if(existsSync$1(f)){let m;try{m=ie(f,n),p=m.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name LIKE 'devflow_%' ORDER BY name").all().map(h=>h.name);}catch(h){o.push({key:"codegraph_telemetry_read",value:h.message,target:"readable SQLite database",ok:false,severity:"error"});}finally{m?.close();}}return o.push({key:"codegraph_devflow_tables",value:p,target:[],ok:p.length===0,severity:c}),{name:"Telemetry",status:T(o),metrics:o}}function wr(e){return (statSync$1(e).mode&511).toString(8).padStart(3,"0")}function Fr(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e!="string")return null;let t=Date.parse(e);return Number.isFinite(t)?t:null}function xc(e){let t=[],n=e.homePath??homedir$1(),o=e.env??process.env,r=join$1(n,".devflow","keys"),s=[["local_api_key","DEVFLOW_API_KEY","local.key"],["local_hmac_secret","DEVFLOW_HMAC_SECRET","hmac.key"]];if(!s.some(([,u])=>!o[u]?.trim())&&!existsSync$1(r))t.push({key:"key_directory",value:"not required (environment overrides active)",ok:true,severity:"info"});else if(!existsSync$1(r))t.push({key:"key_directory",value:"missing",target:r,ok:false,severity:"warning"});else try{let u=lstatSync(r),d=wr(r),g=u.isDirectory()&&!u.isSymbolicLink(),f=process.platform==="win32"||d==="700";t.push({key:"key_directory",value:{path:r,mode:d},target:{type:"directory",mode:"700"},ok:g&&f,severity:g?"warning":"error"});}catch(u){t.push({key:"key_directory",value:u.message,target:"readable directory with mode 700",ok:false,severity:"error"});}for(let[u,d,g]of s){if(o[d]?.trim()){t.push({key:`${u}_source`,value:d,target:"environment override or generated key file",ok:true,severity:"info"});continue}let f=join$1(r,g);if(!existsSync$1(f)){t.push({key:`${u}_source`,value:"missing",target:f,ok:false,severity:"warning"});continue}try{let p=lstatSync(f),m=wr(f),h=readFileSync$1(f,"utf8").trim(),y=p.isFile()&&!p.isSymbolicLink();t.push({key:`${u}_source`,value:{path:f,mode:m,bytes:Buffer.byteLength(h)},target:{type:"regular file",mode:"400",nonempty:!0},ok:y&&h.length>0&&(process.platform==="win32"||m==="400"),severity:!y||h.length===0?"error":"warning"});}catch(p){t.push({key:`${u}_source`,value:p.message,target:"readable nonempty key file with mode 400",ok:false,severity:"error"});}}let a=join$1(n,".devflow","errors","compressor.log"),c=0,l=0;if(existsSync$1(a))try{let u=(e.now??Date.now)()-Ke;for(let d of readFileSync$1(a,"utf8").split(`
|
|
140
|
+
`))if(d.trim())try{let g=JSON.parse(d),f=Fr(g.ts);f===null?l+=1:f>=u&&(c+=1);}catch{l+=1;}}catch(u){t.push({key:"compressor_error_log_read",value:u.message,target:"readable JSONL diagnostics",ok:false,severity:"error"});}return t.push({key:"compressor_errors_24h",value:c,target:0,ok:c===0,severity:"warning"}),t.push({key:"malformed_compressor_records",value:l,target:0,ok:l===0,severity:"error"}),{name:"Runtime security",status:T(t),metrics:t}}function Oc(e){let t=[],n=e.homePath??homedir$1(),o=getGlobalDevFlowDbPath(n);if(!existsSync$1(o))return t.push({key:"latest_benchmark",value:"missing global database",target:"completed baseline within 30 days",ok:false,severity:"warning"}),{name:"Benchmark",status:T(t),metrics:t};let r;try{if(r=ie(o,e),!W(r,"benchmark_reports"))return t.push({key:"latest_benchmark",value:"benchmark_reports table missing",target:"completed baseline within 30 days",ok:!1,severity:"warning"}),{name:"Benchmark",status:T(t),metrics:t};let s=r.prepare(`
|
|
139
141
|
SELECT run_id, suite_id, suite_version, task_count, status, report_json, created_at
|
|
140
142
|
FROM benchmark_reports
|
|
141
143
|
ORDER BY created_at DESC
|
|
142
144
|
LIMIT 1
|
|
143
|
-
`).get();if(!s)return t.push({key:"latest_benchmark",value:"no reports",target:"completed baseline within 30 days",ok:!1,severity:"warning"}),{name:"Benchmark",status:T(t),metrics:t};let i=null;try{if(typeof s.report_json!="string")throw new Error("report_json is not text");let u=JSON.parse(s.report_json);if(!Array.isArray(u.tasks))throw new Error("report tasks are missing");i=u.tasks.length;}catch(u){t.push({key:"benchmark_report_json",value:u.message,target:"valid report with tasks array",ok:!1,severity:"error"});}let a=Number(s.task_count),c=Number(s.created_at),l=(e.now??Date.now)()-c;t.push({key:"latest_benchmark",value:{runId:s.run_id,suiteId:s.suite_id,suiteVersion:s.suite_version,status:s.status,createdAt:c},ok:s.status==="completed"&&Number.isFinite(c),severity:"error"}),t.push({key:"benchmark_task_count",value:a,target:">= 5",ok:Number.isInteger(a)&&a>=5&&i===a,severity:i===null?"error":"warning"}),t.push({key:"benchmark_age_days",value:Number.isFinite(l)?Number((l/
|
|
144
|
-
`))if(
|
|
145
|
+
`).get();if(!s)return t.push({key:"latest_benchmark",value:"no reports",target:"completed baseline within 30 days",ok:!1,severity:"warning"}),{name:"Benchmark",status:T(t),metrics:t};let i=null;try{if(typeof s.report_json!="string")throw new Error("report_json is not text");let u=JSON.parse(s.report_json);if(!Array.isArray(u.tasks))throw new Error("report tasks are missing");i=u.tasks.length;}catch(u){t.push({key:"benchmark_report_json",value:u.message,target:"valid report with tasks array",ok:!1,severity:"error"});}let a=Number(s.task_count),c=Number(s.created_at),l=(e.now??Date.now)()-c;t.push({key:"latest_benchmark",value:{runId:s.run_id,suiteId:s.suite_id,suiteVersion:s.suite_version,status:s.status,createdAt:c},ok:s.status==="completed"&&Number.isFinite(c),severity:"error"}),t.push({key:"benchmark_task_count",value:a,target:">= 5",ok:Number.isInteger(a)&&a>=5&&i===a,severity:i===null?"error":"warning"}),t.push({key:"benchmark_age_days",value:Number.isFinite(l)?Number((l/Ke).toFixed(2)):null,target:"0-30",ok:Number.isFinite(l)&&l>=0&&l<=Ac,severity:l<0||!Number.isFinite(l)?"error":"warning"});}catch(s){t.push({key:"benchmark_database_read",value:s.message,target:"readable canonical benchmark database",ok:false,severity:"error"});}finally{r?.close();}return {name:"Benchmark",status:T(t),metrics:t}}function Nc(e){if(!existsSync$1(e))return {bytes:0,files:0};let t=[e],n=0,o=0;for(;t.length>0;){let r=t.pop(),s=lstatSync(r);if(!s.isSymbolicLink()){if(s.isDirectory()){for(let i of readdirSync(r))t.push(join$1(r,i));continue}s.isFile()&&(n+=s.size,o+=1);}}return {bytes:n,files:o}}function Tc(e){let t=[],n=e.homePath??homedir$1(),o=[join$1(n,".devflow","errors","hook-fallback.log")],r=join$1(n,".devflow","logs","hook-fallback");if(existsSync$1(r))try{for(let y of readdirSync(r))y.endsWith(".log")&&o.push(join$1(r,y));}catch(y){t.push({key:"hook_fallback_directory_read",value:y.message,target:"readable fallback directory",ok:false,severity:"error"});}let s=(e.now??Date.now)()-Ke,i=0,a=0;for(let y of [...new Set(o)])if(existsSync$1(y))try{for(let k of readFileSync$1(y,"utf8").split(`
|
|
146
|
+
`))if(k.trim())try{let R=JSON.parse(k),v=Fr(R.ts);v===null||typeof R.reason!="string"?a+=1:v>=s&&(i+=1);}catch{a+=1;}}catch(k){t.push({key:"hook_fallback_log_read",value:{path:y,error:k.message},target:"readable JSONL diagnostics",ok:false,severity:"error"});}t.push({key:"hook_fallback_events_24h",value:i,target:0,ok:i===0,severity:"warning"}),t.push({key:"malformed_hook_fallback_records",value:a,target:0,ok:a===0,severity:"error"});let c=e.homePath?join$1(n,".devflow","global","devflow.db"):getGlobalDevFlowDbPath(n),l=0,u=0,d=null;if(existsSync$1(c)){let y;try{if(y=ie(c,e),W(y,"telemetry_events")){let k=y.prepare(`
|
|
145
147
|
SELECT COUNT(*) total,
|
|
146
148
|
SUM(CASE WHEN success = 0 THEN 1 ELSE 0 END) failures,
|
|
147
149
|
AVG(CASE WHEN success = 1 THEN duration END) average_duration
|
|
148
150
|
FROM telemetry_events
|
|
149
151
|
WHERE kind = 'hook_daemon_request' AND timestamp >= ?
|
|
150
|
-
`).get(s);l=Number(
|
|
152
|
+
`).get(s);l=Number(k?.total??0),u=Number(k?.failures??0),d=k?.average_duration==null?null:Math.round(Number(k.average_duration)*100)/100;}}catch(k){t.push({key:"hook_daemon_metrics_read",value:k.message,target:"readable canonical telemetry",ok:false,severity:"error"});}finally{y?.close();}}let g=Math.max(i,u),f=Math.max(l,g),p=f===0?0:g/f;t.push({key:"hook_daemon_requests_24h",value:f,ok:true,severity:"info"}),t.push({key:"hook_fallback_rate_24h",value:Math.round(p*1e4)/1e4,target:0,ok:g===0,severity:"warning"}),t.push({key:"hook_daemon_response_ms_avg",value:d??"no successful requests",target:"<= 1000",ok:d===null||d<=1e3,severity:"warning"});let m=g>0?["4-Gate enforcement","memory prefetch cache","daemon-shared hook state"]:[];t.push({key:"degraded_hook_features",value:m,target:[],ok:m.length===0,severity:"warning"});let h=join$1(n,".devflow","logs","hook-debug");try{let y=Nc(h);t.push({key:"hook_debug_log_bytes",value:y.bytes,target:`<= ${kr}`,ok:y.bytes<=kr,severity:"warning"}),t.push({key:"hook_debug_log_files",value:y.files,target:"rotated per project",ok:!0,severity:"info"});}catch(y){t.push({key:"hook_debug_log_read",value:y.message,target:"readable regular files without symlink traversal",ok:false,severity:"error"});}return {name:"Hook path health",status:T(t),metrics:t}}function _e(e){try{return statSync$1(e).isDirectory()?realpathSync.native(e):null}catch{return null}}function Ne(e){return JSON.parse(readFileSync$1(e,"utf8"))}function U(e){return typeof e=="object"&&e!==null?e:null}function Br(e,t){return Mc.has(e)&&!(t.tolerateControlSyntax&&Lc.has(e))}function dt(e,t={}){if(Buffer.byteLength(e)>Wr)return {segments:[],malformed:true};let n=[],o=[],r="",s=null,i=false,a=false,c=()=>{r.length>0&&o.push(r),r="";},l=()=>{c(),o.length>0&&n.push(o),o=[];};for(let u=0;u<e.length;u+=1){let d=e[u];if(i){r+=d,i=false;continue}if(s==="'"){d==="'"?s=null:r+=d;continue}if(d==="\\"){if(e[u+1]===`
|
|
151
153
|
`){u+=1;continue}if(e[u+1]==="\r"&&e[u+2]===`
|
|
152
154
|
`){u+=2;continue}i=true;continue}if(s==='"'){d==='"'?s=null:((d==="`"||d==="$"&&e[u+1]==="(")&&!t.tolerateControlSyntax&&(a=true),r+=d);continue}if(d==="'"||d==='"'){s=d;continue}if((d==="`"||d==="$"&&e[u+1]==="(")&&!t.tolerateControlSyntax){a=true,r+=d;continue}let g=e.slice(u,u+2);if(d==="#"&&r.length===0){for(;u<e.length&&e[u]!==`
|
|
153
|
-
`;)u+=1;l();continue}g==="<<"&&!t.tolerateControlSyntax&&(a=true);let f=d==="{"&&r==="$"&&/^\{(?:CLAUDE_PLUGIN_ROOT|CLAUDE_PROJECT_DIR|HOME|PLUGIN_ROOT)\}/.test(e.slice(u))||d==="}"&&
|
|
154
|
-
`].includes(d)){l();continue}if(/\s/.test(d)){c();continue}r+=d;}return (s!==null||i)&&(a=true),l(),n.some(u=>{let d=u.find(g=>!/^[A-Za-z_][A-Za-z0-9_]*=/.test(g));return d!==void 0&&
|
|
155
|
+
`;)u+=1;l();continue}g==="<<"&&!t.tolerateControlSyntax&&(a=true);let f=d==="{"&&r==="$"&&/^\{(?:CLAUDE_PLUGIN_ROOT|CLAUDE_PROJECT_DIR|HOME|PLUGIN_ROOT)\}/.test(e.slice(u))||d==="}"&&Fc.test(`${r}}`);if(["(",")","{","}"].includes(d)&&!f&&!t.tolerateControlSyntax&&(a=true),g==="&&"||g==="||"){l(),u+=1;continue}if([";","|","&",`
|
|
156
|
+
`].includes(d)){l();continue}if(/\s/.test(d)){c();continue}r+=d;}return (s!==null||i)&&(a=true),l(),n.some(u=>{let d=u.find(g=>!/^[A-Za-z_][A-Za-z0-9_]*=/.test(g));return d!==void 0&&Br(d,t)})&&(a=true),{segments:n,malformed:a}}function Hc(e){return dt(e).segments.flat().join(" ")}function Uc(e,t){let n=extname(e);return [".bash",".sh",".zsh"].includes(n)||/^#![^\n]*\b(?:ba|z)?sh\b/.test(t)?true:n===""&&!/^#!/.test(t)}function qr(e,t){return Uc(e,t)?"shell":/^#![^\n]*\b(?:node|tsx)\b/.test(t)?"node":/^#![^\n]*\bpython(?:3)?\b/.test(t)?"python":[".cjs",".js",".mjs",".ts"].includes(extname(e))?"node":extname(e)===".py"?"python":"infer"}function Wc(e){let t=e.split(""),n=null;for(let o=0;o<e.length;o+=1){let r=e[o];if(n!==null){r==="\\"?o+=1:r===n&&(n=null);continue}if(r==="'"||r==='"'||r==="`"){n=r;continue}if(r!=="/"||!["/","*"].includes(e[o+1]??""))continue;let s=e[o+1]==="*";for(t[o]=" ",t[o+1]=" ",o+=2;o<e.length;){if(s&&e[o]==="*"&&e[o+1]==="/"){t[o]=" ",t[o+1]=" ",o+=1;break}if(!s&&e[o]===`
|
|
155
157
|
`){o-=1;break}e[o]!==`
|
|
156
|
-
`&&e[o]!=="\r"&&(t[o]=" "),o+=1;}}return t.join("")}function
|
|
158
|
+
`&&e[o]!=="\r"&&(t[o]=" "),o+=1;}}return t.join("")}function Bc(e){let t=e.split("");for(let n=0;n<e.length;n+=1){let o=e[n];if(o==="#"){for(;n<e.length&&e[n]!==`
|
|
157
159
|
`;)t[n]=" ",n+=1;continue}if(o!=="'"&&o!=='"')continue;let r=o,s=e.slice(n,n+3)===r.repeat(3)?3:1;for(n+=s;n<e.length;){if(e[n]==="\\"){n+=2;continue}if(e.slice(n,n+s)===r.repeat(s)){n+=s-1;break}if(s===1&&(e[n]===`
|
|
158
|
-
`||e[n]==="\r"))break;n+=1;}}return t.join("")}function fe(e,t,n="infer"){let o=t
|
|
160
|
+
`||e[n]==="\r"))break;n+=1;}}return t.join("")}function fe(e,t,n="infer"){let o=t?Hc(e):n==="node"?Wc(e):n==="python"?Bc(e):e;return [...new Set(o.match(jc)??[])]}function qc(e){return dt(e).segments.flat()}function me(e,t,n=false,o="infer"){let r=[[/^\$\{CLAUDE_PROJECT_DIR\}(?:\/(.*))?$/,t.project],[/^\$CLAUDE_PROJECT_DIR(?:\/(.*))?$/,t.project],[/^\$\{HOME\}(?:\/(.*))?$/,t.homePath],[/^\$HOME(?:\/(.*))?$/,t.homePath],[/^~(?:\/(.*))?$/,t.homePath]];for(let[i,a]of r){let c=e.match(i);if(c)return {path:resolve(a,c[1]??""),containmentRoot:a,cwd:t.cwd,parserKind:o}}if(/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(e)||e.startsWith("node:"))return null;if(isAbsolute(e)){let i=resolve(e),a=resolve(t.project),c=resolve(t.homePath),l=Se(a,i)?a:Se(c,i)?c:dirname(i);return {path:i,containmentRoot:l,cwd:t.cwd,parserKind:o}}return n?{path:resolve(t.cwd,e),containmentRoot:t.project,cwd:t.cwd,parserKind:o}:e.startsWith("-")||e.startsWith("#")?null:/^[A-Za-z0-9._/-]+$/.test(e)&&(e.startsWith("./")||e.startsWith("../")||e.includes("/")||/\.(?:bash|cjs|js|mjs|py|sh|ts|zsh)$/.test(e))?{path:resolve(t.cwd,e),containmentRoot:t.project,cwd:t.cwd,parserKind:o}:null}function Kc(e){let t=e.indexOf(",");if(t<0)return null;try{let n=e.slice(5,t),o=e.slice(t+1),r=n.split(";").includes("base64")?Buffer.from(o,"base64"):Buffer.from(decodeURIComponent(o),"utf8");if(r.length>Wr||r.includes(0))return null;let s=r.toString("utf8");return s.includes("\uFFFD")?null:s}catch{return null}}function Hn(e,t=true){let n=e.value;if(n.startsWith("node:")||isBuiltin(n))return {malformed:false};if(n.startsWith("data:")){let s=Kc(n);return s===null?{malformed:true}:{inlineContent:{content:s,source:n},malformed:Dt(s)}}if(n.startsWith("file:"))try{let s=fileURLToPath(n),i={project:e.project,homePath:e.homePath,cwd:e.cwd};return {reference:me(s,i,!0,e.parserKind)??void 0,malformed:!1}}catch{return {malformed:true}}if(/^[A-Za-z][A-Za-z0-9+.-]*:/.test(n)||Oe(n))return {malformed:true};let o=isAbsolute(n)||n.startsWith("./")||n.startsWith("../")||n.startsWith("~")||n.startsWith("$");if(!t&&!o)return {malformed:false};let r={project:e.project,homePath:e.homePath,cwd:e.cwd};if(o){if(e.issuerPath&&!n.startsWith("~")&&!n.startsWith("$")){let s=Jc(n,e.issuerPath,e.nodeResolutionKind??"esm");if(s)return {reference:me(s,r,true,e.parserKind)??void 0,malformed:false}}return {reference:me(n,r,true,e.parserKind)??void 0,malformed:false}}if(e.nodeResolutionKind==="esm")return {malformed:true};try{let s=e.issuerPath??join$1(e.cwd,"package.json"),i=createRequire$1(s).resolve(n);return isBuiltin(i)?{malformed:!1}:{reference:me(i,r,!0,e.parserKind)??void 0,malformed:!1}}catch{return {malformed:true}}}function zc(e){let t=[e];extname(e)===""&&t.push(...br.map(n=>`${e}${n}`),...br.map(n=>join$1(e,`index${n}`)));for(let n of t)try{if(statSync$1(n).isFile())return n}catch{}return null}function Jc(e,t,n){if(n==="cjs")try{let r=createRequire$1(t).resolve(e);return isBuiltin(r)?null:r}catch{}let o=isAbsolute(e)?resolve(e):resolve(dirname(t),e);return zc(o)??o}function Vc(e){let t=[],n=false;for(let o=0;o<e.length;){let r=e[o];if(/\s/.test(r)){o+=1;continue}if(r==="/"&&e[o+1]==="/"){for(o+=2;o<e.length&&e[o]!==`
|
|
159
161
|
`;)o+=1;continue}if(r==="/"&&e[o+1]==="*"){let s=e.indexOf("*/",o+2);if(s<0){n=true;break}o=s+2;continue}if(r==="'"||r==='"'){let s=r,i="",a=true;o+=1;let c=false;for(;o<e.length;){let l=e[o];if(l===s){c=true,o+=1;break}if(l==="\\"){if(a=false,o+1>=e.length)break;i+=e[o+1],o+=2;continue}if(l===`
|
|
160
|
-
`||l==="\r"){a=false;break}i+=l,o+=1;}n||=!c,t.push({kind:"string",value:i,valid:a&&c});continue}if(r==="`"){let s=false,i=false;for(o+=1;o<e.length;){let a=e[o];if(!s&&a==="`"){i=true,o+=1;break}s=!s&&a==="\\",a!=="\\"&&(s=false),o+=1;}n||=!i,t.push({kind:"template",value:"",valid:i});continue}if(/[A-Za-z_$]/.test(r)){let s=o+1;for(;s<e.length&&/[A-Za-z0-9_$]/.test(e[s]);)s+=1;t.push({kind:"identifier",value:e.slice(o,s),valid:true}),o=s;continue}t.push({kind:"punctuation",value:r,valid:true}),o+=1;}return {tokens:t,malformed:n}}function
|
|
162
|
+
`||l==="\r"){a=false;break}i+=l,o+=1;}n||=!c,t.push({kind:"string",value:i,valid:a&&c});continue}if(r==="`"){let s=false,i=false;for(o+=1;o<e.length;){let a=e[o];if(!s&&a==="`"){i=true,o+=1;break}s=!s&&a==="\\",a!=="\\"&&(s=false),o+=1;}n||=!i,t.push({kind:"template",value:"",valid:i});continue}if(/[A-Za-z_$]/.test(r)){let s=o+1;for(;s<e.length&&/[A-Za-z0-9_$]/.test(e[s]);)s+=1;t.push({kind:"identifier",value:e.slice(o,s),valid:true}),o=s;continue}t.push({kind:"punctuation",value:r,valid:true}),o+=1;}return {tokens:t,malformed:n}}function Gc(e,t,n,o=true){let r=Vc(t),s=[],i=r.malformed,a=(d,g)=>{if(!d||d.kind!=="string"||!d.valid||d.value.length===0){i=true;return}s.push({value:d.value,cwd:dirname(e),project:n.project,homePath:n.homePath,parserKind:"node",nodeResolutionKind:g,issuerPath:e});},{tokens:c}=r;for(let d=0;d<c.length;d+=1){let g=c[d],f=c[d-1];if(g.kind!=="identifier")continue;if(g.value==="eval"&&f?.value!=="."&&c[d+1]?.value==="("){i=true;continue}if(g.value==="require"){if(f?.value==="."){c[d-2]?.value==="module"&&c[d+1]?.value==="("&&(i=true);continue}if(c[d+1]?.value==="("){let m=c[d+2];c[d+3]?.value===")"||(i=true),a(m,"cjs");continue}i=true;continue}if(f?.value==="."||!["export","import"].includes(g.value))continue;if(g.value==="import"&&c[d+1]?.value==="("){let m=c[d+2];c[d+3]?.value===")"||(i=true),a(m,"esm");continue}if(g.value==="import"&&c[d+1]?.kind==="string"){a(c[d+1],"esm");continue}if(g.value==="import"&&c[d+1]?.value===".")continue;let p=-1;for(let m=d+1;m<Math.min(c.length,d+32)&&c[m].value!==";";m+=1)if(c[m].value==="from"){p=m;break}p>=0?a(c[p+1],"esm"):g.value==="import"&&(i=true);}let l=[],u=[];for(let d of s){let g=Hn(d,o);g.reference&&l.push(g.reference),g.inlineContent&&u.push(g.inlineContent),i||=g.malformed;}return {references:l,inlineContents:u,malformed:i}}function Yc(e){let t=e.split(""),n=false;for(let o=0;o<e.length;){let r=e[o];if(r==="#"){for(;o<e.length&&e[o]!==`
|
|
161
163
|
`;)t[o]=" ",o+=1;continue}if(r!=="'"&&r!=='"'){o+=1;continue}let s=o;for(;s>0&&/[A-Za-z]/.test(e[s-1]);)s-=1;let i=e.slice(s,o),a=/^(?:f|fr|rf)$/i.test(i),c=r,l=e.slice(o,o+3)===c.repeat(3),u=l?3:1,d=o;for(let f=0;f<u;f+=1)t[d+f]=" ";d+=u;let g=false;for(;d<e.length;){if(e[d]==="\\"){t[d]=" ",d+1<e.length&&(t[d+1]=" "),d+=2;continue}if(e.slice(d,d+u)===c.repeat(u)){for(let f=0;f<u;f+=1)t[d+f]=" ";d+=u,g=true;break}if(!l&&(e[d]===`
|
|
162
164
|
`||e[d]==="\r"))break;e[d]!==`
|
|
163
|
-
`&&e[d]!=="\r"&&(t[d]=" "),d+=1;}if(a){let f=e.slice(o+u,d-u);for(let p=0;p<f.length;p+=1)if(f[p]==="{"){if(f[p+1]==="{"){p+=1;continue}n=true;break}}n||=!g,o=d;}return {content:t.join(""),malformed:n}}function wr(e,t){let n=t.split(".");if(n.length>Mn)return {paths:[],resolved:false};let o=[],r=e;for(let s=0;s<n.length;s+=1){r=join$1(r,n[s]);let i=join$1(r,"__init__.py");try{if(statSync$1(i).isFile()){o.push(i);continue}}catch{}if(s===n.length-1){let c=`${r}.py`;try{if(statSync$1(c).isFile())return o.push(c),{paths:o,resolved:!0}}catch{return {paths:o,resolved:false}}return {paths:o,resolved:false}}try{if(!statSync$1(r).isDirectory())return {paths:o,resolved:!1}}catch{return {paths:o,resolved:false}}}return {paths:o,resolved:o.length>0}}function Wc(e,t,n){let o=Uc(t),r=[],s=o.malformed||/\b(?:exec|eval|__import__)\s*\(|\bimportlib\s*\./.test(o.content),i=d=>{let g=dirname(e);for(let f=1;f<d;f+=1)g=dirname(g);return g},a=d=>{let g=me(d,{...n,cwd:dirname(e)},true,"python");g?r.push(g):s=true;},c=(d,g=0)=>{if(!/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(d))return s=true,null;let f=i(g),p=wr(f,d);s||=!p.resolved;for(let h of p.paths)a(h);let m=p.paths.at(-1);return m&&basename(m)==="__init__.py"?dirname(m):null},l=d=>{let g=[];for(let f of d.split(",")){let p=f.trim().split(/\s+as\s+/)[0];if(p==="*"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(p)){s=true;continue}g.push(p);}return g},u=(d,g)=>{for(let f of l(g))d&&wr(d,f).resolved&&(s=true);};for(let d of o.content.split(/\r?\n/))for(let g of d.split(/[;:]/)){let f=g.trim();if(f.startsWith("import ")){let v=f.slice(7).split(",");for(let b of v)c(b.trim().split(/\s+as\s+/)[0]);continue}let p=f.match(/^from\s+(\.*)([A-Za-z_][A-Za-z0-9_.]*)?\s+import\s+(.+)$/);if(!p)continue;let m=p[1].length,h=p[2];if(h){let v=c(h,m);u(v,p[3]);continue}if(m===0){s=true;continue}let y=i(m),w=join$1(y,"__init__.py"),R=false;try{R=statSync$1(w).isFile();}catch{}if(R){a(w),u(y,p[3]);continue}for(let v of l(p[3]))c(v,m);}return {references:[...new Map(r.map(d=>[d.path,d])).values()],inlineContents:[],malformed:s}}function Br(e,t,n,o,r=true){return n==="node"?Hc(e,t,o,r):n==="python"?Wc(e,t,o):{references:[],inlineContents:[],malformed:false}}function br(e,t,n,o=t){let r={project:t,homePath:n,cwd:o},s=xt(e,0,r),i=new Set((s.artifacts??[]).map(g=>g.value)),a=s.tokens.filter(g=>!i.has(g)).map(g=>me(g,r)).filter(g=>g!==null),c=[],l=[...s.inlineContents??[]],u=s.malformed;for(let g of s.artifacts??[]){if(g.nodeResolutionKind){let p=Ln(g);p.reference&&c.push(p.reference),p.inlineContent&&l.push(p.inlineContent),u||=p.malformed;continue}let f=me(g.value,{...r,cwd:g.cwd},true,g.parserKind);f?c.push(f):u=true;}let d=[...a,...c];return {references:[...new Map(d.map(g=>[`${g.path}:${g.parserKind}`,g])).values()],inlineContents:l,malformed:u}}function qr(e){return /^[A-Za-z_][A-Za-z0-9_]*=/.test(e)}function Oe(e){return /[*?\[]/.test(e)?true:e.includes("$")?!/^(?:\$(?:CLAUDE_PLUGIN_ROOT|CLAUDE_PROJECT_DIR|HOME|PLUGIN_ROOT)|\$\{(?:CLAUDE_PLUGIN_ROOT|CLAUDE_PROJECT_DIR|HOME|PLUGIN_ROOT)\})(?:\/[A-Za-z0-9._/-]*)?$/.test(e):false}function Dt(e){return /\b(?:import|require)\s*\(/.test(e)||/\bimport\s+(?:[^;\n]*\s+from\s+)?["']/.test(e)||/\b(?:eval|Function)\s*\(/.test(e)}function it(e,t){for(let n of t)if(e.startsWith(`${n}=`))return e.slice(n.length+1);return null}function Vc(e,t,n){let o=[],r=[],s=false,i=(u,d)=>{o.push(u),r.push({value:u,cwd:n.cwd,project:n.project,homePath:n.homePath,parserKind:"node",nodeResolutionKind:d}),s||=Oe(u);},a=(u=s)=>({tokens:o,artifacts:r,malformed:u}),c=t,l=false;for(;c<e.length;){let u=e[c];if(u==="--"){let h=e[c+1];return h&&!l&&i(h),h?a():a(true)}if(!u.startsWith("-"))return l||i(u),a();if(zc.has(u))return a();if(Kc.has(u)){l=true,c+=1;continue}let d=Sr.has(u)?"cjs":_r.has(u)?"esm":null;if(d){let h=e[c+1];if(!h)return a(true);i(h,d),c+=2;continue}let g=it(u,Sr),f=it(u,_r),p=g??f;if(p!==null){if(!p)return a(true);i(p,g!==null?"cjs":"esm"),c+=1;continue}if(u.startsWith("-r")&&u.length>2){i(u.slice(2),"cjs"),c+=1;continue}if(Pr.has(u)){let h=e[c+1];return a(h===void 0?true:s||Dt(h))}let m=it(u,Pr);if(m!==null)return a(s||Dt(m));if((u.startsWith("-e")||u.startsWith("-p"))&&u.length>2)return a(s||Dt(u.slice(2)));if(Er.has(u)){if(e[c+1]===void 0)return a(true);c+=2;continue}if(it(u,Er)!==null){c+=1;continue}if(qc.has(u)){c+=1;continue}return a(true)}return l?a():a(true)}function Zc(e,t,n,o,r){let s=t;for(;s<e.length;){let i=e[s];if(i==="--"){let a=e[s+1];return a?{tokens:[a],artifacts:[{value:a,cwd:o.cwd,project:o.project,homePath:o.homePath,parserKind:"shell"}],malformed:Oe(a)}:{tokens:[],malformed:true}}if(i==="-c"||i==="-lc"){let a=e[s+1];return a?xt(a,n+1,o,r):{tokens:[],malformed:true}}if(i==="-o"){if(!e[s+1])return {tokens:[],malformed:true};s+=2;continue}if(Jc.has(i)){s+=1;continue}return i.startsWith("-")||i.startsWith("+")?{tokens:[],malformed:true}:{tokens:[i],artifacts:[{value:i,cwd:o.cwd,project:o.project,homePath:o.homePath,parserKind:"shell"}],malformed:Oe(i)}}return {tokens:[],malformed:true}}function Qc(e,t,n){let o=t;for(;o<e.length;){let r=e[o];if(r==="--"){let s=e[o+1];return s?{tokens:[s],artifacts:[{value:s,cwd:n.cwd,project:n.project,homePath:n.homePath,parserKind:"python"}],malformed:Oe(s)}:{tokens:[],malformed:true}}if(!r.startsWith("-"))return {tokens:[r],artifacts:[{value:r,cwd:n.cwd,project:n.project,homePath:n.homePath,parserKind:"python"}],malformed:Oe(r)};if(Yc.has(r))return {tokens:[],malformed:false};if(r==="-c"||r==="-m"||r.startsWith("-c"))return {tokens:[],malformed:true};if(Cr.has(r)){if(e[o+1]===void 0)return {tokens:[],malformed:true};o+=2;continue}if(it(r,Cr)!==null){o+=1;continue}if(Gc.has(r)){o+=1;continue}return {tokens:[],malformed:true}}return {tokens:[],malformed:true}}function Cn(e,t){let n=me(e,t,true);if(!n)return null;let o=_e(n.path),r=_e(t.project);return !o||!r||!Se(r,o)?null:o}function tl(e,t,n,o,r){let s=n;if(e==="builtin"){for(;t[s]?.startsWith("-");)s+=1;return {index:s,malformed:s>=t.length}}if(e==="command"){for(;t[s]?.startsWith("-");){let i=t[s];if(/^-[pvV]+$/.test(i)&&/[vV]/.test(i))return {index:t.length,malformed:false};s+=1;}return {index:s,malformed:s>=t.length}}if(e==="exec"){for(;t[s]?.startsWith("-");)t[s]==="-a"||t[s]==="--argv0"?s+=2:s+=1;return {index:s,malformed:s>=t.length}}if(e==="nohup"){for(;t[s]?.startsWith("-");)s+=1;return {index:s,malformed:s>=t.length}}if(e==="env"){let i=o;for(;s<t.length;){let a=t[s];if(qr(a))s+=1;else if(a==="-S"||a==="--split-string"){let c=t[s+1];if(!c)return {index:s,malformed:true};let l=dt(c,r);return l.malformed||l.segments.length!==1?{index:s,malformed:true}:{index:s,malformed:false,replacement:[...l.segments[0],...t.slice(s+2)],context:i}}else if(["-C","--chdir"].includes(a)){let c=t[s+1],l=c?Cn(c,i):null;if(!l)return {index:s,malformed:true};i={...i,cwd:l},s+=2;}else if(a.startsWith("--chdir=")){let c=Cn(a.slice(8),i);if(!c)return {index:s,malformed:true};i={...i,cwd:c},s+=1;}else if(a.startsWith("-C")&&a.length>2){let c=Cn(a.slice(2),i);if(!c)return {index:s,malformed:true};i={...i,cwd:c},s+=1;}else if(["-u","--unset"].includes(a)){if(!t[s+1])return {index:s,malformed:true};s+=2;}else if(a.startsWith("--unset=")||a.startsWith("-u")&&a.length>2)s+=1;else if(["--","-i","--ignore-environment","--null"].includes(a))s+=1;else {if(a.startsWith("-"))return {index:s,malformed:true};break}}return {index:s,malformed:s>=t.length,context:i}}for(;t[s]?.startsWith("-");){let i=t[s];["-k","--kill-after","-s","--signal"].includes(i)?s+=2:s+=1;}return s>=t.length?{index:s,malformed:true}:(s+=1,{index:s,malformed:s>=t.length})}function xt(e,t=0,n={project:process.cwd(),homePath:homedir$1(),cwd:process.cwd()},o={}){if(t>Fr)return {tokens:[],malformed:true};let r=dt(e,o),s=[],i=[],a=[],c=r.malformed;for(let l of r.segments){let u=Kr(l,t,n,o);s.push(...u.tokens),i.push(...u.artifacts??[]),a.push(...u.inlineContents??[]),c||=u.malformed;}return {tokens:s,artifacts:i,inlineContents:a,malformed:c}}function Kr(e,t,n,o){let r=0;for(;qr(e[r]??"");)r+=1;let s=e[r];if(!s)return {tokens:[],malformed:false};let i=[],a=t,c=false;for(;Xc.has(basename(s));){if(c||=basename(s)==="builtin",i.push(s),a+=1,a>Fr)return {tokens:i,malformed:true};let m=tl(basename(s),e,r+1,n,o);if(m.malformed)return {tokens:i,malformed:true};if(n=m.context??n,m.replacement){let h=Kr(m.replacement,a,m.context??n,o);return i.push(...h.tokens),{tokens:i,artifacts:h.artifacts,inlineContents:h.inlineContents,malformed:h.malformed}}if(r=m.index,s=e[r],!s)return {tokens:i,malformed:false}}let l=basename(s),u=!s.includes(sep)&&Ur(l,o),d=c&&!el.has(l);if(u||d)return {tokens:i,malformed:true};let g=Oe(s);i.push(s);let f=l;if(!Bc.has(f))return {tokens:i,malformed:g};let p=["node","tsx"].includes(f)?Vc(e,r+1,n):["bash","sh","zsh"].includes(f)?Zc(e,r+1,a,n,o):Qc(e,r+1,n);return i.push(...p.tokens),{tokens:i,artifacts:p.artifacts,inlineContents:p.inlineContents,malformed:g||p.malformed}}function zr(e){if(!isAbsolute(e))return null;let t=resolve(e),n=`${sep}hooks${sep}`,o=t.lastIndexOf(n);return o<0?null:_e(t.slice(0,o))}function nl(e,t){let n=new Map;for(let o of t)for(let r of jc(o)){let s=zr(r);if(!s)continue;let i=n.get(s)??[];i.push(o),n.set(s,i);}return [...n].map(([o,r])=>({root:o,configPath:e,commands:[...new Set(r)]}))}function ol(e){return e==="devflow@devflow"||e==="devflow@devflow-local"||e.startsWith("@devflow-tools/claude-code-plugin@")}function rl(e){return e.slice(e.lastIndexOf("@")+1)}function Rr(e){for(let t of [e,join$1(e,"claude-code"),join$1(e,"plugins","claude-code")]){let n=_e(t);if(n&&(existsSync$1(join$1(n,"hooks","hooks.json"))||existsSync$1(join$1(n,"hooks.json"))))return n}return null}function sl(e,t,n){let o=rl(e),r=U(t.extraKnownMarketplaces),s=U(r?.[o]);if(s){let i=U(s.source);return {configured:true,root:i?.source==="directory"&&typeof i.path=="string"?Rr(i.path):null}}try{let i=U(Ne(n)),a=U(i?.[o]);if(a){let c=U(a.source);return {configured:!0,root:c?.source==="directory"&&typeof c.path=="string"?Rr(c.path):null}}}catch{}return {configured:false,root:null}}function Dr(e){let t=[e?.lastUpdated,e?.installedAt].map(n=>{if(typeof n=="number"&&Number.isFinite(n)&&n>=0)return n;if(typeof n!="string")return null;let o=Date.parse(n);return Number.isFinite(o)?o:null}).filter(n=>n!==null);return t.length>0?Math.max(...t):null}function il(e,t){let n=U(e.entry),o=U(t.entry),r=Dr(n),s=Dr(o);if(r!==s)return r===null?1:s===null?-1:s-r;let i=typeof n?.version=="string"?$t(n.version):null,a=typeof o?.version=="string"?$t(o.version):null;if(i&&a){let c=Vr(a,i);if(c!==0)return c}else if(i||a)return i?-1:1;return t.index-e.index}function al(e,t){try{let n=U(Ne(t));if(!n)throw new Error("installed plugin manifest must be an object");let o=U(n.plugins);if(!o)throw new Error("installed plugin manifest plugins must be an object");let r=o?.[e];if(r===void 0)return {configured:!1,root:null};if(!Array.isArray(r)||r.length===0)return {configured:!0,malformed:!0,root:null};let s=r.map((a,c)=>({entry:a,index:c})).sort(il)[0],i=U(s?.entry);return !i||typeof i.installPath!="string"||i.installPath.length===0?{configured:!0,malformed:!0,root:null}:{configured:!0,root:_e(i.installPath)}}catch{if(existsSync$1(t))return {configured:true,malformed:true,root:null}}return {configured:false,root:null}}function $t(e){let t=e.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/);return t?{major:Number(t[1]),minor:Number(t[2]),patch:Number(t[3]),prerelease:t[4]?.split(".")??[]}:null}function Vr(e,t){for(let o of ["major","minor","patch"])if(e[o]!==t[o])return e[o]-t[o];if(e.prerelease.length===0||t.prerelease.length===0)return t.prerelease.length-e.prerelease.length;let n=Math.max(e.prerelease.length,t.prerelease.length);for(let o=0;o<n;o+=1){let r=e.prerelease[o],s=t.prerelease[o];if(r===void 0)return -1;if(s===void 0)return 1;if(r===s)continue;let i=/^\d+$/.test(r)?Number(r):null,a=/^\d+$/.test(s)?Number(s):null;return i!==null&&a!==null?i-a:i!==null?-1:a!==null?1:r.localeCompare(s)}return 0}function cl(e,t){let n=e.lastIndexOf("@");if(n<=0||n===e.length-1)return null;let o=e.slice(0,n),r=e.slice(n+1),s=join$1(t,r,o),i;try{i=readdirSync(s,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>{let c=join$1(s,a.name),l=a.name;try{let u=U(Ne(join$1(c,"package.json")));typeof u?.version=="string"&&(l=u.version);}catch{}return {name:a.name,path:c,version:l,mtimeMs:statSync$1(c).mtimeMs}});}catch{return null}return i.sort((a,c)=>{let l=$t(a.version),u=$t(c.version);if(l&&u){let d=Vr(u,l);if(d!==0)return d}else if(l||u)return l?-1:1;return c.mtimeMs-a.mtimeMs||c.name.localeCompare(a.name)}),i[0]?_e(i[0].path):null}function ll(e,t){if(t.legacyArtifactRoots!==void 0){let v=t.legacyArtifactRoots.map(b=>_e(b)).filter(b=>b!==null).map(b=>({root:b,inspectPluginConfig:true}));return {targets:v,configCommands:[],hooksDisabled:false,malformedSettings:[],malformedPluginMetadata:[],method:"injected",ok:v.length>0}}let n=t.claudeSettingsPath??join$1(t.homePath??homedir$1(),".claude","settings.json"),o=t.installedPluginsPath??join$1(t.homePath??homedir$1(),".claude","plugins","installed_plugins.json"),r=t.knownMarketplacesPath??join$1(t.homePath??homedir$1(),".claude","plugins","known_marketplaces.json"),s=t.pluginCachePath??join$1(t.homePath??homedir$1(),".claude","plugins","cache"),i=[],a=[],c=[],l=[...new Set([n,join$1(e,".claude","settings.json"),join$1(e,".claude","settings.local.json")])];for(let v of l)if(existsSync$1(v))try{let b=U(Ne(v));if(!b)throw new Error("settings must be an object");i.push({path:v,settings:b});}catch{a.push(v);}if(i.reduce((v,b)=>typeof b.settings.disableAllHooks=="boolean"?b.settings.disableAllHooks:v,false))return {targets:[],configCommands:[],hooksDisabled:true,malformedSettings:a,malformedPluginMetadata:[],method:"hooks-disabled",ok:a.length===0};let d=i.map(v=>{let b=[];return lt(v.settings.hooks,b),{path:v.path,commands:b}}),g=d.flatMap(v=>v.commands),f=d.flatMap(v=>nl(v.path,v.commands)),m=[...i.reduce((v,b)=>{let _=b.settings.enabledPlugins;if(typeof _!="object"||_===null)return v;for(let[j,Y]of Object.entries(_))ol(j)&&typeof Y=="boolean"&&v.set(j,Y);return v},new Map)].filter(([,v])=>v).map(([v])=>v).sort(),h=[...f],y=false;for(let v of m){let b=al(v,o);b.malformed&&c.push(o);let _=b.root;if(!b.configured){let j=i.map(oe=>sl(v,oe.settings,r)).filter(oe=>oe.configured),Y=j[j.length-1];Y?_=Y.root:_=cl(v,s);}_?h.push({root:_,inspectPluginConfig:true}):y=true;}let w=[...h.reduce((v,b)=>{let _=v.get(b.root);return _?(v.set(b.root,{root:b.root,configPath:_.configPath??b.configPath,commands:[...new Set([..._.commands??[],...b.commands??[]])],inspectPluginConfig:!!(_.inspectPluginConfig||b.inspectPluginConfig)}),v):(v.set(b.root,b),v)},new Map).values()],R=[g.length>0?"settings-hooks":null,m.length>0?"enabled-plugin":null].filter(v=>v!==null);return {targets:w,configCommands:d.filter(v=>v.commands.length>0),hooksDisabled:false,method:R.length>0?`${R.join("+")}${y?"-unresolved":""}`:a.length>0?"settings-unresolved":"enabled-plugin-unresolved",malformedSettings:a,malformedPluginMetadata:[...new Set(c)],ok:(w.length>0||g.length>0)&&!y&&a.length===0&&c.length===0}}function ul(e){let t=e;for(;;){let n=join$1(t,"package.json");if(existsSync$1(n))try{if(JSON.parse(readFileSync$1(n,"utf8")).workspaces)return t}catch{}let o=dirname(t);if(o===t)return;t=o;}}function lt(e,t){if(Array.isArray(e)){for(let n of e)lt(n,t);return}if(!(typeof e!="object"||e===null))for(let[n,o]of Object.entries(e))n==="command"&&typeof o=="string"?t.push(o):lt(o,t);}function Rn(e){return [...e.matchAll(Rc)].map(t=>t[1])}function dl(e){let t=new Map,n=dt(e,{tolerateControlSyntax:true});for(let o of n.segments.flat()){let r=o.match(/^([A-Za-z_][A-Za-z0-9_]*)=(\$(?:\{(?:CLAUDE_)?PLUGIN_ROOT\}|(?:CLAUDE_)?PLUGIN_ROOT)\/[A-Za-z0-9._/-]+)$/);r&&t.set(r[1],r[2]);}return t.size===0?e:e.replace(/\$(?:\{([A-Za-z_][A-Za-z0-9_]*)\}|([A-Za-z_][A-Za-z0-9_]*))/g,(o,r,s)=>t.get(r??s??"")??o)}function gl(e){let t=spawnSync("bash",["--noprofile","--norc","-n"],{encoding:"utf8",env:{PATH:process.env.PATH??"",HOME:process.env.HOME??"",BASH_ENV:"",ENV:""},input:e,timeout:2e3});return t.error!==void 0||t.status!==0}function fl(e){if(![".cjs",".js",".mjs"].includes(extname(e)))return false;let t=spawnSync(process.execPath,["--check",e],{encoding:"utf8",env:{PATH:process.env.PATH??"",HOME:process.env.HOME??""},timeout:2e3});return t.error!==void 0||t.status!==0}function Dn(e,t){let n=resolve(e,t);return n.startsWith(`${resolve(e)}${sep}`)?n:null}function Se(e,t){return t===e||t.startsWith(`${e}${sep}`)}function Nn(e){let t;try{t=lstatSync(e);}catch{return {kind:"missing"}}if(!t.isFile())return {kind:"unsafe",reason:"nonregular"};if(t.size>Rt)return {kind:"unsafe",reason:"oversized"};let n;try{n=openSync(e,constants.O_RDONLY|constants.O_NONBLOCK|constants.O_NOFOLLOW);}catch{return {kind:"missing"}}try{let o=fstatSync(n);if(!o.isFile())return {kind:"unsafe",reason:"nonregular"};if(o.size>Rt)return {kind:"unsafe",reason:"oversized"};let r=Buffer.alloc(Math.min(o.size+1,Rt+1)),s=0;for(;s<r.length;){let c=readSync(n,r,s,r.length-s,null);if(c===0)break;s+=c;}if(s>Rt)return {kind:"unsafe",reason:"oversized"};let i=r.subarray(0,s);if(i.includes(0))return {kind:"unsafe",reason:"binary"};let a=i.toString("utf8");return a.includes("\uFFFD")?{kind:"unsafe",reason:"binary"}:{kind:"text",content:a}}catch{return {kind:"missing"}}finally{closeSync(n);}}function Tn(e,t){return `${e} (${t})`}function ml(e,t,n,o){let r=[],s=new Set,i=0,a=(c,l=0)=>{if(l>Mn){o.traversalLimitRoots.push(e);return}let u=resolve(c.path),d=resolve(c.containmentRoot),g;try{g=realpathSync.native(d);}catch{g=d;}if(!existsSync$1(u)){Se(d,u)?o.missing.push(u):o.escapedArtifacts.push(u);return}let f;try{f=realpathSync.native(u);}catch{o.missing.push(u);return}if(!Se(g,f)){o.escapedArtifacts.push(u);return}let p=`${f}:${c.parserKind}:${c.cwd}`;s.has(p)||(s.add(p),r.push({...c,path:f,depth:l}));};for(let c of n){let l=br(c,e,t);l.malformed&&o.malformedCommands.push(c);for(let u of l.inlineContents)for(let d of fe(u.content,false,"node"))o.findings.push({artifact:u.source,endpoint:d});for(let u of l.references)a(u);}for(;r.length>0;){if(i>=Lr){o.traversalLimitRoots.push(e);break}let c=r.shift(),l=c.path;i+=1;let u=Nn(l);if(u.kind==="missing"){o.missing.push(l);continue}if(u.kind==="unsafe"){u.reason!=="binary"&&o.unsafeArtifacts.push(Tn(l,u.reason));continue}let{content:d}=u;o.inspected.push(l);let g=c.parserKind==="infer"?Wr(l,d):c.parserKind,f=g==="shell";for(let p of fe(d,f,g))o.findings.push({artifact:l,endpoint:p});if(f){let p=br(d,e,t,c.cwd);p.malformed&&o.malformedCommands.push(l);for(let m of p.inlineContents)for(let h of fe(m.content,false,"node"))o.findings.push({artifact:m.source,endpoint:h});for(let m of p.references)a(m,c.depth+1);}else if(g==="node"||g==="python"){let p=Br(l,d,g,{project:e,homePath:t,cwd:dirname(l)});p.malformed&&o.malformedCommands.push(l);for(let m of p.inlineContents)for(let h of fe(m.content,false,"node"))o.findings.push({artifact:m.source,endpoint:h});for(let m of p.references)a(m,c.depth+1);}}}function pl(e,t,n,o){let r=realpathSync.native(n.root),s=[],i=new Set,a=ul(r),c=0,l=(f,p=false,m=r,h="infer",y=e,w=0)=>{if(w>Mn){o.traversalLimitRoots.push(r);return}let R=realpathSync.native(m),v=resolve(f);if(!existsSync$1(v)){if(!Se(R,v)){o.escapedArtifacts.push(v);return}p&&o.missing.push(v);return}let b;try{b=realpathSync.native(v);}catch{p&&o.missing.push(v);return}if(!Se(R,b)){o.escapedArtifacts.push(v);return}let _=`${b}:${h}:${y}`;i.has(_)||(i.add(_),s.push({path:b,parserKind:h,cwd:y,depth:w}));},u=(f,p,m,h=0)=>{for(let y of Rn(f)){let w=Dn(r,y);if(!w)continue;let R=(p.artifacts??[]).find(v=>v.value.includes("PLUGIN_ROOT")&&v.value.endsWith(y));l(w,true,r,R?.parserKind??"infer",R?.cwd??m,h);}},d=(f,p,m=0,h=false)=>{for(let y of f.artifacts??[]){if(y.value.includes("PLUGIN_ROOT"))continue;let w=y.nodeResolutionKind?Ln(y,!h):{reference:me(y.value,{project:y.project,homePath:y.homePath,cwd:y.cwd},true,y.parserKind)??void 0,malformed:false};if(w.malformed){o.malformedCommands.push(y.value);continue}if(w.inlineContent)for(let R of fe(w.inlineContent.content,false,"node"))o.findings.push({artifact:w.inlineContent.source,endpoint:R});w.reference&&l(w.reference.path,true,h?r:w.reference.containmentRoot,w.reference.parserKind,w.reference.cwd??p,m);}},g=f=>{for(let m of fe(f,true))o.findings.push({artifact:n.configPath??join$1(r,"hooks.json"),endpoint:m});let p=xt(f,0,{project:e,homePath:t,cwd:e});p.malformed&&o.malformedCommands.push(f),u(f,p,e),d(p,e);for(let m of p.tokens){if(!isAbsolute(m))continue;let h=zr(m),y=(p.artifacts??[]).find(w=>w.value===m);h===r&&l(m,true,r,y?.parserKind??"infer",y?.cwd??e);}};if(n.commands){n.configPath&&o.configsInspected.push(n.configPath);for(let f of n.commands)g(f);}if(n.inspectPluginConfig||!n.commands){let f=join$1(r,"hooks","hooks.json"),p=join$1(r,"hooks.json"),m=existsSync$1(p)?p:f;if(!existsSync$1(m))o.missing.push(m),l(join$1(r,"hooks","session-start"));else {o.configsInspected.push(m);let h;try{h=realpathSync.native(m);}catch{o.missing.push(m),l(join$1(r,"hooks","session-start")),h="";}if(h&&!Se(r,h)&&(o.escapedArtifacts.push(m),l(join$1(r,"hooks","session-start")),h=""),h){let y=Nn(h);if(y.kind==="unsafe")o.unsafeArtifacts.push(Tn(m,y.reason)),l(join$1(r,"hooks","session-start"));else if(y.kind==="missing")o.missing.push(m),l(join$1(r,"hooks","session-start"));else try{let w=JSON.parse(y.content),R=[];lt(w,R);for(let v of R)g(v);}catch{o.malformedConfigs.push(m),l(join$1(r,"hooks","session-start"));}}}}for(;s.length>0;){if(c>=Lr){o.traversalLimitRoots.push(r);break}let f=s.shift(),p=f.path;c+=1;let m=Nn(p);if(m.kind==="missing"){o.missing.push(p);continue}if(m.kind==="unsafe"){o.unsafeArtifacts.push(Tn(p,m.reason));continue}let{content:h}=m;o.inspected.push(p);let y=f.parserKind==="infer"?Wr(p,h):f.parserKind,w=y==="shell";for(let b of fe(h,w,y))o.findings.push({artifact:p,endpoint:b});if(w){let b=dl(h),_=xt(b,0,{project:e,homePath:t,cwd:dirname(p)},{tolerateControlSyntax:true});gl(h)&&o.malformedCommands.push(p),u(b,_,dirname(p),f.depth+1),d(_,dirname(p),f.depth+1,true);}else if(y==="node"||y==="python"){let b=Br(p,h,y,{project:e,homePath:t,cwd:dirname(p)},false);(y==="node"?fl(p):b.malformed)&&o.malformedCommands.push(p);for(let _ of b.inlineContents)for(let j of fe(_.content,false,"node"))o.findings.push({artifact:_.source,endpoint:j});for(let _ of b.references){let j=relative(r,resolve(_.path));!j.startsWith(`..${sep}`)&&j.split(sep).includes("node_modules")||l(_.path,true,r,_.parserKind,_.cwd,f.depth+1);}for(let _ of Rn(h)){let j=Dn(r,_);j&&l(j,true,r,y,f.cwd,f.depth+1);}}else for(let b of Rn(h)){let _=Dn(r,b);_&&l(_,true,r,y,f.cwd,f.depth+1);}let R=p.startsWith(`${r}/`)?p.slice(r.length+1):"",v=basename(R).replace(/\.js$/,"");a&&(R.startsWith("hooks/")||R.startsWith("dist/hooks/"))&&l(join$1(a,"packages","devflow","src","hooks",`${v}.ts`),false,a),R.startsWith("hooks/")&&l(join$1(r,"dist","hooks",`${v}.js`));}}function hl(e){let t=e.installedPluginsPath??join$1(e.homePath??homedir$1(),".claude","plugins","installed_plugins.json"),n=new Map;if(!existsSync$1(t))return new Map;try{let o=U(Ne(t)),r=U(o?.plugins);if(!r)return new Map;for(let s of Object.values(r))if(Array.isArray(s))for(let i of s){let a=U(i);if(typeof a?.installPath!="string"||typeof a.version!="string")continue;let c=_e(a.installPath);if(!c)continue;let l=n.get(c)??new Set;l.add(a.version),n.set(c,l);}}catch{return new Map}return new Map([...n].map(([o,r])=>[o,[...r].sort()]))}function Ar(e){try{let t=U(Ne(e));return typeof t?.version=="string"?t.version:void 0}catch{return}}function yl(e,t){let n={layoutIssues:[],versionIssues:[],versionRecords:[],sessionStartIssues:[],daemonIssues:[]},o=hl(t);for(let r of e){let s=r.root,i=join$1(s,"package.json"),a=join$1(s,".claude-plugin","plugin.json");if(!(existsSync$1(i)||existsSync$1(a)))continue;let l=join$1(s,"hooks","hooks.json"),u=join$1(s,"hooks.json");existsSync$1(l)||n.layoutIssues.push({root:s,issue:"missing hooks/hooks.json"}),existsSync$1(u)&&n.layoutIssues.push({root:s,issue:"retired root hooks.json is present"});let d=existsSync$1(l)?l:u;try{let w=U(Ne(d)),R=U(w?.hooks),v=[];lt(R?.SessionStart,v),v.some(b=>/(?:^|[/\\])session-start(?:\s|$|["'])/.test(b))||n.sessionStartIssues.push({root:s,issue:"SessionStart wrapper is not registered"});}catch{n.sessionStartIssues.push({root:s,issue:"hook configuration is unreadable"});}let g=Ar(i),f=Ar(a),p=o.get(s)??[],m={root:s,packageVersion:g,manifestVersion:f,registryVersions:p};n.versionRecords.push(m),(!g||!f||g!==f||p.some(w=>w!==g))&&n.versionIssues.push(m);let h=join$1(s,"hooks","session-start"),y=join$1(s,"dist","hooks","hook-daemon.js");try{let w=readFileSync$1(h,"utf8");(!existsSync$1(y)||!w.includes("hook-daemon.js"))&&n.daemonIssues.push({root:s,issue:"SessionStart does not register the packaged hook daemon"});}catch{n.daemonIssues.push({root:s,issue:"SessionStart wrapper or hook daemon is missing"});}}return n}function vl(e,t){let n=ll(e,t),o={configsInspected:[],commandsInspected:[],inspected:[],missing:[],malformedConfigs:[],malformedCommands:[],unsafeArtifacts:[],traversalLimitRoots:[],escapedArtifacts:[],findings:[]};for(let D of n.configCommands){o.configsInspected.push(D.path);for(let F of D.commands){o.commandsInspected.push({configPath:D.path,command:F});for(let X of fe(F,true))o.findings.push({artifact:D.path,endpoint:X});}}ml(e,t.homePath??homedir$1(),n.configCommands.flatMap(D=>D.commands).filter(D=>!n.targets.some(F=>F.commands?.includes(D))),o);for(let D of n.targets)pl(e,t.homePath??homedir$1(),D,o);let r=[...new Set(o.configsInspected)],s=[...new Set(o.inspected)],i=o.commandsInspected.filter((D,F,X)=>X.findIndex(x=>x.configPath===D.configPath&&x.command===D.command)===F),a=[...new Set(o.missing)],c=[...new Set(o.malformedConfigs)],l=[...new Set(o.malformedCommands)],u=[...new Set(o.unsafeArtifacts)],d=[...new Set(o.traversalLimitRoots)],g=[...new Set(o.escapedArtifacts)],f=o.findings.filter((D,F,X)=>X.findIndex(x=>x.artifact===D.artifact&&x.endpoint===D.endpoint)===F),p=a.length>0||g.length>0||u.length>0,m=p&&!n.method.endsWith("-unresolved")?`${n.method}-unresolved`:n.method,h=yl(n.targets,t),y=t.claudeSettingsPath?dirname(t.claudeSettingsPath):null,w=t.homePath??(y&&basename(y)===".claude"?dirname(y):y)??homedir$1(),R=n.targets.map(D=>D.root).find(D=>existsSync$1(join$1(D,"skills")))??null,v=t.activePluginRoot?{root:existsSync$1(t.activePluginRoot)?t.activePluginRoot:null,version:null}:R?{root:R,version:null}:Ee(w,{installedPluginsPath:t.installedPluginsPath,pluginCachePath:t.pluginCachePath}),b=v.root,_=b?Ve(w,b):[],j=_.filter(D=>!D.isKnownDevFlowArtifact).map(D=>({skillName:D.skillName,path:D.globalPath,action:"inspect manually; file is modified or not a known DevFlow artifact"})),Y=[{key:"active_plugin_resolution",value:m,target:"resolved active DevFlow hook configuration",ok:n.ok&&!p,severity:"warning"},{key:"active_plugin_roots",value:n.targets.map(D=>D.root),ok:true,severity:"info"},{key:"hooks_disabled",value:n.hooksDisabled,ok:true,severity:"info"},{key:"plugin_hook_layout",value:h.layoutIssues,target:"hooks/hooks.json present and root hooks.json absent",ok:h.layoutIssues.length===0,severity:"error"},{key:"plugin_version_parity",value:h.versionRecords,target:"manifest, package, and installed registry versions match",ok:h.versionIssues.length===0,severity:"error"},{key:"session_start_hook_registration",value:h.sessionStartIssues,target:[],ok:h.sessionStartIssues.length===0,severity:"error"},{key:"hook_daemon_artifact_registration",value:h.daemonIssues,target:[],ok:h.daemonIssues.length===0,severity:"error"},{key:"malformed_active_settings",value:n.malformedSettings,target:[],ok:n.malformedSettings.length===0,severity:"warning"},{key:"malformed_plugin_metadata",value:n.malformedPluginMetadata,target:[],ok:n.malformedPluginMetadata.length===0,severity:"warning"},{key:"hook_configs_inspected",value:r.length,target:n.hooksDisabled?"hooks disabled":">= 1 hook config file",ok:n.hooksDisabled||r.length>0,severity:"warning"},{key:"legacy_artifacts_inspected",value:s.length+i.length,target:n.hooksDisabled?"hooks disabled":">= 1 active hook artifact",ok:n.hooksDisabled||s.length+i.length>0,severity:"warning"},{key:"missing_legacy_artifacts",value:a,target:[],ok:a.length===0,severity:"warning"},{key:"malformed_hook_configs",value:c,target:[],ok:c.length===0,severity:"warning"},{key:"malformed_hook_commands",value:l,target:[],ok:l.length===0,severity:"warning"},{key:"unsafe_legacy_artifacts",value:u,target:[],ok:u.length===0,severity:"warning"},{key:"legacy_artifact_traversal_limit",value:d,target:[],ok:d.length===0,severity:"warning"},{key:"escaped_legacy_artifacts",value:g.length,target:0,ok:g.length===0,severity:"warning"},{key:"retired_producer_paths",value:f.length,target:0,ok:f.length===0,severity:"error"},{key:"retired_producer_path_findings",value:f,ok:true,severity:"info"},{key:"skill_shadowing_count",value:_.length,target:0,ok:_.length===0,severity:"error"},{key:"shadowed_skills",value:_,target:[],ok:_.length===0,severity:"error"},{key:"active_skill_source",value:b,target:"existing plugin cache path",ok:true,severity:"info"},{key:"skill_shadowing_remediation",value:j,target:[],ok:true,severity:"info"}],oe=v.version??h.versionRecords.find(D=>D.root===b)?.packageVersion;return oe&&Y.push({key:"active_plugin_version",value:oe,ok:true,severity:"info"}),{name:"Legacy paths",status:T(Y),metrics:Y}}function kl(e){let t=dirname(fileURLToPath(import.meta.url)),n=[...new Set([e.acceptanceManifestPath,e.env?.DEVFLOW_ACCEPTANCE_MANIFEST,process.env.DEVFLOW_ACCEPTANCE_MANIFEST,join$1(t,"..","acceptance-manifest.json"),join$1(t,"..","..","..","..","packages","devflow","acceptance-manifest.json"),join$1(process.cwd(),"packages","devflow","acceptance-manifest.json")].filter(o=>!!o))];for(let o of n)if(existsSync$1(o))try{return {path:o,manifest:JSON.parse(readFileSync$1(o,"utf8"))}}catch(r){return {path:o,error:r.message}}return {error:`not found (${n.join(", ")})`}}function Tt(e){let t=kl(e);if(!t.manifest)return {metrics:[{key:"batch4_acceptance_manifest",value:t.error??"missing",target:"readable acceptance-manifest.json",ok:false,severity:"warning"}]};let n=Date.parse(t.manifest.verifiedAt),o=Number.isFinite(n)?((e.now??Date.now)()-n)/qe:Number.POSITIVE_INFINITY;return {manifest:t.manifest,metrics:[{key:"batch4_acceptance_manifest",value:t.path,target:"schemaVersion 1",ok:t.manifest.schemaVersion===1,severity:"error"},{key:"acceptance_evidence_age_days",value:Number.isFinite(o)?Number(o.toFixed(2)):"invalid timestamp",target:"0-30",ok:o>=0&&o<=30,severity:"warning"}]}}function wl(e,t){let n=[],o=join$1(e,".devflow","config.json"),r="default-enabled";if(existsSync$1(o))try{r=JSON.parse(readFileSync$1(o,"utf8")).sessionStart?.injectMemories??"default-enabled";}catch(a){n.push({key:"session_start_config",value:a.message,target:"valid .devflow/config.json",ok:false,severity:"error"});}let s=r!==false;n.push({key:"session_start_memory_injection",value:r,target:"enabled or configured budget",ok:s,severity:"warning"});let i=join$1(e,".devflow","memory","memories.db");if(!existsSync$1(i))n.push({key:"explicit_memory_channel",value:"memory database missing",target:"observations.source supports explicit_intent",ok:false,severity:"warning"});else {let a;try{a=ie(i,t);let l=(W(a,"observations")?a.prepare("PRAGMA table_info(observations)").all().map(u=>u.name):[]).includes("source");n.push({key:"explicit_memory_channel",value:l?"explicit_intent source available":"source column missing",target:"explicit_intent source available",ok:l,severity:"warning"}),l&&n.push({key:"explicit_memory_observations",value:B(a,"SELECT COUNT(*) count FROM observations WHERE source = 'explicit_intent'"),ok:!0,severity:"info"});}catch(c){n.push({key:"explicit_memory_channel_read",value:c.message,target:"readable memory database",ok:false,severity:"error"});}finally{a?.close();}}return {name:"Injection",status:T(n),metrics:n}}function bl(e,t){let n=[],o=join$1(e,".devflow","memory","memories.db");if(!existsSync$1(o))return n.push({key:"memories_db",value:"missing",target:o,ok:false,severity:"warning"}),{name:"Memory quality",status:T(n),metrics:n};let r;try{if(r=ie(o,t),!W(r,"memories"))n.push({key:"memories_schema",value:"memories table missing",target:"Batch 3 memory schema",ok:!1,severity:"warning"});else {let s=(t.now??Date.now)()-7*qe,i=r.prepare(`
|
|
165
|
+
`&&e[d]!=="\r"&&(t[d]=" "),d+=1;}if(a){let f=e.slice(o+u,d-u);for(let p=0;p<f.length;p+=1)if(f[p]==="{"){if(f[p+1]==="{"){p+=1;continue}n=true;break}}n||=!g,o=d;}return {content:t.join(""),malformed:n}}function Sr(e,t){let n=t.split(".");if(n.length>Fn)return {paths:[],resolved:false};let o=[],r=e;for(let s=0;s<n.length;s+=1){r=join$1(r,n[s]);let i=join$1(r,"__init__.py");try{if(statSync$1(i).isFile()){o.push(i);continue}}catch{}if(s===n.length-1){let c=`${r}.py`;try{if(statSync$1(c).isFile())return o.push(c),{paths:o,resolved:!0}}catch{return {paths:o,resolved:false}}return {paths:o,resolved:false}}try{if(!statSync$1(r).isDirectory())return {paths:o,resolved:!1}}catch{return {paths:o,resolved:false}}}return {paths:o,resolved:o.length>0}}function Zc(e,t,n){let o=Yc(t),r=[],s=o.malformed||/\b(?:exec|eval|__import__)\s*\(|\bimportlib\s*\./.test(o.content),i=d=>{let g=dirname(e);for(let f=1;f<d;f+=1)g=dirname(g);return g},a=d=>{let g=me(d,{...n,cwd:dirname(e)},true,"python");g?r.push(g):s=true;},c=(d,g=0)=>{if(!/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(d))return s=true,null;let f=i(g),p=Sr(f,d);s||=!p.resolved;for(let h of p.paths)a(h);let m=p.paths.at(-1);return m&&basename(m)==="__init__.py"?dirname(m):null},l=d=>{let g=[];for(let f of d.split(",")){let p=f.trim().split(/\s+as\s+/)[0];if(p==="*"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(p)){s=true;continue}g.push(p);}return g},u=(d,g)=>{for(let f of l(g))d&&Sr(d,f).resolved&&(s=true);};for(let d of o.content.split(/\r?\n/))for(let g of d.split(/[;:]/)){let f=g.trim();if(f.startsWith("import ")){let v=f.slice(7).split(",");for(let b of v)c(b.trim().split(/\s+as\s+/)[0]);continue}let p=f.match(/^from\s+(\.*)([A-Za-z_][A-Za-z0-9_.]*)?\s+import\s+(.+)$/);if(!p)continue;let m=p[1].length,h=p[2];if(h){let v=c(h,m);u(v,p[3]);continue}if(m===0){s=true;continue}let y=i(m),k=join$1(y,"__init__.py"),R=false;try{R=statSync$1(k).isFile();}catch{}if(R){a(k),u(y,p[3]);continue}for(let v of l(p[3]))c(v,m);}return {references:[...new Map(r.map(d=>[d.path,d])).values()],inlineContents:[],malformed:s}}function Kr(e,t,n,o,r=true){return n==="node"?Gc(e,t,o,r):n==="python"?Zc(e,t,o):{references:[],inlineContents:[],malformed:false}}function _r(e,t,n,o=t){let r={project:t,homePath:n,cwd:o},s=At(e,0,r),i=new Set((s.artifacts??[]).map(g=>g.value)),a=s.tokens.filter(g=>!i.has(g)).map(g=>me(g,r)).filter(g=>g!==null),c=[],l=[...s.inlineContents??[]],u=s.malformed;for(let g of s.artifacts??[]){if(g.nodeResolutionKind){let p=Hn(g);p.reference&&c.push(p.reference),p.inlineContent&&l.push(p.inlineContent),u||=p.malformed;continue}let f=me(g.value,{...r,cwd:g.cwd},true,g.parserKind);f?c.push(f):u=true;}let d=[...a,...c];return {references:[...new Map(d.map(g=>[`${g.path}:${g.parserKind}`,g])).values()],inlineContents:l,malformed:u}}function zr(e){return /^[A-Za-z_][A-Za-z0-9_]*=/.test(e)}function Oe(e){return /[*?\[]/.test(e)?true:e.includes("$")?!/^(?:\$(?:CLAUDE_PLUGIN_ROOT|CLAUDE_PROJECT_DIR|HOME|PLUGIN_ROOT)|\$\{(?:CLAUDE_PLUGIN_ROOT|CLAUDE_PROJECT_DIR|HOME|PLUGIN_ROOT)\})(?:\/[A-Za-z0-9._/-]*)?$/.test(e):false}function Dt(e){return /\b(?:import|require)\s*\(/.test(e)||/\bimport\s+(?:[^;\n]*\s+from\s+)?["']/.test(e)||/\b(?:eval|Function)\s*\(/.test(e)}function it(e,t){for(let n of t)if(e.startsWith(`${n}=`))return e.slice(n.length+1);return null}function nl(e,t,n){let o=[],r=[],s=false,i=(u,d)=>{o.push(u),r.push({value:u,cwd:n.cwd,project:n.project,homePath:n.homePath,parserKind:"node",nodeResolutionKind:d}),s||=Oe(u);},a=(u=s)=>({tokens:o,artifacts:r,malformed:u}),c=t,l=false;for(;c<e.length;){let u=e[c];if(u==="--"){let h=e[c+1];return h&&!l&&i(h),h?a():a(true)}if(!u.startsWith("-"))return l||i(u),a();if(tl.has(u))return a();if(el.has(u)){l=true,c+=1;continue}let d=Pr.has(u)?"cjs":Er.has(u)?"esm":null;if(d){let h=e[c+1];if(!h)return a(true);i(h,d),c+=2;continue}let g=it(u,Pr),f=it(u,Er),p=g??f;if(p!==null){if(!p)return a(true);i(p,g!==null?"cjs":"esm"),c+=1;continue}if(u.startsWith("-r")&&u.length>2){i(u.slice(2),"cjs"),c+=1;continue}if(Cr.has(u)){let h=e[c+1];return a(h===void 0?true:s||Dt(h))}let m=it(u,Cr);if(m!==null)return a(s||Dt(m));if((u.startsWith("-e")||u.startsWith("-p"))&&u.length>2)return a(s||Dt(u.slice(2)));if(Rr.has(u)){if(e[c+1]===void 0)return a(true);c+=2;continue}if(it(u,Rr)!==null){c+=1;continue}if(Xc.has(u)){c+=1;continue}return a(true)}return l?a():a(true)}function il(e,t,n,o,r){let s=t;for(;s<e.length;){let i=e[s];if(i==="--"){let a=e[s+1];return a?{tokens:[a],artifacts:[{value:a,cwd:o.cwd,project:o.project,homePath:o.homePath,parserKind:"shell"}],malformed:Oe(a)}:{tokens:[],malformed:true}}if(i==="-c"||i==="-lc"){let a=e[s+1];return a?At(a,n+1,o,r):{tokens:[],malformed:true}}if(i==="-o"){if(!e[s+1])return {tokens:[],malformed:true};s+=2;continue}if(ol.has(i)){s+=1;continue}return i.startsWith("-")||i.startsWith("+")?{tokens:[],malformed:true}:{tokens:[i],artifacts:[{value:i,cwd:o.cwd,project:o.project,homePath:o.homePath,parserKind:"shell"}],malformed:Oe(i)}}return {tokens:[],malformed:true}}function al(e,t,n){let o=t;for(;o<e.length;){let r=e[o];if(r==="--"){let s=e[o+1];return s?{tokens:[s],artifacts:[{value:s,cwd:n.cwd,project:n.project,homePath:n.homePath,parserKind:"python"}],malformed:Oe(s)}:{tokens:[],malformed:true}}if(!r.startsWith("-"))return {tokens:[r],artifacts:[{value:r,cwd:n.cwd,project:n.project,homePath:n.homePath,parserKind:"python"}],malformed:Oe(r)};if(sl.has(r))return {tokens:[],malformed:false};if(r==="-c"||r==="-m"||r.startsWith("-c"))return {tokens:[],malformed:true};if(Dr.has(r)){if(e[o+1]===void 0)return {tokens:[],malformed:true};o+=2;continue}if(it(r,Dr)!==null){o+=1;continue}if(rl.has(r)){o+=1;continue}return {tokens:[],malformed:true}}return {tokens:[],malformed:true}}function Dn(e,t){let n=me(e,t,true);if(!n)return null;let o=_e(n.path),r=_e(t.project);return !o||!r||!Se(r,o)?null:o}function ul(e,t,n,o,r){let s=n;if(e==="builtin"){for(;t[s]?.startsWith("-");)s+=1;return {index:s,malformed:s>=t.length}}if(e==="command"){for(;t[s]?.startsWith("-");){let i=t[s];if(/^-[pvV]+$/.test(i)&&/[vV]/.test(i))return {index:t.length,malformed:false};s+=1;}return {index:s,malformed:s>=t.length}}if(e==="exec"){for(;t[s]?.startsWith("-");)t[s]==="-a"||t[s]==="--argv0"?s+=2:s+=1;return {index:s,malformed:s>=t.length}}if(e==="nohup"){for(;t[s]?.startsWith("-");)s+=1;return {index:s,malformed:s>=t.length}}if(e==="env"){let i=o;for(;s<t.length;){let a=t[s];if(zr(a))s+=1;else if(a==="-S"||a==="--split-string"){let c=t[s+1];if(!c)return {index:s,malformed:true};let l=dt(c,r);return l.malformed||l.segments.length!==1?{index:s,malformed:true}:{index:s,malformed:false,replacement:[...l.segments[0],...t.slice(s+2)],context:i}}else if(["-C","--chdir"].includes(a)){let c=t[s+1],l=c?Dn(c,i):null;if(!l)return {index:s,malformed:true};i={...i,cwd:l},s+=2;}else if(a.startsWith("--chdir=")){let c=Dn(a.slice(8),i);if(!c)return {index:s,malformed:true};i={...i,cwd:c},s+=1;}else if(a.startsWith("-C")&&a.length>2){let c=Dn(a.slice(2),i);if(!c)return {index:s,malformed:true};i={...i,cwd:c},s+=1;}else if(["-u","--unset"].includes(a)){if(!t[s+1])return {index:s,malformed:true};s+=2;}else if(a.startsWith("--unset=")||a.startsWith("-u")&&a.length>2)s+=1;else if(["--","-i","--ignore-environment","--null"].includes(a))s+=1;else {if(a.startsWith("-"))return {index:s,malformed:true};break}}return {index:s,malformed:s>=t.length,context:i}}for(;t[s]?.startsWith("-");){let i=t[s];["-k","--kill-after","-s","--signal"].includes(i)?s+=2:s+=1;}return s>=t.length?{index:s,malformed:true}:(s+=1,{index:s,malformed:s>=t.length})}function At(e,t=0,n={project:process.cwd(),homePath:homedir$1(),cwd:process.cwd()},o={}){if(t>Ur)return {tokens:[],malformed:true};let r=dt(e,o),s=[],i=[],a=[],c=r.malformed;for(let l of r.segments){let u=Jr(l,t,n,o);s.push(...u.tokens),i.push(...u.artifacts??[]),a.push(...u.inlineContents??[]),c||=u.malformed;}return {tokens:s,artifacts:i,inlineContents:a,malformed:c}}function Jr(e,t,n,o){let r=0;for(;zr(e[r]??"");)r+=1;let s=e[r];if(!s)return {tokens:[],malformed:false};let i=[],a=t,c=false;for(;cl.has(basename(s));){if(c||=basename(s)==="builtin",i.push(s),a+=1,a>Ur)return {tokens:i,malformed:true};let m=ul(basename(s),e,r+1,n,o);if(m.malformed)return {tokens:i,malformed:true};if(n=m.context??n,m.replacement){let h=Jr(m.replacement,a,m.context??n,o);return i.push(...h.tokens),{tokens:i,artifacts:h.artifacts,inlineContents:h.inlineContents,malformed:h.malformed}}if(r=m.index,s=e[r],!s)return {tokens:i,malformed:false}}let l=basename(s),u=!s.includes(sep)&&Br(l,o),d=c&&!ll.has(l);if(u||d)return {tokens:i,malformed:true};let g=Oe(s);i.push(s);let f=l;if(!Qc.has(f))return {tokens:i,malformed:g};let p=["node","tsx"].includes(f)?nl(e,r+1,n):["bash","sh","zsh"].includes(f)?il(e,r+1,a,n,o):al(e,r+1,n);return i.push(...p.tokens),{tokens:i,artifacts:p.artifacts,inlineContents:p.inlineContents,malformed:g||p.malformed}}function Vr(e){if(!isAbsolute(e))return null;let t=resolve(e),n=`${sep}hooks${sep}`,o=t.lastIndexOf(n);return o<0?null:_e(t.slice(0,o))}function dl(e,t){let n=new Map;for(let o of t)for(let r of qc(o)){let s=Vr(r);if(!s)continue;let i=n.get(s)??[];i.push(o),n.set(s,i);}return [...n].map(([o,r])=>({root:o,configPath:e,commands:[...new Set(r)]}))}function gl(e){return e==="devflow@devflow"||e==="devflow@devflow-local"||e.startsWith("@devflow-tools/claude-code-plugin@")}function fl(e){return e.slice(e.lastIndexOf("@")+1)}function $r(e){for(let t of [e,join$1(e,"claude-code"),join$1(e,"plugins","claude-code")]){let n=_e(t);if(n&&(existsSync$1(join$1(n,"hooks","hooks.json"))||existsSync$1(join$1(n,"hooks.json"))))return n}return null}function ml(e,t,n){let o=fl(e),r=U(t.extraKnownMarketplaces),s=U(r?.[o]);if(s){let i=U(s.source);return {configured:true,root:i?.source==="directory"&&typeof i.path=="string"?$r(i.path):null}}try{let i=U(Ne(n)),a=U(i?.[o]);if(a){let c=U(a.source);return {configured:!0,root:c?.source==="directory"&&typeof c.path=="string"?$r(c.path):null}}}catch{}return {configured:false,root:null}}function Ar(e){let t=[e?.lastUpdated,e?.installedAt].map(n=>{if(typeof n=="number"&&Number.isFinite(n)&&n>=0)return n;if(typeof n!="string")return null;let o=Date.parse(n);return Number.isFinite(o)?o:null}).filter(n=>n!==null);return t.length>0?Math.max(...t):null}function pl(e,t){let n=U(e.entry),o=U(t.entry),r=Ar(n),s=Ar(o);if(r!==s)return r===null?1:s===null?-1:s-r;let i=typeof n?.version=="string"?xt(n.version):null,a=typeof o?.version=="string"?xt(o.version):null;if(i&&a){let c=Gr(a,i);if(c!==0)return c}else if(i||a)return i?-1:1;return t.index-e.index}function hl(e,t){try{let n=U(Ne(t));if(!n)throw new Error("installed plugin manifest must be an object");let o=U(n.plugins);if(!o)throw new Error("installed plugin manifest plugins must be an object");let r=o?.[e];if(r===void 0)return {configured:!1,root:null};if(!Array.isArray(r)||r.length===0)return {configured:!0,malformed:!0,root:null};let s=r.map((a,c)=>({entry:a,index:c})).sort(pl)[0],i=U(s?.entry);return !i||typeof i.installPath!="string"||i.installPath.length===0?{configured:!0,malformed:!0,root:null}:{configured:!0,root:_e(i.installPath)}}catch{if(existsSync$1(t))return {configured:true,malformed:true,root:null}}return {configured:false,root:null}}function xt(e){let t=e.match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/);return t?{major:Number(t[1]),minor:Number(t[2]),patch:Number(t[3]),prerelease:t[4]?.split(".")??[]}:null}function Gr(e,t){for(let o of ["major","minor","patch"])if(e[o]!==t[o])return e[o]-t[o];if(e.prerelease.length===0||t.prerelease.length===0)return t.prerelease.length-e.prerelease.length;let n=Math.max(e.prerelease.length,t.prerelease.length);for(let o=0;o<n;o+=1){let r=e.prerelease[o],s=t.prerelease[o];if(r===void 0)return -1;if(s===void 0)return 1;if(r===s)continue;let i=/^\d+$/.test(r)?Number(r):null,a=/^\d+$/.test(s)?Number(s):null;return i!==null&&a!==null?i-a:i!==null?-1:a!==null?1:r.localeCompare(s)}return 0}function yl(e,t){let n=e.lastIndexOf("@");if(n<=0||n===e.length-1)return null;let o=e.slice(0,n),r=e.slice(n+1),s=join$1(t,r,o),i;try{i=readdirSync(s,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>{let c=join$1(s,a.name),l=a.name;try{let u=U(Ne(join$1(c,"package.json")));typeof u?.version=="string"&&(l=u.version);}catch{}return {name:a.name,path:c,version:l,mtimeMs:statSync$1(c).mtimeMs}});}catch{return null}return i.sort((a,c)=>{let l=xt(a.version),u=xt(c.version);if(l&&u){let d=Gr(u,l);if(d!==0)return d}else if(l||u)return l?-1:1;return c.mtimeMs-a.mtimeMs||c.name.localeCompare(a.name)}),i[0]?_e(i[0].path):null}function vl(e,t){if(t.legacyArtifactRoots!==void 0){let v=t.legacyArtifactRoots.map(b=>_e(b)).filter(b=>b!==null).map(b=>({root:b,inspectPluginConfig:true}));return {targets:v,configCommands:[],hooksDisabled:false,malformedSettings:[],malformedPluginMetadata:[],method:"injected",ok:v.length>0}}let n=t.claudeSettingsPath??join$1(t.homePath??homedir$1(),".claude","settings.json"),o=t.installedPluginsPath??join$1(t.homePath??homedir$1(),".claude","plugins","installed_plugins.json"),r=t.knownMarketplacesPath??join$1(t.homePath??homedir$1(),".claude","plugins","known_marketplaces.json"),s=t.pluginCachePath??join$1(t.homePath??homedir$1(),".claude","plugins","cache"),i=[],a=[],c=[],l=[...new Set([n,join$1(e,".claude","settings.json"),join$1(e,".claude","settings.local.json")])];for(let v of l)if(existsSync$1(v))try{let b=U(Ne(v));if(!b)throw new Error("settings must be an object");i.push({path:v,settings:b});}catch{a.push(v);}if(i.reduce((v,b)=>typeof b.settings.disableAllHooks=="boolean"?b.settings.disableAllHooks:v,false))return {targets:[],configCommands:[],hooksDisabled:true,malformedSettings:a,malformedPluginMetadata:[],method:"hooks-disabled",ok:a.length===0};let d=i.map(v=>{let b=[];return lt(v.settings.hooks,b),{path:v.path,commands:b}}),g=d.flatMap(v=>v.commands),f=d.flatMap(v=>dl(v.path,v.commands)),m=[...i.reduce((v,b)=>{let _=b.settings.enabledPlugins;if(typeof _!="object"||_===null)return v;for(let[j,Y]of Object.entries(_))gl(j)&&typeof Y=="boolean"&&v.set(j,Y);return v},new Map)].filter(([,v])=>v).map(([v])=>v).sort(),h=[...f],y=false;for(let v of m){let b=hl(v,o);b.malformed&&c.push(o);let _=b.root;if(!b.configured){let j=i.map(oe=>ml(v,oe.settings,r)).filter(oe=>oe.configured),Y=j[j.length-1];Y?_=Y.root:_=yl(v,s);}_?h.push({root:_,inspectPluginConfig:true}):y=true;}let k=[...h.reduce((v,b)=>{let _=v.get(b.root);return _?(v.set(b.root,{root:b.root,configPath:_.configPath??b.configPath,commands:[...new Set([..._.commands??[],...b.commands??[]])],inspectPluginConfig:!!(_.inspectPluginConfig||b.inspectPluginConfig)}),v):(v.set(b.root,b),v)},new Map).values()],R=[g.length>0?"settings-hooks":null,m.length>0?"enabled-plugin":null].filter(v=>v!==null);return {targets:k,configCommands:d.filter(v=>v.commands.length>0),hooksDisabled:false,method:R.length>0?`${R.join("+")}${y?"-unresolved":""}`:a.length>0?"settings-unresolved":"enabled-plugin-unresolved",malformedSettings:a,malformedPluginMetadata:[...new Set(c)],ok:(k.length>0||g.length>0)&&!y&&a.length===0&&c.length===0}}function kl(e){let t=e;for(;;){let n=join$1(t,"package.json");if(existsSync$1(n))try{if(JSON.parse(readFileSync$1(n,"utf8")).workspaces)return t}catch{}let o=dirname(t);if(o===t)return;t=o;}}function lt(e,t){if(Array.isArray(e)){for(let n of e)lt(n,t);return}if(!(typeof e!="object"||e===null))for(let[n,o]of Object.entries(e))n==="command"&&typeof o=="string"?t.push(o):lt(o,t);}function $n(e){return [...e.matchAll(Ic)].map(t=>t[1])}function wl(e){let t=new Map,n=dt(e,{tolerateControlSyntax:true});for(let o of n.segments.flat()){let r=o.match(/^([A-Za-z_][A-Za-z0-9_]*)=(\$(?:\{(?:CLAUDE_)?PLUGIN_ROOT\}|(?:CLAUDE_)?PLUGIN_ROOT)\/[A-Za-z0-9._/-]+)$/);r&&t.set(r[1],r[2]);}return t.size===0?e:e.replace(/\$(?:\{([A-Za-z_][A-Za-z0-9_]*)\}|([A-Za-z_][A-Za-z0-9_]*))/g,(o,r,s)=>t.get(r??s??"")??o)}function bl(e){let t=spawnSync("bash",["--noprofile","--norc","-n"],{encoding:"utf8",env:{PATH:process.env.PATH??"",HOME:process.env.HOME??"",BASH_ENV:"",ENV:""},input:e,timeout:2e3});return t.error!==void 0||t.status!==0}function Sl(e){if(![".cjs",".js",".mjs"].includes(extname(e)))return false;let t=spawnSync(process.execPath,["--check",e],{encoding:"utf8",env:{PATH:process.env.PATH??"",HOME:process.env.HOME??""},timeout:2e3});return t.error!==void 0||t.status!==0}function An(e,t){let n=resolve(e,t);return n.startsWith(`${resolve(e)}${sep}`)?n:null}function Se(e,t){return t===e||t.startsWith(`${e}${sep}`)}function jn(e){let t;try{t=lstatSync(e);}catch{return {kind:"missing"}}if(!t.isFile())return {kind:"unsafe",reason:"nonregular"};if(t.size>Rt)return {kind:"unsafe",reason:"oversized"};let n;try{n=openSync(e,constants.O_RDONLY|constants.O_NONBLOCK|constants.O_NOFOLLOW);}catch{return {kind:"missing"}}try{let o=fstatSync(n);if(!o.isFile())return {kind:"unsafe",reason:"nonregular"};if(o.size>Rt)return {kind:"unsafe",reason:"oversized"};let r=Buffer.alloc(Math.min(o.size+1,Rt+1)),s=0;for(;s<r.length;){let c=readSync(n,r,s,r.length-s,null);if(c===0)break;s+=c;}if(s>Rt)return {kind:"unsafe",reason:"oversized"};let i=r.subarray(0,s);if(i.includes(0))return {kind:"unsafe",reason:"binary"};let a=i.toString("utf8");return a.includes("\uFFFD")?{kind:"unsafe",reason:"binary"}:{kind:"text",content:a}}catch{return {kind:"missing"}}finally{closeSync(n);}}function In(e,t){return `${e} (${t})`}function _l(e,t,n,o){let r=[],s=new Set,i=0,a=(c,l=0)=>{if(l>Fn){o.traversalLimitRoots.push(e);return}let u=resolve(c.path),d=resolve(c.containmentRoot),g;try{g=realpathSync.native(d);}catch{g=d;}if(!existsSync$1(u)){Se(d,u)?o.missing.push(u):o.escapedArtifacts.push(u);return}let f;try{f=realpathSync.native(u);}catch{o.missing.push(u);return}if(!Se(g,f)){o.escapedArtifacts.push(u);return}let p=`${f}:${c.parserKind}:${c.cwd}`;s.has(p)||(s.add(p),r.push({...c,path:f,depth:l}));};for(let c of n){let l=_r(c,e,t);l.malformed&&o.malformedCommands.push(c);for(let u of l.inlineContents)for(let d of fe(u.content,false,"node"))o.findings.push({artifact:u.source,endpoint:d});for(let u of l.references)a(u);}for(;r.length>0;){if(i>=Hr){o.traversalLimitRoots.push(e);break}let c=r.shift(),l=c.path;i+=1;let u=jn(l);if(u.kind==="missing"){o.missing.push(l);continue}if(u.kind==="unsafe"){u.reason!=="binary"&&o.unsafeArtifacts.push(In(l,u.reason));continue}let{content:d}=u;o.inspected.push(l);let g=c.parserKind==="infer"?qr(l,d):c.parserKind,f=g==="shell";for(let p of fe(d,f,g))o.findings.push({artifact:l,endpoint:p});if(f){let p=_r(d,e,t,c.cwd);p.malformed&&o.malformedCommands.push(l);for(let m of p.inlineContents)for(let h of fe(m.content,false,"node"))o.findings.push({artifact:m.source,endpoint:h});for(let m of p.references)a(m,c.depth+1);}else if(g==="node"||g==="python"){let p=Kr(l,d,g,{project:e,homePath:t,cwd:dirname(l)});p.malformed&&o.malformedCommands.push(l);for(let m of p.inlineContents)for(let h of fe(m.content,false,"node"))o.findings.push({artifact:m.source,endpoint:h});for(let m of p.references)a(m,c.depth+1);}}}function Pl(e,t,n,o){let r=realpathSync.native(n.root),s=[],i=new Set,a=kl(r),c=0,l=(f,p=false,m=r,h="infer",y=e,k=0)=>{if(k>Fn){o.traversalLimitRoots.push(r);return}let R=realpathSync.native(m),v=resolve(f);if(!existsSync$1(v)){if(!Se(R,v)){o.escapedArtifacts.push(v);return}p&&o.missing.push(v);return}let b;try{b=realpathSync.native(v);}catch{p&&o.missing.push(v);return}if(!Se(R,b)){o.escapedArtifacts.push(v);return}let _=`${b}:${h}:${y}`;i.has(_)||(i.add(_),s.push({path:b,parserKind:h,cwd:y,depth:k}));},u=(f,p,m,h=0)=>{for(let y of $n(f)){let k=An(r,y);if(!k)continue;let R=(p.artifacts??[]).find(v=>v.value.includes("PLUGIN_ROOT")&&v.value.endsWith(y));l(k,true,r,R?.parserKind??"infer",R?.cwd??m,h);}},d=(f,p,m=0,h=false)=>{for(let y of f.artifacts??[]){if(y.value.includes("PLUGIN_ROOT"))continue;let k=y.nodeResolutionKind?Hn(y,!h):{reference:me(y.value,{project:y.project,homePath:y.homePath,cwd:y.cwd},true,y.parserKind)??void 0,malformed:false};if(k.malformed){o.malformedCommands.push(y.value);continue}if(k.inlineContent)for(let R of fe(k.inlineContent.content,false,"node"))o.findings.push({artifact:k.inlineContent.source,endpoint:R});k.reference&&l(k.reference.path,true,h?r:k.reference.containmentRoot,k.reference.parserKind,k.reference.cwd??p,m);}},g=f=>{for(let m of fe(f,true))o.findings.push({artifact:n.configPath??join$1(r,"hooks.json"),endpoint:m});let p=At(f,0,{project:e,homePath:t,cwd:e});p.malformed&&o.malformedCommands.push(f),u(f,p,e),d(p,e);for(let m of p.tokens){if(!isAbsolute(m))continue;let h=Vr(m),y=(p.artifacts??[]).find(k=>k.value===m);h===r&&l(m,true,r,y?.parserKind??"infer",y?.cwd??e);}};if(n.commands){n.configPath&&o.configsInspected.push(n.configPath);for(let f of n.commands)g(f);}if(n.inspectPluginConfig||!n.commands){let f=join$1(r,"hooks","hooks.json"),p=join$1(r,"hooks.json"),m=existsSync$1(p)?p:f;if(!existsSync$1(m))o.missing.push(m),l(join$1(r,"hooks","session-start"));else {o.configsInspected.push(m);let h;try{h=realpathSync.native(m);}catch{o.missing.push(m),l(join$1(r,"hooks","session-start")),h="";}if(h&&!Se(r,h)&&(o.escapedArtifacts.push(m),l(join$1(r,"hooks","session-start")),h=""),h){let y=jn(h);if(y.kind==="unsafe")o.unsafeArtifacts.push(In(m,y.reason)),l(join$1(r,"hooks","session-start"));else if(y.kind==="missing")o.missing.push(m),l(join$1(r,"hooks","session-start"));else try{let k=JSON.parse(y.content),R=[];lt(k,R);for(let v of R)g(v);}catch{o.malformedConfigs.push(m),l(join$1(r,"hooks","session-start"));}}}}for(;s.length>0;){if(c>=Hr){o.traversalLimitRoots.push(r);break}let f=s.shift(),p=f.path;c+=1;let m=jn(p);if(m.kind==="missing"){o.missing.push(p);continue}if(m.kind==="unsafe"){o.unsafeArtifacts.push(In(p,m.reason));continue}let{content:h}=m;o.inspected.push(p);let y=f.parserKind==="infer"?qr(p,h):f.parserKind,k=y==="shell";for(let b of fe(h,k,y))o.findings.push({artifact:p,endpoint:b});if(k){let b=wl(h),_=At(b,0,{project:e,homePath:t,cwd:dirname(p)},{tolerateControlSyntax:true});bl(h)&&o.malformedCommands.push(p),u(b,_,dirname(p),f.depth+1),d(_,dirname(p),f.depth+1,true);}else if(y==="node"||y==="python"){let b=Kr(p,h,y,{project:e,homePath:t,cwd:dirname(p)},false);(y==="node"?Sl(p):b.malformed)&&o.malformedCommands.push(p);for(let _ of b.inlineContents)for(let j of fe(_.content,false,"node"))o.findings.push({artifact:_.source,endpoint:j});for(let _ of b.references){let j=relative(r,resolve(_.path));!j.startsWith(`..${sep}`)&&j.split(sep).includes("node_modules")||l(_.path,true,r,_.parserKind,_.cwd,f.depth+1);}for(let _ of $n(h)){let j=An(r,_);j&&l(j,true,r,y,f.cwd,f.depth+1);}}else for(let b of $n(h)){let _=An(r,b);_&&l(_,true,r,y,f.cwd,f.depth+1);}let R=p.startsWith(`${r}/`)?p.slice(r.length+1):"",v=basename(R).replace(/\.js$/,"");a&&(R.startsWith("hooks/")||R.startsWith("dist/hooks/"))&&l(join$1(a,"packages","devflow","src","hooks",`${v}.ts`),false,a),R.startsWith("hooks/")&&l(join$1(r,"dist","hooks",`${v}.js`));}}function El(e){let t=e.installedPluginsPath??join$1(e.homePath??homedir$1(),".claude","plugins","installed_plugins.json"),n=new Map;if(!existsSync$1(t))return new Map;try{let o=U(Ne(t)),r=U(o?.plugins);if(!r)return new Map;for(let s of Object.values(r))if(Array.isArray(s))for(let i of s){let a=U(i);if(typeof a?.installPath!="string"||typeof a.version!="string")continue;let c=_e(a.installPath);if(!c)continue;let l=n.get(c)??new Set;l.add(a.version),n.set(c,l);}}catch{return new Map}return new Map([...n].map(([o,r])=>[o,[...r].sort()]))}function xr(e){try{let t=U(Ne(e));return typeof t?.version=="string"?t.version:void 0}catch{return}}function Cl(e,t){let n={layoutIssues:[],versionIssues:[],versionRecords:[],sessionStartIssues:[],daemonIssues:[]},o=El(t);for(let r of e){let s=r.root,i=join$1(s,"package.json"),a=join$1(s,".claude-plugin","plugin.json");if(!(existsSync$1(i)||existsSync$1(a)))continue;let l=join$1(s,"hooks","hooks.json"),u=join$1(s,"hooks.json");existsSync$1(l)||n.layoutIssues.push({root:s,issue:"missing hooks/hooks.json"}),existsSync$1(u)&&n.layoutIssues.push({root:s,issue:"retired root hooks.json is present"});let d=existsSync$1(l)?l:u;try{let k=U(Ne(d)),R=U(k?.hooks),v=[];lt(R?.SessionStart,v),v.some(b=>/(?:^|[/\\])session-start(?:\s|$|["'])/.test(b))||n.sessionStartIssues.push({root:s,issue:"SessionStart wrapper is not registered"});}catch{n.sessionStartIssues.push({root:s,issue:"hook configuration is unreadable"});}let g=xr(i),f=xr(a),p=o.get(s)??[],m={root:s,packageVersion:g,manifestVersion:f,registryVersions:p};n.versionRecords.push(m),(!g||!f||g!==f||p.some(k=>k!==g))&&n.versionIssues.push(m);let h=join$1(s,"hooks","session-start"),y=join$1(s,"dist","hooks","hook-daemon.js");try{let k=readFileSync$1(h,"utf8");(!existsSync$1(y)||!k.includes("hook-daemon.js"))&&n.daemonIssues.push({root:s,issue:"SessionStart does not register the packaged hook daemon"});}catch{n.daemonIssues.push({root:s,issue:"SessionStart wrapper or hook daemon is missing"});}}return n}function Rl(e,t){let n=vl(e,t),o={configsInspected:[],commandsInspected:[],inspected:[],missing:[],malformedConfigs:[],malformedCommands:[],unsafeArtifacts:[],traversalLimitRoots:[],escapedArtifacts:[],findings:[]};for(let D of n.configCommands){o.configsInspected.push(D.path);for(let F of D.commands){o.commandsInspected.push({configPath:D.path,command:F});for(let X of fe(F,true))o.findings.push({artifact:D.path,endpoint:X});}}_l(e,t.homePath??homedir$1(),n.configCommands.flatMap(D=>D.commands).filter(D=>!n.targets.some(F=>F.commands?.includes(D))),o);for(let D of n.targets)Pl(e,t.homePath??homedir$1(),D,o);let r=[...new Set(o.configsInspected)],s=[...new Set(o.inspected)],i=o.commandsInspected.filter((D,F,X)=>X.findIndex(A=>A.configPath===D.configPath&&A.command===D.command)===F),a=[...new Set(o.missing)],c=[...new Set(o.malformedConfigs)],l=[...new Set(o.malformedCommands)],u=[...new Set(o.unsafeArtifacts)],d=[...new Set(o.traversalLimitRoots)],g=[...new Set(o.escapedArtifacts)],f=o.findings.filter((D,F,X)=>X.findIndex(A=>A.artifact===D.artifact&&A.endpoint===D.endpoint)===F),p=a.length>0||g.length>0||u.length>0,m=p&&!n.method.endsWith("-unresolved")?`${n.method}-unresolved`:n.method,h=Cl(n.targets,t),y=t.claudeSettingsPath?dirname(t.claudeSettingsPath):null,k=t.homePath??(y&&basename(y)===".claude"?dirname(y):y)??homedir$1(),R=n.targets.map(D=>D.root).find(D=>existsSync$1(join$1(D,"skills")))??null,v=t.activePluginRoot?{root:existsSync$1(t.activePluginRoot)?t.activePluginRoot:null,version:null}:R?{root:R,version:null}:Ee(k,{installedPluginsPath:t.installedPluginsPath,pluginCachePath:t.pluginCachePath}),b=v.root,_=b?Ve(k,b):[],j=_.filter(D=>!D.isKnownDevFlowArtifact).map(D=>({skillName:D.skillName,path:D.globalPath,action:"inspect manually; file is modified or not a known DevFlow artifact"})),Y=[{key:"active_plugin_resolution",value:m,target:"resolved active DevFlow hook configuration",ok:n.ok&&!p,severity:"warning"},{key:"active_plugin_roots",value:n.targets.map(D=>D.root),ok:true,severity:"info"},{key:"hooks_disabled",value:n.hooksDisabled,ok:true,severity:"info"},{key:"plugin_hook_layout",value:h.layoutIssues,target:"hooks/hooks.json present and root hooks.json absent",ok:h.layoutIssues.length===0,severity:"error"},{key:"plugin_version_parity",value:h.versionRecords,target:"manifest, package, and installed registry versions match",ok:h.versionIssues.length===0,severity:"error"},{key:"session_start_hook_registration",value:h.sessionStartIssues,target:[],ok:h.sessionStartIssues.length===0,severity:"error"},{key:"hook_daemon_artifact_registration",value:h.daemonIssues,target:[],ok:h.daemonIssues.length===0,severity:"error"},{key:"malformed_active_settings",value:n.malformedSettings,target:[],ok:n.malformedSettings.length===0,severity:"warning"},{key:"malformed_plugin_metadata",value:n.malformedPluginMetadata,target:[],ok:n.malformedPluginMetadata.length===0,severity:"warning"},{key:"hook_configs_inspected",value:r.length,target:n.hooksDisabled?"hooks disabled":">= 1 hook config file",ok:n.hooksDisabled||r.length>0,severity:"warning"},{key:"legacy_artifacts_inspected",value:s.length+i.length,target:n.hooksDisabled?"hooks disabled":">= 1 active hook artifact",ok:n.hooksDisabled||s.length+i.length>0,severity:"warning"},{key:"missing_legacy_artifacts",value:a,target:[],ok:a.length===0,severity:"warning"},{key:"malformed_hook_configs",value:c,target:[],ok:c.length===0,severity:"warning"},{key:"malformed_hook_commands",value:l,target:[],ok:l.length===0,severity:"warning"},{key:"unsafe_legacy_artifacts",value:u,target:[],ok:u.length===0,severity:"warning"},{key:"legacy_artifact_traversal_limit",value:d,target:[],ok:d.length===0,severity:"warning"},{key:"escaped_legacy_artifacts",value:g.length,target:0,ok:g.length===0,severity:"warning"},{key:"retired_producer_paths",value:f.length,target:0,ok:f.length===0,severity:"error"},{key:"retired_producer_path_findings",value:f,ok:true,severity:"info"},{key:"skill_shadowing_count",value:_.length,target:0,ok:_.length===0,severity:"error"},{key:"shadowed_skills",value:_,target:[],ok:_.length===0,severity:"error"},{key:"active_skill_source",value:b,target:"existing plugin cache path",ok:true,severity:"info"},{key:"skill_shadowing_remediation",value:j,target:[],ok:true,severity:"info"}],oe=v.version??h.versionRecords.find(D=>D.root===b)?.packageVersion;return oe&&Y.push({key:"active_plugin_version",value:oe,ok:true,severity:"info"}),{name:"Legacy paths",status:T(Y),metrics:Y}}function Dl(e){let t=dirname(fileURLToPath(import.meta.url)),n=[...new Set([e.acceptanceManifestPath,e.env?.DEVFLOW_ACCEPTANCE_MANIFEST,process.env.DEVFLOW_ACCEPTANCE_MANIFEST,join$1(t,"..","acceptance-manifest.json"),join$1(t,"..","..","..","..","packages","devflow","acceptance-manifest.json"),join$1(process.cwd(),"packages","devflow","acceptance-manifest.json")].filter(o=>!!o))];for(let o of n)if(existsSync$1(o))try{return {path:o,manifest:JSON.parse(readFileSync$1(o,"utf8"))}}catch(r){return {path:o,error:r.message}}return {error:`not found (${n.join(", ")})`}}function Tt(e){let t=Dl(e);if(!t.manifest)return {metrics:[{key:"batch4_acceptance_manifest",value:t.error??"missing",target:"readable acceptance-manifest.json",ok:false,severity:"warning"}]};let n=Date.parse(t.manifest.verifiedAt),o=Number.isFinite(n)?((e.now??Date.now)()-n)/Ke:Number.POSITIVE_INFINITY;return {manifest:t.manifest,metrics:[{key:"batch4_acceptance_manifest",value:t.path,target:"schemaVersion 1",ok:t.manifest.schemaVersion===1,severity:"error"},{key:"acceptance_evidence_age_days",value:Number.isFinite(o)?Number(o.toFixed(2)):"invalid timestamp",target:"0-30",ok:o>=0&&o<=30,severity:"warning"}]}}function $l(e,t){let n=[],o=join$1(e,".devflow","config.json"),r="default-enabled";if(existsSync$1(o))try{r=JSON.parse(readFileSync$1(o,"utf8")).sessionStart?.injectMemories??"default-enabled";}catch(a){n.push({key:"session_start_config",value:a.message,target:"valid .devflow/config.json",ok:false,severity:"error"});}let s=r!==false;n.push({key:"session_start_memory_injection",value:r,target:"enabled or configured budget",ok:s,severity:"warning"});let i=join$1(e,".devflow","memory","memories.db");if(!existsSync$1(i))n.push({key:"explicit_memory_channel",value:"memory database missing",target:"observations.source supports explicit_intent",ok:false,severity:"warning"});else {let a;try{a=ie(i,t);let l=(W(a,"observations")?a.prepare("PRAGMA table_info(observations)").all().map(u=>u.name):[]).includes("source");n.push({key:"explicit_memory_channel",value:l?"explicit_intent source available":"source column missing",target:"explicit_intent source available",ok:l,severity:"warning"}),l&&n.push({key:"explicit_memory_observations",value:B(a,"SELECT COUNT(*) count FROM observations WHERE source = 'explicit_intent'"),ok:!0,severity:"info"});}catch(c){n.push({key:"explicit_memory_channel_read",value:c.message,target:"readable memory database",ok:false,severity:"error"});}finally{a?.close();}}return {name:"Injection",status:T(n),metrics:n}}function Al(e,t){let n=[],o=join$1(e,".devflow","memory","memories.db");if(!existsSync$1(o))return n.push({key:"memories_db",value:"missing",target:o,ok:false,severity:"warning"}),{name:"Memory quality",status:T(n),metrics:n};let r;try{if(r=ie(o,t),!W(r,"memories"))n.push({key:"memories_schema",value:"memories table missing",target:"Batch 3 memory schema",ok:!1,severity:"warning"});else {let s=(t.now??Date.now)()-7*Ke,i=r.prepare(`
|
|
164
166
|
SELECT source, COUNT(*) count FROM memories
|
|
165
167
|
WHERE created_at >= ? GROUP BY source ORDER BY source
|
|
166
168
|
`).all(s),a=r.prepare(`
|
|
@@ -168,11 +170,11 @@ ${o.pid??0}`),o.unref(),{pid:o.pid??0}}async function ot(){let e=wn(process.cwd(
|
|
|
168
170
|
SUM(CASE WHEN access_count = 0 THEN 1 ELSE 0 END) never_accessed,
|
|
169
171
|
SUM(CASE WHEN access_count > 0 THEN 1 ELSE 0 END) accessed
|
|
170
172
|
FROM memories WHERE status = 'active'
|
|
171
|
-
`).get();n.push({key:"memory_sources_7d",value:Object.fromEntries(i.map(c=>[c.source,Number(c.count)])),ok:!0,severity:"info"}),n.push({key:"memory_access_distribution",value:{neverAccessed:Number(a?.never_accessed??0),accessed:Number(a?.accessed??0)},ok:!0,severity:"info"});}}catch(s){n.push({key:"memory_quality_read",value:s.message,target:"readable memory database",ok:false,severity:"error"});}finally{r?.close();}return {name:"Memory quality",status:T(n),metrics:n}}function
|
|
172
|
-
`)}async function
|
|
173
|
-
`)}var
|
|
173
|
+
`).get();n.push({key:"memory_sources_7d",value:Object.fromEntries(i.map(c=>[c.source,Number(c.count)])),ok:!0,severity:"info"}),n.push({key:"memory_access_distribution",value:{neverAccessed:Number(a?.never_accessed??0),accessed:Number(a?.accessed??0)},ok:!0,severity:"info"});}}catch(s){n.push({key:"memory_quality_read",value:s.message,target:"readable memory database",ok:false,severity:"error"});}finally{r?.close();}return {name:"Memory quality",status:T(n),metrics:n}}function xl(e,t){let n=[],o=join$1(e,".devflow","knowledge","knowledge.db");if(!existsSync$1(o))return n.push({key:"knowledge_db",value:"missing",target:o,ok:false,severity:"warning"}),{name:"Knowledge quality",status:T(n),metrics:n};let r;try{if(r=ie(o,t),!W(r,"knowledge_chunks"))n.push({key:"knowledge_schema",value:"knowledge_chunks missing",target:"Batch 3 knowledge schema",ok:!1,severity:"warning"});else {let s=r.prepare("SELECT length(content) length FROM knowledge_chunks ORDER BY length(content)").all().map(u=>Number(u.length)),i=Math.max(0,Math.ceil(s.length*.95)-1),a=s.length===0?0:s[i];n.push({key:"knowledge_chunk_length_p95",value:a,target:"<= 3000",ok:a<=3e3,severity:"warning"});let c=r.prepare("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'knowledge_fts'").get(),l=/tokenize\s*=\s*['\"]?trigram/i.test(c?.sql??"");n.push({key:"knowledge_fts_tokenizer",value:l?"trigram":"missing/non-trigram",target:"trigram",ok:l,severity:"warning"});}}catch(s){n.push({key:"knowledge_quality_read",value:s.message,target:"readable knowledge database",ok:false,severity:"error"});}finally{r?.close();}return {name:"Knowledge quality",status:T(n),metrics:n}}function Ol(e){let{manifest:t,metrics:n}=Tt(e),o=t?.contract?.surfaces??[];return n.push({key:"contract_surfaces",value:o,target:["cli","http","mcp","hook"],ok:t?.contract?.status==="green"&&o.length===4,severity:"error"}),n.push({key:"contract_test_files",value:t?.contract?.tests?.length??0,target:4,ok:t?.contract?.tests?.length===4,severity:"warning"}),{name:"Contract",status:T(n),metrics:n}}function Nl(e){let{manifest:t,metrics:n}=Tt(e),o=t?.deadcode?.actionableExports;return n.push({key:"ts_prune_actionable_exports",value:o??"missing",target:0,ok:t?.deadcode?.status==="green"&&o===0,severity:"error"}),n.push({key:"ts_prune_allowlisted_exports",value:t?.deadcode?.allowlistedExports??"missing",ok:true,severity:"info"}),{name:"Deadcode",status:T(n),metrics:n}}function Tl(e){let{manifest:t,metrics:n}=Tt(e),o=t?.dataFace?.sharedAdapters??[];return n.push({key:"shared_retrieval_adapters",value:o,target:["getProjectContextResult","getMemoryResult","getKnowledgeResult"],ok:t?.dataFace?.status==="green"&&o.length===3,severity:"error"}),{name:"Data face",status:T(n),metrics:n}}async function jl(e){let t=new AbortController,n=setTimeout(()=>t.abort(),500);try{return {status:(await fetch(e,{signal:t.signal})).status}}finally{clearTimeout(n);}}async function Il(e){let{manifest:t,metrics:n}=Tt(e),o=t?.ui?.routes??[];n.push({key:"dashboard_routes",value:o.length,target:">= 13",ok:t?.ui?.status==="green"&&o.length>=13,severity:"warning"});let s=`http://127.0.0.1:${e.env?.PORT??process.env.PORT??"13337"}/api/health`;try{let i=await(e.httpGet??jl)(s);n.push({key:"dashboard_server_health",value:{url:s,status:i.status},target:"HTTP 200",ok:i.status===200,severity:"warning"});}catch(i){n.push({key:"dashboard_server_health",value:i.message,target:"HTTP 200",ok:false,severity:"warning"});}return {name:"UI reachability",status:T(n),metrics:n}}async function Un(e={},t={}){let n=e.project??process.cwd(),o=On(n),r=Ol(t),s=await yc(o.path,t);r.metrics.push(...s.metrics),r.status=T(r.metrics);let i=[kc(n,t),Ec(o.path,t),Rl(o.path,t),await Dc(o.path,t),$c(o.path,!!e.strict,t),$l(o.path,t),Al(o.path,t),xl(o.path,t),r,Nl(t),Oc(t),Tl(t),xc(t),await Il(t),Tc(t)],a=e.strict&&i.some(c=>c.status!=="green")?1:0;return {schemaVersion:DOCTOR_SCHEMA_VERSION,sections:i,exitCode:a}}function Ml(e,t={}){return e===void 0?Zr():Un(e,t)}function Or(e){let t=JSON.stringify(e);return t===void 0?String(e):t}function Yr(e){let t=[];for(let n of e.sections){let o=`[${n.status.toUpperCase()}]`,r=n.status==="green"?S.green:n.status==="yellow"?S.yellow:S.red;t.push(`${r(o)} ${S.bold(n.name)}`);for(let s of n.metrics){let i=s.target===void 0?"":` (target: ${Or(s.target)})`;t.push(` ${s.ok?"OK":"FAIL"} ${s.key}: ${Or(s.value)}${i}`);}}return t.join(`
|
|
174
|
+
`)}async function Ll(e={},t={stdout:o=>console.log(o),stderr:o=>console.error(o)},n={}){let o=await Un(e,n);return t.stdout(e.json?JSON.stringify(o):Yr(o)),o.exitCode}async function jt(e){let{createEngines:t}=await import('@devflow-tools/context-engine');return t(e)}async function Zr(e=process.cwd()){let{codegraph:t,graph:n,memory:o,knowledge:r,workflow:s,data:i}=await jt(e),a=t.getStats(),c=n.export(),l=0;try{l=(await s.list()).length;}catch{}let u=false,d=0;try{let h=await o.getAll();u=!!h?.project,d=Object.keys(h?.user??{}).length;}catch{}let g=0;try{g=(await r.getSources()).length;}catch{}let f={total:0,byTool:{}};try{f=await i.getToolCallStats();}catch{}let p=await st(),m=0;return a.fileCount>0&&(m+=25),a.nodeCount>0&&(m+=15),c.nodes.length>0&&(m+=20),u&&(m+=15),g>0&&(m+=10),l>0&&(m+=5),p.running&&(m+=10),f.total>0&&(m+=5),{index:{totalFiles:a.fileCount,totalSymbols:a.nodeCount,indexing:t.isIndexing()},graph:{nodes:c.nodes.length,edges:c.edges.length},memory:{projectReady:u,userPrefs:d},knowledge:{sources:g},plugins:{installed:0,names:[]},workflows:{registered:l},server:{running:p.running},toolCalls:f,readyScore:m}}async function Fl(){let{data:e}=await jt(process.cwd()),t=await e.auditGetSecret(),n=await e.auditGetAll(),o=createHash("sha256").update("genesis").digest("hex");for(let r of n){if(r.prevHash!==o)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}|${o}`,i=createHmac("sha256",t).update(s).digest("hex");if(r.signature!==i)return {valid:false,brokenAt:r.seq,entryCount:n.length};o=r.signature;}return {valid:true,brokenAt:null,entryCount:n.length}}async function Hl(){let{data:e}=await jt(process.cwd()),t=await e.auditGetSecret(),n=await e.auditGetAll(),o=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}|${o}`,i=createHmac("sha256",t).update(s).digest("hex");await e.sqlExecute("UPDATE devflow_audit_chain SET prev_hash = ?, signature = ? WHERE seq = ?",[o,i,r.seq]),o=i;}return {rebuilt:true}}async function Ul(e){let{data:t}=await jt(process.cwd()),o=(await t.auditGetAll()).filter(r=>r.decision!=="allow");if(e){let r=e.match(/^(\d+)([dh])$/);if(r){let s=Number.parseInt(r[1],10),i=r[2]==="d"?s*864e5:s*36e5,a=Date.now()-i;o=o.filter(c=>c.ts>a);}}return {violations:o.map(r=>({tool:r.tool,decision:r.decision,ruleId:r.ruleId,ts:r.ts,sessionId:r.sessionId}))}}function Wl(){let e=`${process.env.TMPDIR??"/tmp"}/.devflow-receipts`,t=createHash("sha256").update(process.cwd()).digest("hex").slice(0,16),n=`${e}/${t}.json`;try{return {sessionId:t,data:JSON.parse(readFileSync$1(n,"utf8"))}}catch{return {sessionId:t,data:null}}}var Ct,wc,Nn,Pc,Ke,Ac,kr,jc,Ic,Hr,Rt,Fn,Ur,Wr,Mc,Lc,Fc,br,Qc,Pr,Er,Cr,Rr,Xc,el,tl,ol,rl,Dr,sl,cl,ll,Xr=$(()=>{Le();we();yn();wc={distill_leases:["event_ids","expires_at","status"],observations:["title"],session_events:["created_at","id","processed"],sessions:["created_at","id","project_root","status"]},Nn=3600*1e3;Pc=new Set(["pending","committed","expired"]);Ke=1440*60*1e3,Ac=30*Ke,kr=60*1024*1024;jc=/\/api\/memory\/(?:process|events|pending-count|extract(?:-rules)?|ollama\/status)(?![\w/-])/g,Ic=/\$(?:\{(?:CLAUDE_)?PLUGIN_ROOT\}|(?:CLAUDE_)?PLUGIN_ROOT)\/([A-Za-z0-9._/-]+)/g,Hr=64,Rt=1024*1024,Fn=8,Ur=8,Wr=64*1024;Mc=new Set([".","!","[[","]]","case","coproc","do","done","elif","else","esac","eval","fi","for","function","if","in","select","source","then","time","trap","until","while"]),Lc=new Set(["!","[[","]]","case","do","done","elif","else","esac","fi","for","function","if","in","select","then","time","until","while"]),Fc=/^\$\{(?:CLAUDE_PLUGIN_ROOT|CLAUDE_PROJECT_DIR|HOME|PLUGIN_ROOT)\}$/;br=[".cjs",".js",".mjs",".ts",".tsx"];Qc=new Set(["bash","node","python","python3","sh","tsx","zsh"]);Pr=new Set(["-r","--require"]),Er=new Set(["--experimental-loader","--import","--loader"]),Cr=new Set(["-e","--eval","-p","--print"]),Rr=new Set(["-C","--conditions","--input-type","--inspect-port","--title","--unhandled-rejections"]),Xc=new Set(["--enable-source-maps","--experimental-strip-types","--experimental-transform-types","--no-deprecation","--no-warnings","--test","--trace-deprecation","--trace-warnings","--watch"]),el=new Set(["--check","-c"]),tl=new Set(["--help","--version","-h","-v"]);ol=new Set(["-e","-eu","-o","-u","-ue"]),rl=new Set(["-B","-E","-I","-O","-OO","-P","-q","-s","-S","-u","-v","-x"]),Dr=new Set(["-W","-X","--check-hash-based-pycs"]),sl=new Set(["--help","--version","-h","-V"]);cl=new Set(["builtin","command","env","exec","nohup","timeout"]),ll=new Set([":","[","echo","false","printf","pwd","test","true"]);});var es={};x(es,{runMemoryMaintainCommand:()=>zl});function Kl(e){if(!e)return;let t=e.split(",").map(o=>o.trim()).filter(Boolean),n=t.filter(o=>!MEMORY_MAINTENANCE_ACTIONS.includes(o));if(n.length>0)throw new Error(`Unknown memory maintenance action(s): ${n.join(", ")}`);return [...new Set(t)]}async function zl(e){let t=await runMemoryMaintenance({projectRoot:e.projectRoot,actions:Kl(e.actions),apply:e.apply===true,dryRun:e.apply!==true,batchSize:e.batchSize});if(e.json)return JSON.stringify(t,null,2);let{before:n,after:o,changes:r}=t;return [`Memory maintenance: ${t.mode}`,`Pending events: ${n.pendingEvents.count} -> ${o.pendingEvents.count}`,`Eligible observation vectors: ${n.observationVectors.coverage.toFixed(3)} -> ${o.observationVectors.coverage.toFixed(3)}`,`Duplicate groups: ${n.duplicates.groups} -> ${o.duplicates.groups}`,`Changes: events=${r.duplicateEventsDeleted}, low-value=${r.lowValueEventsDiscarded}, observations=${r.observationsQuarantined}, vectors=${r.vectorsBackfilled}, leases=${r.staleLeasesReleased}`,t.backupPath?`Backup: ${t.backupPath}`:"Backup: none (dry-run)"].join(`
|
|
175
|
+
`)}var ts=$(()=>{});var ns={};x(ns,{generateToken:()=>Gl});async function Gl(e,t=3600){let n=Buffer.from(JSON.stringify({alg:"HS256",typ:"JWT"})).toString("base64url"),o=Math.floor(Date.now()/1e3),r={sub:`devflow-session-${Date.now().toString(36)}`,project:e.split("/").pop()??"unknown",iat:o,exp:o+t,scope:["context","knowledge","memory","workflow","graph"]},s=Buffer.from(JSON.stringify(r)).toString("base64url"),i=getLocalHmacSecret(),a=createHmac("sha256",i).update(`${n}.${s}`).digest("base64url");return {token:`${n}.${s}.${a}`,expiresAt:r.exp,scope:r.scope}}var os=$(()=>{});var Wn={};x(Wn,{reportBenchmarkCommand:()=>eu,runBenchmarkCommand:()=>Xl});async function Xl(e){let t=e.suite??"default",n=getBenchmarkSuite(t);if(!n)throw new Error(`Unknown benchmark suite "${t}"`);let r=await new BenchmarkEngine().runSuite(e.projectRoot,n,{rounds:e.rounds}),s=e.database??openGlobalDevFlowDatabase();try{s.insertBenchmarkReport(r);}finally{e.database||s.close();}let i=renderBenchmarkReport(r,e.output??"text");return e.output==="json"?i:`${i}
|
|
174
176
|
|
|
175
|
-
Stored: ${getGlobalDevFlowDbPath()} (${r.runId})`}async function
|
|
177
|
+
Stored: ${getGlobalDevFlowDbPath()} (${r.runId})`}async function eu(e={}){let t=e.database??openGlobalDevFlowDatabase(),n,o=null;try{n=e.runId?t.getBenchmarkReport(e.runId):t.getLatestBenchmarkReport(),e.baselineRunId&&(o=t.getBenchmarkReport(e.baselineRunId));}finally{e.database||t.close();}if(!n)throw new Error(e.runId?`Benchmark report "${e.runId}" not found`:"No benchmark reports found. Run `devflow benchmark run` first.");if(e.baselineRunId&&!o)throw new Error(`Benchmark baseline "${e.baselineRunId}" not found`);let r=e.output??"text",s=renderBenchmarkReport(n,r);if(!o||r==="json")return s;let i=tu(o,n);return r==="markdown"?`${s}
|
|
176
178
|
## Change From Prior Baseline
|
|
177
179
|
|
|
178
180
|
${i.map(a=>`- ${a}`).join(`
|
|
@@ -181,20 +183,20 @@ ${i.map(a=>`- ${a}`).join(`
|
|
|
181
183
|
|
|
182
184
|
Change from ${o.runId}:
|
|
183
185
|
${i.map(a=>`- ${a}`).join(`
|
|
184
|
-
`)}`}function
|
|
185
|
-
`)}var
|
|
186
|
-
Shutting down...`)),await
|
|
186
|
+
`)}`}function tu(e,t){let n=e.summary.devflow,o=t.summary.devflow;return [It("tokensUsed",n.avgTokensUsed,o.avgTokensUsed,false),It("filesTouched",n.avgFilesTouched,o.avgFilesTouched,false),It("correctnessScore",n.avgCorrectnessScore,o.avgCorrectnessScore,true),It("durationMs",n.avgDurationMs,o.avgDurationMs,false)]}function It(e,t,n,o){let r=t>0?(n-t)/t:0,s=o?r<-0.1:r>.1,i=r>0?"+":"";return `${e}: ${i}${(r*100).toFixed(1)}%${s?" (regression >10%)":""}`}var Bn=$(()=>{});var as={};x(as,{runReview:()=>nu});async function nu(e){let t,n;if(e.prUrl){let u=e.prUrl.match(/pull\/(\d+)/);n=`PR: ${u?`#${u[1]}`:e.prUrl}`;try{t=execSync(`gh pr diff ${e.prUrl}`,{encoding:"utf-8",maxBuffer:10*1024*1024});}catch{t=`Could not fetch PR diff from ${e.prUrl}. Ensure 'gh' CLI is installed and authenticated.`;}}else {n="Current branch vs main";try{t=execSync("git diff main...HEAD",{encoding:"utf-8",maxBuffer:10*1024*1024});}catch{t="Could not compute diff. Ensure you're on a feature branch.";}}let o=(t.match(/^diff --git/gm)??[]).length,r=(t.match(/^\+[^+]/gm)??[]).length,s=(t.match(/^-[^-]/gm)??[]).length,i=[],a=[],c=[];return t.includes("console.log")&&a.push("Contains console.log statements \u2014 remove before merge"),(t.includes(".only(")||t.includes("it.only"))&&i.push("Contains .only() test filters \u2014 remove before merge"),(t.includes("TODO")||t.includes("FIXME"))&&a.push("Contains TODO/FIXME comments \u2014 track or resolve"),(t.match(/^\+.*TODO/gm)||t.match(/^\+.*FIXME/gm))&&a.push("New code introduces TODO/FIXME comments"),t.includes("process.exit")&&a.push("Contains process.exit() \u2014 consider throwing instead"),t.includes(": any")&&t.match(/^\+.*: any/gm)&&c.push("New code uses `any` type \u2014 use explicit types instead"),[S.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: ${o}`,`+${r} / -${s}`,"",i.length>0?S.red(`Critical (${i.length})`):"",...i.map(u=>` ${S.red("\u25CF")} ${u}`),"",a.length>0?S.yellow(`Warning (${a.length})`):"",...a.map(u=>` ${S.yellow("\u25CB")} ${u}`),"",c.length>0?S.green(`Suggestion (${c.length})`):"",...c.map(u=>` ${S.green("\u25CB")} ${u}`),"",i.length>0?S.red("Overall: Need changes"):a.length>0?S.yellow("Overall: Approve with comments"):S.green("Overall: LGTM")].join(`
|
|
187
|
+
`)}var cs=$(()=>{});var ls={};x(ls,{startAll:()=>ru});async function ou(e,t=15e3){let n=Date.now();for(;Date.now()-n<t;){try{if((await fetch(`http://127.0.0.1:${e}/api/health`)).ok)return !0}catch{}await new Promise(o=>setTimeout(o,500));}return false}async function ru(e){console.log(S.blue("Starting DevFlow server..."));let{pid:t}=await Pn({port:e.port});console.log(S.green(` Server started (PID: ${t})`)),console.log(S.blue(" Waiting for server..."));let n=await ou(e.port);console.log(n?S.green(" Server ready"):S.yellow(" Server started but health check timed out")),console.log(""),console.log(S.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(S.green("\u2551")+" DevFlow Started! "+S.green("\u2551")),console.log(S.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(S.green("\u2551")+` Server + Dashboard: http://localhost:${e.port}`.padEnd(57)+S.green("\u2551")),console.log(S.green("\u2551")+` API: http://localhost:${e.port}/api`.padEnd(57)+S.green("\u2551")),console.log(S.green("\u2551")+" "+S.green("\u2551")),console.log(S.green("\u2551")+" Press Ctrl+C to stop "+S.green("\u2551")),console.log(S.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(o=>{let r=false,s=async()=>{r||(r=true,console.log(S.blue(`
|
|
188
|
+
Shutting down...`)),await rt(),console.log(S.green("Server stopped.")),o());};process.on("SIGINT",s),process.on("SIGTERM",s);});}var us=$(()=>{we();});var gs={};x(gs,{stopAll:()=>su});async function su(){let e=await rt();console.log(e?S.green("Server stopped"):S.dim("No DevFlow services running"));}var fs=$(()=>{we();});var ps={};x(ps,{showStatus:()=>du});function uu(e){if(!existsSync(e))return false;try{let t=new DatabaseSync(e,{readOnly:!0});try{return !!t.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name LIKE 'devflow_%' LIMIT 1").get()}finally{t.close();}}catch{return true}}async function du(){console.log(S.blue("DevFlow Status")),console.log(S.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));let e=await st(),t=e.port??_t;e.running?(console.log(`Server: ${S.green("\u2713")} running (port ${t}${e.pid?`, PID ${e.pid}`:""})`),console.log(`Dashboard: ${S.green("\u2713")} served at http://localhost:${t}`)):(console.log(`Server: ${S.yellow("\u25CB")} not running`),console.log(`Dashboard: ${S.yellow("\u25CB")} not running`));let n=homedir$1(),o=Ee(n),r=o.root?Ve(n,o.root):[];o.root?console.log(`Plugin: ${S.green("\u2713")} v${o.version??"unknown"} (${o.root})`):console.log(`Plugin: ${S.yellow("\u25CB")} active cache not resolved`),console.log(`Skills: ${r.length===0?S.green("\u2713"):S.red("!")} ${r.length} shadowed`);let s=getGlobalDevFlowDbPath();if(existsSync(s)){let u=(statSync(s).size/1024/1024).toFixed(1);console.log(`Data: ${s} (${u} MB)`);}else console.log(`Data: ${S.dim(`no global database (${s})`)}`);let i=join(process.cwd(),".devflow","devflow.db"),a=join(process.cwd(),".codegraph","codegraph.db"),c=[...existsSync(i)?[i]:[],...uu(a)?[`${a} (devflow_* tables)`]:[]];c.length>0?console.log(`Legacy: ${S.yellow(c.join(", "))}`):console.log(`Legacy: ${S.green("none")}`);}var hs=$(()=>{we();Le();});var ys={};x(ys,{setupCommand:()=>yu});function pu(){try{return yt()}catch{return}}function hu(e){let t=e.path?`${e.message} (${e.path})`:e.message;e.status==="failed"?console.log(S.red(` x ${e.artifact}: ${t}`)):e.status==="degraded"||e.status==="skipped"?console.log(S.yellow(` ! ${e.artifact}: ${t}`)):console.log(S.green(` + ${e.artifact}: ${t}`));}async function yu(e){console.log(S.blue("DevFlow Setup")),console.log(S.dim("--------------"));let t=createDefaultHostAdapterRegistry(),n={projectRoot:process.cwd(),homeDir:homedir$1(),env:process.env,explicitHost:e.agent},o=await t.select(n);if(o.status==="failed")return console.log(S.red(` x Host selection failed: ${o.reason}`)),console.log(S.dim(` ${o.action}`)),process.exitCode=1,{status:"failed",failure:o,projections:[]};let r=o.adapter,s=[];if(console.log(S.dim(` Host: ${r.id}${o.explicit?" (explicit)":" (detected)"}`)),e.skipMcp||s.push(r.mcp.project(n,{command:"devflow-mcp",args:["--mode","stdio"]})),!e.skipPlugin){let l=pu();s.push(...r.skills.project(n,{pluginRoot:l,skillsDirectory:l?join$1(l,"skills"):void 0}));}for(let l of s)hu(l);let i=s.filter(l=>l.status==="failed");if(i.length>0){let l={status:"failed",code:"projection_failed",candidates:o.candidates,availableHosts:t.list().map(u=>u.id).sort(),reason:i.map(u=>`${u.artifact}: ${u.message}`).join("; "),action:"Fix the reported config or artifact path and re-run setup for the selected host."};return console.log(""),console.log(S.red("Setup failed before all selected-host artifacts were projected.")),process.exitCode=1,{status:"failed",failure:l,projections:s}}let c=(await r.capabilities(n)).filter(l=>l.status!=="supported");return c.length>0&&console.log(S.yellow(` ! ${c.length} host capabilities are degraded or unavailable; run devflow doctor for details.`)),console.log(""),console.log(S.green(`Setup complete for ${r.id}.`)),console.log(S.dim("Restart the configured host to load DevFlow MCP and projected artifacts.")),{status:"configured",hostId:r.id,projections:s}}var vs=$(()=>{Le();});var ks={};x(ks,{pluginListCommand:()=>ku});var ku,ws=$(()=>{vt();ku=new Command("list").description("List available plugins").option("-i, --installed","Show only installed plugins").action(async e=>{let t=Fe();if(e.installed){let n=go();if(n.length===0){console.log("No plugins installed."),console.log(`
|
|
187
189
|
Run "devflow plugin list" to see available plugins.`);return}console.log(`Installed plugins:
|
|
188
190
|
`),n.forEach(o=>{let r=t.plugins.find(s=>s.name===o);r?(console.log(` ${S.green(r.name)}@${r.version}`),console.log(` ${r.description}`)):console.log(` ${S.green(o)}`);});}else {if(t.plugins.length===0){console.log("No plugins available.");return}console.log(`Available plugins (${t.plugins.length}):
|
|
189
191
|
`);let n=Math.max(...t.plugins.map(o=>o.name.length));t.plugins.forEach(o=>{let r=" ".repeat(n-o.name.length+2);console.log(` ${S.green(o.name)}${r}v${o.version}`),console.log(` ${" ".repeat(n)}${o.description.substring(0,60)}`),o.tags.length>0&&console.log(` ${" ".repeat(n)}Tags: ${o.tags.join(", ")}`),console.log("");}),console.log(`
|
|
190
|
-
Install a plugin: devflow plugin install <name>`);}});});var
|
|
192
|
+
Install a plugin: devflow plugin install <name>`);}});});var bs={};x(bs,{pluginSearchCommand:()=>Su});var Su,Ss=$(()=>{vt();Su=new Command("search").description("Search for plugins").argument("<keyword>","Search keyword").action(async e=>{let t=Fe(),n=e.toLowerCase(),o=t.plugins.filter(r=>r.name.toLowerCase().includes(n)||r.description.toLowerCase().includes(n)||r.tags.some(s=>s.toLowerCase().includes(n)));if(o.length===0){console.log(`No plugins found matching "${e}"`),console.log(`
|
|
191
193
|
Try: devflow plugin list`);return}console.log(`Found ${o.length} plugin(s) matching "${e}":
|
|
192
|
-
`),o.forEach(r=>{console.log(` ${S.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
|
|
194
|
+
`),o.forEach(r=>{console.log(` ${S.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 Ps={};x(Ps,{pluginInstallCommand:()=>Pu});var Pu,Es=$(()=>{ve();Pu=new Command("install").description("Install a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let n=`@devflow-tools/plugin-${e.replace(/^@devflow-tools\/(?:plugin-)?/,"")}`;console.log(`Installing ${n}...`);try{let o=await Re(n,process.cwd(),!0);console.log(`
|
|
193
195
|
${S.green("\u2713")} ${n}@${o.version} installed and activated`),console.log(`
|
|
194
196
|
Run "devflow plugin list --installed" to verify.`);}catch(o){console.error(`
|
|
195
|
-
${S.red("\u2717")} Installation failed: ${o.message}`),process.exitCode=1;}});});var
|
|
197
|
+
${S.red("\u2717")} Installation failed: ${o.message}`),process.exitCode=1;}});});var Rs={};x(Rs,{pluginUninstallCommand:()=>Cu});var Cu,Ds=$(()=>{ve();Cu=new Command("uninstall").description("Uninstall a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let n=`@devflow-tools/plugin-${e.replace(/^@devflow-tools\/(?:plugin-)?/,"")}`;console.log(`Uninstalling ${n}...`);try{await Vt(n,process.cwd(),!0),console.log(`
|
|
196
198
|
${S.green("\u2713")} ${n} deactivated and uninstalled`);}catch(o){console.error(`
|
|
197
|
-
${S.red("\u2717")} Uninstallation failed: ${o.message}`),process.exitCode=1;}});});function Ft(e){let t=join(e,".devflow","config.json");if(existsSync(t))try{let n=readFileSync(t,"utf-8");if(JSON.parse(n).serverUrl)return "server"}catch{}return "local"}var
|
|
198
|
-
`));}let n=Ft(t);console.error(S.blue(`DevFlow init \u2014 mode: ${n}`));let{initProject:o,renderInitReport:r}=await Promise.resolve().then(()=>(io(),so)),s=await o(t,{force:e.force,migrateLegacySkills:e.migrateLegacySkills});if(e.json&&s.onboardingPack)console.log(JSON.stringify(s.onboardingPack,null,2));else if(e.report&&s.onboardingPack)console.log(r(s.onboardingPack));else {if(s.created.length>0){console.log(S.green("Created:"));for(let i of s.created)console.log(` ${S.dim("+")} ${i}`);}else console.log(S.dim("Already initialized. Use --force to overwrite config."));if(s.indexed&&console.log(S.green(`\u2705 CodeGraph initialized (${s.indexed.files} files, ${s.indexed.symbols} symbols)`)),s.onboardingPack){let i=s.onboardingPack;console.log(S.green("\u2705 Onboarding pack generated")),console.log(S.dim(` ${i.stats.files} files, ${i.stack.frameworks.join(", ")||"no framework"}`));}if(s.pluginDeployed&&console.log(S.green("\u2705 Plugin deployed to ~/.claude/plugins/cache/")),s.pluginEnabled&&console.log(S.green("\u2705 Plugin enabled in ~/.claude/settings.json")),s.mcpConfigured&&console.log(S.green("\u2705 MCP config written to .claude/mcp.json")),s.pluginDeployed&&s.pluginEnabled&&s.mcpConfigured&&console.log(S.green("\nDevFlow is ready! Run `claude` to start.")),typeof e.withPlugin=="string"){let{reviewPluginMemoryHints:i}=await Promise.resolve().then(()=>(co(),ao)),a=await i(t,e.withPlugin);console.log(S.dim(`Plugin memory hints: ${a.selected}/${a.available} selected`));}if(typeof e.plugins=="string"){let{installPluginsFromList:i}=await Promise.resolve().then(()=>(Yt(),Gt));await i(e.plugins);}else if(e.plugins!==false){let{guidePluginInstallation:i}=await Promise.resolve().then(()=>(Yt(),Gt));await i(t);}}});E.command("reset").description("Reset generated DevFlow project data").requiredOption("--scope <scope>","memory | knowledge | codegraph | all").option("--backup-to <dir>","Back up selected data before resetting").option("--force","Reset without creating a backup").option("--project <path>","Project directory",process.cwd()).action(async e=>{let{executeResetCommand:t}=await Promise.resolve().then(()=>(Mo(),Io));t(e,{},{log:o=>console.log(o),error:o=>console.error(S.red(o))})||(process.exitCode=1);});var bu=E.command("db").description("Manage DevFlow databases");bu.command("consolidate").description("Merge legacy project databases into the global database").option("--project <path>","Project directory",process.cwd()).option("--dry-run","Report rows and conflicts without writing").action(async e=>{let{consolidateDatabases:t,formatConsolidateResult:n}=await Promise.resolve().then(()=>(Vo(),zo)),o=t(e);for(let r of n(o))console.log(r);});E.command("connect [agent]").description("Configure the Claude Code MCP connection").option("--command <cmd>","MCP server command","devflow-mcp").action(async(e,t)=>{let n=process.cwd(),o=Ft(n);console.log(S.blue(`DevFlow connect \u2014 mode: ${o}`));let{connectAgent:r,getAvailableAgents:s}=await Promise.resolve().then(()=>(Go(),Jo));if(e){let i=s();i.includes(e)||(console.log(S.red(`Unknown agent: ${e}`)),console.log(`Available: ${i.join(", ")}`),process.exit(1));}try{let i=await r({agent:e,command:t.command});for(let a of i)console.log(S.green(`\u2713 ${a}`));}catch(i){console.error(S.red(`Error: ${i.message}`)),process.exit(1);}});E.command("index").description("Show index status").option("--backfill-vectors","Reconcile the index and wait for symbol vectors").option("--watch","Start file watcher for hot updates (stub)").action(async e=>{let{getIndexStatus:t,refreshIndex:n}=await Promise.resolve().then(()=>(Qo(),Zo)),o=e.backfillVectors?await n(E.opts().local):await t(E.opts().local);console.log(S.blue("Index Status")),console.log(` Files: ${o.totalFiles}`),console.log(` Symbols: ${o.totalSymbols}`),console.log(` Indexing: ${o.indexing?"active":"idle"}`),e.watch&&console.log(S.dim(" (watch mode not yet implemented)"));});E.command("graph [target]").description("Show dependency graph").option("--depth <n>","Expansion depth","2").action(async(e,t)=>{let{getGraph:n}=await Promise.resolve().then(()=>(er(),Xo)),o=await n({target:e,depth:parseInt(t.depth,10),skipServer:E.opts().local});console.log(S.blue("Dependency Graph")),console.log(` Nodes: ${o.nodes.length}`),console.log(` Edges: ${o.edges.length}`);});E.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,t)=>{if(t.task){let{getTaskContext:n}=await Promise.resolve().then(()=>(ln(),cn)),o=await n({query:e,mode:t.mode,maxTokens:parseInt(t.maxTokens,10),skipServer:E.opts().local});console.log(JSON.stringify({requiredFiles:o.requiredFiles,optionalFiles:o.optionalFiles,riskHints:o.riskHints,nextActions:o.nextActions,reasoning:t.why?o.reasoning:void 0},null,2));}else {let{getContext:n}=await Promise.resolve().then(()=>(ln(),cn)),o=await n({query:e,mode:t.mode,maxTokens:parseInt(t.maxTokens,10),skipServer:E.opts().local});console.log(S.blue(`Context: "${e}"`)),console.log(` Files: ${o.files.length}`),console.log(` Confidence: ${(o.confidence*100).toFixed(0)}%`),console.log(` Tokens: ${o.tokenCount}`);}});var Lt=E.command("workflow").description("Workflow management");Lt.command("list").description("List available workflows").action(async()=>{let{listWorkflows:e}=await Promise.resolve().then(()=>(tt(),et)),t=await e(E.opts().local);if(t.length===0){console.log(S.dim("No workflows registered."));return}for(let n of t)console.log(`${S.green(n.name)} \u2014 ${n.description} (${n.stepCount} steps)`);});Lt.command("run <type> [input]").description("Run a workflow").action(async(e,t)=>{let{runWorkflow:n}=await Promise.resolve().then(()=>(tt(),et)),o=await n(e,{input:t??""},E.opts().local);console.log(`Run: ${o.runId}`),console.log(`Status: ${o.status}`),console.log(`Duration: ${o.duration}ms`);});Lt.command("status").description("Show running workflows").action(async()=>{let{getWorkflowStatus:e}=await Promise.resolve().then(()=>(tt(),et)),t=await e(E.opts().local);console.log(`${t.length} run(s)`);for(let n of t)console.log(` ${n.runId} \u2014 ${n.status}`);});Lt.command("runs").description("Show workflow history").action(async()=>{let{getWorkflowRuns:e}=await Promise.resolve().then(()=>(tt(),et)),t=await e(E.opts().local);if(t.length===0){console.log(S.dim("No runs yet."));return}for(let n of t){let o=n.finishedAt?`${n.finishedAt-n.startedAt}ms`:"running";console.log(` ${n.runId} ${S.yellow(n.status)} ${o}`);}});var Te=E.command("memory").description("Memory management");Te.command("show").description("Show current project memory").option("--source <source>","Filter memories by source").action(async e=>{let{showMemory:t}=await Promise.resolve().then(()=>(Ae(),De)),n=await t(E.opts().local,e.source);console.log(JSON.stringify(n,null,2));});Te.command("list").description("List project memories").option("--source <source>","Filter memories by source").action(async e=>{let{showMemory:t}=await Promise.resolve().then(()=>(Ae(),De));console.log(JSON.stringify(await t(E.opts().local,e.source),null,2));});Te.command("query [query]").description("Retrieve ranked project memory with a token budget").option("--purpose <purpose>","Retrieval purpose","task_context").option("--budget-tokens <count>","Maximum response tokens","2000").option("--scope <scope>","Memory scope to include (repeatable)",(e,t)=>[...t,e],[]).action(async(e,t)=>{let{queryMemory:n}=await Promise.resolve().then(()=>(Ae(),De)),o=await n({query:e,purpose:t.purpose,budgetTokens:Number.parseInt(t.budgetTokens,10),scopes:t.scope.length>0?t.scope:void 0,skipServer:E.opts().local});console.log(JSON.stringify(o,null,2));});Te.command("set <key> <value>").description("Set a memory key").action(async(e,t)=>{let{setMemory:n}=await Promise.resolve().then(()=>(Ae(),De));await n(e,t,E.opts().local),console.log(S.green(`Memory set: ${e} = ${t}`));});Te.command("review").description("Review memory candidates").action(async()=>{let{reviewCandidates:e}=await Promise.resolve().then(()=>(Ae(),De)),t=await e(E.opts().local);console.log(JSON.stringify(t,null,2));});Te.command("backfill-obs-vectors").description("Backfill missing observation vectors").option("--batch-size <count>","Embedding batch size","32").action(async e=>{let{backfillObservationVectors:t}=await Promise.resolve().then(()=>(Ae(),De)),n=await t({batchSize:Number.parseInt(e.batchSize,10),onProgress:({processed:o,remaining:r})=>{console.log(` vectors: ${o} processed, ${r} remaining`);}});console.log(S.green(`Observation vectors ready: ${n.processed} added, ${n.remaining} remaining`));});E.command("knowledge <query>").description("Search knowledge base").action(async e=>{let{queryKnowledge:t}=await Promise.resolve().then(()=>(sr(),rr)),o=(await t(e,void 0,void 0,E.opts().local)).results;console.log(S.blue(`Knowledge: "${e}"`)),console.log(` Results: ${o.length}`);for(let r of o.slice(0,5))console.log(` \u2014 ${r.title}`);});var Kn=E.command("docs").description("Documentation index management");Kn.command("sync [plugin-name]").description("Sync documentation for plugins").action(async e=>{console.log(S.blue(`\u25C9 Syncing docs${e?` for ${e} plugin`:""}`));let[{KnowledgeEngine:t},{EmbeddingProvider:n}]=await Promise.all([import('@devflow-tools/knowledge-engine'),import('@devflow-tools/memory-engine')]),o=new t({projectRoot:process.cwd(),embedder:new n});if(e){let r=await o.syncDocs(e);for(let s of r)s.added>0?console.log(` ${S.green("\u2713")} ${s.source} \u2192 ${s.added} chunks`):console.log(` ${S.red("\u2717")} ${s.source} \u2014 ${s.errors.join(", ")||"no content"}`);console.log(S.green(`
|
|
199
|
+
${S.red("\u2717")} Uninstallation failed: ${o.message}`),process.exitCode=1;}});});function Ft(e){let t=join(e,".devflow","config.json");if(existsSync(t))try{let n=readFileSync(t,"utf-8");if(JSON.parse(n).serverUrl)return "server"}catch{}return "local"}var As=createRequire(import.meta.url),zn="0.0.0";try{zn=As("../package.json").version;}catch{try{zn=As("../../package.json").version;}catch{}}var E=new Command;E.name("devflow").description("Developer Intelligence Platform for AI Coding Agents").version(zn).option("--local","Force local engine, skip server");E.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("--with-plugin <names>","Interactively review optional memory hints from installed plugins").option("--no-plugins","Skip plugin installation guide").option("--migrate-legacy-skills","Back up and remove global devflow:* skill shadows").action(async e=>{let t=process.cwd();if(e.abort){console.log(S.yellow("\u{1F5D1}\uFE0F --abort flag detected, removing existing directories..."));let i=[".codegraph",".devflow"];for(let a of i){let c=Du.join(t,a);$s.existsSync(c)&&(console.log(S.dim(` Removing ${a}/...`)),$s.rmSync(c,{recursive:true,force:true}));}console.log(S.green(`\u2705 Existing directories removed
|
|
200
|
+
`));}let n=Ft(t);console.error(S.blue(`DevFlow init \u2014 mode: ${n}`));let{initProject:o,renderInitReport:r}=await Promise.resolve().then(()=>(co(),ao)),s=await o(t,{force:e.force,migrateLegacySkills:e.migrateLegacySkills});if(e.json&&s.onboardingPack)console.log(JSON.stringify(s.onboardingPack,null,2));else if(e.report&&s.onboardingPack)console.log(r(s.onboardingPack));else {if(s.created.length>0){console.log(S.green("Created:"));for(let i of s.created)console.log(` ${S.dim("+")} ${i}`);}else console.log(S.dim("Already initialized. Use --force to overwrite config."));if(s.indexed&&console.log(S.green(`\u2705 CodeGraph initialized (${s.indexed.files} files, ${s.indexed.symbols} symbols)`)),s.onboardingPack){let i=s.onboardingPack;console.log(S.green("\u2705 Onboarding pack generated")),console.log(S.dim(` ${i.stats.files} files, ${i.stack.frameworks.join(", ")||"no framework"}`));}if(s.pluginDeployed&&console.log(S.green("\u2705 Plugin deployed to ~/.claude/plugins/cache/")),s.pluginEnabled&&console.log(S.green("\u2705 Plugin enabled in ~/.claude/settings.json")),s.mcpConfigured&&console.log(S.green("\u2705 MCP config written to .claude/mcp.json")),s.pluginDeployed&&s.pluginEnabled&&s.mcpConfigured&&console.log(S.green("\nDevFlow is ready! Run `claude` to start.")),typeof e.withPlugin=="string"){let{reviewPluginMemoryHints:i}=await Promise.resolve().then(()=>(uo(),lo)),a=await i(t,e.withPlugin);console.log(S.dim(`Plugin memory hints: ${a.selected}/${a.available} selected`));}if(typeof e.plugins=="string"){let{installPluginsFromList:i}=await Promise.resolve().then(()=>(Yt(),Gt));await i(e.plugins);}else if(e.plugins!==false){let{guidePluginInstallation:i}=await Promise.resolve().then(()=>(Yt(),Gt));await i(t);}}});E.command("reset").description("Reset generated DevFlow project data").requiredOption("--scope <scope>","memory | knowledge | codegraph | all").option("--backup-to <dir>","Back up selected data before resetting").option("--force","Reset without creating a backup").option("--project <path>","Project directory",process.cwd()).action(async e=>{let{executeResetCommand:t}=await Promise.resolve().then(()=>(Fo(),Lo));t(e,{},{log:o=>console.log(o),error:o=>console.error(S.red(o))})||(process.exitCode=1);});var Au=E.command("db").description("Manage DevFlow databases");Au.command("consolidate").description("Merge legacy project databases into the global database").option("--project <path>","Project directory",process.cwd()).option("--dry-run","Report rows and conflicts without writing").action(async e=>{let{consolidateDatabases:t,formatConsolidateResult:n}=await Promise.resolve().then(()=>(Go(),Vo)),o=t(e);for(let r of n(o))console.log(r);});E.command("connect [agent]").description("Configure the Claude Code MCP connection").option("--command <cmd>","MCP server command","devflow-mcp").action(async(e,t)=>{let n=process.cwd(),o=Ft(n);console.log(S.blue(`DevFlow connect \u2014 mode: ${o}`));let{connectAgent:r,getAvailableAgents:s}=await Promise.resolve().then(()=>(Zo(),Yo));if(e){let i=s();i.includes(e)||(console.log(S.red(`Unknown agent: ${e}`)),console.log(`Available: ${i.join(", ")}`),process.exit(1));}try{let i=await r({agent:e,command:t.command});for(let a of i)console.log(S.green(`\u2713 ${a}`));}catch(i){console.error(S.red(`Error: ${i.message}`)),process.exit(1);}});E.command("index").description("Show index status").option("--backfill-vectors","Reconcile the index and wait for symbol vectors").option("--watch","Start file watcher for hot updates (stub)").action(async e=>{let{getIndexStatus:t,refreshIndex:n}=await Promise.resolve().then(()=>(er(),Xo)),o=e.backfillVectors?await n(E.opts().local):await t(E.opts().local);console.log(S.blue("Index Status")),console.log(` Files: ${o.totalFiles}`),console.log(` Symbols: ${o.totalSymbols}`),console.log(` Indexing: ${o.indexing?"active":"idle"}`),e.watch&&console.log(S.dim(" (watch mode not yet implemented)"));});E.command("graph [target]").description("Show dependency graph").option("--depth <n>","Expansion depth","2").action(async(e,t)=>{let{getGraph:n}=await Promise.resolve().then(()=>(nr(),tr)),o=await n({target:e,depth:parseInt(t.depth,10),skipServer:E.opts().local});console.log(S.blue("Dependency Graph")),console.log(` Nodes: ${o.nodes.length}`),console.log(` Edges: ${o.edges.length}`);});E.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,t)=>{if(t.task){let{getTaskContext:n}=await Promise.resolve().then(()=>(ln(),cn)),o=await n({query:e,mode:t.mode,maxTokens:parseInt(t.maxTokens,10),skipServer:E.opts().local});console.log(JSON.stringify({requiredFiles:o.requiredFiles,optionalFiles:o.optionalFiles,riskHints:o.riskHints,nextActions:o.nextActions,reasoning:t.why?o.reasoning:void 0},null,2));}else {let{getContext:n}=await Promise.resolve().then(()=>(ln(),cn)),o=await n({query:e,mode:t.mode,maxTokens:parseInt(t.maxTokens,10),skipServer:E.opts().local});console.log(S.blue(`Context: "${e}"`)),console.log(` Files: ${o.files.length}`),console.log(` Confidence: ${(o.confidence*100).toFixed(0)}%`),console.log(` Tokens: ${o.tokenCount}`);}});var Lt=E.command("workflow").description("Workflow management");Lt.command("list").description("List available workflows").action(async()=>{let{listWorkflows:e}=await Promise.resolve().then(()=>(nt(),tt)),t=await e(E.opts().local);if(t.length===0){console.log(S.dim("No workflows registered."));return}for(let n of t)console.log(`${S.green(n.name)} \u2014 ${n.description} (${n.stepCount} steps)`);});Lt.command("run <type> [input]").description("Run a workflow").action(async(e,t)=>{let{runWorkflow:n}=await Promise.resolve().then(()=>(nt(),tt)),o=await n(e,{input:t??""},E.opts().local);console.log(`Run: ${o.runId}`),console.log(`Status: ${o.status}`),console.log(`Duration: ${o.duration}ms`);});Lt.command("status").description("Show running workflows").action(async()=>{let{getWorkflowStatus:e}=await Promise.resolve().then(()=>(nt(),tt)),t=await e(E.opts().local);console.log(`${t.length} run(s)`);for(let n of t)console.log(` ${n.runId} \u2014 ${n.status}`);});Lt.command("runs").description("Show workflow history").action(async()=>{let{getWorkflowRuns:e}=await Promise.resolve().then(()=>(nt(),tt)),t=await e(E.opts().local);if(t.length===0){console.log(S.dim("No runs yet."));return}for(let n of t){let o=n.finishedAt?`${n.finishedAt-n.startedAt}ms`:"running";console.log(` ${n.runId} ${S.yellow(n.status)} ${o}`);}});var xs=E.command("embeddings").description("Manage the shared verified embedding model");xs.command("status").description("Inspect the shared embedding model without network access").option("--json","Output JSON").action(async e=>{let{getEmbeddingStatus:t,renderEmbeddingStatus:n}=await Promise.resolve().then(()=>(gn(),dn)),o=await t();console.log(e.json?JSON.stringify(o,null,2):n(o)),o.ready||(process.exitCode=1);});xs.command("prepare").description("Prepare and verify the shared embedding model").option("--endpoint <url>","Preferred model endpoint (repeatable)",(e,t)=>[...t,e],[]).option("--timeout-ms <milliseconds>","Per-file download timeout","60000").option("--json","Output JSON").action(async e=>{try{let{prepareEmbeddings:t,renderEmbeddingStatus:n}=await Promise.resolve().then(()=>(gn(),dn)),o=Number(e.timeoutMs);if(!Number.isSafeInteger(o)||o<=0)throw new Error("--timeout-ms must be a positive integer");let r=await t({endpoints:e.endpoint,timeoutMs:o});e.json?console.log(JSON.stringify(r,null,2)):(console.log(n(r)),console.log(` source: ${r.source}`),r.migratedFrom&&console.log(` migrated from: ${r.migratedFrom}`),r.attemptedEndpoints.length>0&&console.log(` endpoints: ${r.attemptedEndpoints.join(", ")}`));}catch(t){console.error(S.red(`Embedding model preparation failed: ${t.message}`)),process.exitCode=1;}});var Te=E.command("memory").description("Memory management");Te.command("show").description("Show current project memory").option("--source <source>","Filter memories by source").action(async e=>{let{showMemory:t}=await Promise.resolve().then(()=>($e(),De)),n=await t(E.opts().local,e.source);console.log(JSON.stringify(n,null,2));});Te.command("list").description("List project memories").option("--source <source>","Filter memories by source").action(async e=>{let{showMemory:t}=await Promise.resolve().then(()=>($e(),De));console.log(JSON.stringify(await t(E.opts().local,e.source),null,2));});Te.command("query [query]").description("Retrieve ranked project memory with a token budget").option("--purpose <purpose>","Retrieval purpose","task_context").option("--budget-tokens <count>","Maximum response tokens","2000").option("--scope <scope>","Memory scope to include (repeatable)",(e,t)=>[...t,e],[]).action(async(e,t)=>{let{queryMemory:n}=await Promise.resolve().then(()=>($e(),De)),o=await n({query:e,purpose:t.purpose,budgetTokens:Number.parseInt(t.budgetTokens,10),scopes:t.scope.length>0?t.scope:void 0,skipServer:E.opts().local});console.log(JSON.stringify(o,null,2));});Te.command("set <key> <value>").description("Set a memory key").action(async(e,t)=>{let{setMemory:n}=await Promise.resolve().then(()=>($e(),De));await n(e,t,E.opts().local),console.log(S.green(`Memory set: ${e} = ${t}`));});Te.command("review").description("Review memory candidates").action(async()=>{let{reviewCandidates:e}=await Promise.resolve().then(()=>($e(),De)),t=await e(E.opts().local);console.log(JSON.stringify(t,null,2));});Te.command("backfill-obs-vectors").description("Backfill missing observation vectors").option("--batch-size <count>","Embedding batch size","32").action(async e=>{let{backfillObservationVectors:t}=await Promise.resolve().then(()=>($e(),De)),n=await t({batchSize:Number.parseInt(e.batchSize,10),onProgress:({processed:o,remaining:r})=>{console.log(` vectors: ${o} processed, ${r} remaining`);}});console.log(S.green(`Observation vectors ready: ${n.processed} added, ${n.remaining} remaining`));});E.command("knowledge <query>").description("Search knowledge base").action(async e=>{let{queryKnowledge:t}=await Promise.resolve().then(()=>(ar(),ir)),o=(await t(e,void 0,void 0,E.opts().local)).results;console.log(S.blue(`Knowledge: "${e}"`)),console.log(` Results: ${o.length}`);for(let r of o.slice(0,5))console.log(` \u2014 ${r.title}`);});var Jn=E.command("docs").description("Documentation index management");Jn.command("sync [plugin-name]").description("Sync documentation for plugins").action(async e=>{console.log(S.blue(`\u25C9 Syncing docs${e?` for ${e} plugin`:""}`));let[{KnowledgeEngine:t},{EmbeddingProvider:n}]=await Promise.all([import('@devflow-tools/knowledge-engine'),import('@devflow-tools/memory-engine')]),o=new t({projectRoot:process.cwd(),embedder:new n});if(e){let r=await o.syncDocs(e);for(let s of r)s.added>0?console.log(` ${S.green("\u2713")} ${s.source} \u2192 ${s.added} chunks`):console.log(` ${S.red("\u2717")} ${s.source} \u2014 ${s.errors.join(", ")||"no content"}`);console.log(S.green(`
|
|
199
201
|
${e} docs synced to .devflow/knowledge/${e}/`));}else {let r=await o.getSources();for(let s of r){let i=await o.syncDocs(s.source.name);for(let a of i)a.added>0?console.log(` ${S.green("\u2713")} ${a.source} \u2192 ${a.added} chunks`):console.log(` ${S.red("\u2717")} ${a.source} \u2014 ${a.errors.join(", ")||"no content"}`);}console.log(S.green(`
|
|
200
|
-
All docs synced.`));}});Kn.command("backfill-vectors").description("Backfill missing knowledge chunk vectors").option("--source <name>","Only backfill one knowledge source").option("--batch-size <count>","Embedding batch size","32").action(async e=>{let{backfillKnowledgeVectors:t}=await Promise.resolve().then(()=>(mn(),fn)),n=await t({source:e.source,batchSize:Number.parseInt(e.batchSize,10),onProgress:({processed:o,remaining:r})=>{console.log(` vectors: ${o} processed, ${r} remaining`);}});console.log(S.green(`Knowledge vectors ready: ${n.processed} added, ${n.remaining} remaining`));});Kn.command("resync [plugin-name]").description("Rebuild documentation chunks before vector backfill").requiredOption("--with-headings","Use heading-aware 500-3000 character chunks").action(async(e,t)=>{let{resyncKnowledgeDocs:n}=await Promise.resolve().then(()=>(mn(),fn));console.log(S.blue(`Resyncing docs${e?` for ${e}`:""} with headings`));let o=await n({source:e,withHeadings:t.withHeadings});for(let r of o)r.added>0?console.log(` ${S.green("\u2713")} ${r.source} \u2192 ${r.added} chunks`):console.log(` ${S.red("\u2717")} ${r.source} \u2014 ${r.errors.join(", ")||"no content"}`);console.log(S.green("Docs resynced. Run `devflow docs backfill-vectors` to rebuild vectors."));});var gt=E.command("skill").description("Plugin/Skill management");gt.command("list").description("List installed skills").action(async()=>{let{listSkills:e}=await Promise.resolve().then(()=>(ve(),Ge)),t=await e(E.opts().local);if(t.length===0){console.log(S.dim("No skills installed. Use 'devflow skill search' to find plugins."));return}for(let n of t)console.log(` ${S.green(n.name)} @ ${n.version} \u2014 ${n.description}`);});gt.command("search <query>").description("Search available plugins").action(async e=>{let{searchSkills:t}=await Promise.resolve().then(()=>(ve(),Ge)),n=await t(e,E.opts().local);if(console.log(S.blue(`Search: "${e}"`)),n.length===0){console.log(S.dim(" No matching plugins found."));return}for(let o of n)console.log(` ${S.green(o.name)} @ ${o.version} \u2014 ${o.description}`);});gt.command("install <name>").description("Install a plugin/skill").action(async e=>{try{let{installSkill:t}=await Promise.resolve().then(()=>(ve(),Ge)),n=await t(e,process.cwd(),E.opts().local);console.log(S.green(`\u2713 Installed @devflow-tools/plugin-${n.name}@${n.version}`)),n.templates.length>0&&console.log(` Templates: ${n.templates.join(", ")}`);}catch(t){console.log(S.red(`Error: ${t.message}`)),process.exit(1);}});gt.command("uninstall <name>").description("Uninstall a plugin/skill").action(async e=>{try{let{uninstallSkill:t}=await Promise.resolve().then(()=>(ve(),Ge));await t(e,process.cwd(),E.opts().local),console.log(S.green(`\u2713 Uninstalled ${e}`));}catch(t){console.log(S.red(`Error: ${t.message}`)),process.exit(1);}});gt.command("health").description("Validate installed DevFlow skill artifacts").option("--root <path>","Claude plugin root").option("--json","Output JSON").action(async e=>{let{showSkillHealth:t}=await Promise.resolve().then(()=>(pn(),cr));process.exitCode=t(e);});var As=E.command("mcp").description("Inspect MCP configuration and health");As.command("inventory").description("Show normalized MCP server inventory").option("--project <path>","Project directory",process.cwd()).option("--json","Output JSON").action(async e=>{let{showMcpInventory:t}=await Promise.resolve().then(()=>(yn(),hn));await t(e);});As.command("health").description("Check or show cached MCP server health").option("--project <path>","Project directory",process.cwd()).option("--refresh","Refresh health checks").option("--json","Output JSON").action(async e=>{let{showMcpHealth:t}=await Promise.resolve().then(()=>(yn(),hn));await t(e);});E.command("doctor").description("Run project health check").option("--json","Output as JSON").option("--strict","Exit with status 1 when any health section has warnings or errors").option("--project <path>","Project directory",process.cwd()).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=>{let{runDoctorCommand:t,runDoctorAudit:n,runDoctorAuditFix:o,runDoctorViolations:r,runDoctorReceipts:s}=await Promise.resolve().then(()=>(Zr(),Yr));if(e.audit){let a=await n();console.log(e.json?JSON.stringify(a):`Audit chain: ${a.valid?"VALID":`BROKEN at seq ${a.brokenAt}`} (${a.entryCount} entries)`);return}if(e.auditFix){let a=await o();console.log(e.json?JSON.stringify(a):"Audit chain rebuilt.");return}if(e.violations){let a=await r(e.last);console.log(e.json?JSON.stringify(a):JSON.stringify(a,null,2));return}if(e.receipts){let a=s();e.json?console.log(JSON.stringify(a)):a.data?console.log(JSON.stringify(a.data,null,2)):console.log(`No active receipt found for session ${a.sessionId}.`);return}let i=await t({project:e.project,json:e.json,strict:e.strict});process.exitCode=i;});Te.command("maintain").description("Audit or repair Memory data; defaults to a read-only dry-run").option("--project <path>","Project directory",process.cwd()).option("--actions <names>","Comma-separated actions").option("--apply","Apply changes after creating a SQLite backup").option("--json","Output the audit manifest as JSON").option("--batch-size <n>","Embedding backfill batch size","32").action(async e=>{try{let{runMemoryMaintainCommand:t}=await Promise.resolve().then(()=>(Xr(),Qr));console.log(await t({projectRoot:e.project,actions:e.actions,apply:e.apply,json:e.json,batchSize:Number(e.batchSize)}));}catch(t){console.error(S.red(`Memory maintenance failed: ${t.message}`)),process.exitCode=1;}});E.command("session token").description("Generate a session token for MCP Gateway authentication").option("--expires <seconds>","Token TTL in seconds","3600").action(async e=>{let{generateToken:t}=await Promise.resolve().then(()=>(ts(),es)),n=await t(process.cwd(),parseInt(e.expires,10));console.log(JSON.stringify(n,null,2));});var xs=E.command("benchmark").description("Run and inspect reproducible A/B benchmarks");xs.command("run").description("Run a benchmark suite and persist the report").option("--suite <id>","Benchmark suite","default").option("--project <root>","Initialized project root",process.cwd()).option("--rounds <n>","Rounds per task","1").option("--output <format>","text | json","text").action(async e=>{let{runBenchmarkCommand:t}=await Promise.resolve().then(()=>(Un(),Hn));console.log(await t({projectRoot:e.project,suite:e.suite,rounds:parseInt(e.rounds,10),output:e.output}));});xs.command("report").description("Render a persisted benchmark report").option("--run-id <id>","Specific report; defaults to latest").option("--baseline <id>","Prior report used for regression comparison").option("--output <format>","text | json | markdown","text").action(async e=>{let{reportBenchmarkCommand:t}=await Promise.resolve().then(()=>(Un(),Hn));console.log(await t({runId:e.runId,baselineRunId:e.baseline,output:e.output}));});E.command("review [pr-url]").description("Review a PR or current branch diff").option("--agent <agent>","AI agent to use","claude").action(async(e,t)=>{let{runReview:n}=await Promise.resolve().then(()=>(is(),ss)),o=await n({prUrl:e,agent:t.agent});console.log(o);});var zn=E.command("server").description("Manage DevFlow server");zn.command("start").description("Start the DevFlow REST server").option("--port <n>","Port number","13337").action(async e=>{console.log(S.blue("Starting DevFlow server..."));let{startServer:t}=await Promise.resolve().then(()=>(we(),Pt)),n=await t({port:parseInt(e.port,10)});console.log(S.green(`Server started (pid: ${n.pid}) on port ${e.port}`));});zn.command("stop").description("Stop the DevFlow REST server").action(async()=>{let{stopServer:e}=await Promise.resolve().then(()=>(we(),Pt)),t=await e();console.log(t?S.green("Server stopped"):S.dim("No server running"));});zn.command("status").description("Show server status").action(async()=>{let{serverStatus:e}=await Promise.resolve().then(()=>(we(),Pt)),t=await e();t.running?console.log(S.green(`Running (pid: ${t.pid})`)):console.log(S.yellow("Not running"));});E.command("dashboard").description("Open DevFlow Dashboard").action(()=>{console.log(S.blue("The Dashboard is served by the DevFlow server.")),console.log(S.dim("Run: devflow start")),console.log(S.dim("Then open: http://localhost:13337"));});E.command("start").description("Start DevFlow server (API + Dashboard)").option("--port <n>","Server port","13337").option("-d, --background","Run in background (detached)").action(async e=>{let{startAll:t}=await Promise.resolve().then(()=>(cs(),as));await t({port:parseInt(e.port,10),background:!!e.background});});E.command("stop").description("Stop DevFlow server").action(async()=>{let{stopAll:e}=await Promise.resolve().then(()=>(ds(),us));await e();});E.command("status").description("Show DevFlow services status").action(async()=>{let{showStatus:e}=await Promise.resolve().then(()=>(ms(),fs));await e();});E.command("setup").description("Configure DevFlow for a supported agent host").option("--agent <agent>","Target host (claude-code/codex/generic-mcp)").option("--skip-mcp","Skip MCP configuration").option("--skip-plugin","Skip plugin registration").action(async e=>{let{setupCommand:t}=await Promise.resolve().then(()=>(hs(),ps));await t({agent:e.agent,skipMcp:!!e.skipMcp,skipPlugin:!!e.skipPlugin});});var Mt=E.command("plugin").description("Manage DevFlow plugins");if(process.argv.includes("plugin")){let[{pluginListCommand:e},{pluginSearchCommand:t},{pluginInstallCommand:n},{pluginUninstallCommand:o}]=await Promise.all([Promise.resolve().then(()=>(vs(),ys)),Promise.resolve().then(()=>(ws(),ks)),Promise.resolve().then(()=>(_s(),Ss)),Promise.resolve().then(()=>(Cs(),Es))]);Mt.addCommand(e),Mt.addCommand(t),Mt.addCommand(n),Mt.addCommand(o);}await E.parseAsync();
|
|
202
|
+
All docs synced.`));}});Jn.command("backfill-vectors").description("Backfill missing knowledge chunk vectors").option("--source <name>","Only backfill one knowledge source").option("--batch-size <count>","Embedding batch size","32").action(async e=>{let{backfillKnowledgeVectors:t}=await Promise.resolve().then(()=>(hn(),pn)),n=await t({source:e.source,batchSize:Number.parseInt(e.batchSize,10),onProgress:({processed:o,remaining:r})=>{console.log(` vectors: ${o} processed, ${r} remaining`);}});console.log(S.green(`Knowledge vectors ready: ${n.processed} added, ${n.remaining} remaining`));});Jn.command("resync [plugin-name]").description("Rebuild documentation chunks before vector backfill").requiredOption("--with-headings","Use heading-aware 500-3000 character chunks").action(async(e,t)=>{let{resyncKnowledgeDocs:n}=await Promise.resolve().then(()=>(hn(),pn));console.log(S.blue(`Resyncing docs${e?` for ${e}`:""} with headings`));let o=await n({source:e,withHeadings:t.withHeadings});for(let r of o)r.added>0?console.log(` ${S.green("\u2713")} ${r.source} \u2192 ${r.added} chunks`):console.log(` ${S.red("\u2717")} ${r.source} \u2014 ${r.errors.join(", ")||"no content"}`);console.log(S.green("Docs resynced. Run `devflow docs backfill-vectors` to rebuild vectors."));});var gt=E.command("skill").description("Plugin/Skill management");gt.command("list").description("List installed skills").action(async()=>{let{listSkills:e}=await Promise.resolve().then(()=>(ve(),Ye)),t=await e(E.opts().local);if(t.length===0){console.log(S.dim("No skills installed. Use 'devflow skill search' to find plugins."));return}for(let n of t)console.log(` ${S.green(n.name)} @ ${n.version} \u2014 ${n.description}`);});gt.command("search <query>").description("Search available plugins").action(async e=>{let{searchSkills:t}=await Promise.resolve().then(()=>(ve(),Ye)),n=await t(e,E.opts().local);if(console.log(S.blue(`Search: "${e}"`)),n.length===0){console.log(S.dim(" No matching plugins found."));return}for(let o of n)console.log(` ${S.green(o.name)} @ ${o.version} \u2014 ${o.description}`);});gt.command("install <name>").description("Install a plugin/skill").action(async e=>{try{let{installSkill:t}=await Promise.resolve().then(()=>(ve(),Ye)),n=await t(e,process.cwd(),E.opts().local);console.log(S.green(`\u2713 Installed @devflow-tools/plugin-${n.name}@${n.version}`)),n.templates.length>0&&console.log(` Templates: ${n.templates.join(", ")}`);}catch(t){console.log(S.red(`Error: ${t.message}`)),process.exit(1);}});gt.command("uninstall <name>").description("Uninstall a plugin/skill").action(async e=>{try{let{uninstallSkill:t}=await Promise.resolve().then(()=>(ve(),Ye));await t(e,process.cwd(),E.opts().local),console.log(S.green(`\u2713 Uninstalled ${e}`));}catch(t){console.log(S.red(`Error: ${t.message}`)),process.exit(1);}});gt.command("health").description("Validate installed DevFlow skill artifacts").option("--root <path>","Claude plugin root").option("--json","Output JSON").action(async e=>{let{showSkillHealth:t}=await Promise.resolve().then(()=>(yn(),ur));process.exitCode=t(e);});var Os=E.command("mcp").description("Inspect MCP configuration and health");Os.command("inventory").description("Show normalized MCP server inventory").option("--project <path>","Project directory",process.cwd()).option("--json","Output JSON").action(async e=>{let{showMcpInventory:t}=await Promise.resolve().then(()=>(kn(),vn));await t(e);});Os.command("health").description("Check or show cached MCP server health").option("--project <path>","Project directory",process.cwd()).option("--refresh","Refresh health checks").option("--json","Output JSON").action(async e=>{let{showMcpHealth:t}=await Promise.resolve().then(()=>(kn(),vn));await t(e);});E.command("doctor").description("Run project health check").option("--json","Output as JSON").option("--strict","Exit with status 1 when any health section has warnings or errors").option("--project <path>","Project directory",process.cwd()).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=>{let{runDoctorCommand:t,runDoctorAudit:n,runDoctorAuditFix:o,runDoctorViolations:r,runDoctorReceipts:s}=await Promise.resolve().then(()=>(Xr(),Qr));if(e.audit){let a=await n();console.log(e.json?JSON.stringify(a):`Audit chain: ${a.valid?"VALID":`BROKEN at seq ${a.brokenAt}`} (${a.entryCount} entries)`);return}if(e.auditFix){let a=await o();console.log(e.json?JSON.stringify(a):"Audit chain rebuilt.");return}if(e.violations){let a=await r(e.last);console.log(e.json?JSON.stringify(a):JSON.stringify(a,null,2));return}if(e.receipts){let a=s();e.json?console.log(JSON.stringify(a)):a.data?console.log(JSON.stringify(a.data,null,2)):console.log(`No active receipt found for session ${a.sessionId}.`);return}let i=await t({project:e.project,json:e.json,strict:e.strict});process.exitCode=i;});Te.command("maintain").description("Audit or repair Memory data; defaults to a read-only dry-run").option("--project <path>","Project directory",process.cwd()).option("--actions <names>","Comma-separated actions").option("--apply","Apply changes after creating a SQLite backup").option("--json","Output the audit manifest as JSON").option("--batch-size <n>","Embedding backfill batch size","32").action(async e=>{try{let{runMemoryMaintainCommand:t}=await Promise.resolve().then(()=>(ts(),es));console.log(await t({projectRoot:e.project,actions:e.actions,apply:e.apply,json:e.json,batchSize:Number(e.batchSize)}));}catch(t){console.error(S.red(`Memory maintenance failed: ${t.message}`)),process.exitCode=1;}});E.command("session token").description("Generate a session token for MCP Gateway authentication").option("--expires <seconds>","Token TTL in seconds","3600").action(async e=>{let{generateToken:t}=await Promise.resolve().then(()=>(os(),ns)),n=await t(process.cwd(),parseInt(e.expires,10));console.log(JSON.stringify(n,null,2));});var Ns=E.command("benchmark").description("Run and inspect reproducible A/B benchmarks");Ns.command("run").description("Run a benchmark suite and persist the report").option("--suite <id>","Benchmark suite","default").option("--project <root>","Initialized project root",process.cwd()).option("--rounds <n>","Rounds per task","1").option("--output <format>","text | json","text").action(async e=>{let{runBenchmarkCommand:t}=await Promise.resolve().then(()=>(Bn(),Wn));console.log(await t({projectRoot:e.project,suite:e.suite,rounds:parseInt(e.rounds,10),output:e.output}));});Ns.command("report").description("Render a persisted benchmark report").option("--run-id <id>","Specific report; defaults to latest").option("--baseline <id>","Prior report used for regression comparison").option("--output <format>","text | json | markdown","text").action(async e=>{let{reportBenchmarkCommand:t}=await Promise.resolve().then(()=>(Bn(),Wn));console.log(await t({runId:e.runId,baselineRunId:e.baseline,output:e.output}));});E.command("review [pr-url]").description("Review a PR or current branch diff").option("--agent <agent>","AI agent to use","claude").action(async(e,t)=>{let{runReview:n}=await Promise.resolve().then(()=>(cs(),as)),o=await n({prUrl:e,agent:t.agent});console.log(o);});var Vn=E.command("server").description("Manage DevFlow server");Vn.command("start").description("Start the DevFlow REST server").option("--port <n>","Port number","13337").action(async e=>{console.log(S.blue("Starting DevFlow server..."));let{startServer:t}=await Promise.resolve().then(()=>(we(),Pt)),n=await t({port:parseInt(e.port,10)});console.log(S.green(`Server started (pid: ${n.pid}) on port ${e.port}`));});Vn.command("stop").description("Stop the DevFlow REST server").action(async()=>{let{stopServer:e}=await Promise.resolve().then(()=>(we(),Pt)),t=await e();console.log(t?S.green("Server stopped"):S.dim("No server running"));});Vn.command("status").description("Show server status").action(async()=>{let{serverStatus:e}=await Promise.resolve().then(()=>(we(),Pt)),t=await e();t.running?console.log(S.green(`Running (pid: ${t.pid})`)):console.log(S.yellow("Not running"));});E.command("dashboard").description("Open DevFlow Dashboard").action(()=>{console.log(S.blue("The Dashboard is served by the DevFlow server.")),console.log(S.dim("Run: devflow start")),console.log(S.dim("Then open: http://localhost:13337"));});E.command("start").description("Start DevFlow server (API + Dashboard)").option("--port <n>","Server port","13337").option("-d, --background","Run in background (detached)").action(async e=>{let{startAll:t}=await Promise.resolve().then(()=>(us(),ls));await t({port:parseInt(e.port,10),background:!!e.background});});E.command("stop").description("Stop DevFlow server").action(async()=>{let{stopAll:e}=await Promise.resolve().then(()=>(fs(),gs));await e();});E.command("status").description("Show DevFlow services status").action(async()=>{let{showStatus:e}=await Promise.resolve().then(()=>(hs(),ps));await e();});E.command("setup").description("Configure DevFlow for a supported agent host").option("--agent <agent>","Target host (claude-code/codex/generic-mcp)").option("--skip-mcp","Skip MCP configuration").option("--skip-plugin","Skip plugin registration").action(async e=>{let{setupCommand:t}=await Promise.resolve().then(()=>(vs(),ys));await t({agent:e.agent,skipMcp:!!e.skipMcp,skipPlugin:!!e.skipPlugin});});var Mt=E.command("plugin").description("Manage DevFlow plugins");if(process.argv.includes("plugin")){let[{pluginListCommand:e},{pluginSearchCommand:t},{pluginInstallCommand:n},{pluginUninstallCommand:o}]=await Promise.all([Promise.resolve().then(()=>(ws(),ks)),Promise.resolve().then(()=>(Ss(),bs)),Promise.resolve().then(()=>(Es(),Ps)),Promise.resolve().then(()=>(Ds(),Rs))]);Mt.addCommand(e),Mt.addCommand(t),Mt.addCommand(n),Mt.addCommand(o);}await E.parseAsync();
|