daimon 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +48 -1
  3. package/dist/cli.js +91 -86
  4. package/dist/dashboard/browser/chunk-3EPFSBJ2.js +2 -0
  5. package/dist/dashboard/browser/{chunk-PJPGLT4T.js → chunk-3ZFFKHPU.js} +1 -1
  6. package/dist/dashboard/browser/{chunk-QSBOKS53.js → chunk-4KVYA2AQ.js} +1 -1
  7. package/dist/dashboard/browser/chunk-55AO3FMG.js +1 -0
  8. package/dist/dashboard/browser/{chunk-V2KNRAE4.js → chunk-66VYPESU.js} +1 -1
  9. package/dist/dashboard/browser/chunk-6MTVWBQQ.js +2 -0
  10. package/dist/dashboard/browser/chunk-6Z4FDREI.js +1 -0
  11. package/dist/dashboard/browser/{chunk-7NPLP3QD.js → chunk-7LKM244H.js} +1 -1
  12. package/dist/dashboard/browser/chunk-ACPSBF55.js +1 -0
  13. package/dist/dashboard/browser/{chunk-OHX55ZU4.js → chunk-AGN2F6JP.js} +1 -1
  14. package/dist/dashboard/browser/chunk-B2DPS6BL.js +1 -0
  15. package/dist/dashboard/browser/{chunk-3WKRVGPT.js → chunk-BBTQXZIS.js} +1 -1
  16. package/dist/dashboard/browser/chunk-CIQNXWDY.js +1 -0
  17. package/dist/dashboard/browser/chunk-EBGPIJ7S.js +1 -0
  18. package/dist/dashboard/browser/{chunk-LBRCWYRN.js → chunk-F3FCHBFQ.js} +1 -1
  19. package/dist/dashboard/browser/chunk-FD3BW2ZN.js +1 -0
  20. package/dist/dashboard/browser/chunk-FRKUCFVI.js +1 -0
  21. package/dist/dashboard/browser/chunk-FZLMX6EY.js +1 -0
  22. package/dist/dashboard/browser/chunk-GMEW64AS.js +1 -0
  23. package/dist/dashboard/browser/chunk-HXX2OUOE.js +1 -0
  24. package/dist/dashboard/browser/chunk-HZNVO3JE.js +1 -0
  25. package/dist/dashboard/browser/chunk-JWXROQJJ.js +2 -0
  26. package/dist/dashboard/browser/chunk-K2SFF47Z.js +5 -0
  27. package/dist/dashboard/browser/chunk-K5WKBG55.js +1 -0
  28. package/dist/dashboard/browser/chunk-K6PUQAFE.js +2 -0
  29. package/dist/dashboard/browser/{chunk-NDSAQ2HK.js → chunk-KRC72WWY.js} +1 -1
  30. package/dist/dashboard/browser/{chunk-H3L4MTG4.js → chunk-LBWOIG7N.js} +1 -1
  31. package/dist/dashboard/browser/chunk-NVL5HFLU.js +1 -0
  32. package/dist/dashboard/browser/chunk-O76B43BY.js +4 -0
  33. package/dist/dashboard/browser/{chunk-EIWOTZT3.js → chunk-PRLUGTKR.js} +1 -1
  34. package/dist/dashboard/browser/chunk-QYIYT4YU.js +1 -0
  35. package/dist/dashboard/browser/{chunk-UC3XMN2Y.js → chunk-R7VSXL63.js} +1 -1
  36. package/dist/dashboard/browser/{chunk-7NRE3SNA.js → chunk-RNUJZTKS.js} +1 -1
  37. package/dist/dashboard/browser/{chunk-2BXIFQGQ.js → chunk-RWXAGDGT.js} +1 -1
  38. package/dist/dashboard/browser/chunk-RXOAYCKI.js +2 -0
  39. package/dist/dashboard/browser/chunk-SR4HVFOB.js +2 -0
  40. package/dist/dashboard/browser/chunk-TGSV7ZHM.js +2 -0
  41. package/dist/dashboard/browser/chunk-UC7AWK4C.js +2 -0
  42. package/dist/dashboard/browser/chunk-UUJWPV5O.js +3 -0
  43. package/dist/dashboard/browser/chunk-VHALTUPL.js +2 -0
  44. package/dist/dashboard/browser/{chunk-6WZJCF24.js → chunk-VMW35ZNT.js} +1 -1
  45. package/dist/dashboard/browser/{chunk-Q772THBA.js → chunk-WOMCRDMJ.js} +1 -2
  46. package/dist/dashboard/browser/chunk-WRX32YWH.js +1 -0
  47. package/dist/dashboard/browser/chunk-X4RGWMLE.js +4 -0
  48. package/dist/dashboard/browser/{chunk-P5IU57TV.js → chunk-YHBNUNU3.js} +1 -1
  49. package/dist/dashboard/browser/index.html +1 -1
  50. package/dist/dashboard/browser/main-YAROJLJV.js +1 -0
  51. package/dist/main.js +49 -48
  52. package/dist/mcp.js +3 -3
  53. package/package.json +6 -3
  54. package/dist/dashboard/browser/chunk-44JIQO3X.js +0 -1
  55. package/dist/dashboard/browser/chunk-4BAKWDAV.js +0 -1
  56. package/dist/dashboard/browser/chunk-4OCNYL7T.js +0 -1
  57. package/dist/dashboard/browser/chunk-7C772RJ3.js +0 -3
  58. package/dist/dashboard/browser/chunk-A4BNXJUT.js +0 -1
  59. package/dist/dashboard/browser/chunk-CILFSVSP.js +0 -2
  60. package/dist/dashboard/browser/chunk-CM4RQF3A.js +0 -5
  61. package/dist/dashboard/browser/chunk-CNSXWFDX.js +0 -1
  62. package/dist/dashboard/browser/chunk-CY5YRTQK.js +0 -1
  63. package/dist/dashboard/browser/chunk-GYWEXV2L.js +0 -3
  64. package/dist/dashboard/browser/chunk-H2N3RBHF.js +0 -1
  65. package/dist/dashboard/browser/chunk-I65I7J5Q.js +0 -2
  66. package/dist/dashboard/browser/chunk-K43KW4K2.js +0 -4
  67. package/dist/dashboard/browser/chunk-K7S4ITPJ.js +0 -2
  68. package/dist/dashboard/browser/chunk-KL6X73FV.js +0 -1
  69. package/dist/dashboard/browser/chunk-KLH6B22T.js +0 -1
  70. package/dist/dashboard/browser/chunk-LBL7Z5BE.js +0 -5
  71. package/dist/dashboard/browser/chunk-LHAMBNO6.js +0 -1
  72. package/dist/dashboard/browser/chunk-NX6DTO32.js +0 -1
  73. package/dist/dashboard/browser/chunk-P5IE6DI6.js +0 -2
  74. package/dist/dashboard/browser/chunk-VM2FOT77.js +0 -1
  75. package/dist/dashboard/browser/chunk-Y6B6X4Y6.js +0 -2
  76. package/dist/dashboard/browser/chunk-YYAZGY5M.js +0 -1
  77. package/dist/dashboard/browser/main-4CQTBXSB.js +0 -1
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- var yi=Object.defineProperty;var F=(n,t)=>()=>(n&&(t=n(n=0)),t);var yt=(n,t)=>{for(var e in t)yi(n,e,{get:t[e],enumerable:!0})};var wr={};yt(wr,{configLookupPaths:()=>Lt,loadConfig:()=>st,validateConfig:()=>ve});import xt from"node:fs";import kt from"node:path";import pe from"node:os";import{fileURLToPath as wi}from"node:url";function yr(){return{searchRoots:[],portRange:[4200,4299],apiPort:4999,overrides:{},autoStart:[],profiles:{},tags:{},autoRestart:{enabled:!1,maxAttempts:5,windowMs:3e5},healthProbe:{enabled:!0,intervalMs:3e4,timeoutMs:2e3,path:"/",host:null,scheme:null,rejectUnauthorized:!1,fallbackHosts:["127.0.0.1","::1"]},logs:{enabled:!1,dir:kt.join(pe.homedir(),".daimon","logs"),maxFiles:5,maxBytesPerFile:1e7},depends:{},cascadeRestart:!1,history:{enabled:!0,path:kt.join(pe.homedir(),".daimon","history.db"),retentionDays:30},notifications:{enabled:!0,onError:!0,onUnhealthy:!0,tray:!1},staleDetect:{enabled:!0,silentMs:3e4},headless:!1,envFiles:{},requestLog:{enabled:!1,portOffset:1e3},metrics:{enabled:!1},editor:{scheme:"vscode"},apiToken:null,output:{format:"compact",ndjson:!1},doctor:{autoFix:{onInit:!1,permitted:["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root"]}},dashboard:{theme:"auto",density:"comfortable"},errorRetention:{maxAgeMs:864e5},plugins:{dir:null}}}function un(n){return n.startsWith("~/")||n.startsWith("~\\")?kt.join(pe.homedir(),n.slice(2)):n==="~"?pe.homedir():n}function ve(n,t){return pn(n,t)}function pn(n,t){if(!n||typeof n!="object")throw new Error(`Config at ${t} is not a JSON object`);let e=n,r=yr();if(e.searchRoots!==void 0){if(!Array.isArray(e.searchRoots)||!e.searchRoots.every(s=>typeof s=="string"||s&&typeof s=="object"&&typeof s.path=="string"))throw new Error(`Config "searchRoots" must be an array of strings or { path, viteSubfolders? } objects (${t})`);r.searchRoots=e.searchRoots}if(e.portRange!==void 0){if(!Array.isArray(e.portRange)||e.portRange.length!==2||typeof e.portRange[0]!="number"||typeof e.portRange[1]!="number"||e.portRange[0]>e.portRange[1])throw new Error(`Config "portRange" must be [min, max] numbers (${t})`);r.portRange=[e.portRange[0],e.portRange[1]]}if(e.apiPort!==void 0){if(typeof e.apiPort!="number")throw new Error(`Config "apiPort" must be a number (${t})`);r.apiPort=e.apiPort}if(e.overrides!==void 0){if(typeof e.overrides!="object"||e.overrides===null||Array.isArray(e.overrides))throw new Error(`Config "overrides" must be an object (${t})`);r.overrides=e.overrides}if(e.autoStart!==void 0){if(!Array.isArray(e.autoStart)||!e.autoStart.every(s=>typeof s=="string"))throw new Error(`Config "autoStart" must be an array of strings (${t})`);r.autoStart=e.autoStart}if(e.profiles!==void 0){if(typeof e.profiles!="object"||e.profiles===null||Array.isArray(e.profiles))throw new Error(`Config "profiles" must be an object (${t})`);for(let[s,o]of Object.entries(e.profiles))if(!Array.isArray(o)||!o.every(i=>typeof i=="string"))throw new Error(`Config "profiles.${s}" must be an array of strings (${t})`);r.profiles=e.profiles}if(e.tags!==void 0){if(typeof e.tags!="object"||e.tags===null||Array.isArray(e.tags))throw new Error(`Config "tags" must be an object (${t})`);r.tags=e.tags}if(e.autoRestart&&typeof e.autoRestart=="object"&&(r.autoRestart={...r.autoRestart,...e.autoRestart}),e.healthProbe&&typeof e.healthProbe=="object"&&(r.healthProbe={...r.healthProbe,...e.healthProbe}),e.logs&&typeof e.logs=="object"&&(r.logs={...r.logs,...e.logs},r.logs.dir=un(r.logs.dir)),e.depends&&typeof e.depends=="object"&&!Array.isArray(e.depends)){for(let[s,o]of Object.entries(e.depends))if(!Array.isArray(o)||!o.every(i=>typeof i=="string"))throw new Error(`Config "depends.${s}" must be an array of strings (${t})`);r.depends=e.depends}if(typeof e.cascadeRestart=="boolean"&&(r.cascadeRestart=e.cascadeRestart),e.history&&typeof e.history=="object"&&(r.history={...r.history,...e.history},r.history.path=un(r.history.path)),e.notifications&&typeof e.notifications=="object"&&(r.notifications={...r.notifications,...e.notifications}),e.staleDetect&&typeof e.staleDetect=="object"&&(r.staleDetect={...r.staleDetect,...e.staleDetect}),typeof e.headless=="boolean"&&(r.headless=e.headless),e.envFiles&&typeof e.envFiles=="object"&&!Array.isArray(e.envFiles)&&(r.envFiles=e.envFiles),e.requestLog&&typeof e.requestLog=="object"&&(r.requestLog={...r.requestLog,...e.requestLog}),e.metrics&&typeof e.metrics=="object"&&(r.metrics={...r.metrics,...e.metrics}),e.editor&&typeof e.editor=="object"){let s=e.editor.scheme;typeof s=="string"&&s.trim()&&(r.editor={scheme:s.trim()})}if((typeof e.apiToken=="string"||e.apiToken===null)&&(r.apiToken=e.apiToken),e.output&&typeof e.output=="object"){let s=e.output;(s.format==="compact"||s.format==="full")&&(r.output.format=s.format),typeof s.ndjson=="boolean"&&(r.output.ndjson=s.ndjson)}if(e.doctor&&typeof e.doctor=="object"){let s=e.doctor.autoFix;s&&typeof s=="object"&&(typeof s.onInit=="boolean"&&(r.doctor.autoFix.onInit=s.onInit),Array.isArray(s.permitted)&&(r.doctor.autoFix.permitted=s.permitted.filter(o=>typeof o=="string")))}if(e.dashboard&&typeof e.dashboard=="object"){let s=e.dashboard;(s.theme==="auto"||s.theme==="light"||s.theme==="dark")&&(r.dashboard.theme=s.theme),(s.density==="comfortable"||s.density==="compact")&&(r.dashboard.density=s.density)}if(e.errorRetention&&typeof e.errorRetention=="object"){let s=e.errorRetention;typeof s.maxAgeMs=="number"&&s.maxAgeMs>0&&(r.errorRetention.maxAgeMs=s.maxAgeMs)}if(e.plugins&&typeof e.plugins=="object"){let s=e.plugins;typeof s.dir=="string"&&s.dir.trim()?r.plugins.dir=un(s.dir):s.dir===null&&(r.plugins.dir=null)}return r}function Lt(){return{local:kt.join(process.cwd(),"daimon.config.json"),user:kt.join(pe.homedir(),".daimon","config.json")}}function st(){let{local:n,user:t}=Lt();if(xt.existsSync(n)){let s=JSON.parse(xt.readFileSync(n,"utf8"));return{kind:"loaded",config:pn(s,n),path:n}}if(xt.existsSync(t)){let s=JSON.parse(xt.readFileSync(t,"utf8"));return{kind:"loaded",config:pn(s,t),path:t}}let r=[kt.resolve(gr,"..","daimon.config.example.json"),kt.resolve(gr,"..","..","daimon.config.example.json")].find(s=>xt.existsSync(s));return xt.mkdirSync(kt.dirname(t),{recursive:!0}),r?xt.copyFileSync(r,t):xt.writeFileSync(t,JSON.stringify(yr(),null,2)+`
3
- `,"utf8"),{kind:"stub-created",path:t}}var bi,gr,Xt=F(()=>{"use strict";bi=wi(import.meta.url),gr=kt.dirname(bi)});var hn={};yt(hn,{discoverApps:()=>It});import lt from"node:fs";import Q from"node:path";import dn from"fast-glob";function br(n){try{return JSON.parse(lt.readFileSync(n,"utf8"))}catch{return null}}function vr(n){return!n||typeof n!="object"?!1:!!(n.targets?.serve||n.architect?.serve)}function Sr(n){if(!n||typeof n!="object")return[];let t=n.targets??n.architect??{};return Object.keys(t).filter(e=>e!=="serve").sort()}function fn(n){return n.replace(/\\/g,"/")}function Kt(n,t){n&&(n.rejected[t]=(n.rejected[t]??0)+1)}function mn(n,t){try{return t.test(lt.readFileSync(n,"utf8"))}catch{return!1}}function vi(n,t,e){let r=Q.basename(n),s=!1,o=Q.join(n,"manage.py");if(lt.existsSync(o)&&mn(o,/\bdjango\b/i)){let y=r;e.has(y)||e.set(y,{name:y,workspaceRoot:n,workspaceType:"polyglot",serverProfile:"django",command:"python manage.py runserver",hidden:!1,tags:[],workspaceLabel:t}),s=!0}let i=Q.join(n,"bin","rails"),a=Q.join(n,"Gemfile");if(lt.existsSync(i)&&lt.existsSync(a)){let y=r;e.has(y)||e.set(y,{name:y,workspaceRoot:n,workspaceType:"polyglot",serverProfile:"rails",command:"bin/rails server",hidden:!1,tags:[],workspaceLabel:t}),s=!0}let l=Q.join(n,"pyproject.toml"),c=Q.join(n,"requirements.txt");(lt.existsSync(l)&&mn(l,/\bfastapi\b/i)||lt.existsSync(c)&&mn(c,/\bfastapi\b/i))&&!e.has(r)&&(e.set(r,{name:r,workspaceRoot:n,workspaceType:"polyglot",serverProfile:"fastapi",command:"uvicorn main:app --reload",hidden:!1,tags:[],workspaceLabel:t}),s=!0),(lt.existsSync(Q.join(n,".air.toml"))||lt.existsSync(Q.join(n,"air.toml")))&&!e.has(r)&&(e.set(r,{name:r,workspaceRoot:n,workspaceType:"polyglot",serverProfile:"go-air",command:"air",hidden:!1,tags:[],workspaceLabel:t}),s=!0);let g=Q.join(n,"Trunk.toml");return lt.existsSync(g)&&!e.has(r)&&(e.set(r,{name:r,workspaceRoot:n,workspaceType:"polyglot",serverProfile:"rust-trunk",command:"trunk serve",hidden:!1,tags:[],workspaceLabel:t}),s=!0),s}function It(n,t={}){let e=new Map,r=t.warnings??[],s=t.warnings===void 0;for(let o of n.searchRoots){let i=typeof o=="string"?o:o.path,a=typeof o=="string"?!1:!!o.viteSubfolders,l=typeof o=="string"?void 0:o.label,c=Q.resolve(i);if(!lt.existsSync(c)){r.push(`searchRoot does not exist: ${c}`),Kt(t.stats,"searchRoot missing");continue}let d=Q.join(c,"nx.json"),u=Q.join(c,"angular.json");if(lt.existsSync(d)){let m=dn.sync("**/project.json",{cwd:fn(c),ignore:["**/node_modules/**","**/dist/**","**/.nx/**","**/.git/**"],absolute:!0,dot:!1});for(let h of m){t.stats&&(t.stats.scanned+=1);let f=br(h);if(!f){Kt(t.stats,"unreadable project.json");continue}if(!vr(f)){Kt(t.stats,"no serve target");continue}let w=f.name||Q.basename(Q.dirname(h));if(!w){Kt(t.stats,"project has no name");continue}if(e.has(w)){r.push(`duplicate project name "${w}" \u2014 keeping first`),Kt(t.stats,"duplicate name");continue}e.set(w,{name:w,workspaceRoot:c,workspaceType:"nx",serverProfile:"nx",command:`npx nx serve ${w}`,hidden:!1,tags:[],tasks:Sr(f),workspaceLabel:l})}continue}if(lt.existsSync(u)){let h=br(u)?.projects||{};for(let[f,w]of Object.entries(h))if(vr(w)){if(e.has(f)){r.push(`duplicate project name "${f}" \u2014 keeping first`);continue}e.set(f,{name:f,workspaceRoot:c,workspaceType:"angular",serverProfile:"angular",command:`npx ng serve ${f}`,hidden:!1,tags:[],tasks:Sr(w),workspaceLabel:l})}continue}let g=dn.sync("vite.config.{ts,js,mjs,cjs}",{cwd:fn(c),absolute:!0,deep:1}),y=lt.existsSync(Q.join(c,".storybook")),p=!1;if(g.length>0){let m=Q.basename(c);if(e.has(m)||e.set(m,{name:m,workspaceRoot:c,workspaceType:"vite",serverProfile:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:l}),p=!0,a){let h=dn.sync("*/vite.config.{ts,js,mjs,cjs}",{cwd:fn(c),absolute:!0});for(let f of h){let w=Q.dirname(f),T=Q.basename(w);T===m||e.has(T)||e.set(T,{name:T,workspaceRoot:w,workspaceType:"vite",serverProfile:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:l})}}}if(y){let m=`${Q.basename(c)}-storybook`;e.has(m)||e.set(m,{name:m,workspaceRoot:c,workspaceType:"storybook",serverProfile:"storybook",command:"npx storybook dev --no-open",hidden:!1,tags:[],workspaceLabel:l}),p=!0}p||vi(c,l,e)||(r.push(`searchRoot has none of nx.json/angular.json/vite.config.*/.storybook/polyglot markers: ${c}`),Kt(t.stats,"no project markers"))}for(let[o,i]of Object.entries(n.overrides||{})){let a=e.get(o);a?(i.command&&(a.command=i.command),typeof i.hidden=="boolean"&&(a.hidden=i.hidden),typeof i.port=="number"&&(a.pinnedPort=i.port),i.env&&(a.env=i.env)):i.command&&e.set(o,{name:o,workspaceRoot:process.cwd(),workspaceType:"nx",command:i.command,hidden:i.hidden??!1,pinnedPort:i.port,env:i.env,tags:[]})}for(let o of e.values())o.tags=n.tags?.[o.name]??[];if(s&&r.length)for(let o of r)process.stderr.write(`[daimon] warning: ${o}
4
- `);return[...e.values()].filter(o=>!o.hidden)}var zt=F(()=>{"use strict"});function Se(n){let s=new Map,o=new Map,i=null,a=l=>{if(!i){s.set(l,1);for(let c of n[l]||[]){let d=s.get(c)??0;if(d===1){let u=[c,l],g=o.get(l);for(;g&&g!==c;)u.push(g),g=o.get(g);g===c&&u.push(c),i=u.reverse();return}if(d===0&&(o.set(c,l),a(c),i))return}s.set(l,2)}};for(let l of Object.keys(n))if((s.get(l)??0)===0&&(o.set(l,null),a(l),i))return i;return null}function ke(n,t){let e=new Set,r=[t];for(;r.length;){let s=r.pop();if(!e.has(s)){e.add(s);for(let o of n[s]||[])r.push(o)}}return[...e]}function xe(n,t){let e=new Set(t),r=new Map,s=new Map;for(let a of t)r.set(a,0),s.set(a,[]);for(let a of t)for(let l of n[a]||[])e.has(l)&&(s.get(l).push(a),r.set(a,(r.get(a)??0)+1));let o=[],i=t.filter(a=>(r.get(a)??0)===0);for(;i.length;){o.push([...i].sort());let a=[];for(let l of i)for(let c of s.get(l)??[])r.set(c,(r.get(c)??1)-1),r.get(c)===0&&a.push(c);i=a}return o}function kr(n,t){let e=[];for(let[r,s]of Object.entries(n))s.includes(t)&&e.push(r);return e}var de=F(()=>{"use strict"});import Si from"node:net";function Tt(n){return new Promise(t=>{let e=Si.createServer();e.unref(),e.once("error",()=>t(!1)),e.listen({port:n,host:"127.0.0.1",exclusive:!0},()=>{e.close(()=>t(!0))})})}var Yt,fe=F(()=>{"use strict";Yt=class{assigned=new Map;min;max;onChange;constructor(t,e={}){if(this.min=t[0],this.max=t[1],this.onChange=e.onChange,e.initial){let r=new Set;for(let[s,o]of Object.entries(e.initial))typeof o=="number"&&(o<this.min||o>this.max||r.has(o)||(r.add(o),this.assigned.set(s,o)))}}snapshot(){return Object.fromEntries(this.assigned)}getAssigned(t){return this.assigned.get(t)}pin(t,e){this.assigned.set(t,e),this.onChange?.(this.snapshot())}async allocate(t,e){let r=this.assigned.get(t);if(e!==void 0)return this.assigned.set(t,e),this.onChange?.(this.snapshot()),e;if(r!==void 0)return r;let s=new Set(this.assigned.values());for(let o=this.min;o<=this.max;o++){if(s.has(o))continue;if(await Tt(o))return this.assigned.set(t,o),this.onChange?.(this.snapshot()),o}throw new Error(`No free ports in range ${this.min}-${this.max}`)}async isPortAvailableForUse(t){return Tt(t)}}});import ki from"node:fs";import xi from"node:path";import{createRequire as Ti}from"node:module";var Ci,Ei,Pi,Ri,Ct,Te=F(()=>{"use strict";Ci=Ti(import.meta.url),Ei=200,Pi=360*60*1e3,Ri=1e4,Ct=class{constructor(t){this.cfg=t;if(t.enabled)try{ki.mkdirSync(xi.dirname(t.path),{recursive:!0});let e=Ci("better-sqlite3");this.db=new e(t.path),this.db.pragma("journal_mode = WAL"),this.migrate(),this.flushTimer=setInterval(()=>this.flush(),Ei),this.retentionStart=setTimeout(()=>this.runRetention(),Ri),this.retentionTimer=setInterval(()=>this.runRetention(),Pi)}catch(e){this.warnOnce(`failed to open history db: ${e?.message||e}`),this.db=null}}cfg;db=null;queue=[];flushTimer=null;retentionTimer=null;retentionStart=null;warned=!1;warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] history: ${t}
2
+ var Oi=Object.defineProperty;var U=(n,t)=>()=>(n&&(t=n(n=0)),t);var kt=(n,t)=>{for(var e in t)Oi(n,e,{get:t[e],enumerable:!0})};var Or={};kt(Or,{configLookupPaths:()=>$t,loadConfig:()=>at,validateConfig:()=>je});import Nt from"node:fs";import At from"node:path";import Se from"node:os";import{fileURLToPath as Ni}from"node:url";function Ar(){return{searchRoots:[],portRange:[4200,4299],apiPort:4999,overrides:{},autoStart:[],profiles:{},tags:{},autoRestart:{enabled:!1,maxAttempts:5,windowMs:3e5},healthProbe:{enabled:!0,intervalMs:3e4,timeoutMs:2e3,path:"/",host:null,scheme:null,rejectUnauthorized:!1,fallbackHosts:["127.0.0.1","::1"]},logs:{enabled:!1,dir:At.join(Se.homedir(),".daimon","logs"),maxFiles:5,maxBytesPerFile:1e7},depends:{},cascadeRestart:!1,history:{enabled:!0,path:At.join(Se.homedir(),".daimon","history.db"),retentionDays:30},notifications:{enabled:!0,onError:!0,onUnhealthy:!0,tray:!1},staleDetect:{enabled:!0,silentMs:3e4},headless:!1,envFiles:{},requestLog:{enabled:!1,portOffset:1e3},metrics:{enabled:!1},editor:{scheme:"vscode"},apiToken:null,output:{format:"compact",ndjson:!1},doctor:{autoFix:{onInit:!1,permitted:["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root"]}},dashboard:{theme:"auto",density:"comfortable"},errorRetention:{maxAgeMs:864e5},plugins:{dir:null}}}function xn(n){return n.startsWith("~/")||n.startsWith("~\\")?At.join(Se.homedir(),n.slice(2)):n==="~"?Se.homedir():n}function je(n,t){return Tn(n,t)}function Tn(n,t){if(!n||typeof n!="object")throw new Error(`Config at ${t} is not a JSON object`);let e=n,r=Ar();if(e.searchRoots!==void 0){if(!Array.isArray(e.searchRoots)||!e.searchRoots.every(s=>typeof s=="string"||s&&typeof s=="object"&&typeof s.path=="string"))throw new Error(`Config "searchRoots" must be an array of strings or { path, viteSubfolders? } objects (${t})`);r.searchRoots=e.searchRoots}if(e.portRange!==void 0){if(!Array.isArray(e.portRange)||e.portRange.length!==2||typeof e.portRange[0]!="number"||typeof e.portRange[1]!="number"||e.portRange[0]>e.portRange[1])throw new Error(`Config "portRange" must be [min, max] numbers (${t})`);r.portRange=[e.portRange[0],e.portRange[1]]}if(e.apiPort!==void 0){if(typeof e.apiPort!="number")throw new Error(`Config "apiPort" must be a number (${t})`);r.apiPort=e.apiPort}if(e.overrides!==void 0){if(typeof e.overrides!="object"||e.overrides===null||Array.isArray(e.overrides))throw new Error(`Config "overrides" must be an object (${t})`);r.overrides=e.overrides}if(e.autoStart!==void 0){if(!Array.isArray(e.autoStart)||!e.autoStart.every(s=>typeof s=="string"))throw new Error(`Config "autoStart" must be an array of strings (${t})`);r.autoStart=e.autoStart}if(e.profiles!==void 0){if(typeof e.profiles!="object"||e.profiles===null||Array.isArray(e.profiles))throw new Error(`Config "profiles" must be an object (${t})`);for(let[s,o]of Object.entries(e.profiles))if(!Array.isArray(o)||!o.every(i=>typeof i=="string"))throw new Error(`Config "profiles.${s}" must be an array of strings (${t})`);r.profiles=e.profiles}if(e.tags!==void 0){if(typeof e.tags!="object"||e.tags===null||Array.isArray(e.tags))throw new Error(`Config "tags" must be an object (${t})`);r.tags=e.tags}if(e.autoRestart&&typeof e.autoRestart=="object"&&(r.autoRestart={...r.autoRestart,...e.autoRestart}),e.healthProbe&&typeof e.healthProbe=="object"&&(r.healthProbe={...r.healthProbe,...e.healthProbe}),e.logs&&typeof e.logs=="object"&&(r.logs={...r.logs,...e.logs},r.logs.dir=xn(r.logs.dir)),e.depends&&typeof e.depends=="object"&&!Array.isArray(e.depends)){for(let[s,o]of Object.entries(e.depends))if(!Array.isArray(o)||!o.every(i=>typeof i=="string"))throw new Error(`Config "depends.${s}" must be an array of strings (${t})`);r.depends=e.depends}if(typeof e.cascadeRestart=="boolean"&&(r.cascadeRestart=e.cascadeRestart),e.history&&typeof e.history=="object"&&(r.history={...r.history,...e.history},r.history.path=xn(r.history.path)),e.notifications&&typeof e.notifications=="object"&&(r.notifications={...r.notifications,...e.notifications}),e.staleDetect&&typeof e.staleDetect=="object"&&(r.staleDetect={...r.staleDetect,...e.staleDetect}),typeof e.headless=="boolean"&&(r.headless=e.headless),e.envFiles&&typeof e.envFiles=="object"&&!Array.isArray(e.envFiles)&&(r.envFiles=e.envFiles),e.requestLog&&typeof e.requestLog=="object"&&(r.requestLog={...r.requestLog,...e.requestLog}),e.metrics&&typeof e.metrics=="object"&&(r.metrics={...r.metrics,...e.metrics}),e.editor&&typeof e.editor=="object"){let s=e.editor.scheme;typeof s=="string"&&s.trim()&&(r.editor={scheme:s.trim()})}if((typeof e.apiToken=="string"||e.apiToken===null)&&(r.apiToken=e.apiToken),e.output&&typeof e.output=="object"){let s=e.output;(s.format==="compact"||s.format==="full")&&(r.output.format=s.format),typeof s.ndjson=="boolean"&&(r.output.ndjson=s.ndjson)}if(e.doctor&&typeof e.doctor=="object"){let s=e.doctor.autoFix;s&&typeof s=="object"&&(typeof s.onInit=="boolean"&&(r.doctor.autoFix.onInit=s.onInit),Array.isArray(s.permitted)&&(r.doctor.autoFix.permitted=s.permitted.filter(o=>typeof o=="string")))}if(e.dashboard&&typeof e.dashboard=="object"){let s=e.dashboard;(s.theme==="auto"||s.theme==="light"||s.theme==="dark")&&(r.dashboard.theme=s.theme),(s.density==="comfortable"||s.density==="compact")&&(r.dashboard.density=s.density)}if(e.errorRetention&&typeof e.errorRetention=="object"){let s=e.errorRetention;typeof s.maxAgeMs=="number"&&s.maxAgeMs>0&&(r.errorRetention.maxAgeMs=s.maxAgeMs)}if(e.plugins&&typeof e.plugins=="object"){let s=e.plugins;typeof s.dir=="string"&&s.dir.trim()?r.plugins.dir=xn(s.dir):s.dir===null&&(r.plugins.dir=null)}return r}function $t(){return{local:At.join(process.cwd(),"daimon.config.json"),user:At.join(Se.homedir(),".daimon","config.json")}}function at(){let{local:n,user:t}=$t();if(Nt.existsSync(n)){let s=JSON.parse(Nt.readFileSync(n,"utf8"));return{kind:"loaded",config:Tn(s,n),path:n}}if(Nt.existsSync(t)){let s=JSON.parse(Nt.readFileSync(t,"utf8"));return{kind:"loaded",config:Tn(s,t),path:t}}let r=[At.resolve(Er,"..","daimon.config.example.json"),At.resolve(Er,"..","..","daimon.config.example.json")].find(s=>Nt.existsSync(s));return Nt.mkdirSync(At.dirname(t),{recursive:!0}),r?Nt.copyFileSync(r,t):Nt.writeFileSync(t,JSON.stringify(Ar(),null,2)+`
3
+ `,"utf8"),{kind:"stub-created",path:t}}var $i,Er,ee=U(()=>{"use strict";$i=Ni(import.meta.url),Er=At.dirname($i)});var En={};kt(En,{discoverApps:()=>Ot});import ft from"node:fs";import rt from"node:path";import Pn from"fast-glob";function Nr(n){try{return JSON.parse(ft.readFileSync(n,"utf8"))}catch{return null}}function $r(n){return!n||typeof n!="object"?!1:!!(n.targets?.serve||n.architect?.serve)}function Mr(n){if(!n||typeof n!="object")return[];let t=n.targets??n.architect??{};return Object.keys(t).filter(e=>e!=="serve").sort()}function Cn(n){return n.replace(/\\/g,"/")}function ne(n,t){n&&(n.rejected[t]=(n.rejected[t]??0)+1)}function Mi(n,t,e,r){if(!n.has(t))return{key:t,collided:!1};if(n.get(t).workspaceRoot===r)return{key:t,collided:!0};let o=e||rt.basename(r),i=`${t}@${o}`,a=2;for(;n.has(i);)i=`${t}@${o}-${a++}`;return{key:i,collided:!1}}function Rn(n,t){try{return t.test(ft.readFileSync(n,"utf8"))}catch{return!1}}function xt(n,t,e){let{key:r,collided:s}=Mi(n,t,e.workspaceLabel,e.workspaceRoot);return s?!1:(n.set(r,{name:r,baseName:t,...e}),!0)}function ji(n,t,e){let r=rt.basename(n),s=!1,o=rt.join(n,"manage.py");ft.existsSync(o)&&Rn(o,/\bdjango\b/i)&&(xt(e,r,{workspaceRoot:n,workspaceType:"polyglot",serverProfile:"django",command:"python manage.py runserver",hidden:!1,tags:[],workspaceLabel:t}),s=!0);let i=rt.join(n,"bin","rails"),a=rt.join(n,"Gemfile");ft.existsSync(i)&&ft.existsSync(a)&&(xt(e,r,{workspaceRoot:n,workspaceType:"polyglot",serverProfile:"rails",command:"bin/rails server",hidden:!1,tags:[],workspaceLabel:t}),s=!0);let c=rt.join(n,"pyproject.toml"),l=rt.join(n,"requirements.txt");(ft.existsSync(c)&&Rn(c,/\bfastapi\b/i)||ft.existsSync(l)&&Rn(l,/\bfastapi\b/i))&&(xt(e,r,{workspaceRoot:n,workspaceType:"polyglot",serverProfile:"fastapi",command:"uvicorn main:app --reload",hidden:!1,tags:[],workspaceLabel:t}),s=!0),(ft.existsSync(rt.join(n,".air.toml"))||ft.existsSync(rt.join(n,"air.toml")))&&(xt(e,r,{workspaceRoot:n,workspaceType:"polyglot",serverProfile:"go-air",command:"air",hidden:!1,tags:[],workspaceLabel:t}),s=!0);let f=rt.join(n,"Trunk.toml");return ft.existsSync(f)&&(xt(e,r,{workspaceRoot:n,workspaceType:"polyglot",serverProfile:"rust-trunk",command:"trunk serve",hidden:!1,tags:[],workspaceLabel:t}),s=!0),s}function Ot(n,t={}){let e=new Map,r=t.warnings??[],s=t.warnings===void 0;for(let o of n.searchRoots){let i=typeof o=="string"?o:o.path,a=typeof o=="string"?!1:!!o.viteSubfolders,c=typeof o=="string"?void 0:o.label,l=rt.resolve(i);if(!ft.existsSync(l)){r.push(`searchRoot does not exist: ${l}`),ne(t.stats,"searchRoot missing");continue}let u=rt.join(l,"nx.json"),d=rt.join(l,"angular.json");if(ft.existsSync(u)){let R=Pn.sync("**/project.json",{cwd:Cn(l),ignore:["**/node_modules/**","**/dist/**","**/.nx/**","**/.git/**"],absolute:!0,dot:!1});for(let y of R){t.stats&&(t.stats.scanned+=1);let b=Nr(y);if(!b){ne(t.stats,"unreadable project.json");continue}if(!$r(b)){ne(t.stats,"no serve target");continue}let N=b.name||rt.basename(rt.dirname(y));if(!N){ne(t.stats,"project has no name");continue}xt(e,N,{workspaceRoot:l,workspaceType:"nx",serverProfile:"nx",command:`npx nx serve ${N}`,hidden:!1,tags:[],tasks:Mr(b),workspaceLabel:c})||(r.push(`duplicate project name "${N}" within ${l} \u2014 keeping first`),ne(t.stats,"duplicate name"))}continue}if(ft.existsSync(d)){let y=Nr(d)?.projects||{};for(let[b,N]of Object.entries(y)){if(!$r(N))continue;xt(e,b,{workspaceRoot:l,workspaceType:"angular",serverProfile:"angular",command:`npx ng serve ${b}`,hidden:!1,tags:[],tasks:Mr(N),workspaceLabel:c})||r.push(`duplicate project name "${b}" within ${l} \u2014 keeping first`)}continue}let f=Pn.sync("vite.config.{ts,js,mjs,cjs}",{cwd:Cn(l),absolute:!0,deep:1}),g=ft.existsSync(rt.join(l,".storybook")),C=!1;if(f.length>0){let R=rt.basename(l);if(xt(e,R,{workspaceRoot:l,workspaceType:"vite",serverProfile:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:c}),C=!0,a){let y=Pn.sync("*/vite.config.{ts,js,mjs,cjs}",{cwd:Cn(l),absolute:!0});for(let b of y){let N=rt.dirname(b),p=rt.basename(N);p!==R&&xt(e,p,{workspaceRoot:N,workspaceType:"vite",serverProfile:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:c})}}}if(g){let R=`${rt.basename(l)}-storybook`;xt(e,R,{workspaceRoot:l,workspaceType:"storybook",serverProfile:"storybook",command:"npx storybook dev --no-open",hidden:!1,tags:[],workspaceLabel:c}),C=!0}C||ji(l,c,e)||(r.push(`searchRoot has none of nx.json/angular.json/vite.config.*/.storybook/polyglot markers: ${l}`),ne(t.stats,"no project markers"))}for(let[o,i]of Object.entries(n.overrides||{})){let a=[...e.values()].filter(c=>(c.baseName??c.name)===o);if(a.length>0)for(let c of a)i.command&&(c.command=i.command),typeof i.hidden=="boolean"&&(c.hidden=i.hidden),typeof i.port=="number"&&(c.pinnedPort=i.port),i.env&&(c.env=i.env);else i.command&&e.set(o,{name:o,baseName:o,workspaceRoot:process.cwd(),workspaceType:"nx",command:i.command,hidden:i.hidden??!1,pinnedPort:i.port,env:i.env,tags:[]})}for(let o of e.values())o.tags=n.tags?.[o.baseName??o.name]??[];if(s&&r.length)for(let o of r)process.stderr.write(`[daimon] warning: ${o}
4
+ `);return[...e.values()].filter(o=>!o.hidden)}var qt=U(()=>{"use strict"});function _e(n){let s=new Map,o=new Map,i=null,a=c=>{if(!i){s.set(c,1);for(let l of n[c]||[]){let u=s.get(l)??0;if(u===1){let d=[l,c],f=o.get(c);for(;f&&f!==l;)d.push(f),f=o.get(f);f===l&&d.push(l),i=d.reverse();return}if(u===0&&(o.set(l,c),a(l),i))return}s.set(c,2)}};for(let c of Object.keys(n))if((s.get(c)??0)===0&&(o.set(c,null),a(c),i))return i;return null}function De(n,t){let e=new Set,r=[t];for(;r.length;){let s=r.pop();if(!e.has(s)){e.add(s);for(let o of n[s]||[])r.push(o)}}return[...e]}function Le(n,t){let e=new Set(t),r=new Map,s=new Map;for(let a of t)r.set(a,0),s.set(a,[]);for(let a of t)for(let c of n[a]||[])e.has(c)&&(s.get(c).push(a),r.set(a,(r.get(a)??0)+1));let o=[],i=t.filter(a=>(r.get(a)??0)===0);for(;i.length;){o.push([...i].sort());let a=[];for(let c of i)for(let l of s.get(c)??[])r.set(l,(r.get(l)??1)-1),r.get(l)===0&&a.push(l);i=a}return o}function jr(n,t){let e=[];for(let[r,s]of Object.entries(n))s.includes(t)&&e.push(r);return e}var ke=U(()=>{"use strict"});import _i from"node:net";function Mt(n){return new Promise(t=>{let e=_i.createServer();e.unref(),e.once("error",()=>t(!1)),e.listen({port:n,host:"127.0.0.1",exclusive:!0},()=>{e.close(()=>t(!0))})})}var re,xe=U(()=>{"use strict";re=class{assigned=new Map;min;max;onChange;constructor(t,e={}){if(this.min=t[0],this.max=t[1],this.onChange=e.onChange,e.initial){let r=new Set;for(let[s,o]of Object.entries(e.initial))typeof o=="number"&&(o<this.min||o>this.max||r.has(o)||(r.add(o),this.assigned.set(s,o)))}}snapshot(){return Object.fromEntries(this.assigned)}getAssigned(t){return this.assigned.get(t)}pin(t,e){this.assigned.set(t,e),this.onChange?.(this.snapshot())}async allocate(t,e){let r=this.assigned.get(t);if(e!==void 0)return this.assigned.set(t,e),this.onChange?.(this.snapshot()),e;if(r!==void 0)return r;let s=new Set(this.assigned.values());for(let o=this.min;o<=this.max;o++){if(s.has(o))continue;if(await Mt(o))return this.assigned.set(t,o),this.onChange?.(this.snapshot()),o}throw new Error(`No free ports in range ${this.min}-${this.max}`)}async isPortAvailableForUse(t){return Mt(t)}}});import Di from"node:fs";import Li from"node:path";import{createRequire as Ii}from"node:module";var Fi,Bi,Ui,Hi,jt,Ie=U(()=>{"use strict";Fi=Ii(import.meta.url),Bi=200,Ui=360*60*1e3,Hi=1e4,jt=class{constructor(t){this.cfg=t;if(t.enabled)try{Di.mkdirSync(Li.dirname(t.path),{recursive:!0});let e=Fi("better-sqlite3");this.db=new e(t.path),this.db.pragma("journal_mode = WAL"),this.migrate(),this.flushTimer=setInterval(()=>this.flush(),Bi),this.retentionStart=setTimeout(()=>this.runRetention(),Hi),this.retentionTimer=setInterval(()=>this.runRetention(),Ui)}catch(e){this.warnOnce(`failed to open history db: ${e?.message||e}`),this.db=null}}cfg;db=null;queue=[];flushTimer=null;retentionTimer=null;retentionStart=null;warned=!1;warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] history: ${t}
5
5
  `))}migrate(){this.db&&this.db.exec(`
6
6
  CREATE TABLE IF NOT EXISTS events (
7
7
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -48,107 +48,108 @@ var yi=Object.defineProperty;var F=(n,t)=>()=>(n&&(t=n(n=0)),t);var yt=(n,t)=>{f
48
48
  historyQueryP95Ms REAL NOT NULL
49
49
  );
50
50
  CREATE INDEX IF NOT EXISTS self_metrics_ts ON self_metrics(ts);
51
- `)}recordSelfMetric(t,e,r,s,o=Date.now()){if(this.db)try{this.db.prepare("INSERT INTO self_metrics (ts,rssMB,heapUsedMB,eventLoopLagMs,historyQueryP95Ms) VALUES (?,?,?,?,?)").run(o,t,e,r,s)}catch(i){this.warnOnce(`self_metrics write failed: ${i?.message||i}`)}}querySelfMetrics(t={}){if(!this.db)return[];let e=[],r=[];t.since!=null&&(e.push("ts >= ?"),r.push(t.since));let s=`SELECT ts, rssMB, heapUsedMB, eventLoopLagMs, historyQueryP95Ms FROM self_metrics ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??60),this.db.prepare(s).all(...r)}recordEvent(t){this.db&&this.queue.push({kind:"event",row:{ts:t.ts,app:t.app,type:t.type,from_state:t.from??null,to_state:t.to??null,message:t.message??null}})}recordCompile(t,e,r=Date.now()){this.db&&this.queue.push({kind:"compile",row:{ts:r,app:t,ms:e}})}recordBundle(t,e,r,s,o=Date.now()){this.db&&this.queue.push({kind:"bundle",row:{ts:o,app:t,initialKB:e,lazyKB:r,fileCount:s}})}recordTaskRun(t,e,r,s,o,i=Date.now()){this.db&&this.queue.push({kind:"task",row:{ts:i,app:t,task:e,exit_code:r,duration_ms:s,summary:o==null?null:JSON.stringify(o)}})}flush(){if(!this.db||this.queue.length===0)return;let t=this.queue;this.queue=[];try{let e=this.db.prepare("INSERT INTO events (ts,app,type,from_state,to_state,message) VALUES (?,?,?,?,?,?)"),r=this.db.prepare("INSERT INTO compile_times (ts,app,ms) VALUES (?,?,?)"),s=this.db.prepare("INSERT INTO task_runs (ts,app,task,exit_code,duration_ms,summary) VALUES (?,?,?,?,?,?)"),o=this.db.prepare("INSERT INTO bundles (ts,app,initialKB,lazyKB,fileCount) VALUES (?,?,?,?,?)");this.db.transaction(a=>{for(let l of a)l.kind==="event"?e.run(l.row.ts,l.row.app,l.row.type,l.row.from_state,l.row.to_state,l.row.message):l.kind==="compile"?r.run(l.row.ts,l.row.app,l.row.ms):l.kind==="bundle"?o.run(l.row.ts,l.row.app,l.row.initialKB,l.row.lazyKB,l.row.fileCount):s.run(l.row.ts,l.row.app,l.row.task,l.row.exit_code,l.row.duration_ms,l.row.summary)})(t)}catch(e){this.warnOnce(`history write failed: ${e?.message||e}`)}}runRetention(){if(this.db)try{let t=Date.now()-this.cfg.retentionDays*864e5;this.db.prepare("DELETE FROM events WHERE ts < ?").run(t),this.db.prepare("DELETE FROM compile_times WHERE ts < ?").run(t),this.db.prepare("DELETE FROM task_runs WHERE ts < ?").run(t),this.db.prepare("DELETE FROM bundles WHERE ts < ?").run(t),this.db.prepare("DELETE FROM self_metrics WHERE ts < ?").run(t)}catch(t){this.warnOnce(`retention failed: ${t?.message||t}`)}}queryEvents(t){if(!this.db)return[];let e=[],r=[];t.app&&(e.push("app = ?"),r.push(t.app)),t.since!=null&&(e.push("ts >= ?"),r.push(t.since)),t.until!=null&&(e.push("ts <= ?"),r.push(t.until)),t.type&&(e.push("type = ?"),r.push(t.type));let s=`SELECT * FROM events ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??500),this.db.prepare(s).all(...r)}queryCompiles(t){if(!this.db)return[];let e=[],r=[];t.app&&(e.push("app = ?"),r.push(t.app)),t.since!=null&&(e.push("ts >= ?"),r.push(t.since)),t.until!=null&&(e.push("ts <= ?"),r.push(t.until));let s=`SELECT * FROM compile_times ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??1e3),this.db.prepare(s).all(...r)}queryBundles(t){if(!this.db)return[];let e=[],r=[];t.app&&(e.push("app = ?"),r.push(t.app)),t.since!=null&&(e.push("ts >= ?"),r.push(t.since)),t.until!=null&&(e.push("ts <= ?"),r.push(t.until));let s=`SELECT * FROM bundles ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??1e3),this.db.prepare(s).all(...r)}trends(t){if(!this.db)return{points:[],count:0};let e=Date.now()-t.sinceMs,r=t.bucketMs,s=new Map,o=(d,u)=>{let g=Math.floor(d/r)*r,y=s.get(g)??{sum:0,n:0};y.sum+=u,y.n+=1,s.set(g,y)},i=d=>{let u=Math.floor(d/r)*r,g=s.get(u)??{sum:0,n:0};g.sum+=1,g.n+=1,s.set(u,g)},a=0;if(t.metric==="compile"){let d=this.queryCompiles({app:t.app,since:e,limit:1e4});a=d.length;for(let u of d)o(u.ts,u.ms)}else if(t.metric==="bundle"){let d=this.queryBundles({app:t.app,since:e,limit:1e4});a=d.length;for(let u of d){let g=Math.floor(u.ts/r)*r,y=s.get(g)??{sum:0,n:0,sum2:0};y.sum+=u.initialKB,y.sum2=(y.sum2??0)+u.lazyKB,y.n+=1,s.set(g,y)}}else if(t.metric==="errors"){let d=this.queryEvents({app:t.app,since:e,limit:1e4});for(let u of d)(u.type==="error-new"||u.type==="error-recur")&&(i(u.ts),a++)}else{let d=this.queryEvents({app:t.app,since:e,limit:1e4});for(let u of d)u.type==="status"&&u.to_state==="starting"&&(u.from_state==="error"||u.from_state==="serving"||u.from_state==="compiling")&&(i(u.ts),a++)}let l=[],c=[...s.entries()].sort((d,u)=>d[0]-u[0]);for(let[d,u]of c)t.metric==="compile"||t.metric==="bundle"?l.push({t:d,v:Math.round(u.sum/u.n),...u.sum2!=null?{v2:Math.round(u.sum2/u.n)}:{}}):l.push({t:d,v:u.sum});return{points:l,count:a}}queryTasks(t){if(!this.db)return[];let e=[],r=[];t.app&&(e.push("app = ?"),r.push(t.app)),t.task&&(e.push("task = ?"),r.push(t.task)),t.since!=null&&(e.push("ts >= ?"),r.push(t.since));let s=`SELECT * FROM task_runs ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??200),this.db.prepare(s).all(...r)}summary(t){if(!this.db)return{uptimePct24h:0,restartCount24h:0,compileP50:null,compileP95:null,topErrors:[]};let e=Date.now()-24*3600*1e3,r=this.queryEvents({app:t,since:e,limit:5e3}),s=0,o=e,i=!1,a=null,l=[...r].sort((f,w)=>f.ts-w.ts);for(let f of l)f.type==="status"&&(f.to_state==="serving"&&!i?(i=!0,a=f.ts):i&&f.to_state!=="serving"&&a!=null&&(s+=f.ts-a,i=!1,a=null));i&&a!=null&&(s+=Date.now()-a);let c=Math.round(s/(24*3600*1e3)*1e3)/10,d=r.filter(f=>f.type==="status"&&f.to_state==="starting"&&(f.from_state==="serving"||f.from_state==="error"||f.from_state==="compiling")).length,u=this.queryCompiles({app:t,since:e,limit:1e3}).map(f=>f.ms).sort((f,w)=>f-w),g=(f,w)=>{if(f.length===0)return null;let T=Math.min(f.length-1,Math.floor((f.length-1)*w));return f[T]},y=g(u,.5),p=g(u,.95),m=new Map;for(let f of r)if(f.type==="error-new"||f.type==="error-recur"){let w=f.message??"";if(!w)continue;m.set(w,(m.get(w)??0)+1)}let h=[...m.entries()].sort((f,w)=>w[1]-f[1]).slice(0,5).map(([f,w])=>({message:f,count:w}));return{uptimePct24h:c,restartCount24h:d,compileP50:y,compileP95:p,topErrors:h}}why(t){let e=this.queryEvents({app:t,limit:200}),r=e.find(a=>a.type==="status"&&(a.to_state==="error"||a.from_state==="error"||a.to_state==="serving")),s=r?{ts:r.ts,app:r.app,type:r.type,from:r.from_state??void 0,to:r.to_state??void 0,message:r.message??void 0}:null,o=s?s.ts:Date.now(),i=e.filter(a=>a.ts<o).slice(0,5);return{trigger:s,preceding:i.map(a=>({ts:a.ts,app:a.app,type:a.type,from:a.from_state??void 0,to:a.to_state??void 0,message:a.message??void 0}))}}_flushForTest(){this.flush()}quickCheck(){if(!this.db)return!1;try{return this.db.prepare("PRAGMA quick_check").get()?.quick_check==="ok"}catch{return!1}}close(){if(this.flushTimer&&clearInterval(this.flushTimer),this.retentionTimer&&clearInterval(this.retentionTimer),this.retentionStart&&clearTimeout(this.retentionStart),this.flush(),this.db){try{this.db.close()}catch{}this.db=null}}}});import{spawnSync as gn}from"node:child_process";import Tr from"tree-kill";function Ce(n){if(process.platform==="win32"){let o=gn("powershell",["-NoProfile","-Command",`Get-NetTCPConnection -LocalPort ${n} -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty OwningProcess`],{encoding:"utf8",windowsHide:!0});if(o.status!==0)return null;let i=Number((o.stdout||"").trim().split(/\s+/)[0]);if(!Number.isFinite(i)||i<=0)return null;let a=gn("powershell",["-NoProfile","-Command",`Get-CimInstance Win32_Process -Filter "ProcessId=${i}" | Select-Object -Property Name,CommandLine | ConvertTo-Json -Compress`],{encoding:"utf8",windowsHide:!0}),l,c;try{let d=JSON.parse((a.stdout||"").trim()||"{}");l=typeof d.Name=="string"?d.Name:void 0,c=typeof d.CommandLine=="string"?d.CommandLine:void 0}catch{}return{pid:i,name:l,cmd:c}}let t=gn("lsof",["-nP","-iTCP:"+n,"-sTCP:LISTEN"],{encoding:"utf8"});if(t.status!==0)return null;let e=(t.stdout||"").split(/\r?\n/).filter(o=>o.trim()&&!o.startsWith("COMMAND"));if(!e.length)return null;let r=e[0].split(/\s+/);return{pid:Number(r[1]),name:r[0]}}function Cr(n,t){if(!t)return`port ${n} already in use`;let e=[`port ${n} in use by`];return t.name&&e.push(t.name),e.push(`(pid ${t.pid}`),t.cmd&&(e[e.length-1]+=`, cmd: ${t.cmd.slice(0,120)}`),e[e.length-1]+=")",e.join(" ")}function Er(n){return new Promise(t=>{if(!n.pid||n.pid===process.pid){t(!1);return}Tr(n.pid,"SIGTERM",e=>{if(e){setTimeout(()=>Tr(n.pid,"SIGKILL",r=>t(!r)),500);return}t(!0)})})}var yn=F(()=>{"use strict"});import Ee from"node:fs";import Oi from"node:os";import Pr from"node:path";function Rr(n){return Ee.readFileSync(n,"utf8").split(/\r?\n/).filter(e=>e.trim()).map(e=>JSON.parse(e))}var Pe,wn=F(()=>{"use strict";Pe=class{file=null;startTs=0;isRecording(){return this.file!=null}start(){if(this.file)return{path:this.file};let t=Pr.join(Oi.homedir(),".daimon","sessions");Ee.mkdirSync(t,{recursive:!0});let e=Pr.join(t,`${new Date().toISOString().replace(/[:.]/g,"-")}.jsonl`);return Ee.writeFileSync(e,""),this.file=e,this.startTs=Date.now(),{path:e}}stop(){let t={path:this.file};return this.file=null,this.startTs=0,t}append(t){if(!this.file)return;let e=JSON.stringify({ts:Date.now()-this.startTs,...t})+`
52
- `;try{Ee.appendFileSync(this.file,e)}catch{}}}});import Ni from"node:fs";import bn from"node:path";import{fileURLToPath as Mi}from"node:url";function $i(){let n=[bn.resolve(Ar,"..","package.json"),bn.resolve(Ar,"..","..","package.json")];for(let t of n)try{return JSON.parse(Ni.readFileSync(t,"utf8"))}catch{}return{}}var Ar,Z,Et=F(()=>{"use strict";Ar=bn.dirname(Mi(import.meta.url));Z=$i().version||"0.0.0"});import Zt from"node:fs";import Re from"node:path";import ji from"node:os";import{spawn as _i}from"node:child_process";import{fileURLToPath as Di}from"node:url";function ut(){return Sn}function Ae(){return Qt}function vn(n){try{return process.kill(n,0),!0}catch(t){return t&&t.code==="EPERM"}}function ot(){try{let n=Zt.readFileSync(Qt,"utf8"),t=JSON.parse(n);if(!t||typeof t.pid!="number")return null;if(!vn(t.pid)){try{Zt.unlinkSync(Qt)}catch{}return null}return t}catch{return null}}function Or(n){Zt.mkdirSync(Sn,{recursive:!0});let t=Qt+"."+process.pid+".tmp";Zt.writeFileSync(t,JSON.stringify(n)),Zt.renameSync(t,Qt)}function wt(){try{Zt.unlinkSync(Qt)}catch{}}function Li(){let n=Re.dirname(Di(import.meta.url));return Re.join(n,"main.js")}async function Pt(n={}){let t={...process.env};n.port&&(t.DAIMON_PORT=String(n.port)),_i(process.execPath,[Li(),"--headless"],{detached:!0,stdio:"ignore",env:t,windowsHide:!0}).unref();let r=Date.now();for(;Date.now()-r<5e3;){let s=ot();if(s&&(!n.port||s.apiPort===n.port))return s;await new Promise(o=>setTimeout(o,100))}throw new Error("daemon failed to start within 5s")}async function Bt(n,t){let e=Date.now();for(;Date.now()-e<t;){if(!vn(n))return!0;await new Promise(r=>setTimeout(r,100))}return!vn(n)}function Nr(n,t,e){return{pid:process.pid,apiPort:n,version:Z,startedAt:Date.now(),headless:t,cwd:process.cwd(),configPath:e}}var Sn,Qt,bt=F(()=>{"use strict";Et();Sn=Re.join(ji.homedir(),".daimon"),Qt=Re.join(Sn,"daemon.lock")});var Qr={};yt(Qr,{promptClaudeInstall:()=>Zi});import Jt,{useState as Vr}from"react";import{Box as Zr,render as Ki,Text as $e,useApp as zi,useInput as Yi}from"ink";function Vi({onDone:n}){let{exit:t}=zi(),[e,r]=Vr(0),[s,o]=Vr({skill:!0,commands:!1,agent:!0}),i=[{key:"skill",label:"Skill (~/.claude/skills/daimon/SKILL.md)"},{key:"agent",label:"Subagent (~/.claude/agents/daimon-runner.md)"}];return Yi((a,l)=>{if(l.escape||a==="q"&&!l.shift){n(null),t();return}if(l.upArrow)r(c=>Math.max(0,c-1));else if(l.downArrow)r(c=>Math.min(i.length-1,c+1));else if(a===" "){let c=i[e].key;o(d=>({...d,[c]:!d[c]}))}else l.return&&(n(s),t())}),Jt.createElement(Zr,{flexDirection:"column",paddingX:1},Jt.createElement($e,{bold:!0,color:"cyan"},"Install Claude Code integration artifacts"),Jt.createElement($e,{dimColor:!0},"Space toggles \xB7 Enter confirms \xB7 Esc cancels"),i.map((a,l)=>Jt.createElement(Zr,{key:a.key},Jt.createElement($e,{color:l===e?"cyan":void 0},l===e?"\u25B8 ":" "),Jt.createElement($e,null,"[",s[a.key]?"x":" ","] ",a.label))))}async function Zi(){return new Promise(n=>{let t=!1;Ki(Jt.createElement(Vi,{onDone:r=>{t||(t=!0,n(r))}})).waitUntilExit().then(()=>{t||(t=!0,n(null))})})}var ts=F(()=>{"use strict"});import Qi from"node:crypto";function da(n){for(let{tool:t,rx:e}of pa)if(e.test(n))return t}function Sa(n){return Qi.createHash("sha1").update(n).digest("hex").slice(0,16)}function ka(n){let t={message:n},e=n.match(sa)||n.match(ra);e&&(t.code=`TS${e[1]}`);let r=n.match(ia)||n.match(es)||n.match(oa);if(r)t.file=r[1],t.line=Number(r[2]),t.col=Number(r[3]);else{let o=n.match(la);if(o)t.file=o[1],o[2]&&(t.line=Number(o[2])),o[3]&&(t.col=Number(o[3]));else{let i=n.match(ca);if(i)t.file=i[1];else{let a=n.match(rs);if(a)t.file=a[1],t.line=Number(a[2]),t.col=Number(a[3]);else{let l=n.match(ns);l&&(t.file=l[1],t.line=Number(l[2]))}}}}let s=da(n);return s&&(t.tool=s),t}function xa(n,t){try{let e=new URL(n);return e.hostname==="0.0.0.0"||e.hostname==="[::]"?(e.hostname=t.includes(":")?`[${t}]`:t,e.toString().replace(/\/$/,"")):n.replace(/\/$/,"")}catch{return n}}function Ta(n,t="127.0.0.1"){let e=n.match(fa)||n.match(ma)||n.match(ha)||n.match(ga);if(!e)return null;let r=e[1].replace(/[),.;]+$/,"");return xa(r,t)}function Ca(n,t){if(ya.test(t))return n.bundle||(n.bundle={initialKB:0,lazyKB:0,files:[]}),n._bundleSection="initial",!1;if(wa.test(t))return n.bundle||(n.bundle={initialKB:0,lazyKB:0,files:[]}),n._bundleSection="lazy",!1;let e=t.match(ba);if(e&&n.bundle){let s=parseFloat(e[2]),o=e[3].toUpperCase(),i=Math.round(o==="MB"?s*1024:o==="B"?s/1024:s);return/Initial/i.test(e[1])?n.bundle.initialKB=i:n.bundle.lazyKB=i,!0}let r=t.match(va);if(r&&n.bundle){let s=r[1].trim();if(/^(Initial|Lazy)\s+(total|chunk)/i.test(s))return!1;let o=r[4].toUpperCase(),i=parseFloat(r[3]),a=o==="MB"?i*1024:o==="B"?i/1024:i;return n.bundle.files.push({name:s,sizeKB:Math.round(a*10)/10}),!1}return!1}function ss(n,t){let e=t.match(ua),r=e?null:t.match(es),s=!e&&!r?t.match(rs):null,o=e??r??s;if(o&&n.lastErrorHash){let p=n.errors.get(n.lastErrorHash);p&&!p.parsed?.file&&(p.parsed={...p.parsed??{message:p.message},file:o[1],line:Number(o[2]),col:Number(o[3])})}else if(n.lastErrorHash){let p=t.match(ns),m=p?null:t.match(aa);if(p||m){let h=n.errors.get(n.lastErrorHash);if(h&&!h.parsed?.file){let f=p??m;h.parsed={...h.parsed??{message:h.message},file:f[1],line:Number(f[2])}}}}let i=t.trim();if(!i)return null;let a=n.status,l=!1,c,d=Ta(i);d&&!n.announcedUrl&&(n.announcedUrl=d,c=d);let u=Ca(n,i),g;if(ta.some(p=>p.test(i))){let p=n.status==="error"||!!n.recoveringFromError;if(n.status==="compiling"||n.status==="starting"||n.status==="error"){let m=Date.now();n.compileStartedAt!=null?(g=m-n.compileStartedAt,n.lastCompileMs=g,n.lastCompileAt=m,n.compileStartedAt=null,n.compileHistory.push(g),n.compileHistory.length>20&&n.compileHistory.splice(0,n.compileHistory.length-20)):n.lastCompileAt=m}n.status="serving",p&&(n.errors.clear(),n.recoveringFromError=!1)}else ea.some(p=>p.test(i))&&(n.status==="starting"||n.status==="serving"||n.status==="error")&&(n.status==="error"&&(n.recoveringFromError=!0),n.compileStartedAt=Date.now(),n.status="compiling");let y;if(na.some(p=>p.test(i))){let p=Sa(i),m=Date.now(),h=n.errors.get(p),f=!1,w;h?(h.count+=1,h.lastSeen=m,w=h):(w={message:i,count:1,firstSeen:m,lastSeen:m,parsed:ka(i)},n.errors.set(p,w),f=!0),n.lastErrorHash=p,y={entry:w,isNew:f},n.status="error"}return l=n.status!==a,{statusChanged:l,error:y,announcedUrl:c,bundleUpdated:u,compileMs:g}}var ta,ea,na,ra,sa,oa,es,ia,ns,rs,aa,ca,la,ua,pa,fa,ma,ha,ga,ya,wa,ba,va,os=F(()=>{"use strict";ta=[/Local:\s+http/i,/Application bundle generation complete/i,/compiled successfully/i,/webpack compiled\s+(?:successfully|in\b)/i,/Angular Live Development Server is listening/i,/Storybook\s+[\d.]+\s+(?:for\s+\S+\s+)?started/i,/VITE\s+v[\d.]+\s+ready/i,/Quit the server with CONTROL-C/i,/Uvicorn running on http/i,/Application startup complete/i,/Puma starting in single mode/i,/Use Ctrl-C to stop/i,/Listening on tcp:\/\//i,/running on http/i,/serving HTTP on/i,/trunk serve.*at/i],ea=[/Building\.\.\./i,/Compilation started/i,/Initial chunk files/i,/Compiling/i,/Watching for file changes with StatReloader/i,/Performing system checks/i,/watching files for changes/i,/building\.{3}/i,/Compiling \(/i],na=[/^\s*ERROR\b/,/\berror TS\d+/,/✘/,/\[ERROR\]/,/Cannot find module/i,/^FAIL\s+\S+/,/^\s*●\s+/,/^\s*>\s+NX\s+.*failed/i,/\bModule not found:/,/\[vite\]\s+(?:Internal server error|Pre-transform error)/i,/\[plugin:[^\]]+\]/i,/^\s*ERR!\s+/,/^\s*(?:Uncaught\s+)?(?:Error|TypeError|SyntaxError|ReferenceError|RangeError):\s+/,/^Traceback \(most recent call last\):/,/^\s*[A-Z][a-zA-Z]*Error:\s+/,/^\s*\[error\]\s+/i,/^panic:\s+/,/^thread\s+'[^']+'\s+panicked at/,/^error\[E\d+\]:/,/^\S+\.(?:go|rb|py|rs):\d+:\d+:/,/^\s*[A-Z][a-zA-Z]*\.[A-Z][a-zA-Z]*:\s+/,/^[A-Z][a-zA-Z]+(?:::[A-Z][a-zA-Z]+)+\s*[(:]/,/^[A-Z][a-zA-Z]*Error\s*\(/],ra=/\berror TS(\d+)/,sa=/✘\s*\[ERROR\]\s*TS(\d+)/,oa=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte|py|rb|go|rs)):(\d+):(\d+)/,es=/\(([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte|py|rb|go|rs)):(\d+):(\d+)\)/,ia=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte))\((\d+),(\d+)\)\s*:/,ns=/File\s+"([^"]+\.py)",\s+line\s+(\d+)/,rs=/^\s*-->\s+([^\s:]+\.rs):(\d+):(\d+)/,aa=/^([^\s:()]+\.rb):(\d+):in\b/,ca=/^FAIL\s+(\S+\.(?:tsx?|jsx?|mjs|cjs))(?:\s|$)/,la=/^ERROR in\s+(\S+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte))(?:[:\s](\d+):(\d+))?/,ua=/^\s+([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte)):(\d+):(\d+):?\s*$/,pa=[{tool:"vite",rx:/\[vite\]|\[plugin:vite:|transformWithEsbuild/i},{tool:"storybook",rx:/\bstorybook\b|^\s*ERR!\s|builder-vite/i},{tool:"jest",rx:/^FAIL\s|^\s*●\s+|\bjest\b/i},{tool:"nx",rx:/>\s+NX\s+|Failed tasks:|Nx errored/i},{tool:"webpack",rx:/\bModule not found:|webpack compiled|webpack-dev-server/i},{tool:"esbuild",rx:/✘\s*\[ERROR\]|esbuild/i},{tool:"typescript",rx:/\berror TS\d+/},{tool:"django",rx:/\bdjango\b|StatReloader|manage\.py runserver/i},{tool:"rails",rx:/\brails\b|Puma starting|Booting (?:Puma|Rails)|ActionController|NameError\s*\(|\.rb:\d+:in/i},{tool:"fastapi",rx:/\buvicorn\b|fastapi|ASGI/i},{tool:"go-air",rx:/\bair v\d|building\.{3}|\.go:\d+:\d+/i},{tool:"rust-trunk",rx:/\btrunk\b|^error\[E\d+\]|^\s*-->\s+\S+\.rs:/i},{tool:"python",rx:/^Traceback \(most recent call last\):|^\s*File "[^"]+\.py"|[A-Z][a-zA-Z]*Error:\s/},{tool:"node",rx:/^\s*(?:Uncaught\s+)?(?:Error|TypeError|SyntaxError|ReferenceError|RangeError):/}];fa=/Local:\s+(https?:\/\/\S+)/i,ma=/Server running at\s+(https?:\/\/\S+)/i,ha=/listening on\s+(https?:\/\/\S+)/i,ga=/(?:listening|listen)\s+(https?:\/\/\S+)/i,ya=/Initial chunk files/i,wa=/Lazy chunk files/i,ba=/(Initial total|Lazy total)\s*\|?\s*([\d.]+)\s*(kB|MB|B)\b/i,va=/^\s*\|?\s*([^\s|][^|]*?)\s*\|\s*([^|]+?)\s*\|\s*([\d.]+)\s*(kB|MB|B)\b/i});import{spawn as Ea}from"node:child_process";import is from"tree-kill";import Pa from"strip-ansi";var as,je,cs=F(()=>{"use strict";os();as=500,je=class{child=null;stdoutBuf="";stderrBuf="";deps;stopping=!1;constructor(t){this.deps=t}isRunning(){return this.child!==null&&this.child.exitCode===null&&!this.stopping}start(){if(this.isRunning())return;let{app:t,port:e,state:r}=this.deps,s=Date.now();r.status="starting",r.startedAt=s,r.compileStartedAt=s,r.lastCompileMs=null,r.lastCompileAt=null,r.errors.clear(),r.logBuffer.length=0,r.lastStatusMessage=void 0;let i=`${this.deps.commandOverride||t.command} --port ${e}`,a={...process.env,...t.env||{},...this.deps.envOverride||{},PORT:String(e),FORCE_COLOR:"0"},l=Ea(i,[],{cwd:t.workspaceRoot,shell:!0,env:a,windowsHide:!0});this.child=l,r.pid=l.pid??null,r.port=e,l.stdout?.on("data",c=>this.handleChunk(c,"stdout")),l.stderr?.on("data",c=>this.handleChunk(c,"stderr")),l.on("exit",(c,d)=>{let u=r.status,g=this.stopping;g?(r.status="stopped",r.lastStatusMessage=`stopped (code=${c??"null"}${d?`, ${d}`:""})`):c!==0?(r.status="error",r.lastStatusMessage=`process exited with code ${c}${d?` (${d})`:""}`):r.status="stopped",r.pid=null,r.health="unknown",this.child=null,this.stopping=!1,u!==r.status&&this.deps.onStatusChange?.(u,r.status,r.lastStatusMessage),this.deps.onExit?.(c,d,g),this.deps.onStateChange()}),l.on("error",c=>{r.status="error",r.lastStatusMessage=`spawn error: ${c.message}`,this.deps.onStateChange()}),this.deps.onStateChange()}handleChunk(t,e){let r=t.toString("utf8"),s=this[e==="stdout"?"stdoutBuf":"stderrBuf"]+=r,o=s.lastIndexOf(`
53
- `);if(o<0)return;let i=s.slice(0,o),a=s.slice(o+1);e==="stdout"?this.stdoutBuf=a:this.stderrBuf=a;let{state:l}=this.deps,c=!1;for(let d of i.split(/\r?\n/)){if(!d.length)continue;let u=Pa(d),g=Date.now();l.lastLogTs=g,l.stale&&(l.stale=!1),l.logBuffer.push({ts:g,line:u}),l.logBuffer.length>as&&l.logBuffer.splice(0,l.logBuffer.length-as),this.deps.onLogLine?.(u);let y=l.status,p=ss(l,u);p?.statusChanged&&(c=!0,this.deps.onStatusChange?.(y,l.status)),p?.error&&this.deps.onErrorRecorded?.(p.error.entry,p.error.isNew),p?.compileMs!=null&&this.deps.onCompile?.(p.compileMs),p?.bundleUpdated&&this.deps.onBundleUpdate?.()}(c||i.length>0)&&this.deps.onStateChange()}async stop(){if(!this.child||this.stopping)return;this.stopping=!0;let t=this.child.pid;if(!t){this.child=null,this.stopping=!1;return}await new Promise(e=>{let r=!1,s=()=>{r||(r=!0,e())},o=()=>s();this.child?.once("exit",o),is(t,"SIGTERM",()=>{});let i=setTimeout(()=>{is(t,"SIGKILL",()=>{})},2e3),a=setTimeout(()=>{clearTimeout(i),s()},3e3);this.child?.once("exit",()=>{clearTimeout(i),clearTimeout(a),s()})})}}});import vt from"node:fs";import Ra from"node:path";var _e,ls=F(()=>{"use strict";_e=class{constructor(t,e){this.appName=t;this.cfg=e;this.filePath=Ra.join(e.dir,`${t}.log`),this.open()}appName;cfg;fd=null;bytes=0;warned=!1;filePath;open(){try{vt.mkdirSync(this.cfg.dir,{recursive:!0});try{this.bytes=vt.statSync(this.filePath).size}catch{this.bytes=0}this.fd=vt.openSync(this.filePath,"a")}catch(t){this.warn(`open failed: ${t.message}`),this.fd=null}}write(t){if(this.fd!=null)try{let e=`${new Date().toISOString()} ${t}
54
- `,r=Buffer.from(e,"utf8");vt.writeSync(this.fd,r),this.bytes+=r.length,this.bytes>=this.cfg.maxBytesPerFile&&this.rotate()}catch(e){this.warn(`write failed: ${e.message}`)}}close(){if(this.fd!=null){try{vt.closeSync(this.fd)}catch{}this.fd=null}}rotate(){try{this.close();for(let t=this.cfg.maxFiles-1;t>=1;t--){let e=`${this.filePath}.${t}`,r=`${this.filePath}.${t+1}`;if(t+1>this.cfg.maxFiles-1){try{vt.rmSync(e,{force:!0})}catch{}continue}try{vt.existsSync(e)&&vt.renameSync(e,r)}catch{}}try{let t=`${this.filePath}.1`;vt.existsSync(this.filePath)&&vt.renameSync(this.filePath,t)}catch{}this.open()}catch(t){this.warn(`rotate failed: ${t.message}`)}}warn(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] warning: diskLogger(${this.appName}) ${t}
55
- `))}}});import{spawn as ps}from"node:child_process";import us from"tree-kill";import ds from"strip-ansi";function En(n){let t=[],e;for(let r of n.split(/\r?\n/)){let s=r.match(Ba);if(s){e=s[1];continue}let o=r.match(Fa);if(o){t.push({name:o[1].trim(),file:e});continue}let i=r.match(Ua);if(i){t.push({name:i[2],file:i[1]});continue}}return t.slice(0,50)}function Ha(n){let t=n.match(Aa);if(t){let g=t[1]?Number(t[1]):0,y=Number(t[3]),p=t[4]?Number(t[4]):y+g,m=n.match(Oa);return{passed:y,failed:g,total:p,suites:m?Number(m[3]??m[2]):void 0,framework:"jest",failedTests:g>0?En(n):void 0}}let e=n.match($a);if(e){let g=e[1]?Number(e[1]):0,y=Number(e[2]),p=e[3]?Number(e[3]):y+g,m=n.match(ja);return{passed:y,failed:g,total:p,suites:m?Number(m[3]??m[2]):void 0,framework:"vitest",failedTests:g>0?En(n):void 0}}let r=n.match(Na);if(r){let g=Number(r[1]),y=Number(r[2]),p=r[3]?Number(r[3]):0;return{passed:g-p,failed:p,total:y,framework:"karma"}}let s=n.match(Ma);if(s&&/playwright/i.test(n)){let g=Number(s[1]),y=s[2]?Number(s[2]):0;return{passed:g,failed:y,total:g+y,framework:"playwright"}}let o=n.match(_a);if(o){let g=o[1]?Number(o[1]):0,y=Number(o[2]);return{passed:y,failed:g,total:y+g,durationMs:Math.round(Number(o[3])*1e3),framework:"pytest",failedTests:g>0?En(n):void 0}}let i=n.match(Da);if(i){let g=Number(i[1]),y=Number(i[2]);return{passed:g-y,failed:y,total:g,framework:"rspec"}}let a=n.match(Ia);if(a){let g=Number(a[1]),y=Number(a[2]);return{passed:g,failed:y,total:g+y,framework:"cargo"}}let l=0,c=0,d=0,u=!1;for(let g of n.split(/\r?\n/)){let y=g.match(La);y&&(u=!0,d+=Math.round(Number(y[2])*1e3),y[1]==="ok"?l++:c++)}if(u)return{passed:l,failed:c,total:l+c,durationMs:d,framework:"go"};if(s){let g=Number(s[1]),y=s[2]?Number(s[2]):0;return{passed:g,failed:y,total:g+y,framework:"playwright"}}return null}function fs(n,t,e){let r=e.length?" -- "+e.join(" "):"";return n.workspaceType==="nx"?`npx nx run ${n.name}:${t}${r}`:n.workspaceType==="angular"?`npx ng run ${n.name}:${t}${r}`:`npx ${t}${r}`}function ms(n,t,e=[]){return new Promise(r=>{let s=Date.now(),o=fs(n,t,e),i=ps(o,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),a=[],l="",c=d=>{l+=d.toString("utf8");let u=l.lastIndexOf(`
56
- `);if(u<0)return;let g=l.slice(0,u);l=l.slice(u+1);for(let y of g.split(/\r?\n/)){if(!y.length)continue;let p=ds(y);a.push(p),a.length>1e3&&a.splice(0,a.length-1e3)}};i.stdout?.on("data",c),i.stderr?.on("data",c),i.on("exit",d=>{let u=Date.now()-s,g=a.join(`
57
- `)+(l?`
58
- `+l:""),y=Ha(g);r({app:n.name,task:t,exitCode:d,durationMs:u,summary:y,outputTail:a.slice(-50)})}),i.on("error",()=>{r({app:n.name,task:t,exitCode:-1,durationMs:Date.now()-s,summary:null,outputTail:[...a,"[daimon] task spawn error"]})})})}function hs(n,t,e=[]){let r=fs(n,t,e),s=ps(r,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),o=[],i="",a=c=>{i+=c.toString("utf8");let d=i.lastIndexOf(`
59
- `);if(d<0)return;let u=i.slice(0,d);i=i.slice(d+1);for(let g of u.split(/\r?\n/))g.length&&(o.push(ds(g)),o.length>500&&o.splice(0,o.length-500))};return s.stdout?.on("data",a),s.stderr?.on("data",a),{app:n.name,task:t,pid:s.pid??null,child:s,startedAt:Date.now(),logs:o,stop:()=>new Promise(c=>{if(!s.pid){c();return}let d=!1,u=()=>{d||(d=!0,c())};s.once("exit",u),us(s.pid,"SIGTERM",()=>{}),setTimeout(()=>{s.pid&&us(s.pid,"SIGKILL",()=>{})},2e3),setTimeout(u,3500)})}}var Aa,Oa,Na,Ma,$a,ja,_a,Da,La,Ia,Fa,Ba,Ua,gs=F(()=>{"use strict";Aa=/Tests:\s+(?:(\d+)\s+failed,\s+)?(?:(\d+)\s+skipped,\s+)?(\d+)\s+passed(?:,\s+(\d+)\s+total)?/,Oa=/Test Suites:\s+(?:(\d+)\s+failed,\s+)?(\d+)\s+passed(?:,\s+(\d+)\s+total)?/,Na=/Executed (\d+) of (\d+)(?:\s*\((\d+)\s*FAILED\))?/,Ma=/(\d+)\s+passed(?:.*?(\d+)\s+failed)?/i,$a=/Tests\s+(?:(\d+)\s+failed\s*\|\s*)?(\d+)\s+passed(?:\s*\((\d+)\))?/,ja=/Test Files\s+(?:(\d+)\s+failed\s*\|\s*)?(\d+)\s+passed(?:\s*\((\d+)\))?/,_a=/(?:(\d+)\s+failed,\s+)?(\d+)\s+passed(?:,\s+\d+\s+skipped)?\s+in\s+([\d.]+)s/,Da=/(\d+)\s+examples?,\s+(\d+)\s+failures?/,La=/^(ok|FAIL|---\s+FAIL)\s+\S+\s+([\d.]+)s/,Ia=/test result:\s*(?:ok|FAILED)\.\s+(\d+)\s+passed;\s+(\d+)\s+failed/,Fa=/^\s*✕\s+(.+?)(?:\s+\((\d+)\s*ms\))?$/,Ba=/^\s*FAIL\s+(\S+\.(?:tsx?|jsx?|mjs|cjs|spec\.[a-z]+))/,Ua=/^FAILED\s+(\S+)::([^\s]+)/});import ws from"node:fs";import ys from"node:path";function bs(n){let t={},e;try{e=ws.readFileSync(n,"utf8")}catch{return t}for(let r of e.split(/\r?\n/)){let s=r.trim();if(!s||s.startsWith("#"))continue;let o=s.indexOf("=");if(o<0)continue;let i=s.slice(0,o).trim(),a=s.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),i&&(t[i]=a)}return t}function Pn(n,t){return ys.isAbsolute(t)?t:ys.join(n,t)}function Rn(n,t){return t.filter(e=>ws.existsSync(Pn(n,e)))}var vs=F(()=>{"use strict"});import Ja from"node:fs";import Wa from"node:path";function Ga(){return Wa.join(ut(),"secrets.json")}function Ss(){try{let n=Ja.readFileSync(Ga(),"utf8");n.charCodeAt(0)===65279&&(n=n.slice(1));let t=JSON.parse(n);if(!t||typeof t!="object")return{};let e={};for(let[r,s]of Object.entries(t))typeof s=="string"&&(e[r]=s);return e}catch{return{}}}function ks(n,t){let e={};for(let[r,s]of Object.entries(n))e[r]=s.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,(o,i)=>t[i]??`\${${i}}`);return e}var xs=F(()=>{"use strict";bt()});import{EventEmitter as qa}from"node:events";var Ts,De,Cs=F(()=>{"use strict";cs();fe();ls();de();gs();yn();vs();xs();wn();Ts=500,De=class extends qa{entries=new Map;portAlloc;config;eventBuffer=[];history=null;watchTasks=new Map;sessionRecorder=new Pe;constructor(t,e,r){super(),this.config=t,this.portAlloc=r??new Yt(t.portRange);for(let s of e)this.entries.set(s.name,{app:s,state:this.freshState(s.name,s.tags,s.workspaceLabel??null),proc:null})}getConfig(){return this.config}addDiscoveredApp(t){this.entries.has(t.name)||(this.entries.set(t.name,{app:t,state:this.freshState(t.name,t.tags,t.workspaceLabel??null),proc:null}),this.emit("change"))}updateDiscoveredApp(t){let e=this.entries.get(t.name);e&&(e.app=t,e.state.tags=t.tags,e.state.workspaceLabel=t.workspaceLabel??null,e.state.dependsOn=this.config.depends?.[t.name]??[],this.emit("change"))}getPortAllocator(){return this.portAlloc}setHistory(t){this.history=t}getHistory(){return this.history}freshState(t,e,r=null){return{name:t,status:"stopped",port:null,pid:null,startedAt:null,compileStartedAt:null,lastCompileMs:null,lastCompileAt:null,logBuffer:[],errors:new Map,compileHistory:[],health:"unknown",lastHealthAt:null,cpu:null,memMB:null,restartAttempts:0,restartWindowStart:null,nextRestartAt:null,tags:e,announcedUrl:null,lastHealthError:null,cachedProbeHost:null,lastLogTs:null,stale:!1,bundle:null,bundleRegressionPct:null,activeEnvFile:null,sessionOverrides:null,dependsOn:this.config.depends?.[t]??[],workspaceLabel:r,discoveredHealthPath:null}}names(){return[...this.entries.keys()]}pruneOldErrors(t=Date.now()){let e=this.config.errorRetention?.maxAgeMs??864e5,r=0;for(let s of this.entries.values())for(let[o,i]of s.state.errors)t-i.lastSeen>e&&(s.state.errors.delete(o),r++);return r}list(){return this.names().map(t=>this.summary(t))}summary(t){let e=this.entries.get(t);if(!e)return null;let r=e.state,s=r.startedAt&&(r.status==="serving"||r.status==="compiling"||r.status==="starting")?Date.now()-r.startedAt:null,i=this.config.overrides?.[t]?.url||e.resolvedUrl||r.announcedUrl||(r.port?`http://127.0.0.1:${r.port}`:null),a;for(let l=this.eventBuffer.length-1;l>=0;l--){let c=this.eventBuffer[l];if(c.app===t&&c.type==="status"){a=Date.now()-c.ts;break}}return{name:r.name,status:r.status,port:r.port,url:i,errorCount:[...r.errors.values()].reduce((l,c)=>l+c.count,0),uptimeMs:s,lastCompileMs:r.lastCompileMs,health:r.health,lastHealthAt:r.lastHealthAt,cpu:r.cpu,memMB:r.memMB,compileHistoryMs:[...r.compileHistory],tags:[...r.tags],restartAttempts:r.restartAttempts,nextRestartAt:r.nextRestartAt,announcedUrl:r.announcedUrl,lastHealthError:r.lastHealthError,stale:r.stale,bundle:r.bundle,bundleRegressionPct:r.bundleRegressionPct,dependsOn:[...r.dependsOn],activeEnvFile:r.activeEnvFile,workspaceLabel:r.workspaceLabel,lastChangeMs:a}}getState(t){return this.entries.get(t)?.state??null}getApp(t){return this.entries.get(t)?.app??null}errors(t){let e=this.getState(t);return e?[...e.errors.values()].sort((r,s)=>s.lastSeen-r.lastSeen):null}errorsSince(t,e){let r=this.getState(t);return r?[...r.errors.values()].filter(s=>s.lastSeen>e).sort((s,o)=>o.lastSeen-s.lastSeen):null}logs(t,e={}){let r=this.getState(t);if(!r)return null;let s=r.logBuffer;if(e.sinceMs&&e.sinceMs>0){let o=Date.now()-e.sinceMs;s=s.filter(i=>i.ts>=o)}return e.tail&&e.tail>0&&(s=s.slice(-e.tail)),s.map(o=>o.line)}events(t={}){let e=t.sinceMs&&t.sinceMs>0?Date.now()-t.sinceMs:0;return this.eventBuffer.filter(r=>r.ts>=e&&(!t.app||r.app===t.app))}recordEvent(t){let e={ts:t.ts??Date.now(),...t};this.eventBuffer.push(e),this.emit("event",e),this.eventBuffer.length>Ts&&this.eventBuffer.splice(0,this.eventBuffer.length-Ts),this.history?.recordEvent(e),this.emit("event",e)}setHealth(t,e){let r=this.entries.get(t);if(!r)return;let s=r.state;if(s.lastHealthAt=Date.now(),s.health===e)return;let o=s.health;s.health=e,e==="healthy"&&(r.prevHealthyAt=Date.now(),r.cascadeArmed&&(r.cascadeArmed=!1,this.triggerCascadeRestart(t))),this.recordEvent({app:t,type:"health",from:o,to:e}),this.emit("change")}armCascade(t){let e=this.entries.get(t);e&&this.config.cascadeRestart&&e.prevHealthyAt!=null&&(e.cascadeArmed=!0)}setLastHealthError(t,e){let r=this.getState(t);r&&r.lastHealthError!==e&&(r.lastHealthError=e,this.emit("change"))}setResolvedUrl(t,e){let r=this.entries.get(t);r&&r.resolvedUrl!==e&&(r.resolvedUrl=e,this.emit("change"))}setCachedProbeHost(t,e){let r=this.getState(t);r&&(r.cachedProbeHost=e)}setStale(t,e){let r=this.getState(t);r&&r.stale!==e&&(r.stale=e,this.emit("change"))}setSessionOverride(t,e){let r=this.getState(t);r&&(r.sessionOverrides=e,this.emit("change"))}setActiveEnvFile(t,e){let r=this.getState(t);r&&(r.activeEnvFile=e,this.emit("change"))}async start(t){this.sessionRecorder.append({kind:"start",app:t});let e=this.entries.get(t);if(!e)return{ok:!1,status:"unknown",error:"unknown app"};if(e.proc?.isRunning())return{ok:!0,status:e.state.status};let r=e.state.status,s;try{s=await this.portAlloc.allocate(t,e.app.pinnedPort)}catch(y){return e.state.status="error",e.state.lastStatusMessage=y.message,this.recordEvent({app:t,type:"status",from:r,to:"error",message:y.message}),this.emit("change"),{ok:!1,status:"error",error:y.message}}if(!await Tt(s)){let y=Ce(s),p=Cr(s,y);return e.state.status="error",e.state.port=s,e.state.lastStatusMessage=p,this.recordEvent({app:t,type:"status",from:r,to:"error",message:p}),this.emit("change"),{ok:!1,status:"error",error:p}}e.state.health="unknown",e.state.lastHealthAt=null,e.state.announcedUrl=null,e.state.lastHealthError=null,e.state.cachedProbeHost=null,e.state.stale=!1,e.state.lastLogTs=null,e.resolvedUrl=void 0,!e.logger&&this.config.logs.enabled&&(e.logger=new _e(t,this.config.logs));let i=e.state.sessionOverrides,a=this.config.envFiles?.[t]??[],l={};if(a.length){let y=e.state.activeEnvFile;(!y||!Rn(e.app.workspaceRoot,[y]).length)&&(y=Rn(e.app.workspaceRoot,a)[0]??null,y&&(e.state.activeEnvFile=y)),y&&(l=bs(Pn(e.app.workspaceRoot,y)))}let c={...l,...this.config.overrides?.[t]?.env??{},...i?.env??{}},d=Ss(),u=ks(c,d),g=new je({state:e.state,app:e.app,port:s,envOverride:Object.keys(u).length?u:void 0,commandOverride:i?.command,onStateChange:()=>this.emit("change"),onStatusChange:(y,p,m)=>{this.recordEvent({app:t,type:"status",from:y,to:p,message:m}),(p==="stopped"||p==="error")&&(y==="serving"||y==="compiling")&&this.armCascade(t)},onErrorRecorded:(y,p)=>this.recordEvent({app:t,type:p?"error-new":"error-recur",message:y.message}),onExit:(y,p,m)=>this.emit("childExit",{name:t,code:y,signal:p,stopping:m}),onLogLine:y=>{e.logger?.write(y),this.emit("log",{name:t,ts:Date.now(),line:y})},onCompile:y=>{this.history?.recordCompile(t,y);let p=this.getState(t),m=e.lastBundleInitialKB;if(p.bundle&&p.bundle.initialKB>0){if(m&&m>0){let h=(p.bundle.initialKB-m)/m*100;p.bundleRegressionPct=Math.round(h*10)/10,h>10&&this.recordEvent({app:t,type:"bundle-regression",message:`initialKB +${p.bundleRegressionPct}% (${m}->${p.bundle.initialKB})`})}else p.bundleRegressionPct=null;e.lastBundleInitialKB=p.bundle.initialKB}this.checkCompileRegression(t,y),this.emit("compile",{name:t,ms:y})},onBundleUpdate:()=>{let y=this.getState(t);y?.bundle&&(y.bundle.initialKB>0||y.bundle.lazyKB>0)&&this.history?.recordBundle(t,y.bundle.initialKB,y.bundle.lazyKB,y.bundle.files.length),this.emit("bundleUpdate",{name:t})}});return e.proc=g,this.recordEvent({app:t,type:"status",from:r,to:"starting"}),g.start(),{ok:!0,status:e.state.status}}async stop(t){this.sessionRecorder.append({kind:"stop",app:t});let e=this.entries.get(t);if(!e)return{ok:!1,status:"unknown",error:"unknown app"};if(this.emit("userStop",{name:t}),!e.proc||!e.proc.isRunning())return e.state.status!=="stopped"&&this.recordEvent({app:t,type:"status",from:e.state.status,to:"stopped"}),e.state.status="stopped",e.state.pid=null,e.state.health="unknown",this.emit("change"),{ok:!0,status:"stopped"};let r=e.state.status;return await e.proc.stop(),e.proc=null,e.state.status!==r&&this.recordEvent({app:t,type:"status",from:r,to:e.state.status}),{ok:!0,status:e.state.status}}async restart(t){return this.sessionRecorder.append({kind:"restart",app:t}),await this.stop(t),this.start(t)}async startWithDeps(t,e={}){if(!this.entries.has(t))return{ok:!1,results:[{name:t,status:"unknown",health:"unknown",error:"unknown app"}]};let r=ke(this.config.depends??{},t).filter(a=>this.entries.has(a)),s=xe(this.config.depends??{},r),o=[],i=e.waitMs??6e4;for(let a of s){let l=await Promise.all(a.map(d=>this.start(d)));for(let d=0;d<a.length;d++){let u=l[d];if(!u.ok)return o.push({name:a[d],status:u.status,health:"unknown",error:u.error}),{ok:!1,results:o}}let c=await Promise.all(a.map(d=>this.waitFor(d,"healthy",i)));for(let d=0;d<a.length;d++){let u=c[d],g=!u.timedOut&&u.status==="serving"&&u.health==="healthy";if(o.push({name:u.name,status:u.status,health:u.health,error:g?void 0:u.timedOut?"timeout waiting for healthy":"did not reach healthy"}),!g)return{ok:!1,results:o}}}return{ok:!0,results:o}}triggerCascadeRestart(t){if(!this.config.cascadeRestart)return;let e=kr(this.config.depends??{},t);for(let r of e){let s=this.getState(r);s&&(s.status==="serving"||s.status==="compiling"||s.status==="starting")&&this.restart(r)}}async stopAll(t=3e3){let e=[];for(let r of this.entries.values())r.proc?.isRunning()&&e.push(r.proc.stop());for(let r of this.watchTasks.values())e.push(r.stop());await Promise.race([Promise.all(e),new Promise(r=>setTimeout(r,t))]);for(let r of this.entries.values())r.logger?.close()}listTasks(t){let e=this.getApp(t);return e?[...e.tasks??[]]:null}async runTask(t,e,r=[]){this.sessionRecorder.append({kind:"run",app:t,task:e,args:r});let s=this.getApp(t);if(!s)return{error:"unknown app"};let o=await ms(s,e,r);return this.history?.recordTaskRun(t,e,o.exitCode,o.durationMs,o.summary),this.recordEvent({app:t,type:"task-run",message:`${e} exit=${o.exitCode} duration=${o.durationMs}ms`}),this.emit("taskRun",{name:t,task:e,result:o}),o}startWatchTask(t,e,r=[]){let s=this.getApp(t);if(!s)return{ok:!1,error:"unknown app"};let o=`${t}::${e}`;if(this.watchTasks.has(o))return{ok:!0,pid:this.watchTasks.get(o).pid};let i=hs(s,e,r);return this.watchTasks.set(o,i),i.child.on("exit",()=>this.watchTasks.delete(o)),{ok:!0,pid:i.pid}}async stopWatchTask(t,e){let r=`${t}::${e}`,s=this.watchTasks.get(r);return s?(await s.stop(),this.watchTasks.delete(r),{ok:!0}):{ok:!0}}listWatchTasks(t){let e=[];for(let r of this.watchTasks.values())t&&r.app!==t||e.push({app:r.app,task:r.task,pid:r.pid,startedAt:r.startedAt});return e}checkCompileRegression(t,e){let r=this.history;if(!r)return;let o=r.queryCompiles({app:t,limit:31}).filter(l=>l.ms!==e).slice(0,30).map(l=>l.ms);if(o.length<10)return;let i=[...o].sort((l,c)=>l-c),a=i[Math.floor((i.length-1)*.5)];e>2*a&&this.recordEvent({app:t,type:"compile-regression",message:`${(e/1e3).toFixed(1)}s vs p50 ${(a/1e3).toFixed(1)}s`})}watchTaskLogs(t,e,r){let s=this.watchTasks.get(`${t}::${e}`);if(!s)return null;let o=s.logs;return r?o.slice(-r):[...o]}waitFor(t,e,r){return new Promise(s=>{let o=Date.now(),i=this.entries.get(t),a=()=>{if(!i)return!0;let u=i.state;return e==="serving"&&u.status==="serving"||e==="healthy"&&u.status==="serving"&&u.health==="healthy"||e==="stopped"&&u.status==="stopped"||e==="error"&&u.status==="error"},l=u=>{this.off("change",c),clearTimeout(d);let g=i?.state;s({name:t,status:g?.status??"unknown",health:g?.health??"unknown",timedOut:u,waitedMs:Date.now()-o})},c=()=>{a()&&l(!1)};if(a()){s({name:t,status:i.state.status,health:i.state.health,timedOut:!1,waitedMs:0});return}let d=setTimeout(()=>l(!0),r);this.on("change",c)})}}});import Nn from"node:fs";import Es from"node:path";import Xa from"node:os";function Ka(){try{let n=Nn.readFileSync(Mn,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.errors&&typeof t.errors=="object")return{errors:t.errors}}catch{}return{errors:{}}}function za(n){On=n,!An&&(An=setTimeout(()=>{An=null;let t=On;if(On=null,!!t)try{Nn.mkdirSync(Es.dirname(Mn),{recursive:!0}),Nn.writeFileSync(Mn,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: cursor write failed: ${e.message}
60
- `)}},500))}var Mn,An,On,Le,Ps=F(()=>{"use strict";Mn=Es.join(Xa.homedir(),".daimon","cursors.json");An=null,On=null;Le=class{data=Ka();getErrorCursor(t,e){return this.data.errors[`${t}:${e}`]??0}setErrorCursor(t,e,r){this.data.errors[`${t}:${e}`]=r,za(this.data)}}});import Rs from"node:fs";import Ya from"node:os";import As from"node:path";function Za(n){let t={};for(let[e,r]of Object.entries(n))typeof r=="string"&&(t[e]=Va.test(e)?"***":r);return t}function $n(n,t){let e=n.summary(t);if(!e)return null;let r=n.getState(t),s=n.getApp(t),o=n.getConfig(),i=o.overrides?.[t]??{},a={...process.env,...s.env??{},...r.sessionOverrides?.env??{}},l=n.getHistory(),c=l?l.queryEvents({app:t,limit:50}):[],d=l?l.queryBundles({app:t,limit:100}):[],u=l?l.querySelfMetrics({limit:60}):[];return{takenAt:new Date().toISOString(),summary:e,logs:r.logBuffer.slice(-500).map(g=>({ts:g.ts,line:g.line})),errors:[...r.errors.entries()].map(([g,y])=>({hash:g,message:y.message,count:y.count,firstSeen:y.firstSeen,lastSeen:y.lastSeen})),env:Za(a),configSlice:{command:r.sessionOverrides?.command??i.command??s.command,port:r.sessionOverrides?.port??i.port??null,workspaceRoot:s.workspaceRoot,workspaceType:s.workspaceType,tags:s.tags,depends:o.depends?.[t]??[],envFiles:o.envFiles?.[t]??[]},events:c,bundles:d,selfMetrics:u}}function Os(n,t){let e=$n(n,t);if(!e)return null;let r=As.join(Ya.homedir(),".daimon","snapshots");Rs.mkdirSync(r,{recursive:!0});let s=e.takenAt.replace(/[:.]/g,"-"),o=As.join(r,`${t}-${s}.json`);return Rs.writeFileSync(o,JSON.stringify(e,null,2)),{path:o,payload:e}}var Va,Ns=F(()=>{"use strict";Va=/key|secret|token|password|api[-_]?key/i});import Ie from"node:fs";import Ms from"node:path";function $s(n){let t=0;try{let e=Ie.readdirSync(n,{withFileTypes:!0});for(let r of e){let s=Ms.join(n,r.name);try{r.isDirectory()?t+=$s(s):r.isFile()&&(t+=Ie.statSync(s).size)}catch{}}}catch{}return t}function jn(n,t,e){let r=n.getApp(t);if(!r)return null;let s=n.getState(t),o=s?s.status==="serving"||s.status==="compiling"||s.status==="starting":!1,a=[...Qa,...e?tc:[]].map(l=>{let c=Ms.join(r.workspaceRoot,l),d=Ie.existsSync(c);return{path:c,exists:d,sizeBytes:d?$s(c):0}});return{app:t,workspace:r.workspaceRoot,targets:a,ranOnServing:o}}function js(n,t,e){let r=jn(n,t,e);if(!r)return{error:"unknown app"};if(r.ranOnServing)return{error:"app is currently running; stop it first"};let s=[],o=[];for(let i of r.targets)if(i.exists)try{Ie.rmSync(i.path,{recursive:!0,force:!0}),s.push(i.path)}catch(a){o.push({path:i.path,error:a?.message||String(a)})}return{ok:o.length===0,removed:s,failed:o}}var Qa,tc,_s=F(()=>{"use strict";Qa=["dist",".angular/cache","tmp","out-tsc"],tc=["node_modules"]});function he(n){return n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}function Ds(n){let t=[];t.push("# HELP daimon_up daimon daemon up"),t.push("# TYPE daimon_up gauge"),t.push("daimon_up 1"),t.push("# HELP daimon_app_status app status one-hot"),t.push("# TYPE daimon_app_status gauge");let e=n.list();for(let r of e)for(let s of ec)t.push(`daimon_app_status{name="${he(r.name)}",status="${s}"} ${r.status===s?1:0}`);t.push("# HELP daimon_compile_seconds last successful compile duration in seconds"),t.push("# TYPE daimon_compile_seconds gauge");for(let r of e)r.lastCompileMs!=null&&t.push(`daimon_compile_seconds{name="${he(r.name)}"} ${(r.lastCompileMs/1e3).toFixed(3)}`);t.push("# HELP daimon_error_total cumulative deduped error count"),t.push("# TYPE daimon_error_total counter");for(let r of e)t.push(`daimon_error_total{name="${he(r.name)}"} ${r.errorCount}`);t.push("# HELP daimon_cpu_percent app CPU percent"),t.push("# TYPE daimon_cpu_percent gauge");for(let r of e)r.cpu!=null&&t.push(`daimon_cpu_percent{name="${he(r.name)}"} ${r.cpu}`);t.push("# HELP daimon_mem_mb app resident memory MB"),t.push("# TYPE daimon_mem_mb gauge");for(let r of e)r.memMB!=null&&t.push(`daimon_mem_mb{name="${he(r.name)}"} ${r.memMB}`);return t.join(`
51
+ `)}recordSelfMetric(t,e,r,s,o=Date.now()){if(this.db)try{this.db.prepare("INSERT INTO self_metrics (ts,rssMB,heapUsedMB,eventLoopLagMs,historyQueryP95Ms) VALUES (?,?,?,?,?)").run(o,t,e,r,s)}catch(i){this.warnOnce(`self_metrics write failed: ${i?.message||i}`)}}querySelfMetrics(t={}){if(!this.db)return[];let e=[],r=[];t.since!=null&&(e.push("ts >= ?"),r.push(t.since));let s=`SELECT ts, rssMB, heapUsedMB, eventLoopLagMs, historyQueryP95Ms FROM self_metrics ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??60),this.db.prepare(s).all(...r)}recordEvent(t){this.db&&this.queue.push({kind:"event",row:{ts:t.ts,app:t.app,type:t.type,from_state:t.from??null,to_state:t.to??null,message:t.message??null}})}recordCompile(t,e,r=Date.now()){this.db&&this.queue.push({kind:"compile",row:{ts:r,app:t,ms:e}})}recordBundle(t,e,r,s,o=Date.now()){this.db&&this.queue.push({kind:"bundle",row:{ts:o,app:t,initialKB:e,lazyKB:r,fileCount:s}})}recordTaskRun(t,e,r,s,o,i=Date.now()){this.db&&this.queue.push({kind:"task",row:{ts:i,app:t,task:e,exit_code:r,duration_ms:s,summary:o==null?null:JSON.stringify(o)}})}flush(){if(!this.db||this.queue.length===0)return;let t=this.queue;this.queue=[];try{let e=this.db.prepare("INSERT INTO events (ts,app,type,from_state,to_state,message) VALUES (?,?,?,?,?,?)"),r=this.db.prepare("INSERT INTO compile_times (ts,app,ms) VALUES (?,?,?)"),s=this.db.prepare("INSERT INTO task_runs (ts,app,task,exit_code,duration_ms,summary) VALUES (?,?,?,?,?,?)"),o=this.db.prepare("INSERT INTO bundles (ts,app,initialKB,lazyKB,fileCount) VALUES (?,?,?,?,?)");this.db.transaction(a=>{for(let c of a)c.kind==="event"?e.run(c.row.ts,c.row.app,c.row.type,c.row.from_state,c.row.to_state,c.row.message):c.kind==="compile"?r.run(c.row.ts,c.row.app,c.row.ms):c.kind==="bundle"?o.run(c.row.ts,c.row.app,c.row.initialKB,c.row.lazyKB,c.row.fileCount):s.run(c.row.ts,c.row.app,c.row.task,c.row.exit_code,c.row.duration_ms,c.row.summary)})(t)}catch(e){this.warnOnce(`history write failed: ${e?.message||e}`)}}runRetention(){if(this.db)try{let t=Date.now()-this.cfg.retentionDays*864e5;this.db.prepare("DELETE FROM events WHERE ts < ?").run(t),this.db.prepare("DELETE FROM compile_times WHERE ts < ?").run(t),this.db.prepare("DELETE FROM task_runs WHERE ts < ?").run(t),this.db.prepare("DELETE FROM bundles WHERE ts < ?").run(t),this.db.prepare("DELETE FROM self_metrics WHERE ts < ?").run(t)}catch(t){this.warnOnce(`retention failed: ${t?.message||t}`)}}queryEvents(t){if(!this.db)return[];let e=[],r=[];t.app&&(e.push("app = ?"),r.push(t.app)),t.since!=null&&(e.push("ts >= ?"),r.push(t.since)),t.until!=null&&(e.push("ts <= ?"),r.push(t.until)),t.type&&(e.push("type = ?"),r.push(t.type));let s=`SELECT * FROM events ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??500),this.db.prepare(s).all(...r)}queryCompiles(t){if(!this.db)return[];let e=[],r=[];t.app&&(e.push("app = ?"),r.push(t.app)),t.since!=null&&(e.push("ts >= ?"),r.push(t.since)),t.until!=null&&(e.push("ts <= ?"),r.push(t.until));let s=`SELECT * FROM compile_times ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??1e3),this.db.prepare(s).all(...r)}queryBundles(t){if(!this.db)return[];let e=[],r=[];t.app&&(e.push("app = ?"),r.push(t.app)),t.since!=null&&(e.push("ts >= ?"),r.push(t.since)),t.until!=null&&(e.push("ts <= ?"),r.push(t.until));let s=`SELECT * FROM bundles ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??1e3),this.db.prepare(s).all(...r)}trends(t){if(!this.db)return{points:[],count:0};let e=Date.now()-t.sinceMs,r=t.bucketMs,s=new Map,o=(u,d)=>{let f=Math.floor(u/r)*r,g=s.get(f)??{sum:0,n:0};g.sum+=d,g.n+=1,s.set(f,g)},i=u=>{let d=Math.floor(u/r)*r,f=s.get(d)??{sum:0,n:0};f.sum+=1,f.n+=1,s.set(d,f)},a=0;if(t.metric==="compile"){let u=this.queryCompiles({app:t.app,since:e,limit:1e4});a=u.length;for(let d of u)o(d.ts,d.ms)}else if(t.metric==="bundle"){let u=this.queryBundles({app:t.app,since:e,limit:1e4});a=u.length;for(let d of u){let f=Math.floor(d.ts/r)*r,g=s.get(f)??{sum:0,n:0,sum2:0};g.sum+=d.initialKB,g.sum2=(g.sum2??0)+d.lazyKB,g.n+=1,s.set(f,g)}}else if(t.metric==="errors"){let u=this.queryEvents({app:t.app,since:e,limit:1e4});for(let d of u)(d.type==="error-new"||d.type==="error-recur")&&(i(d.ts),a++)}else{let u=this.queryEvents({app:t.app,since:e,limit:1e4});for(let d of u)d.type==="status"&&d.to_state==="starting"&&(d.from_state==="error"||d.from_state==="serving"||d.from_state==="compiling")&&(i(d.ts),a++)}let c=[],l=[...s.entries()].sort((u,d)=>u[0]-d[0]);for(let[u,d]of l)t.metric==="compile"||t.metric==="bundle"?c.push({t:u,v:Math.round(d.sum/d.n),...d.sum2!=null?{v2:Math.round(d.sum2/d.n)}:{}}):c.push({t:u,v:d.sum});return{points:c,count:a}}queryTimeline(t){if(!this.db)return[];let e=t.limit??5e3,r=t.since,s=t.kinds,o=[],i=!s||s.has("status"),a=!s||s.has("error"),c=!s||s.has("warning"),l=!s||s.has("lint"),u=!s||s.has("health"),d=!s||s.has("bundle"),f=!s||s.has("task"),g=!s||s.has("restart");if(i||a||c||l||u||g){let C=this.queryEvents({app:t.app,since:r,limit:e});for(let R of C){let y=null;if(R.type==="status"&&i?y="status":(R.type==="error-new"||R.type==="error-recur")&&a?y="error":(R.type==="warning-new"||R.type==="warning-recur")&&c?y="warning":(R.type==="lint-new"||R.type==="lint-recur")&&l?y="lint":R.type==="health"&&u?y="health":(R.type==="restart-scheduled"||R.type==="bundle-regression"||R.type==="compile-regression"||R.type==="stale"||R.type==="self-warn")&&g&&(y="restart"),!y)continue;let b=y==="status"?`${R.from_state??"?"} \u2192 ${R.to_state??"?"}`:R.message??R.type;o.push({ts:R.ts,app:R.app,kind:y,summary:b,payload:R})}}if(d){let C=this.queryBundles({app:t.app,since:r,limit:e});for(let R of C)o.push({ts:R.ts,app:R.app,kind:"bundle",summary:`initial ${R.initialKB}KB \xB7 lazy ${R.lazyKB}KB`,payload:R})}if(f){let C=this.queryCompiles({app:t.app,since:r,limit:e});for(let y of C)o.push({ts:y.ts,app:y.app,kind:"compile",summary:`compile ${(y.ms/1e3).toFixed(1)}s`,payload:y});let R=this.queryTasks({app:t.app,since:r,limit:e});for(let y of R){let b=y.duration_ms??0;o.push({ts:y.ts,app:y.app,kind:"task",summary:`${y.task} exit=${y.exit_code} ${(b/1e3).toFixed(1)}s`,payload:y})}}return o.sort((C,R)=>R.ts-C.ts),o.slice(0,e)}queryTasks(t){if(!this.db)return[];let e=[],r=[];t.app&&(e.push("app = ?"),r.push(t.app)),t.task&&(e.push("task = ?"),r.push(t.task)),t.since!=null&&(e.push("ts >= ?"),r.push(t.since));let s=`SELECT * FROM task_runs ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??200),this.db.prepare(s).all(...r)}summary(t){if(!this.db)return{uptimePct24h:0,restartCount24h:0,compileP50:null,compileP95:null,topErrors:[]};let e=Date.now()-24*3600*1e3,r=this.queryEvents({app:t,since:e,limit:5e3}),s=0,o=e,i=!1,a=null,c=[...r].sort((b,N)=>b.ts-N.ts);for(let b of c)b.type==="status"&&(b.to_state==="serving"&&!i?(i=!0,a=b.ts):i&&b.to_state!=="serving"&&a!=null&&(s+=b.ts-a,i=!1,a=null));i&&a!=null&&(s+=Date.now()-a);let l=Math.round(s/(24*3600*1e3)*1e3)/10,u=r.filter(b=>b.type==="status"&&b.to_state==="starting"&&(b.from_state==="serving"||b.from_state==="error"||b.from_state==="compiling")).length,d=this.queryCompiles({app:t,since:e,limit:1e3}).map(b=>b.ms).sort((b,N)=>b-N),f=(b,N)=>{if(b.length===0)return null;let p=Math.min(b.length-1,Math.floor((b.length-1)*N));return b[p]},g=f(d,.5),C=f(d,.95),R=new Map;for(let b of r)if(b.type==="error-new"||b.type==="error-recur"){let N=b.message??"";if(!N)continue;R.set(N,(R.get(N)??0)+1)}let y=[...R.entries()].sort((b,N)=>N[1]-b[1]).slice(0,5).map(([b,N])=>({message:b,count:N}));return{uptimePct24h:l,restartCount24h:u,compileP50:g,compileP95:C,topErrors:y}}why(t){let e=this.queryEvents({app:t,limit:200}),r=e.find(a=>a.type==="status"&&(a.to_state==="error"||a.from_state==="error"||a.to_state==="serving")),s=r?{ts:r.ts,app:r.app,type:r.type,from:r.from_state??void 0,to:r.to_state??void 0,message:r.message??void 0}:null,o=s?s.ts:Date.now(),i=e.filter(a=>a.ts<o).slice(0,5);return{trigger:s,preceding:i.map(a=>({ts:a.ts,app:a.app,type:a.type,from:a.from_state??void 0,to:a.to_state??void 0,message:a.message??void 0}))}}_flushForTest(){this.flush()}quickCheck(){if(!this.db)return!1;try{return this.db.prepare("PRAGMA quick_check").get()?.quick_check==="ok"}catch{return!1}}close(){if(this.flushTimer&&clearInterval(this.flushTimer),this.retentionTimer&&clearInterval(this.retentionTimer),this.retentionStart&&clearTimeout(this.retentionStart),this.flush(),this.db){try{this.db.close()}catch{}this.db=null}}}});import{spawnSync as An}from"node:child_process";import Dr from"tree-kill";function Fe(n){if(process.platform==="win32"){let o=An("powershell",["-NoProfile","-Command",`Get-NetTCPConnection -LocalPort ${n} -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty OwningProcess`],{encoding:"utf8",windowsHide:!0});if(o.status!==0)return null;let i=Number((o.stdout||"").trim().split(/\s+/)[0]);if(!Number.isFinite(i)||i<=0)return null;let a=An("powershell",["-NoProfile","-Command",`Get-CimInstance Win32_Process -Filter "ProcessId=${i}" | Select-Object -Property Name,CommandLine | ConvertTo-Json -Compress`],{encoding:"utf8",windowsHide:!0}),c,l;try{let u=JSON.parse((a.stdout||"").trim()||"{}");c=typeof u.Name=="string"?u.Name:void 0,l=typeof u.CommandLine=="string"?u.CommandLine:void 0}catch{}return{pid:i,name:c,cmd:l}}let t=An("lsof",["-nP","-iTCP:"+n,"-sTCP:LISTEN"],{encoding:"utf8"});if(t.status!==0)return null;let e=(t.stdout||"").split(/\r?\n/).filter(o=>o.trim()&&!o.startsWith("COMMAND"));if(!e.length)return null;let r=e[0].split(/\s+/);return{pid:Number(r[1]),name:r[0]}}function Lr(n,t){if(!t)return`port ${n} already in use`;let e=[`port ${n} in use by`];return t.name&&e.push(t.name),e.push(`(pid ${t.pid}`),t.cmd&&(e[e.length-1]+=`, cmd: ${t.cmd.slice(0,120)}`),e[e.length-1]+=")",e.join(" ")}function Ir(n){return new Promise(t=>{if(!n.pid||n.pid===process.pid){t(!1);return}Dr(n.pid,"SIGTERM",e=>{if(e){setTimeout(()=>Dr(n.pid,"SIGKILL",r=>t(!r)),500);return}t(!0)})})}var On=U(()=>{"use strict"});import Be from"node:fs";import Wi from"node:os";import Fr from"node:path";function Br(n){return Be.readFileSync(n,"utf8").split(/\r?\n/).filter(e=>e.trim()).map(e=>JSON.parse(e))}var Ue,Nn=U(()=>{"use strict";Ue=class{file=null;startTs=0;isRecording(){return this.file!=null}start(){if(this.file)return{path:this.file};let t=Fr.join(Wi.homedir(),".daimon","sessions");Be.mkdirSync(t,{recursive:!0});let e=Fr.join(t,`${new Date().toISOString().replace(/[:.]/g,"-")}.jsonl`);return Be.writeFileSync(e,""),this.file=e,this.startTs=Date.now(),{path:e}}stop(){let t={path:this.file};return this.file=null,this.startTs=0,t}append(t){if(!this.file)return;let e=JSON.stringify({ts:Date.now()-this.startTs,...t})+`
52
+ `;try{Be.appendFileSync(this.file,e)}catch{}}}});import qi from"node:fs";import $n from"node:path";import{fileURLToPath as Gi}from"node:url";function Xi(){let n=[$n.resolve(Ur,"..","package.json"),$n.resolve(Ur,"..","..","package.json")];for(let t of n)try{return JSON.parse(qi.readFileSync(t,"utf8"))}catch{}return{}}var Ur,st,_t=U(()=>{"use strict";Ur=$n.dirname(Gi(import.meta.url));st=Xi().version||"0.0.0"});import oe from"node:fs";import He from"node:path";import Ki from"node:os";import{spawn as zi}from"node:child_process";import{fileURLToPath as Yi}from"node:url";function mt(){return jn}function Je(){return ie}function Mn(n){try{return process.kill(n,0),!0}catch(t){return t&&t.code==="EPERM"}}function ct(){try{let n=oe.readFileSync(ie,"utf8"),t=JSON.parse(n);if(!t||typeof t.pid!="number")return null;if(!Mn(t.pid)){try{oe.unlinkSync(ie)}catch{}return null}return t}catch{return null}}function Hr(n){oe.mkdirSync(jn,{recursive:!0});let t=ie+"."+process.pid+".tmp";oe.writeFileSync(t,JSON.stringify(n)),oe.renameSync(t,ie)}function Tt(){try{oe.unlinkSync(ie)}catch{}}function Vi(){let n=He.dirname(Yi(import.meta.url));return He.join(n,"main.js")}async function Dt(n={}){let t={...process.env};n.port&&(t.DAIMON_PORT=String(n.port)),zi(process.execPath,[Vi(),"--headless"],{detached:!0,stdio:"ignore",env:t,windowsHide:!0}).unref();let r=Date.now();for(;Date.now()-r<5e3;){let s=ct();if(s&&(!n.port||s.apiPort===n.port))return s;await new Promise(o=>setTimeout(o,100))}throw new Error("daemon failed to start within 5s")}async function Xt(n,t){let e=Date.now();for(;Date.now()-e<t;){if(!Mn(n))return!0;await new Promise(r=>setTimeout(r,100))}return!Mn(n)}function Jr(n,t,e){return{pid:process.pid,apiPort:n,version:st,startedAt:Date.now(),headless:t,cwd:process.cwd(),configPath:e}}var jn,ie,Pt=U(()=>{"use strict";_t();jn=He.join(Ki.homedir(),".daimon"),ie=He.join(jn,"daemon.lock")});var ps={};kt(ps,{promptClaudeInstall:()=>da});import Yt,{useState as ls}from"react";import{Box as us,render as ca,Text as Xe,useApp as la,useInput as ua}from"ink";function pa({onDone:n}){let{exit:t}=la(),[e,r]=ls(0),[s,o]=ls({skill:!0,commands:!1,agent:!0}),i=[{key:"skill",label:"Skill (~/.claude/skills/daimon/SKILL.md)"},{key:"agent",label:"Subagent (~/.claude/agents/daimon-runner.md)"}];return ua((a,c)=>{if(c.escape||a==="q"&&!c.shift){n(null),t();return}if(c.upArrow)r(l=>Math.max(0,l-1));else if(c.downArrow)r(l=>Math.min(i.length-1,l+1));else if(a===" "){let l=i[e].key;o(u=>({...u,[l]:!u[l]}))}else c.return&&(n(s),t())}),Yt.createElement(us,{flexDirection:"column",paddingX:1},Yt.createElement(Xe,{bold:!0,color:"cyan"},"Install Claude Code integration artifacts"),Yt.createElement(Xe,{dimColor:!0},"Space toggles \xB7 Enter confirms \xB7 Esc cancels"),i.map((a,c)=>Yt.createElement(us,{key:a.key},Yt.createElement(Xe,{color:c===e?"cyan":void 0},c===e?"\u25B8 ":" "),Yt.createElement(Xe,null,"[",s[a.key]?"x":" ","] ",a.label))))}async function da(){return new Promise(n=>{let t=!1;ca(Yt.createElement(pa,{onDone:r=>{t||(t=!0,n(r))}})).waitUntilExit().then(()=>{t||(t=!0,n(null))})})}var ds=U(()=>{"use strict"});import Fn from"node:path";function fs(n){let t=Fn.resolve(n);return process.platform==="win32"?t.toLowerCase():t}function Ct(n,t){let e=fs(n),r=fs(t);if(e===r)return!0;let s=r.endsWith(Fn.sep)?r:r+Fn.sep;return e.startsWith(s)}var Bn=U(()=>{"use strict"});import fa from"node:crypto";function Ea(n){for(let{tool:t,rx:e}of Ra)if(e.test(n))return t}function La(n){return fa.createHash("sha1").update(n).digest("hex").slice(0,16)}function Ia(n){let t={message:n},e=n.match(va)||n.match(ba);e&&(t.code=`TS${e[1]}`);let r=n.match(ka)||n.match(ms)||n.match(Sa);if(r)t.file=r[1],t.line=Number(r[2]),t.col=Number(r[3]);else{let o=n.match(Pa);if(o)t.file=o[1],o[2]&&(t.line=Number(o[2])),o[3]&&(t.col=Number(o[3]));else{let i=n.match(Ta);if(i)t.file=i[1];else{let a=n.match(gs);if(a)t.file=a[1],t.line=Number(a[2]),t.col=Number(a[3]);else{let c=n.match(hs);c&&(t.file=c[1],t.line=Number(c[2]))}}}}let s=Ea(n);return s&&(t.tool=s),t}function Fa(n,t){try{let e=new URL(n);return e.hostname==="0.0.0.0"||e.hostname==="[::]"?(e.hostname=t.includes(":")?`[${t}]`:t,e.toString().replace(/\/$/,"")):n.replace(/\/$/,"")}catch{return n}}function Ba(n,t="127.0.0.1"){let e=n.match(Aa)||n.match(Oa)||n.match(Na)||n.match($a);if(!e)return null;let r=e[1].replace(/[),.;]+$/,"");return Fa(r,t)}function Ua(n,t){if(Ma.test(t))return n.bundle||(n.bundle={initialKB:0,lazyKB:0,files:[]}),n._bundleSection="initial",!1;if(ja.test(t))return n.bundle||(n.bundle={initialKB:0,lazyKB:0,files:[]}),n._bundleSection="lazy",!1;let e=t.match(_a);if(e&&n.bundle){let s=parseFloat(e[2]),o=e[3].toUpperCase(),i=Math.round(o==="MB"?s*1024:o==="B"?s/1024:s);return/Initial/i.test(e[1])?n.bundle.initialKB=i:n.bundle.lazyKB=i,!0}let r=t.match(Da);if(r&&n.bundle){let s=r[1].trim();if(/^(Initial|Lazy)\s+(total|chunk)/i.test(s))return!1;let o=r[4].toUpperCase(),i=parseFloat(r[3]),a=o==="MB"?i*1024:o==="B"?i/1024:i;return n.bundle.files.push({name:s,sizeKB:Math.round(a*10)/10}),!1}return!1}function ys(n,t){let e=t.match(Ca),r=e?null:t.match(ms),s=!e&&!r?t.match(gs):null,o=e??r??s;if(o&&n.lastErrorHash){let b=n.errors.get(n.lastErrorHash);b&&!b.parsed?.file&&(b.parsed={...b.parsed??{message:b.message},file:o[1],line:Number(o[2]),col:Number(o[3])})}else if(n.lastErrorHash){let b=t.match(hs),N=b?null:t.match(xa);if(b||N){let p=n.errors.get(n.lastErrorHash);if(p&&!p.parsed?.file){let m=b??N;p.parsed={...p.parsed??{message:p.message},file:m[1],line:Number(m[2])}}}}let i=t.trim();if(!i)return null;let a=n.status,c=!1,l,u=Ba(i);u&&!n.announcedUrl&&(n.announcedUrl=u,l=u);let d=Ua(n,i),f;if(ma.some(b=>b.test(i))){let b=n.status==="error"||!!n.recoveringFromError;if(n.status==="compiling"||n.status==="starting"||n.status==="error"){let N=Date.now();n.compileStartedAt!=null?(f=N-n.compileStartedAt,n.lastCompileMs=f,n.lastCompileAt=N,n.compileStartedAt=null,n.compileHistory.push(f),n.compileHistory.length>20&&n.compileHistory.splice(0,n.compileHistory.length-20)):n.lastCompileAt=N}n.status="serving",b&&(n.errors.clear(),n.recoveringFromError=!1)}else ha.some(b=>b.test(i))&&(n.status==="starting"||n.status==="serving"||n.status==="error")&&(n.status==="error"&&(n.recoveringFromError=!0),n.compileStartedAt=Date.now(),n.status="compiling");let g,C=ga.some(b=>b.test(t)),R=!C&&wa.some(b=>b.test(i)),y=!C&&!R&&ya.some(b=>b.test(i));if(R||y||C){let b=La(i),N=Date.now(),p=n.errors.get(b),m=!1,h;p?(p.count+=1,p.lastSeen=N,h=p):(h={message:i,count:1,firstSeen:N,lastSeen:N,parsed:Ia(i),level:C?"lint":y?"warning":"error"},n.errors.set(b,h),m=!0),n.lastErrorHash=b,g={entry:h,isNew:m},R&&(n.status="error")}return c=n.status!==a,{statusChanged:c,error:g,announcedUrl:l,bundleUpdated:d,compileMs:f}}var ma,ha,ga,ya,wa,ba,va,Sa,ms,ka,hs,gs,xa,Ta,Pa,Ca,Ra,Aa,Oa,Na,$a,Ma,ja,_a,Da,ws=U(()=>{"use strict";ma=[/Local:\s+http/i,/Application bundle generation complete/i,/compiled successfully/i,/webpack compiled\s+(?:successfully|in\b)/i,/Angular Live Development Server is listening/i,/Storybook\s+[\d.]+\s+(?:for\s+\S+\s+)?started/i,/VITE\s+v[\d.]+\s+ready/i,/Quit the server with CONTROL-C/i,/Uvicorn running on http/i,/Application startup complete/i,/Puma starting in single mode/i,/Use Ctrl-C to stop/i,/Listening on tcp:\/\//i,/running on http/i,/serving HTTP on/i,/trunk serve.*at/i],ha=[/Building\.\.\./i,/Compilation started/i,/Initial chunk files/i,/Compiling/i,/Watching for file changes with StatReloader/i,/Performing system checks/i,/watching files for changes/i,/building\.{3}/i,/Compiling \(/i],ga=[/^\s+\d+:\d+\s{2,}(?:warning|error)\s{2,}\S/i,/\blint\/[a-z][a-z0-9-]+\/[a-z][a-zA-Z0-9-]+\b/,/^\s*\S+\.py:\d+:\d+:\s+[A-Z]\d{3,}\b/,/^warning:\s.*clippy::/i,/^\s*=\s+note:\s+`#\[warn\(clippy::/],ya=[/^\s*(?:▲\s*)?\[WARNING\]/,/\bwarning TS\d+/i,/^\s*\[(?:warning|warn)\]\s+/i,/^\s*warning\s+\S+\s+is\s+/i,/^\s*\S+:\d+:\s*(?:Deprecation|User|Future|Pending|Resource|Runtime|Syntax)Warning:/,/^WARNING in\s+/,/^\s*\[vite\]\s+warning/i],wa=[/^\s*ERROR\b/,/\berror TS\d+/,/✘/,/\[ERROR\]/,/Cannot find module/i,/^FAIL\s+\S+/,/^\s*●\s+/,/^\s*(?:>\s+)?NX\s+.*failed/i,/^\s*Failed tasks:/,/^\s*Task\s+"[^"]+"\s+is continuous but exited with code\s+\d+/,/\bModule not found:/,/\[vite\]\s+(?:Internal server error|Pre-transform error)/i,/\[plugin:[^\]]+\]/i,/^\s*ERR!\s+/,/^\s*(?:Uncaught\s+)?(?:Error|TypeError|SyntaxError|ReferenceError|RangeError):\s+/,/^Traceback \(most recent call last\):/,/^\s*[A-Z][a-zA-Z]*Error:\s+/,/^\s*\[error\]\s+/i,/^panic:\s+/,/^thread\s+'[^']+'\s+panicked at/,/^error\[E\d+\]:/,/^\S+\.(?:go|rb|py|rs):\d+:\d+:/,/^\s*[A-Z][a-zA-Z]*\.[A-Z][a-zA-Z]*:\s+/,/^[A-Z][a-zA-Z]+(?:::[A-Z][a-zA-Z]+)+\s*[(:]/,/^[A-Z][a-zA-Z]*Error\s*\(/],ba=/\berror TS(\d+)/,va=/✘\s*\[ERROR\]\s*TS(\d+)/,Sa=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte|py|rb|go|rs)):(\d+):(\d+)/,ms=/\(([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte|py|rb|go|rs)):(\d+):(\d+)\)/,ka=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte))\((\d+),(\d+)\)\s*:/,hs=/File\s+"([^"]+\.py)",\s+line\s+(\d+)/,gs=/^\s*-->\s+([^\s:]+\.rs):(\d+):(\d+)/,xa=/^([^\s:()]+\.rb):(\d+):in\b/,Ta=/^FAIL\s+(\S+\.(?:tsx?|jsx?|mjs|cjs))(?:\s|$)/,Pa=/^ERROR in\s+(\S+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte))(?:[:\s](\d+):(\d+))?/,Ca=/^\s+([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte)):(\d+):(\d+):?\s*$/,Ra=[{tool:"vite",rx:/\[vite\]|\[plugin:vite:|transformWithEsbuild/i},{tool:"storybook",rx:/\bstorybook\b|^\s*ERR!\s|builder-vite/i},{tool:"jest",rx:/^FAIL\s|^\s*●\s+|\bjest\b/i},{tool:"nx",rx:/(?:>\s+)?NX\s+(?:\w|.*failed)|Failed tasks:|Nx errored|exited with code\s+\d+/i},{tool:"webpack",rx:/\bModule not found:|webpack compiled|webpack-dev-server/i},{tool:"esbuild",rx:/✘\s*\[ERROR\]|esbuild/i},{tool:"typescript",rx:/\berror TS\d+/},{tool:"django",rx:/\bdjango\b|StatReloader|manage\.py runserver/i},{tool:"rails",rx:/\brails\b|Puma starting|Booting (?:Puma|Rails)|ActionController|NameError\s*\(|\.rb:\d+:in/i},{tool:"fastapi",rx:/\buvicorn\b|fastapi|ASGI/i},{tool:"go-air",rx:/\bair v\d|building\.{3}|\.go:\d+:\d+/i},{tool:"rust-trunk",rx:/\btrunk\b|^error\[E\d+\]|^\s*-->\s+\S+\.rs:/i},{tool:"python",rx:/^Traceback \(most recent call last\):|^\s*File "[^"]+\.py"|[A-Z][a-zA-Z]*Error:\s/},{tool:"node",rx:/^\s*(?:Uncaught\s+)?(?:Error|TypeError|SyntaxError|ReferenceError|RangeError):/}];Aa=/Local:\s+(https?:\/\/\S+)/i,Oa=/Server running at\s+(https?:\/\/\S+)/i,Na=/listening on\s+(https?:\/\/\S+)/i,$a=/(?:listening|listen)\s+(https?:\/\/\S+)/i,Ma=/Initial chunk files/i,ja=/Lazy chunk files/i,_a=/(Initial total|Lazy total)\s*\|?\s*([\d.]+)\s*(kB|MB|B)\b/i,Da=/^\s*\|?\s*([^\s|][^|]*?)\s*\|\s*([^|]+?)\s*\|\s*([\d.]+)\s*(kB|MB|B)\b/i});import{spawn as Ha}from"node:child_process";import bs from"tree-kill";import Ja from"strip-ansi";var vs,Ke,Ss=U(()=>{"use strict";ws();vs=500,Ke=class{child=null;stdoutBuf="";stderrBuf="";deps;stopping=!1;constructor(t){this.deps=t}isRunning(){return this.child!==null&&this.child.exitCode===null&&!this.stopping}start(){if(this.isRunning())return;let{app:t,port:e,state:r}=this.deps,s=Date.now();r.status="starting",r.startedAt=s,r.compileStartedAt=s,r.lastCompileMs=null,r.lastCompileAt=null,r.errors.clear(),r.logBuffer.length=0,r.lastStatusMessage=void 0;let i=`${this.deps.commandOverride||t.command} --port ${e}`,a={...process.env,...t.env||{},...this.deps.envOverride||{},PORT:String(e),FORCE_COLOR:"0"},c=Ha(i,[],{cwd:t.workspaceRoot,shell:!0,env:a,windowsHide:!0});this.child=c,r.pid=c.pid??null,r.port=e,c.stdout?.on("data",l=>this.handleChunk(l,"stdout")),c.stderr?.on("data",l=>this.handleChunk(l,"stderr")),c.on("exit",(l,u)=>{let d=r.status,f=this.stopping;f?(r.status="stopped",r.lastStatusMessage=`stopped (code=${l??"null"}${u?`, ${u}`:""})`):l!==0?(r.status="error",r.lastStatusMessage=`process exited with code ${l}${u?` (${u})`:""}`):r.status="stopped",r.pid=null,r.health="unknown",this.child=null,this.stopping=!1,d!==r.status&&this.deps.onStatusChange?.(d,r.status,r.lastStatusMessage),this.deps.onExit?.(l,u,f),this.deps.onStateChange()}),c.on("error",l=>{r.status="error",r.lastStatusMessage=`spawn error: ${l.message}`,this.deps.onStateChange()}),this.deps.onStateChange()}handleChunk(t,e){let r=t.toString("utf8"),s=this[e==="stdout"?"stdoutBuf":"stderrBuf"]+=r,o=s.lastIndexOf(`
53
+ `);if(o<0)return;let i=s.slice(0,o),a=s.slice(o+1);e==="stdout"?this.stdoutBuf=a:this.stderrBuf=a;let{state:c}=this.deps,l=!1;for(let u of i.split(/\r?\n/)){if(!u.length)continue;let d=Ja(u),f=Date.now();c.lastLogTs=f,c.stale&&(c.stale=!1),c.logBuffer.push({ts:f,line:d}),c.logBuffer.length>vs&&c.logBuffer.splice(0,c.logBuffer.length-vs),this.deps.onLogLine?.(d);let g=c.status,C=ys(c,d);C?.statusChanged&&(l=!0,this.deps.onStatusChange?.(g,c.status)),C?.error&&this.deps.onErrorRecorded?.(C.error.entry,C.error.isNew),C?.compileMs!=null&&this.deps.onCompile?.(C.compileMs),C?.bundleUpdated&&this.deps.onBundleUpdate?.()}(l||i.length>0)&&this.deps.onStateChange()}async stop(){if(!this.child||this.stopping)return;this.stopping=!0;let t=this.child.pid;if(!t){this.child=null,this.stopping=!1;return}await new Promise(e=>{let r=!1,s=()=>{r||(r=!0,e())},o=()=>s();this.child?.once("exit",o),bs(t,"SIGTERM",()=>{});let i=setTimeout(()=>{bs(t,"SIGKILL",()=>{})},2e3),a=setTimeout(()=>{clearTimeout(i),s()},3e3);this.child?.once("exit",()=>{clearTimeout(i),clearTimeout(a),s()})})}}});import Rt from"node:fs";import Wa from"node:path";var ze,ks=U(()=>{"use strict";ze=class{constructor(t,e){this.appName=t;this.cfg=e;this.filePath=Wa.join(e.dir,`${t}.log`),this.open()}appName;cfg;fd=null;bytes=0;warned=!1;filePath;open(){try{Rt.mkdirSync(this.cfg.dir,{recursive:!0});try{this.bytes=Rt.statSync(this.filePath).size}catch{this.bytes=0}this.fd=Rt.openSync(this.filePath,"a")}catch(t){this.warn(`open failed: ${t.message}`),this.fd=null}}write(t){if(this.fd!=null)try{let e=`${new Date().toISOString()} ${t}
54
+ `,r=Buffer.from(e,"utf8");Rt.writeSync(this.fd,r),this.bytes+=r.length,this.bytes>=this.cfg.maxBytesPerFile&&this.rotate()}catch(e){this.warn(`write failed: ${e.message}`)}}close(){if(this.fd!=null){try{Rt.closeSync(this.fd)}catch{}this.fd=null}}rotate(){try{this.close();for(let t=this.cfg.maxFiles-1;t>=1;t--){let e=`${this.filePath}.${t}`,r=`${this.filePath}.${t+1}`;if(t+1>this.cfg.maxFiles-1){try{Rt.rmSync(e,{force:!0})}catch{}continue}try{Rt.existsSync(e)&&Rt.renameSync(e,r)}catch{}}try{let t=`${this.filePath}.1`;Rt.existsSync(this.filePath)&&Rt.renameSync(this.filePath,t)}catch{}this.open()}catch(t){this.warn(`rotate failed: ${t.message}`)}}warn(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] warning: diskLogger(${this.appName}) ${t}
55
+ `))}}});import{spawn as Ts}from"node:child_process";import xs from"tree-kill";import Ps from"strip-ansi";function Un(n){let t=[],e;for(let r of n.split(/\r?\n/)){let s=r.match(nc);if(s){e=s[1];continue}let o=r.match(ec);if(o){t.push({name:o[1].trim(),file:e});continue}let i=r.match(rc);if(i){t.push({name:i[2],file:i[1]});continue}}return t.slice(0,50)}function sc(n){let t=n.match(qa);if(t){let f=t[1]?Number(t[1]):0,g=Number(t[3]),C=t[4]?Number(t[4]):g+f,R=n.match(Ga);return{passed:g,failed:f,total:C,suites:R?Number(R[3]??R[2]):void 0,framework:"jest",failedTests:f>0?Un(n):void 0}}let e=n.match(za);if(e){let f=e[1]?Number(e[1]):0,g=Number(e[2]),C=e[3]?Number(e[3]):g+f,R=n.match(Ya);return{passed:g,failed:f,total:C,suites:R?Number(R[3]??R[2]):void 0,framework:"vitest",failedTests:f>0?Un(n):void 0}}let r=n.match(Xa);if(r){let f=Number(r[1]),g=Number(r[2]),C=r[3]?Number(r[3]):0;return{passed:f-C,failed:C,total:g,framework:"karma"}}let s=n.match(Ka);if(s&&/playwright/i.test(n)){let f=Number(s[1]),g=s[2]?Number(s[2]):0;return{passed:f,failed:g,total:f+g,framework:"playwright"}}let o=n.match(Va);if(o){let f=o[1]?Number(o[1]):0,g=Number(o[2]);return{passed:g,failed:f,total:g+f,durationMs:Math.round(Number(o[3])*1e3),framework:"pytest",failedTests:f>0?Un(n):void 0}}let i=n.match(Za);if(i){let f=Number(i[1]),g=Number(i[2]);return{passed:f-g,failed:g,total:f,framework:"rspec"}}let a=n.match(tc);if(a){let f=Number(a[1]),g=Number(a[2]);return{passed:f,failed:g,total:f+g,framework:"cargo"}}let c=0,l=0,u=0,d=!1;for(let f of n.split(/\r?\n/)){let g=f.match(Qa);g&&(d=!0,u+=Math.round(Number(g[2])*1e3),g[1]==="ok"?c++:l++)}if(d)return{passed:c,failed:l,total:c+l,durationMs:u,framework:"go"};if(s){let f=Number(s[1]),g=s[2]?Number(s[2]):0;return{passed:f,failed:g,total:f+g,framework:"playwright"}}return null}function Cs(n,t,e){let r=e.length?" -- "+e.join(" "):"";return n.workspaceType==="nx"?`npx nx run ${n.name}:${t}${r}`:n.workspaceType==="angular"?`npx ng run ${n.name}:${t}${r}`:`npx ${t}${r}`}function Rs(n,t,e=[]){return new Promise(r=>{let s=Date.now(),o=Cs(n,t,e),i=Ts(o,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),a=[],c="",l=u=>{c+=u.toString("utf8");let d=c.lastIndexOf(`
56
+ `);if(d<0)return;let f=c.slice(0,d);c=c.slice(d+1);for(let g of f.split(/\r?\n/)){if(!g.length)continue;let C=Ps(g);a.push(C),a.length>1e3&&a.splice(0,a.length-1e3)}};i.stdout?.on("data",l),i.stderr?.on("data",l),i.on("exit",u=>{let d=Date.now()-s,f=a.join(`
57
+ `)+(c?`
58
+ `+c:""),g=sc(f);r({app:n.name,task:t,exitCode:u,durationMs:d,summary:g,outputTail:a.slice(-50)})}),i.on("error",()=>{r({app:n.name,task:t,exitCode:-1,durationMs:Date.now()-s,summary:null,outputTail:[...a,"[daimon] task spawn error"]})})})}function Es(n,t,e=[]){let r=Cs(n,t,e),s=Ts(r,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),o=[],i="",a=l=>{i+=l.toString("utf8");let u=i.lastIndexOf(`
59
+ `);if(u<0)return;let d=i.slice(0,u);i=i.slice(u+1);for(let f of d.split(/\r?\n/))f.length&&(o.push(Ps(f)),o.length>500&&o.splice(0,o.length-500))};return s.stdout?.on("data",a),s.stderr?.on("data",a),{app:n.name,task:t,pid:s.pid??null,child:s,startedAt:Date.now(),logs:o,stop:()=>new Promise(l=>{if(!s.pid){l();return}let u=!1,d=()=>{u||(u=!0,l())};s.once("exit",d),xs(s.pid,"SIGTERM",()=>{}),setTimeout(()=>{s.pid&&xs(s.pid,"SIGKILL",()=>{})},2e3),setTimeout(d,3500)})}}var qa,Ga,Xa,Ka,za,Ya,Va,Za,Qa,tc,ec,nc,rc,As=U(()=>{"use strict";qa=/Tests:\s+(?:(\d+)\s+failed,\s+)?(?:(\d+)\s+skipped,\s+)?(\d+)\s+passed(?:,\s+(\d+)\s+total)?/,Ga=/Test Suites:\s+(?:(\d+)\s+failed,\s+)?(\d+)\s+passed(?:,\s+(\d+)\s+total)?/,Xa=/Executed (\d+) of (\d+)(?:\s*\((\d+)\s*FAILED\))?/,Ka=/(\d+)\s+passed(?:.*?(\d+)\s+failed)?/i,za=/Tests\s+(?:(\d+)\s+failed\s*\|\s*)?(\d+)\s+passed(?:\s*\((\d+)\))?/,Ya=/Test Files\s+(?:(\d+)\s+failed\s*\|\s*)?(\d+)\s+passed(?:\s*\((\d+)\))?/,Va=/(?:(\d+)\s+failed,\s+)?(\d+)\s+passed(?:,\s+\d+\s+skipped)?\s+in\s+([\d.]+)s/,Za=/(\d+)\s+examples?,\s+(\d+)\s+failures?/,Qa=/^(ok|FAIL|---\s+FAIL)\s+\S+\s+([\d.]+)s/,tc=/test result:\s*(?:ok|FAILED)\.\s+(\d+)\s+passed;\s+(\d+)\s+failed/,ec=/^\s*✕\s+(.+?)(?:\s+\((\d+)\s*ms\))?$/,nc=/^\s*FAIL\s+(\S+\.(?:tsx?|jsx?|mjs|cjs|spec\.[a-z]+))/,rc=/^FAILED\s+(\S+)::([^\s]+)/});import Ns from"node:fs";import Os from"node:path";function $s(n){let t={},e;try{e=Ns.readFileSync(n,"utf8")}catch{return t}for(let r of e.split(/\r?\n/)){let s=r.trim();if(!s||s.startsWith("#"))continue;let o=s.indexOf("=");if(o<0)continue;let i=s.slice(0,o).trim(),a=s.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),i&&(t[i]=a)}return t}function Hn(n,t){return Os.isAbsolute(t)?t:Os.join(n,t)}function Jn(n,t){return t.filter(e=>Ns.existsSync(Hn(n,e)))}var Ms=U(()=>{"use strict"});import oc from"node:fs";import ic from"node:path";function ac(){return ic.join(mt(),"secrets.json")}function js(){try{let n=oc.readFileSync(ac(),"utf8");n.charCodeAt(0)===65279&&(n=n.slice(1));let t=JSON.parse(n);if(!t||typeof t!="object")return{};let e={};for(let[r,s]of Object.entries(t))typeof s=="string"&&(e[r]=s);return e}catch{return{}}}function _s(n,t){let e={};for(let[r,s]of Object.entries(n))e[r]=s.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,(o,i)=>t[i]??`\${${i}}`);return e}var Ds=U(()=>{"use strict";Pt()});import{EventEmitter as cc}from"node:events";var Ls,Ye,Is=U(()=>{"use strict";Bn();Ss();xe();ks();ke();As();On();Ms();Ds();Nn();Ls=500,Ye=class extends cc{entries=new Map;portAlloc;config;eventBuffer=[];history=null;watchTasks=new Map;sessionRecorder=new Ue;constructor(t,e,r){super(),this.config=t,this.portAlloc=r??new re(t.portRange);for(let s of e)this.entries.set(s.name,{app:s,state:this.freshState(s.name,s.baseName??s.name,s.tags,s.workspaceLabel??null,s.workspaceRoot??null),proc:null})}getConfig(){return this.config}addDiscoveredApp(t){this.entries.has(t.name)||(this.entries.set(t.name,{app:t,state:this.freshState(t.name,t.baseName??t.name,t.tags,t.workspaceLabel??null,t.workspaceRoot??null),proc:null}),this.emit("change"))}updateDiscoveredApp(t){let e=this.entries.get(t.name);e&&(e.app=t,e.state.tags=t.tags,e.state.workspaceLabel=t.workspaceLabel??null,e.state.workspaceRoot=t.workspaceRoot??null,e.state.baseName=t.baseName??t.name,e.state.dependsOn=this.config.depends?.[t.baseName??t.name]??[],this.emit("change"))}getPortAllocator(){return this.portAlloc}setHistory(t){this.history=t}getHistory(){return this.history}freshState(t,e,r,s=null,o=null){return{name:t,status:"stopped",port:null,pid:null,startedAt:null,compileStartedAt:null,lastCompileMs:null,lastCompileAt:null,logBuffer:[],errors:new Map,compileHistory:[],health:"unknown",lastHealthAt:null,cpu:null,memMB:null,restartAttempts:0,restartWindowStart:null,nextRestartAt:null,tags:r,announcedUrl:null,lastHealthError:null,cachedProbeHost:null,lastLogTs:null,stale:!1,bundle:null,bundleRegressionPct:null,activeEnvFile:null,sessionOverrides:null,dependsOn:this.config.depends?.[e]??[],workspaceLabel:s,workspaceRoot:o,baseName:e,discoveredHealthPath:null}}names(){return[...this.entries.keys()]}resolveByCwd(t,e){let s=[...this.entries.values()].filter(i=>i.state.name===t||(i.state.baseName??i.state.name)===t);e&&(s=s.filter(i=>{let a=i.app.workspaceRoot;return a?Ct(a,e)||Ct(e,a):!1}));let o=s.map(i=>({name:i.state.name,baseName:i.state.baseName??i.state.name,workspaceLabel:i.state.workspaceLabel,workspaceRoot:i.state.workspaceRoot??i.app.workspaceRoot??null}));return s.length===0?{kind:"none",candidates:o}:s.length>1?{kind:"collision",candidates:o}:{kind:"unique",key:s[0].state.name,candidates:o}}pruneOldErrors(t=Date.now()){let e=this.config.errorRetention?.maxAgeMs??864e5,r=0;for(let s of this.entries.values())for(let[o,i]of s.state.errors)t-i.lastSeen>e&&(s.state.errors.delete(o),r++);return r}list(){return this.names().map(t=>this.summary(t))}summary(t){let e=this.entries.get(t);if(!e)return null;let r=e.state,s=r.startedAt&&(r.status==="serving"||r.status==="compiling"||r.status==="starting")?Date.now()-r.startedAt:null,i=this.config.overrides?.[t]?.url||e.resolvedUrl||r.announcedUrl||(r.port?`http://127.0.0.1:${r.port}`:null),a;for(let c=this.eventBuffer.length-1;c>=0;c--){let l=this.eventBuffer[c];if(l.app===t&&l.type==="status"){a=Date.now()-l.ts;break}}return{name:r.name,status:r.status,port:r.port,url:i,errorCount:[...r.errors.values()].reduce((c,l)=>{let u=l.level??"error";return c+(u==="error"?l.count:0)},0),warningCount:[...r.errors.values()].reduce((c,l)=>c+(l.level==="warning"?l.count:0),0),lintCount:[...r.errors.values()].reduce((c,l)=>c+(l.level==="lint"?l.count:0),0),uptimeMs:s,lastCompileMs:r.lastCompileMs,health:r.health,lastHealthAt:r.lastHealthAt,cpu:r.cpu,memMB:r.memMB,compileHistoryMs:[...r.compileHistory],tags:[...r.tags],restartAttempts:r.restartAttempts,nextRestartAt:r.nextRestartAt,announcedUrl:r.announcedUrl,lastHealthError:r.lastHealthError,stale:r.stale,bundle:r.bundle,bundleRegressionPct:r.bundleRegressionPct,dependsOn:[...r.dependsOn],activeEnvFile:r.activeEnvFile,workspaceLabel:r.workspaceLabel,workspaceRoot:r.workspaceRoot,baseName:r.baseName??r.name,lastChangeMs:a}}getState(t){return this.entries.get(t)?.state??null}getApp(t){return this.entries.get(t)?.app??null}errors(t){let e=this.getState(t);return e?[...e.errors.values()].sort((r,s)=>s.lastSeen-r.lastSeen):null}errorsSince(t,e){let r=this.getState(t);return r?[...r.errors.values()].filter(s=>s.lastSeen>e).sort((s,o)=>o.lastSeen-s.lastSeen):null}logs(t,e={}){let r=this.getState(t);if(!r)return null;let s=r.logBuffer;if(e.sinceMs&&e.sinceMs>0){let o=Date.now()-e.sinceMs;s=s.filter(i=>i.ts>=o)}return e.tail&&e.tail>0&&(s=s.slice(-e.tail)),s.map(o=>o.line)}events(t={}){let e=t.sinceMs&&t.sinceMs>0?Date.now()-t.sinceMs:0;return this.eventBuffer.filter(r=>r.ts>=e&&(!t.app||r.app===t.app))}recordEvent(t){let e={ts:t.ts??Date.now(),...t};this.eventBuffer.push(e),this.emit("event",e),this.eventBuffer.length>Ls&&this.eventBuffer.splice(0,this.eventBuffer.length-Ls),this.history?.recordEvent(e),this.emit("event",e)}setHealth(t,e){let r=this.entries.get(t);if(!r)return;let s=r.state;if(s.lastHealthAt=Date.now(),s.health===e)return;let o=s.health;s.health=e,e==="healthy"&&(r.prevHealthyAt=Date.now(),r.cascadeArmed&&(r.cascadeArmed=!1,this.triggerCascadeRestart(t))),this.recordEvent({app:t,type:"health",from:o,to:e}),this.emit("change")}armCascade(t){let e=this.entries.get(t);e&&this.config.cascadeRestart&&e.prevHealthyAt!=null&&(e.cascadeArmed=!0)}setLastHealthError(t,e){let r=this.getState(t);r&&r.lastHealthError!==e&&(r.lastHealthError=e,this.emit("change"))}setResolvedUrl(t,e){let r=this.entries.get(t);r&&r.resolvedUrl!==e&&(r.resolvedUrl=e,this.emit("change"))}setCachedProbeHost(t,e){let r=this.getState(t);r&&(r.cachedProbeHost=e)}setStale(t,e){let r=this.getState(t);r&&r.stale!==e&&(r.stale=e,this.emit("change"))}setSessionOverride(t,e){let r=this.getState(t);r&&(r.sessionOverrides=e,this.emit("change"))}setActiveEnvFile(t,e){let r=this.getState(t);r&&(r.activeEnvFile=e,this.emit("change"))}async start(t){this.sessionRecorder.append({kind:"start",app:t});let e=this.entries.get(t);if(!e)return{ok:!1,status:"unknown",error:"unknown app"};if(e.proc?.isRunning())return{ok:!0,status:e.state.status};let r=e.state.status,s;try{s=await this.portAlloc.allocate(t,e.app.pinnedPort)}catch(g){return e.state.status="error",e.state.lastStatusMessage=g.message,this.recordEvent({app:t,type:"status",from:r,to:"error",message:g.message}),this.emit("change"),{ok:!1,status:"error",error:g.message}}if(!await Mt(s)){let g=Fe(s),C=Lr(s,g);return e.state.status="error",e.state.port=s,e.state.lastStatusMessage=C,this.recordEvent({app:t,type:"status",from:r,to:"error",message:C}),this.emit("change"),{ok:!1,status:"error",error:C}}e.state.health="unknown",e.state.lastHealthAt=null,e.state.announcedUrl=null,e.state.lastHealthError=null,e.state.cachedProbeHost=null,e.state.stale=!1,e.state.lastLogTs=null,e.resolvedUrl=void 0,!e.logger&&this.config.logs.enabled&&(e.logger=new ze(t,this.config.logs));let i=e.state.sessionOverrides,a=this.config.envFiles?.[t]??[],c={};if(a.length){let g=e.state.activeEnvFile;(!g||!Jn(e.app.workspaceRoot,[g]).length)&&(g=Jn(e.app.workspaceRoot,a)[0]??null,g&&(e.state.activeEnvFile=g)),g&&(c=$s(Hn(e.app.workspaceRoot,g)))}let l={...c,...this.config.overrides?.[t]?.env??{},...i?.env??{}},u=js(),d=_s(l,u),f=new Ke({state:e.state,app:e.app,port:s,envOverride:Object.keys(d).length?d:void 0,commandOverride:i?.command,onStateChange:()=>this.emit("change"),onStatusChange:(g,C,R)=>{this.recordEvent({app:t,type:"status",from:g,to:C,message:R}),(C==="stopped"||C==="error")&&(g==="serving"||g==="compiling")&&this.armCascade(t)},onErrorRecorded:(g,C)=>{let R=g.level??"error",y;R==="lint"?y=C?"lint-new":"lint-recur":R==="warning"?y=C?"warning-new":"warning-recur":y=C?"error-new":"error-recur",this.recordEvent({app:t,type:y,message:g.message})},onExit:(g,C,R)=>this.emit("childExit",{name:t,code:g,signal:C,stopping:R}),onLogLine:g=>{e.logger?.write(g),this.emit("log",{name:t,ts:Date.now(),line:g})},onCompile:g=>{this.history?.recordCompile(t,g);let C=this.getState(t),R=e.lastBundleInitialKB;if(C.bundle&&C.bundle.initialKB>0){if(R&&R>0){let y=(C.bundle.initialKB-R)/R*100;C.bundleRegressionPct=Math.round(y*10)/10,y>10&&this.recordEvent({app:t,type:"bundle-regression",message:`initialKB +${C.bundleRegressionPct}% (${R}->${C.bundle.initialKB})`})}else C.bundleRegressionPct=null;e.lastBundleInitialKB=C.bundle.initialKB}this.checkCompileRegression(t,g),this.emit("compile",{name:t,ms:g})},onBundleUpdate:()=>{let g=this.getState(t);g?.bundle&&(g.bundle.initialKB>0||g.bundle.lazyKB>0)&&this.history?.recordBundle(t,g.bundle.initialKB,g.bundle.lazyKB,g.bundle.files.length),this.emit("bundleUpdate",{name:t})}});return e.proc=f,this.recordEvent({app:t,type:"status",from:r,to:"starting"}),f.start(),{ok:!0,status:e.state.status}}async stop(t){this.sessionRecorder.append({kind:"stop",app:t});let e=this.entries.get(t);if(!e)return{ok:!1,status:"unknown",error:"unknown app"};if(this.emit("userStop",{name:t}),!e.proc||!e.proc.isRunning())return e.state.status!=="stopped"&&this.recordEvent({app:t,type:"status",from:e.state.status,to:"stopped"}),e.state.status="stopped",e.state.pid=null,e.state.health="unknown",this.emit("change"),{ok:!0,status:"stopped"};let r=e.state.status;return await e.proc.stop(),e.proc=null,e.state.status!==r&&this.recordEvent({app:t,type:"status",from:r,to:e.state.status}),{ok:!0,status:e.state.status}}async restart(t){return this.sessionRecorder.append({kind:"restart",app:t}),await this.stop(t),this.start(t)}async startWithDeps(t,e={}){if(!this.entries.has(t))return{ok:!1,results:[{name:t,status:"unknown",health:"unknown",error:"unknown app"}]};let r=De(this.config.depends??{},t).filter(a=>this.entries.has(a)),s=Le(this.config.depends??{},r),o=[],i=e.waitMs??6e4;for(let a of s){let c=await Promise.all(a.map(u=>this.start(u)));for(let u=0;u<a.length;u++){let d=c[u];if(!d.ok)return o.push({name:a[u],status:d.status,health:"unknown",error:d.error}),{ok:!1,results:o}}let l=await Promise.all(a.map(u=>this.waitFor(u,"healthy",i)));for(let u=0;u<a.length;u++){let d=l[u],f=!d.timedOut&&d.status==="serving"&&d.health==="healthy";if(o.push({name:d.name,status:d.status,health:d.health,error:f?void 0:d.timedOut?"timeout waiting for healthy":"did not reach healthy"}),!f)return{ok:!1,results:o}}}return{ok:!0,results:o}}triggerCascadeRestart(t){if(!this.config.cascadeRestart)return;let e=jr(this.config.depends??{},t);for(let r of e){let s=this.getState(r);s&&(s.status==="serving"||s.status==="compiling"||s.status==="starting")&&this.restart(r)}}async stopAll(t=3e3){let e=[];for(let r of this.entries.values())r.proc?.isRunning()&&e.push(r.proc.stop());for(let r of this.watchTasks.values())e.push(r.stop());await Promise.race([Promise.all(e),new Promise(r=>setTimeout(r,t))]);for(let r of this.entries.values())r.logger?.close()}listTasks(t){let e=this.getApp(t);return e?[...e.tasks??[]]:null}async runTask(t,e,r=[]){this.sessionRecorder.append({kind:"run",app:t,task:e,args:r});let s=this.getApp(t);if(!s)return{error:"unknown app"};let o=await Rs(s,e,r);return this.history?.recordTaskRun(t,e,o.exitCode,o.durationMs,o.summary),this.recordEvent({app:t,type:"task-run",message:`${e} exit=${o.exitCode} duration=${o.durationMs}ms`}),this.emit("taskRun",{name:t,task:e,result:o}),o}startWatchTask(t,e,r=[]){let s=this.getApp(t);if(!s)return{ok:!1,error:"unknown app"};let o=`${t}::${e}`;if(this.watchTasks.has(o))return{ok:!0,pid:this.watchTasks.get(o).pid};let i=Es(s,e,r);return this.watchTasks.set(o,i),i.child.on("exit",()=>this.watchTasks.delete(o)),{ok:!0,pid:i.pid}}async stopWatchTask(t,e){let r=`${t}::${e}`,s=this.watchTasks.get(r);return s?(await s.stop(),this.watchTasks.delete(r),{ok:!0}):{ok:!0}}listWatchTasks(t){let e=[];for(let r of this.watchTasks.values())t&&r.app!==t||e.push({app:r.app,task:r.task,pid:r.pid,startedAt:r.startedAt});return e}checkCompileRegression(t,e){let r=this.history;if(!r)return;let o=r.queryCompiles({app:t,limit:31}).filter(c=>c.ms!==e).slice(0,30).map(c=>c.ms);if(o.length<10)return;let i=[...o].sort((c,l)=>c-l),a=i[Math.floor((i.length-1)*.5)];e>2*a&&this.recordEvent({app:t,type:"compile-regression",message:`${(e/1e3).toFixed(1)}s vs p50 ${(a/1e3).toFixed(1)}s`})}watchTaskLogs(t,e,r){let s=this.watchTasks.get(`${t}::${e}`);if(!s)return null;let o=s.logs;return r?o.slice(-r):[...o]}waitFor(t,e,r){return new Promise(s=>{let o=Date.now(),i=this.entries.get(t),a=()=>{if(!i)return!0;let d=i.state;return e==="serving"&&d.status==="serving"||e==="healthy"&&d.status==="serving"&&d.health==="healthy"||e==="stopped"&&d.status==="stopped"||e==="error"&&d.status==="error"},c=d=>{this.off("change",l),clearTimeout(u);let f=i?.state;s({name:t,status:f?.status??"unknown",health:f?.health??"unknown",timedOut:d,waitedMs:Date.now()-o})},l=()=>{a()&&c(!1)};if(a()){s({name:t,status:i.state.status,health:i.state.health,timedOut:!1,waitedMs:0});return}let u=setTimeout(()=>c(!0),r);this.on("change",l)})}}});import Gn from"node:fs";import Fs from"node:path";import lc from"node:os";function uc(){try{let n=Gn.readFileSync(Xn,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.errors&&typeof t.errors=="object")return{errors:t.errors}}catch{}return{errors:{}}}function pc(n){qn=n,!Wn&&(Wn=setTimeout(()=>{Wn=null;let t=qn;if(qn=null,!!t)try{Gn.mkdirSync(Fs.dirname(Xn),{recursive:!0}),Gn.writeFileSync(Xn,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: cursor write failed: ${e.message}
60
+ `)}},500))}var Xn,Wn,qn,Ve,Bs=U(()=>{"use strict";Xn=Fs.join(lc.homedir(),".daimon","cursors.json");Wn=null,qn=null;Ve=class{data=uc();getErrorCursor(t,e){return this.data.errors[`${t}:${e}`]??0}setErrorCursor(t,e,r){this.data.errors[`${t}:${e}`]=r,pc(this.data)}}});import Us from"node:fs";import dc from"node:os";import Hs from"node:path";function mc(n){let t={};for(let[e,r]of Object.entries(n))typeof r=="string"&&(t[e]=fc.test(e)?"***":r);return t}function Kn(n,t){let e=n.summary(t);if(!e)return null;let r=n.getState(t),s=n.getApp(t),o=n.getConfig(),i=o.overrides?.[t]??{},a={...process.env,...s.env??{},...r.sessionOverrides?.env??{}},c=n.getHistory(),l=c?c.queryEvents({app:t,limit:50}):[],u=c?c.queryBundles({app:t,limit:100}):[],d=c?c.querySelfMetrics({limit:60}):[];return{takenAt:new Date().toISOString(),summary:e,logs:r.logBuffer.slice(-500).map(f=>({ts:f.ts,line:f.line})),errors:[...r.errors.entries()].map(([f,g])=>({hash:f,message:g.message,count:g.count,firstSeen:g.firstSeen,lastSeen:g.lastSeen})),env:mc(a),configSlice:{command:r.sessionOverrides?.command??i.command??s.command,port:r.sessionOverrides?.port??i.port??null,workspaceRoot:s.workspaceRoot,workspaceType:s.workspaceType,tags:s.tags,depends:o.depends?.[t]??[],envFiles:o.envFiles?.[t]??[]},events:l,bundles:u,selfMetrics:d}}function Js(n,t){let e=Kn(n,t);if(!e)return null;let r=Hs.join(dc.homedir(),".daimon","snapshots");Us.mkdirSync(r,{recursive:!0});let s=e.takenAt.replace(/[:.]/g,"-"),o=Hs.join(r,`${t}-${s}.json`);return Us.writeFileSync(o,JSON.stringify(e,null,2)),{path:o,payload:e}}var fc,Ws=U(()=>{"use strict";fc=/key|secret|token|password|api[-_]?key/i});import Ze from"node:fs";import qs from"node:path";function Gs(n){let t=0;try{let e=Ze.readdirSync(n,{withFileTypes:!0});for(let r of e){let s=qs.join(n,r.name);try{r.isDirectory()?t+=Gs(s):r.isFile()&&(t+=Ze.statSync(s).size)}catch{}}}catch{}return t}function zn(n,t,e){let r=n.getApp(t);if(!r)return null;let s=n.getState(t),o=s?s.status==="serving"||s.status==="compiling"||s.status==="starting":!1,a=[...hc,...e?gc:[]].map(c=>{let l=qs.join(r.workspaceRoot,c),u=Ze.existsSync(l);return{path:l,exists:u,sizeBytes:u?Gs(l):0}});return{app:t,workspace:r.workspaceRoot,targets:a,ranOnServing:o}}function Xs(n,t,e){let r=zn(n,t,e);if(!r)return{error:"unknown app"};if(r.ranOnServing)return{error:"app is currently running; stop it first"};let s=[],o=[];for(let i of r.targets)if(i.exists)try{Ze.rmSync(i.path,{recursive:!0,force:!0}),s.push(i.path)}catch(a){o.push({path:i.path,error:a?.message||String(a)})}return{ok:o.length===0,removed:s,failed:o}}var hc,gc,Ks=U(()=>{"use strict";hc=["dist",".angular/cache","tmp","out-tsc"],gc=["node_modules"]});function Pe(n){return n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}function zs(n){let t=[];t.push("# HELP daimon_up daimon daemon up"),t.push("# TYPE daimon_up gauge"),t.push("daimon_up 1"),t.push("# HELP daimon_app_status app status one-hot"),t.push("# TYPE daimon_app_status gauge");let e=n.list();for(let r of e)for(let s of yc)t.push(`daimon_app_status{name="${Pe(r.name)}",status="${s}"} ${r.status===s?1:0}`);t.push("# HELP daimon_compile_seconds last successful compile duration in seconds"),t.push("# TYPE daimon_compile_seconds gauge");for(let r of e)r.lastCompileMs!=null&&t.push(`daimon_compile_seconds{name="${Pe(r.name)}"} ${(r.lastCompileMs/1e3).toFixed(3)}`);t.push("# HELP daimon_error_total cumulative deduped error count"),t.push("# TYPE daimon_error_total counter");for(let r of e)t.push(`daimon_error_total{name="${Pe(r.name)}"} ${r.errorCount}`);t.push("# HELP daimon_cpu_percent app CPU percent"),t.push("# TYPE daimon_cpu_percent gauge");for(let r of e)r.cpu!=null&&t.push(`daimon_cpu_percent{name="${Pe(r.name)}"} ${r.cpu}`);t.push("# HELP daimon_mem_mb app resident memory MB"),t.push("# TYPE daimon_mem_mb gauge");for(let r of e)r.memMB!=null&&t.push(`daimon_mem_mb{name="${Pe(r.name)}"} ${r.memMB}`);return t.join(`
61
61
  `)+`
62
- `}var ec,Ls=F(()=>{"use strict";ec=["stopped","starting","compiling","serving","error"]});import ge from"node:fs";import nc from"node:crypto";import Is from"node:path";function sc(){return Is.join(ut(),"audit.log")}function oc(n){try{if(ge.statSync(n).size>rc){let e=n+".1";try{ge.unlinkSync(e)}catch{}ge.renameSync(n,e)}}catch{}}function Fs(n,t,e,r){let s=sc();ge.mkdirSync(Is.dirname(s),{recursive:!0}),oc(s);let o=JSON.stringify({prev:t,next:e}),i=nc.createHash("sha1").update(o).digest("hex").slice(0,12),a=`${new Date().toISOString()} ${n} ${i} ${r.join(",")}
63
- `;try{ge.appendFileSync(s,a)}catch{}}var rc,Bs=F(()=>{"use strict";bt();rc=1e6});import Fe from"node:fs";import Be from"node:path";import{fileURLToPath as ic}from"node:url";function ac(){let n=[Be.resolve(Us,"templates","presets"),Be.resolve(Us,"..","src","templates","presets")];for(let t of n)if(Fe.existsSync(t))return t;return n[0]}function Hs(){let n=ac();if(!Fe.existsSync(n))return[];let t=Fe.readdirSync(n).filter(r=>r.endsWith(".json")),e=[];for(let r of t)try{let s=Fe.readFileSync(Be.join(n,r),"utf8");s.charCodeAt(0)===65279&&(s=s.slice(1)),e.push(JSON.parse(s))}catch{}return e}var Us,Js=F(()=>{"use strict";Us=Be.dirname(ic(import.meta.url))});import Ue from"node:fs";import Ws from"node:path";function Gs(){return Ws.join(ut(),"state-handoff.json")}function qs(n){let t=[];for(let s of n.names()){let o=n.getState(s);o&&(o.status==="serving"||o.status==="compiling"||o.status==="starting")&&o.port&&t.push({name:s,port:o.port})}let e={ts:Date.now(),apps:t},r=Gs();return Ue.mkdirSync(Ws.dirname(r),{recursive:!0}),Ue.writeFileSync(r,JSON.stringify(e)),r}function Xs(n=6e4){let t=Gs();try{let e=Ue.readFileSync(t,"utf8"),r=JSON.parse(e);return Ue.unlinkSync(t),!r||typeof r.ts!="number"||Date.now()-r.ts>n?null:r}catch{return null}}var _n=F(()=>{"use strict";bt()});var re={};yt(re,{ALL_AUTO_FIX:()=>Ks,runAutoFix:()=>Pc});import B from"node:fs";import K from"node:path";function cc(){let n=ot();if(!n)return{detected:!1,description:"no daemon running"};let t=process.cwd(),e=K.join(t,"daimon.config.json");if(!B.existsSync(e))return{detected:!1,description:"no local daimon.config.json in cwd"};let r=n.cwd,s=n.configPath,o=r&&K.resolve(r)===K.resolve(t),i=s&&K.resolve(s)===K.resolve(e);return o||i?{detected:!1,description:"daemon already running from this cwd/config"}:{detected:!0,description:`daemon (pid ${n.pid}) is running from ${r??"(unknown)"} but local daimon.config.json exists at ${t}`,lockCwd:r}}async function lc(){let n=ot();if(!n)return"no daemon running; nothing to do";try{await fetch(`http://127.0.0.1:${n.apiPort}/api/snapshot-state`,{method:"POST"})}catch{}try{await fetch(`http://127.0.0.1:${n.apiPort}/api/shutdown`,{method:"POST"})}catch{}return await Bt(n.pid,5e3),wt(),`respawned daemon at pid ${(await Pt({})).pid} from ${process.cwd()}; previous pid ${n.pid} (cwd ${n.cwd??"unknown"}) was shut down with state handoff. To undo: stop with 'daimon daemon stop' and start from the prior directory.`}function uc(){let n;try{n=B.readFileSync(Ae(),"utf8")}catch{return{detected:!1,description:"no lock file present"}}let t;try{t=JSON.parse(n)}catch{return{detected:!0,description:"lock file is malformed JSON"}}if(!t||typeof t.pid!="number")return{detected:!0,description:"lock file has no pid"};try{return process.kill(t.pid,0),{detected:!1,description:`lock file owner pid ${t.pid} is alive`}}catch(e){return e?.code==="EPERM"?{detected:!1,description:`lock file owner pid ${t.pid} alive (EPERM)`}:{detected:!0,description:`lock file claims pid ${t.pid} but the process is gone`}}}async function pc(){let n="(unknown)";try{let e=JSON.parse(B.readFileSync(Ae(),"utf8"));n=String(e?.pid??"?")}catch{}wt();let t=await Pt({});return`removed stale ${Ae()} (prior pid ${n} was dead); spawned fresh daemon at pid ${t.pid}.`}function dc(){let n=process.cwd(),e=["nx.json","angular.json","vite.config.ts","vite.config.js","vite.config.mjs","vite.config.cjs",".storybook"].filter(i=>B.existsSync(K.join(n,i)));if(!e.length)return{detected:!1,description:"no nx.json/angular.json/vite.config.*/.storybook in cwd"};let r=st();return r.kind!=="loaded"?{detected:!0,description:`${e.join(", ")} present but no config is loaded`,markerFiles:e}:r.config.searchRoots.map(i=>K.resolve(typeof i=="string"?i:i.path)).some(i=>n.startsWith(i))?{detected:!1,description:`${e.join(", ")} present and a configured searchRoot covers ${n}`}:{detected:!0,description:`${e.join(", ")} present in ${n} but no searchRoot covers it`,markerFiles:e}}function fc(){let n=process.cwd(),{local:t,user:e}=Lt(),r=B.existsSync(t)?t:e,s={};try{s=JSON.parse(B.readFileSync(r,"utf8"))}catch{}if(s.searchRoots=Array.isArray(s.searchRoots)?s.searchRoots:[],!s.searchRoots.some(i=>(typeof i=="string"?i:i?.path)===n)){let i;try{let a=JSON.parse(B.readFileSync(K.join(n,"package.json"),"utf8"));typeof a.name=="string"&&(i=a.name)}catch{}s.searchRoots.push(i?{path:n,label:i}:n)}B.mkdirSync(K.dirname(r),{recursive:!0}),B.writeFileSync(r,JSON.stringify(s,null,2)+`
64
- `,"utf8");let o=ot();if(o)try{fetch(`http://127.0.0.1:${o.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`appended ${n} as a searchRoot in ${r}; triggered soft-reload of the running daemon.`}function mc(){let n=st();if(n.kind!=="loaded"||!n.config.history.enabled)return{detected:!1,description:"history disabled"};let t=n.config.history.path;if(!B.existsSync(t))return{detected:!1,description:"history db does not exist (will be created on next start)"};try{let e=new Ct(n.config.history),r=e.quickCheck();return e.close(),r?{detected:!1,description:"history db quick_check passed"}:{detected:!0,description:`quick_check failed on ${t}`,dbPath:t}}catch(e){return{detected:!0,description:`cannot open ${t}: ${e?.message??String(e)}`,dbPath:t}}}function hc(){let n=st();if(n.kind!=="loaded")return"no config; cannot determine history path";let t=n.config.history.path,e=`${t}.corrupt-${Date.now()}`;for(let r of["","-wal","-shm"])try{B.renameSync(t+r,e+r)}catch{}return`rotated ${t} \u2192 ${e} (and -wal/-shm siblings). The daemon will rebuild an empty history db on next start.`}async function gc(){let n=st();if(n.kind!=="loaded")return{detected:!1,description:"no config loaded"};let[t,e]=n.config.portRange??[4200,4299],r=n.config.overrides??{},s=Object.values(r).map(a=>a.port).filter(a=>typeof a=="number"),o=Array.from(new Set([...s,t,e])),i=[];for(let a of o)if(!(!Number.isFinite(a)||a<=0))try{await Tt(a)||i.push(a)}catch{}return i.length?{detected:!0,description:`ports already LISTEN: ${i.join(", ")} (range ${t}-${e} + pinned overrides)`,conflicts:i}:{detected:!1,description:`all checked ports free (range ${t}-${e} + pinned)`}}function yc(){return"no automated fix \u2014 predictive rule only. Run `daimon free-port <port>` to inspect the holder, or pick a different port in daimon.config.json. To undo: nothing was changed."}function wc(){let n=process.cwd(),t=process.versions.node,e=K.join(n,".nvmrc");if(B.existsSync(e)){let s=B.readFileSync(e,"utf8").trim().replace(/^v/i,"");if(s&&!t.startsWith(s))return{detected:!0,description:`.nvmrc requires ${s}, running ${t}`,expected:s,actual:t}}let r=K.join(n,"package.json");if(B.existsSync(r))try{let o=JSON.parse(B.readFileSync(r,"utf8"))?.engines?.node;if(typeof o=="string"&&o.trim()){let i=o.match(/(\d+)(?:\.(\d+))?/);if(i){let a=Number(i[1]),l=Number(t.split(".")[0]);if(Number.isFinite(a)&&Number.isFinite(l)&&l<a)return{detected:!0,description:`package.json engines.node = "${o}" but running ${t}`,expected:o,actual:t}}}}catch{}return{detected:!1,description:`node ${t} satisfies .nvmrc / engines.node (or neither is present)`}}function bc(){return"no automated fix \u2014 switching Node versions touches the user environment. Run `nvm use` (or your version manager equivalent) in this directory, then re-run daimon. To undo: nothing was changed."}function vc(){let n=st();if(n.kind!=="loaded")return[];let t=[],e=new Set;for(let r of n.config.searchRoots){let s=typeof r=="string"?r:r.path;if(!s||!B.existsSync(s)||e.has(s))continue;e.add(s);let o=K.join(s,"package.json");if(!B.existsSync(o))continue;let i=null;for(let a of["package-lock.json","pnpm-lock.yaml","yarn.lock"]){let l=K.join(s,a);if(B.existsSync(l)){i=l;break}}t.push({name:K.basename(s),root:s,pkgPath:o,lockPath:i,nmPath:K.join(s,"node_modules")})}return t}function zs(){let n=vc();if(!n.length)return{detected:!1,description:"no searchRoots with package.json found"};let t=[];for(let r of n){if(!B.existsSync(r.nmPath)){t.push({root:r.root,reason:"missing"});continue}if(r.lockPath)try{let s=B.statSync(r.lockPath).mtimeMs,o=B.statSync(r.nmPath).mtimeMs;s>o+1e3&&t.push({root:r.root,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`node_modules issues \u2014 ${t.map(r=>`${r.reason}: ${r.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every searchRoot package.json has a fresh node_modules"}}function Sc(){let n=zs();return!n.detected||!n.entries?"nothing to suggest":`would suggest: ${n.entries.map(e=>`(cd "${e.root}" && npm install)`).join(" && ")}. Daimon does not run package managers on your behalf \u2014 run the command(s) yourself. To undo: nothing was changed.`}function Dn(){let n=st();if(n.kind!=="loaded")return[];let t=[],e=new Set;for(let r of n.config.searchRoots){let s=typeof r=="string"?r:r?.path;!s||!B.existsSync(s)||e.has(s)||(e.add(s),t.push(s))}return t}function Ys(){let n=Dn();if(!n.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let r of n){let s=K.join(r,"pyproject.toml"),o=K.join(r,"requirements.txt"),i=K.join(r,"manage.py");if(!(B.existsSync(s)||B.existsSync(o)||B.existsSync(i)))continue;let l=[".venv","venv","env"].map(d=>K.join(r,d)).find(d=>B.existsSync(d));if(!l){t.push({root:r,reason:"missing"});continue}let c=[];for(let d of[s,o])if(B.existsSync(d))try{c.push(B.statSync(d).mtimeMs)}catch{}if(c.length)try{let d=B.statSync(l).mtimeMs;Math.max(...c)>d+1e3&&t.push({root:r,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`venv issues \u2014 ${t.map(r=>`${r.reason}: ${r.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every Python searchRoot has a fresh venv (or no Python markers)"}}function kc(){let n=Ys();return!n.detected||!n.entries?"nothing to suggest":`would suggest: ${n.entries.map(e=>`(cd "${e.root}" && python -m venv .venv && .venv/Scripts/pip install -r requirements.txt)`).join(" && ")}. Daimon does not run pip on your behalf \u2014 run the command(s) yourself. To undo: nothing was changed.`}function Vs(){let n=Dn();if(!n.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let r of n){let s=K.join(r,"Gemfile");if(!B.existsSync(s))continue;let o=K.join(r,"Gemfile.lock"),i=K.join(r,"vendor","bundle"),a=K.join(r,".bundle"),l=B.existsSync(i)?i:B.existsSync(a)?a:null;if(!l){t.push({root:r,reason:"missing"});continue}if(B.existsSync(o))try{let c=B.statSync(o).mtimeMs,d=B.statSync(l).mtimeMs;c>d+1e3&&t.push({root:r,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`bundler cache issues \u2014 ${t.map(r=>`${r.reason}: ${r.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every Ruby searchRoot has a fresh bundle cache (or no Gemfile)"}}function xc(){let n=Vs();return!n.detected||!n.entries?"nothing to suggest":`would suggest: ${n.entries.map(e=>`(cd "${e.root}" && bundle install)`).join(" && ")}. Daimon does not run bundle install on your behalf \u2014 run the command(s) yourself. To undo: nothing was changed.`}function Zs(){let n=Dn();if(!n.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let r of n){let s=K.join(r,"Cargo.toml");if(!B.existsSync(s))continue;let o=K.join(r,"Cargo.lock"),i=K.join(r,"target");if(!B.existsSync(i)){t.push({root:r,reason:"missing"});continue}if(B.existsSync(o))try{let a=B.statSync(o).mtimeMs,l=B.statSync(i).mtimeMs;a>l+1e3&&t.push({root:r,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`cargo target issues \u2014 ${t.map(r=>`${r.reason}: ${r.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every Rust searchRoot has a fresh target/ (or no Cargo.toml)"}}function Tc(){let n=Zs();return!n.detected||!n.entries?"nothing to suggest":`would suggest: ${n.entries.map(e=>`(cd "${e.root}" && cargo build)`).join(" && ")}. Daimon does not run cargo on your behalf \u2014 run the command(s) yourself. To undo: nothing was changed.`}function Qs(){let n=st();if(n.kind!=="loaded")return{detected:!1,description:"no config loaded"};let t=[];for(let e of n.config.searchRoots){let r=typeof e=="string"?e:e.path;r&&(B.existsSync(r)||t.push(r))}return t.length?{detected:!0,description:`searchRoots no longer on disk: ${t.join(", ")}`,dead:t}:{detected:!1,description:"every configured searchRoot resolves on disk"}}function Cc(){let n=Qs();if(!n.detected||!n.dead||!n.dead.length)return"nothing to remove";let{local:t,user:e}=Lt(),r=B.existsSync(t)?t:e,s={};try{s=JSON.parse(B.readFileSync(r,"utf8"))}catch{}if(!Array.isArray(s.searchRoots))return"config has no searchRoots array; nothing removed";let o=new Set(n.dead),i=s.searchRoots.length;s.searchRoots=s.searchRoots.filter(c=>{let d=typeof c=="string"?c:c?.path;return!o.has(d)});let a=i-s.searchRoots.length;B.writeFileSync(r,JSON.stringify(s,null,2)+`
65
- `,"utf8");let l=ot();if(l)try{fetch(`http://127.0.0.1:${l.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`removed ${a} dead searchRoot entr${a===1?"y":"ies"} from ${r} (${[...o].join(", ")}); triggered soft-reload. To undo: edit ${r} and re-add the path(s).`}async function Pc(n){let t={ran:[],skipped:[],errors:[]};for(let e of Ks){if(!n.permitted.includes(e))continue;let r=Ec[e],s;try{s=await r.detect()}catch(o){t.errors.push({name:e,error:o?.message??String(o)});continue}if(!s.detected){t.skipped.push({name:e,detected:!1,description:s.description});continue}if(n.dryRun){t.ran.push({name:e,detected:!0,description:`(dry-run) would fix: ${s.description}`});continue}try{let o=await r.fix();t.ran.push({name:e,detected:!0,description:`${s.description} \u2014 ${o}`})}catch(o){t.errors.push({name:e,error:o?.message??String(o)})}}return t}var Ks,Ec,se=F(()=>{"use strict";bt();Xt();Te();fe();Ks=["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root"];Ec={"orphan-daemon":{detect:cc,fix:lc},"stale-lock":{detect:uc,fix:pc},"missing-search-root":{detect:dc,fix:fc},"corrupt-history-db":{detect:mc,fix:hc},"port-conflict-pred":{detect:gc,fix:yc},"node-version-mismatch":{detect:wc,fix:bc},"orphan-node-modules":{detect:zs,fix:Sc},"orphan-venv":{detect:Ys,fix:kc},"orphan-bundler-cache":{detect:Vs,fix:xc},"orphan-cargo-target":{detect:Zs,fix:Tc},"dead-search-root":{detect:Qs,fix:Cc}}});var Ln={};yt(Ln,{orchestrateProfile:()=>Oc});function to(n,t,e,r,s){let o=n.summary(t);if(!o)return!1;if(e==="serving")return o.status==="serving";if(e==="healthy")return o.status==="serving"&&o.health==="healthy";let i=Date.now()-r;return o.status==="serving"&&o.health==="healthy"&&i>=s}async function eo(n,t,e,r,s){let o=Date.now();if(e!=="stable"){let l=await n.waitFor(t,e==="serving"?"serving":"healthy",r);return{reached:!l.timedOut,waitedMs:l.waitedMs}}let i=Date.now(),a=l=>{l?.app===t&&(i=Date.now())};n.on("event",a);try{for(;Date.now()-o<r;){if(to(n,t,e,i,s))return{reached:!0,waitedMs:Date.now()-o};await new Promise(l=>setTimeout(l,500))}return{reached:to(n,t,e,i,s),waitedMs:Date.now()-o}}finally{n.off("event",a)}}async function Oc(n,t,e){let r=Date.now(),s=t.profiles?.[e.profile];if(!s)return{error:`unknown profile: ${e.profile}`};let o=s.filter(h=>n.summary(h)!=null),i=Array.from(new Set(o.flatMap(h=>ke(t.depends??{},h)))).filter(h=>n.summary(h)!=null),a=xe(t.depends??{},i),l=[];for(let h of i){let f=n.summary(h);f&&(e.goal==="serving"&&f.status==="serving"||(e.goal==="healthy"||e.goal==="stable")&&f.status==="serving"&&f.health==="healthy")&&l.push(h)}if(e.dryRun){let h=i.filter(f=>!l.includes(f));return{profile:e.profile,goal:e.goal,perApp:h.map(f=>({name:f,reached:!1,tries:0})),totalMs:Date.now()-r,allReached:h.length===0,dryRun:!0,plannedOrder:a,alreadyHealthy:l}}let c=Math.max(5e3,Math.floor(e.timeoutMs/2)),d=e.stableMs??5e3,u=new Map;for(let h of i)u.set(h,{name:h,reached:!1,tries:0});for(let h of a)await Promise.all(h.map(async f=>{let w=n.summary(f);if(!w){u.set(f,{name:f,reached:!1,tries:0,error:"unknown app"});return}if(l.includes(f)){u.set(f,{name:f,reached:!0,tries:0});return}w.status!=="starting"&&w.status!=="compiling"&&w.status!=="serving"&&await n.start(f)})),await Promise.all(h.map(async f=>{if(u.get(f)?.reached)return;let w=await eo(n,f,e.goal,c,d),T=u.get(f);T.tries=1,T.waitedMs=w.waitedMs,T.reached=w.reached,u.set(f,T)}));let g=[...u.values()].filter(h=>!h.reached);if(g.length>0){let{runAutoFix:h,ALL_AUTO_FIX:f}=await Promise.resolve().then(()=>(se(),re)),w=t.doctor?.autoFix?.permitted??f,T=Math.max(5e3,e.timeoutMs-(Date.now()-r)),E=Math.max(5e3,Math.floor(T/Math.max(g.length,1))),b={ran:[]};try{b=await h({permitted:w,dryRun:!1})}catch{}let _=(b.ran??[]).map(A=>A.name);await Promise.all(g.map(async A=>{let x=u.get(A.name);x.tries=2;try{let O=await n.restart(A.name);O?.ok||(x.error=O?.error??"restart failed")}catch(O){x.error=O?.message??String(O)}let P=await eo(n,A.name,e.goal,E,d);if(x.waitedMs=(x.waitedMs??0)+P.waitedMs,x.reached=P.reached,!x.reached){let O=n.errors(A.name)??[];x.stillFailing=O.slice(0,3).map(S=>({file:S.parsed?.file??null,line:S.parsed?.line??null,code:S.parsed?.code??null,tool:S.parsed?.tool??null,message:S.parsed?.message??S.message}))}x.fixed=_,u.set(A.name,x)}))}let y=[...u.values()],p=y.every(h=>h.reached),m={profile:e.profile,goal:e.goal,perApp:y,totalMs:Date.now()-r,allReached:p};if(typeof e.budgetTokens=="number"&&e.budgetTokens>0){let h=e.budgetTokens,f=0,w=0;for(let T of y)if(T.stillFailing){let E=T.stillFailing.length*Rc;E>h?(f+=T.stillFailing.length,delete T.stillFailing):h-=E}for(;h<0||y.length*Ac>Math.max(h,e.budgetTokens/4);){let T=y.findIndex(E=>E.reached);if(T===-1)break;y.splice(T,1),w++}(f||w)&&(m._meta={omitted:{}},f&&(m._meta.omitted.stillFailing=f),w&&(m._meta.omitted.perApp=w))}return m}var Rc,Ac,In=F(()=>{"use strict";de();Rc=60,Ac=25});import Nc from"node:http";import Mc from"node:crypto";import Wt from"node:fs";import pt from"node:path";import{fileURLToPath as $c}from"node:url";function Fn(){let n=[pt.resolve(He,"dashboard","browser"),pt.resolve(He,"dashboard"),pt.resolve(He,"..","dist","dashboard","browser"),pt.resolve(He,"..","dist","dashboard")];for(let t of n)if(Wt.existsSync(pt.join(t,"index.html")))return t;return null}function ye(n,t){try{if(!Wt.statSync(t).isFile())return!1;let r=pt.extname(t).toLowerCase(),s=_c[r]??"application/octet-stream",o=Wt.readFileSync(t);return n.writeHead(200,{"content-type":s,"content-length":o.length,"cache-control":r===".html"?"no-cache":"public, max-age=3600"}),n.end(o),!0}catch{return!1}}function v(n,t,e){let r=JSON.stringify(e);n.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(r)}),n.end(r)}function ie(n){if(!n)return;let t=n.match(/^(\d+)(ms|s|m|h)?$/);if(!t)return;let e=Number(t[1]);switch(t[2]||"ms"){case"ms":return e;case"s":return e*1e3;case"m":return e*60*1e3;case"h":return e*60*60*1e3}}function Je(n,t){let e=(n.searchParams.get("format")||"").toLowerCase();return e==="full"?"full":e==="compact"?"compact":t?.().output?.format==="full"?"full":"compact"}function Dc(n){return{name:n.name,status:n.status,port:n.port,health:n.health,errCount:n.errorCount,lastChangeMs:n.lastChangeMs??null}}function oe(n){return{name:n.name,status:n.status,port:n.port,url:n.url,health:n.health,errCount:n.errorCount,lastChangeMs:n.lastChangeMs??null,uptime:n.uptimeMs}}function Bn(n){let t=n.parsed;return t&&(t.file||t.code)?{file:t.file??null,line:t.line??null,col:t.col??null,code:t.code??null,message:t.message??n.message}:{file:null,line:null,col:null,code:null,message:n.message}}function no(n){if(!n)return{};if(/^\d{10,}$/.test(n))return{sinceTs:Number(n)};let t=ie(n);return t!=null?{sinceMs:t}:{}}function Ic(n){let t=JSON.parse(JSON.stringify(n));if(t.apiToken&&(t.apiToken="***"),t.overrides&&typeof t.overrides=="object")for(let e of Object.keys(t.overrides)){let r=t.overrides[e]?.env;if(r&&typeof r=="object")for(let s of Object.keys(r))Lc.test(s)&&(r[s]="***")}return t}function Un(n){if(!n)return"";try{let t=Wt.readFileSync(n);return Mc.createHash("sha1").update(t).digest("hex")}catch{return""}}function ro(n,t,e={}){let r=new Le,s=Nc.createServer(async(o,i)=>{try{let a=new URL(o.url||"/","http://127.0.0.1"),l=o.method||"GET",c=a.pathname.replace(/\/$/,"").split("/").filter(Boolean),d=()=>{let m=(e.getConfig?e.getConfig():null)?.apiToken??null;if(!m)return!0;let h=o.headers.authorization;return typeof h=="string"&&h.toLowerCase().startsWith("bearer ")&&h.slice(7).trim()===m?!0:(v(i,401,{error:"unauthorized"}),!1)};if(l==="POST"&&a.pathname==="/api/shutdown"){if(!d())return;v(i,200,{ok:!0}),e.onShutdown&&setImmediate(()=>{try{e.onShutdown()}catch{}});return}if(a.pathname==="/api/config"&&e.getConfig){if(l==="GET"){let p=e.getConfig(),m=Un(e.configPath);i.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:m}),i.end(JSON.stringify({etag:m,config:Ic(p)}));return}if(l==="PATCH"&&e.patchConfig){if(!d())return;let p=o.headers["if-match"]?.trim(),m=Un(e.configPath);if(!p||p!==m){v(i,412,{error:"etag mismatch",current:m});return}let h={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(T=>{let E=[];o.on("data",b=>E.push(b)),o.on("end",()=>{try{h=JSON.parse(Buffer.concat(E).toString("utf8"))}catch{}T()})});let f=e.patchConfig(h);if(!f.ok){v(i,400,{error:f.error});return}let w=Un(e.configPath);try{let T=o.socket.remoteAddress||"127.0.0.1";Fs(T,h,h,f.applied)}catch{}i.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:w}),i.end(JSON.stringify({etag:w,applied:f.applied,addedApps:f.addedApps,removedApps:f.removedApps,restartRequired:f.restartRequired}));return}v(i,405,{error:"method not allowed"});return}if(a.pathname==="/api/presets"&&l==="GET"){v(i,200,Hs());return}if(a.pathname==="/api/self"&&l==="GET"){if(!e.selfMetrics){v(i,503,{error:"self-metrics collector not attached"});return}v(i,200,e.selfMetrics.snapshot());return}if(a.pathname==="/api/plugins"&&l==="GET"){let p=e.getPlugins?e.getPlugins():[];v(i,200,p.map(m=>({name:m.name,description:m.description??null,file:m.file,status:m.status,error:m.error??null,findings:m.lastFindings??[]})));return}if(a.pathname==="/api/plugins/scan"&&l==="POST"){if(!d())return;if(!e.runPluginScans){v(i,503,{error:"plug-in scan not available"});return}try{await e.runPluginScans()}catch(m){v(i,500,{error:m?.message||String(m)});return}let p=e.getPlugins?e.getPlugins():[];v(i,200,p);return}if(a.pathname==="/api/self/history"&&l==="GET"){let p=no(a.searchParams.get("since")),m=p.sinceMs??3600*1e3,h=p.sinceTs??Date.now()-m,f=n.getHistory(),w=f?f.querySelfMetrics({since:h,limit:1440}):[];v(i,200,w);return}if(a.pathname==="/api/snapshot-state"&&l==="POST"){if(!d())return;let p=qs(n);v(i,200,{ok:!0,path:p});return}if(a.pathname==="/api/config/reload"&&l==="POST"&&e.reloadConfig){if(!d())return;try{let p=await e.reloadConfig();v(i,200,p)}catch(p){v(i,400,{error:p?.message||String(p)})}return}if(l==="GET"&&a.pathname==="/metrics"&&e.metricsEnabled){let p=Ds(n);i.writeHead(200,{"content-type":"text/plain; version=0.0.4","content-length":Buffer.byteLength(p)}),i.end(p);return}if(l!=="GET"&&a.pathname.startsWith("/api/")&&a.pathname!=="/api/shutdown"&&a.pathname!=="/api/config"&&a.pathname!=="/api/config/reload"&&!d())return;if(l==="GET"&&a.pathname==="/"){let p=Fn();if(p&&ye(i,pt.join(p,"index.html")))return;i.writeHead(404).end('dashboard not found \u2014 run "npm run build:dashboard" in the daimon repo');return}if(c[0]==="api"&&c[1]==="events"&&c.length===2){if(l!=="GET"){v(i,405,{error:"method not allowed"});return}let p=ie(a.searchParams.get("since")),m=a.searchParams.get("app")||void 0;if(a.searchParams.get("stream")==="ndjson"){i.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});let w=n.events({sinceMs:p,app:m});for(let b of w)i.write(JSON.stringify(b)+`
66
- `);let T=b=>{m&&b.app!==m||i.write(JSON.stringify(b)+`
67
- `)};n.on("event",T);let E=setInterval(()=>{try{i.write(`
68
- `)}catch{}},3e4);o.on("close",()=>{n.off("event",T),clearInterval(E);try{i.end()}catch{}});return}let h=n.events({sinceMs:p,app:m}),f=n.getHistory();if(f&&p&&h.length<500){let w=Date.now()-p,T=f.queryEvents({app:m,since:w,limit:1e3}),E=new Set(h.map(b=>`${b.ts}|${b.app}|${b.type}|${b.from??""}|${b.to??""}|${b.message??""}`));for(let b of T){let _=`${b.ts}|${b.app}|${b.type}|${b.from_state??""}|${b.to_state??""}|${b.message??""}`;E.has(_)||h.push({ts:b.ts,app:b.app,type:b.type,from:b.from_state??void 0,to:b.to_state??void 0,message:b.message??void 0})}h.sort((b,_)=>b.ts-_.ts)}v(i,200,h);return}if(c[0]==="api"&&c[1]==="session"){if(c[2]==="record"&&l==="POST"){let p=a.searchParams.get("action")||"toggle";if(p==="start"||p==="toggle"&&!n.sessionRecorder.isRecording()){let m=n.sessionRecorder.start();v(i,200,{recording:!0,path:m.path});return}if(p==="stop"||p==="toggle"&&n.sessionRecorder.isRecording()){let m=n.sessionRecorder.stop();v(i,200,{recording:!1,path:m.path});return}v(i,400,{error:"invalid action"});return}if(c[2]==="status"&&l==="GET"){v(i,200,{recording:n.sessionRecorder.isRecording()});return}v(i,404,{error:"not found"});return}if(c[0]==="api"&&c[1]==="history"){if(l!=="GET"){v(i,405,{error:"method not allowed"});return}let p=n.getHistory();if(!p){v(i,200,[]);return}let m=c[2],h=a.searchParams.get("app")||void 0,f=a.searchParams.get("since"),w=a.searchParams.get("until"),T=a.searchParams.get("limit"),E=f?/^\d{10,}$/.test(f)?Number(f):Date.now()-(ie(f)??0):void 0,b=w?/^\d{10,}$/.test(w)?Number(w):Date.now()-(ie(w)??0):void 0,_=T?Number(T):void 0;if(m==="events"){v(i,200,p.queryEvents({app:h,since:E,until:b,type:a.searchParams.get("type")||void 0,limit:_}));return}if(m==="compile-times"){v(i,200,p.queryCompiles({app:h,since:E,until:b,limit:_}));return}if(m==="tasks"){v(i,200,p.queryTasks({app:h,task:a.searchParams.get("task")||void 0,since:E,limit:_}));return}if(m==="bundles"){v(i,200,p.queryBundles({app:h,since:E,until:b,limit:_}));return}if(m==="trends"){let A=a.searchParams.get("metric")||"compile";if(!["compile","bundle","errors","restarts"].includes(A)){v(i,400,{error:"metric must be compile|bundle|errors|restarts"});return}let x=(a.searchParams.get("since")||"24h").toLowerCase(),P={"24h":24*3600*1e3,"7d":7*86400*1e3,"30d":30*86400*1e3},O=P[x]??P["24h"],S=x==="24h"?3600*1e3:86400*1e3,{points:k,count:I}=p.trends({app:h,metric:A,sinceMs:O,bucketMs:S});v(i,200,{app:h??null,metric:A,since:x,points:k,_meta:{aggregation:x==="24h"?"hour":"day",count:I}});return}if(m==="summary"&&c.length>=4){let A=decodeURIComponent(c[3]);v(i,200,p.summary(A));return}if(m==="why"&&c.length>=4){let A=decodeURIComponent(c[3]);v(i,200,p.why(A));return}v(i,404,{error:"not found"});return}if(c[0]==="api"&&c[1]==="profiles"&&c[3]==="ensure-up"&&l==="POST"){let p=decodeURIComponent(c[2]),m=e.getConfig?.(),h=m?.profiles?.[p];if(!h){v(i,404,{error:"unknown profile"});return}let f=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(f)){v(i,400,{error:"until must be serving|healthy"});return}let w=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),T=w?Number(w):3e5;(!Number.isFinite(T)||T<=0)&&(T=3e5),T=Math.min(T,12e5);let E=m?.healthProbe?.enabled??!0,b=f==="healthy"&&!E?"serving":f,_=Date.now();for(let x of h){let P=n.summary(x);P&&P.status!=="serving"&&P.status!=="starting"&&P.status!=="compiling"&&await n.startWithDeps(x)}let A=await Promise.all(h.map(async x=>{let P=Math.max(1e3,T-(Date.now()-_));if(!n.summary(x))return{name:x,state:null,until:b,reachedTargetMs:null,timedOut:!1,error:"unknown"};let S=await n.waitFor(x,b,P),k=n.summary(x);return{name:x,state:k?oe(k):null,until:b,reachedTargetMs:S.timedOut?null:S.waitedMs,timedOut:S.timedOut}}));v(i,200,{profile:p,apps:A,_meta:{totalMs:Date.now()-_,until:b}});return}if(c[0]==="api"&&c[1]==="orchestrate"&&l==="POST"){let p=e.getConfig?.();if(!p){v(i,500,{error:"no config loaded"});return}let m=a.searchParams.get("profile");if(!m){v(i,400,{error:"profile query param required"});return}let h=(a.searchParams.get("goal")||"healthy").toLowerCase();if(!["serving","healthy","stable"].includes(h)){v(i,400,{error:"goal must be serving|healthy|stable"});return}let f=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),w=f?Number(f):3e5;(!Number.isFinite(w)||w<=0)&&(w=3e5),w=Math.min(w,12e5);let T=a.searchParams.get("dryRun")==="true"||a.searchParams.get("dry-run")==="true",E=a.searchParams.get("budget"),b=E&&Number.isFinite(Number(E))?Number(E):void 0,{orchestrateProfile:_}=await Promise.resolve().then(()=>(In(),Ln)),A=await _(n,p,{profile:m,goal:h,timeoutMs:w,dryRun:T,budgetTokens:b});if(A.error){v(i,404,A);return}v(i,200,A);return}if(c[0]==="api"&&c[1]==="discovery"&&c[2]==="explain"&&l==="GET"){let p=e.getConfig?.();if(!p){v(i,200,{searchRoots:[],scanned:0,rejected:{},warnings:[],suggestion:"no config loaded"});return}let{discoverApps:m}=await Promise.resolve().then(()=>(zt(),hn)),h={scanned:0,rejected:{}},f=[],w=m(p,{warnings:f,stats:h}),T=p.searchRoots.map(A=>typeof A=="string"?A:A.path),E=w.filter(A=>A.workspaceType==="polyglot"),b=w.map(A=>({name:A.name,workspaceType:A.workspaceType,serverProfile:A.serverProfile??A.workspaceType,workspaceRoot:A.workspaceRoot})),_=E.length>0?` \xB7 ${E.length} polyglot app${E.length===1?"":"s"} found (${[...new Set(E.map(A=>A.serverProfile))].join(", ")})`:"";v(i,200,{searchRoots:T,scanned:h.scanned,rejected:h.rejected,warnings:f,appsFound:w.length,apps:b,suggestion:w.length===0?T.length===0?"no searchRoots configured. Run 'daimon init --auto' from a workspace folder.":"discovery returned no apps. Check that searchRoots contain nx.json / angular.json / vite.config.* / .storybook / manage.py / Gemfile / pyproject.toml (fastapi) / .air.toml / Trunk.toml.":`${w.length} apps discovered${_}`});return}if(c[0]==="api"&&c[1]==="doctor"&&c[2]==="auto-fix"&&l==="POST"){if(!d())return;let p={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(E=>{let b=[];o.on("data",_=>b.push(_)),o.on("end",()=>{try{p=JSON.parse(Buffer.concat(b).toString("utf8"))}catch{}E()})});let{runAutoFix:m,ALL_AUTO_FIX:h}=await Promise.resolve().then(()=>(se(),re)),w=e.getConfig?.()?.doctor?.autoFix?.permitted??h,T=Array.isArray(p.permitted)&&p.permitted.length?p.permitted:w;try{let E=await m({permitted:T,dryRun:!!p.dryRun});v(i,200,E)}catch(E){v(i,500,{error:E?.message??String(E)})}return}if(c[0]==="api"&&c[1]==="overview"&&l==="GET"){let p=e.getConfig?.(),m=n.list(),h=a.searchParams.get("workspace"),f=a.searchParams.get("profile"),w=m;if(h&&(w=w.filter(S=>S.workspaceLabel===h)),f){let S=p?.profiles?.[f]??null;S&&(w=w.filter(k=>S.includes(k.name)))}let T={apps:w.length,serving:w.filter(S=>S.status==="serving").length,errors:w.filter(S=>S.status==="error").length,stopped:w.filter(S=>S.status==="stopped").length,totalErrCount:w.reduce((S,k)=>S+k.errorCount,0),totalCpuPct:Math.round(w.reduce((S,k)=>S+(k.cpu??0),0)*10)/10,totalMemMb:Math.round(w.reduce((S,k)=>S+(k.memMB??0),0))},E={};for(let S of w)(E[S.status]??=[]).push(S.name);let b=w.filter(S=>S.status==="error"||S.errorCount>0).map(S=>{let k=n.errors(S.name)??[],I=k[k.length-1],D=I?.parsed;return{name:S.name,status:S.status,errCount:S.errorCount,firstError:D?{file:D.file??null,line:D.line??null,code:D.code??null,message:D.message??I?.message??""}:I?{file:null,line:null,code:null,message:I.message}:null}}),_=Date.now()-5*6e4,A=n.events({sinceMs:5*6e4}).filter(S=>S.type==="status"&&S.ts>=_).filter(S=>h?w.some(k=>k.name===S.app):!0).filter(S=>f?w.some(k=>k.name===S.app):!0).slice(-5).map(S=>({name:S.app,transition:`${S.from??"?"}\u2192${S.to??"?"}`,msAgo:Date.now()-S.ts})),x={ts:Date.now(),version:Z,totals:T,byStatus:E,needsAttention:b,recentlyChanged:A};T.apps===0&&(x._meta={suggestion:"no apps registered. run 'daimon doctor' for recommended next step, or 'daimon init --auto' from a workspace folder."});let P=a.searchParams.get("budget"),O=P?Math.max(64,Number(P)|0):null;if(O){let S=O*4,k=0,I=0;for(;JSON.stringify(x).length>S&&(x.needsAttention.length||x.recentlyChanged.length);)if(x.needsAttention.length>1)x.needsAttention.pop(),k++;else if(x.recentlyChanged.length)x.recentlyChanged.pop(),I++;else if(x.needsAttention.length===1)x.needsAttention.pop(),k++;else break;k||I?x._meta={...x._meta??{},budget:O,omitted:{needsAttention:k,recentlyChanged:I}}:x._meta={...x._meta??{},budget:O}}v(i,200,x);return}if(c[0]!=="api"||c[1]!=="apps"){if(l==="GET"&&!a.pathname.startsWith("/metrics")){let p=Fn();if(p){let m=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(m){let h=pt.resolve(p,m);if(h.startsWith(p)&&ye(i,h))return}if(!pt.extname(m||"")&&ye(i,pt.join(p,"index.html")))return}}v(i,404,{error:"not found"});return}if(c.length===2){if(l!=="GET"){v(i,405,{error:"method not allowed"});return}let p=Je(a,e.getConfig),m=n.list(),h=p==="full"?m:m.map(Dc);if(a.searchParams.get("stream")==="ndjson"){i.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});for(let f of h)i.write(JSON.stringify(f)+`
69
- `);i.end();return}if(a.searchParams.get("explain")==="1"){let f=e.getConfig?.(),w={format:p};if(f){let{discoverApps:T}=await Promise.resolve().then(()=>(zt(),hn)),E={scanned:0,rejected:{}},b=[];T(f,{warnings:b,stats:E});let _=f.searchRoots.map(A=>typeof A=="string"?A:A.path);w={format:p,searchRoots:_,scanned:E.scanned,rejected:E.rejected,warnings:b,suggestion:h.length===0?_.length===0?"no searchRoots configured. Run 'daimon init --auto' from a workspace folder to add the current cwd.":"discovery returned no apps. Check that searchRoots contain nx.json / angular.json / vite.config.* / .storybook, then run 'daimon doctor'.":"apps discovered; _meta is informational."}}v(i,200,{apps:h,_meta:w});return}v(i,200,h);return}let u=decodeURIComponent(c[2]),g=c[3],y=c[4];if(!g){if(l!=="GET"){v(i,405,{error:"method not allowed"});return}let p=n.summary(u);if(!p){v(i,404,{error:"unknown app"});return}Je(a,e.getConfig)==="full"?v(i,200,{...p,_meta:{format:"full"}}):v(i,200,{...oe(p),_meta:{format:"compact"}});return}if(g==="errors"&&y==="since-last"&&l==="GET"){let p=a.searchParams.get("client")||"default",m=r.getErrorCursor(p,u),h=n.errorsSince(u,m);if(h==null){v(i,404,{error:"unknown app"});return}let f=h.reduce((T,E)=>Math.max(T,E.lastSeen),m);f>m&&r.setErrorCursor(p,u,f);let w=Je(a,e.getConfig);v(i,200,w==="full"?h:h.map(Bn));return}if(g==="errors"&&!y&&l==="GET"){let p=a.searchParams.get("since"),m=Je(a,e.getConfig);if(p){let{sinceMs:f,sinceTs:w}=no(p),T=w??(f!=null?Date.now()-f:0),E=n.errorsSince(u,T);if(E==null){v(i,404,{error:"unknown app"});return}v(i,200,m==="full"?E:E.map(Bn));return}let h=n.errors(u);if(h==null){v(i,404,{error:"unknown app"});return}v(i,200,m==="full"?h:h.map(Bn));return}if(g==="logs"&&c[4]==="stream"&&l==="GET"){if(!n.summary(u)){v(i,404,{error:"unknown app"});return}i.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"});let p=n.logs(u,{tail:50})??[];for(let E of p)i.write(`data: ${JSON.stringify({ts:Date.now(),line:E})}
62
+ `}var yc,Ys=U(()=>{"use strict";yc=["stopped","starting","compiling","serving","error"]});import Ce from"node:fs";import wc from"node:crypto";import Vs from"node:path";function vc(){return Vs.join(mt(),"audit.log")}function Sc(n){try{if(Ce.statSync(n).size>bc){let e=n+".1";try{Ce.unlinkSync(e)}catch{}Ce.renameSync(n,e)}}catch{}}function Zs(n,t,e,r,s=null){let o=vc();Ce.mkdirSync(Vs.dirname(o),{recursive:!0}),Sc(o);let i=JSON.stringify({prev:t,next:e}),a=wc.createHash("sha1").update(i).digest("hex").slice(0,12),c=`${new Date().toISOString()} ${n} ${a} ${r.join(",")} ${s??""}
63
+ `;try{Ce.appendFileSync(o,c)}catch{}}var bc,Qs=U(()=>{"use strict";Pt();bc=1e6});import Qe from"node:fs";import tn from"node:path";import{fileURLToPath as kc}from"node:url";function xc(){let n=[tn.resolve(to,"templates","presets"),tn.resolve(to,"..","src","templates","presets")];for(let t of n)if(Qe.existsSync(t))return t;return n[0]}function eo(){let n=xc();if(!Qe.existsSync(n))return[];let t=Qe.readdirSync(n).filter(r=>r.endsWith(".json")),e=[];for(let r of t)try{let s=Qe.readFileSync(tn.join(n,r),"utf8");s.charCodeAt(0)===65279&&(s=s.slice(1)),e.push(JSON.parse(s))}catch{}return e}var to,no=U(()=>{"use strict";to=tn.dirname(kc(import.meta.url))});import en from"node:fs";import ro from"node:path";function so(){return ro.join(mt(),"state-handoff.json")}function oo(n){let t=[];for(let s of n.names()){let o=n.getState(s);o&&(o.status==="serving"||o.status==="compiling"||o.status==="starting")&&o.port&&t.push({name:s,port:o.port})}let e={ts:Date.now(),apps:t},r=so();return en.mkdirSync(ro.dirname(r),{recursive:!0}),en.writeFileSync(r,JSON.stringify(e)),r}function io(n=6e4){let t=so();try{let e=en.readFileSync(t,"utf8"),r=JSON.parse(e);return en.unlinkSync(t),!r||typeof r.ts!="number"||Date.now()-r.ts>n?null:r}catch{return null}}var Yn=U(()=>{"use strict";Pt()});function nn(n){return n?Tc[n]??null:null}function ao(n){return n===200||n===301||n===302||n===304||n===307||n===308||n===401}function co(n){return n?n==="ECONNREFUSED"||n==="ECONNRESET"||n==="EHOSTUNREACH":!1}var Tc,Vn=U(()=>{"use strict";Tc={django:"/admin/login/",rails:"/up",fastapi:"/docs","go-air":"/","rust-trunk":"/"}});var ue={};kt(ue,{ALL_AUTO_FIX:()=>lo,runAutoFix:()=>qc});import B from"node:fs";import V from"node:path";function Pc(){let n=ct();if(!n)return{detected:!1,description:"no daemon running"};let t=process.cwd(),e=V.join(t,"daimon.config.json");if(!B.existsSync(e))return{detected:!1,description:"no local daimon.config.json in cwd"};let r=n.cwd,s=n.configPath,o=r&&V.resolve(r)===V.resolve(t),i=s&&V.resolve(s)===V.resolve(e);return o||i?{detected:!1,description:"daemon already running from this cwd/config"}:{detected:!0,description:`daemon (pid ${n.pid}) is running from ${r??"(unknown)"} but local daimon.config.json exists at ${t}`,lockCwd:r}}async function Cc(){let n=ct();if(!n)return"no daemon running; nothing to do";try{await fetch(`http://127.0.0.1:${n.apiPort}/api/snapshot-state`,{method:"POST"})}catch{}try{await fetch(`http://127.0.0.1:${n.apiPort}/api/shutdown`,{method:"POST"})}catch{}return await Xt(n.pid,5e3),Tt(),`respawned daemon at pid ${(await Dt({})).pid} from ${process.cwd()}; previous pid ${n.pid} (cwd ${n.cwd??"unknown"}) was shut down with state handoff. To undo: stop with 'daimon daemon stop' and start from the prior directory.`}function Rc(){let n;try{n=B.readFileSync(Je(),"utf8")}catch{return{detected:!1,description:"no lock file present"}}let t;try{t=JSON.parse(n)}catch{return{detected:!0,description:"lock file is malformed JSON"}}if(!t||typeof t.pid!="number")return{detected:!0,description:"lock file has no pid"};try{return process.kill(t.pid,0),{detected:!1,description:`lock file owner pid ${t.pid} is alive`}}catch(e){return e?.code==="EPERM"?{detected:!1,description:`lock file owner pid ${t.pid} alive (EPERM)`}:{detected:!0,description:`lock file claims pid ${t.pid} but the process is gone`}}}async function Ec(){let n="(unknown)";try{let e=JSON.parse(B.readFileSync(Je(),"utf8"));n=String(e?.pid??"?")}catch{}Tt();let t=await Dt({});return`removed stale ${Je()} (prior pid ${n} was dead); spawned fresh daemon at pid ${t.pid}.`}function Ac(){let n=process.cwd(),e=["nx.json","angular.json","vite.config.ts","vite.config.js","vite.config.mjs","vite.config.cjs",".storybook"].filter(i=>B.existsSync(V.join(n,i)));if(!e.length)return{detected:!1,description:"no nx.json/angular.json/vite.config.*/.storybook in cwd"};let r=at();return r.kind!=="loaded"?{detected:!0,description:`${e.join(", ")} present but no config is loaded`,markerFiles:e}:r.config.searchRoots.map(i=>V.resolve(typeof i=="string"?i:i.path)).some(i=>n.startsWith(i))?{detected:!1,description:`${e.join(", ")} present and a configured searchRoot covers ${n}`}:{detected:!0,description:`${e.join(", ")} present in ${n} but no searchRoot covers it`,markerFiles:e}}function Oc(){let n=process.cwd(),{local:t,user:e}=$t(),r=B.existsSync(t)?t:e,s={};try{s=JSON.parse(B.readFileSync(r,"utf8"))}catch{}if(s.searchRoots=Array.isArray(s.searchRoots)?s.searchRoots:[],!s.searchRoots.some(i=>(typeof i=="string"?i:i?.path)===n)){let i;try{let a=JSON.parse(B.readFileSync(V.join(n,"package.json"),"utf8"));typeof a.name=="string"&&(i=a.name)}catch{}s.searchRoots.push(i?{path:n,label:i}:n)}B.mkdirSync(V.dirname(r),{recursive:!0}),B.writeFileSync(r,JSON.stringify(s,null,2)+`
64
+ `,"utf8");let o=ct();if(o)try{fetch(`http://127.0.0.1:${o.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`appended ${n} as a searchRoot in ${r}; triggered soft-reload of the running daemon.`}function Nc(){let n=at();if(n.kind!=="loaded"||!n.config.history.enabled)return{detected:!1,description:"history disabled"};let t=n.config.history.path;if(!B.existsSync(t))return{detected:!1,description:"history db does not exist (will be created on next start)"};try{let e=new jt(n.config.history),r=e.quickCheck();return e.close(),r?{detected:!1,description:"history db quick_check passed"}:{detected:!0,description:`quick_check failed on ${t}`,dbPath:t}}catch(e){return{detected:!0,description:`cannot open ${t}: ${e?.message??String(e)}`,dbPath:t}}}function $c(){let n=at();if(n.kind!=="loaded")return"no config; cannot determine history path";let t=n.config.history.path,e=`${t}.corrupt-${Date.now()}`;for(let r of["","-wal","-shm"])try{B.renameSync(t+r,e+r)}catch{}return`rotated ${t} \u2192 ${e} (and -wal/-shm siblings). The daemon will rebuild an empty history db on next start.`}async function Mc(){let n=at();if(n.kind!=="loaded")return{detected:!1,description:"no config loaded"};let[t,e]=n.config.portRange??[4200,4299],r=n.config.overrides??{},s=Object.values(r).map(a=>a.port).filter(a=>typeof a=="number"),o=Array.from(new Set([...s,t,e])),i=[];for(let a of o)if(!(!Number.isFinite(a)||a<=0))try{await Mt(a)||i.push(a)}catch{}return i.length?{detected:!0,description:`ports already LISTEN: ${i.join(", ")} (range ${t}-${e} + pinned overrides)`,conflicts:i}:{detected:!1,description:`all checked ports free (range ${t}-${e} + pinned)`}}function jc(){return"no automated fix \u2014 predictive rule only. Run `daimon free-port <port>` to inspect the holder, or pick a different port in daimon.config.json. To undo: nothing was changed."}function _c(){let n=process.cwd(),t=process.versions.node,e=V.join(n,".nvmrc");if(B.existsSync(e)){let s=B.readFileSync(e,"utf8").trim().replace(/^v/i,"");if(s&&!t.startsWith(s))return{detected:!0,description:`.nvmrc requires ${s}, running ${t}`,expected:s,actual:t}}let r=V.join(n,"package.json");if(B.existsSync(r))try{let o=JSON.parse(B.readFileSync(r,"utf8"))?.engines?.node;if(typeof o=="string"&&o.trim()){let i=o.match(/(\d+)(?:\.(\d+))?/);if(i){let a=Number(i[1]),c=Number(t.split(".")[0]);if(Number.isFinite(a)&&Number.isFinite(c)&&c<a)return{detected:!0,description:`package.json engines.node = "${o}" but running ${t}`,expected:o,actual:t}}}}catch{}return{detected:!1,description:`node ${t} satisfies .nvmrc / engines.node (or neither is present)`}}function Dc(){return"no automated fix \u2014 switching Node versions touches the user environment. Run `nvm use` (or your version manager equivalent) in this directory, then re-run daimon. To undo: nothing was changed."}function Lc(){let n=at();if(n.kind!=="loaded")return[];let t=[],e=new Set;for(let r of n.config.searchRoots){let s=typeof r=="string"?r:r.path;if(!s||!B.existsSync(s)||e.has(s))continue;e.add(s);let o=V.join(s,"package.json");if(!B.existsSync(o))continue;let i=null;for(let a of["package-lock.json","pnpm-lock.yaml","yarn.lock"]){let c=V.join(s,a);if(B.existsSync(c)){i=c;break}}t.push({name:V.basename(s),root:s,pkgPath:o,lockPath:i,nmPath:V.join(s,"node_modules")})}return t}function uo(){let n=Lc();if(!n.length)return{detected:!1,description:"no searchRoots with package.json found"};let t=[];for(let r of n){if(!B.existsSync(r.nmPath)){t.push({root:r.root,reason:"missing"});continue}if(r.lockPath)try{let s=B.statSync(r.lockPath).mtimeMs,o=B.statSync(r.nmPath).mtimeMs;s>o+1e3&&t.push({root:r.root,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`node_modules issues \u2014 ${t.map(r=>`${r.reason}: ${r.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every searchRoot package.json has a fresh node_modules"}}function Ic(){let n=uo();return!n.detected||!n.entries?"nothing to suggest":`would suggest: ${n.entries.map(e=>`(cd "${e.root}" && npm install)`).join(" && ")}. Daimon does not run package managers on your behalf \u2014 run the command(s) yourself. To undo: nothing was changed.`}function Zn(){let n=at();if(n.kind!=="loaded")return[];let t=[],e=new Set;for(let r of n.config.searchRoots){let s=typeof r=="string"?r:r?.path;!s||!B.existsSync(s)||e.has(s)||(e.add(s),t.push(s))}return t}function po(){let n=Zn();if(!n.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let r of n){let s=V.join(r,"pyproject.toml"),o=V.join(r,"requirements.txt"),i=V.join(r,"manage.py");if(!(B.existsSync(s)||B.existsSync(o)||B.existsSync(i)))continue;let c=[".venv","venv","env"].map(u=>V.join(r,u)).find(u=>B.existsSync(u));if(!c){t.push({root:r,reason:"missing"});continue}let l=[];for(let u of[s,o])if(B.existsSync(u))try{l.push(B.statSync(u).mtimeMs)}catch{}if(l.length)try{let u=B.statSync(c).mtimeMs;Math.max(...l)>u+1e3&&t.push({root:r,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`venv issues \u2014 ${t.map(r=>`${r.reason}: ${r.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every Python searchRoot has a fresh venv (or no Python markers)"}}function Fc(){let n=po();return!n.detected||!n.entries?"nothing to suggest":`would suggest: ${n.entries.map(e=>`(cd "${e.root}" && python -m venv .venv && .venv/Scripts/pip install -r requirements.txt)`).join(" && ")}. Daimon does not run pip on your behalf \u2014 run the command(s) yourself. To undo: nothing was changed.`}function fo(){let n=Zn();if(!n.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let r of n){let s=V.join(r,"Gemfile");if(!B.existsSync(s))continue;let o=V.join(r,"Gemfile.lock"),i=V.join(r,"vendor","bundle"),a=V.join(r,".bundle"),c=B.existsSync(i)?i:B.existsSync(a)?a:null;if(!c){t.push({root:r,reason:"missing"});continue}if(B.existsSync(o))try{let l=B.statSync(o).mtimeMs,u=B.statSync(c).mtimeMs;l>u+1e3&&t.push({root:r,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`bundler cache issues \u2014 ${t.map(r=>`${r.reason}: ${r.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every Ruby searchRoot has a fresh bundle cache (or no Gemfile)"}}function Bc(){let n=fo();return!n.detected||!n.entries?"nothing to suggest":`would suggest: ${n.entries.map(e=>`(cd "${e.root}" && bundle install)`).join(" && ")}. Daimon does not run bundle install on your behalf \u2014 run the command(s) yourself. To undo: nothing was changed.`}function mo(){let n=Zn();if(!n.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let r of n){let s=V.join(r,"Cargo.toml");if(!B.existsSync(s))continue;let o=V.join(r,"Cargo.lock"),i=V.join(r,"target");if(!B.existsSync(i)){t.push({root:r,reason:"missing"});continue}if(B.existsSync(o))try{let a=B.statSync(o).mtimeMs,c=B.statSync(i).mtimeMs;a>c+1e3&&t.push({root:r,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`cargo target issues \u2014 ${t.map(r=>`${r.reason}: ${r.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every Rust searchRoot has a fresh target/ (or no Cargo.toml)"}}function Uc(){let n=mo();return!n.detected||!n.entries?"nothing to suggest":`would suggest: ${n.entries.map(e=>`(cd "${e.root}" && cargo build)`).join(" && ")}. Daimon does not run cargo on your behalf \u2014 run the command(s) yourself. To undo: nothing was changed.`}function ho(){let n=at();if(n.kind!=="loaded")return{detected:!1,description:"no config loaded"};let t=[];for(let e of n.config.searchRoots){let r=typeof e=="string"?e:e.path;r&&(B.existsSync(r)||t.push(r))}return t.length?{detected:!0,description:`searchRoots no longer on disk: ${t.join(", ")}`,dead:t}:{detected:!1,description:"every configured searchRoot resolves on disk"}}function Hc(){let n=ho();if(!n.detected||!n.dead||!n.dead.length)return"nothing to remove";let{local:t,user:e}=$t(),r=B.existsSync(t)?t:e,s={};try{s=JSON.parse(B.readFileSync(r,"utf8"))}catch{}if(!Array.isArray(s.searchRoots))return"config has no searchRoots array; nothing removed";let o=new Set(n.dead),i=s.searchRoots.length;s.searchRoots=s.searchRoots.filter(l=>{let u=typeof l=="string"?l:l?.path;return!o.has(u)});let a=i-s.searchRoots.length;B.writeFileSync(r,JSON.stringify(s,null,2)+`
65
+ `,"utf8");let c=ct();if(c)try{fetch(`http://127.0.0.1:${c.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`removed ${a} dead searchRoot entr${a===1?"y":"ies"} from ${r} (${[...o].join(", ")}); triggered soft-reload. To undo: edit ${r} and re-add the path(s).`}function go(){let n=at();if(n.kind!=="loaded")return{detected:!1,description:"no config loaded"};let t=Ot(n.config,{}),e=n.config.overrides??{},r=[];for(let o of t){if(!o.serverProfile)continue;let i=o.baseName??o.name;if(e[o.name]?.healthProbePath??e[i]?.healthProbePath)continue;let c=nn(o.serverProfile);!c||c==="/"||r.push({name:o.name,profile:o.serverProfile,path:c})}return r.length?{detected:!0,description:`apps missing a profile-aware health probe path: ${r.map(o=>`${o.name} (${o.profile} \u2192 ${o.path})`).join(" \xB7 ")}`,entries:r}:{detected:!1,description:"every app with a known framework profile already has a probe path resolved"}}function Jc(){let n=go();if(!n.detected||!n.entries)return"nothing to set";let{local:t,user:e}=$t(),r=B.existsSync(t)?t:e,s={};try{s=JSON.parse(B.readFileSync(r,"utf8"))}catch{}(!s.overrides||typeof s.overrides!="object")&&(s.overrides={});let o=[];for(let a of n.entries)(!s.overrides[a.name]||typeof s.overrides[a.name]!="object")&&(s.overrides[a.name]={}),!s.overrides[a.name].healthProbePath&&(s.overrides[a.name].healthProbePath=a.path,o.push(`${a.name} \u2192 ${a.path}`));if(!o.length)return"every detected app already had a healthProbePath in overrides; nothing changed.";B.mkdirSync(V.dirname(r),{recursive:!0}),B.writeFileSync(r,JSON.stringify(s,null,2)+`
66
+ `,"utf8");let i=ct();if(i)try{fetch(`http://127.0.0.1:${i.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`wrote healthProbePath to overrides in ${r} for: ${o.join(", ")}; triggered soft-reload. To undo: edit ${r}.`}async function qc(n){let t={ran:[],skipped:[],errors:[]};for(let e of lo){if(!n.permitted.includes(e))continue;let r=Wc[e],s;try{s=await r.detect()}catch(o){t.errors.push({name:e,error:o?.message??String(o)});continue}if(!s.detected){t.skipped.push({name:e,detected:!1,description:s.description});continue}if(n.dryRun){t.ran.push({name:e,detected:!0,description:`(dry-run) would fix: ${s.description}`});continue}try{let o=await r.fix();t.ran.push({name:e,detected:!0,description:`${s.description} \u2014 ${o}`})}catch(o){t.errors.push({name:e,error:o?.message??String(o)})}}return t}var lo,Wc,pe=U(()=>{"use strict";Pt();ee();Ie();xe();qt();Vn();lo=["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root","health-probe-missing"];Wc={"orphan-daemon":{detect:Pc,fix:Cc},"stale-lock":{detect:Rc,fix:Ec},"missing-search-root":{detect:Ac,fix:Oc},"corrupt-history-db":{detect:Nc,fix:$c},"port-conflict-pred":{detect:Mc,fix:jc},"node-version-mismatch":{detect:_c,fix:Dc},"orphan-node-modules":{detect:uo,fix:Ic},"orphan-venv":{detect:po,fix:Fc},"orphan-bundler-cache":{detect:fo,fix:Bc},"orphan-cargo-target":{detect:mo,fix:Uc},"dead-search-root":{detect:ho,fix:Hc},"health-probe-missing":{detect:go,fix:Jc}}});var Qn={};kt(Qn,{orchestrateProfile:()=>Kc});function yo(n,t,e,r,s){let o=n.summary(t);if(!o)return!1;if(e==="serving")return o.status==="serving";if(e==="healthy")return o.status==="serving"&&o.health==="healthy";let i=Date.now()-r;return o.status==="serving"&&o.health==="healthy"&&i>=s}async function wo(n,t,e,r,s){let o=Date.now();if(e!=="stable"){let c=await n.waitFor(t,e==="serving"?"serving":"healthy",r);return{reached:!c.timedOut,waitedMs:c.waitedMs}}let i=Date.now(),a=c=>{c?.app===t&&(i=Date.now())};n.on("event",a);try{for(;Date.now()-o<r;){if(yo(n,t,e,i,s))return{reached:!0,waitedMs:Date.now()-o};await new Promise(c=>setTimeout(c,500))}return{reached:yo(n,t,e,i,s),waitedMs:Date.now()-o}}finally{n.off("event",a)}}async function Kc(n,t,e){let r=Date.now(),s=t.profiles?.[e.profile];if(!s)return{error:`unknown profile: ${e.profile}`};let o=s.filter(y=>n.summary(y)!=null),i=Array.from(new Set(o.flatMap(y=>De(t.depends??{},y)))).filter(y=>n.summary(y)!=null),a=Le(t.depends??{},i),c=[];for(let y of i){let b=n.summary(y);b&&(e.goal==="serving"&&b.status==="serving"||(e.goal==="healthy"||e.goal==="stable")&&b.status==="serving"&&b.health==="healthy")&&c.push(y)}if(e.dryRun){let y=i.filter(b=>!c.includes(b));return{profile:e.profile,goal:e.goal,perApp:y.map(b=>({name:b,reached:!1,tries:0})),totalMs:Date.now()-r,allReached:y.length===0,dryRun:!0,plannedOrder:a,alreadyHealthy:c}}let l=Math.max(5e3,Math.floor(e.timeoutMs/2)),u=e.stableMs??5e3,d=new Map;for(let y of i)d.set(y,{name:y,reached:!1,tries:0});for(let y of a)await Promise.all(y.map(async b=>{let N=n.summary(b);if(!N){d.set(b,{name:b,reached:!1,tries:0,error:"unknown app"});return}if(c.includes(b)){d.set(b,{name:b,reached:!0,tries:0});return}N.status!=="starting"&&N.status!=="compiling"&&N.status!=="serving"&&await n.start(b)})),await Promise.all(y.map(async b=>{if(d.get(b)?.reached)return;let N=await wo(n,b,e.goal,l,u),p=d.get(b);p.tries=1,p.waitedMs=N.waitedMs,p.reached=N.reached,d.set(b,p)}));let f=[...d.values()].filter(y=>!y.reached);if(f.length>0){let{runAutoFix:y,ALL_AUTO_FIX:b}=await Promise.resolve().then(()=>(pe(),ue)),N=t.doctor?.autoFix?.permitted??b,p=Math.max(5e3,e.timeoutMs-(Date.now()-r)),m=Math.max(5e3,Math.floor(p/Math.max(f.length,1))),h={ran:[]};try{h=await y({permitted:N,dryRun:!1})}catch{}let k=(h.ran??[]).map(T=>T.name);await Promise.all(f.map(async T=>{let P=d.get(T.name);P.tries=2;try{let w=await n.restart(T.name);w?.ok||(P.error=w?.error??"restart failed")}catch(w){P.error=w?.message??String(w)}let v=await wo(n,T.name,e.goal,m,u);if(P.waitedMs=(P.waitedMs??0)+v.waitedMs,P.reached=v.reached,!P.reached){let w=n.errors(T.name)??[];P.stillFailing=w.slice(0,3).map(E=>({file:E.parsed?.file??null,line:E.parsed?.line??null,code:E.parsed?.code??null,tool:E.parsed?.tool??null,message:E.parsed?.message??E.message}))}P.fixed=k,d.set(T.name,P)}))}let g=[...d.values()],C=g.every(y=>y.reached),R={profile:e.profile,goal:e.goal,perApp:g,totalMs:Date.now()-r,allReached:C};if(typeof e.budgetTokens=="number"&&e.budgetTokens>0){let y=e.budgetTokens,b=0,N=0;for(let p of g)if(p.stillFailing){let m=p.stillFailing.length*Gc;m>y?(b+=p.stillFailing.length,delete p.stillFailing):y-=m}for(;y<0||g.length*Xc>Math.max(y,e.budgetTokens/4);){let p=g.findIndex(m=>m.reached);if(p===-1)break;g.splice(p,1),N++}(b||N)&&(R._meta={omitted:{}},b&&(R._meta.omitted.stillFailing=b),N&&(R._meta.omitted.perApp=N))}return R}var Gc,Xc,tr=U(()=>{"use strict";ke();Gc=60,Xc=25});import zc from"node:http";import Yc from"node:crypto";import Lt from"node:fs";import ht from"node:path";import{fileURLToPath as Vc}from"node:url";function er(){let n=[ht.resolve(rn,"dashboard","browser"),ht.resolve(rn,"dashboard"),ht.resolve(rn,"..","dist","dashboard","browser"),ht.resolve(rn,"..","dist","dashboard")];for(let t of n)if(Lt.existsSync(ht.join(t,"index.html")))return t;return null}function Re(n,t){try{if(!Lt.statSync(t).isFile())return!1;let r=ht.extname(t).toLowerCase(),s=Qc[r]??"application/octet-stream",o=Lt.readFileSync(t);return n.writeHead(200,{"content-type":s,"content-length":o.length,"cache-control":r===".html"?"no-cache":"public, max-age=3600"}),n.end(o),!0}catch{return!1}}function x(n,t,e){let r=JSON.stringify(e);n.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(r)}),n.end(r)}function fe(n){if(!n)return;let t=n.match(/^(\d+)(ms|s|m|h)?$/);if(!t)return;let e=Number(t[1]);switch(t[2]||"ms"){case"ms":return e;case"s":return e*1e3;case"m":return e*60*1e3;case"h":return e*60*60*1e3}}function sn(n,t){let e=(n.searchParams.get("format")||"").toLowerCase();return e==="full"?"full":e==="compact"?"compact":t?.().output?.format==="full"?"full":"compact"}function tl(n){return{name:n.name,status:n.status,port:n.port,health:n.health,errCount:n.errorCount,lastChangeMs:n.lastChangeMs??null}}function de(n){return{name:n.name,status:n.status,port:n.port,url:n.url,health:n.health,errCount:n.errorCount,lastChangeMs:n.lastChangeMs??null,uptime:n.uptimeMs}}function nr(n){let t=n.parsed,e=n.level??"error";return t&&(t.file||t.code)?{file:t.file??null,line:t.line??null,col:t.col??null,code:t.code??null,message:t.message??n.message,level:e}:{file:null,line:null,col:null,code:null,message:n.message,level:e}}function bo(n){if(!n)return{};if(/^\d{10,}$/.test(n))return{sinceTs:Number(n)};let t=fe(n);return t!=null?{sinceMs:t}:{}}function nl(n){let t=JSON.parse(JSON.stringify(n));if(t.apiToken&&(t.apiToken="***"),t.overrides&&typeof t.overrides=="object")for(let e of Object.keys(t.overrides)){let r=t.overrides[e]?.env;if(r&&typeof r=="object")for(let s of Object.keys(r))el.test(s)&&(r[s]="***")}return t}function rr(n){if(!n)return"";try{let t=Lt.readFileSync(n);return Yc.createHash("sha1").update(t).digest("hex")}catch{return""}}function vo(n,t,e={}){let r=new Ve,s=zc.createServer(async(o,i)=>{try{let a=new URL(o.url||"/","http://127.0.0.1"),c=o.method||"GET",l=a.pathname.replace(/\/$/,"").split("/").filter(Boolean),u=()=>{let m=(e.getConfig?e.getConfig():null)?.apiToken??null;if(!m)return!0;let h=o.headers.authorization;return typeof h=="string"&&h.toLowerCase().startsWith("bearer ")&&h.slice(7).trim()===m?!0:(x(i,401,{error:"unauthorized"}),!1)};if(c==="POST"&&a.pathname==="/api/shutdown"){if(!u())return;x(i,200,{ok:!0}),e.onShutdown&&setImmediate(()=>{try{e.onShutdown()}catch{}});return}if(a.pathname==="/api/config"&&e.getConfig){if(c==="GET"){let p=e.getConfig(),m=rr(e.configPath);i.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:m}),i.end(JSON.stringify({etag:m,config:nl(p)}));return}if(c==="PATCH"&&e.patchConfig){if(!u())return;let p=o.headers["if-match"]?.trim(),m=rr(e.configPath);if(!p||p!==m){x(i,412,{error:"etag mismatch",current:m});return}let h={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(P=>{let v=[];o.on("data",w=>v.push(w)),o.on("end",()=>{try{h=JSON.parse(Buffer.concat(v).toString("utf8"))}catch{}P()})});let k=e.patchConfig(h);if(!k.ok){x(i,400,{error:k.error});return}let T=rr(e.configPath);try{let P=o.socket.remoteAddress||"127.0.0.1",v=o.headers["x-daimon-cwd"]||null;Zs(P,h,h,k.applied,v)}catch{}i.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:T}),i.end(JSON.stringify({etag:T,applied:k.applied,addedApps:k.addedApps,removedApps:k.removedApps,restartRequired:k.restartRequired}));return}x(i,405,{error:"method not allowed"});return}if(a.pathname==="/api/presets"&&c==="GET"){x(i,200,eo());return}if(a.pathname==="/api/self"&&c==="GET"){if(!e.selfMetrics){x(i,503,{error:"self-metrics collector not attached"});return}x(i,200,e.selfMetrics.snapshot());return}if(a.pathname==="/api/plugins"&&c==="GET"){let p=e.getPlugins?e.getPlugins():[];x(i,200,p.map(m=>({name:m.name,description:m.description??null,file:m.file,status:m.status,error:m.error??null,findings:m.lastFindings??[]})));return}if(a.pathname==="/api/plugins/scan"&&c==="POST"){if(!u())return;if(!e.runPluginScans){x(i,503,{error:"plug-in scan not available"});return}try{await e.runPluginScans()}catch(m){x(i,500,{error:m?.message||String(m)});return}let p=e.getPlugins?e.getPlugins():[];x(i,200,p);return}if(a.pathname==="/api/self/history"&&c==="GET"){let p=bo(a.searchParams.get("since")),m=p.sinceMs??3600*1e3,h=p.sinceTs??Date.now()-m,k=n.getHistory(),T=k?k.querySelfMetrics({since:h,limit:1440}):[];x(i,200,T);return}if(a.pathname==="/api/snapshot-state"&&c==="POST"){if(!u())return;let p=oo(n);x(i,200,{ok:!0,path:p});return}if(a.pathname==="/api/config/reload"&&c==="POST"&&e.reloadConfig){if(!u())return;try{let p=await e.reloadConfig();x(i,200,p)}catch(p){x(i,400,{error:p?.message||String(p)})}return}if(a.pathname==="/api/workspaces"&&c==="GET"&&e.getConfig){let p=e.getConfig(),m=n.list(),h=p.searchRoots.map(k=>{let T=typeof k=="string"?k:k.path,P=typeof k=="string"?null:k.label??null,v=m.filter(w=>{let E=w.workspaceRoot;return!!E&&Ct(E,T)});return{path:T,label:P,appCount:v.length,apps:v.map(w=>w.name)}});x(i,200,h);return}if(a.pathname==="/api/workspaces/resolve"&&c==="GET"&&e.getConfig){let p=a.searchParams.get("cwd");if(!p){x(i,400,{error:"cwd query param required"});return}let k=e.getConfig().searchRoots.map(T=>typeof T=="string"?{path:T,label:null}:{path:T.path,label:T.label??null}).find(T=>Ct(p,T.path));if(!k){x(i,404,{error:"no workspace covers cwd",cwd:p});return}x(i,200,{path:k.path,label:k.label,cwd:p});return}if(a.pathname==="/api/workspaces/remove"&&c==="POST"&&e.getConfig&&e.patchConfig){if(!u())return;let p={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(w=>{let E=[];o.on("data",S=>E.push(S)),o.on("end",()=>{try{p=JSON.parse(Buffer.concat(E).toString("utf8"))}catch{}w()})});let m=typeof p?.path=="string"?p.path:"";if(!m){x(i,400,{error:"path is required"});return}let h=e.getConfig(),k=w=>typeof w=="string"?w:w.path,T=h.searchRoots.map(k),P=h.searchRoots.filter(w=>k(w)!==m);if(P.length===T.length){x(i,404,{error:`not a registered searchRoot: ${m}`});return}let v=e.patchConfig({searchRoots:P});if(!v.ok){x(i,400,{error:v.error});return}x(i,200,{removed:m,removedApps:v.removedApps??[]});return}if(a.pathname==="/api/workspaces/ensure"&&c==="POST"&&e.getConfig&&e.patchConfig){if(!u())return;let p={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(S=>{let O=[];o.on("data",I=>O.push(I)),o.on("end",()=>{try{p=JSON.parse(Buffer.concat(O).toString("utf8"))}catch{}S()})});let m=typeof p?.path=="string"?p.path:"",h=typeof p?.label=="string"&&p.label?p.label:null;if(!m){x(i,400,{error:"path is required"});return}if(!Lt.existsSync(m)){x(i,400,{error:`path does not exist: ${m}`});return}let k=e.getConfig(),T=k.searchRoots.map(S=>typeof S=="string"?S:S.path);if(T.some(S=>Ct(m,S))){let S=T.find(O=>Ct(m,O));x(i,200,{added:!1,root:S,reason:"already covered"});return}let v=h?{path:m,label:h}:m,w=[...k.searchRoots,v],E=e.patchConfig({searchRoots:w});if(!E.ok){x(i,400,{error:E.error});return}x(i,200,{added:!0,root:m,label:h,addedApps:E.addedApps??[]});return}if(c==="GET"&&a.pathname==="/metrics"&&e.metricsEnabled){let p=zs(n);i.writeHead(200,{"content-type":"text/plain; version=0.0.4","content-length":Buffer.byteLength(p)}),i.end(p);return}if(c!=="GET"&&a.pathname.startsWith("/api/")&&a.pathname!=="/api/shutdown"&&a.pathname!=="/api/config"&&a.pathname!=="/api/config/reload"&&!u())return;if(c==="GET"&&a.pathname==="/"){let p=er();if(p&&Re(i,ht.join(p,"index.html")))return;i.writeHead(404).end('dashboard not found \u2014 run "npm run build:dashboard" in the daimon repo');return}if(l[0]==="api"&&l[1]==="events"&&l.length===2){if(c!=="GET"){x(i,405,{error:"method not allowed"});return}let p=fe(a.searchParams.get("since")),m=a.searchParams.get("app")||void 0;if(a.searchParams.get("stream")==="ndjson"){i.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});let T=n.events({sinceMs:p,app:m});for(let w of T)i.write(JSON.stringify(w)+`
67
+ `);let P=w=>{m&&w.app!==m||i.write(JSON.stringify(w)+`
68
+ `)};n.on("event",P);let v=setInterval(()=>{try{i.write(`
69
+ `)}catch{}},3e4);o.on("close",()=>{n.off("event",P),clearInterval(v);try{i.end()}catch{}});return}let h=n.events({sinceMs:p,app:m}),k=n.getHistory();if(k&&p&&h.length<500){let T=Date.now()-p,P=k.queryEvents({app:m,since:T,limit:1e3}),v=new Set(h.map(w=>`${w.ts}|${w.app}|${w.type}|${w.from??""}|${w.to??""}|${w.message??""}`));for(let w of P){let E=`${w.ts}|${w.app}|${w.type}|${w.from_state??""}|${w.to_state??""}|${w.message??""}`;v.has(E)||h.push({ts:w.ts,app:w.app,type:w.type,from:w.from_state??void 0,to:w.to_state??void 0,message:w.message??void 0})}h.sort((w,E)=>w.ts-E.ts)}x(i,200,h);return}if(l[0]==="api"&&l[1]==="session"){if(l[2]==="record"&&c==="POST"){let p=a.searchParams.get("action")||"toggle";if(p==="start"||p==="toggle"&&!n.sessionRecorder.isRecording()){let m=n.sessionRecorder.start();x(i,200,{recording:!0,path:m.path});return}if(p==="stop"||p==="toggle"&&n.sessionRecorder.isRecording()){let m=n.sessionRecorder.stop();x(i,200,{recording:!1,path:m.path});return}x(i,400,{error:"invalid action"});return}if(l[2]==="status"&&c==="GET"){x(i,200,{recording:n.sessionRecorder.isRecording()});return}x(i,404,{error:"not found"});return}if(l[0]==="api"&&l[1]==="history"){if(c!=="GET"){x(i,405,{error:"method not allowed"});return}let p=n.getHistory();if(!p){x(i,200,[]);return}let m=l[2],h=a.searchParams.get("app")||void 0,k=a.searchParams.get("since"),T=a.searchParams.get("until"),P=a.searchParams.get("limit"),v=k?/^\d{10,}$/.test(k)?Number(k):Date.now()-(fe(k)??0):void 0,w=T?/^\d{10,}$/.test(T)?Number(T):Date.now()-(fe(T)??0):void 0,E=P?Number(P):void 0;if(m==="events"){x(i,200,p.queryEvents({app:h,since:v,until:w,type:a.searchParams.get("type")||void 0,limit:E}));return}if(m==="compile-times"){x(i,200,p.queryCompiles({app:h,since:v,until:w,limit:E}));return}if(m==="tasks"){x(i,200,p.queryTasks({app:h,task:a.searchParams.get("task")||void 0,since:v,limit:E}));return}if(m==="timeline"){let S=a.searchParams.get("kinds"),O=S?new Set(S.split(",").map(X=>X.trim()).filter(Boolean)):void 0,I=p.queryTimeline({app:h,since:v,kinds:O,limit:E??5e3});x(i,200,I);return}if(m==="bundles"){x(i,200,p.queryBundles({app:h,since:v,until:w,limit:E}));return}if(m==="trends"){let S=(a.searchParams.get("since")||"24h").toLowerCase(),O={"24h":24*3600*1e3,"7d":7*86400*1e3,"30d":30*86400*1e3},I=O[S]??O["24h"],X=S==="24h"?3600*1e3:86400*1e3,j=a.searchParams.get("metrics");if(j){let wt=j.split(",").map(tt=>tt.trim()).filter(Boolean),Z=["compile","bundle","errors","restarts"],Ne=wt.filter(tt=>Z.includes(tt));if(!Ne.length){x(i,400,{error:"metrics must include at least one of compile|bundle|errors|restarts"});return}let ve={};for(let tt of Ne){let $e=p.trends({app:h,metric:tt,sinceMs:I,bucketMs:X});ve[tt]={points:$e.points,count:$e.count}}x(i,200,{app:h??null,since:S,metrics:ve,_meta:{aggregation:S==="24h"?"hour":"day"}});return}let W=a.searchParams.get("metric")||"compile";if(!["compile","bundle","errors","restarts"].includes(W)){x(i,400,{error:"metric must be compile|bundle|errors|restarts"});return}let{points:Q,count:J}=p.trends({app:h,metric:W,sinceMs:I,bucketMs:X});x(i,200,{app:h??null,metric:W,since:S,points:Q,_meta:{aggregation:S==="24h"?"hour":"day",count:J}});return}if(m==="summary"&&l.length>=4){let S=decodeURIComponent(l[3]);x(i,200,p.summary(S));return}if(m==="why"&&l.length>=4){let S=decodeURIComponent(l[3]);x(i,200,p.why(S));return}x(i,404,{error:"not found"});return}if(l[0]==="api"&&l[1]==="profiles"&&l[3]==="ensure-up"&&c==="POST"){let p=decodeURIComponent(l[2]),m=e.getConfig?.(),h=m?.profiles?.[p];if(!h){x(i,404,{error:"unknown profile"});return}let k=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(k)){x(i,400,{error:"until must be serving|healthy"});return}let T=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),P=T?Number(T):3e5;(!Number.isFinite(P)||P<=0)&&(P=3e5),P=Math.min(P,12e5);let v=m?.healthProbe?.enabled??!0,w=k==="healthy"&&!v?"serving":k,E=Date.now();for(let O of h){let I=n.summary(O);I&&I.status!=="serving"&&I.status!=="starting"&&I.status!=="compiling"&&await n.startWithDeps(O)}let S=await Promise.all(h.map(async O=>{let I=Math.max(1e3,P-(Date.now()-E));if(!n.summary(O))return{name:O,state:null,until:w,reachedTargetMs:null,timedOut:!1,error:"unknown"};let j=await n.waitFor(O,w,I),W=n.summary(O);return{name:O,state:W?de(W):null,until:w,reachedTargetMs:j.timedOut?null:j.waitedMs,timedOut:j.timedOut}}));x(i,200,{profile:p,apps:S,_meta:{totalMs:Date.now()-E,until:w}});return}if(l[0]==="api"&&l[1]==="orchestrate"&&c==="POST"){let p=e.getConfig?.();if(!p){x(i,500,{error:"no config loaded"});return}let m=a.searchParams.get("profile");if(!m){x(i,400,{error:"profile query param required"});return}let h=(a.searchParams.get("goal")||"healthy").toLowerCase();if(!["serving","healthy","stable"].includes(h)){x(i,400,{error:"goal must be serving|healthy|stable"});return}let k=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),T=k?Number(k):3e5;(!Number.isFinite(T)||T<=0)&&(T=3e5),T=Math.min(T,12e5);let P=a.searchParams.get("dryRun")==="true"||a.searchParams.get("dry-run")==="true",v=a.searchParams.get("budget"),w=v&&Number.isFinite(Number(v))?Number(v):void 0,{orchestrateProfile:E}=await Promise.resolve().then(()=>(tr(),Qn)),S=await E(n,p,{profile:m,goal:h,timeoutMs:T,dryRun:P,budgetTokens:w});if(S.error){x(i,404,S);return}x(i,200,S);return}if(l[0]==="api"&&l[1]==="discovery"&&l[2]==="explain"&&c==="GET"){let p=e.getConfig?.();if(!p){x(i,200,{searchRoots:[],scanned:0,rejected:{},warnings:[],suggestion:"no config loaded"});return}let{discoverApps:m}=await Promise.resolve().then(()=>(qt(),En)),h={scanned:0,rejected:{}},k=[],T=m(p,{warnings:k,stats:h}),P=p.searchRoots.map(S=>typeof S=="string"?S:S.path),v=T.filter(S=>S.workspaceType==="polyglot"),w=T.map(S=>({name:S.name,workspaceType:S.workspaceType,serverProfile:S.serverProfile??S.workspaceType,workspaceRoot:S.workspaceRoot})),E=v.length>0?` \xB7 ${v.length} polyglot app${v.length===1?"":"s"} found (${[...new Set(v.map(S=>S.serverProfile))].join(", ")})`:"";x(i,200,{searchRoots:P,scanned:h.scanned,rejected:h.rejected,warnings:k,appsFound:T.length,apps:w,suggestion:T.length===0?P.length===0?"no searchRoots configured. Run 'daimon init --auto' from a workspace folder.":"discovery returned no apps. Check that searchRoots contain nx.json / angular.json / vite.config.* / .storybook / manage.py / Gemfile / pyproject.toml (fastapi) / .air.toml / Trunk.toml.":`${T.length} apps discovered${E}`});return}if(l[0]==="api"&&l[1]==="doctor"&&l[2]==="auto-fix"&&c==="POST"){if(!u())return;let p={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(v=>{let w=[];o.on("data",E=>w.push(E)),o.on("end",()=>{try{p=JSON.parse(Buffer.concat(w).toString("utf8"))}catch{}v()})});let{runAutoFix:m,ALL_AUTO_FIX:h}=await Promise.resolve().then(()=>(pe(),ue)),T=e.getConfig?.()?.doctor?.autoFix?.permitted??h,P=Array.isArray(p.permitted)&&p.permitted.length?p.permitted:T;try{let v=await m({permitted:P,dryRun:!!p.dryRun});x(i,200,v)}catch(v){x(i,500,{error:v?.message??String(v)})}return}if(l[0]==="api"&&l[1]==="overview"&&c==="GET"){let p=e.getConfig?.(),m=n.list(),h=a.searchParams.get("workspace"),k=a.searchParams.get("profile"),T=m;if(h&&(T=T.filter(j=>j.workspaceLabel===h)),k){let j=p?.profiles?.[k]??null;j&&(T=T.filter(W=>j.includes(W.name)))}let P={apps:T.length,serving:T.filter(j=>j.status==="serving").length,errors:T.filter(j=>j.status==="error").length,stopped:T.filter(j=>j.status==="stopped").length,totalErrCount:T.reduce((j,W)=>j+W.errorCount,0),totalCpuPct:Math.round(T.reduce((j,W)=>j+(W.cpu??0),0)*10)/10,totalMemMb:Math.round(T.reduce((j,W)=>j+(W.memMB??0),0))},v={};for(let j of T)(v[j.status]??=[]).push(j.name);let w=T.filter(j=>j.status==="error"||j.errorCount>0).map(j=>{let W=n.errors(j.name)??[],Q=W[W.length-1],J=Q?.parsed;return{name:j.name,status:j.status,errCount:j.errorCount,firstError:J?{file:J.file??null,line:J.line??null,code:J.code??null,message:J.message??Q?.message??""}:Q?{file:null,line:null,code:null,message:Q.message}:null}}),E=Date.now()-5*6e4,S=n.events({sinceMs:5*6e4}).filter(j=>j.type==="status"&&j.ts>=E).filter(j=>h?T.some(W=>W.name===j.app):!0).filter(j=>k?T.some(W=>W.name===j.app):!0).slice(-5).map(j=>({name:j.app,transition:`${j.from??"?"}\u2192${j.to??"?"}`,msAgo:Date.now()-j.ts})),O={ts:Date.now(),version:st,totals:P,byStatus:v,needsAttention:w,recentlyChanged:S};P.apps===0&&(O._meta={suggestion:"no apps registered. run 'daimon doctor' for recommended next step, or 'daimon init --auto' from a workspace folder."});let I=a.searchParams.get("budget"),X=I?Math.max(64,Number(I)|0):null;if(X){let j=X*4,W=0,Q=0;for(;JSON.stringify(O).length>j&&(O.needsAttention.length||O.recentlyChanged.length);)if(O.needsAttention.length>1)O.needsAttention.pop(),W++;else if(O.recentlyChanged.length)O.recentlyChanged.pop(),Q++;else if(O.needsAttention.length===1)O.needsAttention.pop(),W++;else break;W||Q?O._meta={...O._meta??{},budget:X,omitted:{needsAttention:W,recentlyChanged:Q}}:O._meta={...O._meta??{},budget:X}}x(i,200,O);return}if(l[0]!=="api"||l[1]!=="apps"){if(c==="GET"&&!a.pathname.startsWith("/metrics")){let p=er();if(p){let m=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(m){let h=ht.resolve(p,m);if(h.startsWith(p)&&Re(i,h))return}if(!ht.extname(m||"")&&Re(i,ht.join(p,"index.html")))return}}x(i,404,{error:"not found"});return}if(l.length===2){if(c!=="GET"){x(i,405,{error:"method not allowed"});return}let p=sn(a,e.getConfig),m=n.list(),h=a.searchParams.get("cwd"),k=h&&h.length>0?h:null;k&&(m=m.filter(P=>{let v=n.getApp(P.name);return v?Ct(v.workspaceRoot,k)||Ct(k,v.workspaceRoot):!1}));let T=p==="full"?m:m.map(tl);if(a.searchParams.get("stream")==="ndjson"){i.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});for(let P of T)i.write(JSON.stringify(P)+`
70
+ `);i.end();return}if(a.searchParams.get("explain")==="1"){let P=e.getConfig?.(),v={format:p};if(P){let{discoverApps:w}=await Promise.resolve().then(()=>(qt(),En)),E={scanned:0,rejected:{}},S=[];w(P,{warnings:S,stats:E});let O=P.searchRoots.map(I=>typeof I=="string"?I:I.path);v={format:p,searchRoots:O,scanned:E.scanned,rejected:E.rejected,warnings:S,...k?{cwdScope:k}:{},suggestion:T.length===0?O.length===0?"no searchRoots configured. Run 'daimon init --auto' from a workspace folder to add the current cwd.":k?`no apps under cwd '${k}'. Run 'daimon list --all' to see apps from other workspaces, or 'daimon init --auto' to register this dir.`:"discovery returned no apps. Check that searchRoots contain nx.json / angular.json / vite.config.* / .storybook, then run 'daimon doctor'.":"apps discovered; _meta is informational."}}x(i,200,{apps:T,_meta:v});return}x(i,200,T);return}let d=decodeURIComponent(l[2]),f=l[3],g=l[4],C=a.searchParams.get("cwd")||null,R=n.resolveByCwd(d,C),y=d;if(R.kind==="unique"&&R.key)y=R.key;else if(R.kind==="none"&&C){x(i,404,{error:`no app named '${d}' under cwd '${C}'`,hint:"use --all (or omit cwd) to broaden the search, or --workspace <label> to target a specific workspace"});return}else if(R.kind==="collision"){x(i,412,{error:"name-collision",candidates:R.candidates,hint:C?"multiple apps under that cwd share this name \u2014 use --workspace <label> to disambiguate":"multiple workspaces share this app name \u2014 pass --cwd or --workspace <label>"});return}if(!f){if(c!=="GET"){x(i,405,{error:"method not allowed"});return}let p=n.summary(y);if(!p){x(i,404,{error:"unknown app"});return}sn(a,e.getConfig)==="full"?x(i,200,{...p,_meta:{format:"full"}}):x(i,200,{...de(p),_meta:{format:"compact"}});return}let b=(a.searchParams.get("level")||"error").toLowerCase(),N=p=>{let m=p.level??"error";return b==="all"?!0:b==="warning"?m==="warning":b==="lint"?m==="lint":m==="error"};if(f==="errors"&&g==="since-last"&&c==="GET"){let p=a.searchParams.get("client")||"default",m=r.getErrorCursor(p,y),h=n.errorsSince(y,m);if(h==null){x(i,404,{error:"unknown app"});return}let k=h.filter(N),T=k.reduce((v,w)=>Math.max(v,w.lastSeen),m);T>m&&r.setErrorCursor(p,y,T);let P=sn(a,e.getConfig);x(i,200,P==="full"?k:k.map(nr));return}if(f==="errors"&&!g&&c==="GET"){let p=a.searchParams.get("since"),m=sn(a,e.getConfig);if(p){let{sinceMs:T,sinceTs:P}=bo(p),v=P??(T!=null?Date.now()-T:0),w=n.errorsSince(y,v);if(w==null){x(i,404,{error:"unknown app"});return}let E=w.filter(N);x(i,200,m==="full"?E:E.map(nr));return}let h=n.errors(y);if(h==null){x(i,404,{error:"unknown app"});return}let k=h.filter(N);x(i,200,m==="full"?k:k.map(nr));return}if(f==="logs"&&l[4]==="stream"&&c==="GET"){if(!n.summary(y)){x(i,404,{error:"unknown app"});return}i.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"});let p=n.logs(y,{tail:50})??[];for(let v of p)i.write(`data: ${JSON.stringify({ts:Date.now(),line:v})}
70
71
 
71
- `);let m=[],h=0,f=()=>{for(;m.length&&i.write(m.shift()););},w=E=>{E.name===u&&(m.length>=200&&(h++,m.shift()),m.push(`data: ${JSON.stringify({ts:E.ts,line:E.line})}
72
+ `);let m=[],h=0,k=()=>{for(;m.length&&i.write(m.shift()););},T=v=>{v.name===y&&(m.length>=200&&(h++,m.shift()),m.push(`data: ${JSON.stringify({ts:v.ts,line:v.line})}
72
73
 
73
- `),f())};n.on("log",w);let T=setInterval(()=>i.write(`: ping
74
+ `),k())};n.on("log",T);let P=setInterval(()=>i.write(`: ping
74
75
 
75
- `),3e4);o.on("close",()=>{n.off("log",w),clearInterval(T)});return}if(g==="logs"&&l==="GET"){let p=a.searchParams.get("tail"),m=a.searchParams.get("since"),h=n.logs(u,{tail:p?Number(p):void 0,sinceMs:ie(m)});if(h==null){v(i,404,{error:"unknown app"});return}v(i,200,{lines:h});return}if(g==="focus"&&l==="POST"){let p=n.summary(u);if(!p){v(i,404,{error:"unknown app"});return}let m=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy","stable"].includes(m)){v(i,400,{error:"until must be one of serving|healthy|stable"});return}let h=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),f=h?Number(h):18e4;(!Number.isFinite(f)||f<=0)&&(f=18e4),f=Math.min(f,6e5);let w=a.searchParams.get("stableMs"),T=w&&Number.isFinite(Number(w))?Math.max(1e3,Number(w)):5e3;i.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8","cache-control":"no-cache",connection:"keep-alive"});let E=D=>{try{i.write(JSON.stringify(D)+`
76
- `)}catch{}};E({kind:"subscribed",app:u,until:m,ts:Date.now(),state:oe(p)});let b=Date.now(),_=Date.now(),A=!1,x=D=>{if(A)return;A=!0,n.off("event",O),clearInterval(S),clearInterval(k),clearTimeout(I);let z=n.summary(u);E({kind:"done",reason:D,ts:Date.now(),state:z?oe(z):null,waitedMs:Date.now()-b});try{i.end()}catch{}},P=()=>{let D=n.summary(u);if(!D)return!1;if(m==="serving")return D.status==="serving";if(m==="healthy")return D.status==="serving"&&D.health==="healthy";if(m==="stable"){let z=Date.now()-_;return D.status==="serving"&&D.health==="healthy"&&z>=T}return!1},O=D=>{if(D.app===u)if(_=Date.now(),D.type==="status")E({kind:"status",from:D.from,to:D.to,ts:D.ts}),m!=="stable"&&P()&&x("reached");else if(D.type==="error-new"||D.type==="error-recur"){let J=(n.errors(u)??[])[0];J&&E({kind:"error",message:J.message,parsed:J.parsed??null,ts:D.ts})}else D.type==="health"&&(E({kind:"health",from:D.from,to:D.to,ts:D.ts}),m!=="stable"&&P()&&x("reached"))};n.on("event",O);let S=setInterval(()=>{P()&&x("reached")},1e3),k=setInterval(()=>{try{i.write(`
77
- `)}catch{}},3e4),I=setTimeout(()=>x("timeout"),f);o.on("close",()=>x("closed")),P()&&x("reached");return}if(g==="health"&&y==="pin"&&l==="POST"){let p=n.getState(u);if(!p){v(i,404,{error:"unknown app"});return}let m={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(A=>{let x=[];o.on("data",P=>x.push(P)),o.on("end",()=>{try{m=JSON.parse(Buffer.concat(x).toString("utf8"))}catch{}A()})});let h=typeof m.path=="string"&&m.path?m.path:p.discoveredHealthPath??null;if(!h){v(i,400,{error:"no path supplied and no discoveredHealthPath on app"});return}let{configLookupPaths:f}=await Promise.resolve().then(()=>(Xt(),wr)),{local:w,user:T}=f(),E=Wt.existsSync(w)?w:T,b={};try{b=JSON.parse(Wt.readFileSync(E,"utf8"))}catch{}(!b.overrides||typeof b.overrides!="object")&&(b.overrides={}),(!b.overrides[u]||typeof b.overrides[u]!="object")&&(b.overrides[u]={});let _=b.overrides[u].healthProbePath??null;if(b.overrides[u].healthProbePath=h,Wt.writeFileSync(E,JSON.stringify(b,null,2)+`
78
- `,"utf8"),e.reloadConfig)try{await e.reloadConfig()}catch{}v(i,200,{pinned:h,app:u,configPath:E,previous:_});return}if(g==="try-fix"&&l==="POST"){let p=n.summary(u);if(!p){v(i,404,{error:"unknown app"});return}let m=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(m)){v(i,400,{error:"until must be serving|healthy"});return}let h=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),f=h?Number(h):18e4;(!Number.isFinite(f)||f<=0)&&(f=18e4),f=Math.min(f,6e5);let w={status:p.status,health:p.health,errCount:p.errorCount,firstError:(n.errors(u)??[])[0]?.parsed??null},{runAutoFix:T,ALL_AUTO_FIX:E}=await Promise.resolve().then(()=>(se(),re)),_=e.getConfig?.()?.doctor?.autoFix?.permitted??E,A={ran:[],skipped:[],errors:[]};try{A=await T({permitted:_,dryRun:!1})}catch(J){A.errors.push({name:"auto-fix",error:J?.message??String(J)})}let x=(A.ran??[]).map(J=>J.name),P=null;try{let J=await n.restart(u);J?.ok||(P=J?.error??"restart failed")}catch(J){P=J?.message??String(J)}let O=await n.waitFor(u,m,f),S=n.summary(u),I=(n.errors(u)??[]).slice(0,5).map(J=>({file:J.parsed?.file??null,line:J.parsed?.line??null,code:J.parsed?.code??null,tool:J.parsed?.tool??null,message:J.parsed?.message??J.message})),D=S?{status:S.status,health:S.health,errCount:S.errorCount}:{status:O.status,health:O.health,errCount:0},z=m==="serving"&&D.status==="serving"||m==="healthy"&&D.status==="serving"&&D.health==="healthy";v(i,200,{before:w,after:D,fixed:x,stillFailing:I,reached:z,waitedMs:O.waitedMs,_meta:{autoFix:A,restartErr:P,timedOut:O.timedOut}});return}if(g==="wait"&&l==="GET"){if(!n.summary(u)){v(i,404,{error:"unknown app"});return}let p=(a.searchParams.get("until")||"serving").toLowerCase();if(!["serving","healthy","stopped","error"].includes(p)){v(i,400,{error:"until must be one of serving|healthy|stopped|error"});return}let m=a.searchParams.get("timeout"),h=m?Number(m):120;(!Number.isFinite(h)||h<=0)&&(h=120),h=Math.min(h,600);let f=await n.waitFor(u,p,h*1e3);v(i,200,f);return}if(g==="ensure"&&l==="POST"){let p=n.summary(u);if(!p){v(i,404,{error:"unknown app"});return}let m=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(m)){v(i,400,{error:"until must be serving|healthy"});return}let h=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),f=h?Number(h):18e4;(!Number.isFinite(f)||f<=0)&&(f=18e4),f=Math.min(f,6e5);let w=e.getConfig?.().healthProbe?.enabled??!0,T=m,E;if(T==="healthy"&&!w&&(T="serving",E="no health probe; treated serving as terminal"),T==="serving"&&p.status==="serving"||T==="healthy"&&p.status==="serving"&&p.health==="healthy"){v(i,200,{...oe(p),_meta:{format:"compact",startedFromState:null,warning:E,waitedMs:0}});return}let _=p.status;p.status!=="starting"&&p.status!=="compiling"&&await n.start(u);let A=await n.waitFor(u,T,f),x=n.summary(u),P=x?oe(x):{name:u,status:A.status,port:null,url:null,health:A.health,errCount:0,lastChangeMs:null,uptime:null};if(A.timedOut){v(i,200,{error:"timeout",state:P,_meta:{format:"compact",startedFromState:_,warning:E,waitedMs:A.waitedMs,timedOut:!0}});return}v(i,200,{...P,_meta:{format:"compact",startedFromState:_,warning:E,waitedMs:A.waitedMs}});return}if(g==="start"&&l==="POST"){if(a.searchParams.get("withDeps")==="1"){let h=await n.startWithDeps(u);v(i,h.ok?200:400,h);return}let m=await n.start(u);v(i,m.ok?200:400,m);return}if(g==="start-with-deps"&&l==="POST"){let p=await n.startWithDeps(u);v(i,p.ok?200:400,p);return}if(g==="tasks"&&l==="GET"&&!y){let p=n.listTasks(u);if(p==null){v(i,404,{error:"unknown app"});return}v(i,200,{tasks:p,watching:n.listWatchTasks(u)});return}if(g==="run"&&y&&l==="POST"){let p={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(f=>{let w=[];o.on("data",T=>w.push(T)),o.on("end",()=>{try{p=JSON.parse(Buffer.concat(w).toString("utf8"))}catch{}f()})});let m=Array.isArray(p.args)?p.args.map(String):[];if(p.watch){let f=n.startWatchTask(u,y,m);v(i,f.ok?200:400,f);return}let h=await n.runTask(u,y,m);if("error"in h){v(i,404,h);return}v(i,200,h);return}if(g==="run-stop"&&y&&l==="POST"){let p=await n.stopWatchTask(u,y);v(i,200,p);return}if(g==="env"&&l==="GET"){let m=n.getConfig().envFiles?.[u]??[],h=n.getState(u);v(i,200,{candidates:m,active:h?.activeEnvFile??null});return}if(g==="env"&&l==="POST"){let p={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(h=>{let f=[];o.on("data",w=>f.push(w)),o.on("end",()=>{try{p=JSON.parse(Buffer.concat(f).toString("utf8"))}catch{}h()})}),n.setActiveEnvFile(u,p.use??null);let m=n.getState(u);v(i,200,{active:m?.activeEnvFile??null});return}if(g==="requests"&&l==="GET"){if(!e.requestLog){v(i,200,[]);return}let p=ie(a.searchParams.get("since"));v(i,200,e.requestLog.requests(u,p));return}if(g==="clean"&&l==="POST"){let p=a.searchParams.get("deep")==="1",m=a.searchParams.get("yes")==="1",h=jn(n,u,p);if(!h){v(i,404,{error:"unknown app"});return}if(h.ranOnServing){v(i,409,{error:"refusing: app is currently running",plan:h});return}if(!m){v(i,200,{plan:h,hint:"pass --yes to delete"});return}let f=js(n,u,p);v(i,200,f);return}if(g==="snapshot"&&l==="POST"){if(a.searchParams.get("write")==="1"){let h=Os(n,u);if(!h){v(i,404,{error:"unknown app"});return}v(i,200,{snapshot:h.path});return}let m=$n(n,u);if(!m){v(i,404,{error:"unknown app"});return}v(i,200,m);return}if(g==="stop"&&l==="POST"){let p=await n.stop(u);v(i,p.ok?200:400,p);return}if(g==="restart"&&l==="POST"){let p=await n.restart(u);v(i,p.ok?200:400,p);return}if(l==="GET"&&!a.pathname.startsWith("/api/")&&!a.pathname.startsWith("/metrics")){let p=Fn();if(p){let m=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(m){let h=pt.resolve(p,m);if(h.startsWith(p)&&ye(i,h))return}if(!pt.extname(m||"")&&ye(i,pt.join(p,"index.html")))return}}v(i,404,{error:"not found"})}catch(a){v(i,500,{error:a?.message||String(a)})}});return s.listen(t,"127.0.0.1"),s}var jc,He,_c,Lc,so=F(()=>{"use strict";Ps();Ns();_s();Ls();Bs();Js();_n();Et();jc=$c(import.meta.url),He=pt.dirname(jc);_c={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".ico":"image/x-icon",".json":"application/json; charset=utf-8",".map":"application/json; charset=utf-8",".woff2":"font/woff2",".woff":"font/woff",".ttf":"font/ttf"};Lc=/key|secret|token|password|pass/i});import Fc from"node:http";import Bc from"node:https";function oo(n,t,e,r,s){if(t)return[t];let o=n.path||"/",i=n.fallbackHosts&&n.fallbackHosts.length?n.fallbackHosts:["127.0.0.1"];if(n.host||n.scheme){let l=e?We(e):null,c=n.scheme||l?.protocol?.replace(":","")||"http",d=n.host||l?.hostname||(r?i[0]:"127.0.0.1"),u=r??(l?.port?Number(l.port):null);return[io(c,d,u,o)]}if(e){let l=We(e);if(l)return l.pathname=o,[l.toString()]}let a=[];s&&a.push(s);for(let l of i)a.includes(l)||a.push(l);return a.map(l=>io("http",l,r,o))}function We(n){try{return new URL(n)}catch{return null}}function io(n,t,e,r){let s=t.includes(":")&&!t.startsWith("[")?`[${t}]`:t,o=e?`:${e}`:"";return`${n}://${s}${o}${r.startsWith("/")?r:"/"+r}`}var Uc,Hc,Jc,Ge,ao=F(()=>{"use strict";Uc=1e3,Hc=500,Jc=["/","/health","/-/health","/api/health","/ready","/healthz"];Ge=class{constructor(t,e,r){this.registry=t;this.cfg=e;this.fullConfig=r;if(e.enabled){t.on("change",this.onChange);for(let s of t.names())this.evaluate(s)}}registry;cfg;fullConfig;timers=new Map;starting=new Map;freshness=new Map;stopped=!1;stop(){this.stopped=!0,this.registry.off("change",this.onChange);for(let t of this.timers.values())clearInterval(t);for(let t of this.starting.values())clearTimeout(t);this.timers.clear(),this.starting.clear()}onChange=()=>{if(!this.stopped)for(let t of this.registry.names())this.evaluate(t)};evaluate(t){let e=this.registry.getState(t);if(e)if(e.status==="serving"){if(this.timers.has(t)||this.starting.has(t))return;this.freshness.set(t,{retried:!1});let r=setTimeout(()=>{this.starting.delete(t),this.probe(t);let s=setInterval(()=>{this.probe(t)},this.cfg.intervalMs);this.timers.set(t,s)},Hc);this.starting.set(t,r)}else{let r=this.timers.get(t);r&&(clearInterval(r),this.timers.delete(t));let s=this.starting.get(t);s&&(clearTimeout(s),this.starting.delete(t)),this.freshness.delete(t),e.health!=="unknown"&&(e.status==="stopped"||e.status==="error")&&this.registry.setHealth(t,"unknown")}}async probe(t){let e=this.registry.getState(t);if(!e||e.status!=="serving")return;let r=this.fullConfig?.overrides?.[t]?.url,s=this.fullConfig?.overrides?.[t]?.healthProbePath,o=this.cfg;s?o={...this.cfg,path:s}:e.discoveredHealthPath&&(o={...this.cfg,path:e.discoveredHealthPath});let i=oo(o,r,e.announcedUrl,e.port,e.cachedProbeHost);if(!r&&!s&&!e.discoveredHealthPath&&(this.cfg.path==="/"||!this.cfg.path)&&e.health!=="healthy"&&this.discoverPath(t),i.length===0){this.registry.setLastHealthError(t,"no probe URL available"),this.registry.setHealth(t,"unhealthy");return}let a=null;for(let c of i){let d=await this.tryProbe(c);if(d.ok){let u=We(c);u&&this.registry.setCachedProbeHost(t,u.hostname.replace(/^\[|\]$/g,"")),this.registry.setResolvedUrl(t,c),this.registry.setLastHealthError(t,null),this.registry.setHealth(t,"healthy");return}a||(a=`${d.error} ${c}`)}let l=this.freshness.get(t);if(l&&!l.retried){l.retried=!0,setTimeout(()=>{this.probe(t)},Uc);return}this.registry.setLastHealthError(t,a||"unknown probe failure"),this.registry.setHealth(t,"unhealthy")}async discoverPath(t){let e=this.registry.getState(t);if(!(!e||e.status!=="serving")&&!e.discoveredHealthPath)for(let r of Jc){let s={...this.cfg,path:r},o=oo(s,void 0,e.announcedUrl,e.port,e.cachedProbeHost);for(let i of o)if((await this.tryProbe(i,{strict2xx:!0})).ok){e.discoveredHealthPath=r,this.registry.recordEvent({app:t,type:"health",message:`discovered probe path: ${r} (pin via POST /api/apps/${encodeURIComponent(t)}/health/pin or daimon pin-health ${t} --accept)`});return}}}tryProbe(t,e={}){return new Promise(r=>{let s=!1,o=d=>{s||(s=!0,r(d))},i=t.startsWith("https://"),a=i?Bc:Fc,l={timeout:this.cfg.timeoutMs};if(i){let u=We(t)?.hostname?.replace(/^\[|\]$/g,"")??"",g=u==="127.0.0.1"||u==="::1"||u==="localhost";l.rejectUnauthorized=g?!1:!!this.cfg.rejectUnauthorized}let c=e.strict2xx?300:500;try{let d=a.get(t,l,u=>{let g=u.statusCode??0;u.resume(),g>=200&&g<c?o({ok:!0}):o({ok:!1,error:`http ${g}`})});d.on("timeout",()=>d.destroy(new Error("timeout"))),d.on("error",u=>o({ok:!1,error:u?.code||u?.message||"error"}))}catch(d){o({ok:!1,error:d?.message||"throw"})}})}}});import Wc from"pidusage";var qe,co=F(()=>{"use strict";qe=class{constructor(t,e=2e3){this.registry=t;this.intervalMs=e;this.timer=setInterval(()=>this.tick(),e)}registry;intervalMs;timer=null;stopped=!1;stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}async tick(){if(this.stopped)return;let t=[];for(let r of this.registry.names()){let s=this.registry.getState(r);s?.pid&&t.push({name:r,pid:s.pid})}if(!t.length)return;let e=!1;await Promise.all(t.map(async({name:r,pid:s})=>{try{let o=await Wc(s),i=this.registry.getState(r);if(!i)return;let a=Math.round(o.cpu*10)/10,l=Math.round(o.memory/(1024*1024));(i.cpu!==a||i.memMB!==l)&&(i.cpu=a,i.memMB=l,e=!0)}catch{let o=this.registry.getState(r);o&&(o.cpu!=null||o.memMB!=null)&&(o.cpu=null,o.memMB=null,e=!0)}})),e&&this.registry.emit("change")}}});var Xe,lo=F(()=>{"use strict";Xe=class{constructor(t,e){this.registry=t;this.cfg=e}registry;cfg;timers=new Map;stopped=!1;stop(){this.stopped=!0;for(let t of this.timers.values())clearTimeout(t);this.timers.clear()}onExit(t,e,r,s){if(this.stopped||s||!this.cfg.enabled||e===0&&!r)return;let o=this.registry.getState(t);if(!o)return;let i=Date.now();if((o.restartWindowStart==null||i-o.restartWindowStart>this.cfg.windowMs)&&(o.restartWindowStart=i,o.restartAttempts=0),o.restartAttempts+=1,o.restartAttempts>this.cfg.maxAttempts){o.lastStatusMessage=`auto-restart aborted (${o.restartAttempts-1}/${this.cfg.maxAttempts} within window)`,o.nextRestartAt=null,this.registry.recordEvent({app:t,type:"restart-scheduled",message:o.lastStatusMessage}),this.registry.emit("change");return}let a=Math.min(2**(o.restartAttempts-1)*1e3,3e4);o.nextRestartAt=i+a,o.lastStatusMessage=`restarting in ${Math.round(a/1e3)}s (attempt ${o.restartAttempts}/${this.cfg.maxAttempts})`,this.registry.recordEvent({app:t,type:"restart-scheduled",message:o.lastStatusMessage}),this.registry.emit("change");let l=setTimeout(()=>{this.timers.delete(t);let c=this.registry.getState(t);c&&(c.nextRestartAt=null),this.registry.start(t)},a);this.timers.set(t,l)}onUserStop(t){let e=this.timers.get(t);e&&(clearTimeout(e),this.timers.delete(t));let r=this.registry.getState(t);r&&(r.restartAttempts=0,r.restartWindowStart=null,r.nextRestartAt=null)}}});import Wn from"node:fs";import uo from"node:path";import Gc from"node:os";function po(){try{let n=Wn.readFileSync(Gn,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.ports&&typeof t.ports=="object")return{ports:t.ports}}catch{}return{ports:{}}}function fo(n){Jn=n,!Hn&&(Hn=setTimeout(()=>{Hn=null;let t=Jn;if(Jn=null,!!t)try{Wn.mkdirSync(uo.dirname(Gn),{recursive:!0}),Wn.writeFileSync(Gn,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: state write failed: ${e.message}
79
- `)}},500))}var Gn,Hn,Jn,mo=F(()=>{"use strict";Gn=uo.join(Gc.homedir(),".daimon","state.json");Hn=null,Jn=null});import ho from"node:fs";import qc from"node:os";import go from"node:path";import{createRequire as Xc}from"node:module";var Kc,zc,Ke,yo=F(()=>{"use strict";Kc=Xc(import.meta.url),zc=6e4,Ke=class{constructor(t,e){this.registry=t;this.cfg=e;this.logFile=go.join(qc.homedir(),".daimon","notifications.log");try{ho.mkdirSync(go.dirname(this.logFile),{recursive:!0})}catch{}if(!e.enabled){this.audit("init","disabled by config");return}try{let r=Kc("node-notifier");if(this.notifier=r,process.platform==="win32")try{let s=r.WindowsToaster;s&&(this.toaster=new s({withFallback:!0}))}catch(s){this.audit("init",`WindowsToaster unavailable: ${s?.message||s}`)}this.audit("init",`node-notifier loaded${this.toaster?" (+WindowsToaster fallback)":""}`)}catch(r){this.warnOnce(`node-notifier unavailable: ${r?.message||r}`),this.audit("init",`node-notifier load failed: ${r?.message||r}`);return}t.on("event",this.onEvent)}registry;cfg;notifier=null;toaster=null;lastSent=new Map;warned=!1;logFile;audit(t,e){let r=`${new Date().toISOString()} ${t} ${e}
80
- `;try{ho.appendFileSync(this.logFile,r)}catch{}}warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] notifier: ${t}
81
- `))}stop(){this.registry.off("event",this.onEvent)}onEvent=t=>{this.notifier&&(t.type==="status"&&t.to==="error"&&this.cfg.onError?this.fire(t.app,"error",`${t.app} \u2192 error`,t.message||"app entered error state"):t.type==="health"&&t.to==="unhealthy"&&this.cfg.onUnhealthy?this.fire(t.app,"unhealthy",`${t.app} unhealthy`,"health probe failing"):t.type==="stale"?this.fire(t.app,"stale",`${t.app} stale`,t.message||"no output despite source changes"):t.type==="compile-regression"?this.fire(t.app,"compile-regression",`${t.app} slow compile`,t.message||"compile time regression"):t.type==="bundle-regression"?this.fire(t.app,"bundle-regression",`${t.app} bundle grew`,t.message||"bundle size regression"):t.type==="task-run"&&/exit=[1-9]/.test(t.message||"")&&this.fire(t.app,"task-fail",`${t.app} task failed`,t.message||""))};fire(t,e,r,s){if(!this.notifier)return;let o=`${t}::${e}`,i=this.lastSent.get(o)??0,a=Date.now();if(a-i<zc){this.audit("throttled",`${o}`);return}this.lastSent.set(o,a);let l={title:`daimon: ${r}`,message:s,wait:!1,appID:"daimon"},c=(d,u)=>{d?(this.audit("fail",`${o} :: ${d?.message||d}`),this.warnOnce(`notify failed: ${d?.message||d}`)):this.audit("ok",`${o} :: ${r} :: ${u??"(no response)"}`)};try{this.audit("attempt",`${o} :: ${r}`),(this.toaster??this.notifier).notify(l,c)}catch(d){this.audit("throw",`${o} :: ${d?.message||d}`),this.warnOnce(`notify threw: ${d?.message||d}`)}}}});import wo from"node:fs";import qn from"node:path";var Yc,Vc,Zc,Qc,ze,bo=F(()=>{"use strict";Yc=5e3,Vc=3e4,Zc=new Set(["node_modules","dist",".angular",".nx",".git","tmp","out-tsc","coverage"]),Qc=new Set([".ts",".tsx",".html",".scss",".css",".js",".jsx",".json"]),ze=class{constructor(t,e){this.registry=t;this.cfg=e;e.enabled&&(this.timer=setInterval(()=>this.tick(),Yc),t.on("compile",this.onCompile))}registry;cfg;timer=null;caches=new Map;stop(){this.timer&&clearInterval(this.timer),this.registry.off("compile",this.onCompile)}onCompile=t=>{let e=this.registry.getApp(t.name);e&&this.caches.delete(e.workspaceRoot)};tick(){for(let t of this.registry.names())this.evaluate(t)}evaluate(t){let e=this.registry.getState(t),r=this.registry.getApp(t);if(!e||!r)return;if(e.status!=="serving"){e.stale&&this.registry.setStale(t,!1);return}if(e.startedAt==null)return;let s=e.lastLogTs??e.startedAt,o=Date.now()-s;if(o<this.cfg.silentMs){e.stale&&this.registry.setStale(t,!1);return}let i=e.lastCompileAt??e.startedAt;this.hasSourceChange(r.workspaceRoot,i,e.lastCompileAt)&&(e.stale||(this.registry.setStale(t,!0),this.registry.recordEvent({app:t,type:"stale",message:`no output in ${Math.round(o/1e3)}s despite source changes`})))}hasSourceChange(t,e,r){let s=this.caches.get(t);if(!s||Date.now()-s.ts>Vc||r!=null&&s.ts<r){let a=this.scan(t);this.caches.set(t,{ts:Date.now(),files:a})}return this.caches.get(t).files.some(a=>a.mtime>e)}scan(t){let e=[],r=(s,o)=>{if(o>8||e.length>4e3)return;let i;try{i=wo.readdirSync(s,{withFileTypes:!0})}catch{return}for(let a of i)if(!a.name.startsWith(".git")){if(a.isDirectory()){if(Zc.has(a.name))continue;r(qn.join(s,a.name),o+1)}else if(a.isFile()){let l=qn.extname(a.name);if(!Qc.has(l))continue;try{let c=qn.join(s,a.name),d=wo.statSync(c);e.push({path:c,mtime:d.mtimeMs})}catch{}}}};return r(t,0),e}}});import vo from"node:http";var Ye,Ve,So=F(()=>{"use strict";Ye=200,Ve=class{constructor(t,e){this.registry=t;this.cfg=e;e.enabled&&(t.on("change",this.onChange),this.tick())}registry;cfg;proxies=new Map;stopped=!1;stop(){this.stopped=!0,this.registry.off("change",this.onChange);for(let t of this.proxies.values())try{t.server.close()}catch{}this.proxies.clear()}onChange=()=>{this.stopped||this.tick()};tick(){for(let t of this.registry.names()){let e=this.registry.getState(t);if(!e)continue;let r=this.proxies.has(t);e.status==="serving"&&e.port&&!r?this.startProxy(t,e.port):e.status!=="serving"&&r&&this.stopProxy(t)}}stopProxy(t){let e=this.proxies.get(t);if(e){try{e.server.close()}catch{}this.proxies.delete(t)}}startProxy(t,e){let r=e+this.cfg.portOffset,s=[],o=vo.createServer((i,a)=>{let l=Date.now(),c={hostname:"127.0.0.1",port:e,method:i.method,path:i.url,headers:{...i.headers,host:`127.0.0.1:${e}`}},d=vo.request(c,u=>{a.writeHead(u.statusCode||502,u.headers),u.pipe(a);let g=()=>{s.push({ts:Date.now(),method:i.method||"GET",path:i.url||"/",status:u.statusCode||0,durationMs:Date.now()-l}),s.length>Ye&&s.splice(0,s.length-Ye)};u.on("end",g),u.on("error",g)});d.on("error",()=>{a.writeHead(502).end("upstream error"),s.push({ts:Date.now(),method:i.method||"GET",path:i.url||"/",status:502,durationMs:Date.now()-l}),s.length>Ye&&s.splice(0,s.length-Ye)}),i.pipe(d)});o.on("error",i=>{i?.code==="EADDRINUSE"&&process.stderr.write(`[daimon] requestLog: port ${r} in use for ${t}; disabling proxy
82
- `),this.proxies.delete(t)}),o.listen(r,"127.0.0.1",()=>{this.proxies.set(t,{app:t,proxyPort:r,server:o,buffer:s})})}requests(t,e){let r=this.proxies.get(t);if(!r)return[];if(e){let s=Date.now()-e;return r.buffer.filter(o=>o.ts>=s)}return[...r.buffer]}proxyPortFor(t){return this.proxies.get(t)?.proxyPort??null}}});import Xn from"node:fs";function ko(n){let t=Xn.readFileSync(n,"utf8");t.charCodeAt(0)===65279&&(t=t.slice(1));let e=JSON.parse(t);if(!e||typeof e!="object"||Array.isArray(e))throw new Error("config must be a JSON object");return e}function xo(n,t){if(t===null)return null;if(typeof t!="object"||Array.isArray(t))return t;let e=n&&typeof n=="object"&&!Array.isArray(n)?{...n}:{};for(let[r,s]of Object.entries(t))s===null?delete e[r]:e[r]=xo(e[r],s);return e}function el(n,t){let e=n+"."+process.pid+".tmp";Xn.writeFileSync(e,t,"utf8"),Xn.renameSync(e,n)}function nl(n,t){let e=new Set;for(let r of Object.keys(t))JSON.stringify(n?.[r])!==JSON.stringify(t[r])&&e.add(r);for(let r of Object.keys(n||{}))r in t||e.add(r);return[...e]}function To(n){let t=ko(n.configPath),e=xo(t,n.patch);if(!e||typeof e!="object")throw new Error("patch produced non-object config");let r=ve(e,n.configPath);return el(n.configPath,JSON.stringify(e,null,2)+`
83
- `),{config:r,raw:e,applied:nl(t,e),prevRaw:t}}function Kn(n){let t=ko(n.configPath),e=ve(t,n.configPath);return rl(n.registry,e)}function rl(n,t){let e=n.getConfig();for(let c of Object.keys(e))e[c]=void 0;Object.assign(e,t);let r=new Set(n.names()),s=It(e),o=new Set(s.map(c=>c.name)),i=[],a=[];for(let c of s)r.has(c.name)?n.updateDiscoveredApp(c):(n.addDiscoveredApp(c),i.push(c.name));for(let c of r)o.has(c)||a.push(c);let l=[];for(let c of n.names()){let d=n.getState(c);if(d&&(d.status==="serving"||d.status==="compiling")){let u=e.overrides?.[c];if(!u)continue;for(let g of tl)if(g in u){l.push(c);break}}}return{addedApps:i,removedApps:a,restartRequired:l,config:e}}var tl,Co=F(()=>{"use strict";Xt();zt();tl=new Set(["command","port","env","url"])});import Eo from"node:fs";import sl from"node:os";import Po from"node:path";function il(n){if(!n)return null;let t=JSON.parse(JSON.stringify(n));if(t.apiToken&&(t.apiToken="***"),t.overrides)for(let e of Object.keys(t.overrides)){let r=t.overrides[e]?.env;if(r)for(let s of Object.keys(r))ol.test(s)&&(r[s]="***")}return t}function al(n,t=200){if(!n)return[];let e=[];for(let r of n.names()){let s=n.getState(r);if(s)for(let o of s.logBuffer)e.push({ts:o.ts,line:`[${r}] ${o.line}`})}return e.sort((r,s)=>r.ts-s.ts),e.slice(-t).map(r=>r.line)}function cl(){let n=Po.join(ut(),"crashes");return Eo.mkdirSync(n,{recursive:!0}),n}function ll(n,t,e){let r=new Date().toISOString().replace(/[:.]/g,"-"),s=Po.join(cl(),`${r}.txt`),o=n,i=[`daimon crash dump @ ${new Date().toISOString()}`,`version: ${Z}`,`node: ${process.version}`,`platform: ${process.platform} ${sl.release()}`,`cwd: ${process.cwd()}`,`pid: ${process.pid}`,"","ERROR:",o?.stack||String(o),"","CONFIG (redacted):",JSON.stringify(il(e),null,2),"","RECENT LOG (last 200 lines across apps):",...al(t,200)];try{Eo.writeFileSync(s,i.join(`
84
- `))}catch{}return s}function Ro(n){let t=e=>{let r=null;try{r=ll(e,n.getRegistry(),n.getConfig())}catch{}try{process.stderr.write(`[daimon] fatal: ${e?.stack||e}
76
+ `),3e4);o.on("close",()=>{n.off("log",T),clearInterval(P)});return}if(f==="logs"&&c==="GET"){let p=a.searchParams.get("tail"),m=a.searchParams.get("since"),h=n.logs(y,{tail:p?Number(p):void 0,sinceMs:fe(m)});if(h==null){x(i,404,{error:"unknown app"});return}x(i,200,{lines:h});return}if(f==="focus"&&c==="POST"){let p=n.summary(y);if(!p){x(i,404,{error:"unknown app"});return}let m=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy","stable"].includes(m)){x(i,400,{error:"until must be one of serving|healthy|stable"});return}let h=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),k=h?Number(h):18e4;(!Number.isFinite(k)||k<=0)&&(k=18e4),k=Math.min(k,6e5);let T=a.searchParams.get("stableMs"),P=T&&Number.isFinite(Number(T))?Math.max(1e3,Number(T)):5e3;i.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8","cache-control":"no-cache",connection:"keep-alive"});let v=J=>{try{i.write(JSON.stringify(J)+`
77
+ `)}catch{}};v({kind:"subscribed",app:y,until:m,ts:Date.now(),state:de(p)});let w=Date.now(),E=Date.now(),S=!1,O=J=>{if(S)return;S=!0,n.off("event",X),clearInterval(j),clearInterval(W),clearTimeout(Q);let wt=n.summary(y);v({kind:"done",reason:J,ts:Date.now(),state:wt?de(wt):null,waitedMs:Date.now()-w});try{i.end()}catch{}},I=()=>{let J=n.summary(y);if(!J)return!1;if(m==="serving")return J.status==="serving";if(m==="healthy")return J.status==="serving"&&J.health==="healthy";if(m==="stable"){let wt=Date.now()-E;return J.status==="serving"&&J.health==="healthy"&&wt>=P}return!1},X=J=>{if(J.app===y)if(E=Date.now(),J.type==="status")v({kind:"status",from:J.from,to:J.to,ts:J.ts}),m!=="stable"&&I()&&O("reached");else if(J.type==="error-new"||J.type==="error-recur"){let Z=(n.errors(y)??[])[0];Z&&v({kind:"error",message:Z.message,parsed:Z.parsed??null,ts:J.ts})}else J.type==="health"&&(v({kind:"health",from:J.from,to:J.to,ts:J.ts}),m!=="stable"&&I()&&O("reached"))};n.on("event",X);let j=setInterval(()=>{I()&&O("reached")},1e3),W=setInterval(()=>{try{i.write(`
78
+ `)}catch{}},3e4),Q=setTimeout(()=>O("timeout"),k);o.on("close",()=>O("closed")),I()&&O("reached");return}if(f==="health"&&g==="pin"&&c==="POST"){let p=n.getState(y);if(!p){x(i,404,{error:"unknown app"});return}let m={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(S=>{let O=[];o.on("data",I=>O.push(I)),o.on("end",()=>{try{m=JSON.parse(Buffer.concat(O).toString("utf8"))}catch{}S()})});let h=typeof m.path=="string"&&m.path?m.path:p.discoveredHealthPath??null;if(!h){x(i,400,{error:"no path supplied and no discoveredHealthPath on app"});return}let{configLookupPaths:k}=await Promise.resolve().then(()=>(ee(),Or)),{local:T,user:P}=k(),v=Lt.existsSync(T)?T:P,w={};try{w=JSON.parse(Lt.readFileSync(v,"utf8"))}catch{}(!w.overrides||typeof w.overrides!="object")&&(w.overrides={}),(!w.overrides[y]||typeof w.overrides[y]!="object")&&(w.overrides[y]={});let E=w.overrides[y].healthProbePath??null;if(w.overrides[y].healthProbePath=h,Lt.writeFileSync(v,JSON.stringify(w,null,2)+`
79
+ `,"utf8"),e.reloadConfig)try{await e.reloadConfig()}catch{}x(i,200,{pinned:h,app:y,configPath:v,previous:E});return}if(f==="try-fix"&&c==="POST"){let p=n.summary(y);if(!p){x(i,404,{error:"unknown app"});return}let m=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(m)){x(i,400,{error:"until must be serving|healthy"});return}let h=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),k=h?Number(h):18e4;(!Number.isFinite(k)||k<=0)&&(k=18e4),k=Math.min(k,6e5);let T={status:p.status,health:p.health,errCount:p.errorCount,firstError:(n.errors(y)??[])[0]?.parsed??null},{runAutoFix:P,ALL_AUTO_FIX:v}=await Promise.resolve().then(()=>(pe(),ue)),E=e.getConfig?.()?.doctor?.autoFix?.permitted??v,S={ran:[],skipped:[],errors:[]};try{S=await P({permitted:E,dryRun:!1})}catch(Z){S.errors.push({name:"auto-fix",error:Z?.message??String(Z)})}let O=(S.ran??[]).map(Z=>Z.name),I=null;try{let Z=await n.restart(y);Z?.ok||(I=Z?.error??"restart failed")}catch(Z){I=Z?.message??String(Z)}let X=await n.waitFor(y,m,k),j=n.summary(y),Q=(n.errors(y)??[]).slice(0,5).map(Z=>({file:Z.parsed?.file??null,line:Z.parsed?.line??null,code:Z.parsed?.code??null,tool:Z.parsed?.tool??null,message:Z.parsed?.message??Z.message})),J=j?{status:j.status,health:j.health,errCount:j.errorCount}:{status:X.status,health:X.health,errCount:0},wt=m==="serving"&&J.status==="serving"||m==="healthy"&&J.status==="serving"&&J.health==="healthy";x(i,200,{before:T,after:J,fixed:O,stillFailing:Q,reached:wt,waitedMs:X.waitedMs,_meta:{autoFix:S,restartErr:I,timedOut:X.timedOut}});return}if(f==="wait"&&c==="GET"){if(!n.summary(y)){x(i,404,{error:"unknown app"});return}let p=(a.searchParams.get("until")||"serving").toLowerCase();if(!["serving","healthy","stopped","error"].includes(p)){x(i,400,{error:"until must be one of serving|healthy|stopped|error"});return}let m=a.searchParams.get("timeout"),h=m?Number(m):120;(!Number.isFinite(h)||h<=0)&&(h=120),h=Math.min(h,600);let k=await n.waitFor(y,p,h*1e3);x(i,200,k);return}if(f==="ensure"&&c==="POST"){let p=n.summary(y);if(!p){x(i,404,{error:"unknown app"});return}let m=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(m)){x(i,400,{error:"until must be serving|healthy"});return}let h=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),k=h?Number(h):18e4;(!Number.isFinite(k)||k<=0)&&(k=18e4),k=Math.min(k,6e5);let T=e.getConfig?.().healthProbe?.enabled??!0,P=m,v;if(P==="healthy"&&!T&&(P="serving",v="no health probe; treated serving as terminal"),P==="serving"&&p.status==="serving"||P==="healthy"&&p.status==="serving"&&p.health==="healthy"){x(i,200,{...de(p),_meta:{format:"compact",startedFromState:null,warning:v,waitedMs:0}});return}let E=p.status;p.status!=="starting"&&p.status!=="compiling"&&await n.start(y);let S=await n.waitFor(y,P,k),O=n.summary(y),I=O?de(O):{name:y,status:S.status,port:null,url:null,health:S.health,errCount:0,lastChangeMs:null,uptime:null};if(S.timedOut){x(i,200,{error:"timeout",state:I,_meta:{format:"compact",startedFromState:E,warning:v,waitedMs:S.waitedMs,timedOut:!0}});return}x(i,200,{...I,_meta:{format:"compact",startedFromState:E,warning:v,waitedMs:S.waitedMs}});return}if(f==="start"&&c==="POST"){if(a.searchParams.get("withDeps")==="1"){let h=await n.startWithDeps(y);x(i,h.ok?200:400,h);return}let m=await n.start(y);x(i,m.ok?200:400,m);return}if(f==="start-with-deps"&&c==="POST"){let p=await n.startWithDeps(y);x(i,p.ok?200:400,p);return}if(f==="tasks"&&c==="GET"&&!g){let p=n.listTasks(y);if(p==null){x(i,404,{error:"unknown app"});return}x(i,200,{tasks:p,watching:n.listWatchTasks(y)});return}if(f==="run"&&g&&c==="POST"){let p={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(k=>{let T=[];o.on("data",P=>T.push(P)),o.on("end",()=>{try{p=JSON.parse(Buffer.concat(T).toString("utf8"))}catch{}k()})});let m=Array.isArray(p.args)?p.args.map(String):[];if(p.watch){let k=n.startWatchTask(y,g,m);x(i,k.ok?200:400,k);return}let h=await n.runTask(y,g,m);if("error"in h){x(i,404,h);return}x(i,200,h);return}if(f==="run-stop"&&g&&c==="POST"){let p=await n.stopWatchTask(y,g);x(i,200,p);return}if(f==="env"&&c==="GET"){let m=n.getConfig().envFiles?.[y]??[],h=n.getState(y);x(i,200,{candidates:m,active:h?.activeEnvFile??null});return}if(f==="env"&&c==="POST"){let p={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(h=>{let k=[];o.on("data",T=>k.push(T)),o.on("end",()=>{try{p=JSON.parse(Buffer.concat(k).toString("utf8"))}catch{}h()})}),n.setActiveEnvFile(y,p.use??null);let m=n.getState(y);x(i,200,{active:m?.activeEnvFile??null});return}if(f==="requests"&&c==="GET"){if(!e.requestLog){x(i,200,[]);return}let p=fe(a.searchParams.get("since"));x(i,200,e.requestLog.requests(y,p));return}if(f==="clean"&&c==="POST"){let p=a.searchParams.get("deep")==="1",m=a.searchParams.get("yes")==="1",h=zn(n,y,p);if(!h){x(i,404,{error:"unknown app"});return}if(h.ranOnServing){x(i,409,{error:"refusing: app is currently running",plan:h});return}if(!m){x(i,200,{plan:h,hint:"pass --yes to delete"});return}let k=Xs(n,y,p);x(i,200,k);return}if(f==="snapshot"&&c==="POST"){if(a.searchParams.get("write")==="1"){let h=Js(n,y);if(!h){x(i,404,{error:"unknown app"});return}x(i,200,{snapshot:h.path});return}let m=Kn(n,y);if(!m){x(i,404,{error:"unknown app"});return}x(i,200,m);return}if(f==="stop"&&c==="POST"){let p=await n.stop(y);x(i,p.ok?200:400,p);return}if(f==="restart"&&c==="POST"){let p=await n.restart(y);x(i,p.ok?200:400,p);return}if(c==="GET"&&!a.pathname.startsWith("/api/")&&!a.pathname.startsWith("/metrics")){let p=er();if(p){let m=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(m){let h=ht.resolve(p,m);if(h.startsWith(p)&&Re(i,h))return}if(!ht.extname(m||"")&&Re(i,ht.join(p,"index.html")))return}}x(i,404,{error:"not found"})}catch(a){x(i,500,{error:a?.message||String(a)})}});return s.listen(t,"127.0.0.1"),s}var Zc,rn,Qc,el,So=U(()=>{"use strict";Bs();Ws();Ks();Ys();Qs();no();Yn();_t();Bn();Zc=Vc(import.meta.url),rn=ht.dirname(Zc);Qc={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".ico":"image/x-icon",".json":"application/json; charset=utf-8",".map":"application/json; charset=utf-8",".woff2":"font/woff2",".woff":"font/woff",".ttf":"font/ttf"};el=/key|secret|token|password|pass/i});import rl from"node:http";import sl from"node:https";function ko(n,t,e,r,s){if(t)return[t];let o=n.path||"/",i=n.fallbackHosts&&n.fallbackHosts.length?n.fallbackHosts:["127.0.0.1"];if(n.host||n.scheme){let c=e?on(e):null,l=n.scheme||c?.protocol?.replace(":","")||"http",u=n.host||c?.hostname||(r?i[0]:"127.0.0.1"),d=r??(c?.port?Number(c.port):null);return[xo(l,u,d,o)]}if(e){let c=on(e);if(c)return c.pathname=o,[c.toString()]}let a=[];s&&a.push(s);for(let c of i)a.includes(c)||a.push(c);return a.map(c=>xo("http",c,r,o))}function on(n){try{return new URL(n)}catch{return null}}function xo(n,t,e,r){let s=t.includes(":")&&!t.startsWith("[")?`[${t}]`:t,o=e?`:${e}`:"";return`${n}://${s}${o}${r.startsWith("/")?r:"/"+r}`}var ol,il,al,an,To=U(()=>{"use strict";Vn();ol=1e3,il=500,al=["/","/health","/-/health","/api/health","/ready","/healthz"];an=class{constructor(t,e,r){this.registry=t;this.cfg=e;this.fullConfig=r;if(e.enabled){t.on("change",this.onChange);for(let s of t.names())this.evaluate(s)}}registry;cfg;fullConfig;timers=new Map;starting=new Map;freshness=new Map;stopped=!1;stop(){this.stopped=!0,this.registry.off("change",this.onChange);for(let t of this.timers.values())clearInterval(t);for(let t of this.starting.values())clearTimeout(t);this.timers.clear(),this.starting.clear()}onChange=()=>{if(!this.stopped)for(let t of this.registry.names())this.evaluate(t)};evaluate(t){let e=this.registry.getState(t);if(e)if(e.status==="serving"){if(this.timers.has(t)||this.starting.has(t))return;this.freshness.set(t,{retried:!1});let r=setTimeout(()=>{this.starting.delete(t),this.probe(t);let s=setInterval(()=>{this.probe(t)},this.cfg.intervalMs);this.timers.set(t,s)},il);this.starting.set(t,r)}else{let r=this.timers.get(t);r&&(clearInterval(r),this.timers.delete(t));let s=this.starting.get(t);s&&(clearTimeout(s),this.starting.delete(t)),this.freshness.delete(t),e.health!=="unknown"&&(e.status==="stopped"||e.status==="error")&&this.registry.setHealth(t,"unknown")}}async probe(t){let e=this.registry.getState(t);if(!e||e.status!=="serving")return;let r=this.fullConfig?.overrides?.[t]?.url,s=this.registry.getApp(t),o=e.baseName??t,i=this.fullConfig?.overrides?.[t]?.healthProbePath??this.fullConfig?.overrides?.[o]?.healthProbePath,a=nn(s?.serverProfile),c=this.cfg;i?c={...this.cfg,path:i}:e.discoveredHealthPath?c={...this.cfg,path:e.discoveredHealthPath}:a&&(this.cfg.path==="/"||!this.cfg.path)&&(c={...this.cfg,path:a});let l=ko(c,r,e.announcedUrl,e.port,e.cachedProbeHost);if(!r&&!i&&!e.discoveredHealthPath&&(this.cfg.path==="/"||!this.cfg.path)&&e.health!=="healthy"&&this.discoverPath(t),l.length===0){this.registry.setLastHealthError(t,"no probe URL available"),this.registry.setHealth(t,"unhealthy");return}let u=null;for(let f of l){let g=await this.tryProbe(f);if(g.ok){let C=on(f);C&&this.registry.setCachedProbeHost(t,C.hostname.replace(/^\[|\]$/g,"")),this.registry.setResolvedUrl(t,f),this.registry.setLastHealthError(t,null),this.registry.setHealth(t,"healthy");return}u||(u=`${g.error} ${f}`)}let d=this.freshness.get(t);if(d&&!d.retried){d.retried=!0,setTimeout(()=>{this.probe(t)},ol);return}this.registry.setLastHealthError(t,u||"unknown probe failure"),this.registry.setHealth(t,"unhealthy")}async discoverPath(t){let e=this.registry.getState(t);if(!(!e||e.status!=="serving")&&!e.discoveredHealthPath)for(let r of al){let s={...this.cfg,path:r},o=ko(s,void 0,e.announcedUrl,e.port,e.cachedProbeHost);for(let i of o)if((await this.tryProbe(i,{strict2xx:!0})).ok){e.discoveredHealthPath=r,this.registry.recordEvent({app:t,type:"health",message:`discovered probe path: ${r} (pin via POST /api/apps/${encodeURIComponent(t)}/health/pin or daimon pin-health ${t} --accept)`});return}}}tryProbe(t,e={}){return new Promise(r=>{let s=!1,o=u=>{s||(s=!0,r(u))},i=t.startsWith("https://"),a=i?sl:rl,c={timeout:this.cfg.timeoutMs};if(i){let d=on(t)?.hostname?.replace(/^\[|\]$/g,"")??"",f=d==="127.0.0.1"||d==="::1"||d==="localhost";c.rejectUnauthorized=f?!1:!!this.cfg.rejectUnauthorized}let l=e.strict2xx?300:500;try{let u=a.get(t,c,d=>{let f=d.statusCode??0;d.resume(),e.strict2xx?f>=200&&f<l?o({ok:!0}):o({ok:!1,error:`http ${f}`}):ao(f)||f>=200&&f<l?o({ok:!0}):o({ok:!1,error:`http ${f}`})});u.on("timeout",()=>u.destroy(new Error("timeout"))),u.on("error",d=>{let f=d?.code||d?.message||"error";co(d?.code)?o({ok:!1,error:`${f} (server not responding)`}):o({ok:!1,error:f})})}catch(u){o({ok:!1,error:u?.message||"throw"})}})}}});import cl from"pidusage";var cn,Po=U(()=>{"use strict";cn=class{constructor(t,e=2e3){this.registry=t;this.intervalMs=e;this.timer=setInterval(()=>this.tick(),e)}registry;intervalMs;timer=null;stopped=!1;stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}async tick(){if(this.stopped)return;let t=[];for(let r of this.registry.names()){let s=this.registry.getState(r);s?.pid&&t.push({name:r,pid:s.pid})}if(!t.length)return;let e=!1;await Promise.all(t.map(async({name:r,pid:s})=>{try{let o=await cl(s),i=this.registry.getState(r);if(!i)return;let a=Math.round(o.cpu*10)/10,c=Math.round(o.memory/(1024*1024));(i.cpu!==a||i.memMB!==c)&&(i.cpu=a,i.memMB=c,e=!0)}catch{let o=this.registry.getState(r);o&&(o.cpu!=null||o.memMB!=null)&&(o.cpu=null,o.memMB=null,e=!0)}})),e&&this.registry.emit("change")}}});var ln,Co=U(()=>{"use strict";ln=class{constructor(t,e){this.registry=t;this.cfg=e}registry;cfg;timers=new Map;stopped=!1;stop(){this.stopped=!0;for(let t of this.timers.values())clearTimeout(t);this.timers.clear()}onExit(t,e,r,s){if(this.stopped||s||!this.cfg.enabled||e===0&&!r)return;let o=this.registry.getState(t);if(!o)return;let i=Date.now();if((o.restartWindowStart==null||i-o.restartWindowStart>this.cfg.windowMs)&&(o.restartWindowStart=i,o.restartAttempts=0),o.restartAttempts+=1,o.restartAttempts>this.cfg.maxAttempts){o.lastStatusMessage=`auto-restart aborted (${o.restartAttempts-1}/${this.cfg.maxAttempts} within window)`,o.nextRestartAt=null,this.registry.recordEvent({app:t,type:"restart-scheduled",message:o.lastStatusMessage}),this.registry.emit("change");return}let a=Math.min(2**(o.restartAttempts-1)*1e3,3e4);o.nextRestartAt=i+a,o.lastStatusMessage=`restarting in ${Math.round(a/1e3)}s (attempt ${o.restartAttempts}/${this.cfg.maxAttempts})`,this.registry.recordEvent({app:t,type:"restart-scheduled",message:o.lastStatusMessage}),this.registry.emit("change");let c=setTimeout(()=>{this.timers.delete(t);let l=this.registry.getState(t);l&&(l.nextRestartAt=null),this.registry.start(t)},a);this.timers.set(t,c)}onUserStop(t){let e=this.timers.get(t);e&&(clearTimeout(e),this.timers.delete(t));let r=this.registry.getState(t);r&&(r.restartAttempts=0,r.restartWindowStart=null,r.nextRestartAt=null)}}});import ir from"node:fs";import Ro from"node:path";import ll from"node:os";function Eo(){try{let n=ir.readFileSync(ar,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.ports&&typeof t.ports=="object")return{ports:t.ports}}catch{}return{ports:{}}}function Ao(n){or=n,!sr&&(sr=setTimeout(()=>{sr=null;let t=or;if(or=null,!!t)try{ir.mkdirSync(Ro.dirname(ar),{recursive:!0}),ir.writeFileSync(ar,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: state write failed: ${e.message}
80
+ `)}},500))}var ar,sr,or,Oo=U(()=>{"use strict";ar=Ro.join(ll.homedir(),".daimon","state.json");sr=null,or=null});import No from"node:fs";import ul from"node:os";import $o from"node:path";import{createRequire as pl}from"node:module";var dl,fl,un,Mo=U(()=>{"use strict";dl=pl(import.meta.url),fl=6e4,un=class{constructor(t,e){this.registry=t;this.cfg=e;this.logFile=$o.join(ul.homedir(),".daimon","notifications.log");try{No.mkdirSync($o.dirname(this.logFile),{recursive:!0})}catch{}if(!e.enabled){this.audit("init","disabled by config");return}try{let r=dl("node-notifier");if(this.notifier=r,process.platform==="win32")try{let s=r.WindowsToaster;s&&(this.toaster=new s({withFallback:!0}))}catch(s){this.audit("init",`WindowsToaster unavailable: ${s?.message||s}`)}this.audit("init",`node-notifier loaded${this.toaster?" (+WindowsToaster fallback)":""}`)}catch(r){this.warnOnce(`node-notifier unavailable: ${r?.message||r}`),this.audit("init",`node-notifier load failed: ${r?.message||r}`);return}t.on("event",this.onEvent)}registry;cfg;notifier=null;toaster=null;lastSent=new Map;warned=!1;logFile;audit(t,e){let r=`${new Date().toISOString()} ${t} ${e}
81
+ `;try{No.appendFileSync(this.logFile,r)}catch{}}warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] notifier: ${t}
82
+ `))}stop(){this.registry.off("event",this.onEvent)}onEvent=t=>{this.notifier&&(t.type==="status"&&t.to==="error"&&this.cfg.onError?this.fire(t.app,"error",`${t.app} \u2192 error`,t.message||"app entered error state"):t.type==="health"&&t.to==="unhealthy"&&this.cfg.onUnhealthy?this.fire(t.app,"unhealthy",`${t.app} unhealthy`,"health probe failing"):t.type==="stale"?this.fire(t.app,"stale",`${t.app} stale`,t.message||"no output despite source changes"):t.type==="compile-regression"?this.fire(t.app,"compile-regression",`${t.app} slow compile`,t.message||"compile time regression"):t.type==="bundle-regression"?this.fire(t.app,"bundle-regression",`${t.app} bundle grew`,t.message||"bundle size regression"):t.type==="task-run"&&/exit=[1-9]/.test(t.message||"")&&this.fire(t.app,"task-fail",`${t.app} task failed`,t.message||""))};fire(t,e,r,s){if(!this.notifier)return;let o=`${t}::${e}`,i=this.lastSent.get(o)??0,a=Date.now();if(a-i<fl){this.audit("throttled",`${o}`);return}this.lastSent.set(o,a);let c={title:`daimon: ${r}`,message:s,wait:!1,appID:"daimon"},l=(u,d)=>{u?(this.audit("fail",`${o} :: ${u?.message||u}`),this.warnOnce(`notify failed: ${u?.message||u}`)):this.audit("ok",`${o} :: ${r} :: ${d??"(no response)"}`)};try{this.audit("attempt",`${o} :: ${r}`),(this.toaster??this.notifier).notify(c,l)}catch(u){this.audit("throw",`${o} :: ${u?.message||u}`),this.warnOnce(`notify threw: ${u?.message||u}`)}}}});import jo from"node:fs";import cr from"node:path";var ml,hl,gl,yl,pn,_o=U(()=>{"use strict";ml=5e3,hl=3e4,gl=new Set(["node_modules","dist",".angular",".nx",".git","tmp","out-tsc","coverage"]),yl=new Set([".ts",".tsx",".html",".scss",".css",".js",".jsx",".json"]),pn=class{constructor(t,e){this.registry=t;this.cfg=e;e.enabled&&(this.timer=setInterval(()=>this.tick(),ml),t.on("compile",this.onCompile))}registry;cfg;timer=null;caches=new Map;stop(){this.timer&&clearInterval(this.timer),this.registry.off("compile",this.onCompile)}onCompile=t=>{let e=this.registry.getApp(t.name);e&&this.caches.delete(e.workspaceRoot)};tick(){for(let t of this.registry.names())this.evaluate(t)}evaluate(t){let e=this.registry.getState(t),r=this.registry.getApp(t);if(!e||!r)return;if(e.status!=="serving"){e.stale&&this.registry.setStale(t,!1);return}if(e.startedAt==null)return;let s=e.lastLogTs??e.startedAt,o=Date.now()-s;if(o<this.cfg.silentMs){e.stale&&this.registry.setStale(t,!1);return}let i=e.lastCompileAt??e.startedAt;this.hasSourceChange(r.workspaceRoot,i,e.lastCompileAt)&&(e.stale||(this.registry.setStale(t,!0),this.registry.recordEvent({app:t,type:"stale",message:`no output in ${Math.round(o/1e3)}s despite source changes`})))}hasSourceChange(t,e,r){let s=this.caches.get(t);if(!s||Date.now()-s.ts>hl||r!=null&&s.ts<r){let a=this.scan(t);this.caches.set(t,{ts:Date.now(),files:a})}return this.caches.get(t).files.some(a=>a.mtime>e)}scan(t){let e=[],r=(s,o)=>{if(o>8||e.length>4e3)return;let i;try{i=jo.readdirSync(s,{withFileTypes:!0})}catch{return}for(let a of i)if(!a.name.startsWith(".git")){if(a.isDirectory()){if(gl.has(a.name))continue;r(cr.join(s,a.name),o+1)}else if(a.isFile()){let c=cr.extname(a.name);if(!yl.has(c))continue;try{let l=cr.join(s,a.name),u=jo.statSync(l);e.push({path:l,mtime:u.mtimeMs})}catch{}}}};return r(t,0),e}}});import Do from"node:http";var dn,fn,Lo=U(()=>{"use strict";dn=200,fn=class{constructor(t,e){this.registry=t;this.cfg=e;e.enabled&&(t.on("change",this.onChange),this.tick())}registry;cfg;proxies=new Map;stopped=!1;stop(){this.stopped=!0,this.registry.off("change",this.onChange);for(let t of this.proxies.values())try{t.server.close()}catch{}this.proxies.clear()}onChange=()=>{this.stopped||this.tick()};tick(){for(let t of this.registry.names()){let e=this.registry.getState(t);if(!e)continue;let r=this.proxies.has(t);e.status==="serving"&&e.port&&!r?this.startProxy(t,e.port):e.status!=="serving"&&r&&this.stopProxy(t)}}stopProxy(t){let e=this.proxies.get(t);if(e){try{e.server.close()}catch{}this.proxies.delete(t)}}startProxy(t,e){let r=e+this.cfg.portOffset,s=[],o=Do.createServer((i,a)=>{let c=Date.now(),l={hostname:"127.0.0.1",port:e,method:i.method,path:i.url,headers:{...i.headers,host:`127.0.0.1:${e}`}},u=Do.request(l,d=>{a.writeHead(d.statusCode||502,d.headers),d.pipe(a);let f=()=>{s.push({ts:Date.now(),method:i.method||"GET",path:i.url||"/",status:d.statusCode||0,durationMs:Date.now()-c}),s.length>dn&&s.splice(0,s.length-dn)};d.on("end",f),d.on("error",f)});u.on("error",()=>{a.writeHead(502).end("upstream error"),s.push({ts:Date.now(),method:i.method||"GET",path:i.url||"/",status:502,durationMs:Date.now()-c}),s.length>dn&&s.splice(0,s.length-dn)}),i.pipe(u)});o.on("error",i=>{i?.code==="EADDRINUSE"&&process.stderr.write(`[daimon] requestLog: port ${r} in use for ${t}; disabling proxy
83
+ `),this.proxies.delete(t)}),o.listen(r,"127.0.0.1",()=>{this.proxies.set(t,{app:t,proxyPort:r,server:o,buffer:s})})}requests(t,e){let r=this.proxies.get(t);if(!r)return[];if(e){let s=Date.now()-e;return r.buffer.filter(o=>o.ts>=s)}return[...r.buffer]}proxyPortFor(t){return this.proxies.get(t)?.proxyPort??null}}});import lr from"node:fs";function Io(n){let t=lr.readFileSync(n,"utf8");t.charCodeAt(0)===65279&&(t=t.slice(1));let e=JSON.parse(t);if(!e||typeof e!="object"||Array.isArray(e))throw new Error("config must be a JSON object");return e}function Fo(n,t){if(t===null)return null;if(typeof t!="object"||Array.isArray(t))return t;let e=n&&typeof n=="object"&&!Array.isArray(n)?{...n}:{};for(let[r,s]of Object.entries(t))s===null?delete e[r]:e[r]=Fo(e[r],s);return e}function bl(n,t){let e=n+"."+process.pid+".tmp";lr.writeFileSync(e,t,"utf8"),lr.renameSync(e,n)}function vl(n,t){let e=new Set;for(let r of Object.keys(t))JSON.stringify(n?.[r])!==JSON.stringify(t[r])&&e.add(r);for(let r of Object.keys(n||{}))r in t||e.add(r);return[...e]}function Bo(n){let t=Io(n.configPath),e=Fo(t,n.patch);if(!e||typeof e!="object")throw new Error("patch produced non-object config");let r=je(e,n.configPath);return bl(n.configPath,JSON.stringify(e,null,2)+`
84
+ `),{config:r,raw:e,applied:vl(t,e),prevRaw:t}}function ur(n){let t=Io(n.configPath),e=je(t,n.configPath);return Sl(n.registry,e)}function Sl(n,t){let e=n.getConfig();for(let l of Object.keys(e))e[l]=void 0;Object.assign(e,t);let r=new Set(n.names()),s=Ot(e),o=new Set(s.map(l=>l.name)),i=[],a=[];for(let l of s)r.has(l.name)?n.updateDiscoveredApp(l):(n.addDiscoveredApp(l),i.push(l.name));for(let l of r)o.has(l)||a.push(l);let c=[];for(let l of n.names()){let u=n.getState(l);if(u&&(u.status==="serving"||u.status==="compiling")){let d=e.overrides?.[l];if(!d)continue;for(let f of wl)if(f in d){c.push(l);break}}}return{addedApps:i,removedApps:a,restartRequired:c,config:e}}var wl,Uo=U(()=>{"use strict";ee();qt();wl=new Set(["command","port","env","url"])});import Ho from"node:fs";import kl from"node:os";import Jo from"node:path";function Tl(n){if(!n)return null;let t=JSON.parse(JSON.stringify(n));if(t.apiToken&&(t.apiToken="***"),t.overrides)for(let e of Object.keys(t.overrides)){let r=t.overrides[e]?.env;if(r)for(let s of Object.keys(r))xl.test(s)&&(r[s]="***")}return t}function Pl(n,t=200){if(!n)return[];let e=[];for(let r of n.names()){let s=n.getState(r);if(s)for(let o of s.logBuffer)e.push({ts:o.ts,line:`[${r}] ${o.line}`})}return e.sort((r,s)=>r.ts-s.ts),e.slice(-t).map(r=>r.line)}function Cl(){let n=Jo.join(mt(),"crashes");return Ho.mkdirSync(n,{recursive:!0}),n}function Rl(n,t,e){let r=new Date().toISOString().replace(/[:.]/g,"-"),s=Jo.join(Cl(),`${r}.txt`),o=n,i=[`daimon crash dump @ ${new Date().toISOString()}`,`version: ${st}`,`node: ${process.version}`,`platform: ${process.platform} ${kl.release()}`,`cwd: ${process.cwd()}`,`pid: ${process.pid}`,"","ERROR:",o?.stack||String(o),"","CONFIG (redacted):",JSON.stringify(Tl(e),null,2),"","RECENT LOG (last 200 lines across apps):",...Pl(t,200)];try{Ho.writeFileSync(s,i.join(`
85
+ `))}catch{}return s}function Wo(n){let t=e=>{let r=null;try{r=Rl(e,n.getRegistry(),n.getConfig())}catch{}try{process.stderr.write(`[daimon] fatal: ${e?.stack||e}
85
86
  `)}catch{}if(r)try{process.stderr.write(`[daimon] crash dump: ${r}
86
- `)}catch{}process.exit(1)};process.on("uncaughtException",t),process.on("unhandledRejection",t)}var ol,Ao=F(()=>{"use strict";Et();bt();ol=/key|secret|token|password|pass/i});function Ze(n,t){if(n.length===0)return 0;let e=[...n].sort((s,o)=>s-o),r=Math.min(e.length-1,Math.floor((e.length-1)*t));return Math.round(e[r]*100)/100}var zn,ul,pl,Qe,Oo=F(()=>{"use strict";Et();zn=1e3,ul=60,pl=256;Qe=class{constructor(t){this.history=t;this.start()}history;startMs=Date.now();lagTimer=null;lagSamples=[];querySamples=[];lockContentionCount=0;lastTickAt=Date.now();highLagStreak=0;warnedAtStreak=0;onSelfWarn=null;start(){let t=performance.now();this.lagTimer=setInterval(()=>{let e=performance.now(),r=Math.max(0,e-t-zn);t=e,this.lagSamples.push(r),this.lagSamples.length>ul&&this.lagSamples.shift(),this.lastTickAt=Date.now(),r>100?(this.highLagStreak++,this.highLagStreak>=5&&this.highLagStreak>this.warnedAtStreak&&this.onSelfWarn&&(this.warnedAtStreak=this.highLagStreak,this.onSelfWarn(`event loop lag sustained: ${Math.round(r)}ms (${this.highLagStreak} consecutive ticks)`))):(this.highLagStreak=0,this.warnedAtStreak=0)},zn),this.lagTimer.unref&&this.lagTimer.unref()}setSelfWarnHandler(t){this.onSelfWarn=t}recordQueryMs(t){this.querySamples.push(t),this.querySamples.length>pl&&this.querySamples.shift()}incLockContention(){this.lockContentionCount++}snapshot(){let t=process.memoryUsage(),e=1024*1024;return{pid:process.pid,version:Z,uptimeMs:Date.now()-this.startMs,rssMB:Math.round(t.rss/e*10)/10,heapUsedMB:Math.round(t.heapUsed/e*10)/10,heapTotalMB:Math.round(t.heapTotal/e*10)/10,eventLoopLagMs:this.lagSamples.length?Math.round(this.lagSamples[this.lagSamples.length-1]*100)/100:0,eventLoopLagP95Ms:Ze(this.lagSamples,.95),historyDbQueryMs:{p50:Ze(this.querySamples,.5),p95:Ze(this.querySamples,.95),p99:Ze(this.querySamples,.99)},lockContentionCount:this.lockContentionCount,tickIntervalMs:zn,lastTickAt:this.lastTickAt}}stop(){this.lagTimer&&clearInterval(this.lagTimer),this.lagTimer=null}}});var _o={};yt(_o,{buildContext:()=>Qn,loadPlugins:()=>Vn,pluginsDir:()=>Yn,runPluginScans:()=>Zn,validatePluginFile:()=>hl});import dl from"node:fs";import No from"node:path";import fl from"node:os";import{pathToFileURL as Mo}from"node:url";function Yn(n){return n&&typeof n=="string"&&n.trim()?n:No.join(fl.homedir(),".daimon","plugins")}function ml(n){return n.startsWith("doctor-")&&n.endsWith(".mjs")}function $o(n){if(!n||typeof n!="object")return{ok:!1,error:"module has no default export"};let t=n.default??n;return t?typeof t.name!="string"||!t.name.length?{ok:!1,error:"plugin.name must be a non-empty string"}:/^[a-z][a-z0-9-]*$/.test(t.name)?typeof t.scan!="function"?{ok:!1,error:"plugin.scan must be a function"}:t.fix!==void 0&&typeof t.fix!="function"?{ok:!1,error:"plugin.fix, if present, must be a function"}:t.undo!==void 0&&typeof t.undo!="function"?{ok:!1,error:"plugin.undo, if present, must be a function"}:{ok:!0,plugin:t}:{ok:!1,error:`plugin.name must be kebab-case (got "${t.name}")`}:{ok:!1,error:"plugin shape is null"}}async function Vn(n){let t=[],e;try{e=dl.readdirSync(n).filter(ml).sort()}catch{return t}let r=new Set;for(let s of e){let o=No.join(n,s);try{let i=await import(Mo(o).href+`?t=${Date.now()}`),a=$o(i);if(!a.ok){t.push({name:s,file:o,status:"failed",error:a.error});continue}let l=a.plugin;if(jo.has(l.name)){t.push({name:l.name,file:o,status:"failed",error:`name collides with built-in rule "${l.name}"`});continue}if(r.has(l.name)){t.push({name:l.name,file:o,status:"failed",error:"duplicate plug-in name"});continue}r.add(l.name),t.push({name:l.name,description:l.description,file:o,status:"ok",module:l})}catch(i){t.push({name:s,file:o,status:"failed",error:i?.message??String(i)})}}return t}async function hl(n){try{let t=await import(Mo(n).href+`?t=${Date.now()}`),e=$o(t);return e.ok?jo.has(e.plugin.name)?{ok:!1,error:`name collides with built-in rule "${e.plugin.name}"`}:{ok:!0,name:e.plugin.name,description:e.plugin.description}:{ok:!1,error:e.error}}catch(t){return{ok:!1,error:t?.message??String(t)}}}async function Zn(n,t){for(let e of n)if(!(e.status!=="ok"||!e.module))try{e.lastFindings=await e.module.scan(t),Array.isArray(e.lastFindings)||(e.lastFindings=[])}catch(r){e.status="failed",e.error=`scan failed: ${r?.message??String(r)}`,e.lastFindings=[]}return n}function Qn(n){return{config:n.config,apps:n.apps,history:n.history&&typeof n.history.querySelfMetrics=="function"?{querySelfMetrics:n.history.querySelfMetrics.bind(n.history)}:null,mutations:{setOverride:()=>{throw new Error("mutations.setOverride is not implemented in v0.8 \u2014 fix functions are advisory until M44 wires the M36 patch surface")}}}}var jo,tr=F(()=>{"use strict";jo=new Set(["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root"])});import et,{useEffect as gl,useMemo as yl,useState as ae}from"react";import{Box as we,Text as ft,useInput as wl,useStdout as bl}from"ink";import vl from"ink-text-input";function er({registry:n,appName:t,onExit:e}){let{stdout:r}=bl(),[s,o]=ae(0),[i,a]=ae(!1),[l,c]=ae(""),[d,u]=ae(""),[g,y]=ae(0),[p,m]=ae(0);gl(()=>{let P=()=>o(S=>S+1);n.on("change",P);let O=setInterval(()=>o(S=>S+1),500);return()=>{n.off("change",P),clearInterval(O)}},[n]);let f=n.getState(t)?.logBuffer.map(P=>P.line)??[],w=(r.rows||30)-4,T=yl(()=>{if(!d)return[];let P=d.toLowerCase();return f.reduce((O,S,k)=>(S.toLowerCase().includes(P)&&O.push(k),O),[])},[f,d,s]);wl((P,O)=>{if(i){if(O.escape){a(!1),c("");return}return}if(P==="q"||O.escape){e();return}if(P==="/"){a(!0);return}if(P==="g"){y(Math.max(0,f.length-w));return}if(P==="G"){y(0);return}if(O.pageUp){y(S=>Math.min(Math.max(0,f.length-w),S+w));return}if(O.pageDown){y(S=>Math.max(0,S-w));return}if(O.upArrow){y(S=>Math.min(Math.max(0,f.length-w),S+1));return}if(O.downArrow){y(S=>Math.max(0,S-1));return}if((P==="n"||P==="N")&&T.length){let S=P==="n"?(p+1)%T.length:(p-1+T.length)%T.length;m(S);let k=T[S],I=f.length-g,D=I-w;(k<D||k>=I)&&y(Math.max(0,f.length-k-Math.floor(w/2)));return}});let E=P=>{u(P),a(!1),c(""),m(0)},b=f.length-g,_=Math.max(0,b-w),A=f.slice(_,b),x=(P,O)=>{if(!d)return et.createElement(ft,{key:O},et.createElement(ft,{dimColor:!0},String(O+1).padStart(5)," "),P);let S=d,k=P.toLowerCase(),I=S.toLowerCase(),D=[],z=0,J=0;for(;z<P.length;){let St=k.indexOf(I,z);if(St<0){D.push(et.createElement(ft,{key:J++},P.slice(z)));break}St>z&&D.push(et.createElement(ft,{key:J++},P.slice(z,St))),D.push(et.createElement(ft,{key:J++,backgroundColor:"yellow",color:"black"},P.slice(St,St+S.length))),z=St+S.length}let Mt=T[p]===O;return et.createElement(ft,{key:O},et.createElement(ft,{color:Mt?"cyan":void 0,dimColor:!Mt},String(O+1).padStart(5)," "),D)};return et.createElement(we,{flexDirection:"column"},et.createElement(we,null,et.createElement(ft,{bold:!0},"full log: ",et.createElement(ft,{color:"cyan"},t)),et.createElement(ft,{dimColor:!0}," (",f.length," lines",d?`, ${T.length} matches for "${d}"`:"",", scroll=",g,")")),et.createElement(we,{flexDirection:"column"},A.length===0?et.createElement(ft,{dimColor:!0},"(no log yet)"):A.map((P,O)=>x(P,_+O))),et.createElement(we,null,i?et.createElement(we,null,et.createElement(ft,null,"/"),et.createElement(vl,{value:l,onChange:c,onSubmit:E})):et.createElement(ft,{dimColor:!0},"[/] search [n/N] next/prev [g/G] bottom/top [PgUp/PgDn] [\u2191\u2193] [q/Esc] back")))}var Do=F(()=>{"use strict"});function Io(n,t,e=Date.now()){let r=e-36e5,s=36e5/20,o=new Array(20).fill("");for(let i of n){if(i.type!=="status"||i.app!==t||!i.to||i.ts<r||i.ts>e)continue;let a=Math.min(19,Math.floor((i.ts-r)/s)),l=o[a];(!l||(Lo[i.to]??0)>(Lo[l]??0))&&(o[a]=i.to)}return o}function Fo(n){return n.map(t=>Sl[t]??"\xB7").join("")}var Lo,Sl,Bo=F(()=>{"use strict";Lo={stopped:1,serving:2,compiling:3,starting:3,error:4},Sl={"":"\xB7",stopped:"\u2591",serving:"\u2593",compiling:"\u2592",starting:"\u2592",error:"\u2588"}});import R,{useEffect as kl,useState as nt}from"react";import nr from"node:fs";import xl from"node:os";import Tl from"node:path";import{Box as at,Text as L,useApp as Cl,useInput as El,useStdout as Pl}from"ink";import rr from"ink-text-input";import{spawn as sr,spawnSync as Rl}from"node:child_process";function Al(n){try{process.platform==="win32"?sr("cmd",["/c","start","",n],{detached:!0,stdio:"ignore",windowsHide:!0}).unref():process.platform==="darwin"?sr("open",[n],{detached:!0,stdio:"ignore"}).unref():sr("xdg-open",[n],{detached:!0,stdio:"ignore"}).unref()}catch{}}function Ol(n){if(n==null)return"";let t=Math.floor(n/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60);return e<60?`${e}m ${t%60}s`:`${Math.floor(e/60)}h ${e%60}m`}function or({registry:n,apiPort:t,onQuit:e}){let{exit:r}=Cl(),{stdout:s}=Pl(),[o,i]=nt(n.list()),[a,l]=nt(0),[c,d]=nt(!1),[u,g]=nt(0),[y,p]=nt(!1),[m,h]=nt([]),[f,w]=nt(!1),[T,E]=nt(""),[b,_]=nt(null),[,A]=nt(0),[x,P]=nt(null),[O,S]=nt(""),[k,I]=nt(!1),[D,z]=nt(null),[J,Mt]=nt(""),[St,on]=nt(!1),[pr,dr]=nt(null),[di,fr]=nt(n.events({sinceMs:3600*1e3}));kl(()=>{let C=()=>i(n.list()),j=()=>fr(n.events({sinceMs:36e5}));n.on("change",C),n.on("event",j);let U=setInterval(()=>{i(n.list()),fr(n.events({sinceMs:3600*1e3})),A($=>$+1)},1e3);return()=>{n.off("change",C),n.off("event",j),clearInterval(U)}},[n]),El((C,j)=>{if(y)return;if(b){if(j.escape){_(null);return}if(j.tab){let $=b.field==="command"?"port":b.field==="port"?"env":"command";_({...b,field:$});return}return}if(f){if(j.escape){w(!1),E("");return}if(j.return){let $=T.trim();h($?$.split(/[\s,]+/).filter(Boolean):[]),w(!1),E("");return}if(j.backspace||j.delete){E($=>$.slice(0,-1));return}C&&!j.ctrl&&E($=>$+C);return}if(k){if(j.escape){I(!1);return}if(j.return){I(!1);return}if(j.backspace||j.delete){S($=>$.slice(0,-1));return}C&&!j.ctrl&&S($=>$+C);return}if(St){if(j.escape){on(!1),Mt("");return}if(j.return){let $=J.trim();on(!1),Mt(""),$&&hi($);return}if(j.backspace||j.delete){Mt($=>$.slice(0,-1));return}C&&!j.ctrl&&Mt($=>$+C);return}if(D){if(C==="y"||C==="Y"){let $=D;z(null),n.restart($),rt(`restarted ${$}`)}else(C==="n"||C==="N"||j.escape)&&z(null);return}if(C==="q"||j.ctrl&&C==="c"){e(),r();return}if(o.length===0)return;if(x==="g"){P(null);let $=C.toLowerCase();$==="a"?rt("view: apps (only TUI view)"):$==="e"?rt("view: errors \u2014 selected app errors shown in detail pane"):$==="v"?rt("view: events \u2014 recent registry events shown in log pane"):$==="s"?rt("view: settings \u2014 edit `daimon.config.json`"):$==="n"&&rt("view: sessions \u2014 `daimon record` to toggle recording");return}if(j.upArrow||C==="k"){l($=>Math.max(0,$-1)),g(0);return}if(j.downArrow||C==="j"){l($=>Math.min(o.length-1,$+1)),g(0);return}let U=o[a];if(U){if(C==="g"){P("g"),setTimeout(()=>P($=>$==="g"?null:$),1200);return}if(C==="/"){I(!0);return}if(C==="s")n.start(U.name);else if(C==="S")n.stop(U.name);else if(C==="r")z(U.name);else if(C==="f")mi(U.name);else if(C==="x")fi(U.name);else if(C==="O")on(!0);else if(C==="L")p(!0);else if(C==="t")w(!0),E(m.join(" "));else if(C==="e"){let $=n.getConfig(),Y=n.getApp(U.name),dt=n.getState(U.name)?.sessionOverrides??null,jt=dt?.env??$.overrides?.[U.name]?.env??{},_t=Object.entries(jt).map(([cn,ln])=>`${cn}=${ln}`).join(`
87
- `);_({name:U.name,field:"command",cmd:dt?.command??Y?.command??"",port:String(dt?.port??$.overrides?.[U.name]?.port??U.port??""),env:_t})}else if(C==="E"){let Y=n.getConfig().envFiles?.[U.name]??[];if(!Y.length)return;let dt=n.getState(U.name)?.activeEnvFile??null,jt=dt?Y.indexOf(dt):-1,_t=Y[(jt+1)%Y.length];n.setActiveEnvFile(U.name,_t)}else if(C==="V"){let $=process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),Y=Tl.join(xl.tmpdir(),`daimon-${U.name}-${Date.now()}.json`),dt=n.getConfig(),jt=n.getApp(U.name),_t=n.getState(U.name)?.sessionOverrides??null,cn={command:_t?.command??jt?.command,port:_t?.port??dt.overrides?.[U.name]?.port??null,env:_t?.env??dt.overrides?.[U.name]?.env??{}};try{nr.writeFileSync(Y,JSON.stringify(cn,null,2)),Rl($,[Y],{stdio:"inherit",shell:!0});let ln=nr.readFileSync(Y,"utf8"),Dt=JSON.parse(ln);n.setSessionOverride(U.name,{command:typeof Dt.command=="string"?Dt.command:void 0,port:typeof Dt.port=="number"?Dt.port:void 0,env:Dt.env&&typeof Dt.env=="object"?Dt.env:void 0}),nr.unlinkSync(Y)}catch{}}else C==="l"?d($=>!$):C==="o"?U.url&&Al(U.url):j.pageUp?g($=>$+5):j.pageDown&&g($=>Math.max(0,$-5))}});let rt=C=>{dr(C),setTimeout(()=>dr(j=>j===C?null:j),4e3)},fi=async C=>{rt(`try-fix ${C}\u2026`);try{let{runAutoFix:j,ALL_AUTO_FIX:U}=await Promise.resolve().then(()=>(se(),re)),Y=n.getConfig().doctor?.autoFix?.permitted??U,dt=await j({permitted:Y,dryRun:!1});await n.restart(C);let jt=await n.waitFor(C,"healthy",6e4);rt(`try-fix ${C}: ${jt.timedOut?"timeout":"reached"} \xB7 fixed ${dt.ran.length}`)}catch(j){rt(`try-fix ${C} failed: ${j?.message??j}`)}},mi=async C=>{rt(`focus ${C} until stable\u2026`);try{let j=Date.now(),U=Date.now(),$=Y=>{Y.app===C&&(U=Date.now())};n.on("event",$);try{for(;Date.now()-j<18e4;){let Y=n.summary(C);if(Y&&Y.status==="serving"&&Y.health==="healthy"&&Date.now()-U>=5e3){rt(`focus ${C}: stable after ${Math.round((Date.now()-j)/1e3)}s`);return}await new Promise(dt=>setTimeout(dt,500))}}finally{n.off("event",$)}rt(`focus ${C}: timed out`)}catch(j){rt(`focus ${C} failed: ${j?.message??j}`)}},hi=async C=>{rt(`orchestrate ${C}\u2026`);try{let{orchestrateProfile:j}=await Promise.resolve().then(()=>(In(),Ln)),U=await j(n,n.getConfig(),{profile:C,goal:"healthy",timeoutMs:3e5});if(U.error){rt(`orchestrate ${C}: ${U.error}`);return}let $=U.allReached;rt(`orchestrate ${C}: ${$?"all reached":"some failing"} \xB7 ${Math.round(U.totalMs/1e3)}s`)}catch(j){rt(`orchestrate ${C} failed: ${j?.message??j}`)}},mr=O.trim().toLowerCase(),be=(m.length===0?o:o.filter(C=>m.every(j=>C.tags.includes(j)))).filter(C=>!mr||C.name.toLowerCase().includes(mr)),H=be[Math.min(a,Math.max(0,be.length-1))],$t=H?n.getState(H.name):null,hr=$t?$t.logBuffer.slice(Math.max(0,$t.logBuffer.length-12-u),$t.logBuffer.length-u).map(C=>C.line):[],an=s.columns||100,gi=Math.min(36,Math.floor(an*.4));return y&&H?R.createElement(er,{registry:n,appName:H.name,onExit:()=>p(!1)}):R.createElement(at,{flexDirection:"column",width:an},R.createElement(at,{borderStyle:"round",borderColor:"cyan",paddingX:1},R.createElement(L,{bold:!0,color:"cyan"},"daimon"),R.createElement(L,{dimColor:!0}," \u2022 api http://127.0.0.1:",t)),R.createElement(at,{flexDirection:"row"},R.createElement(at,{flexDirection:"column",width:gi,borderStyle:"single",borderColor:"gray",paddingX:1},R.createElement(L,{bold:!0},"Apps ",m.length?R.createElement(L,{dimColor:!0},"(tags: ",m.join(", "),")"):null),be.length===0?R.createElement(L,{dimColor:!0},o.length===0?"(no apps discovered)":"(no apps match filter)"):be.map((C,j)=>{let U=j===a,$=Io(di,C.name),Y=Fo($);return R.createElement(at,{key:C.name,flexDirection:"column"},R.createElement(at,null,R.createElement(L,{color:U?"cyan":void 0},U?"\u25B8 ":" "),R.createElement(L,{color:U?"cyan":void 0},((n.getState(C.name)?.sessionOverrides?"*":"")+C.name).padEnd(20).slice(0,20)),R.createElement(L,{color:Uo[C.status]}," ",C.status.padEnd(9)),R.createElement(L,{color:Ho[C.health]},C.status==="serving"?"\u25CF":" "),R.createElement(L,{dimColor:!0},C.port?` :${C.port}`:""),an>=100&&C.cpu!=null?R.createElement(L,{dimColor:!0}," ",String(C.cpu).padStart(5),"% ",String(C.memMB??0).padStart(5),"MB"):null),R.createElement(at,null,R.createElement(L,{dimColor:!0}," "),R.createElement(L,{dimColor:!0},Y)))})),R.createElement(at,{flexDirection:"column",flexGrow:1,borderStyle:"single",borderColor:"gray",paddingX:1},H&&$t?R.createElement(R.Fragment,null,R.createElement(L,null,"Selected: ",R.createElement(L,{bold:!0},H.name)),R.createElement(L,null,"Status: ",R.createElement(L,{color:Uo[H.status]},H.status)," ",R.createElement(L,{color:Ho[H.health]},"\u25CF")," ",R.createElement(L,{dimColor:!0},H.health)),R.createElement(L,null,"Port: ",H.port??"-"),R.createElement(L,null,"URL: ",H.url??"-"),H.announcedUrl&&H.announcedUrl!==H.url?R.createElement(L,{dimColor:!0},"Announced: ",H.announcedUrl):null,H.lastHealthError?R.createElement(L,{color:"red"},"HealthErr: ",H.lastHealthError):null,H.stale?R.createElement(L,{color:"yellow"},"\u26A0 stale (best guess)"):null,R.createElement(L,null,"Errors: ",R.createElement(L,{color:H.errorCount?"red":void 0},H.errorCount)),R.createElement(L,null,"Uptime: ",Ol(H.uptimeMs)),H.cpu!=null||H.memMB!=null?R.createElement(L,null,"Usage: ",H.cpu??"-","% ",H.memMB??"-"," MB"):null,H.compileHistoryMs.length>0?R.createElement(L,null,"Recent compile: ",H.compileHistoryMs.slice(-5).map(C=>(C/1e3).toFixed(1)+"s").join(" \xB7 ")):null,H.bundle?R.createElement(L,null,"Bundle: ",H.bundle.initialKB,"KB initial \xB7 ",H.bundle.lazyKB,"KB lazy",H.bundleRegressionPct!=null&&H.bundleRegressionPct>10?R.createElement(L,{color:"red"}," (+",H.bundleRegressionPct,"% \u26A0)"):null):null,$t.lastStatusMessage?R.createElement(L,{dimColor:!0},"Note: ",$t.lastStatusMessage):null,R.createElement(L,null,"\u2500\u2500\u2500\u2500 recent log ",c?"(focused)":""," \u2500\u2500\u2500\u2500"),hr.length===0?R.createElement(L,{dimColor:!0},"(no output yet)"):hr.map((C,j)=>R.createElement(L,{key:j,wrap:"truncate-end"},C))):R.createElement(L,{dimColor:!0},"No app selected."))),R.createElement(at,{flexDirection:"column"},f?R.createElement(L,null,"tag filter (space-separated, Enter to apply, Esc to cancel): ",R.createElement(L,{color:"cyan"},T)):null,b?R.createElement(at,{flexDirection:"column",borderStyle:"round",borderColor:"yellow",paddingX:1},R.createElement(L,{bold:!0,color:"yellow"},"edit ",b.name," (session-only) Tab=next field Enter=save Esc=cancel"),R.createElement(at,null,R.createElement(L,null,b.field==="command"?"> ":" ","command: "),b.field==="command"?R.createElement(rr,{value:b.cmd,onChange:C=>_({...b,cmd:C}),onSubmit:()=>_({...b,field:"port"})}):R.createElement(L,{dimColor:!0},b.cmd)),R.createElement(at,null,R.createElement(L,null,b.field==="port"?"> ":" ","port: "),b.field==="port"?R.createElement(rr,{value:b.port,onChange:C=>_({...b,port:C}),onSubmit:()=>_({...b,field:"env"})}):R.createElement(L,{dimColor:!0},b.port)),R.createElement(at,null,R.createElement(L,null,b.field==="env"?"> ":" ","env (k=v;): "),b.field==="env"?R.createElement(rr,{value:b.env.replace(/\n/g,";"),onChange:C=>_({...b,env:C.replace(/;/g,`
88
- `)}),onSubmit:()=>{let C=Number(b.port),j={};for(let U of b.env.split(/\n/)){let $=U.match(/^\s*([^=]+)=(.*)$/);$&&(j[$[1].trim()]=$[2])}n.setSessionOverride(b.name,{command:b.cmd||void 0,port:Number.isFinite(C)&&C>0?C:void 0,env:Object.keys(j).length?j:void 0}),_(null)}}):R.createElement(L,{dimColor:!0},b.env))):null,D?R.createElement(at,{borderStyle:"round",borderColor:"yellow",paddingX:1},R.createElement(L,{color:"yellow",bold:!0},"Restart ",D,"? "),R.createElement(L,{dimColor:!0},"[y]es [n]o / Esc")):null,k?R.createElement(L,null,"filter (Enter to apply, Esc to clear): ",R.createElement(L,{color:"cyan"},O)):null,St?R.createElement(at,{borderStyle:"round",borderColor:"cyan",paddingX:1},R.createElement(L,{bold:!0,color:"cyan"},"orchestrate profile (Enter to run, Esc to cancel): "),R.createElement(L,{color:"cyan"},J)):null,pr?R.createElement(L,{color:"cyan"},"[i] ",pr):null,R.createElement(L,{dimColor:!0},"[j/k or \u2191/\u2193] move [s] start [S] stop [r] restart [f] focus [x] try-fix [O] orchestrate [o] open URL [/] filter [g a|e|v|s|n] view hint [e] edit [E] env [V] $EDITOR [l] log focus [Shift+L] full log [q] quit")))}var Uo,Ho,Jo=F(()=>{"use strict";Do();Bo();Uo={stopped:"gray",starting:"yellow",compiling:"yellow",serving:"green",error:"red"},Ho={healthy:"green",unhealthy:"red",unknown:"gray"}});var Go={};yt(Go,{startInProcess:()=>Wo});import Nl from"react";import Ml from"node:path";import{render as $l}from"ink";import{pathToFileURL as jl}from"node:url";async function Wo(n={}){let t=null,e=null;Ro({getRegistry:()=>t,getConfig:()=>e});let r;try{r=st()}catch(k){process.stderr.write(`[daimon] config error: ${k.message}
89
- `),process.exit(1)}if(r.kind==="stub-created"){let k=Lt();process.stdout.write(`[daimon] no config found. Created stub at:
87
+ `)}catch{}process.exit(1)};process.on("uncaughtException",t),process.on("unhandledRejection",t)}var xl,qo=U(()=>{"use strict";_t();Pt();xl=/key|secret|token|password|pass/i});function mn(n,t){if(n.length===0)return 0;let e=[...n].sort((s,o)=>s-o),r=Math.min(e.length-1,Math.floor((e.length-1)*t));return Math.round(e[r]*100)/100}var pr,El,Al,hn,Go=U(()=>{"use strict";_t();pr=1e3,El=60,Al=256;hn=class{constructor(t){this.history=t;this.start()}history;startMs=Date.now();lagTimer=null;lagSamples=[];querySamples=[];lockContentionCount=0;lastTickAt=Date.now();highLagStreak=0;warnedAtStreak=0;onSelfWarn=null;start(){let t=performance.now();this.lagTimer=setInterval(()=>{let e=performance.now(),r=Math.max(0,e-t-pr);t=e,this.lagSamples.push(r),this.lagSamples.length>El&&this.lagSamples.shift(),this.lastTickAt=Date.now(),r>100?(this.highLagStreak++,this.highLagStreak>=5&&this.highLagStreak>this.warnedAtStreak&&this.onSelfWarn&&(this.warnedAtStreak=this.highLagStreak,this.onSelfWarn(`event loop lag sustained: ${Math.round(r)}ms (${this.highLagStreak} consecutive ticks)`))):(this.highLagStreak=0,this.warnedAtStreak=0)},pr),this.lagTimer.unref&&this.lagTimer.unref()}setSelfWarnHandler(t){this.onSelfWarn=t}recordQueryMs(t){this.querySamples.push(t),this.querySamples.length>Al&&this.querySamples.shift()}incLockContention(){this.lockContentionCount++}snapshot(){let t=process.memoryUsage(),e=1024*1024;return{pid:process.pid,version:st,uptimeMs:Date.now()-this.startMs,rssMB:Math.round(t.rss/e*10)/10,heapUsedMB:Math.round(t.heapUsed/e*10)/10,heapTotalMB:Math.round(t.heapTotal/e*10)/10,eventLoopLagMs:this.lagSamples.length?Math.round(this.lagSamples[this.lagSamples.length-1]*100)/100:0,eventLoopLagP95Ms:mn(this.lagSamples,.95),historyDbQueryMs:{p50:mn(this.querySamples,.5),p95:mn(this.querySamples,.95),p99:mn(this.querySamples,.99)},lockContentionCount:this.lockContentionCount,tickIntervalMs:pr,lastTickAt:this.lastTickAt}}stop(){this.lagTimer&&clearInterval(this.lagTimer),this.lagTimer=null}}});var Vo={};kt(Vo,{buildContext:()=>hr,loadPlugins:()=>fr,pluginsDir:()=>dr,runPluginScans:()=>mr,validatePluginFile:()=>Ml});import Ol from"node:fs";import Xo from"node:path";import Nl from"node:os";import{pathToFileURL as Ko}from"node:url";function dr(n){return n&&typeof n=="string"&&n.trim()?n:Xo.join(Nl.homedir(),".daimon","plugins")}function $l(n){return n.startsWith("doctor-")&&n.endsWith(".mjs")}function zo(n){if(!n||typeof n!="object")return{ok:!1,error:"module has no default export"};let t=n.default??n;return t?typeof t.name!="string"||!t.name.length?{ok:!1,error:"plugin.name must be a non-empty string"}:/^[a-z][a-z0-9-]*$/.test(t.name)?typeof t.scan!="function"?{ok:!1,error:"plugin.scan must be a function"}:t.fix!==void 0&&typeof t.fix!="function"?{ok:!1,error:"plugin.fix, if present, must be a function"}:t.undo!==void 0&&typeof t.undo!="function"?{ok:!1,error:"plugin.undo, if present, must be a function"}:{ok:!0,plugin:t}:{ok:!1,error:`plugin.name must be kebab-case (got "${t.name}")`}:{ok:!1,error:"plugin shape is null"}}async function fr(n){let t=[],e;try{e=Ol.readdirSync(n).filter($l).sort()}catch{return t}let r=new Set;for(let s of e){let o=Xo.join(n,s);try{let i=await import(Ko(o).href+`?t=${Date.now()}`),a=zo(i);if(!a.ok){t.push({name:s,file:o,status:"failed",error:a.error});continue}let c=a.plugin;if(Yo.has(c.name)){t.push({name:c.name,file:o,status:"failed",error:`name collides with built-in rule "${c.name}"`});continue}if(r.has(c.name)){t.push({name:c.name,file:o,status:"failed",error:"duplicate plug-in name"});continue}r.add(c.name),t.push({name:c.name,description:c.description,file:o,status:"ok",module:c})}catch(i){t.push({name:s,file:o,status:"failed",error:i?.message??String(i)})}}return t}async function Ml(n){try{let t=await import(Ko(n).href+`?t=${Date.now()}`),e=zo(t);return e.ok?Yo.has(e.plugin.name)?{ok:!1,error:`name collides with built-in rule "${e.plugin.name}"`}:{ok:!0,name:e.plugin.name,description:e.plugin.description}:{ok:!1,error:e.error}}catch(t){return{ok:!1,error:t?.message??String(t)}}}async function mr(n,t){for(let e of n)if(!(e.status!=="ok"||!e.module))try{e.lastFindings=await e.module.scan(t),Array.isArray(e.lastFindings)||(e.lastFindings=[])}catch(r){e.status="failed",e.error=`scan failed: ${r?.message??String(r)}`,e.lastFindings=[]}return n}function hr(n){return{config:n.config,apps:n.apps,history:n.history&&typeof n.history.querySelfMetrics=="function"?{querySelfMetrics:n.history.querySelfMetrics.bind(n.history)}:null,mutations:{setOverride:()=>{throw new Error("mutations.setOverride is not implemented in v0.8 \u2014 fix functions are advisory until M44 wires the M36 patch surface")}}}}var Yo,gr=U(()=>{"use strict";Yo=new Set(["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root"])});import it,{useEffect as jl,useMemo as _l,useState as me}from"react";import{Box as Ee,Text as yt,useInput as Dl,useStdout as Ll}from"ink";import Il from"ink-text-input";function yr({registry:n,appName:t,onExit:e}){let{stdout:r}=Ll(),[s,o]=me(0),[i,a]=me(!1),[c,l]=me(""),[u,d]=me(""),[f,g]=me(0),[C,R]=me(0);jl(()=>{let v=()=>o(E=>E+1);n.on("change",v);let w=setInterval(()=>o(E=>E+1),500);return()=>{n.off("change",v),clearInterval(w)}},[n]);let b=n.getState(t)?.logBuffer.map(v=>v.line)??[],N=(r.rows||30)-4,p=_l(()=>{if(!u)return[];let v=u.toLowerCase();return b.reduce((w,E,S)=>(E.toLowerCase().includes(v)&&w.push(S),w),[])},[b,u,s]);Dl((v,w)=>{if(i){if(w.escape){a(!1),l("");return}return}if(v==="q"||w.escape){e();return}if(v==="/"){a(!0);return}if(v==="g"){g(Math.max(0,b.length-N));return}if(v==="G"){g(0);return}if(w.pageUp){g(E=>Math.min(Math.max(0,b.length-N),E+N));return}if(w.pageDown){g(E=>Math.max(0,E-N));return}if(w.upArrow){g(E=>Math.min(Math.max(0,b.length-N),E+1));return}if(w.downArrow){g(E=>Math.max(0,E-1));return}if((v==="n"||v==="N")&&p.length){let E=v==="n"?(C+1)%p.length:(C-1+p.length)%p.length;R(E);let S=p[E],O=b.length-f,I=O-N;(S<I||S>=O)&&g(Math.max(0,b.length-S-Math.floor(N/2)));return}});let m=v=>{d(v),a(!1),l(""),R(0)},h=b.length-f,k=Math.max(0,h-N),T=b.slice(k,h),P=(v,w)=>{if(!u)return it.createElement(yt,{key:w},it.createElement(yt,{dimColor:!0},String(w+1).padStart(5)," "),v);let E=u,S=v.toLowerCase(),O=E.toLowerCase(),I=[],X=0,j=0;for(;X<v.length;){let Q=S.indexOf(O,X);if(Q<0){I.push(it.createElement(yt,{key:j++},v.slice(X)));break}Q>X&&I.push(it.createElement(yt,{key:j++},v.slice(X,Q))),I.push(it.createElement(yt,{key:j++,backgroundColor:"yellow",color:"black"},v.slice(Q,Q+E.length))),X=Q+E.length}let W=p[C]===w;return it.createElement(yt,{key:w},it.createElement(yt,{color:W?"cyan":void 0,dimColor:!W},String(w+1).padStart(5)," "),I)};return it.createElement(Ee,{flexDirection:"column"},it.createElement(Ee,null,it.createElement(yt,{bold:!0},"full log: ",it.createElement(yt,{color:"cyan"},t)),it.createElement(yt,{dimColor:!0}," (",b.length," lines",u?`, ${p.length} matches for "${u}"`:"",", scroll=",f,")")),it.createElement(Ee,{flexDirection:"column"},T.length===0?it.createElement(yt,{dimColor:!0},"(no log yet)"):T.map((v,w)=>P(v,k+w))),it.createElement(Ee,null,i?it.createElement(Ee,null,it.createElement(yt,null,"/"),it.createElement(Il,{value:c,onChange:l,onSubmit:m})):it.createElement(yt,{dimColor:!0},"[/] search [n/N] next/prev [g/G] bottom/top [PgUp/PgDn] [\u2191\u2193] [q/Esc] back")))}var Zo=U(()=>{"use strict"});function ti(n,t,e=Date.now()){let r=e-36e5,s=36e5/20,o=new Array(20).fill("");for(let i of n){if(i.type!=="status"||i.app!==t||!i.to||i.ts<r||i.ts>e)continue;let a=Math.min(19,Math.floor((i.ts-r)/s)),c=o[a];(!c||(Qo[i.to]??0)>(Qo[c]??0))&&(o[a]=i.to)}return o}function ei(n){return n.map(t=>Fl[t]??"\xB7").join("")}var Qo,Fl,ni=U(()=>{"use strict";Qo={stopped:1,serving:2,compiling:3,starting:3,error:4},Fl={"":"\xB7",stopped:"\u2591",serving:"\u2593",compiling:"\u2592",starting:"\u2592",error:"\u2588"}});import $,{useEffect as Bl,useState as lt}from"react";import wr from"node:fs";import Ul from"node:os";import Hl from"node:path";import{Box as dt,Text as F,useApp as Jl,useInput as Wl,useStdout as ql}from"ink";import br from"ink-text-input";import{spawn as vr,spawnSync as Gl}from"node:child_process";function Xl(n){try{process.platform==="win32"?vr("cmd",["/c","start","",n],{detached:!0,stdio:"ignore",windowsHide:!0}).unref():process.platform==="darwin"?vr("open",[n],{detached:!0,stdio:"ignore"}).unref():vr("xdg-open",[n],{detached:!0,stdio:"ignore"}).unref()}catch{}}function Kl(n){if(n==null)return"";let t=Math.floor(n/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60);return e<60?`${e}m ${t%60}s`:`${Math.floor(e/60)}h ${e%60}m`}function Sr({registry:n,apiPort:t,onQuit:e}){let{exit:r}=Jl(),{stdout:s}=ql(),[o,i]=lt(n.list()),[a,c]=lt(0),[l,u]=lt(!1),[d,f]=lt(0),[g,C]=lt(!1),[R,y]=lt([]),[b,N]=lt(!1),[p,m]=lt(""),[h,k]=lt(null),[,T]=lt(0),[P,v]=lt(null),[w,E]=lt(""),[S,O]=lt(!1),[I,X]=lt(null),[j,W]=lt(""),[Q,J]=lt(!1),[wt,Z]=lt(null),[Ne,ve]=lt(n.events({sinceMs:3600*1e3}));Bl(()=>{let A=()=>i(n.list()),L=()=>ve(n.events({sinceMs:36e5}));n.on("change",A),n.on("event",L);let H=setInterval(()=>{i(n.list()),ve(n.events({sinceMs:3600*1e3})),T(D=>D+1)},1e3);return()=>{n.off("change",A),n.off("event",L),clearInterval(H)}},[n]),Wl((A,L)=>{if(g)return;if(h){if(L.escape){k(null);return}if(L.tab){let D=h.field==="command"?"port":h.field==="port"?"env":"command";k({...h,field:D});return}return}if(b){if(L.escape){N(!1),m("");return}if(L.return){let D=p.trim();y(D?D.split(/[\s,]+/).filter(Boolean):[]),N(!1),m("");return}if(L.backspace||L.delete){m(D=>D.slice(0,-1));return}A&&!L.ctrl&&m(D=>D+A);return}if(S){if(L.escape){O(!1);return}if(L.return){O(!1);return}if(L.backspace||L.delete){E(D=>D.slice(0,-1));return}A&&!L.ctrl&&E(D=>D+A);return}if(Q){if(L.escape){J(!1),W("");return}if(L.return){let D=j.trim();J(!1),W(""),D&&Ei(D);return}if(L.backspace||L.delete){W(D=>D.slice(0,-1));return}A&&!L.ctrl&&W(D=>D+A);return}if(I){if(A==="y"||A==="Y"){let D=I;X(null),n.restart(D),tt(`restarted ${D}`)}else(A==="n"||A==="N"||L.escape)&&X(null);return}if(A==="q"||L.ctrl&&A==="c"){e(),r();return}if(o.length===0)return;if(P==="g"){v(null);let D=A.toLowerCase();D==="a"?tt("view: apps (only TUI view)"):D==="e"?tt("view: errors \u2014 selected app errors shown in detail pane"):D==="v"?tt("view: events \u2014 recent registry events shown in log pane"):D==="s"?tt("view: settings \u2014 edit `daimon.config.json`"):D==="n"&&tt("view: sessions \u2014 `daimon record` to toggle recording");return}if(L.upArrow||A==="k"){c(D=>Math.max(0,D-1)),f(0);return}if(L.downArrow||A==="j"){c(D=>Math.min(o.length-1,D+1)),f(0);return}let H=o[a];if(H){if(A==="g"){v("g"),setTimeout(()=>v(D=>D==="g"?null:D),1200);return}if(A==="/"){O(!0);return}if(A==="s")n.start(H.name);else if(A==="S")n.stop(H.name);else if(A==="r")X(H.name);else if(A==="f")Ri(H.name);else if(A==="x")$e(H.name);else if(A==="O")J(!0);else if(A==="L")C(!0);else if(A==="t")N(!0),m(R.join(" "));else if(A==="e"){let D=n.getConfig(),et=n.getApp(H.name),gt=n.getState(H.name)?.sessionOverrides??null,Ht=gt?.env??D.overrides?.[H.name]?.env??{},Jt=Object.entries(Ht).map(([Sn,kn])=>`${Sn}=${kn}`).join(`
88
+ `);k({name:H.name,field:"command",cmd:gt?.command??et?.command??"",port:String(gt?.port??D.overrides?.[H.name]?.port??H.port??""),env:Jt})}else if(A==="E"){let et=n.getConfig().envFiles?.[H.name]??[];if(!et.length)return;let gt=n.getState(H.name)?.activeEnvFile??null,Ht=gt?et.indexOf(gt):-1,Jt=et[(Ht+1)%et.length];n.setActiveEnvFile(H.name,Jt)}else if(A==="V"){let D=process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),et=Hl.join(Ul.tmpdir(),`daimon-${H.name}-${Date.now()}.json`),gt=n.getConfig(),Ht=n.getApp(H.name),Jt=n.getState(H.name)?.sessionOverrides??null,Sn={command:Jt?.command??Ht?.command,port:Jt?.port??gt.overrides?.[H.name]?.port??null,env:Jt?.env??gt.overrides?.[H.name]?.env??{}};try{wr.writeFileSync(et,JSON.stringify(Sn,null,2)),Gl(D,[et],{stdio:"inherit",shell:!0});let kn=wr.readFileSync(et,"utf8"),Wt=JSON.parse(kn);n.setSessionOverride(H.name,{command:typeof Wt.command=="string"?Wt.command:void 0,port:typeof Wt.port=="number"?Wt.port:void 0,env:Wt.env&&typeof Wt.env=="object"?Wt.env:void 0}),wr.unlinkSync(et)}catch{}}else A==="l"?u(D=>!D):A==="o"?H.url&&Xl(H.url):L.pageUp?f(D=>D+5):L.pageDown&&f(D=>Math.max(0,D-5))}});let tt=A=>{Z(A),setTimeout(()=>Z(L=>L===A?null:L),4e3)},$e=async A=>{tt(`try-fix ${A}\u2026`);try{let{runAutoFix:L,ALL_AUTO_FIX:H}=await Promise.resolve().then(()=>(pe(),ue)),et=n.getConfig().doctor?.autoFix?.permitted??H,gt=await L({permitted:et,dryRun:!1});await n.restart(A);let Ht=await n.waitFor(A,"healthy",6e4);tt(`try-fix ${A}: ${Ht.timedOut?"timeout":"reached"} \xB7 fixed ${gt.ran.length}`)}catch(L){tt(`try-fix ${A} failed: ${L?.message??L}`)}},Ri=async A=>{tt(`focus ${A} until stable\u2026`);try{let L=Date.now(),H=Date.now(),D=et=>{et.app===A&&(H=Date.now())};n.on("event",D);try{for(;Date.now()-L<18e4;){let et=n.summary(A);if(et&&et.status==="serving"&&et.health==="healthy"&&Date.now()-H>=5e3){tt(`focus ${A}: stable after ${Math.round((Date.now()-L)/1e3)}s`);return}await new Promise(gt=>setTimeout(gt,500))}}finally{n.off("event",D)}tt(`focus ${A}: timed out`)}catch(L){tt(`focus ${A} failed: ${L?.message??L}`)}},Ei=async A=>{tt(`orchestrate ${A}\u2026`);try{let{orchestrateProfile:L}=await Promise.resolve().then(()=>(tr(),Qn)),H=await L(n,n.getConfig(),{profile:A,goal:"healthy",timeoutMs:3e5});if(H.error){tt(`orchestrate ${A}: ${H.error}`);return}let D=H.allReached;tt(`orchestrate ${A}: ${D?"all reached":"some failing"} \xB7 ${Math.round(H.totalMs/1e3)}s`)}catch(L){tt(`orchestrate ${A} failed: ${L?.message??L}`)}},Cr=w.trim().toLowerCase(),Me=(R.length===0?o:o.filter(A=>R.every(L=>A.tags.includes(L)))).filter(A=>!Cr||A.name.toLowerCase().includes(Cr)),K=Me[Math.min(a,Math.max(0,Me.length-1))],Ut=K?n.getState(K.name):null,Rr=Ut?Ut.logBuffer.slice(Math.max(0,Ut.logBuffer.length-12-d),Ut.logBuffer.length-d).map(A=>A.line):[],vn=s.columns||100,Ai=Math.min(36,Math.floor(vn*.4));return g&&K?$.createElement(yr,{registry:n,appName:K.name,onExit:()=>C(!1)}):$.createElement(dt,{flexDirection:"column",width:vn},$.createElement(dt,{borderStyle:"round",borderColor:"cyan",paddingX:1},$.createElement(F,{bold:!0,color:"cyan"},"daimon"),$.createElement(F,{dimColor:!0}," \u2022 api http://127.0.0.1:",t)),$.createElement(dt,{flexDirection:"row"},$.createElement(dt,{flexDirection:"column",width:Ai,borderStyle:"single",borderColor:"gray",paddingX:1},$.createElement(F,{bold:!0},"Apps ",R.length?$.createElement(F,{dimColor:!0},"(tags: ",R.join(", "),")"):null),Me.length===0?$.createElement(F,{dimColor:!0},o.length===0?"(no apps discovered)":"(no apps match filter)"):Me.map((A,L)=>{let H=L===a,D=ti(Ne,A.name),et=ei(D);return $.createElement(dt,{key:A.name,flexDirection:"column"},$.createElement(dt,null,$.createElement(F,{color:H?"cyan":void 0},H?"\u25B8 ":" "),$.createElement(F,{color:H?"cyan":void 0},((n.getState(A.name)?.sessionOverrides?"*":"")+A.name).padEnd(20).slice(0,20)),$.createElement(F,{color:ri[A.status]}," ",A.status.padEnd(9)),$.createElement(F,{color:si[A.health]},A.status==="serving"?"\u25CF":" "),$.createElement(F,{dimColor:!0},A.port?` :${A.port}`:""),vn>=100&&A.cpu!=null?$.createElement(F,{dimColor:!0}," ",String(A.cpu).padStart(5),"% ",String(A.memMB??0).padStart(5),"MB"):null),$.createElement(dt,null,$.createElement(F,{dimColor:!0}," "),$.createElement(F,{dimColor:!0},et)))})),$.createElement(dt,{flexDirection:"column",flexGrow:1,borderStyle:"single",borderColor:"gray",paddingX:1},K&&Ut?$.createElement($.Fragment,null,$.createElement(F,null,"Selected: ",$.createElement(F,{bold:!0},K.name)),$.createElement(F,null,"Status: ",$.createElement(F,{color:ri[K.status]},K.status)," ",$.createElement(F,{color:si[K.health]},"\u25CF")," ",$.createElement(F,{dimColor:!0},K.health)),$.createElement(F,null,"Port: ",K.port??"-"),$.createElement(F,null,"URL: ",K.url??"-"),K.announcedUrl&&K.announcedUrl!==K.url?$.createElement(F,{dimColor:!0},"Announced: ",K.announcedUrl):null,K.lastHealthError?$.createElement(F,{color:"red"},"HealthErr: ",K.lastHealthError):null,K.stale?$.createElement(F,{color:"yellow"},"\u26A0 stale (best guess)"):null,$.createElement(F,null,"Errors: ",$.createElement(F,{color:K.errorCount?"red":void 0},K.errorCount)),$.createElement(F,null,"Uptime: ",Kl(K.uptimeMs)),K.cpu!=null||K.memMB!=null?$.createElement(F,null,"Usage: ",K.cpu??"-","% ",K.memMB??"-"," MB"):null,K.compileHistoryMs.length>0?$.createElement(F,null,"Recent compile: ",K.compileHistoryMs.slice(-5).map(A=>(A/1e3).toFixed(1)+"s").join(" \xB7 ")):null,K.bundle?$.createElement(F,null,"Bundle: ",K.bundle.initialKB,"KB initial \xB7 ",K.bundle.lazyKB,"KB lazy",K.bundleRegressionPct!=null&&K.bundleRegressionPct>10?$.createElement(F,{color:"red"}," (+",K.bundleRegressionPct,"% \u26A0)"):null):null,Ut.lastStatusMessage?$.createElement(F,{dimColor:!0},"Note: ",Ut.lastStatusMessage):null,$.createElement(F,null,"\u2500\u2500\u2500\u2500 recent log ",l?"(focused)":""," \u2500\u2500\u2500\u2500"),Rr.length===0?$.createElement(F,{dimColor:!0},"(no output yet)"):Rr.map((A,L)=>$.createElement(F,{key:L,wrap:"truncate-end"},A))):$.createElement(F,{dimColor:!0},"No app selected."))),$.createElement(dt,{flexDirection:"column"},b?$.createElement(F,null,"tag filter (space-separated, Enter to apply, Esc to cancel): ",$.createElement(F,{color:"cyan"},p)):null,h?$.createElement(dt,{flexDirection:"column",borderStyle:"round",borderColor:"yellow",paddingX:1},$.createElement(F,{bold:!0,color:"yellow"},"edit ",h.name," (session-only) Tab=next field Enter=save Esc=cancel"),$.createElement(dt,null,$.createElement(F,null,h.field==="command"?"> ":" ","command: "),h.field==="command"?$.createElement(br,{value:h.cmd,onChange:A=>k({...h,cmd:A}),onSubmit:()=>k({...h,field:"port"})}):$.createElement(F,{dimColor:!0},h.cmd)),$.createElement(dt,null,$.createElement(F,null,h.field==="port"?"> ":" ","port: "),h.field==="port"?$.createElement(br,{value:h.port,onChange:A=>k({...h,port:A}),onSubmit:()=>k({...h,field:"env"})}):$.createElement(F,{dimColor:!0},h.port)),$.createElement(dt,null,$.createElement(F,null,h.field==="env"?"> ":" ","env (k=v;): "),h.field==="env"?$.createElement(br,{value:h.env.replace(/\n/g,";"),onChange:A=>k({...h,env:A.replace(/;/g,`
89
+ `)}),onSubmit:()=>{let A=Number(h.port),L={};for(let H of h.env.split(/\n/)){let D=H.match(/^\s*([^=]+)=(.*)$/);D&&(L[D[1].trim()]=D[2])}n.setSessionOverride(h.name,{command:h.cmd||void 0,port:Number.isFinite(A)&&A>0?A:void 0,env:Object.keys(L).length?L:void 0}),k(null)}}):$.createElement(F,{dimColor:!0},h.env))):null,I?$.createElement(dt,{borderStyle:"round",borderColor:"yellow",paddingX:1},$.createElement(F,{color:"yellow",bold:!0},"Restart ",I,"? "),$.createElement(F,{dimColor:!0},"[y]es [n]o / Esc")):null,S?$.createElement(F,null,"filter (Enter to apply, Esc to clear): ",$.createElement(F,{color:"cyan"},w)):null,Q?$.createElement(dt,{borderStyle:"round",borderColor:"cyan",paddingX:1},$.createElement(F,{bold:!0,color:"cyan"},"orchestrate profile (Enter to run, Esc to cancel): "),$.createElement(F,{color:"cyan"},j)):null,wt?$.createElement(F,{color:"cyan"},"[i] ",wt):null,$.createElement(F,{dimColor:!0},"[j/k or \u2191/\u2193] move [s] start [S] stop [r] restart [f] focus [x] try-fix [O] orchestrate [o] open URL [/] filter [g a|e|v|s|n] view hint [e] edit [E] env [V] $EDITOR [l] log focus [Shift+L] full log [q] quit")))}var ri,si,oi=U(()=>{"use strict";Zo();ni();ri={stopped:"gray",starting:"yellow",compiling:"yellow",serving:"green",error:"red"},si={healthy:"green",unhealthy:"red",unknown:"gray"}});var ai={};kt(ai,{startInProcess:()=>ii});import zl from"react";import Yl from"node:path";import{render as Vl}from"ink";import{pathToFileURL as Zl}from"node:url";async function ii(n={}){let t=null,e=null;Wo({getRegistry:()=>t,getConfig:()=>e});let r;try{r=at()}catch(S){process.stderr.write(`[daimon] config error: ${S.message}
90
+ `),process.exit(1)}if(r.kind==="stub-created"){let S=$t();process.stdout.write(`[daimon] no config found. Created stub at:
90
91
  ${r.path}
91
92
  `),process.stdout.write(`[daimon] Edit it to add "searchRoots" pointing at your Nx/Angular workspace, then run again.
92
- `),process.stdout.write(`[daimon] (Local override path: ${k.local})
93
+ `),process.stdout.write(`[daimon] (Local override path: ${S.local})
93
94
  `),process.exit(0)}let{config:s,path:o}=r;if(process.stdout.write(`[daimon] config: ${o}
94
- `),s.depends&&Object.keys(s.depends).length){let k=Se(s.depends);k&&(process.stderr.write(`[daimon] config error: depends graph has a cycle: ${k.join(" -> ")}
95
- `),process.exit(1))}let i=It(s);i.length===0&&process.stdout.write(`[daimon] no serveable projects discovered in: ${s.searchRoots.join(", ")||"(none)"}
96
- `);let a=po(),l=new Yt(s.portRange,{initial:a.ports,onChange:k=>fo({ports:k})}),c=new De(s,i,l);t=c,e=s;let d=new Ct(s.history);c.setHistory(d);let u=new Ge(c,s.healthProbe,s),g=new qe(c),y=new Xe(c,s.autoRestart),p=new Ke(c,s.notifications),m=new ze(c,s.staleDetect),h=new Ve(c,s.requestLog);c.on("childExit",({name:k,code:I,signal:D,stopping:z})=>y.onExit(k,I,D,z)),c.on("userStop",({name:k})=>y.onUserStop(k));let f=Xs();if(f&&f.apps.length){process.stdout.write(`[daimon] state-handoff: restoring ${f.apps.map(k=>k.name).join(", ")}
97
- `);for(let k of f.apps)l.pin(k.name,k.port);for(let k of f.apps)c.names().includes(k.name)&&c.start(k.name)}if(s.autoStart&&s.autoStart.length){let k=new Set(c.names());for(let I of s.autoStart){if(!k.has(I)){process.stderr.write(`[daimon] warning: autoStart references unknown app "${I}"
98
- `);continue}s.depends&&s.depends[I]&&s.depends[I].length?c.startWithDeps(I):c.start(I)}}let w=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):s.apiPort,T=!!n.headless||!!s.headless||process.argv.includes("--headless"),E=setInterval(()=>{try{c.pruneOldErrors()}catch{}},3600*1e3),b=[];try{b=await Vn(Yn(s.plugins?.dir??void 0));for(let k of b)k.status==="failed"&&process.stderr.write(`[daimon] plug-in skipped: ${Ml.basename(k.file)} \u2014 ${k.error}
99
- `)}catch{}let _=new Qe(d);_.setSelfWarnHandler(k=>{try{c.recordEvent({app:"__daemon__",type:"self-warn",message:k})}catch{}});let A=setInterval(()=>{let k=_.snapshot();d.recordSelfMetric(k.rssMB,k.heapUsedMB,k.eventLoopLagMs,k.historyDbQueryMs.p95)},60*1e3);A.unref&&A.unref();let x=!1,P=async()=>{if(!x){x=!0;try{clearInterval(E)}catch{}try{clearInterval(A)}catch{}try{_.stop()}catch{}try{u.stop()}catch{}try{g.stop()}catch{}try{y.stop()}catch{}try{p.stop()}catch{}try{m.stop()}catch{}try{h.stop()}catch{}try{d.close()}catch{}try{await c.stopAll(3e3)}catch{}try{O.close()}catch{}try{wt()}catch{}process.exit(0)}},O=ro(c,w,{metricsEnabled:s.metrics.enabled,requestLog:h,onShutdown:()=>{P()},configPath:o,getConfig:()=>c.getConfig(),patchConfig:k=>{try{let I=To({configPath:o,patch:k}),D=Kn({configPath:o,registry:c});return{ok:!0,applied:I.applied,addedApps:D.addedApps,removedApps:D.removedApps,restartRequired:D.restartRequired}}catch(I){return{ok:!1,error:I?.message||String(I)}}},reloadConfig:async()=>{let k=Kn({configPath:o,registry:c});return{ok:!0,addedApps:k.addedApps,removedApps:k.removedApps,restartRequired:k.restartRequired}},selfMetrics:_,getPlugins:()=>b.map(k=>({name:k.name,description:k.description,file:k.file,status:k.status,error:k.error,lastFindings:k.lastFindings})),runPluginScans:async()=>{let k=Qn({config:c.getConfig(),apps:c.names().map(I=>({name:I,workspaceRoot:c.getApp(I)?.workspaceRoot??""})),history:d});await Zn(b,k)}});process.stdout.write(`[daimon] api: http://127.0.0.1:${w}
100
- `);try{Or(Nr(w,T,o))}catch(k){process.stderr.write(`[daimon] warning: could not write daemon.lock: ${k?.message||k}
101
- `)}if(process.on("SIGINT",()=>{P()}),process.on("SIGTERM",()=>{P()}),process.on("beforeExit",()=>{P()}),T){process.stdout.write(`[daimon] headless mode \u2014 TUI suppressed. Dashboard: http://127.0.0.1:${w}
102
- `);let k="",I=setInterval(()=>{let D=c.list().map(J=>({name:J.name,status:J.status,health:J.health,port:J.port})),z=JSON.stringify(D);z!==k&&(process.stderr.write(z+`
103
- `),k=z)},6e4);await new Promise(()=>{}),clearInterval(I);return}await $l(Nl.createElement(or,{registry:c,apiPort:w,onQuit:()=>{P()}})).waitUntilExit(),await P()}var _l,qo=F(()=>{"use strict";Xt();zt();Cs();fe();so();ao();co();lo();mo();Te();de();yo();bo();So();bt();Co();Ao();_n();Oo();tr();Jo();_l=(()=>{try{return import.meta.url===jl(process.argv[1]||"").href}catch{return!1}})();_l&&Wo().catch(n=>{process.stderr.write(`[daimon] fatal: ${n?.stack||n}
104
- `),process.exit(1)})});var zo={};yt(zo,{attachToDaemon:()=>Kl});import X,{useEffect as Xo,useState as Rt}from"react";import ir from"node:fs";import Ko from"node:path";import Dl from"node:os";import{Box as ce,render as Ll,Text as V,useApp as Il,useInput as Fl,useStdout as Bl}from"ink";import Ul from"ink-text-input";function Wl(n){if(n==null)return"";let t=Math.floor(n/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60);return e<60?`${e}m ${t%60}s`:`${Math.floor(e/60)}h ${e%60}m`}function ar(n){return Ko.join(Dl.homedir(),".daimon",`attach-token.${n}`)}function Gl(n){try{return ir.readFileSync(ar(n),"utf8").trim()||null}catch{return null}}function ql(n,t){try{ir.mkdirSync(Ko.dirname(ar(n)),{recursive:!0}),ir.writeFileSync(ar(n),t,"utf8")}catch{}}function Xl({port:n,onExit:t}){let{exit:e}=Il(),{stdout:r}=Bl(),[s,o]=Rt([]),[i,a]=Rt(0),[l,c]=Rt(!1),[d,u]=Rt([]),[g,y]=Rt(null),[p,m]=Rt(()=>Gl(n)),[h,f]=Rt(!1),[w,T]=Rt(""),E=`http://127.0.0.1:${n}`;async function b(x,P={}){try{let O={...P.headers||{}};p&&(O.authorization=`Bearer ${p}`);let S=await fetch(E+x,{...P,headers:O}),k=await S.text(),I=k;try{I=JSON.parse(k)}catch{}return{status:S.status,body:I}}catch(O){return{status:0,body:{error:O?.message||String(O)}}}}if(Xo(()=>{let x=!1,P=async()=>{let S=await b("/api/apps?format=full");if(!x){if(S.status===0){y(S.body?.error||"daemon unreachable");return}if(S.status===401){f(!0);return}y(null),o(Array.isArray(S.body)?S.body:[])}};P();let O=setInterval(P,1e3);return()=>{x=!0,clearInterval(O)}},[p]),Xo(()=>{if(!l){u([]);return}let x=!1,P=s[i];if(!P)return;let O=async()=>{let k=await b(`/api/apps/${encodeURIComponent(P.name)}/logs?tail=12`);x||Array.isArray(k.body?.lines)&&u(k.body.lines)};O();let S=setInterval(O,1e3);return()=>{x=!0,clearInterval(S)}},[l,i,s.length,p]),Fl((x,P)=>{if(h){if(P.escape){f(!1);return}return}if(x==="q"||P.ctrl&&x==="c"){t(),e();return}if(P.upArrow)a(O=>Math.max(0,O-1));else if(P.downArrow)a(O=>Math.min(Math.max(0,s.length-1),O+1));else if(P.return||x===" ")c(O=>!O);else if(x==="s"||x==="x"||x==="r"){let O=s[i];if(!O)return;let S=x==="s"?"start":x==="x"?"stop":"restart";b(`/api/apps/${encodeURIComponent(O.name)}/${S}`,{method:"POST"})}}),h)return X.createElement(ce,{flexDirection:"column",paddingX:1},X.createElement(V,{color:"yellow"},"daemon requires a bearer token. Enter token (Esc to cancel):"),X.createElement(Ul,{value:w,onChange:T,mask:"*",onSubmit:()=>{let x=w.trim();x&&(m(x),ql(n,x)),T(""),f(!1)}}));let _=r.columns||100,A=s[i];return X.createElement(ce,{flexDirection:"column",width:_},X.createElement(ce,{borderStyle:"round",borderColor:"cyan",paddingX:1},X.createElement(V,{bold:!0,color:"cyan"},"daimon attach"),X.createElement(V,{dimColor:!0}," \u2022 http://127.0.0.1:",n," \u2022 HTTP-client TUI (q detaches, daemon keeps running)")),g?X.createElement(V,{color:"red"},g):null,X.createElement(ce,{flexDirection:"column",borderStyle:"single",borderColor:"gray",paddingX:1},X.createElement(V,{bold:!0},"Apps (",s.length,")"),s.length===0?X.createElement(V,{dimColor:!0},"(no apps)"):s.map((x,P)=>{let O=P===i;return X.createElement(ce,{key:x.name},X.createElement(V,{color:O?"cyan":void 0},O?"\u25B8 ":" "),X.createElement(V,{color:O?"cyan":void 0},x.name.padEnd(20).slice(0,20)),X.createElement(V,{color:Hl[x.status]}," ",x.status.padEnd(9)),X.createElement(V,{color:Jl[x.health]},x.status==="serving"?"\u25CF":" "),X.createElement(V,{dimColor:!0},x.port?` :${x.port}`:""),X.createElement(V,{dimColor:!0}," errs=",x.errorCount," up=",Wl(x.uptimeMs)))})),A?X.createElement(ce,{flexDirection:"column",borderStyle:"single",borderColor:"gray",paddingX:1},X.createElement(V,null,"Selected: ",X.createElement(V,{bold:!0},A.name)),X.createElement(V,null,"URL: ",A.url??"-"),A.lastHealthError?X.createElement(V,{color:"red"},"HealthErr: ",A.lastHealthError):null,X.createElement(V,{dimColor:!0},"\u2500\u2500\u2500\u2500 recent log (Enter/Space toggles) \u2500\u2500\u2500\u2500"),l?d.length===0?X.createElement(V,{dimColor:!0},"(loading\u2026)"):d.map((x,P)=>X.createElement(V,{key:P,wrap:"truncate-end"},x)):X.createElement(V,{dimColor:!0},"(press Enter to fetch logs)")):null,X.createElement(V,{dimColor:!0},"[s] start [x] stop [r] restart [Enter] toggle log [q] detach (daemon keeps running)"))}async function Kl(n){let t,e=new Promise(s=>{t=s});await Ll(X.createElement(Xl,{port:n,onExit:()=>t()})).waitUntilExit(),await e}var Hl,Jl,Yo=F(()=>{"use strict";Hl={stopped:"gray",starting:"yellow",compiling:"yellow",serving:"green",error:"red"},Jl={healthy:"green",unhealthy:"red",unknown:"gray"}});var ti={};yt(ti,{buildServiceArtifact:()=>Qo,installServiceArtifact:()=>Yl});import Vo from"node:fs";import Zo from"node:os";import At from"node:path";import{fileURLToPath as zl}from"node:url";function tn(){return process.execPath}function en(){let n=At.dirname(zl(import.meta.url));return At.join(n,"main.js")}function Qo(){let n=process.platform;if(n==="win32"){let r=`<?xml version="1.0" encoding="UTF-8"?>
95
+ `),s.depends&&Object.keys(s.depends).length){let S=_e(s.depends);S&&(process.stderr.write(`[daimon] config error: depends graph has a cycle: ${S.join(" -> ")}
96
+ `),process.exit(1))}let i=Ot(s);i.length===0&&process.stdout.write(`[daimon] no serveable projects discovered in: ${s.searchRoots.join(", ")||"(none)"}
97
+ `);let a=Eo(),c=new re(s.portRange,{initial:a.ports,onChange:S=>Ao({ports:S})}),l=new Ye(s,i,c);t=l,e=s;let u=new jt(s.history);l.setHistory(u);let d=new an(l,s.healthProbe,s),f=new cn(l),g=new ln(l,s.autoRestart),C=new un(l,s.notifications),R=new pn(l,s.staleDetect),y=new fn(l,s.requestLog);l.on("childExit",({name:S,code:O,signal:I,stopping:X})=>g.onExit(S,O,I,X)),l.on("userStop",({name:S})=>g.onUserStop(S));let b=io();if(b&&b.apps.length){process.stdout.write(`[daimon] state-handoff: restoring ${b.apps.map(S=>S.name).join(", ")}
98
+ `);for(let S of b.apps)c.pin(S.name,S.port);for(let S of b.apps)l.names().includes(S.name)&&l.start(S.name)}if(s.autoStart&&s.autoStart.length){let S=new Set(l.names());for(let O of s.autoStart){if(!S.has(O)){process.stderr.write(`[daimon] warning: autoStart references unknown app "${O}"
99
+ `);continue}s.depends&&s.depends[O]&&s.depends[O].length?l.startWithDeps(O):l.start(O)}}let N=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):s.apiPort,p=!!n.headless||!!s.headless||process.argv.includes("--headless"),m=setInterval(()=>{try{l.pruneOldErrors()}catch{}},3600*1e3),h=[];try{h=await fr(dr(s.plugins?.dir??void 0));for(let S of h)S.status==="failed"&&process.stderr.write(`[daimon] plug-in skipped: ${Yl.basename(S.file)} \u2014 ${S.error}
100
+ `)}catch{}let k=new hn(u);k.setSelfWarnHandler(S=>{try{l.recordEvent({app:"__daemon__",type:"self-warn",message:S})}catch{}});let T=setInterval(()=>{let S=k.snapshot();u.recordSelfMetric(S.rssMB,S.heapUsedMB,S.eventLoopLagMs,S.historyDbQueryMs.p95)},60*1e3);T.unref&&T.unref();let P=!1,v=async()=>{if(!P){P=!0;try{clearInterval(m)}catch{}try{clearInterval(T)}catch{}try{k.stop()}catch{}try{d.stop()}catch{}try{f.stop()}catch{}try{g.stop()}catch{}try{C.stop()}catch{}try{R.stop()}catch{}try{y.stop()}catch{}try{u.close()}catch{}try{await l.stopAll(3e3)}catch{}try{w.close()}catch{}try{Tt()}catch{}process.exit(0)}},w=vo(l,N,{metricsEnabled:s.metrics.enabled,requestLog:y,onShutdown:()=>{v()},configPath:o,getConfig:()=>l.getConfig(),patchConfig:S=>{try{let O=Bo({configPath:o,patch:S}),I=ur({configPath:o,registry:l});return{ok:!0,applied:O.applied,addedApps:I.addedApps,removedApps:I.removedApps,restartRequired:I.restartRequired}}catch(O){return{ok:!1,error:O?.message||String(O)}}},reloadConfig:async()=>{let S=ur({configPath:o,registry:l});return{ok:!0,addedApps:S.addedApps,removedApps:S.removedApps,restartRequired:S.restartRequired}},selfMetrics:k,getPlugins:()=>h.map(S=>({name:S.name,description:S.description,file:S.file,status:S.status,error:S.error,lastFindings:S.lastFindings})),runPluginScans:async()=>{let S=hr({config:l.getConfig(),apps:l.names().map(O=>({name:O,workspaceRoot:l.getApp(O)?.workspaceRoot??""})),history:u});await mr(h,S)}});process.stdout.write(`[daimon] api: http://127.0.0.1:${N}
101
+ `);try{Hr(Jr(N,p,o))}catch(S){process.stderr.write(`[daimon] warning: could not write daemon.lock: ${S?.message||S}
102
+ `)}if(process.on("SIGINT",()=>{v()}),process.on("SIGTERM",()=>{v()}),process.on("beforeExit",()=>{v()}),p){process.stdout.write(`[daimon] headless mode \u2014 TUI suppressed. Dashboard: http://127.0.0.1:${N}
103
+ `);let S="",O=setInterval(()=>{let I=l.list().map(j=>({name:j.name,status:j.status,health:j.health,port:j.port})),X=JSON.stringify(I);X!==S&&(process.stderr.write(X+`
104
+ `),S=X)},6e4);await new Promise(()=>{}),clearInterval(O);return}await Vl(zl.createElement(Sr,{registry:l,apiPort:N,onQuit:()=>{v()}})).waitUntilExit(),await v()}var Ql,ci=U(()=>{"use strict";ee();qt();Is();xe();So();To();Po();Co();Oo();Ie();ke();Mo();_o();Lo();Pt();Uo();qo();Yn();Go();gr();oi();Ql=(()=>{try{return import.meta.url===Zl(process.argv[1]||"").href}catch{return!1}})();Ql&&ii().catch(n=>{process.stderr.write(`[daimon] fatal: ${n?.stack||n}
105
+ `),process.exit(1)})});var pi={};kt(pi,{attachToDaemon:()=>du});import Y,{useEffect as li,useState as It}from"react";import kr from"node:fs";import ui from"node:path";import tu from"node:os";import{Box as he,render as eu,Text as nt,useApp as nu,useInput as ru,useStdout as su}from"ink";import ou from"ink-text-input";function cu(n){if(n==null)return"";let t=Math.floor(n/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60);return e<60?`${e}m ${t%60}s`:`${Math.floor(e/60)}h ${e%60}m`}function xr(n){return ui.join(tu.homedir(),".daimon",`attach-token.${n}`)}function lu(n){try{return kr.readFileSync(xr(n),"utf8").trim()||null}catch{return null}}function uu(n,t){try{kr.mkdirSync(ui.dirname(xr(n)),{recursive:!0}),kr.writeFileSync(xr(n),t,"utf8")}catch{}}function pu({port:n,onExit:t}){let{exit:e}=nu(),{stdout:r}=su(),[s,o]=It([]),[i,a]=It(0),[c,l]=It(!1),[u,d]=It([]),[f,g]=It(null),[C,R]=It(()=>lu(n)),[y,b]=It(!1),[N,p]=It(""),m=`http://127.0.0.1:${n}`;async function h(P,v={}){try{let w={...v.headers||{}};C&&(w.authorization=`Bearer ${C}`);let E=await fetch(m+P,{...v,headers:w}),S=await E.text(),O=S;try{O=JSON.parse(S)}catch{}return{status:E.status,body:O}}catch(w){return{status:0,body:{error:w?.message||String(w)}}}}if(li(()=>{let P=!1,v=async()=>{let E=await h("/api/apps?format=full");if(!P){if(E.status===0){g(E.body?.error||"daemon unreachable");return}if(E.status===401){b(!0);return}g(null),o(Array.isArray(E.body)?E.body:[])}};v();let w=setInterval(v,1e3);return()=>{P=!0,clearInterval(w)}},[C]),li(()=>{if(!c){d([]);return}let P=!1,v=s[i];if(!v)return;let w=async()=>{let S=await h(`/api/apps/${encodeURIComponent(v.name)}/logs?tail=12`);P||Array.isArray(S.body?.lines)&&d(S.body.lines)};w();let E=setInterval(w,1e3);return()=>{P=!0,clearInterval(E)}},[c,i,s.length,C]),ru((P,v)=>{if(y){if(v.escape){b(!1);return}return}if(P==="q"||v.ctrl&&P==="c"){t(),e();return}if(v.upArrow)a(w=>Math.max(0,w-1));else if(v.downArrow)a(w=>Math.min(Math.max(0,s.length-1),w+1));else if(v.return||P===" ")l(w=>!w);else if(P==="s"||P==="x"||P==="r"){let w=s[i];if(!w)return;let E=P==="s"?"start":P==="x"?"stop":"restart";h(`/api/apps/${encodeURIComponent(w.name)}/${E}`,{method:"POST"})}}),y)return Y.createElement(he,{flexDirection:"column",paddingX:1},Y.createElement(nt,{color:"yellow"},"daemon requires a bearer token. Enter token (Esc to cancel):"),Y.createElement(ou,{value:N,onChange:p,mask:"*",onSubmit:()=>{let P=N.trim();P&&(R(P),uu(n,P)),p(""),b(!1)}}));let k=r.columns||100,T=s[i];return Y.createElement(he,{flexDirection:"column",width:k},Y.createElement(he,{borderStyle:"round",borderColor:"cyan",paddingX:1},Y.createElement(nt,{bold:!0,color:"cyan"},"daimon attach"),Y.createElement(nt,{dimColor:!0}," \u2022 http://127.0.0.1:",n," \u2022 HTTP-client TUI (q detaches, daemon keeps running)")),f?Y.createElement(nt,{color:"red"},f):null,Y.createElement(he,{flexDirection:"column",borderStyle:"single",borderColor:"gray",paddingX:1},Y.createElement(nt,{bold:!0},"Apps (",s.length,")"),s.length===0?Y.createElement(nt,{dimColor:!0},"(no apps)"):s.map((P,v)=>{let w=v===i;return Y.createElement(he,{key:P.name},Y.createElement(nt,{color:w?"cyan":void 0},w?"\u25B8 ":" "),Y.createElement(nt,{color:w?"cyan":void 0},P.name.padEnd(20).slice(0,20)),Y.createElement(nt,{color:iu[P.status]}," ",P.status.padEnd(9)),Y.createElement(nt,{color:au[P.health]},P.status==="serving"?"\u25CF":" "),Y.createElement(nt,{dimColor:!0},P.port?` :${P.port}`:""),Y.createElement(nt,{dimColor:!0}," errs=",P.errorCount," up=",cu(P.uptimeMs)))})),T?Y.createElement(he,{flexDirection:"column",borderStyle:"single",borderColor:"gray",paddingX:1},Y.createElement(nt,null,"Selected: ",Y.createElement(nt,{bold:!0},T.name)),Y.createElement(nt,null,"URL: ",T.url??"-"),T.lastHealthError?Y.createElement(nt,{color:"red"},"HealthErr: ",T.lastHealthError):null,Y.createElement(nt,{dimColor:!0},"\u2500\u2500\u2500\u2500 recent log (Enter/Space toggles) \u2500\u2500\u2500\u2500"),c?u.length===0?Y.createElement(nt,{dimColor:!0},"(loading\u2026)"):u.map((P,v)=>Y.createElement(nt,{key:v,wrap:"truncate-end"},P)):Y.createElement(nt,{dimColor:!0},"(press Enter to fetch logs)")):null,Y.createElement(nt,{dimColor:!0},"[s] start [x] stop [r] restart [Enter] toggle log [q] detach (daemon keeps running)"))}async function du(n){let t,e=new Promise(s=>{t=s});await eu(Y.createElement(pu,{port:n,onExit:()=>t()})).waitUntilExit(),await e}var iu,au,di=U(()=>{"use strict";iu={stopped:"gray",starting:"yellow",compiling:"yellow",serving:"green",error:"red"},au={healthy:"green",unhealthy:"red",unknown:"gray"}});var gi={};kt(gi,{buildServiceArtifact:()=>hi,installServiceArtifact:()=>mu});import fi from"node:fs";import mi from"node:os";import Ft from"node:path";import{fileURLToPath as fu}from"node:url";function gn(){return process.execPath}function yn(){let n=Ft.dirname(fu(import.meta.url));return Ft.join(n,"main.js")}function hi(){let n=process.platform;if(n==="win32"){let r=`<?xml version="1.0" encoding="UTF-8"?>
105
106
  <!-- generated by daimon daemon install-service -->
106
107
  <service>
107
108
  <id>daimon</id>
108
109
  <name>daimon daemon</name>
109
110
  <description>Local Angular/Nx/Vite dev server manager (daimon headless daemon)</description>
110
- <executable>${tn()}</executable>
111
- <arguments>"${en()}" --headless</arguments>
111
+ <executable>${gn()}</executable>
112
+ <arguments>"${yn()}" --headless</arguments>
112
113
  <log mode="rotate"/>
113
114
  <onfailure action="restart" delay="10 sec"/>
114
115
  </service>
115
- `,s=At.join(ut(),"daimon-daemon.xml");return{platform:n,path:s,body:r,installCmd:`nssm install daimon "${tn()}" "${en()}" --headless`}}if(n==="darwin"){let r=`<?xml version="1.0" encoding="UTF-8"?>
116
+ `,s=Ft.join(mt(),"daimon-daemon.xml");return{platform:n,path:s,body:r,installCmd:`nssm install daimon "${gn()}" "${yn()}" --headless`}}if(n==="darwin"){let r=`<?xml version="1.0" encoding="UTF-8"?>
116
117
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
117
118
  <plist version="1.0">
118
119
  <dict>
119
120
  <key>Label</key><string>dev.daimon</string>
120
121
  <key>ProgramArguments</key>
121
122
  <array>
122
- <string>${tn()}</string>
123
- <string>${en()}</string>
123
+ <string>${gn()}</string>
124
+ <string>${yn()}</string>
124
125
  <string>--headless</string>
125
126
  </array>
126
127
  <key>RunAtLoad</key><true/>
127
128
  <key>KeepAlive</key><true/>
128
- <key>StandardOutPath</key><string>${At.join(ut(),"service.out.log")}</string>
129
- <key>StandardErrorPath</key><string>${At.join(ut(),"service.err.log")}</string>
129
+ <key>StandardOutPath</key><string>${Ft.join(mt(),"service.out.log")}</string>
130
+ <key>StandardErrorPath</key><string>${Ft.join(mt(),"service.err.log")}</string>
130
131
  </dict>
131
132
  </plist>
132
- `,s=At.join(Zo.homedir(),"Library","LaunchAgents","dev.daimon.plist");return{platform:n,path:s,body:r,installCmd:`launchctl load ${s}`}}let t=`[Unit]
133
+ `,s=Ft.join(mi.homedir(),"Library","LaunchAgents","dev.daimon.plist");return{platform:n,path:s,body:r,installCmd:`launchctl load ${s}`}}let t=`[Unit]
133
134
  Description=daimon daemon (local dev-server manager)
134
135
  After=network.target
135
136
 
136
137
  [Service]
137
- ExecStart=${tn()} ${en()} --headless
138
+ ExecStart=${gn()} ${yn()} --headless
138
139
  Restart=on-failure
139
140
  RestartSec=10
140
141
 
141
142
  [Install]
142
143
  WantedBy=default.target
143
- `,e=At.join(Zo.homedir(),".config","systemd","user","daimon.service");return{platform:n,path:e,body:t,installCmd:"systemctl --user enable daimon && systemctl --user start daimon"}}function Yl(){let n=Qo();return Vo.mkdirSync(At.dirname(n.path),{recursive:!0}),Vo.writeFileSync(n.path,n.body,"utf8"),{path:n.path,installCmd:n.installCmd,platform:n.platform}}var ei=F(()=>{"use strict";bt()});var si={};yt(si,{runInit:()=>tu,runInitAuto:()=>ri});import Ot from"node:fs";import Vl from"node:os";import qt from"node:path";import Zl from"node:readline";function Gt(n,t){return new Promise(e=>n.question(t,r=>e(r.trim())))}function ni(n){let t=[];for(let e of Ql)Ot.existsSync(qt.join(n,e))&&t.push(e);return t}async function ri(n={}){let t=n.cwd??process.cwd(),e=ni(t),r=[],s;try{let a=JSON.parse(Ot.readFileSync(qt.join(t,"package.json"),"utf8"));typeof a.name=="string"&&(s=a.name)}catch{}e.length&&r.push(s?{path:t,label:s}:t);let o=qt.join(t,"daimon.config.json");if(Ot.existsSync(o)&&!n.force)throw new Error(`refusing to overwrite ${o} (pass --force to overwrite)`);let i={searchRoots:r,portRange:[4200,4299],apiPort:4999};return Ot.mkdirSync(qt.dirname(o),{recursive:!0}),Ot.writeFileSync(o,JSON.stringify(i,null,2)+`
144
- `,"utf8"),{path:o,installClaude:!1,config:i,auto:!0}}async function tu(n={}){if(n.auto)return ri(n);let t=n.cwd??process.cwd(),e=Zl.createInterface({input:process.stdin,output:process.stdout});try{let r=ni(t),s=[];if(r.length&&(process.stdout.write(`[daimon init] detected in ${t}: ${r.join(", ")}
145
- `),(await Gt(e,"Add this folder as a searchRoot? [Y/n] ")||"y").toLowerCase().startsWith("y"))){let f=await Gt(e,"Optional label for this workspace (blank = none): ");s.push(f?{path:t,label:f}:t)}let o=await Gt(e,"Additional searchRoots (comma-separated absolute paths, blank to skip): ");if(o)for(let h of o.split(",").map(f=>f.trim()).filter(Boolean))s.push(h);let a=(await Gt(e,"Port range [4200-4299]: ")||"4200-4299").match(/^(\d+)\s*[-,\s]\s*(\d+)$/),l=a?[Number(a[1]),Number(a[2])]:[4200,4299],c=await Gt(e,"apiPort [4999]: ")||"4999",d=Number(c)||4999,g=(await Gt(e,"Write to (1) ./daimon.config.json or (2) ~/.daimon/config.json? [1] ")||"1").trim()==="2"?qt.join(Vl.homedir(),".daimon","config.json"):qt.join(t,"daimon.config.json");if(Ot.existsSync(g)&&!n.force)throw new Error(`refusing to overwrite ${g} (pass --force to overwrite)`);let y={searchRoots:s,portRange:l,apiPort:d};Ot.mkdirSync(qt.dirname(g),{recursive:!0}),Ot.writeFileSync(g,JSON.stringify(y,null,2)+`
146
- `,"utf8"),process.stdout.write(`[daimon init] wrote ${g}
147
- `);let m=(await Gt(e,"Install Claude Code integration? [Y/n] ")||"y").toLowerCase().startsWith("y");return{path:g,installClaude:m,config:y}}finally{e.close()}}var Ql,oi=F(()=>{"use strict";Ql=["nx.json","angular.json","vite.config.ts","vite.config.js","vite.config.mjs",".storybook"]});Xt();zt();import li from"node:os";import ui from"node:path";de();fe();Te();import Ft from"node:fs";import Vt from"node:path";async function xr(n,t){let e=[],r=new Set(t.map(c=>c.name));for(let c of n.searchRoots){let d=typeof c=="string"?c:c.path,u=Vt.resolve(d);if(!Ft.existsSync(u)){e.push({name:`searchRoot exists: ${u}`,ok:!1,detail:"not found"});continue}let g=Ft.existsSync(Vt.join(u,"nx.json"))||Ft.existsSync(Vt.join(u,"angular.json"))||Ft.existsSync(Vt.join(u,".storybook"))||["ts","js","mjs","cjs"].some(y=>Ft.existsSync(Vt.join(u,`vite.config.${y}`)));e.push({name:`searchRoot has marker: ${u}`,ok:g,detail:g?void 0:"no nx.json/angular.json/vite.config.*/.storybook"})}for(let[c,d]of Object.entries(n.overrides??{})){let u=r.has(c),g=!!d.command,y=u||g;e.push({name:`override "${c}"`,ok:y,detail:y?void 0:"unknown app and no command override"})}let s=Object.entries(n.overrides??{}).filter(([,c])=>typeof c.port=="number").map(([c,d])=>({name:c,port:d.port})),o=new Map;for(let c of s)o.has(c.port)?e.push({name:`port pin ${c.port}`,ok:!1,detail:`collision: ${o.get(c.port)} and ${c.name}`}):o.set(c.port,c.name);s.length&&!e.some(c=>c.name.startsWith("port pin"))&&e.push({name:"pinned ports",ok:!0});for(let c of n.autoStart??[])e.push({name:`autoStart "${c}"`,ok:r.has(c),detail:r.has(c)?void 0:"unknown app"});for(let[c,d]of Object.entries(n.profiles??{}))for(let u of d)e.push({name:`profile "${c}" entry "${u}"`,ok:r.has(u),detail:r.has(u)?void 0:"unknown app"});if(n.depends&&Object.keys(n.depends).length){for(let[d,u]of Object.entries(n.depends))for(let g of u)r.has(g)||e.push({name:`depends "${d}" -> "${g}"`,ok:!1,detail:"unknown app"});let c=Se(n.depends);c?e.push({name:"depends DAG",ok:!1,detail:`cycle: ${c.join(" -> ")}`}):e.push({name:"depends DAG",ok:!0})}let i=new Set(t.map(c=>c.workspaceRoot));for(let c of i){let d=Vt.join(c,"node_modules");e.push({name:`node_modules: ${c}`,ok:Ft.existsSync(d),detail:Ft.existsSync(d)?void 0:"missing"})}let a=await Tt(n.apiPort);if(e.push({name:`apiPort ${n.apiPort}`,ok:a,detail:a?void 0:"in use (may be held by us)"}),n.history.enabled){let c=!1,d;try{let u=new Ct(n.history);c=u.quickCheck(),u.close(),c||(d="quick_check failed")}catch(u){d=u?.message||String(u)}e.push({name:"history db",ok:c,detail:d})}return e.push({name:"agent token footprint",ok:!0,detail:Ai(t)}),{ok:e.every(c=>c.ok),checks:e}}function Ai(n){let t=n.length,e=120,r=34,s=285,o=e+t*r,i=e+t*s,a=t>0?Math.round((1-o/i)*100):0;return`skill=${e} tokens \xB7 daimon list (${t} apps) \u2248 ${o} tokens compact / ${i} tokens full \xB7 savings: ~${a}%`}yn();wn();bt();Et();var Mr=[{id:"lifecycle",title:"lifecycle"},{id:"queries",title:"queries"},{id:"agent",title:"agent verbs"},{id:"introspection",title:"introspection"},{id:"config",title:"config"},{id:"claude",title:"claude"},{id:"plugin",title:"plugin"}],W=[{code:0,meaning:"success"},{code:1,meaning:"error"}],te=[...W,{code:2,meaning:"target state not reached within --timeout"}],mt=[{name:"list",args:"[--tag <name>] [--workspace <label>] [--full|--compact] [--stream] [--explain]",summary:"List apps. Compact by default; --full for v0.4 shape; --stream for NDJSON; --explain wraps with _meta (searchRoots, scanned, rejected, suggestion).",description:"List discovered apps. Compact JSON is the default; pass --full for the v0.4-shape full snapshot. --stream emits NDJSON until SIGINT. --explain wraps the response with _meta describing discovery.",example:"daimon list",examples:["daimon list","daimon list --tag web","daimon list --full --workspace fullstack","daimon list --stream"],options:[{flag:"--tag",arg:"<name>",description:"Filter to apps carrying this tag (repeatable)."},{flag:"--workspace",arg:"<label>",description:"Filter to a workspace label."},{flag:"--full",description:"Emit the full v0.4-shape snapshot per app."},{flag:"--compact",description:"Emit compact JSON (default)."},{flag:"--stream",description:"NDJSON stream until SIGINT."},{flag:"--explain",description:"Wrap with discovery _meta (searchRoots, scanned, rejected, suggestion)."}],needsDaemon:!0,group:"queries",aliases:["ls"],exitCodes:W},{name:"status",args:"<name> [--full|--compact]",summary:"Get the current status of one app. Compact by default.",description:"Show the current status of one app. Compact JSON is the default.",example:"daimon status web-admin",options:[{flag:"--full",description:"Full v0.4-shape snapshot."},{flag:"--compact",description:"Compact JSON (default)."}],needsDaemon:!0,group:"queries",aliases:["ps"],exitCodes:W},{name:"errors",args:"<name> [--since 2m] [--since-last] [--client <id>] [--structured] [--full|--compact]",summary:"Get deduplicated errors for an app. Compact by default ({file,line,col,code,message}).",description:"Deduplicated parsed errors for an app. Compact JSON by default.",example:"daimon errors web-admin --since 5m",options:[{flag:"--since",arg:"<duration>",description:"Time window (e.g. 30s, 5m, 1h)."},{flag:"--since-last",description:"Only errors since the previous --since-last call (per --client)."},{flag:"--client",arg:"<id>",description:"Cursor identity for --since-last."},{flag:"--structured",description:"Emit only parsed {file,line,col,code,message} rows."},{flag:"--full",description:"Full per-error entries."},{flag:"--compact",description:"Compact JSON (default)."}],needsDaemon:!0,group:"queries",exitCodes:W},{name:"events",args:"[--since 1h] [--app <name>] [--stream]",summary:"Get the event log. --stream emits NDJSON until SIGINT.",description:"Get the global event log. --stream emits NDJSON until SIGINT. Filter to a single app with --app.",example:"daimon events --since 1h",options:[{flag:"--since",arg:"<duration>",description:"Time window."},{flag:"--app",arg:"<name>",description:"Filter to a single app."},{flag:"--stream",description:"NDJSON stream."}],needsDaemon:!0,group:"queries",exitCodes:W},{name:"wait",args:"<name> [--until serving|healthy|stopped|error] [--timeout 60s]",summary:"Block until app reaches the given state.",description:"Block until an app reaches the given terminal state. Exits 2 on timeout.",example:"daimon wait web-admin --until healthy",options:[{flag:"--until",arg:"<state>",description:"Target state (serving|healthy|stopped|error). Default: serving."},{flag:"--timeout",arg:"<duration>",description:"Max wait, parsed as 60s/5m (default 60s)."}],needsDaemon:!0,group:"agent",exitCodes:te},{name:"ensure",args:"<name> [--until serving|healthy] [--timeout 180s]",summary:"One-call: start if needed, block to target state, return terminal state. Idempotent.",description:"Idempotent start+wait: starts the app if not already serving, then blocks until --until is reached.",example:"daimon ensure web-admin",options:[{flag:"--until",arg:"<state>",description:"Target state (serving|healthy). Default: healthy."},{flag:"--timeout",arg:"<duration>",description:"Max wait (default 180s)."}],needsDaemon:!0,group:"agent",exitCodes:te},{name:"ensure-up",args:"<profile> [--until serving|healthy] [--timeout 300s]",summary:"One-call: cascade-start every app in the profile and wait for each to reach target.",description:"Cascade-start every app in the profile and wait for each to reach the target state.",example:"daimon ensure-up fullstack",options:[{flag:"--until",arg:"<state>",description:"serving|healthy (default: healthy)."},{flag:"--timeout",arg:"<duration>",description:"Global budget (default 300s)."}],needsDaemon:!0,group:"agent",exitCodes:te},{name:"overview",args:"[--workspace <label>] [--profile <name>] [--budget <tokens>]",summary:"Decision-ready snapshot: totals, byStatus, needsAttention (with first parsed error), recentlyChanged. First call in a session. --budget caps the response size for agents; overflow collapses to _meta.omitted.",description:"Decision-ready snapshot \u2014 totals, byStatus, needsAttention (with first parsed error), recentlyChanged. Designed as the first call in an agent session.",example:"daimon overview --budget 1500",options:[{flag:"--workspace",arg:"<label>",description:"Filter to one workspace label."},{flag:"--profile",arg:"<name>",description:"Filter to apps in this profile."},{flag:"--budget",arg:"<tokens>",description:"Cap response size; overflow collapses to _meta.omitted."}],needsDaemon:!0,group:"agent",exitCodes:W},{name:"focus",args:"<name> [--until serving|healthy|stable] [--timeout 180s]",summary:"One round-trip subscribe-then-act: streams NDJSON of status/error/url events for one app until target state or timeout. Designed for agents.",description:"Subscribe-then-act: stream NDJSON of status/error/url events for one app until --until or --timeout.",example:"daimon focus web-admin --until stable",options:[{flag:"--until",arg:"<state>",description:"serving|healthy|stable (default: healthy)."},{flag:"--timeout",arg:"<duration>",description:"Max wait (default 180s)."}],needsDaemon:!0,group:"agent",exitCodes:te},{name:"try-fix",args:"<name> [--until serving|healthy] [--timeout 180s]",summary:"Composite: run doctor --auto-fix on permitted rules, restart the app, wait for target, return {before,after,fixed,stillFailing}. Never edits user source.",description:"Run doctor --auto-fix on permitted rules, restart the app, wait for target. Never edits user source.",example:"daimon try-fix web-admin",options:[{flag:"--until",arg:"<state>",description:"serving|healthy (default: healthy)."},{flag:"--timeout",arg:"<duration>",description:"Max wait (default 180s)."}],needsDaemon:!0,group:"agent",exitCodes:te},{name:"orchestrate",args:"<profile> [--goal serving|healthy|stable] [--timeout 300s] [--dry-run] [--budget <tokens>]",summary:"Bring up a whole profile in one call: cascade-start, wait for goal, run ONE try-fix round on stragglers. Returns {profile, goal, perApp, totalMs, allReached}. --dry-run reports planned order only. Designed for agents.",description:"Bring up a whole profile in one call: cascade-start, wait, one try-fix round on stragglers.",example:"daimon orchestrate fullstack --goal stable",options:[{flag:"--goal",arg:"<state>",description:"serving|healthy|stable (default: healthy)."},{flag:"--timeout",arg:"<duration>",description:"Global budget (default 300s)."},{flag:"--dry-run",description:"Print planned order without executing."},{flag:"--budget",arg:"<tokens>",description:"Cap response size."}],needsDaemon:!0,group:"agent",exitCodes:te},{name:"pin-health",args:"<name> [--accept] [--path <p>]",summary:"Show the auto-discovered health-probe path for an app; --accept persists it as overrides.<name>.healthProbePath in daimon.config.json and soft-reloads. Default behaviour is opt-in: nothing is written without --accept.",description:"Show the auto-discovered health-probe path for an app. --accept persists it to daimon.config.json.",example:"daimon pin-health api --accept",options:[{flag:"--accept",description:"Persist the candidate path to overrides.<name>.healthProbePath."},{flag:"--path",arg:"<p>",description:"Override the candidate path explicitly."}],needsDaemon:!0,group:"config",exitCodes:W},{name:"logs",args:"<name> [--tail N] [--since 30s]",summary:"Recent log lines for an app.",description:"Recent log lines for an app.",example:"daimon logs web-admin --tail 100",options:[{flag:"--tail",arg:"<N>",description:"Last N lines (default 50)."},{flag:"--since",arg:"<duration>",description:"Time window."}],needsDaemon:!0,group:"queries",aliases:["log"],exitCodes:W},{name:"start",args:"<name> [--with-deps]",summary:"Start an app.",description:"Start an app.",example:"daimon start web-admin",options:[{flag:"--with-deps",description:"Also start declared dependencies."}],needsDaemon:!0,group:"lifecycle",exitCodes:W},{name:"stop",args:"<name>",summary:"Stop an app.",description:"Stop an app.",example:"daimon stop web-admin",needsDaemon:!0,group:"lifecycle",exitCodes:W},{name:"restart",args:"<name>",summary:"Restart an app.",description:"Restart an app.",example:"daimon restart web-admin",needsDaemon:!0,group:"lifecycle",exitCodes:W},{name:"up",args:"[<profile>]",summary:"Start a profile (or autoStart). Waits for each to reach serving.",description:"Start a profile (or autoStart). Waits for each to reach serving.",example:"daimon up fullstack",needsDaemon:!0,group:"lifecycle",exitCodes:W},{name:"down",args:"[<profile>]",summary:"Stop a profile (or all apps).",description:"Stop a profile (or all apps).",example:"daimon down",needsDaemon:!0,group:"lifecycle",exitCodes:W},{name:"history",args:"<name>",summary:"Summary metrics (uptime%, restarts, compile p50/p95, top errors).",description:"Summary metrics for an app (uptime%, restarts, compile p50/p95, top errors).",example:"daimon history web-admin",needsDaemon:!0,group:"queries",exitCodes:W},{name:"why",args:"<name>",summary:"Last status transition + 5 preceding events.",description:"Explain the most recent state transition with the 5 events leading up to it.",example:"daimon why web-admin",needsDaemon:!0,group:"introspection",exitCodes:W},{name:"why-empty",args:"",summary:"Explain why `daimon list` is empty: configured searchRoots, scanned/rejected counts, suggested next step.",description:"Explain why `daimon list` is empty \u2014 search roots, scanned/rejected counts, suggestion.",example:"daimon why-empty",needsDaemon:!0,group:"introspection",exitCodes:W},{name:"discover",args:"[--dry-run]",summary:"Run discovery without changing state. Prints _meta: searchRoots, scanned, rejected per folder, suggestion.",description:"Run discovery without changing state. Emits per-folder scanned/rejected and suggestion.",example:"daimon discover --dry-run",options:[{flag:"--dry-run",description:"Report planned discovery without persisting."}],needsDaemon:!0,group:"introspection",exitCodes:W},{name:"export-config",args:"[--redacted]",summary:'Emit the active config to stdout. --redacted replaces apiToken with "<redacted>" and rewrites home paths to ~/...',description:'Emit the active config to stdout. --redacted replaces apiToken with "<redacted>" and home paths with ~/...',example:"daimon export-config --redacted",options:[{flag:"--redacted",description:"Replace apiToken and home paths."}],needsDaemon:!1,group:"config",exitCodes:W},{name:"tasks",args:"<name>",summary:"List discovered non-serve tasks.",description:"List discovered non-serve tasks for an app.",example:"daimon tasks web-admin",needsDaemon:!0,group:"introspection",exitCodes:W},{name:"run",args:"<name> <task> [--watch] [-- args...]",summary:"Run a discovered task.",description:"Run a discovered task. Pass extra args after `--`.",example:"daimon run web-admin test",options:[{flag:"--watch",description:"Keep running and stream output."}],needsDaemon:!0,group:"lifecycle",exitCodes:W},{name:"snapshot",args:"<name>",summary:"Write a snapshot of app state to ~/.daimon/snapshots.",description:"Write a diagnostic snapshot of app state to ~/.daimon/snapshots.",example:"daimon snapshot web-admin",needsDaemon:!0,group:"introspection",exitCodes:W},{name:"env",args:"<name> [--use <file>]",summary:"List or set the active env file for an app.",description:"List or set the active env file for an app.",example:"daimon env web-admin --use .env.staging",options:[{flag:"--use",arg:"<file>",description:"Activate an env file for the app."}],needsDaemon:!0,group:"config",exitCodes:W},{name:"clean",args:"<name> [--deep] [--yes]",summary:"Remove build artifacts for an app.",description:"Remove build artifacts for an app. --deep also removes node_modules; --yes skips the confirmation prompt.",example:"daimon clean web-admin --yes",options:[{flag:"--deep",description:"Also remove node_modules / language-specific deps caches."},{flag:"--yes",description:"Skip confirmation prompt."}],needsDaemon:!0,group:"lifecycle",exitCodes:W},{name:"record",args:"",summary:"Toggle session recording.",description:"Toggle JSONL session recording (~/.daimon/sessions).",example:"daimon record",needsDaemon:!0,group:"introspection",exitCodes:W},{name:"replay",args:"<session.jsonl> [--speed N]",summary:"Replay a recorded session.",description:"Replay a recorded session.",example:"daimon replay session.jsonl",options:[{flag:"--speed",arg:"<N>",description:"Speed multiplier (default 1)."}],needsDaemon:!0,group:"introspection",exitCodes:W},{name:"doctor",args:"[--auto-fix] [--dry-run] [--self]",summary:"Sanity-check config + env. --auto-fix repairs orphan daemon, stale lock, missing search root, corrupt history db. --self checks daimon's own metrics.",description:"Sanity-check config + env. --auto-fix repairs known issues; --dry-run shows what would change. --self runs the self-observability checks (heap, event-loop lag, history.db query p95).",example:"daimon doctor --auto-fix",options:[{flag:"--auto-fix",description:"Apply permitted repairs."},{flag:"--dry-run",description:"Report planned changes without writing."},{flag:"--self",description:"Run self-observability checks against the running daemon."}],needsDaemon:!1,group:"introspection",exitCodes:W},{name:"free-port",args:"<port> [--force]",summary:"Diagnose / free a port.",description:"Show which process is holding a port. --force kills it.",example:"daimon free-port 4200 --force",options:[{flag:"--force",description:"Kill the holder."}],needsDaemon:!1,group:"introspection",exitCodes:W},{name:"daemon",args:"start|stop|status|restart|attach|install-service [--detach] [--headless]",summary:"Manage the daimon daemon.",description:"Manage the daimon daemon lifecycle.",example:"daimon daemon status",options:[{flag:"--detach",description:"Spawn detached (for `start`)."},{flag:"--headless",description:"Start without the TUI (for `start`)."}],needsDaemon:!1,group:"lifecycle",exitCodes:W},{name:"claude",args:"install|update|uninstall|status [--skill] [--commands] [--agent] [--all] [--dir <path>] [--yes]",summary:"Install/update Claude Code integration artifacts.",description:"Install/update/uninstall the Claude Code integration artifacts.",example:"daimon claude install --all",needsDaemon:!1,group:"claude",exitCodes:W},{name:"init",args:"[--force] [--auto]",summary:"Create a daimon config in cwd; --auto picks safe defaults (no prompts) for workspaces with nx/angular/vite markers.",description:"Create a daimon config in cwd. --auto picks safe defaults for known workspace markers.",example:"daimon init --auto",options:[{flag:"--force",description:"Overwrite an existing daimon.config.json."},{flag:"--auto",description:"Skip prompts; pick safe defaults."}],needsDaemon:!1,group:"config",exitCodes:W},{name:"completion",args:"<bash|zsh|fish|powershell>",summary:"Emit a shell completion script for the given shell.",description:"Emit a shell-completion script for bash, zsh, fish, or PowerShell. Pipe the output to the appropriate per-shell location (see README).",example:"daimon completion bash > /etc/bash_completion.d/daimon",needsDaemon:!1,group:"config",exitCodes:W},{name:"plugin",args:"list|show <name>|validate <path>",summary:"Manage doctor plug-ins.",description:"Manage doctor plug-ins. `list` shows installed plug-ins with status; `show <name>` prints a plug-in manifest; `validate <path>` sanity-checks a plug-in file.",example:"daimon plugin list",needsDaemon:!0,group:"plugin",exitCodes:W},{name:"self",args:"",summary:"Print daimon's own runtime metrics (pid, version, uptime, rss, heap, event-loop lag, history-db p95).",description:"Print daimon's own runtime metrics. Useful for bug reports.",example:"daimon self",needsDaemon:!0,group:"introspection",exitCodes:W}],ht={};for(let n of mt)for(let t of n.aliases??[])ht[t]=n.name;function Oe(n){let t=ht[n]??n;return mt.find(e=>e.name===t)}function $r(){let n=Math.max(...mt.map(t=>t.name.length));return mt.map(t=>`${t.name.padEnd(n)} ${t.summary}`).join(`
148
- `)}Et();var kn=null;function jr(n){kn=n}function Ne(){return kn==="off"?!1:kn==="on"?!0:process.env.NO_COLOR&&process.env.NO_COLOR!==""?!1:process.env.FORCE_COLOR==="1"||process.env.FORCE_COLOR==="2"||process.env.FORCE_COLOR==="3"?!0:!!process.stdout.isTTY}var Ut={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m"};function ee(n,t){return Ne()?t+n+Ut.reset:n}var q={bold:n=>ee(n,Ut.bold),dim:n=>ee(n,Ut.dim),red:n=>ee(n,Ut.red),green:n=>ee(n,Ut.green),yellow:n=>ee(n,Ut.yellow),cyan:n=>ee(n,Ut.cyan)};function _r(){let n=[];n.push(`${q.bold("daimon")} v${Z}`),n.push("usage: daimon <command> [args]"),n.push("");for(let e of Mr){let r=mt.filter(o=>o.group===e.id);if(!r.length)continue;n.push(q.bold(e.title));let s=Math.max(...r.map(o=>o.name.length));for(let o of r)n.push(" "+q.cyan(o.name.padEnd(s))+" "+q.dim(o.summary));n.push("")}let t=Object.entries(ht);if(t.length){n.push(q.bold("aliases"));for(let[e,r]of t)n.push(" "+q.cyan(e.padEnd(6))+" "+q.dim(`\u2192 ${r}`));n.push("")}return n.push(q.bold("global flags")),n.push(" --help, -h Show this help (or per-command help when used after a verb)."),n.push(" --version, -v Print the daimon version and exit."),n.push(" --about Print {version,nodeVersion,platform,configPath,lockPath,claudeArtifacts}."),n.push(" --no-color Disable ANSI color (also: NO_COLOR=1)."),n.push(" --no-spawn Do not auto-spawn the daemon (also: DAIMON_NO_SPAWN=1)."),n.push(" DAIMON_PORT=N Target a non-default daemon port."),n.push(""),n.push(q.bold("flag conventions")),n.push(q.dim(" --timeout <duration> 60s, 5m, 2h")),n.push(q.dim(" --since <duration> duration window for queries")),n.push(q.dim(" --budget <tokens> cap response size for agents")),n.push(q.dim(" --until <state> target state for blocking calls")),n.push(q.dim(" --app <name> filter to one app")),n.push(q.dim(" --profile <name> target/filter profile")),n.push(q.dim(" --full / --compact output shape (compact = default)")),n.push(q.dim(" --stream NDJSON stream")),n.push(q.dim(" --explain wrap with _meta diagnostics")),n.push(q.dim(" --dry-run report planned actions, do not execute")),n.push(q.dim(" --yes skip interactive confirmations")),n.join(`
149
- `)}function Dr(n){let t=[];if(t.push(q.bold(`daimon ${n.name}`)+" "+q.dim(n.args)),t.push(""),t.push(n.description),n.options?.length){t.push(""),t.push(q.bold("options"));let r=Math.max(...n.options.map(s=>(s.flag+(s.arg?" "+s.arg:"")).length));for(let s of n.options){let o=(s.flag+(s.arg?" "+s.arg:"")).padEnd(r);t.push(" "+q.cyan(o)+" "+q.dim(s.description))}}let e=n.examples??(n.example?[n.example]:[]);if(e.length){t.push(""),t.push(q.bold("examples"));for(let r of e)t.push(" "+r)}if(n.exitCodes?.length){t.push(""),t.push(q.bold("exit codes"));for(let r of n.exitCodes)t.push(" "+String(r.code).padStart(2)+" "+q.dim(r.meaning))}return n.aliases?.length&&(t.push(""),t.push(q.bold("aliases")+" "+n.aliases.join(", "))),t.join(`
150
- `)}function Lr(n,t){if(n===t)return 0;if(!n.length)return t.length;if(!t.length)return n.length;let e=new Array(t.length+1);for(let r=0;r<=t.length;r++)e[r]=r;for(let r=1;r<=n.length;r++){let s=e[0];e[0]=r;for(let o=1;o<=t.length;o++){let i=e[o];e[o]=n[r-1]===t[o-1]?s:1+Math.min(s,e[o],e[o-1]),s=i}}return e[t.length]}function Ir(n){let t=mt.map(r=>r.name).concat(Object.keys(ht)),e=null;for(let r of t){let s=Lr(n,r);s<=2&&(!e||s<e.d)&&(e={name:r,d:s})}return e?.name??null}function Fr(n,t){let e=null;for(let r of t){let s=Lr(n,r);s<=2&&(!e||s<e.d)&&(e={name:r,d:s})}return e?.name??null}function Br(n){return JSON.stringify({error:n.error,...n.hint?{hint:n.hint}:{},exit:n.exit??1})}function xn(n){let t=[q.red("error: ")+n.error];return n.hint&&t.push(q.dim(" hint: ")+n.hint),t.join(`
151
- `)}var Ur=mt.map(n=>n.name).concat(Object.keys(ht)).sort().join(" ");function Ii(){return`#!/usr/bin/env bash
144
+ `,e=Ft.join(mi.homedir(),".config","systemd","user","daimon.service");return{platform:n,path:e,body:t,installCmd:"systemctl --user enable daimon && systemctl --user start daimon"}}function mu(){let n=hi();return fi.mkdirSync(Ft.dirname(n.path),{recursive:!0}),fi.writeFileSync(n.path,n.body,"utf8"),{path:n.path,installCmd:n.installCmd,platform:n.platform}}var yi=U(()=>{"use strict";Pt()});var vi={};kt(vi,{runInit:()=>wu,runInitAuto:()=>bi});import Bt from"node:fs";import hu from"node:os";import Zt from"node:path";import gu from"node:readline";function Vt(n,t){return new Promise(e=>n.question(t,r=>e(r.trim())))}function wi(n){let t=[];for(let e of yu)Bt.existsSync(Zt.join(n,e))&&t.push(e);return t}async function bi(n={}){let t=n.cwd??process.cwd(),e=wi(t),r=[],s;try{let a=JSON.parse(Bt.readFileSync(Zt.join(t,"package.json"),"utf8"));typeof a.name=="string"&&(s=a.name)}catch{}e.length&&r.push(s?{path:t,label:s}:t);let o=Zt.join(t,"daimon.config.json");if(Bt.existsSync(o)&&!n.force)throw new Error(`refusing to overwrite ${o} (pass --force to overwrite)`);let i={searchRoots:r,portRange:[4200,4299],apiPort:4999};return Bt.mkdirSync(Zt.dirname(o),{recursive:!0}),Bt.writeFileSync(o,JSON.stringify(i,null,2)+`
145
+ `,"utf8"),{path:o,installClaude:!1,config:i,auto:!0}}async function wu(n={}){if(n.auto)return bi(n);let t=n.cwd??process.cwd(),e=gu.createInterface({input:process.stdin,output:process.stdout});try{let r=wi(t),s=[];if(r.length&&(process.stdout.write(`[daimon init] detected in ${t}: ${r.join(", ")}
146
+ `),(await Vt(e,"Add this folder as a searchRoot? [Y/n] ")||"y").toLowerCase().startsWith("y"))){let b=await Vt(e,"Optional label for this workspace (blank = none): ");s.push(b?{path:t,label:b}:t)}let o=await Vt(e,"Additional searchRoots (comma-separated absolute paths, blank to skip): ");if(o)for(let y of o.split(",").map(b=>b.trim()).filter(Boolean))s.push(y);let a=(await Vt(e,"Port range [4200-4299]: ")||"4200-4299").match(/^(\d+)\s*[-,\s]\s*(\d+)$/),c=a?[Number(a[1]),Number(a[2])]:[4200,4299],l=await Vt(e,"apiPort [4999]: ")||"4999",u=Number(l)||4999,f=(await Vt(e,"Write to (1) ./daimon.config.json or (2) ~/.daimon/config.json? [1] ")||"1").trim()==="2"?Zt.join(hu.homedir(),".daimon","config.json"):Zt.join(t,"daimon.config.json");if(Bt.existsSync(f)&&!n.force)throw new Error(`refusing to overwrite ${f} (pass --force to overwrite)`);let g={searchRoots:s,portRange:c,apiPort:u};Bt.mkdirSync(Zt.dirname(f),{recursive:!0}),Bt.writeFileSync(f,JSON.stringify(g,null,2)+`
147
+ `,"utf8"),process.stdout.write(`[daimon init] wrote ${f}
148
+ `);let R=(await Vt(e,"Install Claude Code integration? [Y/n] ")||"y").toLowerCase().startsWith("y");return{path:f,installClaude:R,config:g}}finally{e.close()}}var yu,Si=U(()=>{"use strict";yu=["nx.json","angular.json","vite.config.ts","vite.config.js","vite.config.mjs",".storybook"]});ee();qt();import Pi from"node:os";import Ae from"node:path";ke();xe();Ie();import Gt from"node:fs";import se from"node:path";async function _r(n,t){let e=[],r=new Set(t.map(l=>l.name));for(let l of n.searchRoots){let u=typeof l=="string"?l:l.path,d=se.resolve(u);if(!Gt.existsSync(d)){e.push({name:`searchRoot exists: ${d}`,ok:!1,detail:"not found"});continue}let f=Gt.existsSync(se.join(d,"nx.json"))||Gt.existsSync(se.join(d,"angular.json"))||Gt.existsSync(se.join(d,".storybook"))||["ts","js","mjs","cjs"].some(g=>Gt.existsSync(se.join(d,`vite.config.${g}`)));e.push({name:`searchRoot has marker: ${d}`,ok:f,detail:f?void 0:"no nx.json/angular.json/vite.config.*/.storybook"})}for(let[l,u]of Object.entries(n.overrides??{})){let d=r.has(l),f=!!u.command,g=d||f;e.push({name:`override "${l}"`,ok:g,detail:g?void 0:"unknown app and no command override"})}let s=Object.entries(n.overrides??{}).filter(([,l])=>typeof l.port=="number").map(([l,u])=>({name:l,port:u.port})),o=new Map;for(let l of s)o.has(l.port)?e.push({name:`port pin ${l.port}`,ok:!1,detail:`collision: ${o.get(l.port)} and ${l.name}`}):o.set(l.port,l.name);s.length&&!e.some(l=>l.name.startsWith("port pin"))&&e.push({name:"pinned ports",ok:!0});for(let l of n.autoStart??[])e.push({name:`autoStart "${l}"`,ok:r.has(l),detail:r.has(l)?void 0:"unknown app"});for(let[l,u]of Object.entries(n.profiles??{}))for(let d of u)e.push({name:`profile "${l}" entry "${d}"`,ok:r.has(d),detail:r.has(d)?void 0:"unknown app"});if(n.depends&&Object.keys(n.depends).length){for(let[u,d]of Object.entries(n.depends))for(let f of d)r.has(f)||e.push({name:`depends "${u}" -> "${f}"`,ok:!1,detail:"unknown app"});let l=_e(n.depends);l?e.push({name:"depends DAG",ok:!1,detail:`cycle: ${l.join(" -> ")}`}):e.push({name:"depends DAG",ok:!0})}let i=new Set(t.map(l=>l.workspaceRoot));for(let l of i){let u=se.join(l,"node_modules");e.push({name:`node_modules: ${l}`,ok:Gt.existsSync(u),detail:Gt.existsSync(u)?void 0:"missing"})}let a=await Mt(n.apiPort);if(e.push({name:`apiPort ${n.apiPort}`,ok:a,detail:a?void 0:"in use (may be held by us)"}),n.history.enabled){let l=!1,u;try{let d=new jt(n.history);l=d.quickCheck(),d.close(),l||(u="quick_check failed")}catch(d){u=d?.message||String(d)}e.push({name:"history db",ok:l,detail:u})}return e.push({name:"agent token footprint",ok:!0,detail:Ji(t)}),{ok:e.every(l=>l.ok),checks:e}}function Ji(n){let t=n.length,e=120,r=34,s=285,o=e+t*r,i=e+t*s,a=t>0?Math.round((1-o/i)*100):0;return`skill=${e} tokens \xB7 daimon list (${t} apps) \u2248 ${o} tokens compact / ${i} tokens full \xB7 savings: ~${a}%`}On();Nn();Pt();_t();var Wr=[{id:"lifecycle",title:"lifecycle"},{id:"queries",title:"queries"},{id:"agent",title:"agent verbs"},{id:"introspection",title:"introspection"},{id:"config",title:"config"},{id:"claude",title:"claude"},{id:"plugin",title:"plugin"}],q=[{code:0,meaning:"success"},{code:1,meaning:"error"}],ae=[...q,{code:2,meaning:"target state not reached within --timeout"}],vt=[{name:"list",args:"[--tag <name>] [--workspace <label>] [--full|--compact] [--stream] [--explain]",summary:"List apps. Compact by default; --full for v0.4 shape; --stream for NDJSON; --explain wraps with _meta (searchRoots, scanned, rejected, suggestion).",description:"List discovered apps. Compact JSON is the default; pass --full for the v0.4-shape full snapshot. --stream emits NDJSON until SIGINT. --explain wraps the response with _meta describing discovery.",example:"daimon list",examples:["daimon list","daimon list --tag web","daimon list --full --workspace fullstack","daimon list --stream"],options:[{flag:"--tag",arg:"<name>",description:"Filter to apps carrying this tag (repeatable)."},{flag:"--workspace",arg:"<label>",description:"Filter to a workspace label."},{flag:"--full",description:"Emit the full v0.4-shape snapshot per app."},{flag:"--compact",description:"Emit compact JSON (default)."},{flag:"--stream",description:"NDJSON stream until SIGINT."},{flag:"--explain",description:"Wrap with discovery _meta (searchRoots, scanned, rejected, suggestion)."}],needsDaemon:!0,group:"queries",aliases:["ls"],exitCodes:q},{name:"status",args:"<name> [--full|--compact]",summary:"Get the current status of one app. Compact by default.",description:"Show the current status of one app. Compact JSON is the default.",example:"daimon status web-admin",options:[{flag:"--full",description:"Full v0.4-shape snapshot."},{flag:"--compact",description:"Compact JSON (default)."}],needsDaemon:!0,group:"queries",aliases:["ps"],exitCodes:q},{name:"errors",args:"<name> [--since 2m] [--since-last] [--client <id>] [--structured] [--full|--compact]",summary:"Get deduplicated errors for an app. Compact by default ({file,line,col,code,message}).",description:"Deduplicated parsed errors for an app. Compact JSON by default.",example:"daimon errors web-admin --since 5m",options:[{flag:"--since",arg:"<duration>",description:"Time window (e.g. 30s, 5m, 1h)."},{flag:"--since-last",description:"Only errors since the previous --since-last call (per --client)."},{flag:"--client",arg:"<id>",description:"Cursor identity for --since-last."},{flag:"--structured",description:"Emit only parsed {file,line,col,code,message} rows."},{flag:"--full",description:"Full per-error entries."},{flag:"--compact",description:"Compact JSON (default)."}],needsDaemon:!0,group:"queries",exitCodes:q},{name:"events",args:"[--since 1h] [--app <name>] [--stream]",summary:"Get the event log. --stream emits NDJSON until SIGINT.",description:"Get the global event log. --stream emits NDJSON until SIGINT. Filter to a single app with --app.",example:"daimon events --since 1h",options:[{flag:"--since",arg:"<duration>",description:"Time window."},{flag:"--app",arg:"<name>",description:"Filter to a single app."},{flag:"--stream",description:"NDJSON stream."}],needsDaemon:!0,group:"queries",exitCodes:q},{name:"wait",args:"<name> [--until serving|healthy|stopped|error] [--timeout 60s]",summary:"Block until app reaches the given state.",description:"Block until an app reaches the given terminal state. Exits 2 on timeout.",example:"daimon wait web-admin --until healthy",options:[{flag:"--until",arg:"<state>",description:"Target state (serving|healthy|stopped|error). Default: serving."},{flag:"--timeout",arg:"<duration>",description:"Max wait, parsed as 60s/5m (default 60s)."}],needsDaemon:!0,group:"agent",exitCodes:ae},{name:"ensure",args:"<name> [--until serving|healthy] [--timeout 180s]",summary:"One-call: start if needed, block to target state, return terminal state. Idempotent.",description:"Idempotent start+wait: starts the app if not already serving, then blocks until --until is reached.",example:"daimon ensure web-admin",options:[{flag:"--until",arg:"<state>",description:"Target state (serving|healthy). Default: healthy."},{flag:"--timeout",arg:"<duration>",description:"Max wait (default 180s)."}],needsDaemon:!0,group:"agent",exitCodes:ae},{name:"ensure-up",args:"<profile> [--until serving|healthy] [--timeout 300s]",summary:"One-call: cascade-start every app in the profile and wait for each to reach target.",description:"Cascade-start every app in the profile and wait for each to reach the target state.",example:"daimon ensure-up fullstack",options:[{flag:"--until",arg:"<state>",description:"serving|healthy (default: healthy)."},{flag:"--timeout",arg:"<duration>",description:"Global budget (default 300s)."}],needsDaemon:!0,group:"agent",exitCodes:ae},{name:"overview",args:"[--workspace <label>] [--profile <name>] [--budget <tokens>]",summary:"Decision-ready snapshot: totals, byStatus, needsAttention (with first parsed error), recentlyChanged. First call in a session. --budget caps the response size for agents; overflow collapses to _meta.omitted.",description:"Decision-ready snapshot \u2014 totals, byStatus, needsAttention (with first parsed error), recentlyChanged. Designed as the first call in an agent session.",example:"daimon overview --budget 1500",options:[{flag:"--workspace",arg:"<label>",description:"Filter to one workspace label."},{flag:"--profile",arg:"<name>",description:"Filter to apps in this profile."},{flag:"--budget",arg:"<tokens>",description:"Cap response size; overflow collapses to _meta.omitted."}],needsDaemon:!0,group:"agent",exitCodes:q},{name:"focus",args:"<name> [--until serving|healthy|stable] [--timeout 180s]",summary:"One round-trip subscribe-then-act: streams NDJSON of status/error/url events for one app until target state or timeout. Designed for agents.",description:"Subscribe-then-act: stream NDJSON of status/error/url events for one app until --until or --timeout.",example:"daimon focus web-admin --until stable",options:[{flag:"--until",arg:"<state>",description:"serving|healthy|stable (default: healthy)."},{flag:"--timeout",arg:"<duration>",description:"Max wait (default 180s)."}],needsDaemon:!0,group:"agent",exitCodes:ae},{name:"try-fix",args:"<name> [--until serving|healthy] [--timeout 180s]",summary:"Composite: run doctor --auto-fix on permitted rules, restart the app, wait for target, return {before,after,fixed,stillFailing}. Never edits user source.",description:"Run doctor --auto-fix on permitted rules, restart the app, wait for target. Never edits user source.",example:"daimon try-fix web-admin",options:[{flag:"--until",arg:"<state>",description:"serving|healthy (default: healthy)."},{flag:"--timeout",arg:"<duration>",description:"Max wait (default 180s)."}],needsDaemon:!0,group:"agent",exitCodes:ae},{name:"orchestrate",args:"<profile> [--goal serving|healthy|stable] [--timeout 300s] [--dry-run] [--budget <tokens>]",summary:"Bring up a whole profile in one call: cascade-start, wait for goal, run ONE try-fix round on stragglers. Returns {profile, goal, perApp, totalMs, allReached}. --dry-run reports planned order only. Designed for agents.",description:"Bring up a whole profile in one call: cascade-start, wait, one try-fix round on stragglers.",example:"daimon orchestrate fullstack --goal stable",options:[{flag:"--goal",arg:"<state>",description:"serving|healthy|stable (default: healthy)."},{flag:"--timeout",arg:"<duration>",description:"Global budget (default 300s)."},{flag:"--dry-run",description:"Print planned order without executing."},{flag:"--budget",arg:"<tokens>",description:"Cap response size."}],needsDaemon:!0,group:"agent",exitCodes:ae},{name:"pin-health",args:"<name> [--accept] [--path <p>]",summary:"Show the auto-discovered health-probe path for an app; --accept persists it as overrides.<name>.healthProbePath in daimon.config.json and soft-reloads. Default behaviour is opt-in: nothing is written without --accept.",description:"Show the auto-discovered health-probe path for an app. --accept persists it to daimon.config.json.",example:"daimon pin-health api --accept",options:[{flag:"--accept",description:"Persist the candidate path to overrides.<name>.healthProbePath."},{flag:"--path",arg:"<p>",description:"Override the candidate path explicitly."}],needsDaemon:!0,group:"config",exitCodes:q},{name:"logs",args:"<name> [--tail N] [--since 30s]",summary:"Recent log lines for an app.",description:"Recent log lines for an app.",example:"daimon logs web-admin --tail 100",options:[{flag:"--tail",arg:"<N>",description:"Last N lines (default 50)."},{flag:"--since",arg:"<duration>",description:"Time window."}],needsDaemon:!0,group:"queries",aliases:["log"],exitCodes:q},{name:"start",args:"<name> [--with-deps]",summary:"Start an app.",description:"Start an app.",example:"daimon start web-admin",options:[{flag:"--with-deps",description:"Also start declared dependencies."}],needsDaemon:!0,group:"lifecycle",exitCodes:q},{name:"stop",args:"<name>",summary:"Stop an app.",description:"Stop an app.",example:"daimon stop web-admin",needsDaemon:!0,group:"lifecycle",exitCodes:q},{name:"restart",args:"<name>",summary:"Restart an app.",description:"Restart an app.",example:"daimon restart web-admin",needsDaemon:!0,group:"lifecycle",exitCodes:q},{name:"up",args:"[<profile>]",summary:"Start a profile (or autoStart). Waits for each to reach serving.",description:"Start a profile (or autoStart). Waits for each to reach serving.",example:"daimon up fullstack",needsDaemon:!0,group:"lifecycle",exitCodes:q},{name:"down",args:"[<profile>]",summary:"Stop a profile (or all apps).",description:"Stop a profile (or all apps).",example:"daimon down",needsDaemon:!0,group:"lifecycle",exitCodes:q},{name:"history",args:"<name>",summary:"Summary metrics (uptime%, restarts, compile p50/p95, top errors).",description:"Summary metrics for an app (uptime%, restarts, compile p50/p95, top errors).",example:"daimon history web-admin",needsDaemon:!0,group:"queries",exitCodes:q},{name:"why",args:"<name>",summary:"Last status transition + 5 preceding events.",description:"Explain the most recent state transition with the 5 events leading up to it.",example:"daimon why web-admin",needsDaemon:!0,group:"introspection",exitCodes:q},{name:"why-empty",args:"",summary:"Explain why `daimon list` is empty: configured searchRoots, scanned/rejected counts, suggested next step.",description:"Explain why `daimon list` is empty \u2014 search roots, scanned/rejected counts, suggestion.",example:"daimon why-empty",needsDaemon:!0,group:"introspection",exitCodes:q},{name:"discover",args:"[--dry-run]",summary:"Run discovery without changing state. Prints _meta: searchRoots, scanned, rejected per folder, suggestion.",description:"Run discovery without changing state. Emits per-folder scanned/rejected and suggestion.",example:"daimon discover --dry-run",options:[{flag:"--dry-run",description:"Report planned discovery without persisting."}],needsDaemon:!0,group:"introspection",exitCodes:q},{name:"export-config",args:"[--redacted]",summary:'Emit the active config to stdout. --redacted replaces apiToken with "<redacted>" and rewrites home paths to ~/...',description:'Emit the active config to stdout. --redacted replaces apiToken with "<redacted>" and home paths with ~/...',example:"daimon export-config --redacted",options:[{flag:"--redacted",description:"Replace apiToken and home paths."}],needsDaemon:!1,group:"config",exitCodes:q},{name:"tasks",args:"<name>",summary:"List discovered non-serve tasks.",description:"List discovered non-serve tasks for an app.",example:"daimon tasks web-admin",needsDaemon:!0,group:"introspection",exitCodes:q},{name:"run",args:"<name> <task> [--watch] [-- args...]",summary:"Run a discovered task.",description:"Run a discovered task. Pass extra args after `--`.",example:"daimon run web-admin test",options:[{flag:"--watch",description:"Keep running and stream output."}],needsDaemon:!0,group:"lifecycle",exitCodes:q},{name:"snapshot",args:"<name>",summary:"Write a snapshot of app state to ~/.daimon/snapshots.",description:"Write a diagnostic snapshot of app state to ~/.daimon/snapshots.",example:"daimon snapshot web-admin",needsDaemon:!0,group:"introspection",exitCodes:q},{name:"env",args:"<name> [--use <file>]",summary:"List or set the active env file for an app.",description:"List or set the active env file for an app.",example:"daimon env web-admin --use .env.staging",options:[{flag:"--use",arg:"<file>",description:"Activate an env file for the app."}],needsDaemon:!0,group:"config",exitCodes:q},{name:"clean",args:"<name> [--deep] [--yes]",summary:"Remove build artifacts for an app.",description:"Remove build artifacts for an app. --deep also removes node_modules; --yes skips the confirmation prompt.",example:"daimon clean web-admin --yes",options:[{flag:"--deep",description:"Also remove node_modules / language-specific deps caches."},{flag:"--yes",description:"Skip confirmation prompt."}],needsDaemon:!0,group:"lifecycle",exitCodes:q},{name:"record",args:"",summary:"Toggle session recording.",description:"Toggle JSONL session recording (~/.daimon/sessions).",example:"daimon record",needsDaemon:!0,group:"introspection",exitCodes:q},{name:"replay",args:"<session.jsonl> [--speed N]",summary:"Replay a recorded session.",description:"Replay a recorded session.",example:"daimon replay session.jsonl",options:[{flag:"--speed",arg:"<N>",description:"Speed multiplier (default 1)."}],needsDaemon:!0,group:"introspection",exitCodes:q},{name:"doctor",args:"[--auto-fix] [--dry-run] [--self]",summary:"Sanity-check config + env. --auto-fix repairs orphan daemon, stale lock, missing search root, corrupt history db. --self checks daimon's own metrics.",description:"Sanity-check config + env. --auto-fix repairs known issues; --dry-run shows what would change. --self runs the self-observability checks (heap, event-loop lag, history.db query p95).",example:"daimon doctor --auto-fix",options:[{flag:"--auto-fix",description:"Apply permitted repairs."},{flag:"--dry-run",description:"Report planned changes without writing."},{flag:"--self",description:"Run self-observability checks against the running daemon."}],needsDaemon:!1,group:"introspection",exitCodes:q},{name:"free-port",args:"<port> [--force]",summary:"Diagnose / free a port.",description:"Show which process is holding a port. --force kills it.",example:"daimon free-port 4200 --force",options:[{flag:"--force",description:"Kill the holder."}],needsDaemon:!1,group:"introspection",exitCodes:q},{name:"daemon",args:"start|stop|status|restart|attach|install-service [--detach] [--headless]",summary:"Manage the daimon daemon.",description:"Manage the daimon daemon lifecycle.",example:"daimon daemon status",options:[{flag:"--detach",description:"Spawn detached (for `start`)."},{flag:"--headless",description:"Start without the TUI (for `start`)."}],needsDaemon:!1,group:"lifecycle",exitCodes:q},{name:"claude",args:"install|update|uninstall|status [--skill] [--commands] [--agent] [--all] [--dir <path>] [--yes]",summary:"Install/update Claude Code integration artifacts.",description:"Install/update/uninstall the Claude Code integration artifacts.",example:"daimon claude install --all",needsDaemon:!1,group:"claude",exitCodes:q},{name:"init",args:"[--force] [--auto]",summary:"Create a daimon config in cwd; --auto picks safe defaults (no prompts) for workspaces with nx/angular/vite markers.",description:"Create a daimon config in cwd. --auto picks safe defaults for known workspace markers.",example:"daimon init --auto",options:[{flag:"--force",description:"Overwrite an existing daimon.config.json."},{flag:"--auto",description:"Skip prompts; pick safe defaults."}],needsDaemon:!1,group:"config",exitCodes:q},{name:"completion",args:"<bash|zsh|fish|powershell>",summary:"Emit a shell completion script for the given shell.",description:"Emit a shell-completion script for bash, zsh, fish, or PowerShell. Pipe the output to the appropriate per-shell location (see README).",example:"daimon completion bash > /etc/bash_completion.d/daimon",needsDaemon:!1,group:"config",exitCodes:q},{name:"plugin",args:"list|show <name>|validate <path>",summary:"Manage doctor plug-ins.",description:"Manage doctor plug-ins. `list` shows installed plug-ins with status; `show <name>` prints a plug-in manifest; `validate <path>` sanity-checks a plug-in file.",example:"daimon plugin list",needsDaemon:!0,group:"plugin",exitCodes:q},{name:"self",args:"",summary:"Print daimon's own runtime metrics (pid, version, uptime, rss, heap, event-loop lag, history-db p95).",description:"Print daimon's own runtime metrics. Useful for bug reports.",example:"daimon self",needsDaemon:!0,group:"introspection",exitCodes:q},{name:"workspaces",args:"list|add [path] [--label <name>] | rm <path> | show [path]",summary:"Manage the workspace registry (searchRoots).",description:"List, add, remove, and inspect workspaces. `add` ensures the given path (defaults to cwd) is a registered searchRoot. `show` reports which workspace covers a cwd.",example:"daimon workspaces list",needsDaemon:!0,group:"config",exitCodes:q},{name:"dashboard",args:"",summary:"Open the dashboard in your default browser, scoped to the current cwd.",description:"Open http://127.0.0.1:4999/?cwd=<process.cwd()> in the default browser. The dashboard pre-selects the workspace pill covering cwd.",example:"daimon dashboard",needsDaemon:!0,group:"introspection",exitCodes:q},{name:"timeline",args:"[--since 7d] [--app <name>] [--kinds status,error,warning,lint,bundle,task]",summary:"Print a unified chronological event timeline.",description:"Merge status / error / warning / lint / bundle / task / health rows into one chronological stream. JSON output suits piping; use `daimon dashboard` then /timeline for the visual view.",example:"daimon timeline --since 24h --kinds status,error",needsDaemon:!0,group:"introspection",exitCodes:q}],St={};for(let n of vt)for(let t of n.aliases??[])St[t]=n.name;function We(n){let t=St[n]??n;return vt.find(e=>e.name===t)}function qr(){let n=Math.max(...vt.map(t=>t.name.length));return vt.map(t=>`${t.name.padEnd(n)} ${t.summary}`).join(`
149
+ `)}_t();var _n=null;function Gr(n){_n=n}function qe(){return _n==="off"?!1:_n==="on"?!0:process.env.NO_COLOR&&process.env.NO_COLOR!==""?!1:process.env.FORCE_COLOR==="1"||process.env.FORCE_COLOR==="2"||process.env.FORCE_COLOR==="3"?!0:!!process.stdout.isTTY}var Kt={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m"};function ce(n,t){return qe()?t+n+Kt.reset:n}var z={bold:n=>ce(n,Kt.bold),dim:n=>ce(n,Kt.dim),red:n=>ce(n,Kt.red),green:n=>ce(n,Kt.green),yellow:n=>ce(n,Kt.yellow),cyan:n=>ce(n,Kt.cyan)};function Xr(){let n=[];n.push(`${z.bold("daimon")} v${st}`),n.push("usage: daimon <command> [args]"),n.push("");for(let e of Wr){let r=vt.filter(o=>o.group===e.id);if(!r.length)continue;n.push(z.bold(e.title));let s=Math.max(...r.map(o=>o.name.length));for(let o of r)n.push(" "+z.cyan(o.name.padEnd(s))+" "+z.dim(o.summary));n.push("")}let t=Object.entries(St);if(t.length){n.push(z.bold("aliases"));for(let[e,r]of t)n.push(" "+z.cyan(e.padEnd(6))+" "+z.dim(`\u2192 ${r}`));n.push("")}return n.push(z.bold("global flags")),n.push(" --help, -h Show this help (or per-command help when used after a verb)."),n.push(" --version, -v Print the daimon version and exit."),n.push(" --about Print {version,nodeVersion,platform,configPath,lockPath,claudeArtifacts}."),n.push(" --no-color Disable ANSI color (also: NO_COLOR=1)."),n.push(" --no-spawn Do not auto-spawn the daemon (also: DAIMON_NO_SPAWN=1)."),n.push(" DAIMON_PORT=N Target a non-default daemon port."),n.push(""),n.push(z.bold("flag conventions")),n.push(z.dim(" --timeout <duration> 60s, 5m, 2h")),n.push(z.dim(" --since <duration> duration window for queries")),n.push(z.dim(" --budget <tokens> cap response size for agents")),n.push(z.dim(" --until <state> target state for blocking calls")),n.push(z.dim(" --app <name> filter to one app")),n.push(z.dim(" --profile <name> target/filter profile")),n.push(z.dim(" --full / --compact output shape (compact = default)")),n.push(z.dim(" --stream NDJSON stream")),n.push(z.dim(" --explain wrap with _meta diagnostics")),n.push(z.dim(" --dry-run report planned actions, do not execute")),n.push(z.dim(" --yes skip interactive confirmations")),n.join(`
150
+ `)}function Kr(n){let t=[];if(t.push(z.bold(`daimon ${n.name}`)+" "+z.dim(n.args)),t.push(""),t.push(n.description),n.options?.length){t.push(""),t.push(z.bold("options"));let r=Math.max(...n.options.map(s=>(s.flag+(s.arg?" "+s.arg:"")).length));for(let s of n.options){let o=(s.flag+(s.arg?" "+s.arg:"")).padEnd(r);t.push(" "+z.cyan(o)+" "+z.dim(s.description))}}let e=n.examples??(n.example?[n.example]:[]);if(e.length){t.push(""),t.push(z.bold("examples"));for(let r of e)t.push(" "+r)}if(n.exitCodes?.length){t.push(""),t.push(z.bold("exit codes"));for(let r of n.exitCodes)t.push(" "+String(r.code).padStart(2)+" "+z.dim(r.meaning))}return n.aliases?.length&&(t.push(""),t.push(z.bold("aliases")+" "+n.aliases.join(", "))),t.join(`
151
+ `)}function zr(n,t){if(n===t)return 0;if(!n.length)return t.length;if(!t.length)return n.length;let e=new Array(t.length+1);for(let r=0;r<=t.length;r++)e[r]=r;for(let r=1;r<=n.length;r++){let s=e[0];e[0]=r;for(let o=1;o<=t.length;o++){let i=e[o];e[o]=n[r-1]===t[o-1]?s:1+Math.min(s,e[o],e[o-1]),s=i}}return e[t.length]}function Yr(n){let t=vt.map(r=>r.name).concat(Object.keys(St)),e=null;for(let r of t){let s=zr(n,r);s<=2&&(!e||s<e.d)&&(e={name:r,d:s})}return e?.name??null}function Vr(n,t){let e=null;for(let r of t){let s=zr(n,r);s<=2&&(!e||s<e.d)&&(e={name:r,d:s})}return e?.name??null}function Zr(n){return JSON.stringify({error:n.error,...n.hint?{hint:n.hint}:{},exit:n.exit??1})}function Dn(n){let t=[z.red("error: ")+n.error];return n.hint&&t.push(z.dim(" hint: ")+n.hint),t.join(`
152
+ `)}var Qr=vt.map(n=>n.name).concat(Object.keys(St)).sort().join(" ");function Zi(){return`#!/usr/bin/env bash
152
153
  # daimon bash completion
153
154
  # install: source <(daimon completion bash) (or copy to /etc/bash_completion.d/daimon)
154
155
  _daimon_complete() {
@@ -156,7 +157,7 @@ _daimon_complete() {
156
157
  COMPREPLY=()
157
158
  cur="\${COMP_WORDS[COMP_CWORD]}"
158
159
  prev="\${COMP_WORDS[COMP_CWORD-1]}"
159
- verbs="${Ur}"
160
+ verbs="${Qr}"
160
161
  if [ "$COMP_CWORD" -eq 1 ]; then
161
162
  COMPREPLY=( $(compgen -W "$verbs" -- "$cur") )
162
163
  return 0
@@ -174,12 +175,12 @@ _daimon_complete() {
174
175
  COMPREPLY=( $(compgen -W "--full --compact --stream --explain --tag --workspace --since --until --timeout --tail --app --budget --dry-run --yes --no-color --no-spawn --help" -- "$cur") )
175
176
  }
176
177
  complete -F _daimon_complete daimon
177
- `}function Fi(){return`#compdef daimon
178
+ `}function Qi(){return`#compdef daimon
178
179
  # daimon zsh completion
179
180
  # install: daimon completion zsh > "\${fpath[1]}/_daimon" (or source it from .zshrc)
180
181
  _daimon() {
181
182
  local -a verbs
182
- verbs=(${mt.map(n=>`'${n.name}:${n.summary.replace(/'/g,"''").replace(/:/g,"\\:").slice(0,80)}'`).join(" ")})
183
+ verbs=(${vt.map(n=>`'${n.name}:${n.summary.replace(/'/g,"''").replace(/:/g,"\\:").slice(0,80)}'`).join(" ")})
183
184
  if (( CURRENT == 2 )); then
184
185
  _describe 'command' verbs
185
186
  return
@@ -204,15 +205,15 @@ _daimon() {
204
205
  '--help[help]'
205
206
  }
206
207
  compdef _daimon daimon
207
- `}function Bi(){let n=["# daimon fish completion"];n.push("# install: daimon completion fish > ~/.config/fish/completions/daimon.fish"),n.push("complete -c daimon -f");for(let t of mt){let e=t.summary.replace(/'/g,"\\'").slice(0,100);n.push(`complete -c daimon -n "__fish_use_subcommand" -a "${t.name}" -d '${e}'`)}for(let t of Object.keys(ht))n.push(`complete -c daimon -n "__fish_use_subcommand" -a "${t}" -d 'alias \u2192 ${ht[t]}'`);for(let t of["--full","--compact","--stream","--explain","--dry-run","--yes","--no-color","--no-spawn","--help"])n.push(`complete -c daimon -l ${t.replace(/^--/,"")}`);for(let t of["tag","workspace","since","until","timeout","tail","app","budget"])n.push(`complete -c daimon -l ${t} -x`);return n.join(`
208
+ `}function ta(){let n=["# daimon fish completion"];n.push("# install: daimon completion fish > ~/.config/fish/completions/daimon.fish"),n.push("complete -c daimon -f");for(let t of vt){let e=t.summary.replace(/'/g,"\\'").slice(0,100);n.push(`complete -c daimon -n "__fish_use_subcommand" -a "${t.name}" -d '${e}'`)}for(let t of Object.keys(St))n.push(`complete -c daimon -n "__fish_use_subcommand" -a "${t}" -d 'alias \u2192 ${St[t]}'`);for(let t of["--full","--compact","--stream","--explain","--dry-run","--yes","--no-color","--no-spawn","--help"])n.push(`complete -c daimon -l ${t.replace(/^--/,"")}`);for(let t of["tag","workspace","since","until","timeout","tail","app","budget"])n.push(`complete -c daimon -l ${t} -x`);return n.join(`
208
209
  `)+`
209
- `}function Ui(){return`# daimon PowerShell completion
210
+ `}function ea(){return`# daimon PowerShell completion
210
211
  # install: daimon completion powershell | Out-String | Invoke-Expression
211
212
  # permanent: add the same line to $PROFILE
212
213
  Register-ArgumentCompleter -Native -CommandName daimon -ScriptBlock {
213
214
  param($wordToComplete, $commandAst, $cursorPosition)
214
215
  $tokens = $commandAst.CommandElements
215
- $verbs = @(${Ur.split(" ").map(t=>`'${t}'`).join(",")})
216
+ $verbs = @(${Qr.split(" ").map(t=>`'${t}'`).join(",")})
216
217
  if ($tokens.Count -le 1) {
217
218
  $verbs | Where-Object { $_ -like "$wordToComplete*" } |
218
219
  ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
@@ -234,20 +235,24 @@ Register-ArgumentCompleter -Native -CommandName daimon -ScriptBlock {
234
235
  $flags | Where-Object { $_ -like "$wordToComplete*" } |
235
236
  ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_) }
236
237
  }
237
- `}function Hr(n){switch(n){case"bash":return{ok:!0,script:Ii()};case"zsh":return{ok:!0,script:Fi()};case"fish":return{ok:!0,script:Bi()};case"powershell":case"pwsh":case"ps":return{ok:!0,script:Ui()};default:return{ok:!1,error:`unknown shell: ${n}`}}}Et();import it from"node:fs";import Hi from"node:os";import tt from"node:path";import{fileURLToPath as Ji}from"node:url";bt();var Jr=tt.dirname(Ji(import.meta.url)),qr=["status","start","stop","restart","errors","logs","up","doctor","why","wait"],Wi=["daimon-status.md","daimon-start.md","daimon-stop.md","daimon-restart.md","daimon-errors.md","daimon-logs.md","daimon-up.md","daimon-doctor.md","daimon-why.md","daimon-wait.md"];function me(){return tt.join(Hi.homedir(),".claude")}function ne(n){return tt.join(n,"daimon.installed.json")}function Gi(){let n=[tt.resolve(Jr,"templates","claude"),tt.resolve(Jr,"..","src","templates","claude")];for(let t of n)if(it.existsSync(t))return t;throw new Error("claude templates directory not found")}function Wr(n){return it.readFileSync(tt.join(Gi(),n),"utf8")}function Gr(n,t){let e=new Date().toISOString();return n.replace(/\{\{daimon_version\}\}/g,Z).replace(/\{\{api_port\}\}/g,String(t)).replace(/\{\{generated_at\}\}/g,e).replace(/\{\{commands_table\}\}/g,$r())}function Cn(n,t){it.mkdirSync(tt.dirname(n),{recursive:!0}),it.writeFileSync(n,t,"utf8")}function Ht(n){try{let t=it.readFileSync(ne(n),"utf8");return t.charCodeAt(0)===65279&&(t=t.slice(1)),JSON.parse(t)}catch{return null}}function Xr(n,t){Cn(ne(n),JSON.stringify(t,null,2)+`
238
- `)}function qi(n){let t=[],e=[],r=n.priorInstalledAt?Date.parse(n.priorInstalledAt):0;for(let s of Wi){let o=tt.join(n.dir,"commands",s),i;try{i=it.statSync(o)}catch{continue}if(!i.isFile())continue;let a=r>0?i.mtimeMs>r+5e3:!1;try{a?(it.renameSync(o,o+".bak"),e.push(s),n.onEvent?.({kind:"backed-up",file:s})):(it.rmSync(o,{force:!0}),t.push(s),n.onEvent?.({kind:"removed",file:s}))}catch{}}return{removed:t,backedUp:e}}function Me(n){let t=[],e=Ht(n.dir),r=e??{"daimon-version":Z,"installed-at":new Date().toISOString()};r["daimon-version"]=Z,r["installed-at"]=new Date().toISOString();let s=qi({dir:n.dir,priorInstalledAt:e?.["installed-at"],onEvent:n.onMigrationEvent});if(r.commands=[],(s.removed.length||s.backedUp.length)&&(r.migrated={removedCommands:s.removed,backedUpCommands:s.backedUp}),n.skill){let o=tt.join("skills","daimon","SKILL.md");Cn(tt.join(n.dir,o),Gr(Wr("skill.md.tmpl"),n.apiPort)),r.skill={path:o.replace(/\\/g,"/")},t.push(o)}if(n.agent){let o=tt.join("agents","daimon-runner.md");Cn(tt.join(n.dir,o),Gr(Wr("agent.md.tmpl"),n.apiPort)),r.agent={path:o.replace(/\\/g,"/")},t.push(o)}return Xr(n.dir,r),{installed:t,manifestPath:ne(n.dir),migrated:s}}function Kr(n){let t=[],e=Ht(n.dir);if(!e)return{removed:t,manifestPath:null};let r=n.selection.all;if((r||n.selection.skill)&&e.skill){let s=tt.join(n.dir,e.skill.path);try{it.rmSync(s,{force:!0}),t.push(e.skill.path)}catch{}try{it.rmdirSync(tt.dirname(s))}catch{}e.skill=null}if((r||n.selection.commands)&&e.commands){for(let s of e.commands){let o=tt.join("commands",`daimon-${s}.md`);try{it.rmSync(tt.join(n.dir,o),{force:!0}),t.push(o)}catch{}}e.commands=[]}if((r||n.selection.agent)&&e.agent){try{it.rmSync(tt.join(n.dir,e.agent.path),{force:!0}),t.push(e.agent.path)}catch{}e.agent=null}if(!e.skill&&(!e.commands||e.commands.length===0)&&!e.agent){try{it.unlinkSync(ne(n.dir))}catch{}return{removed:t,manifestPath:null}}return Xr(n.dir,e),{removed:t,manifestPath:ne(n.dir)}}function zr(n){let t=Ht(n);return t?{skill:{installed:!!t.skill,version:t.skill?t["daimon-version"]:null,path:t.skill?.path??null},commands:{installed:!!(t.commands&&t.commands.length),version:t.commands&&t.commands.length?t["daimon-version"]:null,names:t.commands??[]},agent:{installed:!!t.agent,version:t.agent?t["daimon-version"]:null,path:t.agent?.path??null},manifestPath:ne(n)}:{skill:{installed:!1,version:null,path:null},commands:{installed:!1,version:null,names:[]},agent:{installed:!1,version:null,path:null},manifestPath:null}}var Tn=tt.join(ut(),".claude-nudge"),Xi=1440*60*1e3;function Yr(){if(process.env.DAIMON_NO_CLAUDE_NUDGE==="1")return;let n=me(),t=Ht(n);if(t&&t["daimon-version"]!==Z){try{let e=it.statSync(Tn);if(Date.now()-e.mtimeMs<Xi)return}catch{}process.stderr.write(`[daimon] claude integration is from v${t["daimon-version"]} \u2014 run \`daimon claude update\` to refresh
239
- `);try{it.mkdirSync(tt.dirname(Tn),{recursive:!0}),it.writeFileSync(Tn,String(Date.now()))}catch{}}}var ii=Number((process.versions.node||"0").split(".")[0]);ii&&ii<20&&(process.stderr.write(`daimon requires Node >= 20
240
- `),process.exit(1));var pi=!1,cr=!1;function M(n,t=1){if(n.startsWith("{"))try{let e=JSON.parse(n),r=typeof e.exit=="number"?e.exit:t;Ne()?process.stderr.write(xn({error:e.error??n,hint:e.hint})+`
238
+ `}function ts(n){switch(n){case"bash":return{ok:!0,script:Zi()};case"zsh":return{ok:!0,script:Qi()};case"fish":return{ok:!0,script:ta()};case"powershell":case"pwsh":case"ps":return{ok:!0,script:ea()};default:return{ok:!1,error:`unknown shell: ${n}`}}}_t();import pt from"node:fs";import na from"node:os";import ot from"node:path";import{fileURLToPath as ra}from"node:url";Pt();var es=ot.dirname(ra(import.meta.url)),ss=["status","start","stop","restart","errors","logs","up","doctor","why","wait"],sa=["daimon-status.md","daimon-start.md","daimon-stop.md","daimon-restart.md","daimon-errors.md","daimon-logs.md","daimon-up.md","daimon-doctor.md","daimon-why.md","daimon-wait.md"];function Te(){return ot.join(na.homedir(),".claude")}function le(n){return ot.join(n,"daimon.installed.json")}function oa(){let n=[ot.resolve(es,"templates","claude"),ot.resolve(es,"..","src","templates","claude")];for(let t of n)if(pt.existsSync(t))return t;throw new Error("claude templates directory not found")}function ns(n){return pt.readFileSync(ot.join(oa(),n),"utf8")}function rs(n,t){let e=new Date().toISOString();return n.replace(/\{\{daimon_version\}\}/g,st).replace(/\{\{api_port\}\}/g,String(t)).replace(/\{\{generated_at\}\}/g,e).replace(/\{\{commands_table\}\}/g,qr())}function In(n,t){pt.mkdirSync(ot.dirname(n),{recursive:!0}),pt.writeFileSync(n,t,"utf8")}function zt(n){try{let t=pt.readFileSync(le(n),"utf8");return t.charCodeAt(0)===65279&&(t=t.slice(1)),JSON.parse(t)}catch{return null}}function os(n,t){In(le(n),JSON.stringify(t,null,2)+`
239
+ `)}function ia(n){let t=[],e=[],r=n.priorInstalledAt?Date.parse(n.priorInstalledAt):0;for(let s of sa){let o=ot.join(n.dir,"commands",s),i;try{i=pt.statSync(o)}catch{continue}if(!i.isFile())continue;let a=r>0?i.mtimeMs>r+5e3:!1;try{a?(pt.renameSync(o,o+".bak"),e.push(s),n.onEvent?.({kind:"backed-up",file:s})):(pt.rmSync(o,{force:!0}),t.push(s),n.onEvent?.({kind:"removed",file:s}))}catch{}}return{removed:t,backedUp:e}}function Ge(n){let t=[],e=zt(n.dir),r=e??{"daimon-version":st,"installed-at":new Date().toISOString()};r["daimon-version"]=st,r["installed-at"]=new Date().toISOString();let s=ia({dir:n.dir,priorInstalledAt:e?.["installed-at"],onEvent:n.onMigrationEvent});if(r.commands=[],(s.removed.length||s.backedUp.length)&&(r.migrated={removedCommands:s.removed,backedUpCommands:s.backedUp}),n.skill){let o=ot.join("skills","daimon","SKILL.md");In(ot.join(n.dir,o),rs(ns("skill.md.tmpl"),n.apiPort)),r.skill={path:o.replace(/\\/g,"/")},t.push(o)}if(n.agent){let o=ot.join("agents","daimon-runner.md");In(ot.join(n.dir,o),rs(ns("agent.md.tmpl"),n.apiPort)),r.agent={path:o.replace(/\\/g,"/")},t.push(o)}return os(n.dir,r),{installed:t,manifestPath:le(n.dir),migrated:s}}function is(n){let t=[],e=zt(n.dir);if(!e)return{removed:t,manifestPath:null};let r=n.selection.all;if((r||n.selection.skill)&&e.skill){let s=ot.join(n.dir,e.skill.path);try{pt.rmSync(s,{force:!0}),t.push(e.skill.path)}catch{}try{pt.rmdirSync(ot.dirname(s))}catch{}e.skill=null}if((r||n.selection.commands)&&e.commands){for(let s of e.commands){let o=ot.join("commands",`daimon-${s}.md`);try{pt.rmSync(ot.join(n.dir,o),{force:!0}),t.push(o)}catch{}}e.commands=[]}if((r||n.selection.agent)&&e.agent){try{pt.rmSync(ot.join(n.dir,e.agent.path),{force:!0}),t.push(e.agent.path)}catch{}e.agent=null}if(!e.skill&&(!e.commands||e.commands.length===0)&&!e.agent){try{pt.unlinkSync(le(n.dir))}catch{}return{removed:t,manifestPath:null}}return os(n.dir,e),{removed:t,manifestPath:le(n.dir)}}function as(n){let t=zt(n);return t?{skill:{installed:!!t.skill,version:t.skill?t["daimon-version"]:null,path:t.skill?.path??null},commands:{installed:!!(t.commands&&t.commands.length),version:t.commands&&t.commands.length?t["daimon-version"]:null,names:t.commands??[]},agent:{installed:!!t.agent,version:t.agent?t["daimon-version"]:null,path:t.agent?.path??null},manifestPath:le(n)}:{skill:{installed:!1,version:null,path:null},commands:{installed:!1,version:null,names:[]},agent:{installed:!1,version:null,path:null},manifestPath:null}}var Ln=ot.join(mt(),".claude-nudge"),aa=1440*60*1e3;function cs(){if(process.env.DAIMON_NO_CLAUDE_NUDGE==="1")return;let n=Te(),t=zt(n);if(t&&t["daimon-version"]!==st){try{let e=pt.statSync(Ln);if(Date.now()-e.mtimeMs<aa)return}catch{}process.stderr.write(`[daimon] claude integration is from v${t["daimon-version"]} \u2014 run \`daimon claude update\` to refresh
240
+ `);try{pt.mkdirSync(ot.dirname(Ln),{recursive:!0}),pt.writeFileSync(Ln,String(Date.now()))}catch{}}}var ki=Number((process.versions.node||"0").split(".")[0]);ki&&ki<20&&(process.stderr.write(`daimon requires Node >= 20
241
+ `),process.exit(1));var Ci=!1,Tr=!1;function _(n,t=1){if(n.startsWith("{"))try{let e=JSON.parse(n),r=typeof e.exit=="number"?e.exit:t;qe()?process.stderr.write(Dn({error:e.error??n,hint:e.hint})+`
241
242
  `):process.stderr.write(JSON.stringify({error:e.error,...e.hint?{hint:e.hint}:{},exit:r})+`
242
243
  `),process.exit(r)}catch{}process.stderr.write(n.endsWith(`
243
244
  `)?n:n+`
244
- `),process.exit(t)}function ct(n,t,e=1){Ne()?process.stderr.write(xn({error:n,hint:t})+`
245
- `):process.stderr.write(Br({error:n,hint:t,exit:e})+`
246
- `),process.exit(e)}function N(n){process.stdout.write(JSON.stringify(n)+`
247
- `)}async function ai(n){let t=[];try{let s=await fetch(ue()+"/api/apps",{headers:gt()});if(s.ok){let o=await s.json();Array.isArray(o)&&(t=o.map(i=>i.name).filter(Boolean))}}catch{}let e=Fr(n,t),r=e?`did you mean '${e}'? \u2014 list apps with \`daimon list\``:"list available with `daimon list`";ct(`unknown app: ${n}`,r)}function ur(){if(process.env.DAIMON_PORT){let t=Number(process.env.DAIMON_PORT);if(Number.isFinite(t)&&t>0)return t}let n=ot();if(n)return n.apiPort;try{let t=st();if(t.kind==="loaded")return t.config.apiPort}catch{}return 4999}async function eu(){try{let n=st();if(n.kind==="loaded")return{config:n.config}}catch{}return{config:{}}}function ue(){return`http://127.0.0.1:${ur()}`}async function Nt(){if(!(pi||process.env.DAIMON_NO_SPAWN==="1")&&!ot())try{let n=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0;await Pt({port:Number.isFinite(n)&&n>0?n:void 0})}catch{}}function gt(){let n=process.env.DAIMON_TOKEN;return n?{authorization:`Bearer ${n}`}:{}}async function lr(n,t="GET"){try{let e=await fetch(ue()+n,{method:t,headers:gt()});(!e.ok||!e.body)&&M(JSON.stringify({error:`stream failed: HTTP ${e.status}`}));let r=e.body.getReader(),s=new TextDecoder,o="";for(;;){let{done:i,value:a}=await r.read();if(i)break;o+=s.decode(a,{stream:!0});let l=o.split(`
248
- `);o=l.pop()??"";for(let c of l)c.trim()&&process.stdout.write(c+`
245
+ `),process.exit(t)}function ut(n,t,e=1){qe()?process.stderr.write(Dn({error:n,hint:t})+`
246
+ `):process.stderr.write(Zr({error:n,hint:t,exit:e})+`
247
+ `),process.exit(e)}function M(n){process.stdout.write(JSON.stringify(n)+`
248
+ `)}async function xi(n){let t=[];try{let s=await fetch(te()+"/api/apps",{headers:bt()});if(s.ok){let o=await s.json();Array.isArray(o)&&(t=o.map(i=>i.name).filter(Boolean))}}catch{}let e=Vr(n,t),r=e?`did you mean '${e}'? \u2014 list apps with \`daimon list\``:"list available with `daimon list`";ut(`unknown app: ${n}`,r)}function bn(){if(process.env.DAIMON_PORT){let t=Number(process.env.DAIMON_PORT);if(Number.isFinite(t)&&t>0)return t}let n=ct();if(n)return n.apiPort;try{let t=at();if(t.kind==="loaded")return t.config.apiPort}catch{}return 4999}async function bu(){try{let n=at();if(n.kind==="loaded")return{config:n.config}}catch{}return{config:{}}}function te(){return`http://127.0.0.1:${bn()}`}async function Et(){if(!(Ci||process.env.DAIMON_NO_SPAWN==="1")&&!ct())try{let n=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0;await Dt({port:Number.isFinite(n)&&n>0?n:void 0})}catch{}}async function Qt(){try{let n=await fetch(te()+"/api/workspaces/ensure",{method:"POST",headers:{"content-type":"application/json",...bt()},body:JSON.stringify({path:process.cwd()})})}catch{}}function bt(){let n=process.env.DAIMON_TOKEN,t={"x-daimon-cwd":process.cwd()};return n&&(t.authorization=`Bearer ${n}`),t}async function Pr(n,t="GET"){try{let e=await fetch(te()+n,{method:t,headers:bt()});(!e.ok||!e.body)&&_(JSON.stringify({error:`stream failed: HTTP ${e.status}`}));let r=e.body.getReader(),s=new TextDecoder,o="";for(;;){let{done:i,value:a}=await r.read();if(i)break;o+=s.decode(a,{stream:!0});let c=o.split(`
249
+ `);o=c.pop()??"";for(let l of c)l.trim()&&process.stdout.write(l+`
249
250
  `)}o.trim()&&process.stdout.write(o+`
250
- `)}catch(e){M(JSON.stringify({error:e?.message||String(e)}))}}async function G(n,t="GET"){try{let e=await fetch(ue()+n,{method:t,headers:gt()}),r=await e.text(),s=r;try{s=JSON.parse(r)}catch{}return{status:e.status,body:s}}catch{ct("daimon is not running","start it with: daimon daemon start --detach")}}async function nn(n,t,e){try{let r=await fetch(ue()+n,{method:t,headers:{"content-type":"application/json",...gt()},body:JSON.stringify(e)}),s=await r.text(),o=s;try{o=JSON.parse(s)}catch{}return{status:r.status,body:o}}catch{ct("daimon is not running","start it with: daimon daemon start --detach")}}function sn(n){let t={tags:[],positional:[],passthrough:[]},e=!1;for(let r=0;r<n.length;r++){let s=n[r];if(e){t.passthrough.push(s);continue}if(s==="--"){e=!0;continue}s==="--tail"?t.tail=Number(n[++r]):s==="--since"?t.since=n[++r]:s==="--since-last"?t.sinceLast=!0:s==="--client"?t.client=n[++r]:s==="--structured"?t.structured=!0:s==="--until"?t.until=n[++r]:s==="--timeout"?t.timeout=n[++r]:s==="--app"?t.app=n[++r]:s==="--tag"?t.tags.push(n[++r]):s==="--with-deps"?t.withDeps=!0:s==="--watch"?t.watch=!0:s==="--force"?t.force=!0:s==="--yes"?t.yes=!0:s==="--deep"?t.deep=!0:s==="--use"?t.use=n[++r]:s==="--speed"?t.speed=Number(n[++r]):s==="--task"?t.task=n[++r]:s==="--headless"?t.headless=!0:s==="--detach"?t.detach=!0:s==="--workspace"?t.workspace=n[++r]:s==="--full"?t.full=!0:s==="--compact"?t.compact=!0:s==="--profile"?t.profile=n[++r]:s==="--stream"?t.stream=!0:s==="--explain"?t.explain=!0:s==="--auto-fix"?t.autoFix=!0:s==="--dry-run"?t.dryRun=!0:s==="--auto"?t.auto=!0:s==="--redacted"?t.redacted=!0:s==="--budget"?t.budget=Number(n[++r]):s==="--accept"?t.accept=!0:s==="--path"?t.path=n[++r]:s==="--goal"?t.goal=n[++r]:s==="--self"?t.self=!0:t.positional.push(s)}return t}function nu(n){return n.full?"?format=full":n.compact?"?format=compact":""}function le(n){let t=n.match(/^(\d+)(ms|s|m|h)?$/);if(!t)return null;let e=Number(t[1]);switch(t[2]||"s"){case"ms":return e/1e3;case"s":return e;case"m":return e*60;case"h":return e*60*60}return null}function rn(){process.stdout.write(_r()+`
251
- `)}function ci(n){let t=Oe(n);return t?(process.stdout.write(Dr(t)+`
252
- `),!0):!1}function ru(){let n=ot(),t=null;try{let s=st();s.kind==="loaded"&&(t=s.path)}catch{}let e=ui.join(li.homedir(),".daimon","lock.json"),r=[];try{let s=Ht(me());s&&(s.skill&&r.push("skill"),s.agent&&r.push("agent"),Array.isArray(s.commands)&&s.commands.length&&r.push("commands"))}catch{}N({version:Z,nodeVersion:process.versions.node,platform:process.platform,configPath:t,lockPath:e,running:!!n,runningPid:n?.pid??null,runningPort:n?.apiPort??null,claudeArtifacts:r})}function su(n){let t={},e=[];for(let r=0;r<n.length;r++){let s=n[r];s==="--skill"?t.skill=!0:s==="--commands"?t.commands=!0:s==="--agent"?t.agent=!0:s==="--all"?t.all=!0:s==="--dir"?t.dir=n[++r]:s==="--yes"?t.yes=!0:e.push(s)}return{positional:e,flags:t}}async function ou(n){let t=n[0];t||M(JSON.stringify({error:"usage: daimon claude <install|update|uninstall|status> [--skill] [--commands] [--agent] [--all] [--dir <path>] [--yes]"}));let{flags:e}=su(n.slice(1)),r=e.dir??me(),s=ur();if(t==="status"){N(zr(r));return}if(t==="install"){let o,i=e.skill||e.commands||e.agent||e.all;if(e.all||e.yes||!i&&!process.stdin.isTTY)o={skill:!0,commands:!1,agent:!0};else if(i)o={skill:!!e.skill,commands:!1,agent:!!e.agent};else{let{promptClaudeInstall:l}=await Promise.resolve().then(()=>(ts(),Qr)),c=await l();if(!c){N({cancelled:!0});return}o={skill:c.skill,commands:!1,agent:c.agent}}let a=Me({...o,dir:r,apiPort:s,onMigrationEvent:l=>{l.kind==="removed"?N({removed:l.file}):N({warning:`${l.file} was modified; backing up to ${l.file}.bak`})}});N({installed:a.installed,manifest:a.manifestPath,version:Z});return}if(t==="update"){let o=Ht(r);o||M(JSON.stringify({error:"no manifest at "+r+" \u2014 run `daimon claude install` first"}));let i={skill:!!o.skill,commands:!1,agent:!!o.agent},a=Me({...i,dir:r,apiPort:s,onMigrationEvent:l=>{l.kind==="removed"?N({removed:l.file}):N({warning:`${l.file} was modified; backing up to ${l.file}.bak`})}});N({updated:a.installed,manifest:a.manifestPath,version:Z});return}if(t==="uninstall"){e.skill||e.commands||e.agent||e.all||M(JSON.stringify({error:"usage: daimon claude uninstall [--all|--skill|--commands|--agent]"}));let i=Kr({dir:r,selection:{all:e.all,skill:e.skill,commands:e.commands,agent:e.agent}});N({removed:i.removed,manifest:i.manifestPath});return}M(JSON.stringify({error:`unknown claude subcommand: ${t}`}))}async function iu(n){let t=n[0],e=sn(n.slice(1));switch(t){case"status":{let r=ot();if(!r){N({running:!1});return}let s=Date.now()-r.startedAt;N({running:!0,pid:r.pid,port:r.apiPort,uptime:s,version:r.version,headless:r.headless});return}case"start":{if(e.detach){let s=ot();if(s){N({ok:!0,alreadyRunning:!0,pid:s.pid,port:s.apiPort});return}try{let o=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0,i=await Pt({port:Number.isFinite(o)&&o>0?o:void 0});N({ok:!0,pid:i.pid,port:i.apiPort})}catch(o){M(JSON.stringify({error:o?.message||String(o)}))}return}let{startInProcess:r}=await Promise.resolve().then(()=>(qo(),Go));await r({headless:!!e.headless});return}case"stop":{let r=ot();if(!r){N({ok:!0,wasRunning:!1});return}try{await fetch(`http://127.0.0.1:${r.apiPort}/api/shutdown`,{method:"POST",headers:gt()})}catch{}if(await Bt(r.pid,5e3))wt(),N({ok:!0,wasRunning:!0});else{try{process.kill(r.pid,"SIGTERM")}catch{}await Bt(r.pid,2e3),wt(),N({ok:!0,wasRunning:!0,forced:!0})}return}case"restart":{let r=ot();if(r){try{await fetch(`http://127.0.0.1:${r.apiPort}/api/snapshot-state`,{method:"POST",headers:gt()})}catch{}try{await fetch(`http://127.0.0.1:${r.apiPort}/api/shutdown`,{method:"POST",headers:gt()})}catch{}await Bt(r.pid,5e3),wt()}let s=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0,o=await Pt({port:Number.isFinite(s)&&s>0?s:void 0});N({ok:!0,pid:o.pid,port:o.apiPort,handoff:!0});return}case"attach":{await Nt();let r=ot();r||M(JSON.stringify({error:"no daemon running and auto-spawn failed"}));let{attachToDaemon:s}=await Promise.resolve().then(()=>(Yo(),zo));await s(r.apiPort);return}case"install-service":{let{installServiceArtifact:r}=await Promise.resolve().then(()=>(ei(),ti)),s=r();N({platform:s.platform,artifact:s.path,installCmd:s.installCmd});return}default:M(JSON.stringify({error:"usage: daimon daemon <start|stop|status|restart|attach|install-service> [--detach] [--headless]"}))}}async function au(){let n=process.argv.slice(2).filter(o=>o==="--no-spawn"?(pi=!0,!1):o==="--no-color"?(jr("off"),!1):o==="--help"||o==="-h"?(cr=!0,!1):!0),[t,...e]=n;try{Yr()}catch{}if(!t&&cr){rn();return}if(!t){rn();return}if(t==="help"){let o=e[0];if(o&&ci(o))return;rn();return}if(t==="--version"||t==="-v"){process.stdout.write(Z+`
253
- `);return}if(t==="--about"){ru();return}if(ht[t]&&(t=ht[t]),cr){if(ci(t))return;rn();return}if(t==="completion"){let o=e[0];o||ct("missing shell","usage: daimon completion <bash|zsh|fish|powershell>");let i=Hr(o);i.ok||ct(i.error,"supported shells: bash, zsh, fish, powershell"),process.stdout.write(i.script);return}if(t==="self"){await Nt();let o=await G("/api/self");o.status===404&&ct("self endpoint not available","daemon may be from an older daimon version \u2014 run `daimon daemon restart`"),N(o.body);return}if(t==="plugin"){let o=e[0];if(o||ct("missing subcommand","usage: daimon plugin <list|show <name>|validate <path>>"),o==="list"){await Nt();let i=await G("/api/plugins");N(i.body);return}if(o==="show"){let i=e[1];i||ct("missing plug-in name","usage: daimon plugin show <name>"),await Nt();let a=await G("/api/plugins"),c=(Array.isArray(a.body)?a.body:[]).find(d=>d.name===i);c||ct(`unknown plug-in: ${i}`,"list installed plug-ins with: daimon plugin list"),N(c);return}if(o==="validate"){let i=e[1];i||ct("missing file path","usage: daimon plugin validate <path>");let{validatePluginFile:a}=await Promise.resolve().then(()=>(tr(),_o)),l=await a(ui.resolve(i));N(l),l.ok||process.exit(1);return}ct(`unknown plugin subcommand: ${o}`,"usage: daimon plugin <list|show <name>|validate <path>>")}if(t==="daemon"){await iu(e);return}if(t==="claude"){await ou(e);return}if(t==="export-config"){let o=st();o.kind!=="loaded"&&M(JSON.stringify({error:"no config loaded"}));let i=sn(e),a=JSON.parse(JSON.stringify(o.config));if(i.redacted){let l=li.homedir().replace(/\\/g,"/"),c=d=>{if(typeof d!="string")return d;let u=d.replace(/\\/g,"/");return u.toLowerCase().startsWith(l.toLowerCase())?"~"+u.slice(l.length):d};a.apiToken!=null&&a.apiToken!==""&&(a.apiToken="<redacted>"),a.history?.path&&(a.history.path=c(a.history.path)),a.logs?.dir&&(a.logs.dir=c(a.logs.dir)),Array.isArray(a.searchRoots)&&(a.searchRoots=a.searchRoots.map(d=>typeof d=="string"?c(d):{...d,path:c(d.path)}))}N(a);return}if(t==="discover"){await Nt();let o=await G("/api/discovery/explain");o.status!==200&&M(JSON.stringify({error:"discovery failed",status:o.status})),N(o.body);return}if(t==="init"){let{runInit:o}=await Promise.resolve().then(()=>(oi(),si)),i=sn(e);try{let a=await o({force:!!i.force,auto:!!i.auto});if(N({path:a.path,installClaude:a.installClaude,auto:a.auto}),a.installClaude){let c=ur(),d=Me({skill:!0,commands:!1,agent:!0,dir:me(),apiPort:c,onMigrationEvent:u=>{u.kind==="removed"?N({removed:u.file}):N({warning:`${u.file} was modified; backing up to ${u.file}.bak`})}});N({claudeInstalled:d.installed})}let l=ot();if(l){try{await fetch(`http://127.0.0.1:${l.apiPort}/api/snapshot-state`,{method:"POST",headers:gt()})}catch{}try{await fetch(`http://127.0.0.1:${l.apiPort}/api/shutdown`,{method:"POST",headers:gt()})}catch{}await Bt(l.pid,5e3),wt();try{let c=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0,d=await Pt({port:Number.isFinite(c)&&c>0?c:void 0});N({daemonRestarted:!0,pid:d.pid,port:d.apiPort})}catch(c){N({daemonRestarted:!1,error:c?.message||String(c)})}}try{await Nt();let c=await fetch(ue()+"/api/discovery/explain",{headers:gt()});if(c.ok){let d=await c.json(),u={};try{let m=await(await fetch(ue()+"/api/apps?format=full",{headers:gt()})).json();if(Array.isArray(m))for(let h of m){let f=h.workspaceType??"unknown";u[f]=(u[f]??0)+1}}catch{}let g=d.appsFound??0,y={init:"ok",configPath:a.path,discovered:{apps:g,byKind:u}};g===0&&(y._meta={searchRoots:d.searchRoots,scanned:d.scanned,rejected:d.rejected,suggestion:d.suggestion},y.warning="discovery found 0 apps; see _meta.suggestion"),N(y)}}catch{}}catch(a){M(JSON.stringify({error:a?.message||String(a)}))}return}let r=sn(e);switch(Oe(t)?.needsDaemon&&await Nt(),t){case"list":{let o=r.full||(r.tags.length||r.workspace)&&!r.compact,i=new URLSearchParams;if(o?i.set("format","full"):r.compact&&i.set("format","compact"),r.explain&&i.set("explain","1"),r.stream){i.set("stream","ndjson");let d=i.toString();await lr("/api/apps"+(d?"?"+d:""));return}let a=i.toString(),l=await G("/api/apps"+(a?"?"+a:""));if(r.explain){N(l.body);return}let c=Array.isArray(l.body)?l.body:[];r.tags.length&&(c=c.filter(d=>r.tags.every(u=>(d.tags||[]).includes(u)))),r.workspace&&(c=c.filter(d=>d.workspaceLabel===r.workspace)),N(c);return}case"why-empty":{let o=await G("/api/apps?explain=1");N(o.body);return}case"status":case"stop":case"restart":{let o=r.positional[0];o||ct("missing app name",`usage: daimon ${t} <name>`);let i=t==="status"?"":"/"+t,a=t==="status"?"GET":"POST",l=t==="status"?nu(r):"",c=await G(`/api/apps/${encodeURIComponent(o)}${i}${l}`,a);c.status===404&&await ai(o),N(c.body);return}case"start":{let o=r.positional[0];o||ct("missing app name","usage: daimon start <name> [--with-deps]");let i=r.withDeps?"?withDeps=1":"",a=await G(`/api/apps/${encodeURIComponent(o)}/start${i}`,"POST");a.status===404&&await ai(o),N(a.body);return}case"history":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon history <name>"}));let i=await G(`/api/history/summary/${encodeURIComponent(o)}`);N(i.body);return}case"why":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon why <name>"}));let i=await G(`/api/history/why/${encodeURIComponent(o)}`);N(i.body);return}case"env":{let o=r.positional[0];if(o||M(JSON.stringify({error:"usage: daimon env <name> [--use <file>]"})),r.use){let a=await nn(`/api/apps/${encodeURIComponent(o)}/env`,"POST",{use:r.use});a.status===404&&M(JSON.stringify({error:"unknown app"})),N(a.body);return}let i=await G(`/api/apps/${encodeURIComponent(o)}/env`);i.status===404&&M(JSON.stringify({error:"unknown app"})),N(i.body);return}case"clean":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon clean <name> [--deep] [--yes]"}));let i=new URLSearchParams;r.deep&&i.set("deep","1"),r.yes&&i.set("yes","1");let a=await G(`/api/apps/${encodeURIComponent(o)}/clean${i.toString()?"?"+i.toString():""}`,"POST");a.status===404&&M(JSON.stringify({error:"unknown app"})),a.status===409&&(N(a.body),process.exit(1)),N(a.body);return}case"record":{let o=await G("/api/session/record?action=toggle","POST");N(o.body);return}case"replay":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon replay <session.jsonl> [--speed N]"}));let i=r.speed&&r.speed>0?r.speed:1,a;try{a=Rr(o)}catch(c){M(JSON.stringify({error:c?.message||String(c)}))}let l=0;for(let c of a){let d=Math.max(0,(c.ts-l)/i);d>0&&await new Promise(u=>setTimeout(u,d)),l=c.ts,c.kind==="run"?await nn(`/api/apps/${encodeURIComponent(c.app)}/run/${encodeURIComponent(c.task||"")}`,"POST",{args:c.args||[]}):await G(`/api/apps/${encodeURIComponent(c.app)}/${c.kind}`,"POST")}N({replayed:a.length,file:o});return}case"doctor":{let o=st();if(o.kind!=="loaded"&&M(JSON.stringify({error:"no config loaded"})),r.self){await Nt();let c=await G("/api/self");c.status===503&&ct("self-metrics not available","daemon may need a restart: daimon daemon restart");let d=c.body??{},u=[],g=256,y=100,p=50;u.push({name:"heap",ok:d.heapUsedMB<g,detail:`heapUsed ${d.heapUsedMB}MB (warn at ${g}MB)`}),u.push({name:"event-loop-lag",ok:d.eventLoopLagP95Ms<y,detail:`p95 ${d.eventLoopLagP95Ms}ms (warn at ${y}ms)`}),u.push({name:"history-db-query",ok:(d.historyDbQueryMs?.p95??0)<p,detail:`p95 ${d.historyDbQueryMs?.p95??0}ms (warn at ${p}ms)`});let m=u.every(h=>h.ok);N({ok:m,checks:u,metrics:d}),m||process.exit(1);return}if(r.autoFix){let{runAutoFix:c,ALL_AUTO_FIX:d}=await Promise.resolve().then(()=>(se(),re)),u=o.config.doctor?.autoFix?.permitted??d,g=await c({permitted:u,dryRun:!!r.dryRun});N(g),g.errors.length&&process.exit(1);return}let i=[],a=It(o.config,{warnings:i}),l=await xr(o.config,a);for(let c of i)l.checks.unshift({name:`discovery: ${c}`,ok:!1,detail:c});i.length&&(l.ok=!1),N(l),l.ok||process.exit(1);return}case"free-port":{let o=Number(r.positional[0]);(!Number.isFinite(o)||o<=0)&&M(JSON.stringify({error:"usage: daimon free-port <port> [--force]"}));let i=Ce(o);if(!i){N({port:o,free:!0});return}if(!r.force){N({port:o,free:!1,holder:i});return}i.pid===process.pid&&M(JSON.stringify({error:"refuse to kill daimon itself",holder:i}));let a=await Er(i);N({port:o,killed:a,holder:i}),a||process.exit(1);return}case"snapshot":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon snapshot <name>"}));let i=await G(`/api/apps/${encodeURIComponent(o)}/snapshot?write=1`,"POST");i.status===404&&M(JSON.stringify({error:"unknown app"})),N(i.body);return}case"tasks":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon tasks <name>"}));let i=await G(`/api/apps/${encodeURIComponent(o)}/tasks`);i.status===404&&M(JSON.stringify({error:"unknown app"})),N(i.body);return}case"run":{let o=r.positional[0],i=r.positional[1];(!o||!i)&&M(JSON.stringify({error:"usage: daimon run <name> <task> [--watch] [-- args...]"}));let a={args:r.passthrough,watch:!!r.watch},l=await nn(`/api/apps/${encodeURIComponent(o)}/run/${encodeURIComponent(i)}`,"POST",a);l.status===404&&M(JSON.stringify({error:"unknown app"})),N(l.body),!r.watch&&typeof l.body?.exitCode=="number"&&process.exit(l.body.exitCode===0?0:1);return}case"errors":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon errors <name> [--since 2m] [--since-last] [--client <id>] [--structured] [--full|--compact]"}));let i=new URLSearchParams,a=`/api/apps/${encodeURIComponent(o)}/errors`;r.sinceLast?(a+="/since-last",r.client&&i.set("client",r.client)):r.since&&i.set("since",r.since),r.full?i.set("format","full"):r.compact&&i.set("format","compact");let l=i.toString(),c=await G(a+(l?"?"+l:""));c.status===404&&M(JSON.stringify({error:"unknown app"}));let d=c.body;r.structured&&Array.isArray(d)&&(d=d.map(u=>u.parsed??{message:u.message})),N(d);return}case"events":{let o=new URLSearchParams;if(r.since&&o.set("since",r.since),r.app&&o.set("app",r.app),r.stream){o.set("stream","ndjson");let l=o.toString();await lr("/api/events"+(l?"?"+l:""));return}let i=o.toString(),a=await G("/api/events"+(i?"?"+i:""));N(a.body);return}case"ensure":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon ensure <name> [--until serving|healthy] [--timeout 180s]"}));let i=new URLSearchParams,a=(r.until||"healthy").toLowerCase();a!=="serving"&&a!=="healthy"&&M(JSON.stringify({error:"ensure --until must be serving|healthy"})),i.set("until",a);let l=180;if(r.timeout){let d=le(r.timeout);d==null&&M(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),l=Math.min(d,600)}i.set("timeoutMs",String(Math.ceil(l*1e3)));let c=await G(`/api/apps/${encodeURIComponent(o)}/ensure?${i.toString()}`,"POST");c.status===404&&M(JSON.stringify({error:"unknown app"})),N(c.body),c.body?.error==="timeout"&&process.exit(2);return}case"ensure-up":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon ensure-up <profile> [--until serving|healthy] [--timeout 300s]"}));let i=new URLSearchParams,a=(r.until||"healthy").toLowerCase();a!=="serving"&&a!=="healthy"&&M(JSON.stringify({error:"ensure-up --until must be serving|healthy"})),i.set("until",a);let l=300;if(r.timeout){let u=le(r.timeout);u==null&&M(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),l=Math.min(u,1200)}i.set("timeoutMs",String(Math.ceil(l*1e3)));let c=await G(`/api/profiles/${encodeURIComponent(o)}/ensure-up?${i.toString()}`,"POST");c.status===404&&M(JSON.stringify({error:"unknown profile"})),N(c.body),Array.isArray(c.body?.apps)&&c.body.apps.some(u=>u.timedOut)&&process.exit(2);return}case"overview":{let o=new URLSearchParams;r.workspace&&o.set("workspace",r.workspace),r.profile&&o.set("profile",r.profile),r.budget&&Number.isFinite(r.budget)&&r.budget>0&&o.set("budget",String(Math.floor(r.budget)));let i=o.toString(),a=await G("/api/overview"+(i?"?"+i:""));N(a.body);return}case"focus":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon focus <name> [--until serving|healthy|stable] [--timeout 180s]"}));let i=new URLSearchParams,a=(r.until||"healthy").toLowerCase();["serving","healthy","stable"].includes(a)||M(JSON.stringify({error:"focus --until must be serving|healthy|stable"})),i.set("until",a);let l=180;if(r.timeout){let c=le(r.timeout);c==null&&M(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),l=Math.min(c,600)}i.set("timeoutMs",String(Math.ceil(l*1e3))),await lr(`/api/apps/${encodeURIComponent(o)}/focus?${i.toString()}`,"POST");return}case"pin-health":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon pin-health <name> [--accept] [--path <p>]"}));let i=await G(`/api/apps/${encodeURIComponent(o)}?format=full`);i.status===404&&M(JSON.stringify({error:"unknown app"}));let a=i.body?.discoveredHealthPath??null,l=r.path??a??null;if(!r.accept){N({app:o,discoveredHealthPath:a,candidate:l,hint:l?`re-run with --accept to persist ${l} to daimon.config.json`:"no path discovered yet; start the app and wait for first serving"});return}l||M(JSON.stringify({error:"no path to pin \u2014 pass --path or wait for auto-discovery"}));let c=await nn(`/api/apps/${encodeURIComponent(o)}/health/pin`,"POST",{path:l});c.status===404&&M(JSON.stringify({error:"unknown app"})),N(c.body);return}case"orchestrate":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon orchestrate <profile> [--goal serving|healthy|stable] [--timeout 300s] [--dry-run] [--budget <tokens>]"}));let i=new URLSearchParams;i.set("profile",o);let a=(r.goal||r.until||"healthy").toLowerCase();["serving","healthy","stable"].includes(a)||M(JSON.stringify({error:"orchestrate --goal must be serving|healthy|stable"})),i.set("goal",a);let l=300;if(r.timeout){let d=le(r.timeout);d==null&&M(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),l=Math.min(d,1200)}i.set("timeoutMs",String(Math.ceil(l*1e3))),r.dryRun&&i.set("dryRun","true"),r.budget&&Number.isFinite(r.budget)&&r.budget>0&&i.set("budget",String(Math.floor(r.budget)));let c=await G(`/api/orchestrate?${i.toString()}`,"POST");c.status===404&&M(JSON.stringify(c.body)),c.status===400&&M(JSON.stringify(c.body)),N(c.body),c.body&&c.body.allReached===!1&&process.exit(2);return}case"try-fix":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon try-fix <name> [--until serving|healthy] [--timeout 180s]"}));let i=new URLSearchParams,a=(r.until||"healthy").toLowerCase();["serving","healthy"].includes(a)||M(JSON.stringify({error:"try-fix --until must be serving|healthy"})),i.set("until",a);let l=180;if(r.timeout){let d=le(r.timeout);d==null&&M(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),l=Math.min(d,600)}i.set("timeoutMs",String(Math.ceil(l*1e3)));let c=await G(`/api/apps/${encodeURIComponent(o)}/try-fix?${i.toString()}`,"POST");c.status===404&&M(JSON.stringify({error:"unknown app"})),N(c.body),c.body&&c.body.reached===!1&&process.exit(2);return}case"wait":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon wait <name> [--until serving|healthy|stopped|error] [--timeout 60s]"}));let i=new URLSearchParams;r.until&&i.set("until",r.until);let a=120;if(r.timeout){let c=le(r.timeout);c==null&&M(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),a=Math.min(c,600)}i.set("timeout",String(Math.ceil(a)));let l=await G(`/api/apps/${encodeURIComponent(o)}/wait?${i.toString()}`);l.status===404&&M(JSON.stringify({error:"unknown app"})),N(l.body),l.body?.timedOut&&process.exit(2);return}case"up":case"down":{let o=r.positional[0],i=await G("/api/apps"),a=Array.isArray(i.body)?i.body:[],l=(await eu()).config,c;if(!o)c=l.autoStart||[],t==="up"&&c.length===0&&M(JSON.stringify({error:"no autoStart configured and no profile given"})),t==="down"&&c.length===0&&(c=a.map(p=>p.name));else{let p=l.profiles?.[o];p||M(JSON.stringify({error:`unknown profile: ${o}`})),c=p}let d=t==="up"?"start":"stop";if(t==="up"?await Promise.all(c.map(p=>G(`/api/apps/${encodeURIComponent(p)}/start?withDeps=1`,"POST"))):await Promise.all(c.map(p=>G(`/api/apps/${encodeURIComponent(p)}/${d}`,"POST"))),t==="up"){let m=Date.now(),h=()=>Math.max(5,Math.floor((12e4-(Date.now()-m))/1e3));await Promise.all(c.map(f=>G(`/api/apps/${encodeURIComponent(f)}/wait?until=serving&timeout=${h()}`)))}else await Promise.all(c.map(p=>G(`/api/apps/${encodeURIComponent(p)}/wait?until=stopped&timeout=10`)));let u=await G("/api/apps"),y=(Array.isArray(u.body)?u.body:[]).filter(p=>c.includes(p.name)).map(p=>({name:p.name,status:p.status,health:p.health}));N(y);return}case"logs":{let o=r.positional[0];o||M(JSON.stringify({error:"usage: daimon logs <name> [--tail N] [--since 30s]"}));let i=new URLSearchParams;r.tail!=null&&!Number.isNaN(r.tail)&&i.set("tail",String(r.tail)),r.since&&i.set("since",r.since);let a=i.toString(),l=await G(`/api/apps/${encodeURIComponent(o)}/logs${a?"?"+a:""}`);l.status===404&&M(JSON.stringify({error:"unknown app"})),N(l.body);return}default:{let o=Ir(t),i=o?`did you mean '${o}'? \u2014 run \`daimon --help\` to list commands`:"run `daimon --help` to list commands";ct(`unknown command: ${t}`,i)}}}au().catch(n=>M(JSON.stringify({error:n?.message||String(n)})));
251
+ `)}catch(e){_(JSON.stringify({error:e?.message||String(e)}))}}async function G(n,t="GET"){try{let e=await fetch(te()+n,{method:t,headers:bt()}),r=await e.text(),s=r;try{s=JSON.parse(r)}catch{}return{status:e.status,body:s}}catch{ut("daimon is not running","start it with: daimon daemon start --detach")}}async function ge(n,t,e){try{let r=await fetch(te()+n,{method:t,headers:{"content-type":"application/json",...bt()},body:JSON.stringify(e)}),s=await r.text(),o=s;try{o=JSON.parse(s)}catch{}return{status:r.status,body:o}}catch{ut("daimon is not running","start it with: daimon daemon start --detach")}}function Oe(n){let t={tags:[],positional:[],passthrough:[]},e=!1;for(let r=0;r<n.length;r++){let s=n[r];if(e){t.passthrough.push(s);continue}if(s==="--"){e=!0;continue}s==="--tail"?t.tail=Number(n[++r]):s==="--since"?t.since=n[++r]:s==="--since-last"?t.sinceLast=!0:s==="--client"?t.client=n[++r]:s==="--structured"?t.structured=!0:s==="--until"?t.until=n[++r]:s==="--timeout"?t.timeout=n[++r]:s==="--app"?t.app=n[++r]:s==="--tag"?t.tags.push(n[++r]):s==="--with-deps"?t.withDeps=!0:s==="--watch"?t.watch=!0:s==="--force"?t.force=!0:s==="--yes"?t.yes=!0:s==="--deep"?t.deep=!0:s==="--use"?t.use=n[++r]:s==="--speed"?t.speed=Number(n[++r]):s==="--task"?t.task=n[++r]:s==="--headless"?t.headless=!0:s==="--detach"?t.detach=!0:s==="--workspace"?t.workspace=n[++r]:s==="--full"?t.full=!0:s==="--compact"?t.compact=!0:s==="--profile"?t.profile=n[++r]:s==="--stream"?t.stream=!0:s==="--explain"?t.explain=!0:s==="--auto-fix"?t.autoFix=!0:s==="--dry-run"?t.dryRun=!0:s==="--auto"?t.auto=!0:s==="--redacted"?t.redacted=!0:s==="--budget"?t.budget=Number(n[++r]):s==="--accept"?t.accept=!0:s==="--path"?t.path=n[++r]:s==="--goal"?t.goal=n[++r]:s==="--self"?t.self=!0:s==="--all"?t.all=!0:s==="--level"?t.level=n[++r]:s==="--label"?t.label=n[++r]:s==="--kinds"?t.kinds=n[++r]:s==="--open"?t.open=!0:t.positional.push(s)}return t}function ye(n){let t=new URLSearchParams;return!n.all&&!n.workspace&&t.set("cwd",process.cwd()),t}function we(n){let t=Array.isArray(n?.candidates)?n.candidates:[];if(process.stderr.write(`error: ${n?.error||"name-collision"}
252
+ `),n?.hint&&process.stderr.write(`hint: ${n.hint}
253
+ `),t.length){process.stderr.write(`candidates:
254
+ `);for(let e of t){let r=e.workspaceLabel?` [${e.workspaceLabel}]`:"";process.stderr.write(` - ${e.name}${r} (${e.workspaceRoot??"?"})
255
+ `)}}M({error:n?.error||"name-collision",candidates:t}),process.exit(4)}function be(n){let t=n.match(/^(\d+)(ms|s|m|h)?$/);if(!t)return null;let e=Number(t[1]);switch(t[2]||"s"){case"ms":return e/1e3;case"s":return e;case"m":return e*60;case"h":return e*60*60}return null}function wn(){process.stdout.write(Xr()+`
256
+ `)}function Ti(n){let t=We(n);return t?(process.stdout.write(Kr(t)+`
257
+ `),!0):!1}function vu(){let n=ct(),t=null;try{let s=at();s.kind==="loaded"&&(t=s.path)}catch{}let e=Ae.join(Pi.homedir(),".daimon","lock.json"),r=[];try{let s=zt(Te());s&&(s.skill&&r.push("skill"),s.agent&&r.push("agent"),Array.isArray(s.commands)&&s.commands.length&&r.push("commands"))}catch{}M({version:st,nodeVersion:process.versions.node,platform:process.platform,configPath:t,lockPath:e,running:!!n,runningPid:n?.pid??null,runningPort:n?.apiPort??null,claudeArtifacts:r})}function Su(n){let t={},e=[];for(let r=0;r<n.length;r++){let s=n[r];s==="--skill"?t.skill=!0:s==="--commands"?t.commands=!0:s==="--agent"?t.agent=!0:s==="--all"?t.all=!0:s==="--dir"?t.dir=n[++r]:s==="--yes"?t.yes=!0:e.push(s)}return{positional:e,flags:t}}async function ku(n){let t=n[0];t||_(JSON.stringify({error:"usage: daimon claude <install|update|uninstall|status> [--skill] [--commands] [--agent] [--all] [--dir <path>] [--yes]"}));let{flags:e}=Su(n.slice(1)),r=e.dir??Te(),s=bn();if(t==="status"){M(as(r));return}if(t==="install"){let o,i=e.skill||e.commands||e.agent||e.all;if(e.all||e.yes||!i&&!process.stdin.isTTY)o={skill:!0,commands:!1,agent:!0};else if(i)o={skill:!!e.skill,commands:!1,agent:!!e.agent};else{let{promptClaudeInstall:c}=await Promise.resolve().then(()=>(ds(),ps)),l=await c();if(!l){M({cancelled:!0});return}o={skill:l.skill,commands:!1,agent:l.agent}}let a=Ge({...o,dir:r,apiPort:s,onMigrationEvent:c=>{c.kind==="removed"?M({removed:c.file}):M({warning:`${c.file} was modified; backing up to ${c.file}.bak`})}});M({installed:a.installed,manifest:a.manifestPath,version:st});return}if(t==="update"){let o=zt(r);o||_(JSON.stringify({error:"no manifest at "+r+" \u2014 run `daimon claude install` first"}));let i={skill:!!o.skill,commands:!1,agent:!!o.agent},a=Ge({...i,dir:r,apiPort:s,onMigrationEvent:c=>{c.kind==="removed"?M({removed:c.file}):M({warning:`${c.file} was modified; backing up to ${c.file}.bak`})}});M({updated:a.installed,manifest:a.manifestPath,version:st});return}if(t==="uninstall"){e.skill||e.commands||e.agent||e.all||_(JSON.stringify({error:"usage: daimon claude uninstall [--all|--skill|--commands|--agent]"}));let i=is({dir:r,selection:{all:e.all,skill:e.skill,commands:e.commands,agent:e.agent}});M({removed:i.removed,manifest:i.manifestPath});return}_(JSON.stringify({error:`unknown claude subcommand: ${t}`}))}async function xu(n){let t=n[0],e=Oe(n.slice(1));switch(t){case"status":{let r=ct();if(!r){M({running:!1});return}let s=Date.now()-r.startedAt;M({running:!0,pid:r.pid,port:r.apiPort,uptime:s,version:r.version,headless:r.headless});return}case"start":{if(e.detach){let s=ct();if(s){M({ok:!0,alreadyRunning:!0,pid:s.pid,port:s.apiPort});return}try{let o=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0,i=await Dt({port:Number.isFinite(o)&&o>0?o:void 0});M({ok:!0,pid:i.pid,port:i.apiPort})}catch(o){_(JSON.stringify({error:o?.message||String(o)}))}return}let{startInProcess:r}=await Promise.resolve().then(()=>(ci(),ai));await r({headless:!!e.headless});return}case"stop":{let r=ct();if(!r){M({ok:!0,wasRunning:!1});return}try{await fetch(`http://127.0.0.1:${r.apiPort}/api/shutdown`,{method:"POST",headers:bt()})}catch{}if(await Xt(r.pid,5e3))Tt(),M({ok:!0,wasRunning:!0});else{try{process.kill(r.pid,"SIGTERM")}catch{}await Xt(r.pid,2e3),Tt(),M({ok:!0,wasRunning:!0,forced:!0})}return}case"restart":{let r=ct();if(r){try{await fetch(`http://127.0.0.1:${r.apiPort}/api/snapshot-state`,{method:"POST",headers:bt()})}catch{}try{await fetch(`http://127.0.0.1:${r.apiPort}/api/shutdown`,{method:"POST",headers:bt()})}catch{}await Xt(r.pid,5e3),Tt()}let s=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0,o=await Dt({port:Number.isFinite(s)&&s>0?s:void 0});M({ok:!0,pid:o.pid,port:o.apiPort,handoff:!0});return}case"attach":{await Et();let r=ct();r||_(JSON.stringify({error:"no daemon running and auto-spawn failed"}));let{attachToDaemon:s}=await Promise.resolve().then(()=>(di(),pi));await s(r.apiPort);return}case"install-service":{let{installServiceArtifact:r}=await Promise.resolve().then(()=>(yi(),gi)),s=r();M({platform:s.platform,artifact:s.path,installCmd:s.installCmd});return}default:_(JSON.stringify({error:"usage: daimon daemon <start|stop|status|restart|attach|install-service> [--detach] [--headless]"}))}}async function Tu(){let n=process.argv.slice(2).filter(o=>o==="--no-spawn"?(Ci=!0,!1):o==="--no-color"?(Gr("off"),!1):o==="--help"||o==="-h"?(Tr=!0,!1):!0),[t,...e]=n;try{cs()}catch{}if(!t&&Tr){wn();return}if(!t){wn();return}if(t==="help"){let o=e[0];if(o&&Ti(o))return;wn();return}if(t==="--version"||t==="-v"){process.stdout.write(st+`
258
+ `);return}if(t==="--about"){vu();return}if(St[t]&&(t=St[t]),Tr){if(Ti(t))return;wn();return}if(t==="completion"){let o=e[0];o||ut("missing shell","usage: daimon completion <bash|zsh|fish|powershell>");let i=ts(o);i.ok||ut(i.error,"supported shells: bash, zsh, fish, powershell"),process.stdout.write(i.script);return}if(t==="self"){await Et();let o=await G("/api/self");o.status===404&&ut("self endpoint not available","daemon may be from an older daimon version \u2014 run `daimon daemon restart`"),M(o.body);return}if(t==="plugin"){let o=e[0];if(o||ut("missing subcommand","usage: daimon plugin <list|show <name>|validate <path>>"),o==="list"){await Et();let i=await G("/api/plugins");M(i.body);return}if(o==="show"){let i=e[1];i||ut("missing plug-in name","usage: daimon plugin show <name>"),await Et();let a=await G("/api/plugins"),l=(Array.isArray(a.body)?a.body:[]).find(u=>u.name===i);l||ut(`unknown plug-in: ${i}`,"list installed plug-ins with: daimon plugin list"),M(l);return}if(o==="validate"){let i=e[1];i||ut("missing file path","usage: daimon plugin validate <path>");let{validatePluginFile:a}=await Promise.resolve().then(()=>(gr(),Vo)),c=await a(Ae.resolve(i));M(c),c.ok||process.exit(1);return}ut(`unknown plugin subcommand: ${o}`,"usage: daimon plugin <list|show <name>|validate <path>>")}if(t==="workspaces"){await Et();let o=e[0],i=Oe(e.slice(1));if(!o||o==="list"){let a=await G("/api/workspaces");M(a.body);return}if(o==="add"){let a=i.positional[0]||process.cwd(),c={path:Ae.resolve(a)};i.label&&(c.label=i.label);let l=await ge("/api/workspaces/ensure","POST",c);M(l.body);return}if(o==="rm"||o==="remove"){let a=i.positional[0];a||ut("missing path","usage: daimon workspaces rm <path>");let c=await ge("/api/workspaces/remove","POST",{path:Ae.resolve(a)});c.status===404&&ut(`not registered: ${a}`,"run 'daimon workspaces list' to see registered searchRoots"),M(c.body);return}if(o==="show"){let a=i.positional[0]||process.cwd(),c=await G("/api/workspaces/resolve?cwd="+encodeURIComponent(Ae.resolve(a)));M(c.body);return}ut(`unknown workspaces subcommand: ${o}`,"usage: daimon workspaces <list|add|rm|show> [--label <name>]")}if(t==="dashboard"){await Et();let a=`http://127.0.0.1:${ct()?.apiPort??bn()}/?cwd=${encodeURIComponent(process.cwd())}`,c=process.platform==="win32"?"start":process.platform==="darwin"?"open":"xdg-open";try{let{spawn:l}=await import("node:child_process");process.platform==="win32"?l("cmd",["/c","start","",a],{detached:!0,stdio:"ignore"}).unref():l(c,[a],{detached:!0,stdio:"ignore"}).unref()}catch{}M({url:a,cwd:process.cwd()});return}if(t==="daemon"){await xu(e);return}if(t==="claude"){await ku(e);return}if(t==="export-config"){let o=at();o.kind!=="loaded"&&_(JSON.stringify({error:"no config loaded"}));let i=Oe(e),a=JSON.parse(JSON.stringify(o.config));if(i.redacted){let c=Pi.homedir().replace(/\\/g,"/"),l=u=>{if(typeof u!="string")return u;let d=u.replace(/\\/g,"/");return d.toLowerCase().startsWith(c.toLowerCase())?"~"+d.slice(c.length):u};a.apiToken!=null&&a.apiToken!==""&&(a.apiToken="<redacted>"),a.history?.path&&(a.history.path=l(a.history.path)),a.logs?.dir&&(a.logs.dir=l(a.logs.dir)),Array.isArray(a.searchRoots)&&(a.searchRoots=a.searchRoots.map(u=>typeof u=="string"?l(u):{...u,path:l(u.path)}))}M(a);return}if(t==="discover"){await Et();let o=await G("/api/discovery/explain");o.status!==200&&_(JSON.stringify({error:"discovery failed",status:o.status})),M(o.body);return}if(t==="init"){let{runInit:o}=await Promise.resolve().then(()=>(Si(),vi)),i=Oe(e);try{let a=await o({force:!!i.force,auto:!!i.auto});if(M({path:a.path,installClaude:a.installClaude,auto:a.auto}),a.installClaude){let l=bn(),u=Ge({skill:!0,commands:!1,agent:!0,dir:Te(),apiPort:l,onMigrationEvent:d=>{d.kind==="removed"?M({removed:d.file}):M({warning:`${d.file} was modified; backing up to ${d.file}.bak`})}});M({claudeInstalled:u.installed})}let c=ct();if(c){try{await fetch(`http://127.0.0.1:${c.apiPort}/api/snapshot-state`,{method:"POST",headers:bt()})}catch{}try{await fetch(`http://127.0.0.1:${c.apiPort}/api/shutdown`,{method:"POST",headers:bt()})}catch{}await Xt(c.pid,5e3),Tt();try{let l=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0,u=await Dt({port:Number.isFinite(l)&&l>0?l:void 0});M({daemonRestarted:!0,pid:u.pid,port:u.apiPort})}catch(l){M({daemonRestarted:!1,error:l?.message||String(l)})}}try{await Et();let l=await fetch(te()+"/api/discovery/explain",{headers:bt()});if(l.ok){let u=await l.json(),d={};try{let R=await(await fetch(te()+"/api/apps?format=full",{headers:bt()})).json();if(Array.isArray(R))for(let y of R){let b=y.workspaceType??"unknown";d[b]=(d[b]??0)+1}}catch{}let f=u.appsFound??0,g={init:"ok",configPath:a.path,discovered:{apps:f,byKind:d}};f===0&&(g._meta={searchRoots:u.searchRoots,scanned:u.scanned,rejected:u.rejected,suggestion:u.suggestion},g.warning="discovery found 0 apps; see _meta.suggestion"),M(g)}}catch{}}catch(a){_(JSON.stringify({error:a?.message||String(a)}))}return}let r=Oe(e);switch(We(t)?.needsDaemon&&await Et(),t){case"list":{let o=r.full||(r.tags.length||r.workspace)&&!r.compact,i=new URLSearchParams;if(o?i.set("format","full"):r.compact&&i.set("format","compact"),r.explain&&i.set("explain","1"),r.all||(await Qt(),i.set("cwd",process.cwd())),r.stream){i.set("stream","ndjson");let u=i.toString();await Pr("/api/apps"+(u?"?"+u:""));return}let a=i.toString(),c=await G("/api/apps"+(a?"?"+a:""));if(r.explain){M(c.body);return}let l=Array.isArray(c.body)?c.body:[];r.tags.length&&(l=l.filter(u=>r.tags.every(d=>(u.tags||[]).includes(d)))),r.workspace&&(l=l.filter(u=>u.workspaceLabel===r.workspace)),M(l);return}case"why-empty":{let o=await G("/api/apps?explain=1");M(o.body);return}case"status":case"stop":case"restart":{let o=r.positional[0];o||ut("missing app name",`usage: daimon ${t} <name>`),r.all||await Qt();let i=t==="status"?"":"/"+t,a=t==="status"?"GET":"POST",c=ye(r);t==="status"&&r.full?c.set("format","full"):t==="status"&&r.compact&&c.set("format","compact");let l=c.toString(),u=await G(`/api/apps/${encodeURIComponent(o)}${i}${l?"?"+l:""}`,a);u.status===412&&we(u.body),u.status===404&&await xi(o),M(u.body);return}case"start":{let o=r.positional[0];o||ut("missing app name","usage: daimon start <name> [--with-deps]"),r.all||await Qt();let i=ye(r);r.withDeps&&i.set("withDeps","1");let a=i.toString(),c=await G(`/api/apps/${encodeURIComponent(o)}/start${a?"?"+a:""}`,"POST");c.status===412&&we(c.body),c.status===404&&await xi(o),M(c.body);return}case"history":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon history <name>"}));let i=await G(`/api/history/summary/${encodeURIComponent(o)}`);M(i.body);return}case"why":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon why <name>"}));let i=await G(`/api/history/why/${encodeURIComponent(o)}`);M(i.body);return}case"env":{let o=r.positional[0];if(o||_(JSON.stringify({error:"usage: daimon env <name> [--use <file>]"})),r.use){let a=await ge(`/api/apps/${encodeURIComponent(o)}/env`,"POST",{use:r.use});a.status===404&&_(JSON.stringify({error:"unknown app"})),M(a.body);return}let i=await G(`/api/apps/${encodeURIComponent(o)}/env`);i.status===404&&_(JSON.stringify({error:"unknown app"})),M(i.body);return}case"clean":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon clean <name> [--deep] [--yes]"}));let i=new URLSearchParams;r.deep&&i.set("deep","1"),r.yes&&i.set("yes","1");let a=await G(`/api/apps/${encodeURIComponent(o)}/clean${i.toString()?"?"+i.toString():""}`,"POST");a.status===404&&_(JSON.stringify({error:"unknown app"})),a.status===409&&(M(a.body),process.exit(1)),M(a.body);return}case"record":{let o=await G("/api/session/record?action=toggle","POST");M(o.body);return}case"replay":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon replay <session.jsonl> [--speed N]"}));let i=r.speed&&r.speed>0?r.speed:1,a;try{a=Br(o)}catch(l){_(JSON.stringify({error:l?.message||String(l)}))}let c=0;for(let l of a){let u=Math.max(0,(l.ts-c)/i);u>0&&await new Promise(d=>setTimeout(d,u)),c=l.ts,l.kind==="run"?await ge(`/api/apps/${encodeURIComponent(l.app)}/run/${encodeURIComponent(l.task||"")}`,"POST",{args:l.args||[]}):await G(`/api/apps/${encodeURIComponent(l.app)}/${l.kind}`,"POST")}M({replayed:a.length,file:o});return}case"doctor":{let o=at();if(o.kind!=="loaded"&&_(JSON.stringify({error:"no config loaded"})),r.self){await Et();let l=await G("/api/self");l.status===503&&ut("self-metrics not available","daemon may need a restart: daimon daemon restart");let u=l.body??{},d=[],f=256,g=100,C=50;d.push({name:"heap",ok:u.heapUsedMB<f,detail:`heapUsed ${u.heapUsedMB}MB (warn at ${f}MB)`}),d.push({name:"event-loop-lag",ok:u.eventLoopLagP95Ms<g,detail:`p95 ${u.eventLoopLagP95Ms}ms (warn at ${g}ms)`}),d.push({name:"history-db-query",ok:(u.historyDbQueryMs?.p95??0)<C,detail:`p95 ${u.historyDbQueryMs?.p95??0}ms (warn at ${C}ms)`});let R=d.every(y=>y.ok);M({ok:R,checks:d,metrics:u}),R||process.exit(1);return}if(r.autoFix){let{runAutoFix:l,ALL_AUTO_FIX:u}=await Promise.resolve().then(()=>(pe(),ue)),d=o.config.doctor?.autoFix?.permitted??u,f=await l({permitted:d,dryRun:!!r.dryRun});M(f),f.errors.length&&process.exit(1);return}let i=[],a=Ot(o.config,{warnings:i}),c=await _r(o.config,a);for(let l of i)c.checks.unshift({name:`discovery: ${l}`,ok:!1,detail:l});i.length&&(c.ok=!1),M(c),c.ok||process.exit(1);return}case"free-port":{let o=Number(r.positional[0]);(!Number.isFinite(o)||o<=0)&&_(JSON.stringify({error:"usage: daimon free-port <port> [--force]"}));let i=Fe(o);if(!i){M({port:o,free:!0});return}if(!r.force){M({port:o,free:!1,holder:i});return}i.pid===process.pid&&_(JSON.stringify({error:"refuse to kill daimon itself",holder:i}));let a=await Ir(i);M({port:o,killed:a,holder:i}),a||process.exit(1);return}case"snapshot":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon snapshot <name>"}));let i=await G(`/api/apps/${encodeURIComponent(o)}/snapshot?write=1`,"POST");i.status===404&&_(JSON.stringify({error:"unknown app"})),M(i.body);return}case"tasks":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon tasks <name>"}));let i=await G(`/api/apps/${encodeURIComponent(o)}/tasks`);i.status===404&&_(JSON.stringify({error:"unknown app"})),M(i.body);return}case"run":{let o=r.positional[0],i=r.positional[1];(!o||!i)&&_(JSON.stringify({error:"usage: daimon run <name> <task> [--watch] [-- args...]"})),r.all||await Qt();let a={args:r.passthrough,watch:!!r.watch},l=ye(r).toString(),u=await ge(`/api/apps/${encodeURIComponent(o)}/run/${encodeURIComponent(i)}${l?"?"+l:""}`,"POST",a);u.status===412&&we(u.body),u.status===404&&_(JSON.stringify({error:"unknown app"})),M(u.body),!r.watch&&typeof u.body?.exitCode=="number"&&process.exit(u.body.exitCode===0?0:1);return}case"errors":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon errors <name> [--since 2m] [--since-last] [--client <id>] [--structured] [--full|--compact] [--level error|warning|lint|all]"})),r.all||await Qt();let i=ye(r),a=`/api/apps/${encodeURIComponent(o)}/errors`;r.sinceLast?(a+="/since-last",r.client&&i.set("client",r.client)):r.since&&i.set("since",r.since),r.level&&i.set("level",r.level),r.full?i.set("format","full"):r.compact&&i.set("format","compact");let c=i.toString(),l=await G(a+(c?"?"+c:""));l.status===412&&we(l.body),l.status===404&&_(JSON.stringify({error:"unknown app"}));let u=l.body;r.structured&&Array.isArray(u)&&(u=u.map(d=>d.parsed??{message:d.message})),M(u);return}case"events":{let o=new URLSearchParams;if(r.since&&o.set("since",r.since),r.app&&o.set("app",r.app),r.stream){o.set("stream","ndjson");let c=o.toString();await Pr("/api/events"+(c?"?"+c:""));return}let i=o.toString(),a=await G("/api/events"+(i?"?"+i:""));M(a.body);return}case"ensure":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon ensure <name> [--until serving|healthy] [--timeout 180s]"}));let i=new URLSearchParams,a=(r.until||"healthy").toLowerCase();a!=="serving"&&a!=="healthy"&&_(JSON.stringify({error:"ensure --until must be serving|healthy"})),i.set("until",a);let c=180;if(r.timeout){let u=be(r.timeout);u==null&&_(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),c=Math.min(u,600)}i.set("timeoutMs",String(Math.ceil(c*1e3)));let l=await G(`/api/apps/${encodeURIComponent(o)}/ensure?${i.toString()}`,"POST");l.status===404&&_(JSON.stringify({error:"unknown app"})),M(l.body),l.body?.error==="timeout"&&process.exit(2);return}case"ensure-up":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon ensure-up <profile> [--until serving|healthy] [--timeout 300s]"}));let i=new URLSearchParams,a=(r.until||"healthy").toLowerCase();a!=="serving"&&a!=="healthy"&&_(JSON.stringify({error:"ensure-up --until must be serving|healthy"})),i.set("until",a);let c=300;if(r.timeout){let d=be(r.timeout);d==null&&_(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),c=Math.min(d,1200)}i.set("timeoutMs",String(Math.ceil(c*1e3)));let l=await G(`/api/profiles/${encodeURIComponent(o)}/ensure-up?${i.toString()}`,"POST");l.status===404&&_(JSON.stringify({error:"unknown profile"})),M(l.body),Array.isArray(l.body?.apps)&&l.body.apps.some(d=>d.timedOut)&&process.exit(2);return}case"overview":{let o=new URLSearchParams;r.workspace&&o.set("workspace",r.workspace),r.profile&&o.set("profile",r.profile),r.budget&&Number.isFinite(r.budget)&&r.budget>0&&o.set("budget",String(Math.floor(r.budget)));let i=o.toString(),a=await G("/api/overview"+(i?"?"+i:""));M(a.body);return}case"focus":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon focus <name> [--until serving|healthy|stable] [--timeout 180s]"}));let i=new URLSearchParams,a=(r.until||"healthy").toLowerCase();["serving","healthy","stable"].includes(a)||_(JSON.stringify({error:"focus --until must be serving|healthy|stable"})),i.set("until",a);let c=180;if(r.timeout){let l=be(r.timeout);l==null&&_(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),c=Math.min(l,600)}i.set("timeoutMs",String(Math.ceil(c*1e3))),await Pr(`/api/apps/${encodeURIComponent(o)}/focus?${i.toString()}`,"POST");return}case"pin-health":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon pin-health <name> [--accept] [--path <p>]"}));let i=await G(`/api/apps/${encodeURIComponent(o)}?format=full`);i.status===404&&_(JSON.stringify({error:"unknown app"}));let a=i.body?.discoveredHealthPath??null,c=r.path??a??null;if(!r.accept){M({app:o,discoveredHealthPath:a,candidate:c,hint:c?`re-run with --accept to persist ${c} to daimon.config.json`:"no path discovered yet; start the app and wait for first serving"});return}c||_(JSON.stringify({error:"no path to pin \u2014 pass --path or wait for auto-discovery"}));let l=await ge(`/api/apps/${encodeURIComponent(o)}/health/pin`,"POST",{path:c});l.status===404&&_(JSON.stringify({error:"unknown app"})),M(l.body);return}case"orchestrate":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon orchestrate <profile> [--goal serving|healthy|stable] [--timeout 300s] [--dry-run] [--budget <tokens>]"}));let i=new URLSearchParams;i.set("profile",o);let a=(r.goal||r.until||"healthy").toLowerCase();["serving","healthy","stable"].includes(a)||_(JSON.stringify({error:"orchestrate --goal must be serving|healthy|stable"})),i.set("goal",a);let c=300;if(r.timeout){let u=be(r.timeout);u==null&&_(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),c=Math.min(u,1200)}i.set("timeoutMs",String(Math.ceil(c*1e3))),r.dryRun&&i.set("dryRun","true"),r.budget&&Number.isFinite(r.budget)&&r.budget>0&&i.set("budget",String(Math.floor(r.budget)));let l=await G(`/api/orchestrate?${i.toString()}`,"POST");l.status===404&&_(JSON.stringify(l.body)),l.status===400&&_(JSON.stringify(l.body)),M(l.body),l.body&&l.body.allReached===!1&&process.exit(2);return}case"try-fix":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon try-fix <name> [--until serving|healthy] [--timeout 180s]"}));let i=new URLSearchParams,a=(r.until||"healthy").toLowerCase();["serving","healthy"].includes(a)||_(JSON.stringify({error:"try-fix --until must be serving|healthy"})),i.set("until",a);let c=180;if(r.timeout){let u=be(r.timeout);u==null&&_(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),c=Math.min(u,600)}i.set("timeoutMs",String(Math.ceil(c*1e3)));let l=await G(`/api/apps/${encodeURIComponent(o)}/try-fix?${i.toString()}`,"POST");l.status===404&&_(JSON.stringify({error:"unknown app"})),M(l.body),l.body&&l.body.reached===!1&&process.exit(2);return}case"wait":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon wait <name> [--until serving|healthy|stopped|error] [--timeout 60s]"})),r.all||await Qt();let i=ye(r);r.until&&i.set("until",r.until);let a=120;if(r.timeout){let l=be(r.timeout);l==null&&_(JSON.stringify({error:`invalid --timeout: ${r.timeout}`})),a=Math.min(l,600)}i.set("timeout",String(Math.ceil(a)));let c=await G(`/api/apps/${encodeURIComponent(o)}/wait?${i.toString()}`);c.status===412&&we(c.body),c.status===404&&_(JSON.stringify({error:"unknown app"})),M(c.body),c.body?.timedOut&&process.exit(2);return}case"up":case"down":{let o=r.positional[0],i=await G("/api/apps"),a=Array.isArray(i.body)?i.body:[],c=(await bu()).config,l;if(!o)l=c.autoStart||[],t==="up"&&l.length===0&&_(JSON.stringify({error:"no autoStart configured and no profile given"})),t==="down"&&l.length===0&&(l=a.map(C=>C.name));else{let C=c.profiles?.[o];C||_(JSON.stringify({error:`unknown profile: ${o}`})),l=C}let u=t==="up"?"start":"stop";if(t==="up"?await Promise.all(l.map(C=>G(`/api/apps/${encodeURIComponent(C)}/start?withDeps=1`,"POST"))):await Promise.all(l.map(C=>G(`/api/apps/${encodeURIComponent(C)}/${u}`,"POST"))),t==="up"){let R=Date.now(),y=()=>Math.max(5,Math.floor((12e4-(Date.now()-R))/1e3));await Promise.all(l.map(b=>G(`/api/apps/${encodeURIComponent(b)}/wait?until=serving&timeout=${y()}`)))}else await Promise.all(l.map(C=>G(`/api/apps/${encodeURIComponent(C)}/wait?until=stopped&timeout=10`)));let d=await G("/api/apps"),g=(Array.isArray(d.body)?d.body:[]).filter(C=>l.includes(C.name)).map(C=>({name:C.name,status:C.status,health:C.health}));M(g);return}case"timeline":{let o=new URLSearchParams;r.since&&o.set("since",r.since),r.app&&o.set("app",r.app),r.kinds&&o.set("kinds",r.kinds);let i=o.toString(),a=await G("/api/history/timeline"+(i?"?"+i:""));M(a.body);return}case"logs":{let o=r.positional[0];o||_(JSON.stringify({error:"usage: daimon logs <name> [--tail N] [--since 30s]"})),r.all||await Qt();let i=ye(r);r.tail!=null&&!Number.isNaN(r.tail)&&i.set("tail",String(r.tail)),r.since&&i.set("since",r.since);let a=i.toString(),c=await G(`/api/apps/${encodeURIComponent(o)}/logs${a?"?"+a:""}`);c.status===412&&we(c.body),c.status===404&&_(JSON.stringify({error:"unknown app"})),M(c.body);return}default:{let o=Yr(t),i=o?`did you mean '${o}'? \u2014 run \`daimon --help\` to list commands`:"run `daimon --help` to list commands";ut(`unknown command: ${t}`,i)}}}Tu().catch(n=>_(JSON.stringify({error:n?.message||String(n)})));