daimon 0.5.0 → 0.7.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 (67) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/README.md +43 -29
  3. package/dist/cli.js +79 -66
  4. package/dist/dashboard/3rdpartylicenses.txt +4 -4
  5. package/dist/dashboard/browser/{chunk-HFJ25UTJ.js → chunk-25VLDASM.js} +4 -4
  6. package/dist/dashboard/browser/chunk-5PAHWCG5.js +1 -0
  7. package/dist/dashboard/browser/chunk-6BDWIJ3G.js +3 -0
  8. package/dist/dashboard/browser/chunk-6C6GHU3A.js +1 -0
  9. package/dist/dashboard/browser/{chunk-JX3IOOXU.js → chunk-7NRE3SNA.js} +3 -3
  10. package/dist/dashboard/browser/chunk-BDYOKQF3.js +1 -0
  11. package/dist/dashboard/browser/chunk-CILFSVSP.js +2 -0
  12. package/dist/dashboard/browser/chunk-GDJOSLWM.js +1 -0
  13. package/dist/dashboard/browser/chunk-HYGMRGYR.js +4 -0
  14. package/dist/dashboard/browser/chunk-HYIZMKSF.js +1 -0
  15. package/dist/dashboard/browser/chunk-IQZZO5IM.js +3 -0
  16. package/dist/dashboard/browser/chunk-J5UK77OJ.js +1 -0
  17. package/dist/dashboard/browser/chunk-JI63U3KC.js +2 -0
  18. package/dist/dashboard/browser/chunk-K43KW4K2.js +4 -0
  19. package/dist/dashboard/browser/chunk-KLH6B22T.js +1 -0
  20. package/dist/dashboard/browser/chunk-L2PHC6DL.js +1 -0
  21. package/dist/dashboard/browser/{chunk-Q7R63OUT.js → chunk-LBRCWYRN.js} +1 -1
  22. package/dist/dashboard/browser/chunk-MHYQENOC.js +1 -0
  23. package/dist/dashboard/browser/{chunk-AEERNAF7.js → chunk-NDSAQ2HK.js} +1 -1
  24. package/dist/dashboard/browser/chunk-OHX55ZU4.js +2 -0
  25. package/dist/dashboard/browser/chunk-OUXULJ3Z.js +3 -0
  26. package/dist/dashboard/browser/chunk-P5IU57TV.js +2 -0
  27. package/dist/dashboard/browser/{chunk-3TYCIBMV.js → chunk-PJPGLT4T.js} +1 -1
  28. package/dist/dashboard/browser/chunk-Q3N4MMWW.js +5 -0
  29. package/dist/dashboard/browser/chunk-RIDV4B55.js +5 -0
  30. package/dist/dashboard/browser/chunk-SR5JAOLW.js +2 -0
  31. package/dist/dashboard/browser/{chunk-ZVU34B5S.js → chunk-UC3XMN2Y.js} +1 -1
  32. package/dist/dashboard/browser/chunk-UU5K6ZPO.js +1 -0
  33. package/dist/dashboard/browser/chunk-XXIJQBCQ.js +2 -0
  34. package/dist/dashboard/browser/chunk-Y6B6X4Y6.js +2 -0
  35. package/dist/dashboard/browser/chunk-YA4AZONZ.js +5 -0
  36. package/dist/dashboard/browser/chunk-YNCTXEXX.js +3 -0
  37. package/dist/dashboard/browser/chunk-YNQPX5G6.js +1 -0
  38. package/dist/dashboard/browser/{chunk-SLQ2WBUA.js → chunk-YYAZGY5M.js} +1 -1
  39. package/dist/dashboard/browser/chunk-ZDNBWNU5.js +1 -0
  40. package/dist/dashboard/browser/chunk-ZEO5YLWG.js +3 -0
  41. package/dist/dashboard/browser/chunk-ZVUH3ISD.js +2 -0
  42. package/dist/dashboard/browser/index.html +1 -1
  43. package/dist/dashboard/browser/main-IDF27PFI.js +1 -0
  44. package/dist/main.js +57 -44
  45. package/dist/mcp.js +3 -2
  46. package/package.json +2 -2
  47. package/dist/dashboard/browser/chunk-5UAN6ETO.js +0 -1
  48. package/dist/dashboard/browser/chunk-AX3RJNG4.js +0 -1
  49. package/dist/dashboard/browser/chunk-BADBUP5C.js +0 -3
  50. package/dist/dashboard/browser/chunk-BF6RQFHS.js +0 -2
  51. package/dist/dashboard/browser/chunk-C65CUT7O.js +0 -4
  52. package/dist/dashboard/browser/chunk-CNIZYK4A.js +0 -1
  53. package/dist/dashboard/browser/chunk-D4BFRQ63.js +0 -4
  54. package/dist/dashboard/browser/chunk-E235WGFQ.js +0 -3
  55. package/dist/dashboard/browser/chunk-F2EDJ6FT.js +0 -4
  56. package/dist/dashboard/browser/chunk-HFAARBWL.js +0 -1
  57. package/dist/dashboard/browser/chunk-LQNYSOSZ.js +0 -1
  58. package/dist/dashboard/browser/chunk-MBVVV35N.js +0 -1
  59. package/dist/dashboard/browser/chunk-NC2VPB4Y.js +0 -2
  60. package/dist/dashboard/browser/chunk-NXNVIINH.js +0 -1
  61. package/dist/dashboard/browser/chunk-QLKOKZDG.js +0 -9
  62. package/dist/dashboard/browser/chunk-QQSPJIPQ.js +0 -1
  63. package/dist/dashboard/browser/chunk-SCAIGUJL.js +0 -6
  64. package/dist/dashboard/browser/chunk-TSB6OOH2.js +0 -6
  65. package/dist/dashboard/browser/chunk-WWUKM5OG.js +0 -1
  66. package/dist/dashboard/browser/chunk-ZYE3XQS4.js +0 -2
  67. package/dist/dashboard/browser/main-Z6L5VPBT.js +0 -4
package/dist/main.js CHANGED
@@ -1,6 +1,6 @@
1
- var qr=Object.defineProperty;var tt=(n,t)=>()=>(n&&(t=n(n=0)),t);var je=(n,t)=>{for(var e in t)qr(n,e,{get:t[e],enumerable:!0})};import K from"node:fs";import q from"node:path";import pt from"node:os";import{fileURLToPath as Xr}from"node:url";function Me(){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:q.join(pt.homedir(),".daimon","logs"),maxFiles:5,maxBytesPerFile:1e7},depends:{},cascadeRestart:!1,history:{enabled:!0,path:q.join(pt.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"]}},dashboard:{theme:"auto",density:"comfortable"}}}function Ne(n){return n.startsWith("~/")||n.startsWith("~\\")?q.join(pt.homedir(),n.slice(2)):n==="~"?pt.homedir():n}function Vt(n,t){return zt(n,t)}function zt(n,t){if(!n||typeof n!="object")throw new Error(`Config at ${t} is not a JSON object`);let e=n,r=Me();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,i]of Object.entries(e.profiles))if(!Array.isArray(i)||!i.every(o=>typeof o=="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=Ne(r.logs.dir)),e.depends&&typeof e.depends=="object"&&!Array.isArray(e.depends)){for(let[s,i]of Object.entries(e.depends))if(!Array.isArray(i)||!i.every(o=>typeof o=="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=Ne(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(i=>typeof i=="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)}return r}function ft(){return{local:q.join(process.cwd(),"daimon.config.json"),user:q.join(pt.homedir(),".daimon","config.json")}}function et(){let{local:n,user:t}=ft();if(K.existsSync(n)){let s=JSON.parse(K.readFileSync(n,"utf8"));return{kind:"loaded",config:zt(s,n),path:n}}if(K.existsSync(t)){let s=JSON.parse(K.readFileSync(t,"utf8"));return{kind:"loaded",config:zt(s,t),path:t}}let r=[q.resolve($e,"..","daimon.config.example.json"),q.resolve($e,"..","..","daimon.config.example.json")].find(s=>K.existsSync(s));return K.mkdirSync(q.dirname(t),{recursive:!0}),r?K.copyFileSync(r,t):K.writeFileSync(t,JSON.stringify(Me(),null,2)+`
2
- `,"utf8"),{kind:"stub-created",path:t}}var Kr,$e,kt=tt(()=>{"use strict";Kr=Xr(import.meta.url),$e=q.dirname(Kr)});var te={};je(te,{discoverApps:()=>mt});import dt from"node:fs";import U from"node:path";import Qt from"fast-glob";function _e(n){try{return JSON.parse(dt.readFileSync(n,"utf8"))}catch{return null}}function Le(n){return!n||typeof n!="object"?!1:!!(n.targets?.serve||n.architect?.serve)}function De(n){if(!n||typeof n!="object")return[];let t=n.targets??n.architect??{};return Object.keys(t).filter(e=>e!=="serve").sort()}function Zt(n){return n.replace(/\\/g,"/")}function rt(n,t){n&&(n.rejected[t]=(n.rejected[t]??0)+1)}function mt(n,t={}){let e=new Map,r=t.warnings??[],s=t.warnings===void 0;for(let i of n.searchRoots){let o=typeof i=="string"?i:i.path,a=typeof i=="string"?!1:!!i.viteSubfolders,u=typeof i=="string"?void 0:i.label,c=U.resolve(o);if(!dt.existsSync(c)){r.push(`searchRoot does not exist: ${c}`),rt(t.stats,"searchRoot missing");continue}let h=U.join(c,"nx.json"),p=U.join(c,"angular.json");if(dt.existsSync(h)){let m=Qt.sync("**/project.json",{cwd:Zt(c),ignore:["**/node_modules/**","**/dist/**","**/.nx/**","**/.git/**"],absolute:!0,dot:!1});for(let g of m){t.stats&&(t.stats.scanned+=1);let d=_e(g);if(!d){rt(t.stats,"unreadable project.json");continue}if(!Le(d)){rt(t.stats,"no serve target");continue}let y=d.name||U.basename(U.dirname(g));if(!y){rt(t.stats,"project has no name");continue}if(e.has(y)){r.push(`duplicate project name "${y}" \u2014 keeping first`),rt(t.stats,"duplicate name");continue}e.set(y,{name:y,workspaceRoot:c,workspaceType:"nx",command:`npx nx serve ${y}`,hidden:!1,tags:[],tasks:De(d),workspaceLabel:u})}continue}if(dt.existsSync(p)){let g=_e(p)?.projects||{};for(let[d,y]of Object.entries(g))if(Le(y)){if(e.has(d)){r.push(`duplicate project name "${d}" \u2014 keeping first`);continue}e.set(d,{name:d,workspaceRoot:c,workspaceType:"angular",command:`npx ng serve ${d}`,hidden:!1,tags:[],tasks:De(y),workspaceLabel:u})}continue}let b=Qt.sync("vite.config.{ts,js,mjs,cjs}",{cwd:Zt(c),absolute:!0,deep:1}),S=dt.existsSync(U.join(c,".storybook")),l=!1;if(b.length>0){let m=U.basename(c);if(e.has(m)||e.set(m,{name:m,workspaceRoot:c,workspaceType:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:u}),l=!0,a){let g=Qt.sync("*/vite.config.{ts,js,mjs,cjs}",{cwd:Zt(c),absolute:!0});for(let d of g){let y=U.dirname(d),k=U.basename(y);k===m||e.has(k)||e.set(k,{name:k,workspaceRoot:y,workspaceType:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:u})}}}if(S){let m=`${U.basename(c)}-storybook`;e.has(m)||e.set(m,{name:m,workspaceRoot:c,workspaceType:"storybook",command:"npx storybook dev --no-open",hidden:!1,tags:[],workspaceLabel:u}),l=!0}l||(r.push(`searchRoot has none of nx.json/angular.json/vite.config.*/.storybook: ${c}`),rt(t.stats,"no project markers"))}for(let[i,o]of Object.entries(n.overrides||{})){let a=e.get(i);a?(o.command&&(a.command=o.command),typeof o.hidden=="boolean"&&(a.hidden=o.hidden),typeof o.port=="number"&&(a.pinnedPort=o.port),o.env&&(a.env=o.env)):o.command&&e.set(i,{name:i,workspaceRoot:process.cwd(),workspaceType:"nx",command:o.command,hidden:o.hidden??!1,pinnedPort:o.port,env:o.env,tags:[]})}for(let i of e.values())i.tags=n.tags?.[i.name]??[];if(s&&r.length)for(let i of r)process.stderr.write(`[daimon] warning: ${i}
3
- `);return[...e.values()].filter(i=>!i.hidden)}var ht=tt(()=>{"use strict"});import Tn from"node:fs";import se from"node:path";import{fileURLToPath as An}from"node:url";function Cn(){let n=[se.resolve(rr,"..","package.json"),se.resolve(rr,"..","..","package.json")];for(let t of n)try{return JSON.parse(Tn.readFileSync(t,"utf8"))}catch{}return{}}var rr,st,At=tt(()=>{"use strict";rr=se.dirname(An(import.meta.url));st=Cn().version||"0.0.0"});import ot from"node:fs";import Ct from"node:path";import Rn from"node:os";import{spawn as Pn}from"node:child_process";import{fileURLToPath as On}from"node:url";function Y(){return ie}function Rt(){return it}function oe(n){try{return process.kill(n,0),!0}catch(t){return t&&t.code==="EPERM"}}function gt(){try{let n=ot.readFileSync(it,"utf8"),t=JSON.parse(n);if(!t||typeof t.pid!="number")return null;if(!oe(t.pid)){try{ot.unlinkSync(it)}catch{}return null}return t}catch{return null}}function nr(n){ot.mkdirSync(ie,{recursive:!0});let t=it+"."+process.pid+".tmp";ot.writeFileSync(t,JSON.stringify(n)),ot.renameSync(t,it)}function yt(){try{ot.unlinkSync(it)}catch{}}function jn(){let n=Ct.dirname(On(import.meta.url));return Ct.join(n,"main.js")}async function ae(n={}){let t={...process.env};n.port&&(t.DAIMON_PORT=String(n.port)),Pn(process.execPath,[jn(),"--headless"],{detached:!0,stdio:"ignore",env:t,windowsHide:!0}).unref();let r=Date.now();for(;Date.now()-r<5e3;){let s=gt();if(s&&(!n.port||s.apiPort===n.port))return s;await new Promise(i=>setTimeout(i,100))}throw new Error("daemon failed to start within 5s")}async function sr(n,t){let e=Date.now();for(;Date.now()-e<t;){if(!oe(n))return!0;await new Promise(r=>setTimeout(r,100))}return!oe(n)}function or(n,t,e){return{pid:process.pid,apiPort:n,version:st,startedAt:Date.now(),headless:t,cwd:process.cwd(),configPath:e}}var ie,it,Q=tt(()=>{"use strict";At();ie=Ct.join(Rn.homedir(),".daimon"),it=Ct.join(ie,"daemon.lock")});import Qn from"node:fs";import Zn from"node:path";import{createRequire as ts}from"node:module";var es,rs,ns,ss,at,he=tt(()=>{"use strict";es=ts(import.meta.url),rs=200,ns=360*60*1e3,ss=1e4,at=class{constructor(t){this.cfg=t;if(t.enabled)try{Qn.mkdirSync(Zn.dirname(t.path),{recursive:!0});let e=es("better-sqlite3");this.db=new e(t.path),this.db.pragma("journal_mode = WAL"),this.migrate(),this.flushTimer=setInterval(()=>this.flush(),rs),this.retentionStart=setTimeout(()=>this.runRetention(),ss),this.retentionTimer=setInterval(()=>this.runRetention(),ns)}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}
1
+ var _n=Object.defineProperty;var rt=(n,t)=>()=>(n&&(t=n(n=0)),t);var Dt=(n,t)=>{for(var e in t)_n(n,e,{get:t[e],enumerable:!0})};var ar={};Dt(ar,{configLookupPaths:()=>pt,loadConfig:()=>Q,validateConfig:()=>Ft});import st from"node:fs";import nt from"node:path";import Et from"node:os";import{fileURLToPath as Ln}from"node:url";function ir(){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:nt.join(Et.homedir(),".daimon","logs"),maxFiles:5,maxBytesPerFile:1e7},depends:{},cascadeRestart:!1,history:{enabled:!0,path:nt.join(Et.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"}}}function or(n){return n.startsWith("~/")||n.startsWith("~\\")?nt.join(Et.homedir(),n.slice(2)):n==="~"?Et.homedir():n}function Ft(n,t){return he(n,t)}function he(n,t){if(!n||typeof n!="object")throw new Error(`Config at ${t} is not a JSON object`);let e=n,r=ir();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,i]of Object.entries(e.profiles))if(!Array.isArray(i)||!i.every(o=>typeof o=="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=or(r.logs.dir)),e.depends&&typeof e.depends=="object"&&!Array.isArray(e.depends)){for(let[s,i]of Object.entries(e.depends))if(!Array.isArray(i)||!i.every(o=>typeof o=="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=or(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(i=>typeof i=="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)}return r}function pt(){return{local:nt.join(process.cwd(),"daimon.config.json"),user:nt.join(Et.homedir(),".daimon","config.json")}}function Q(){let{local:n,user:t}=pt();if(st.existsSync(n)){let s=JSON.parse(st.readFileSync(n,"utf8"));return{kind:"loaded",config:he(s,n),path:n}}if(st.existsSync(t)){let s=JSON.parse(st.readFileSync(t,"utf8"));return{kind:"loaded",config:he(s,t),path:t}}let r=[nt.resolve(sr,"..","daimon.config.example.json"),nt.resolve(sr,"..","..","daimon.config.example.json")].find(s=>st.existsSync(s));return st.mkdirSync(nt.dirname(t),{recursive:!0}),r?st.copyFileSync(r,t):st.writeFileSync(t,JSON.stringify(ir(),null,2)+`
2
+ `,"utf8"),{kind:"stub-created",path:t}}var Dn,sr,Rt=rt(()=>{"use strict";Dn=Ln(import.meta.url),sr=nt.dirname(Dn)});var be={};Dt(be,{discoverApps:()=>At});import z from"node:fs";import W from"node:path";import ge from"fast-glob";function cr(n){try{return JSON.parse(z.readFileSync(n,"utf8"))}catch{return null}}function lr(n){return!n||typeof n!="object"?!1:!!(n.targets?.serve||n.architect?.serve)}function ur(n){if(!n||typeof n!="object")return[];let t=n.targets??n.architect??{};return Object.keys(t).filter(e=>e!=="serve").sort()}function ye(n){return n.replace(/\\/g,"/")}function mt(n,t){n&&(n.rejected[t]=(n.rejected[t]??0)+1)}function ve(n,t){try{return t.test(z.readFileSync(n,"utf8"))}catch{return!1}}function Fn(n,t,e){let r=W.basename(n),s=!1,i=W.join(n,"manage.py");if(z.existsSync(i)&&ve(i,/\bdjango\b/i)){let b=r;e.has(b)||e.set(b,{name:b,workspaceRoot:n,workspaceType:"polyglot",serverProfile:"django",command:"python manage.py runserver",hidden:!1,tags:[],workspaceLabel:t}),s=!0}let o=W.join(n,"bin","rails"),a=W.join(n,"Gemfile");if(z.existsSync(o)&&z.existsSync(a)){let b=r;e.has(b)||e.set(b,{name:b,workspaceRoot:n,workspaceType:"polyglot",serverProfile:"rails",command:"bin/rails server",hidden:!1,tags:[],workspaceLabel:t}),s=!0}let c=W.join(n,"pyproject.toml"),u=W.join(n,"requirements.txt");(z.existsSync(c)&&ve(c,/\bfastapi\b/i)||z.existsSync(u)&&ve(u,/\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),(z.existsSync(W.join(n,".air.toml"))||z.existsSync(W.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 v=W.join(n,"Trunk.toml");return z.existsSync(v)&&!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 At(n,t={}){let e=new Map,r=t.warnings??[],s=t.warnings===void 0;for(let i of n.searchRoots){let o=typeof i=="string"?i:i.path,a=typeof i=="string"?!1:!!i.viteSubfolders,c=typeof i=="string"?void 0:i.label,u=W.resolve(o);if(!z.existsSync(u)){r.push(`searchRoot does not exist: ${u}`),mt(t.stats,"searchRoot missing");continue}let h=W.join(u,"nx.json"),p=W.join(u,"angular.json");if(z.existsSync(h)){let m=ge.sync("**/project.json",{cwd:ye(u),ignore:["**/node_modules/**","**/dist/**","**/.nx/**","**/.git/**"],absolute:!0,dot:!1});for(let f of m){t.stats&&(t.stats.scanned+=1);let d=cr(f);if(!d){mt(t.stats,"unreadable project.json");continue}if(!lr(d)){mt(t.stats,"no serve target");continue}let g=d.name||W.basename(W.dirname(f));if(!g){mt(t.stats,"project has no name");continue}if(e.has(g)){r.push(`duplicate project name "${g}" \u2014 keeping first`),mt(t.stats,"duplicate name");continue}e.set(g,{name:g,workspaceRoot:u,workspaceType:"nx",serverProfile:"nx",command:`npx nx serve ${g}`,hidden:!1,tags:[],tasks:ur(d),workspaceLabel:c})}continue}if(z.existsSync(p)){let f=cr(p)?.projects||{};for(let[d,g]of Object.entries(f))if(lr(g)){if(e.has(d)){r.push(`duplicate project name "${d}" \u2014 keeping first`);continue}e.set(d,{name:d,workspaceRoot:u,workspaceType:"angular",serverProfile:"angular",command:`npx ng serve ${d}`,hidden:!1,tags:[],tasks:ur(g),workspaceLabel:c})}continue}let v=ge.sync("vite.config.{ts,js,mjs,cjs}",{cwd:ye(u),absolute:!0,deep:1}),b=z.existsSync(W.join(u,".storybook")),l=!1;if(v.length>0){let m=W.basename(u);if(e.has(m)||e.set(m,{name:m,workspaceRoot:u,workspaceType:"vite",serverProfile:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:c}),l=!0,a){let f=ge.sync("*/vite.config.{ts,js,mjs,cjs}",{cwd:ye(u),absolute:!0});for(let d of f){let g=W.dirname(d),T=W.basename(g);T===m||e.has(T)||e.set(T,{name:T,workspaceRoot:g,workspaceType:"vite",serverProfile:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:c})}}}if(b){let m=`${W.basename(u)}-storybook`;e.has(m)||e.set(m,{name:m,workspaceRoot:u,workspaceType:"storybook",serverProfile:"storybook",command:"npx storybook dev --no-open",hidden:!1,tags:[],workspaceLabel:c}),l=!0}l||Fn(u,c,e)||(r.push(`searchRoot has none of nx.json/angular.json/vite.config.*/.storybook/polyglot markers: ${u}`),mt(t.stats,"no project markers"))}for(let[i,o]of Object.entries(n.overrides||{})){let a=e.get(i);a?(o.command&&(a.command=o.command),typeof o.hidden=="boolean"&&(a.hidden=o.hidden),typeof o.port=="number"&&(a.pinnedPort=o.port),o.env&&(a.env=o.env)):o.command&&e.set(i,{name:i,workspaceRoot:process.cwd(),workspaceType:"nx",command:o.command,hidden:o.hidden??!1,pinnedPort:o.port,env:o.env,tags:[]})}for(let i of e.values())i.tags=n.tags?.[i.name]??[];if(s&&r.length)for(let i of r)process.stderr.write(`[daimon] warning: ${i}
3
+ `);return[...e.values()].filter(i=>!i.hidden)}var Ct=rt(()=>{"use strict"});import ms from"node:net";function gt(n){return new Promise(t=>{let e=ms.createServer();e.unref(),e.once("error",()=>t(!1)),e.listen({port:n,host:"127.0.0.1",exclusive:!0},()=>{e.close(()=>t(!0))})})}var ht,Bt=rt(()=>{"use strict";ht=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,i]of Object.entries(e.initial))typeof i=="number"&&(i<this.min||i>this.max||r.has(i)||(r.add(i),this.assigned.set(s,i)))}}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 i=this.min;i<=this.max;i++){if(s.has(i))continue;if(await gt(i))return this.assigned.set(t,i),this.onChange?.(this.snapshot()),i}throw new Error(`No free ports in range ${this.min}-${this.max}`)}async isPortAvailableForUse(t){return gt(t)}}});function yr(n){let s=new Map,i=new Map,o=null,a=c=>{if(!o){s.set(c,1);for(let u of n[c]||[]){let h=s.get(u)??0;if(h===1){let p=[u,c],v=i.get(c);for(;v&&v!==u;)p.push(v),v=i.get(v);v===u&&p.push(u),o=p.reverse();return}if(h===0&&(i.set(u,c),a(u),o))return}s.set(c,2)}};for(let c of Object.keys(n))if((s.get(c)??0)===0&&(i.set(c,null),a(c),o))return o;return null}function Ut(n,t){let e=new Set,r=[t];for(;r.length;){let s=r.pop();if(!e.has(s)){e.add(s);for(let i of n[s]||[])r.push(i)}}return[...e]}function Wt(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 i=[],o=t.filter(a=>(r.get(a)??0)===0);for(;o.length;){i.push([...o].sort());let a=[];for(let c of o)for(let u of s.get(c)??[])r.set(u,(r.get(u)??1)-1),r.get(u)===0&&a.push(u);o=a}return i}function vr(n,t){let e=[];for(let[r,s]of Object.entries(n))s.includes(t)&&e.push(r);return e}var Gt=rt(()=>{"use strict"});import ws from"node:fs";import ke from"node:path";import{fileURLToPath as Ss}from"node:url";function xs(){let n=[ke.resolve(Or,"..","package.json"),ke.resolve(Or,"..","..","package.json")];for(let t of n)try{return JSON.parse(ws.readFileSync(t,"utf8"))}catch{}return{}}var Or,yt,Jt=rt(()=>{"use strict";Or=ke.dirname(Ss(import.meta.url));yt=xs().version||"0.0.0"});import vt from"node:fs";import qt from"node:path";import ks from"node:os";import{spawn as Ts}from"node:child_process";import{fileURLToPath as Es}from"node:url";function ot(){return Ee}function Kt(){return bt}function Te(n){try{return process.kill(n,0),!0}catch(t){return t&&t.code==="EPERM"}}function wt(){try{let n=vt.readFileSync(bt,"utf8"),t=JSON.parse(n);if(!t||typeof t.pid!="number")return null;if(!Te(t.pid)){try{vt.unlinkSync(bt)}catch{}return null}return t}catch{return null}}function Mr(n){vt.mkdirSync(Ee,{recursive:!0});let t=bt+"."+process.pid+".tmp";vt.writeFileSync(t,JSON.stringify(n)),vt.renameSync(t,bt)}function Pt(){try{vt.unlinkSync(bt)}catch{}}function Rs(){let n=qt.dirname(Es(import.meta.url));return qt.join(n,"main.js")}async function Re(n={}){let t={...process.env};n.port&&(t.DAIMON_PORT=String(n.port)),Ts(process.execPath,[Rs(),"--headless"],{detached:!0,stdio:"ignore",env:t,windowsHide:!0}).unref();let r=Date.now();for(;Date.now()-r<5e3;){let s=wt();if(s&&(!n.port||s.apiPort===n.port))return s;await new Promise(i=>setTimeout(i,100))}throw new Error("daemon failed to start within 5s")}async function jr(n,t){let e=Date.now();for(;Date.now()-e<t;){if(!Te(n))return!0;await new Promise(r=>setTimeout(r,100))}return!Te(n)}function Nr(n,t,e){return{pid:process.pid,apiPort:n,version:yt,startedAt:Date.now(),headless:t,cwd:process.cwd(),configPath:e}}var Ee,bt,dt=rt(()=>{"use strict";Jt();Ee=qt.join(ks.homedir(),".daimon"),bt=qt.join(Ee,"daemon.lock")});import Ks from"node:fs";import Xs from"node:path";import{createRequire as zs}from"node:module";var Ys,Vs,Zs,Qs,St,$e=rt(()=>{"use strict";Ys=zs(import.meta.url),Vs=200,Zs=360*60*1e3,Qs=1e4,St=class{constructor(t){this.cfg=t;if(t.enabled)try{Ks.mkdirSync(Xs.dirname(t.path),{recursive:!0});let e=Ys("better-sqlite3");this.db=new e(t.path),this.db.pragma("journal_mode = WAL"),this.migrate(),this.flushTimer=setInterval(()=>this.flush(),Vs),this.retentionStart=setTimeout(()=>this.runRetention(),Qs),this.retentionTimer=setInterval(()=>this.runRetention(),Zs)}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}
4
4
  `))}migrate(){this.db&&this.db.exec(`
5
5
  CREATE TABLE IF NOT EXISTS events (
6
6
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -29,52 +29,65 @@ var qr=Object.defineProperty;var tt=(n,t)=>()=>(n&&(t=n(n=0)),t);var je=(n,t)=>{
29
29
  summary TEXT
30
30
  );
31
31
  CREATE INDEX IF NOT EXISTS task_runs_app_ts ON task_runs(app, ts);
32
- `)}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}})}recordTaskRun(t,e,r,s,i,o=Date.now()){this.db&&this.queue.push({kind:"task",row:{ts:o,app:t,task:e,exit_code:r,duration_ms:s,summary:i==null?null:JSON.stringify(i)}})}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 (?,?,?,?,?,?)");this.db.transaction(o=>{for(let a of o)a.kind==="event"?e.run(a.row.ts,a.row.app,a.row.type,a.row.from_state,a.row.to_state,a.row.message):a.kind==="compile"?r.run(a.row.ts,a.row.app,a.row.ms):s.run(a.row.ts,a.row.app,a.row.task,a.row.exit_code,a.row.duration_ms,a.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)}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)}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,i=e,o=!1,a=null,u=[...r].sort((d,y)=>d.ts-y.ts);for(let d of u)d.type==="status"&&(d.to_state==="serving"&&!o?(o=!0,a=d.ts):o&&d.to_state!=="serving"&&a!=null&&(s+=d.ts-a,o=!1,a=null));o&&a!=null&&(s+=Date.now()-a);let c=Math.round(s/(24*3600*1e3)*1e3)/10,h=r.filter(d=>d.type==="status"&&d.to_state==="starting"&&(d.from_state==="serving"||d.from_state==="error"||d.from_state==="compiling")).length,p=this.queryCompiles({app:t,since:e,limit:1e3}).map(d=>d.ms).sort((d,y)=>d-y),b=(d,y)=>{if(d.length===0)return null;let k=Math.min(d.length-1,Math.floor((d.length-1)*y));return d[k]},S=b(p,.5),l=b(p,.95),m=new Map;for(let d of r)if(d.type==="error-new"||d.type==="error-recur"){let y=d.message??"";if(!y)continue;m.set(y,(m.get(y)??0)+1)}let g=[...m.entries()].sort((d,y)=>y[1]-d[1]).slice(0,5).map(([d,y])=>({message:d,count:y}));return{uptimePct24h:c,restartCount24h:h,compileP50:S,compileP95:l,topErrors:g}}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,i=s?s.ts:Date.now(),o=e.filter(a=>a.ts<i).slice(0,5);return{trigger:s,preceding:o.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}))}}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}}}});var Cr={};je(Cr,{ALL_AUTO_FIX:()=>Ar,runAutoFix:()=>ms});import B from"node:fs";import X from"node:path";function os(){let n=gt();if(!n)return{detected:!1,description:"no daemon running"};let t=process.cwd(),e=X.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,i=r&&X.resolve(r)===X.resolve(t),o=s&&X.resolve(s)===X.resolve(e);return i||o?{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 is(){let n=gt();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 sr(n.pid,5e3),yt(),`respawned daemon at pid ${(await ae({})).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 as(){let n;try{n=B.readFileSync(Rt(),"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 cs(){let n="(unknown)";try{let e=JSON.parse(B.readFileSync(Rt(),"utf8"));n=String(e?.pid??"?")}catch{}yt();let t=await ae({});return`removed stale ${Rt()} (prior pid ${n} was dead); spawned fresh daemon at pid ${t.pid}.`}function ls(){let n=process.cwd(),e=["nx.json","angular.json","vite.config.ts","vite.config.js","vite.config.mjs","vite.config.cjs",".storybook"].filter(o=>B.existsSync(X.join(n,o)));if(!e.length)return{detected:!1,description:"no nx.json/angular.json/vite.config.*/.storybook in cwd"};let r=et();return r.kind!=="loaded"?{detected:!0,description:`${e.join(", ")} present but no config is loaded`,markerFiles:e}:r.config.searchRoots.map(o=>X.resolve(typeof o=="string"?o:o.path)).some(o=>n.startsWith(o))?{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 us(){let n=process.cwd(),{local:t,user:e}=ft(),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(o=>(typeof o=="string"?o:o?.path)===n)){let o;try{let a=JSON.parse(B.readFileSync(X.join(n,"package.json"),"utf8"));typeof a.name=="string"&&(o=a.name)}catch{}s.searchRoots.push(o?{path:n,label:o}:n)}B.mkdirSync(X.dirname(r),{recursive:!0}),B.writeFileSync(r,JSON.stringify(s,null,2)+`
33
- `,"utf8");let i=gt();if(i)try{fetch(`http://127.0.0.1:${i.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`appended ${n} as a searchRoot in ${r}; triggered soft-reload of the running daemon.`}function ps(){let n=et();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 at(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 fs(){let n=et();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 ms(n){let t={ran:[],skipped:[],errors:[]};for(let e of Ar){if(!n.permitted.includes(e))continue;let r=ds[e],s;try{s=await r.detect()}catch(i){t.errors.push({name:e,error:i?.message??String(i)});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 i=await r.fix();t.ran.push({name:e,detected:!0,description:`${s.description} \u2014 ${i}`})}catch(i){t.errors.push({name:e,error:i?.message??String(i)})}}return t}var Ar,ds,Rr=tt(()=>{"use strict";Q();kt();he();Ar=["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db"];ds={"orphan-daemon":{detect:os,fix:is},"stale-lock":{detect:as,fix:cs},"missing-search-root":{detect:ls,fix:us},"corrupt-history-db":{detect:ps,fix:fs}}});kt();ht();import lo from"react";import{render as uo}from"ink";import{pathToFileURL as po}from"node:url";import{EventEmitter as Ln}from"node:events";import{spawn as yn}from"node:child_process";import Ie from"tree-kill";import vn from"strip-ansi";import Yr from"node:crypto";var zr=[/Local:\s+http/i,/Application bundle generation complete/i,/compiled successfully/i,/webpack compiled/i,/Angular Live Development Server is listening/i],Vr=[/Building\.\.\./i,/Compilation started/i,/Initial chunk files/i,/Compiling/i],Qr=[/^\s*ERROR\b/,/\berror TS\d+/,/✘/,/\[ERROR\]/,/Cannot find module/i],Zr=/\berror TS(\d+)/,tn=/✘\s*\[ERROR\]\s*TS(\d+)/,en=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte)):(\d+):(\d+)/,rn=/^\s+([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte)):(\d+):(\d+):?\s*$/,nn=/Local:\s+(https?:\/\/\S+)/i,sn=/Server running at\s+(https?:\/\/\S+)/i,on=/listening on\s+(https?:\/\/\S+)/i,an=/(?:listening|listen)\s+(https?:\/\/\S+)/i,cn=/Initial chunk files/i,ln=/Lazy chunk files/i,un=/(Initial total|Lazy total)\s*\|?\s*([\d.]+)\s*(kB|MB|B)\b/i,pn=/^\s*\|?\s*([^\s|][^|]*?)\s*\|\s*([^|]+?)\s*\|\s*([\d.]+)\s*(kB|MB|B)\b/i;function fn(n){return Yr.createHash("sha1").update(n).digest("hex").slice(0,16)}function dn(n){let t={message:n},e=n.match(tn)||n.match(Zr);e&&(t.code=`TS${e[1]}`);let r=n.match(en);return r&&(t.file=r[1],t.line=Number(r[2]),t.col=Number(r[3])),t}function mn(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 hn(n,t="127.0.0.1"){let e=n.match(nn)||n.match(sn)||n.match(on)||n.match(an);if(!e)return null;let r=e[1].replace(/[),.;]+$/,"");return mn(r,t)}function gn(n,t){if(cn.test(t))return n.bundle||(n.bundle={initialKB:0,lazyKB:0,files:[]}),n._bundleSection="initial",!1;if(ln.test(t))return n.bundle||(n.bundle={initialKB:0,lazyKB:0,files:[]}),n._bundleSection="lazy",!1;let e=t.match(un);if(e&&n.bundle){let s=parseFloat(e[2]),i=e[3].toUpperCase(),o=Math.round(i==="MB"?s*1024:i==="B"?s/1024:s);return/Initial/i.test(e[1])?n.bundle.initialKB=o:n.bundle.lazyKB=o,!0}let r=t.match(pn);if(r&&n.bundle){let s=r[1].trim();if(/^(Initial|Lazy)\s+(total|chunk)/i.test(s))return!1;let i=r[4].toUpperCase(),o=parseFloat(r[3]),a=i==="MB"?o*1024:i==="B"?o/1024:o;return n.bundle.files.push({name:s,sizeKB:Math.round(a*10)/10}),!1}return!1}function Fe(n,t){let e=t.match(rn);if(e&&n.lastErrorHash){let p=n.errors.get(n.lastErrorHash);p&&!p.parsed?.file&&(p.parsed={...p.parsed??{message:p.message},file:e[1],line:Number(e[2]),col:Number(e[3])})}let r=t.trim();if(!r)return null;let s=n.status,i=!1,o,a=hn(r);a&&!n.announcedUrl&&(n.announcedUrl=a,o=a);let u=gn(n,r),c;if(zr.some(p=>p.test(r))){let p=n.status==="error"||!!n.recoveringFromError;if(n.status==="compiling"||n.status==="starting"||n.status==="error"){let b=Date.now();n.compileStartedAt!=null?(c=b-n.compileStartedAt,n.lastCompileMs=c,n.lastCompileAt=b,n.compileStartedAt=null,n.compileHistory.push(c),n.compileHistory.length>20&&n.compileHistory.splice(0,n.compileHistory.length-20)):n.lastCompileAt=b}n.status="serving",p&&(n.errors.clear(),n.recoveringFromError=!1)}else Vr.some(p=>p.test(r))&&(n.status==="starting"||n.status==="serving"||n.status==="error")&&(n.status==="error"&&(n.recoveringFromError=!0),n.compileStartedAt=Date.now(),n.status="compiling");let h;if(Qr.some(p=>p.test(r))){let p=fn(r),b=Date.now(),S=n.errors.get(p),l=!1,m;S?(S.count+=1,S.lastSeen=b,m=S):(m={message:r,count:1,firstSeen:b,lastSeen:b,parsed:dn(r)},n.errors.set(p,m),l=!0),n.lastErrorHash=p,h={entry:m,isNew:l},n.status="error"}return i=n.status!==s,{statusChanged:i,error:h,announcedUrl:o,bundleUpdated:u,compileMs:c}}var Be=500,xt=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 o=`${this.deps.commandOverride||t.command} --port ${e}`,a={...process.env,...t.env||{},...this.deps.envOverride||{},PORT:String(e),FORCE_COLOR:"0"},u=yn(o,[],{cwd:t.workspaceRoot,shell:!0,env:a,windowsHide:!0});this.child=u,r.pid=u.pid??null,r.port=e,u.stdout?.on("data",c=>this.handleChunk(c,"stdout")),u.stderr?.on("data",c=>this.handleChunk(c,"stderr")),u.on("exit",(c,h)=>{let p=r.status,b=this.stopping;b?(r.status="stopped",r.lastStatusMessage=`stopped (code=${c??"null"}${h?`, ${h}`:""})`):c!==0?(r.status="error",r.lastStatusMessage=`process exited with code ${c}${h?` (${h})`:""}`):r.status="stopped",r.pid=null,r.health="unknown",this.child=null,this.stopping=!1,p!==r.status&&this.deps.onStatusChange?.(p,r.status,r.lastStatusMessage),this.deps.onExit?.(c,h,b),this.deps.onStateChange()}),u.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,i=s.lastIndexOf(`
34
- `);if(i<0)return;let o=s.slice(0,i),a=s.slice(i+1);e==="stdout"?this.stdoutBuf=a:this.stderrBuf=a;let{state:u}=this.deps,c=!1;for(let h of o.split(/\r?\n/)){if(!h.length)continue;let p=vn(h),b=Date.now();u.lastLogTs=b,u.stale&&(u.stale=!1),u.logBuffer.push({ts:b,line:p}),u.logBuffer.length>Be&&u.logBuffer.splice(0,u.logBuffer.length-Be),this.deps.onLogLine?.(p);let S=u.status,l=Fe(u,p);l?.statusChanged&&(c=!0,this.deps.onStatusChange?.(S,u.status)),l?.error&&this.deps.onErrorRecorded?.(l.error.entry,l.error.isNew),l?.compileMs!=null&&this.deps.onCompile?.(l.compileMs),l?.bundleUpdated&&this.deps.onBundleUpdate?.()}(c||o.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())},i=()=>s();this.child?.once("exit",i),Ie(t,"SIGTERM",()=>{});let o=setTimeout(()=>{Ie(t,"SIGKILL",()=>{})},2e3),a=setTimeout(()=>{clearTimeout(o),s()},3e3);this.child?.once("exit",()=>{clearTimeout(o),clearTimeout(a),s()})})}};import wn from"node:net";var nt=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,i]of Object.entries(e.initial))typeof i=="number"&&(i<this.min||i>this.max||r.has(i)||(r.add(i),this.assigned.set(s,i)))}}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 i=this.min;i<=this.max;i++){if(s.has(i))continue;if(await Et(i))return this.assigned.set(t,i),this.onChange?.(this.snapshot()),i}throw new Error(`No free ports in range ${this.min}-${this.max}`)}async isPortAvailableForUse(t){return Et(t)}};function Et(n){return new Promise(t=>{let e=wn.createServer();e.unref(),e.once("error",()=>t(!1)),e.listen({port:n,host:"127.0.0.1",exclusive:!0},()=>{e.close(()=>t(!0))})})}import W from"node:fs";import bn from"node:path";var Tt=class{constructor(t,e){this.appName=t;this.cfg=e;this.filePath=bn.join(e.dir,`${t}.log`),this.open()}appName;cfg;fd=null;bytes=0;warned=!1;filePath;open(){try{W.mkdirSync(this.cfg.dir,{recursive:!0});try{this.bytes=W.statSync(this.filePath).size}catch{this.bytes=0}this.fd=W.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}
35
- `,r=Buffer.from(e,"utf8");W.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{W.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{W.rmSync(e,{force:!0})}catch{}continue}try{W.existsSync(e)&&W.renameSync(e,r)}catch{}}try{let t=`${this.filePath}.1`;W.existsSync(this.filePath)&&W.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}
36
- `))}};function He(n){let s=new Map,i=new Map,o=null,a=u=>{if(!o){s.set(u,1);for(let c of n[u]||[]){let h=s.get(c)??0;if(h===1){let p=[c,u],b=i.get(u);for(;b&&b!==c;)p.push(b),b=i.get(b);b===c&&p.push(c),o=p.reverse();return}if(h===0&&(i.set(c,u),a(c),o))return}s.set(u,2)}};for(let u of Object.keys(n))if((s.get(u)??0)===0&&(i.set(u,null),a(u),o))return o;return null}function Ue(n,t){let e=new Set,r=[t];for(;r.length;){let s=r.pop();if(!e.has(s)){e.add(s);for(let i of n[s]||[])r.push(i)}}return[...e]}function We(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 u of n[a]||[])e.has(u)&&(s.get(u).push(a),r.set(a,(r.get(a)??0)+1));let i=[],o=t.filter(a=>(r.get(a)??0)===0);for(;o.length;){i.push([...o].sort());let a=[];for(let u of o)for(let c of s.get(u)??[])r.set(c,(r.get(c)??1)-1),r.get(c)===0&&a.push(c);o=a}return i}function Je(n,t){let e=[];for(let[r,s]of Object.entries(n))s.includes(t)&&e.push(r);return e}import{spawn as qe}from"node:child_process";import Ge from"tree-kill";import Xe from"strip-ansi";var Sn=/Tests:\s+(?:(\d+)\s+failed,\s+)?(\d+)\s+passed(?:,\s+(\d+)\s+total)?/,kn=/Executed (\d+) of (\d+)(?:\s*\((\d+)\s*FAILED\))?/,xn=/(\d+)\s+passed(?:.*?(\d+)\s+failed)?/i;function En(n){let t=n.match(Sn);if(t){let s=t[1]?Number(t[1]):0,i=Number(t[2]),o=t[3]?Number(t[3]):i+s;return{passed:i,failed:s,total:o}}let e=n.match(kn);if(e){let s=Number(e[1]),i=Number(e[2]),o=e[3]?Number(e[3]):0;return{passed:s-o,failed:o,total:i}}let r=n.match(xn);if(r){let s=Number(r[1]),i=r[2]?Number(r[2]):0;return{passed:s,failed:i,total:s+i}}return null}function Ke(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 Ye(n,t,e=[]){return new Promise(r=>{let s=Date.now(),i=Ke(n,t,e),o=qe(i,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),a=[],u="",c=h=>{u+=h.toString("utf8");let p=u.lastIndexOf(`
37
- `);if(p<0)return;let b=u.slice(0,p);u=u.slice(p+1);for(let S of b.split(/\r?\n/)){if(!S.length)continue;let l=Xe(S);a.push(l),a.length>1e3&&a.splice(0,a.length-1e3)}};o.stdout?.on("data",c),o.stderr?.on("data",c),o.on("exit",h=>{let p=Date.now()-s,b=a.join(`
38
- `)+(u?`
39
- `+u:""),S=En(b);r({app:n.name,task:t,exitCode:h,durationMs:p,summary:S,outputTail:a.slice(-50)})}),o.on("error",()=>{r({app:n.name,task:t,exitCode:-1,durationMs:Date.now()-s,summary:null,outputTail:[...a,"[daimon] task spawn error"]})})})}function ze(n,t,e=[]){let r=Ke(n,t,e),s=qe(r,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),i=[],o="",a=c=>{o+=c.toString("utf8");let h=o.lastIndexOf(`
40
- `);if(h<0)return;let p=o.slice(0,h);o=o.slice(h+1);for(let b of p.split(/\r?\n/))b.length&&(i.push(Xe(b)),i.length>500&&i.splice(0,i.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:i,stop:()=>new Promise(c=>{if(!s.pid){c();return}let h=!1,p=()=>{h||(h=!0,c())};s.once("exit",p),Ge(s.pid,"SIGTERM",()=>{}),setTimeout(()=>{s.pid&&Ge(s.pid,"SIGKILL",()=>{})},2e3),setTimeout(p,3500)})}}import{spawnSync as ee}from"node:child_process";import Go from"tree-kill";function Ve(n){if(process.platform==="win32"){let i=ee("powershell",["-NoProfile","-Command",`Get-NetTCPConnection -LocalPort ${n} -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty OwningProcess`],{encoding:"utf8",windowsHide:!0});if(i.status!==0)return null;let o=Number((i.stdout||"").trim().split(/\s+/)[0]);if(!Number.isFinite(o)||o<=0)return null;let a=ee("powershell",["-NoProfile","-Command",`Get-CimInstance Win32_Process -Filter "ProcessId=${o}" | Select-Object -Property Name,CommandLine | ConvertTo-Json -Compress`],{encoding:"utf8",windowsHide:!0}),u,c;try{let h=JSON.parse((a.stdout||"").trim()||"{}");u=typeof h.Name=="string"?h.Name:void 0,c=typeof h.CommandLine=="string"?h.CommandLine:void 0}catch{}return{pid:o,name:u,cmd:c}}let t=ee("lsof",["-nP","-iTCP:"+n,"-sTCP:LISTEN"],{encoding:"utf8"});if(t.status!==0)return null;let e=(t.stdout||"").split(/\r?\n/).filter(i=>i.trim()&&!i.startsWith("COMMAND"));if(!e.length)return null;let r=e[0].split(/\s+/);return{pid:Number(r[1]),name:r[0]}}function Qe(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(" ")}import tr from"node:fs";import Ze from"node:path";function er(n){let t={},e;try{e=tr.readFileSync(n,"utf8")}catch{return t}for(let r of e.split(/\r?\n/)){let s=r.trim();if(!s||s.startsWith("#"))continue;let i=s.indexOf("=");if(i<0)continue;let o=s.slice(0,i).trim(),a=s.slice(i+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),o&&(t[o]=a)}return t}function re(n,t){return Ze.isAbsolute(t)?t:Ze.join(n,t)}function ne(n,t){return t.filter(e=>tr.existsSync(re(n,e)))}Q();import $n from"node:fs";import Nn from"node:path";function Mn(){return Nn.join(Y(),"secrets.json")}function ir(){try{let n=$n.readFileSync(Mn(),"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 ar(n,t){let e={};for(let[r,s]of Object.entries(n))e[r]=s.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,(i,o)=>t[o]??`\${${o}}`);return e}import ce from"node:fs";import _n from"node:os";import cr from"node:path";var Pt=class{file=null;startTs=0;isRecording(){return this.file!=null}start(){if(this.file)return{path:this.file};let t=cr.join(_n.homedir(),".daimon","sessions");ce.mkdirSync(t,{recursive:!0});let e=cr.join(t,`${new Date().toISOString().replace(/[:.]/g,"-")}.jsonl`);return ce.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})+`
41
- `;try{ce.appendFileSync(this.file,e)}catch{}}};var lr=500,Ot=class extends Ln{entries=new Map;portAlloc;config;eventBuffer=[];history=null;watchTasks=new Map;sessionRecorder=new Pt;constructor(t,e,r){super(),this.config=t,this.portAlloc=r??new nt(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}}names(){return[...this.entries.keys()]}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,o=this.config.overrides?.[t]?.url||e.resolvedUrl||r.announcedUrl||(r.port?`http://127.0.0.1:${r.port}`:null),a;for(let u=this.eventBuffer.length-1;u>=0;u--){let c=this.eventBuffer[u];if(c.app===t&&c.type==="status"){a=Date.now()-c.ts;break}}return{name:r.name,status:r.status,port:r.port,url:o,errorCount:[...r.errors.values()].reduce((u,c)=>u+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,i)=>i.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 i=Date.now()-e.sinceMs;s=s.filter(o=>o.ts>=i)}return e.tail&&e.tail>0&&(s=s.slice(-e.tail)),s.map(i=>i.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>lr&&this.eventBuffer.splice(0,this.eventBuffer.length-lr),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 i=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:i,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(S){return e.state.status="error",e.state.lastStatusMessage=S.message,this.recordEvent({app:t,type:"status",from:r,to:"error",message:S.message}),this.emit("change"),{ok:!1,status:"error",error:S.message}}if(!await Et(s)){let S=Ve(s),l=Qe(s,S);return e.state.status="error",e.state.port=s,e.state.lastStatusMessage=l,this.recordEvent({app:t,type:"status",from:r,to:"error",message:l}),this.emit("change"),{ok:!1,status:"error",error:l}}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 Tt(t,this.config.logs));let o=e.state.sessionOverrides,a=this.config.envFiles?.[t]??[],u={};if(a.length){let S=e.state.activeEnvFile;(!S||!ne(e.app.workspaceRoot,[S]).length)&&(S=ne(e.app.workspaceRoot,a)[0]??null,S&&(e.state.activeEnvFile=S)),S&&(u=er(re(e.app.workspaceRoot,S)))}let c={...u,...this.config.overrides?.[t]?.env??{},...o?.env??{}},h=ir(),p=ar(c,h),b=new xt({state:e.state,app:e.app,port:s,envOverride:Object.keys(p).length?p:void 0,commandOverride:o?.command,onStateChange:()=>this.emit("change"),onStatusChange:(S,l,m)=>{this.recordEvent({app:t,type:"status",from:S,to:l,message:m}),(l==="stopped"||l==="error")&&(S==="serving"||S==="compiling")&&this.armCascade(t)},onErrorRecorded:(S,l)=>this.recordEvent({app:t,type:l?"error-new":"error-recur",message:S.message}),onExit:(S,l,m)=>this.emit("childExit",{name:t,code:S,signal:l,stopping:m}),onLogLine:S=>{e.logger?.write(S),this.emit("log",{name:t,ts:Date.now(),line:S})},onCompile:S=>{this.history?.recordCompile(t,S);let l=this.getState(t),m=e.lastBundleInitialKB;if(l.bundle&&l.bundle.initialKB>0){if(m&&m>0){let g=(l.bundle.initialKB-m)/m*100;l.bundleRegressionPct=Math.round(g*10)/10,g>10&&this.recordEvent({app:t,type:"bundle-regression",message:`initialKB +${l.bundleRegressionPct}% (${m}->${l.bundle.initialKB})`})}else l.bundleRegressionPct=null;e.lastBundleInitialKB=l.bundle.initialKB}this.checkCompileRegression(t,S),this.emit("compile",{name:t,ms:S})},onBundleUpdate:()=>this.emit("bundleUpdate",{name:t})});return e.proc=b,this.recordEvent({app:t,type:"status",from:r,to:"starting"}),b.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=Ue(this.config.depends??{},t).filter(a=>this.entries.has(a)),s=We(this.config.depends??{},r),i=[],o=e.waitMs??6e4;for(let a of s){let u=await Promise.all(a.map(h=>this.start(h)));for(let h=0;h<a.length;h++){let p=u[h];if(!p.ok)return i.push({name:a[h],status:p.status,health:"unknown",error:p.error}),{ok:!1,results:i}}let c=await Promise.all(a.map(h=>this.waitFor(h,"healthy",o)));for(let h=0;h<a.length;h++){let p=c[h],b=!p.timedOut&&p.status==="serving"&&p.health==="healthy";if(i.push({name:p.name,status:p.status,health:p.health,error:b?void 0:p.timedOut?"timeout waiting for healthy":"did not reach healthy"}),!b)return{ok:!1,results:i}}}return{ok:!0,results:i}}triggerCascadeRestart(t){if(!this.config.cascadeRestart)return;let e=Je(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 i=await Ye(s,e,r);return this.history?.recordTaskRun(t,e,i.exitCode,i.durationMs,i.summary),this.recordEvent({app:t,type:"task-run",message:`${e} exit=${i.exitCode} duration=${i.durationMs}ms`}),this.emit("taskRun",{name:t,task:e,result:i}),i}startWatchTask(t,e,r=[]){let s=this.getApp(t);if(!s)return{ok:!1,error:"unknown app"};let i=`${t}::${e}`;if(this.watchTasks.has(i))return{ok:!0,pid:this.watchTasks.get(i).pid};let o=ze(s,e,r);return this.watchTasks.set(i,o),o.child.on("exit",()=>this.watchTasks.delete(i)),{ok:!0,pid:o.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 i=r.queryCompiles({app:t,limit:31}).filter(u=>u.ms!==e).slice(0,30).map(u=>u.ms);if(i.length<10)return;let o=[...i].sort((u,c)=>u-c),a=o[Math.floor((o.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 i=s.logs;return r?i.slice(-r):[...i]}waitFor(t,e,r){return new Promise(s=>{let i=Date.now(),o=this.entries.get(t),a=()=>{if(!o)return!0;let p=o.state;return e==="serving"&&p.status==="serving"||e==="healthy"&&p.status==="serving"&&p.health==="healthy"||e==="stopped"&&p.status==="stopped"||e==="error"&&p.status==="error"},u=p=>{this.off("change",c),clearTimeout(h);let b=o?.state;s({name:t,status:b?.status??"unknown",health:b?.health??"unknown",timedOut:p,waitedMs:Date.now()-i})},c=()=>{a()&&u(!1)};if(a()){s({name:t,status:o.state.status,health:o.state.health,timedOut:!1,waitedMs:0});return}let h=setTimeout(()=>u(!0),r);this.on("change",c)})}};import hs from"node:http";import gs from"node:crypto";import It from"node:fs";import F from"node:path";import{fileURLToPath as ys}from"node:url";import pe from"node:fs";import ur from"node:path";import Dn from"node:os";var fe=ur.join(Dn.homedir(),".daimon","cursors.json");function Fn(){try{let n=pe.readFileSync(fe,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.errors&&typeof t.errors=="object")return{errors:t.errors}}catch{}return{errors:{}}}var le=null,ue=null;function In(n){ue=n,!le&&(le=setTimeout(()=>{le=null;let t=ue;if(ue=null,!!t)try{pe.mkdirSync(ur.dirname(fe),{recursive:!0}),pe.writeFileSync(fe,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: cursor write failed: ${e.message}
42
- `)}},500))}var jt=class{data=Fn();getErrorCursor(t,e){return this.data.errors[`${t}:${e}`]??0}setErrorCursor(t,e,r){this.data.errors[`${t}:${e}`]=r,In(this.data)}};import pr from"node:fs";import Bn from"node:os";import fr from"node:path";var Hn=/key|secret|token|password|api[-_]?key/i;function Un(n){let t={};for(let[e,r]of Object.entries(n))typeof r=="string"&&(t[e]=Hn.test(e)?"***":r);return t}function de(n,t){let e=n.summary(t);if(!e)return null;let r=n.getState(t),s=n.getApp(t),i=n.getConfig(),o=i.overrides?.[t]??{},a={...process.env,...s.env??{},...r.sessionOverrides?.env??{}},u=n.getHistory(),c=u?u.queryEvents({app:t,limit:50}):[];return{takenAt:new Date().toISOString(),summary:e,logs:r.logBuffer.slice(-500).map(h=>({ts:h.ts,line:h.line})),errors:[...r.errors.entries()].map(([h,p])=>({hash:h,message:p.message,count:p.count,firstSeen:p.firstSeen,lastSeen:p.lastSeen})),env:Un(a),configSlice:{command:r.sessionOverrides?.command??o.command??s.command,port:r.sessionOverrides?.port??o.port??null,workspaceRoot:s.workspaceRoot,workspaceType:s.workspaceType,tags:s.tags,depends:i.depends?.[t]??[],envFiles:i.envFiles?.[t]??[]},events:c}}function dr(n,t){let e=de(n,t);if(!e)return null;let r=fr.join(Bn.homedir(),".daimon","snapshots");pr.mkdirSync(r,{recursive:!0});let s=e.takenAt.replace(/[:.]/g,"-"),i=fr.join(r,`${t}-${s}.json`);return pr.writeFileSync(i,JSON.stringify(e,null,2)),{path:i,payload:e}}import $t from"node:fs";import mr from"node:path";var Wn=["dist",".angular/cache","tmp","out-tsc"],Jn=["node_modules"];function hr(n){let t=0;try{let e=$t.readdirSync(n,{withFileTypes:!0});for(let r of e){let s=mr.join(n,r.name);try{r.isDirectory()?t+=hr(s):r.isFile()&&(t+=$t.statSync(s).size)}catch{}}}catch{}return t}function me(n,t,e){let r=n.getApp(t);if(!r)return null;let s=n.getState(t),i=s?s.status==="serving"||s.status==="compiling"||s.status==="starting":!1,a=[...Wn,...e?Jn:[]].map(u=>{let c=mr.join(r.workspaceRoot,u),h=$t.existsSync(c);return{path:c,exists:h,sizeBytes:h?hr(c):0}});return{app:t,workspace:r.workspaceRoot,targets:a,ranOnServing:i}}function gr(n,t,e){let r=me(n,t,e);if(!r)return{error:"unknown app"};if(r.ranOnServing)return{error:"app is currently running; stop it first"};let s=[],i=[];for(let o of r.targets)if(o.exists)try{$t.rmSync(o.path,{recursive:!0,force:!0}),s.push(o.path)}catch(a){i.push({path:o.path,error:a?.message||String(a)})}return{ok:i.length===0,removed:s,failed:i}}function vt(n){return n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}var Gn=["stopped","starting","compiling","serving","error"];function yr(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 Gn)t.push(`daimon_app_status{name="${vt(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="${vt(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="${vt(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="${vt(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="${vt(r.name)}"} ${r.memMB}`);return t.join(`
32
+ CREATE TABLE IF NOT EXISTS bundles (
33
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
34
+ ts INTEGER NOT NULL,
35
+ app TEXT NOT NULL,
36
+ initialKB INTEGER NOT NULL,
37
+ lazyKB INTEGER NOT NULL,
38
+ fileCount INTEGER NOT NULL
39
+ );
40
+ CREATE INDEX IF NOT EXISTS bundles_app_ts ON bundles(app, ts);
41
+ `)}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,i=Date.now()){this.db&&this.queue.push({kind:"bundle",row:{ts:i,app:t,initialKB:e,lazyKB:r,fileCount:s}})}recordTaskRun(t,e,r,s,i,o=Date.now()){this.db&&this.queue.push({kind:"task",row:{ts:o,app:t,task:e,exit_code:r,duration_ms:s,summary:i==null?null:JSON.stringify(i)}})}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 (?,?,?,?,?,?)"),i=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"?i.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)}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,i=(h,p)=>{let v=Math.floor(h/r)*r,b=s.get(v)??{sum:0,n:0};b.sum+=p,b.n+=1,s.set(v,b)},o=h=>{let p=Math.floor(h/r)*r,v=s.get(p)??{sum:0,n:0};v.sum+=1,v.n+=1,s.set(p,v)},a=0;if(t.metric==="compile"){let h=this.queryCompiles({app:t.app,since:e,limit:1e4});a=h.length;for(let p of h)i(p.ts,p.ms)}else if(t.metric==="bundle"){let h=this.queryBundles({app:t.app,since:e,limit:1e4});a=h.length;for(let p of h){let v=Math.floor(p.ts/r)*r,b=s.get(v)??{sum:0,n:0,sum2:0};b.sum+=p.initialKB,b.sum2=(b.sum2??0)+p.lazyKB,b.n+=1,s.set(v,b)}}else if(t.metric==="errors"){let h=this.queryEvents({app:t.app,since:e,limit:1e4});for(let p of h)(p.type==="error-new"||p.type==="error-recur")&&(o(p.ts),a++)}else{let h=this.queryEvents({app:t.app,since:e,limit:1e4});for(let p of h)p.type==="status"&&p.to_state==="starting"&&(p.from_state==="error"||p.from_state==="serving"||p.from_state==="compiling")&&(o(p.ts),a++)}let c=[],u=[...s.entries()].sort((h,p)=>h[0]-p[0]);for(let[h,p]of u)t.metric==="compile"||t.metric==="bundle"?c.push({t:h,v:Math.round(p.sum/p.n),...p.sum2!=null?{v2:Math.round(p.sum2/p.n)}:{}}):c.push({t:h,v:p.sum});return{points:c,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,i=e,o=!1,a=null,c=[...r].sort((d,g)=>d.ts-g.ts);for(let d of c)d.type==="status"&&(d.to_state==="serving"&&!o?(o=!0,a=d.ts):o&&d.to_state!=="serving"&&a!=null&&(s+=d.ts-a,o=!1,a=null));o&&a!=null&&(s+=Date.now()-a);let u=Math.round(s/(24*3600*1e3)*1e3)/10,h=r.filter(d=>d.type==="status"&&d.to_state==="starting"&&(d.from_state==="serving"||d.from_state==="error"||d.from_state==="compiling")).length,p=this.queryCompiles({app:t,since:e,limit:1e3}).map(d=>d.ms).sort((d,g)=>d-g),v=(d,g)=>{if(d.length===0)return null;let T=Math.min(d.length-1,Math.floor((d.length-1)*g));return d[T]},b=v(p,.5),l=v(p,.95),m=new Map;for(let d of r)if(d.type==="error-new"||d.type==="error-recur"){let g=d.message??"";if(!g)continue;m.set(g,(m.get(g)??0)+1)}let f=[...m.entries()].sort((d,g)=>g[1]-d[1]).slice(0,5).map(([d,g])=>({message:d,count:g}));return{uptimePct24h:u,restartCount24h:h,compileP50:b,compileP95:l,topErrors:f}}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,i=s?s.ts:Date.now(),o=e.filter(a=>a.ts<i).slice(0,5);return{trigger:s,preceding:o.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}))}}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}}}});var jt={};Dt(jt,{ALL_AUTO_FIX:()=>tn,runAutoFix:()=>wo});import _ from"node:fs";import B from"node:path";function to(){let n=wt();if(!n)return{detected:!1,description:"no daemon running"};let t=process.cwd(),e=B.join(t,"daimon.config.json");if(!_.existsSync(e))return{detected:!1,description:"no local daimon.config.json in cwd"};let r=n.cwd,s=n.configPath,i=r&&B.resolve(r)===B.resolve(t),o=s&&B.resolve(s)===B.resolve(e);return i||o?{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 eo(){let n=wt();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 jr(n.pid,5e3),Pt(),`respawned daemon at pid ${(await Re({})).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 ro(){let n;try{n=_.readFileSync(Kt(),"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 no(){let n="(unknown)";try{let e=JSON.parse(_.readFileSync(Kt(),"utf8"));n=String(e?.pid??"?")}catch{}Pt();let t=await Re({});return`removed stale ${Kt()} (prior pid ${n} was dead); spawned fresh daemon at pid ${t.pid}.`}function so(){let n=process.cwd(),e=["nx.json","angular.json","vite.config.ts","vite.config.js","vite.config.mjs","vite.config.cjs",".storybook"].filter(o=>_.existsSync(B.join(n,o)));if(!e.length)return{detected:!1,description:"no nx.json/angular.json/vite.config.*/.storybook in cwd"};let r=Q();return r.kind!=="loaded"?{detected:!0,description:`${e.join(", ")} present but no config is loaded`,markerFiles:e}:r.config.searchRoots.map(o=>B.resolve(typeof o=="string"?o:o.path)).some(o=>n.startsWith(o))?{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 oo(){let n=process.cwd(),{local:t,user:e}=pt(),r=_.existsSync(t)?t:e,s={};try{s=JSON.parse(_.readFileSync(r,"utf8"))}catch{}if(s.searchRoots=Array.isArray(s.searchRoots)?s.searchRoots:[],!s.searchRoots.some(o=>(typeof o=="string"?o:o?.path)===n)){let o;try{let a=JSON.parse(_.readFileSync(B.join(n,"package.json"),"utf8"));typeof a.name=="string"&&(o=a.name)}catch{}s.searchRoots.push(o?{path:n,label:o}:n)}_.mkdirSync(B.dirname(r),{recursive:!0}),_.writeFileSync(r,JSON.stringify(s,null,2)+`
42
+ `,"utf8");let i=wt();if(i)try{fetch(`http://127.0.0.1:${i.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`appended ${n} as a searchRoot in ${r}; triggered soft-reload of the running daemon.`}function io(){let n=Q();if(n.kind!=="loaded"||!n.config.history.enabled)return{detected:!1,description:"history disabled"};let t=n.config.history.path;if(!_.existsSync(t))return{detected:!1,description:"history db does not exist (will be created on next start)"};try{let e=new St(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 ao(){let n=Q();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{_.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 co(){let n=Q();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"),i=Array.from(new Set([...s,t,e])),o=[];for(let a of i)if(!(!Number.isFinite(a)||a<=0))try{await gt(a)||o.push(a)}catch{}return o.length?{detected:!0,description:`ports already LISTEN: ${o.join(", ")} (range ${t}-${e} + pinned overrides)`,conflicts:o}:{detected:!1,description:`all checked ports free (range ${t}-${e} + pinned)`}}function lo(){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 uo(){let n=process.cwd(),t=process.versions.node,e=B.join(n,".nvmrc");if(_.existsSync(e)){let s=_.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=B.join(n,"package.json");if(_.existsSync(r))try{let i=JSON.parse(_.readFileSync(r,"utf8"))?.engines?.node;if(typeof i=="string"&&i.trim()){let o=i.match(/(\d+)(?:\.(\d+))?/);if(o){let a=Number(o[1]),c=Number(t.split(".")[0]);if(Number.isFinite(a)&&Number.isFinite(c)&&c<a)return{detected:!0,description:`package.json engines.node = "${i}" but running ${t}`,expected:i,actual:t}}}}catch{}return{detected:!1,description:`node ${t} satisfies .nvmrc / engines.node (or neither is present)`}}function po(){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 fo(){let n=Q();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||!_.existsSync(s)||e.has(s))continue;e.add(s);let i=B.join(s,"package.json");if(!_.existsSync(i))continue;let o=null;for(let a of["package-lock.json","pnpm-lock.yaml","yarn.lock"]){let c=B.join(s,a);if(_.existsSync(c)){o=c;break}}t.push({name:B.basename(s),root:s,pkgPath:i,lockPath:o,nmPath:B.join(s,"node_modules")})}return t}function en(){let n=fo();if(!n.length)return{detected:!1,description:"no searchRoots with package.json found"};let t=[];for(let r of n){if(!_.existsSync(r.nmPath)){t.push({root:r.root,reason:"missing"});continue}if(r.lockPath)try{let s=_.statSync(r.lockPath).mtimeMs,i=_.statSync(r.nmPath).mtimeMs;s>i+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 mo(){let n=en();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 _e(){let n=Q();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||!_.existsSync(s)||e.has(s)||(e.add(s),t.push(s))}return t}function rn(){let n=_e();if(!n.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let r of n){let s=B.join(r,"pyproject.toml"),i=B.join(r,"requirements.txt"),o=B.join(r,"manage.py");if(!(_.existsSync(s)||_.existsSync(i)||_.existsSync(o)))continue;let c=[".venv","venv","env"].map(h=>B.join(r,h)).find(h=>_.existsSync(h));if(!c){t.push({root:r,reason:"missing"});continue}let u=[];for(let h of[s,i])if(_.existsSync(h))try{u.push(_.statSync(h).mtimeMs)}catch{}if(u.length)try{let h=_.statSync(c).mtimeMs;Math.max(...u)>h+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 ho(){let n=rn();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 nn(){let n=_e();if(!n.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let r of n){let s=B.join(r,"Gemfile");if(!_.existsSync(s))continue;let i=B.join(r,"Gemfile.lock"),o=B.join(r,"vendor","bundle"),a=B.join(r,".bundle"),c=_.existsSync(o)?o:_.existsSync(a)?a:null;if(!c){t.push({root:r,reason:"missing"});continue}if(_.existsSync(i))try{let u=_.statSync(i).mtimeMs,h=_.statSync(c).mtimeMs;u>h+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 go(){let n=nn();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 sn(){let n=_e();if(!n.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let r of n){let s=B.join(r,"Cargo.toml");if(!_.existsSync(s))continue;let i=B.join(r,"Cargo.lock"),o=B.join(r,"target");if(!_.existsSync(o)){t.push({root:r,reason:"missing"});continue}if(_.existsSync(i))try{let a=_.statSync(i).mtimeMs,c=_.statSync(o).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 yo(){let n=sn();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 on(){let n=Q();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&&(_.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 vo(){let n=on();if(!n.detected||!n.dead||!n.dead.length)return"nothing to remove";let{local:t,user:e}=pt(),r=_.existsSync(t)?t:e,s={};try{s=JSON.parse(_.readFileSync(r,"utf8"))}catch{}if(!Array.isArray(s.searchRoots))return"config has no searchRoots array; nothing removed";let i=new Set(n.dead),o=s.searchRoots.length;s.searchRoots=s.searchRoots.filter(u=>{let h=typeof u=="string"?u:u?.path;return!i.has(h)});let a=o-s.searchRoots.length;_.writeFileSync(r,JSON.stringify(s,null,2)+`
43
+ `,"utf8");let c=wt();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} (${[...i].join(", ")}); triggered soft-reload. To undo: edit ${r} and re-add the path(s).`}async function wo(n){let t={ran:[],skipped:[],errors:[]};for(let e of tn){if(!n.permitted.includes(e))continue;let r=bo[e],s;try{s=await r.detect()}catch(i){t.errors.push({name:e,error:i?.message??String(i)});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 i=await r.fix();t.ran.push({name:e,detected:!0,description:`${s.description} \u2014 ${i}`})}catch(i){t.errors.push({name:e,error:i?.message??String(i)})}}return t}var tn,bo,Nt=rt(()=>{"use strict";dt();Rt();$e();Bt();tn=["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"];bo={"orphan-daemon":{detect:to,fix:eo},"stale-lock":{detect:ro,fix:no},"missing-search-root":{detect:so,fix:oo},"corrupt-history-db":{detect:io,fix:ao},"port-conflict-pred":{detect:co,fix:lo},"node-version-mismatch":{detect:uo,fix:po},"orphan-node-modules":{detect:en,fix:mo},"orphan-venv":{detect:rn,fix:ho},"orphan-bundler-cache":{detect:nn,fix:go},"orphan-cargo-target":{detect:sn,fix:yo},"dead-search-root":{detect:on,fix:vo}}});var Le={};Dt(Le,{orchestrateProfile:()=>ko});function an(n,t,e,r,s){let i=n.summary(t);if(!i)return!1;if(e==="serving")return i.status==="serving";if(e==="healthy")return i.status==="serving"&&i.health==="healthy";let o=Date.now()-r;return i.status==="serving"&&i.health==="healthy"&&o>=s}async function cn(n,t,e,r,s){let i=Date.now();if(e!=="stable"){let c=await n.waitFor(t,e==="serving"?"serving":"healthy",r);return{reached:!c.timedOut,waitedMs:c.waitedMs}}let o=Date.now(),a=c=>{c?.app===t&&(o=Date.now())};n.on("event",a);try{for(;Date.now()-i<r;){if(an(n,t,e,o,s))return{reached:!0,waitedMs:Date.now()-i};await new Promise(c=>setTimeout(c,500))}return{reached:an(n,t,e,o,s),waitedMs:Date.now()-i}}finally{n.off("event",a)}}async function ko(n,t,e){let r=Date.now(),s=t.profiles?.[e.profile];if(!s)return{error:`unknown profile: ${e.profile}`};let i=s.filter(f=>n.summary(f)!=null),o=Array.from(new Set(i.flatMap(f=>Ut(t.depends??{},f)))).filter(f=>n.summary(f)!=null),a=Wt(t.depends??{},o),c=[];for(let f of o){let d=n.summary(f);d&&(e.goal==="serving"&&d.status==="serving"||(e.goal==="healthy"||e.goal==="stable")&&d.status==="serving"&&d.health==="healthy")&&c.push(f)}if(e.dryRun){let f=o.filter(d=>!c.includes(d));return{profile:e.profile,goal:e.goal,perApp:f.map(d=>({name:d,reached:!1,tries:0})),totalMs:Date.now()-r,allReached:f.length===0,dryRun:!0,plannedOrder:a,alreadyHealthy:c}}let u=Math.max(5e3,Math.floor(e.timeoutMs/2)),h=e.stableMs??5e3,p=new Map;for(let f of o)p.set(f,{name:f,reached:!1,tries:0});for(let f of a)await Promise.all(f.map(async d=>{let g=n.summary(d);if(!g){p.set(d,{name:d,reached:!1,tries:0,error:"unknown app"});return}if(c.includes(d)){p.set(d,{name:d,reached:!0,tries:0});return}g.status!=="starting"&&g.status!=="compiling"&&g.status!=="serving"&&await n.start(d)})),await Promise.all(f.map(async d=>{if(p.get(d)?.reached)return;let g=await cn(n,d,e.goal,u,h),T=p.get(d);T.tries=1,T.waitedMs=g.waitedMs,T.reached=g.reached,p.set(d,T)}));let v=[...p.values()].filter(f=>!f.reached);if(v.length>0){let{runAutoFix:f,ALL_AUTO_FIX:d}=await Promise.resolve().then(()=>(Nt(),jt)),g=t.doctor?.autoFix?.permitted??d,T=Math.max(5e3,e.timeoutMs-(Date.now()-r)),E=Math.max(5e3,Math.floor(T/Math.max(v.length,1))),y={ran:[]};try{y=await f({permitted:g,dryRun:!1})}catch{}let N=(y.ran??[]).map(C=>C.name);await Promise.all(v.map(async C=>{let S=p.get(C.name);S.tries=2;try{let M=await n.restart(C.name);M?.ok||(S.error=M?.error??"restart failed")}catch(M){S.error=M?.message??String(M)}let R=await cn(n,C.name,e.goal,E,h);if(S.waitedMs=(S.waitedMs??0)+R.waitedMs,S.reached=R.reached,!S.reached){let M=n.errors(C.name)??[];S.stillFailing=M.slice(0,3).map(x=>({file:x.parsed?.file??null,line:x.parsed?.line??null,code:x.parsed?.code??null,tool:x.parsed?.tool??null,message:x.parsed?.message??x.message}))}S.fixed=N,p.set(C.name,S)}))}let b=[...p.values()],l=b.every(f=>f.reached),m={profile:e.profile,goal:e.goal,perApp:b,totalMs:Date.now()-r,allReached:l};if(typeof e.budgetTokens=="number"&&e.budgetTokens>0){let f=e.budgetTokens,d=0,g=0;for(let T of b)if(T.stillFailing){let E=T.stillFailing.length*So;E>f?(d+=T.stillFailing.length,delete T.stillFailing):f-=E}for(;f<0||b.length*xo>Math.max(f,e.budgetTokens/4);){let T=b.findIndex(E=>E.reached);if(T===-1)break;b.splice(T,1),g++}(d||g)&&(m._meta={omitted:{}},d&&(m._meta.omitted.stillFailing=d),g&&(m._meta.omitted.perApp=g))}return m}var So,xo,De=rt(()=>{"use strict";Gt();So=60,xo=25});Rt();Ct();import bi from"react";import{render as wi}from"ink";import{pathToFileURL as Si}from"node:url";import{EventEmitter as Ms}from"node:events";import{spawn as ds}from"node:child_process";import hr from"tree-kill";import fs from"strip-ansi";import In from"node:crypto";var Bn=[/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],Hn=[/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],Un=[/^\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*\(/],Wn=/\berror TS(\d+)/,Gn=/✘\s*\[ERROR\]\s*TS(\d+)/,Jn=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte|py|rb|go|rs)):(\d+):(\d+)/,pr=/\(([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte|py|rb|go|rs)):(\d+):(\d+)\)/,qn=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte))\((\d+),(\d+)\)\s*:/,dr=/File\s+"([^"]+\.py)",\s+line\s+(\d+)/,fr=/^\s*-->\s+([^\s:]+\.rs):(\d+):(\d+)/,Kn=/^([^\s:()]+\.rb):(\d+):in\b/,Xn=/^FAIL\s+(\S+\.(?:tsx?|jsx?|mjs|cjs))(?:\s|$)/,zn=/^ERROR in\s+(\S+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte))(?:[:\s](\d+):(\d+))?/,Yn=/^\s+([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte)):(\d+):(\d+):?\s*$/,Vn=[{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):/}];function Zn(n){for(let{tool:t,rx:e}of Vn)if(e.test(n))return t}var Qn=/Local:\s+(https?:\/\/\S+)/i,ts=/Server running at\s+(https?:\/\/\S+)/i,es=/listening on\s+(https?:\/\/\S+)/i,rs=/(?:listening|listen)\s+(https?:\/\/\S+)/i,ns=/Initial chunk files/i,ss=/Lazy chunk files/i,os=/(Initial total|Lazy total)\s*\|?\s*([\d.]+)\s*(kB|MB|B)\b/i,is=/^\s*\|?\s*([^\s|][^|]*?)\s*\|\s*([^|]+?)\s*\|\s*([\d.]+)\s*(kB|MB|B)\b/i;function as(n){return In.createHash("sha1").update(n).digest("hex").slice(0,16)}function cs(n){let t={message:n},e=n.match(Gn)||n.match(Wn);e&&(t.code=`TS${e[1]}`);let r=n.match(qn)||n.match(pr)||n.match(Jn);if(r)t.file=r[1],t.line=Number(r[2]),t.col=Number(r[3]);else{let i=n.match(zn);if(i)t.file=i[1],i[2]&&(t.line=Number(i[2])),i[3]&&(t.col=Number(i[3]));else{let o=n.match(Xn);if(o)t.file=o[1];else{let a=n.match(fr);if(a)t.file=a[1],t.line=Number(a[2]),t.col=Number(a[3]);else{let c=n.match(dr);c&&(t.file=c[1],t.line=Number(c[2]))}}}}let s=Zn(n);return s&&(t.tool=s),t}function ls(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 us(n,t="127.0.0.1"){let e=n.match(Qn)||n.match(ts)||n.match(es)||n.match(rs);if(!e)return null;let r=e[1].replace(/[),.;]+$/,"");return ls(r,t)}function ps(n,t){if(ns.test(t))return n.bundle||(n.bundle={initialKB:0,lazyKB:0,files:[]}),n._bundleSection="initial",!1;if(ss.test(t))return n.bundle||(n.bundle={initialKB:0,lazyKB:0,files:[]}),n._bundleSection="lazy",!1;let e=t.match(os);if(e&&n.bundle){let s=parseFloat(e[2]),i=e[3].toUpperCase(),o=Math.round(i==="MB"?s*1024:i==="B"?s/1024:s);return/Initial/i.test(e[1])?n.bundle.initialKB=o:n.bundle.lazyKB=o,!0}let r=t.match(is);if(r&&n.bundle){let s=r[1].trim();if(/^(Initial|Lazy)\s+(total|chunk)/i.test(s))return!1;let i=r[4].toUpperCase(),o=parseFloat(r[3]),a=i==="MB"?o*1024:i==="B"?o/1024:o;return n.bundle.files.push({name:s,sizeKB:Math.round(a*10)/10}),!1}return!1}function mr(n,t){let e=t.match(Yn),r=e?null:t.match(pr),s=!e&&!r?t.match(fr):null,i=e??r??s;if(i&&n.lastErrorHash){let l=n.errors.get(n.lastErrorHash);l&&!l.parsed?.file&&(l.parsed={...l.parsed??{message:l.message},file:i[1],line:Number(i[2]),col:Number(i[3])})}else if(n.lastErrorHash){let l=t.match(dr),m=l?null:t.match(Kn);if(l||m){let f=n.errors.get(n.lastErrorHash);if(f&&!f.parsed?.file){let d=l??m;f.parsed={...f.parsed??{message:f.message},file:d[1],line:Number(d[2])}}}}let o=t.trim();if(!o)return null;let a=n.status,c=!1,u,h=us(o);h&&!n.announcedUrl&&(n.announcedUrl=h,u=h);let p=ps(n,o),v;if(Bn.some(l=>l.test(o))){let l=n.status==="error"||!!n.recoveringFromError;if(n.status==="compiling"||n.status==="starting"||n.status==="error"){let m=Date.now();n.compileStartedAt!=null?(v=m-n.compileStartedAt,n.lastCompileMs=v,n.lastCompileAt=m,n.compileStartedAt=null,n.compileHistory.push(v),n.compileHistory.length>20&&n.compileHistory.splice(0,n.compileHistory.length-20)):n.lastCompileAt=m}n.status="serving",l&&(n.errors.clear(),n.recoveringFromError=!1)}else Hn.some(l=>l.test(o))&&(n.status==="starting"||n.status==="serving"||n.status==="error")&&(n.status==="error"&&(n.recoveringFromError=!0),n.compileStartedAt=Date.now(),n.status="compiling");let b;if(Un.some(l=>l.test(o))){let l=as(o),m=Date.now(),f=n.errors.get(l),d=!1,g;f?(f.count+=1,f.lastSeen=m,g=f):(g={message:o,count:1,firstSeen:m,lastSeen:m,parsed:cs(o)},n.errors.set(l,g),d=!0),n.lastErrorHash=l,b={entry:g,isNew:d},n.status="error"}return c=n.status!==a,{statusChanged:c,error:b,announcedUrl:u,bundleUpdated:p,compileMs:v}}var gr=500,It=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 o=`${this.deps.commandOverride||t.command} --port ${e}`,a={...process.env,...t.env||{},...this.deps.envOverride||{},PORT:String(e),FORCE_COLOR:"0"},c=ds(o,[],{cwd:t.workspaceRoot,shell:!0,env:a,windowsHide:!0});this.child=c,r.pid=c.pid??null,r.port=e,c.stdout?.on("data",u=>this.handleChunk(u,"stdout")),c.stderr?.on("data",u=>this.handleChunk(u,"stderr")),c.on("exit",(u,h)=>{let p=r.status,v=this.stopping;v?(r.status="stopped",r.lastStatusMessage=`stopped (code=${u??"null"}${h?`, ${h}`:""})`):u!==0?(r.status="error",r.lastStatusMessage=`process exited with code ${u}${h?` (${h})`:""}`):r.status="stopped",r.pid=null,r.health="unknown",this.child=null,this.stopping=!1,p!==r.status&&this.deps.onStatusChange?.(p,r.status,r.lastStatusMessage),this.deps.onExit?.(u,h,v),this.deps.onStateChange()}),c.on("error",u=>{r.status="error",r.lastStatusMessage=`spawn error: ${u.message}`,this.deps.onStateChange()}),this.deps.onStateChange()}handleChunk(t,e){let r=t.toString("utf8"),s=this[e==="stdout"?"stdoutBuf":"stderrBuf"]+=r,i=s.lastIndexOf(`
44
+ `);if(i<0)return;let o=s.slice(0,i),a=s.slice(i+1);e==="stdout"?this.stdoutBuf=a:this.stderrBuf=a;let{state:c}=this.deps,u=!1;for(let h of o.split(/\r?\n/)){if(!h.length)continue;let p=fs(h),v=Date.now();c.lastLogTs=v,c.stale&&(c.stale=!1),c.logBuffer.push({ts:v,line:p}),c.logBuffer.length>gr&&c.logBuffer.splice(0,c.logBuffer.length-gr),this.deps.onLogLine?.(p);let b=c.status,l=mr(c,p);l?.statusChanged&&(u=!0,this.deps.onStatusChange?.(b,c.status)),l?.error&&this.deps.onErrorRecorded?.(l.error.entry,l.error.isNew),l?.compileMs!=null&&this.deps.onCompile?.(l.compileMs),l?.bundleUpdated&&this.deps.onBundleUpdate?.()}(u||o.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())},i=()=>s();this.child?.once("exit",i),hr(t,"SIGTERM",()=>{});let o=setTimeout(()=>{hr(t,"SIGKILL",()=>{})},2e3),a=setTimeout(()=>{clearTimeout(o),s()},3e3);this.child?.once("exit",()=>{clearTimeout(o),clearTimeout(a),s()})})}};Bt();import tt from"node:fs";import hs from"node:path";var Ht=class{constructor(t,e){this.appName=t;this.cfg=e;this.filePath=hs.join(e.dir,`${t}.log`),this.open()}appName;cfg;fd=null;bytes=0;warned=!1;filePath;open(){try{tt.mkdirSync(this.cfg.dir,{recursive:!0});try{this.bytes=tt.statSync(this.filePath).size}catch{this.bytes=0}this.fd=tt.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}
45
+ `,r=Buffer.from(e,"utf8");tt.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{tt.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{tt.rmSync(e,{force:!0})}catch{}continue}try{tt.existsSync(e)&&tt.renameSync(e,r)}catch{}}try{let t=`${this.filePath}.1`;tt.existsSync(this.filePath)&&tt.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}
46
+ `))}};Gt();import{spawn as wr}from"node:child_process";import br from"tree-kill";import Sr from"strip-ansi";var gs=/Tests:\s+(?:(\d+)\s+failed,\s+)?(\d+)\s+passed(?:,\s+(\d+)\s+total)?/,ys=/Executed (\d+) of (\d+)(?:\s*\((\d+)\s*FAILED\))?/,vs=/(\d+)\s+passed(?:.*?(\d+)\s+failed)?/i;function bs(n){let t=n.match(gs);if(t){let s=t[1]?Number(t[1]):0,i=Number(t[2]),o=t[3]?Number(t[3]):i+s;return{passed:i,failed:s,total:o}}let e=n.match(ys);if(e){let s=Number(e[1]),i=Number(e[2]),o=e[3]?Number(e[3]):0;return{passed:s-o,failed:o,total:i}}let r=n.match(vs);if(r){let s=Number(r[1]),i=r[2]?Number(r[2]):0;return{passed:s,failed:i,total:s+i}}return null}function xr(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 kr(n,t,e=[]){return new Promise(r=>{let s=Date.now(),i=xr(n,t,e),o=wr(i,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),a=[],c="",u=h=>{c+=h.toString("utf8");let p=c.lastIndexOf(`
47
+ `);if(p<0)return;let v=c.slice(0,p);c=c.slice(p+1);for(let b of v.split(/\r?\n/)){if(!b.length)continue;let l=Sr(b);a.push(l),a.length>1e3&&a.splice(0,a.length-1e3)}};o.stdout?.on("data",u),o.stderr?.on("data",u),o.on("exit",h=>{let p=Date.now()-s,v=a.join(`
48
+ `)+(c?`
49
+ `+c:""),b=bs(v);r({app:n.name,task:t,exitCode:h,durationMs:p,summary:b,outputTail:a.slice(-50)})}),o.on("error",()=>{r({app:n.name,task:t,exitCode:-1,durationMs:Date.now()-s,summary:null,outputTail:[...a,"[daimon] task spawn error"]})})})}function Tr(n,t,e=[]){let r=xr(n,t,e),s=wr(r,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),i=[],o="",a=u=>{o+=u.toString("utf8");let h=o.lastIndexOf(`
50
+ `);if(h<0)return;let p=o.slice(0,h);o=o.slice(h+1);for(let v of p.split(/\r?\n/))v.length&&(i.push(Sr(v)),i.length>500&&i.splice(0,i.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:i,stop:()=>new Promise(u=>{if(!s.pid){u();return}let h=!1,p=()=>{h||(h=!0,u())};s.once("exit",p),br(s.pid,"SIGTERM",()=>{}),setTimeout(()=>{s.pid&&br(s.pid,"SIGKILL",()=>{})},2e3),setTimeout(p,3500)})}}import{spawnSync as we}from"node:child_process";import Qi from"tree-kill";function Er(n){if(process.platform==="win32"){let i=we("powershell",["-NoProfile","-Command",`Get-NetTCPConnection -LocalPort ${n} -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty OwningProcess`],{encoding:"utf8",windowsHide:!0});if(i.status!==0)return null;let o=Number((i.stdout||"").trim().split(/\s+/)[0]);if(!Number.isFinite(o)||o<=0)return null;let a=we("powershell",["-NoProfile","-Command",`Get-CimInstance Win32_Process -Filter "ProcessId=${o}" | Select-Object -Property Name,CommandLine | ConvertTo-Json -Compress`],{encoding:"utf8",windowsHide:!0}),c,u;try{let h=JSON.parse((a.stdout||"").trim()||"{}");c=typeof h.Name=="string"?h.Name:void 0,u=typeof h.CommandLine=="string"?h.CommandLine:void 0}catch{}return{pid:o,name:c,cmd:u}}let t=we("lsof",["-nP","-iTCP:"+n,"-sTCP:LISTEN"],{encoding:"utf8"});if(t.status!==0)return null;let e=(t.stdout||"").split(/\r?\n/).filter(i=>i.trim()&&!i.startsWith("COMMAND"));if(!e.length)return null;let r=e[0].split(/\s+/);return{pid:Number(r[1]),name:r[0]}}function Rr(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(" ")}import Cr from"node:fs";import Ar from"node:path";function Pr(n){let t={},e;try{e=Cr.readFileSync(n,"utf8")}catch{return t}for(let r of e.split(/\r?\n/)){let s=r.trim();if(!s||s.startsWith("#"))continue;let i=s.indexOf("=");if(i<0)continue;let o=s.slice(0,i).trim(),a=s.slice(i+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),o&&(t[o]=a)}return t}function Se(n,t){return Ar.isAbsolute(t)?t:Ar.join(n,t)}function xe(n,t){return t.filter(e=>Cr.existsSync(Se(n,e)))}dt();import As from"node:fs";import Cs from"node:path";function Ps(){return Cs.join(ot(),"secrets.json")}function $r(){try{let n=As.readFileSync(Ps(),"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 _r(n,t){let e={};for(let[r,s]of Object.entries(n))e[r]=s.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,(i,o)=>t[o]??`\${${o}}`);return e}import Ae from"node:fs";import Os from"node:os";import Lr from"node:path";var Xt=class{file=null;startTs=0;isRecording(){return this.file!=null}start(){if(this.file)return{path:this.file};let t=Lr.join(Os.homedir(),".daimon","sessions");Ae.mkdirSync(t,{recursive:!0});let e=Lr.join(t,`${new Date().toISOString().replace(/[:.]/g,"-")}.jsonl`);return Ae.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})+`
51
+ `;try{Ae.appendFileSync(this.file,e)}catch{}}};var Dr=500,zt=class extends Ms{entries=new Map;portAlloc;config;eventBuffer=[];history=null;watchTasks=new Map;sessionRecorder=new Xt;constructor(t,e,r){super(),this.config=t,this.portAlloc=r??new ht(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()]}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,o=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 u=this.eventBuffer[c];if(u.app===t&&u.type==="status"){a=Date.now()-u.ts;break}}return{name:r.name,status:r.status,port:r.port,url:o,errorCount:[...r.errors.values()].reduce((c,u)=>c+u.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,i)=>i.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 i=Date.now()-e.sinceMs;s=s.filter(o=>o.ts>=i)}return e.tail&&e.tail>0&&(s=s.slice(-e.tail)),s.map(i=>i.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>Dr&&this.eventBuffer.splice(0,this.eventBuffer.length-Dr),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 i=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:i,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(b){return e.state.status="error",e.state.lastStatusMessage=b.message,this.recordEvent({app:t,type:"status",from:r,to:"error",message:b.message}),this.emit("change"),{ok:!1,status:"error",error:b.message}}if(!await gt(s)){let b=Er(s),l=Rr(s,b);return e.state.status="error",e.state.port=s,e.state.lastStatusMessage=l,this.recordEvent({app:t,type:"status",from:r,to:"error",message:l}),this.emit("change"),{ok:!1,status:"error",error:l}}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 Ht(t,this.config.logs));let o=e.state.sessionOverrides,a=this.config.envFiles?.[t]??[],c={};if(a.length){let b=e.state.activeEnvFile;(!b||!xe(e.app.workspaceRoot,[b]).length)&&(b=xe(e.app.workspaceRoot,a)[0]??null,b&&(e.state.activeEnvFile=b)),b&&(c=Pr(Se(e.app.workspaceRoot,b)))}let u={...c,...this.config.overrides?.[t]?.env??{},...o?.env??{}},h=$r(),p=_r(u,h),v=new It({state:e.state,app:e.app,port:s,envOverride:Object.keys(p).length?p:void 0,commandOverride:o?.command,onStateChange:()=>this.emit("change"),onStatusChange:(b,l,m)=>{this.recordEvent({app:t,type:"status",from:b,to:l,message:m}),(l==="stopped"||l==="error")&&(b==="serving"||b==="compiling")&&this.armCascade(t)},onErrorRecorded:(b,l)=>this.recordEvent({app:t,type:l?"error-new":"error-recur",message:b.message}),onExit:(b,l,m)=>this.emit("childExit",{name:t,code:b,signal:l,stopping:m}),onLogLine:b=>{e.logger?.write(b),this.emit("log",{name:t,ts:Date.now(),line:b})},onCompile:b=>{this.history?.recordCompile(t,b);let l=this.getState(t),m=e.lastBundleInitialKB;if(l.bundle&&l.bundle.initialKB>0){if(m&&m>0){let f=(l.bundle.initialKB-m)/m*100;l.bundleRegressionPct=Math.round(f*10)/10,f>10&&this.recordEvent({app:t,type:"bundle-regression",message:`initialKB +${l.bundleRegressionPct}% (${m}->${l.bundle.initialKB})`})}else l.bundleRegressionPct=null;e.lastBundleInitialKB=l.bundle.initialKB}this.checkCompileRegression(t,b),this.emit("compile",{name:t,ms:b})},onBundleUpdate:()=>{let b=this.getState(t);b?.bundle&&(b.bundle.initialKB>0||b.bundle.lazyKB>0)&&this.history?.recordBundle(t,b.bundle.initialKB,b.bundle.lazyKB,b.bundle.files.length),this.emit("bundleUpdate",{name:t})}});return e.proc=v,this.recordEvent({app:t,type:"status",from:r,to:"starting"}),v.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=Ut(this.config.depends??{},t).filter(a=>this.entries.has(a)),s=Wt(this.config.depends??{},r),i=[],o=e.waitMs??6e4;for(let a of s){let c=await Promise.all(a.map(h=>this.start(h)));for(let h=0;h<a.length;h++){let p=c[h];if(!p.ok)return i.push({name:a[h],status:p.status,health:"unknown",error:p.error}),{ok:!1,results:i}}let u=await Promise.all(a.map(h=>this.waitFor(h,"healthy",o)));for(let h=0;h<a.length;h++){let p=u[h],v=!p.timedOut&&p.status==="serving"&&p.health==="healthy";if(i.push({name:p.name,status:p.status,health:p.health,error:v?void 0:p.timedOut?"timeout waiting for healthy":"did not reach healthy"}),!v)return{ok:!1,results:i}}}return{ok:!0,results:i}}triggerCascadeRestart(t){if(!this.config.cascadeRestart)return;let e=vr(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 i=await kr(s,e,r);return this.history?.recordTaskRun(t,e,i.exitCode,i.durationMs,i.summary),this.recordEvent({app:t,type:"task-run",message:`${e} exit=${i.exitCode} duration=${i.durationMs}ms`}),this.emit("taskRun",{name:t,task:e,result:i}),i}startWatchTask(t,e,r=[]){let s=this.getApp(t);if(!s)return{ok:!1,error:"unknown app"};let i=`${t}::${e}`;if(this.watchTasks.has(i))return{ok:!0,pid:this.watchTasks.get(i).pid};let o=Tr(s,e,r);return this.watchTasks.set(i,o),o.child.on("exit",()=>this.watchTasks.delete(i)),{ok:!0,pid:o.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 i=r.queryCompiles({app:t,limit:31}).filter(c=>c.ms!==e).slice(0,30).map(c=>c.ms);if(i.length<10)return;let o=[...i].sort((c,u)=>c-u),a=o[Math.floor((o.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 i=s.logs;return r?i.slice(-r):[...i]}waitFor(t,e,r){return new Promise(s=>{let i=Date.now(),o=this.entries.get(t),a=()=>{if(!o)return!0;let p=o.state;return e==="serving"&&p.status==="serving"||e==="healthy"&&p.status==="serving"&&p.health==="healthy"||e==="stopped"&&p.status==="stopped"||e==="error"&&p.status==="error"},c=p=>{this.off("change",u),clearTimeout(h);let v=o?.state;s({name:t,status:v?.status??"unknown",health:v?.health??"unknown",timedOut:p,waitedMs:Date.now()-i})},u=()=>{a()&&c(!1)};if(a()){s({name:t,status:o.state.status,health:o.state.health,timedOut:!1,waitedMs:0});return}let h=setTimeout(()=>c(!0),r);this.on("change",u)})}};Bt();import To from"node:http";import Eo from"node:crypto";import ft from"node:fs";import Y from"node:path";import{fileURLToPath as Ro}from"node:url";import Oe from"node:fs";import Fr from"node:path";import js from"node:os";var Me=Fr.join(js.homedir(),".daimon","cursors.json");function Ns(){try{let n=Oe.readFileSync(Me,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.errors&&typeof t.errors=="object")return{errors:t.errors}}catch{}return{errors:{}}}var Ce=null,Pe=null;function $s(n){Pe=n,!Ce&&(Ce=setTimeout(()=>{Ce=null;let t=Pe;if(Pe=null,!!t)try{Oe.mkdirSync(Fr.dirname(Me),{recursive:!0}),Oe.writeFileSync(Me,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: cursor write failed: ${e.message}
52
+ `)}},500))}var Yt=class{data=Ns();getErrorCursor(t,e){return this.data.errors[`${t}:${e}`]??0}setErrorCursor(t,e,r){this.data.errors[`${t}:${e}`]=r,$s(this.data)}};import Ir from"node:fs";import _s from"node:os";import Br from"node:path";var Ls=/key|secret|token|password|api[-_]?key/i;function Ds(n){let t={};for(let[e,r]of Object.entries(n))typeof r=="string"&&(t[e]=Ls.test(e)?"***":r);return t}function je(n,t){let e=n.summary(t);if(!e)return null;let r=n.getState(t),s=n.getApp(t),i=n.getConfig(),o=i.overrides?.[t]??{},a={...process.env,...s.env??{},...r.sessionOverrides?.env??{}},c=n.getHistory(),u=c?c.queryEvents({app:t,limit:50}):[],h=c?c.queryBundles({app:t,limit:100}):[];return{takenAt:new Date().toISOString(),summary:e,logs:r.logBuffer.slice(-500).map(p=>({ts:p.ts,line:p.line})),errors:[...r.errors.entries()].map(([p,v])=>({hash:p,message:v.message,count:v.count,firstSeen:v.firstSeen,lastSeen:v.lastSeen})),env:Ds(a),configSlice:{command:r.sessionOverrides?.command??o.command??s.command,port:r.sessionOverrides?.port??o.port??null,workspaceRoot:s.workspaceRoot,workspaceType:s.workspaceType,tags:s.tags,depends:i.depends?.[t]??[],envFiles:i.envFiles?.[t]??[]},events:u,bundles:h}}function Hr(n,t){let e=je(n,t);if(!e)return null;let r=Br.join(_s.homedir(),".daimon","snapshots");Ir.mkdirSync(r,{recursive:!0});let s=e.takenAt.replace(/[:.]/g,"-"),i=Br.join(r,`${t}-${s}.json`);return Ir.writeFileSync(i,JSON.stringify(e,null,2)),{path:i,payload:e}}import Vt from"node:fs";import Ur from"node:path";var Fs=["dist",".angular/cache","tmp","out-tsc"],Is=["node_modules"];function Wr(n){let t=0;try{let e=Vt.readdirSync(n,{withFileTypes:!0});for(let r of e){let s=Ur.join(n,r.name);try{r.isDirectory()?t+=Wr(s):r.isFile()&&(t+=Vt.statSync(s).size)}catch{}}}catch{}return t}function Ne(n,t,e){let r=n.getApp(t);if(!r)return null;let s=n.getState(t),i=s?s.status==="serving"||s.status==="compiling"||s.status==="starting":!1,a=[...Fs,...e?Is:[]].map(c=>{let u=Ur.join(r.workspaceRoot,c),h=Vt.existsSync(u);return{path:u,exists:h,sizeBytes:h?Wr(u):0}});return{app:t,workspace:r.workspaceRoot,targets:a,ranOnServing:i}}function Gr(n,t,e){let r=Ne(n,t,e);if(!r)return{error:"unknown app"};if(r.ranOnServing)return{error:"app is currently running; stop it first"};let s=[],i=[];for(let o of r.targets)if(o.exists)try{Vt.rmSync(o.path,{recursive:!0,force:!0}),s.push(o.path)}catch(a){i.push({path:o.path,error:a?.message||String(a)})}return{ok:i.length===0,removed:s,failed:i}}function Ot(n){return n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}var Bs=["stopped","starting","compiling","serving","error"];function Jr(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 Bs)t.push(`daimon_app_status{name="${Ot(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="${Ot(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="${Ot(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="${Ot(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="${Ot(r.name)}"} ${r.memMB}`);return t.join(`
43
53
  `)+`
44
- `}Q();import wt from"node:fs";import qn from"node:crypto";import vr from"node:path";var Xn=1e6;function Kn(){return vr.join(Y(),"audit.log")}function Yn(n){try{if(wt.statSync(n).size>Xn){let e=n+".1";try{wt.unlinkSync(e)}catch{}wt.renameSync(n,e)}}catch{}}function wr(n,t,e,r){let s=Kn();wt.mkdirSync(vr.dirname(s),{recursive:!0}),Yn(s);let i=JSON.stringify({prev:t,next:e}),o=qn.createHash("sha1").update(i).digest("hex").slice(0,12),a=`${new Date().toISOString()} ${n} ${o} ${r.join(",")}
45
- `;try{wt.appendFileSync(s,a)}catch{}}import Nt from"node:fs";import Mt from"node:path";import{fileURLToPath as zn}from"node:url";var br=Mt.dirname(zn(import.meta.url));function Vn(){let n=[Mt.resolve(br,"templates","presets"),Mt.resolve(br,"..","src","templates","presets")];for(let t of n)if(Nt.existsSync(t))return t;return n[0]}function Sr(){let n=Vn();if(!Nt.existsSync(n))return[];let t=Nt.readdirSync(n).filter(r=>r.endsWith(".json")),e=[];for(let r of t)try{let s=Nt.readFileSync(Mt.join(n,r),"utf8");s.charCodeAt(0)===65279&&(s=s.slice(1)),e.push(JSON.parse(s))}catch{}return e}Q();import _t from"node:fs";import kr from"node:path";function xr(){return kr.join(Y(),"state-handoff.json")}function Er(n){let t=[];for(let s of n.names()){let i=n.getState(s);i&&(i.status==="serving"||i.status==="compiling"||i.status==="starting")&&i.port&&t.push({name:s,port:i.port})}let e={ts:Date.now(),apps:t},r=xr();return _t.mkdirSync(kr.dirname(r),{recursive:!0}),_t.writeFileSync(r,JSON.stringify(e)),r}function Tr(n=6e4){let t=xr();try{let e=_t.readFileSync(t,"utf8"),r=JSON.parse(e);return _t.unlinkSync(t),!r||typeof r.ts!="number"||Date.now()-r.ts>n?null:r}catch{return null}}At();var vs=ys(import.meta.url),Lt=F.dirname(vs);function ge(){let n=[F.resolve(Lt,"dashboard","browser"),F.resolve(Lt,"dashboard"),F.resolve(Lt,"..","dist","dashboard","browser"),F.resolve(Lt,"..","dist","dashboard")];for(let t of n)if(It.existsSync(F.join(t,"index.html")))return t;return null}var ws={".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"};function bt(n,t){try{if(!It.statSync(t).isFile())return!1;let r=F.extname(t).toLowerCase(),s=ws[r]??"application/octet-stream",i=It.readFileSync(t);return n.writeHead(200,{"content-type":s,"content-length":i.length,"cache-control":r===".html"?"no-cache":"public, max-age=3600"}),n.end(i),!0}catch{return!1}}function w(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 ct(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 Dt(n,t){let e=(n.searchParams.get("format")||"").toLowerCase();return e==="full"?"full":e==="compact"?"compact":t?.().output?.format==="full"?"full":"compact"}function bs(n){return{name:n.name,status:n.status,port:n.port,health:n.health,errCount:n.errorCount,lastChangeMs:n.lastChangeMs??null}}function Ft(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 ye(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 Ss(n){if(!n)return{};if(/^\d{10,}$/.test(n))return{sinceTs:Number(n)};let t=ct(n);return t!=null?{sinceMs:t}:{}}var ks=/key|secret|token|password|pass/i;function xs(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))ks.test(s)&&(r[s]="***")}return t}function ve(n){if(!n)return"";try{let t=It.readFileSync(n);return gs.createHash("sha1").update(t).digest("hex")}catch{return""}}function Pr(n,t,e={}){let r=new jt,s=hs.createServer(async(i,o)=>{try{let a=new URL(i.url||"/","http://127.0.0.1"),u=i.method||"GET",c=a.pathname.replace(/\/$/,"").split("/").filter(Boolean),h=()=>{let m=(e.getConfig?e.getConfig():null)?.apiToken??null;if(!m)return!0;let g=i.headers.authorization;return typeof g=="string"&&g.toLowerCase().startsWith("bearer ")&&g.slice(7).trim()===m?!0:(w(o,401,{error:"unauthorized"}),!1)};if(u==="POST"&&a.pathname==="/api/shutdown"){if(!h())return;w(o,200,{ok:!0}),e.onShutdown&&setImmediate(()=>{try{e.onShutdown()}catch{}});return}if(a.pathname==="/api/config"&&e.getConfig){if(u==="GET"){let l=e.getConfig(),m=ve(e.configPath);o.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:m}),o.end(JSON.stringify({etag:m,config:xs(l)}));return}if(u==="PATCH"&&e.patchConfig){if(!h())return;let l=i.headers["if-match"]?.trim(),m=ve(e.configPath);if(!l||l!==m){w(o,412,{error:"etag mismatch",current:m});return}let g={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(k=>{let E=[];i.on("data",v=>E.push(v)),i.on("end",()=>{try{g=JSON.parse(Buffer.concat(E).toString("utf8"))}catch{}k()})});let d=e.patchConfig(g);if(!d.ok){w(o,400,{error:d.error});return}let y=ve(e.configPath);try{let k=i.socket.remoteAddress||"127.0.0.1";wr(k,g,g,d.applied)}catch{}o.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:y}),o.end(JSON.stringify({etag:y,applied:d.applied,addedApps:d.addedApps,removedApps:d.removedApps,restartRequired:d.restartRequired}));return}w(o,405,{error:"method not allowed"});return}if(a.pathname==="/api/presets"&&u==="GET"){w(o,200,Sr());return}if(a.pathname==="/api/snapshot-state"&&u==="POST"){if(!h())return;let l=Er(n);w(o,200,{ok:!0,path:l});return}if(a.pathname==="/api/config/reload"&&u==="POST"&&e.reloadConfig){if(!h())return;try{let l=await e.reloadConfig();w(o,200,l)}catch(l){w(o,400,{error:l?.message||String(l)})}return}if(u==="GET"&&a.pathname==="/metrics"&&e.metricsEnabled){let l=yr(n);o.writeHead(200,{"content-type":"text/plain; version=0.0.4","content-length":Buffer.byteLength(l)}),o.end(l);return}if(u!=="GET"&&a.pathname.startsWith("/api/")&&a.pathname!=="/api/shutdown"&&a.pathname!=="/api/config"&&a.pathname!=="/api/config/reload"&&!h())return;if(u==="GET"&&a.pathname==="/"){let l=ge();if(l&&bt(o,F.join(l,"index.html")))return;o.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(u!=="GET"){w(o,405,{error:"method not allowed"});return}let l=ct(a.searchParams.get("since")),m=a.searchParams.get("app")||void 0;if(a.searchParams.get("stream")==="ndjson"){o.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});let y=n.events({sinceMs:l,app:m});for(let v of y)o.write(JSON.stringify(v)+`
46
- `);let k=v=>{m&&v.app!==m||o.write(JSON.stringify(v)+`
47
- `)};n.on("event",k);let E=setInterval(()=>{try{o.write(`
48
- `)}catch{}},3e4);i.on("close",()=>{n.off("event",k),clearInterval(E);try{o.end()}catch{}});return}let g=n.events({sinceMs:l,app:m}),d=n.getHistory();if(d&&l&&g.length<500){let y=Date.now()-l,k=d.queryEvents({app:m,since:y,limit:1e3}),E=new Set(g.map(v=>`${v.ts}|${v.app}|${v.type}|${v.from??""}|${v.to??""}|${v.message??""}`));for(let v of k){let O=`${v.ts}|${v.app}|${v.type}|${v.from_state??""}|${v.to_state??""}|${v.message??""}`;E.has(O)||g.push({ts:v.ts,app:v.app,type:v.type,from:v.from_state??void 0,to:v.to_state??void 0,message:v.message??void 0})}g.sort((v,O)=>v.ts-O.ts)}w(o,200,g);return}if(c[0]==="api"&&c[1]==="session"){if(c[2]==="record"&&u==="POST"){let l=a.searchParams.get("action")||"toggle";if(l==="start"||l==="toggle"&&!n.sessionRecorder.isRecording()){let m=n.sessionRecorder.start();w(o,200,{recording:!0,path:m.path});return}if(l==="stop"||l==="toggle"&&n.sessionRecorder.isRecording()){let m=n.sessionRecorder.stop();w(o,200,{recording:!1,path:m.path});return}w(o,400,{error:"invalid action"});return}if(c[2]==="status"&&u==="GET"){w(o,200,{recording:n.sessionRecorder.isRecording()});return}w(o,404,{error:"not found"});return}if(c[0]==="api"&&c[1]==="history"){if(u!=="GET"){w(o,405,{error:"method not allowed"});return}let l=n.getHistory();if(!l){w(o,200,[]);return}let m=c[2],g=a.searchParams.get("app")||void 0,d=a.searchParams.get("since"),y=a.searchParams.get("until"),k=a.searchParams.get("limit"),E=d?/^\d{10,}$/.test(d)?Number(d):Date.now()-(ct(d)??0):void 0,v=y?/^\d{10,}$/.test(y)?Number(y):Date.now()-(ct(y)??0):void 0,O=k?Number(k):void 0;if(m==="events"){w(o,200,l.queryEvents({app:g,since:E,until:v,type:a.searchParams.get("type")||void 0,limit:O}));return}if(m==="compile-times"){w(o,200,l.queryCompiles({app:g,since:E,until:v,limit:O}));return}if(m==="tasks"){w(o,200,l.queryTasks({app:g,task:a.searchParams.get("task")||void 0,since:E,limit:O}));return}if(m==="summary"&&c.length>=4){let _=decodeURIComponent(c[3]);w(o,200,l.summary(_));return}if(m==="why"&&c.length>=4){let _=decodeURIComponent(c[3]);w(o,200,l.why(_));return}w(o,404,{error:"not found"});return}if(c[0]==="api"&&c[1]==="profiles"&&c[3]==="ensure-up"&&u==="POST"){let l=decodeURIComponent(c[2]),m=e.getConfig?.(),g=m?.profiles?.[l];if(!g){w(o,404,{error:"unknown profile"});return}let d=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(d)){w(o,400,{error:"until must be serving|healthy"});return}let y=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),k=y?Number(y):3e5;(!Number.isFinite(k)||k<=0)&&(k=3e5),k=Math.min(k,12e5);let E=m?.healthProbe?.enabled??!0,v=d==="healthy"&&!E?"serving":d,O=Date.now();for(let T of g){let f=n.summary(T);f&&f.status!=="serving"&&f.status!=="starting"&&f.status!=="compiling"&&await n.startWithDeps(T)}let _=await Promise.all(g.map(async T=>{let f=Math.max(1e3,k-(Date.now()-O));if(!n.summary(T))return{name:T,state:null,until:v,reachedTargetMs:null,timedOut:!1,error:"unknown"};let P=await n.waitFor(T,v,f),M=n.summary(T);return{name:T,state:M?Ft(M):null,until:v,reachedTargetMs:P.timedOut?null:P.waitedMs,timedOut:P.timedOut}}));w(o,200,{profile:l,apps:_,_meta:{totalMs:Date.now()-O,until:v}});return}if(c[0]==="api"&&c[1]==="discovery"&&c[2]==="explain"&&u==="GET"){let l=e.getConfig?.();if(!l){w(o,200,{searchRoots:[],scanned:0,rejected:{},warnings:[],suggestion:"no config loaded"});return}let{discoverApps:m}=await Promise.resolve().then(()=>(ht(),te)),g={scanned:0,rejected:{}},d=[],y=m(l,{warnings:d,stats:g}),k=l.searchRoots.map(E=>typeof E=="string"?E:E.path);w(o,200,{searchRoots:k,scanned:g.scanned,rejected:g.rejected,warnings:d,appsFound:y.length,suggestion:y.length===0?k.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.":`${y.length} apps discovered`});return}if(c[0]==="api"&&c[1]==="doctor"&&c[2]==="auto-fix"&&u==="POST"){if(!h())return;let l={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(E=>{let v=[];i.on("data",O=>v.push(O)),i.on("end",()=>{try{l=JSON.parse(Buffer.concat(v).toString("utf8"))}catch{}E()})});let{runAutoFix:m,ALL_AUTO_FIX:g}=await Promise.resolve().then(()=>(Rr(),Cr)),y=e.getConfig?.()?.doctor?.autoFix?.permitted??g,k=Array.isArray(l.permitted)&&l.permitted.length?l.permitted:y;try{let E=await m({permitted:k,dryRun:!!l.dryRun});w(o,200,E)}catch(E){w(o,500,{error:E?.message??String(E)})}return}if(c[0]==="api"&&c[1]==="overview"&&u==="GET"){let l=e.getConfig?.(),m=n.list(),g=a.searchParams.get("workspace"),d=a.searchParams.get("profile"),y=m;if(g&&(y=y.filter(f=>f.workspaceLabel===g)),d){let f=l?.profiles?.[d]??null;f&&(y=y.filter(C=>f.includes(C.name)))}let k={apps:y.length,serving:y.filter(f=>f.status==="serving").length,errors:y.filter(f=>f.status==="error").length,stopped:y.filter(f=>f.status==="stopped").length,totalErrCount:y.reduce((f,C)=>f+C.errorCount,0),totalCpuPct:Math.round(y.reduce((f,C)=>f+(C.cpu??0),0)*10)/10,totalMemMb:Math.round(y.reduce((f,C)=>f+(C.memMB??0),0))},E={};for(let f of y)(E[f.status]??=[]).push(f.name);let v=y.filter(f=>f.status==="error"||f.errorCount>0).map(f=>{let C=n.errors(f.name)??[],P=C[C.length-1],M=P?.parsed;return{name:f.name,status:f.status,errCount:f.errorCount,firstError:M?{file:M.file??null,line:M.line??null,code:M.code??null,message:M.message??P?.message??""}:P?{file:null,line:null,code:null,message:P.message}:null}}),O=Date.now()-5*6e4,_=n.events({sinceMs:5*6e4}).filter(f=>f.type==="status"&&f.ts>=O).filter(f=>g?y.some(C=>C.name===f.app):!0).filter(f=>d?y.some(C=>C.name===f.app):!0).slice(-5).map(f=>({name:f.app,transition:`${f.from??"?"}\u2192${f.to??"?"}`,msAgo:Date.now()-f.ts})),T={ts:Date.now(),version:st,totals:k,byStatus:E,needsAttention:v,recentlyChanged:_};k.apps===0&&(T._meta={suggestion:"no apps registered. run 'daimon doctor' for recommended next step, or 'daimon init --auto' from a workspace folder."}),w(o,200,T);return}if(c[0]!=="api"||c[1]!=="apps"){if(u==="GET"&&!a.pathname.startsWith("/metrics")){let l=ge();if(l){let m=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(m){let g=F.resolve(l,m);if(g.startsWith(l)&&bt(o,g))return}if(!F.extname(m||"")&&bt(o,F.join(l,"index.html")))return}}w(o,404,{error:"not found"});return}if(c.length===2){if(u!=="GET"){w(o,405,{error:"method not allowed"});return}let l=Dt(a,e.getConfig),m=n.list(),g=l==="full"?m:m.map(bs);if(a.searchParams.get("stream")==="ndjson"){o.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});for(let d of g)o.write(JSON.stringify(d)+`
49
- `);o.end();return}if(a.searchParams.get("explain")==="1"){let d=e.getConfig?.(),y={format:l};if(d){let{discoverApps:k}=await Promise.resolve().then(()=>(ht(),te)),E={scanned:0,rejected:{}},v=[];k(d,{warnings:v,stats:E});let O=d.searchRoots.map(_=>typeof _=="string"?_:_.path);y={format:l,searchRoots:O,scanned:E.scanned,rejected:E.rejected,warnings:v,suggestion:g.length===0?O.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."}}w(o,200,{apps:g,_meta:y});return}w(o,200,g);return}let p=decodeURIComponent(c[2]),b=c[3],S=c[4];if(!b){if(u!=="GET"){w(o,405,{error:"method not allowed"});return}let l=n.summary(p);if(!l){w(o,404,{error:"unknown app"});return}Dt(a,e.getConfig)==="full"?w(o,200,{...l,_meta:{format:"full"}}):w(o,200,{...Ft(l),_meta:{format:"compact"}});return}if(b==="errors"&&S==="since-last"&&u==="GET"){let l=a.searchParams.get("client")||"default",m=r.getErrorCursor(l,p),g=n.errorsSince(p,m);if(g==null){w(o,404,{error:"unknown app"});return}let d=g.reduce((k,E)=>Math.max(k,E.lastSeen),m);d>m&&r.setErrorCursor(l,p,d);let y=Dt(a,e.getConfig);w(o,200,y==="full"?g:g.map(ye));return}if(b==="errors"&&!S&&u==="GET"){let l=a.searchParams.get("since"),m=Dt(a,e.getConfig);if(l){let{sinceMs:d,sinceTs:y}=Ss(l),k=y??(d!=null?Date.now()-d:0),E=n.errorsSince(p,k);if(E==null){w(o,404,{error:"unknown app"});return}w(o,200,m==="full"?E:E.map(ye));return}let g=n.errors(p);if(g==null){w(o,404,{error:"unknown app"});return}w(o,200,m==="full"?g:g.map(ye));return}if(b==="logs"&&c[4]==="stream"&&u==="GET"){if(!n.summary(p)){w(o,404,{error:"unknown app"});return}o.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"});let l=n.logs(p,{tail:50})??[];for(let E of l)o.write(`data: ${JSON.stringify({ts:Date.now(),line:E})}
54
+ `}dt();import Mt from"node:fs";import Hs from"node:crypto";import qr from"node:path";var Us=1e6;function Ws(){return qr.join(ot(),"audit.log")}function Gs(n){try{if(Mt.statSync(n).size>Us){let e=n+".1";try{Mt.unlinkSync(e)}catch{}Mt.renameSync(n,e)}}catch{}}function Kr(n,t,e,r){let s=Ws();Mt.mkdirSync(qr.dirname(s),{recursive:!0}),Gs(s);let i=JSON.stringify({prev:t,next:e}),o=Hs.createHash("sha1").update(i).digest("hex").slice(0,12),a=`${new Date().toISOString()} ${n} ${o} ${r.join(",")}
55
+ `;try{Mt.appendFileSync(s,a)}catch{}}import Zt from"node:fs";import Qt from"node:path";import{fileURLToPath as Js}from"node:url";var Xr=Qt.dirname(Js(import.meta.url));function qs(){let n=[Qt.resolve(Xr,"templates","presets"),Qt.resolve(Xr,"..","src","templates","presets")];for(let t of n)if(Zt.existsSync(t))return t;return n[0]}function zr(){let n=qs();if(!Zt.existsSync(n))return[];let t=Zt.readdirSync(n).filter(r=>r.endsWith(".json")),e=[];for(let r of t)try{let s=Zt.readFileSync(Qt.join(n,r),"utf8");s.charCodeAt(0)===65279&&(s=s.slice(1)),e.push(JSON.parse(s))}catch{}return e}dt();import te from"node:fs";import Yr from"node:path";function Vr(){return Yr.join(ot(),"state-handoff.json")}function Zr(n){let t=[];for(let s of n.names()){let i=n.getState(s);i&&(i.status==="serving"||i.status==="compiling"||i.status==="starting")&&i.port&&t.push({name:s,port:i.port})}let e={ts:Date.now(),apps:t},r=Vr();return te.mkdirSync(Yr.dirname(r),{recursive:!0}),te.writeFileSync(r,JSON.stringify(e)),r}function Qr(n=6e4){let t=Vr();try{let e=te.readFileSync(t,"utf8"),r=JSON.parse(e);return te.unlinkSync(t),!r||typeof r.ts!="number"||Date.now()-r.ts>n?null:r}catch{return null}}Jt();var Ao=Ro(import.meta.url),ee=Y.dirname(Ao);function Fe(){let n=[Y.resolve(ee,"dashboard","browser"),Y.resolve(ee,"dashboard"),Y.resolve(ee,"..","dist","dashboard","browser"),Y.resolve(ee,"..","dist","dashboard")];for(let t of n)if(ft.existsSync(Y.join(t,"index.html")))return t;return null}var Co={".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"};function $t(n,t){try{if(!ft.statSync(t).isFile())return!1;let r=Y.extname(t).toLowerCase(),s=Co[r]??"application/octet-stream",i=ft.readFileSync(t);return n.writeHead(200,{"content-type":s,"content-length":i.length,"cache-control":r===".html"?"no-cache":"public, max-age=3600"}),n.end(i),!0}catch{return!1}}function w(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 kt(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 re(n,t){let e=(n.searchParams.get("format")||"").toLowerCase();return e==="full"?"full":e==="compact"?"compact":t?.().output?.format==="full"?"full":"compact"}function Po(n){return{name:n.name,status:n.status,port:n.port,health:n.health,errCount:n.errorCount,lastChangeMs:n.lastChangeMs??null}}function xt(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 Ie(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 Oo(n){if(!n)return{};if(/^\d{10,}$/.test(n))return{sinceTs:Number(n)};let t=kt(n);return t!=null?{sinceMs:t}:{}}var Mo=/key|secret|token|password|pass/i;function jo(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))Mo.test(s)&&(r[s]="***")}return t}function Be(n){if(!n)return"";try{let t=ft.readFileSync(n);return Eo.createHash("sha1").update(t).digest("hex")}catch{return""}}function ln(n,t,e={}){let r=new Yt,s=To.createServer(async(i,o)=>{try{let a=new URL(i.url||"/","http://127.0.0.1"),c=i.method||"GET",u=a.pathname.replace(/\/$/,"").split("/").filter(Boolean),h=()=>{let m=(e.getConfig?e.getConfig():null)?.apiToken??null;if(!m)return!0;let f=i.headers.authorization;return typeof f=="string"&&f.toLowerCase().startsWith("bearer ")&&f.slice(7).trim()===m?!0:(w(o,401,{error:"unauthorized"}),!1)};if(c==="POST"&&a.pathname==="/api/shutdown"){if(!h())return;w(o,200,{ok:!0}),e.onShutdown&&setImmediate(()=>{try{e.onShutdown()}catch{}});return}if(a.pathname==="/api/config"&&e.getConfig){if(c==="GET"){let l=e.getConfig(),m=Be(e.configPath);o.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:m}),o.end(JSON.stringify({etag:m,config:jo(l)}));return}if(c==="PATCH"&&e.patchConfig){if(!h())return;let l=i.headers["if-match"]?.trim(),m=Be(e.configPath);if(!l||l!==m){w(o,412,{error:"etag mismatch",current:m});return}let f={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(T=>{let E=[];i.on("data",y=>E.push(y)),i.on("end",()=>{try{f=JSON.parse(Buffer.concat(E).toString("utf8"))}catch{}T()})});let d=e.patchConfig(f);if(!d.ok){w(o,400,{error:d.error});return}let g=Be(e.configPath);try{let T=i.socket.remoteAddress||"127.0.0.1";Kr(T,f,f,d.applied)}catch{}o.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:g}),o.end(JSON.stringify({etag:g,applied:d.applied,addedApps:d.addedApps,removedApps:d.removedApps,restartRequired:d.restartRequired}));return}w(o,405,{error:"method not allowed"});return}if(a.pathname==="/api/presets"&&c==="GET"){w(o,200,zr());return}if(a.pathname==="/api/snapshot-state"&&c==="POST"){if(!h())return;let l=Zr(n);w(o,200,{ok:!0,path:l});return}if(a.pathname==="/api/config/reload"&&c==="POST"&&e.reloadConfig){if(!h())return;try{let l=await e.reloadConfig();w(o,200,l)}catch(l){w(o,400,{error:l?.message||String(l)})}return}if(c==="GET"&&a.pathname==="/metrics"&&e.metricsEnabled){let l=Jr(n);o.writeHead(200,{"content-type":"text/plain; version=0.0.4","content-length":Buffer.byteLength(l)}),o.end(l);return}if(c!=="GET"&&a.pathname.startsWith("/api/")&&a.pathname!=="/api/shutdown"&&a.pathname!=="/api/config"&&a.pathname!=="/api/config/reload"&&!h())return;if(c==="GET"&&a.pathname==="/"){let l=Fe();if(l&&$t(o,Y.join(l,"index.html")))return;o.writeHead(404).end('dashboard not found \u2014 run "npm run build:dashboard" in the daimon repo');return}if(u[0]==="api"&&u[1]==="events"&&u.length===2){if(c!=="GET"){w(o,405,{error:"method not allowed"});return}let l=kt(a.searchParams.get("since")),m=a.searchParams.get("app")||void 0;if(a.searchParams.get("stream")==="ndjson"){o.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});let g=n.events({sinceMs:l,app:m});for(let y of g)o.write(JSON.stringify(y)+`
56
+ `);let T=y=>{m&&y.app!==m||o.write(JSON.stringify(y)+`
57
+ `)};n.on("event",T);let E=setInterval(()=>{try{o.write(`
58
+ `)}catch{}},3e4);i.on("close",()=>{n.off("event",T),clearInterval(E);try{o.end()}catch{}});return}let f=n.events({sinceMs:l,app:m}),d=n.getHistory();if(d&&l&&f.length<500){let g=Date.now()-l,T=d.queryEvents({app:m,since:g,limit:1e3}),E=new Set(f.map(y=>`${y.ts}|${y.app}|${y.type}|${y.from??""}|${y.to??""}|${y.message??""}`));for(let y of T){let N=`${y.ts}|${y.app}|${y.type}|${y.from_state??""}|${y.to_state??""}|${y.message??""}`;E.has(N)||f.push({ts:y.ts,app:y.app,type:y.type,from:y.from_state??void 0,to:y.to_state??void 0,message:y.message??void 0})}f.sort((y,N)=>y.ts-N.ts)}w(o,200,f);return}if(u[0]==="api"&&u[1]==="session"){if(u[2]==="record"&&c==="POST"){let l=a.searchParams.get("action")||"toggle";if(l==="start"||l==="toggle"&&!n.sessionRecorder.isRecording()){let m=n.sessionRecorder.start();w(o,200,{recording:!0,path:m.path});return}if(l==="stop"||l==="toggle"&&n.sessionRecorder.isRecording()){let m=n.sessionRecorder.stop();w(o,200,{recording:!1,path:m.path});return}w(o,400,{error:"invalid action"});return}if(u[2]==="status"&&c==="GET"){w(o,200,{recording:n.sessionRecorder.isRecording()});return}w(o,404,{error:"not found"});return}if(u[0]==="api"&&u[1]==="history"){if(c!=="GET"){w(o,405,{error:"method not allowed"});return}let l=n.getHistory();if(!l){w(o,200,[]);return}let m=u[2],f=a.searchParams.get("app")||void 0,d=a.searchParams.get("since"),g=a.searchParams.get("until"),T=a.searchParams.get("limit"),E=d?/^\d{10,}$/.test(d)?Number(d):Date.now()-(kt(d)??0):void 0,y=g?/^\d{10,}$/.test(g)?Number(g):Date.now()-(kt(g)??0):void 0,N=T?Number(T):void 0;if(m==="events"){w(o,200,l.queryEvents({app:f,since:E,until:y,type:a.searchParams.get("type")||void 0,limit:N}));return}if(m==="compile-times"){w(o,200,l.queryCompiles({app:f,since:E,until:y,limit:N}));return}if(m==="tasks"){w(o,200,l.queryTasks({app:f,task:a.searchParams.get("task")||void 0,since:E,limit:N}));return}if(m==="bundles"){w(o,200,l.queryBundles({app:f,since:E,until:y,limit:N}));return}if(m==="trends"){let C=a.searchParams.get("metric")||"compile";if(!["compile","bundle","errors","restarts"].includes(C)){w(o,400,{error:"metric must be compile|bundle|errors|restarts"});return}let S=(a.searchParams.get("since")||"24h").toLowerCase(),R={"24h":24*3600*1e3,"7d":7*86400*1e3,"30d":30*86400*1e3},M=R[S]??R["24h"],x=S==="24h"?3600*1e3:86400*1e3,{points:L,count:H}=l.trends({app:f,metric:C,sinceMs:M,bucketMs:x});w(o,200,{app:f??null,metric:C,since:S,points:L,_meta:{aggregation:S==="24h"?"hour":"day",count:H}});return}if(m==="summary"&&u.length>=4){let C=decodeURIComponent(u[3]);w(o,200,l.summary(C));return}if(m==="why"&&u.length>=4){let C=decodeURIComponent(u[3]);w(o,200,l.why(C));return}w(o,404,{error:"not found"});return}if(u[0]==="api"&&u[1]==="profiles"&&u[3]==="ensure-up"&&c==="POST"){let l=decodeURIComponent(u[2]),m=e.getConfig?.(),f=m?.profiles?.[l];if(!f){w(o,404,{error:"unknown profile"});return}let d=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(d)){w(o,400,{error:"until must be serving|healthy"});return}let g=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),T=g?Number(g):3e5;(!Number.isFinite(T)||T<=0)&&(T=3e5),T=Math.min(T,12e5);let E=m?.healthProbe?.enabled??!0,y=d==="healthy"&&!E?"serving":d,N=Date.now();for(let S of f){let R=n.summary(S);R&&R.status!=="serving"&&R.status!=="starting"&&R.status!=="compiling"&&await n.startWithDeps(S)}let C=await Promise.all(f.map(async S=>{let R=Math.max(1e3,T-(Date.now()-N));if(!n.summary(S))return{name:S,state:null,until:y,reachedTargetMs:null,timedOut:!1,error:"unknown"};let x=await n.waitFor(S,y,R),L=n.summary(S);return{name:S,state:L?xt(L):null,until:y,reachedTargetMs:x.timedOut?null:x.waitedMs,timedOut:x.timedOut}}));w(o,200,{profile:l,apps:C,_meta:{totalMs:Date.now()-N,until:y}});return}if(u[0]==="api"&&u[1]==="orchestrate"&&c==="POST"){let l=e.getConfig?.();if(!l){w(o,500,{error:"no config loaded"});return}let m=a.searchParams.get("profile");if(!m){w(o,400,{error:"profile query param required"});return}let f=(a.searchParams.get("goal")||"healthy").toLowerCase();if(!["serving","healthy","stable"].includes(f)){w(o,400,{error:"goal must be serving|healthy|stable"});return}let d=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),g=d?Number(d):3e5;(!Number.isFinite(g)||g<=0)&&(g=3e5),g=Math.min(g,12e5);let T=a.searchParams.get("dryRun")==="true"||a.searchParams.get("dry-run")==="true",E=a.searchParams.get("budget"),y=E&&Number.isFinite(Number(E))?Number(E):void 0,{orchestrateProfile:N}=await Promise.resolve().then(()=>(De(),Le)),C=await N(n,l,{profile:m,goal:f,timeoutMs:g,dryRun:T,budgetTokens:y});if(C.error){w(o,404,C);return}w(o,200,C);return}if(u[0]==="api"&&u[1]==="discovery"&&u[2]==="explain"&&c==="GET"){let l=e.getConfig?.();if(!l){w(o,200,{searchRoots:[],scanned:0,rejected:{},warnings:[],suggestion:"no config loaded"});return}let{discoverApps:m}=await Promise.resolve().then(()=>(Ct(),be)),f={scanned:0,rejected:{}},d=[],g=m(l,{warnings:d,stats:f}),T=l.searchRoots.map(C=>typeof C=="string"?C:C.path),E=g.filter(C=>C.workspaceType==="polyglot"),y=g.map(C=>({name:C.name,workspaceType:C.workspaceType,serverProfile:C.serverProfile??C.workspaceType,workspaceRoot:C.workspaceRoot})),N=E.length>0?` \xB7 ${E.length} polyglot app${E.length===1?"":"s"} found (${[...new Set(E.map(C=>C.serverProfile))].join(", ")})`:"";w(o,200,{searchRoots:T,scanned:f.scanned,rejected:f.rejected,warnings:d,appsFound:g.length,apps:y,suggestion:g.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.":`${g.length} apps discovered${N}`});return}if(u[0]==="api"&&u[1]==="doctor"&&u[2]==="auto-fix"&&c==="POST"){if(!h())return;let l={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(E=>{let y=[];i.on("data",N=>y.push(N)),i.on("end",()=>{try{l=JSON.parse(Buffer.concat(y).toString("utf8"))}catch{}E()})});let{runAutoFix:m,ALL_AUTO_FIX:f}=await Promise.resolve().then(()=>(Nt(),jt)),g=e.getConfig?.()?.doctor?.autoFix?.permitted??f,T=Array.isArray(l.permitted)&&l.permitted.length?l.permitted:g;try{let E=await m({permitted:T,dryRun:!!l.dryRun});w(o,200,E)}catch(E){w(o,500,{error:E?.message??String(E)})}return}if(u[0]==="api"&&u[1]==="overview"&&c==="GET"){let l=e.getConfig?.(),m=n.list(),f=a.searchParams.get("workspace"),d=a.searchParams.get("profile"),g=m;if(f&&(g=g.filter(x=>x.workspaceLabel===f)),d){let x=l?.profiles?.[d]??null;x&&(g=g.filter(L=>x.includes(L.name)))}let T={apps:g.length,serving:g.filter(x=>x.status==="serving").length,errors:g.filter(x=>x.status==="error").length,stopped:g.filter(x=>x.status==="stopped").length,totalErrCount:g.reduce((x,L)=>x+L.errorCount,0),totalCpuPct:Math.round(g.reduce((x,L)=>x+(L.cpu??0),0)*10)/10,totalMemMb:Math.round(g.reduce((x,L)=>x+(L.memMB??0),0))},E={};for(let x of g)(E[x.status]??=[]).push(x.name);let y=g.filter(x=>x.status==="error"||x.errorCount>0).map(x=>{let L=n.errors(x.name)??[],H=L[L.length-1],$=H?.parsed;return{name:x.name,status:x.status,errCount:x.errorCount,firstError:$?{file:$.file??null,line:$.line??null,code:$.code??null,message:$.message??H?.message??""}:H?{file:null,line:null,code:null,message:H.message}:null}}),N=Date.now()-5*6e4,C=n.events({sinceMs:5*6e4}).filter(x=>x.type==="status"&&x.ts>=N).filter(x=>f?g.some(L=>L.name===x.app):!0).filter(x=>d?g.some(L=>L.name===x.app):!0).slice(-5).map(x=>({name:x.app,transition:`${x.from??"?"}\u2192${x.to??"?"}`,msAgo:Date.now()-x.ts})),S={ts:Date.now(),version:yt,totals:T,byStatus:E,needsAttention:y,recentlyChanged:C};T.apps===0&&(S._meta={suggestion:"no apps registered. run 'daimon doctor' for recommended next step, or 'daimon init --auto' from a workspace folder."});let R=a.searchParams.get("budget"),M=R?Math.max(64,Number(R)|0):null;if(M){let x=M*4,L=0,H=0;for(;JSON.stringify(S).length>x&&(S.needsAttention.length||S.recentlyChanged.length);)if(S.needsAttention.length>1)S.needsAttention.pop(),L++;else if(S.recentlyChanged.length)S.recentlyChanged.pop(),H++;else if(S.needsAttention.length===1)S.needsAttention.pop(),L++;else break;L||H?S._meta={...S._meta??{},budget:M,omitted:{needsAttention:L,recentlyChanged:H}}:S._meta={...S._meta??{},budget:M}}w(o,200,S);return}if(u[0]!=="api"||u[1]!=="apps"){if(c==="GET"&&!a.pathname.startsWith("/metrics")){let l=Fe();if(l){let m=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(m){let f=Y.resolve(l,m);if(f.startsWith(l)&&$t(o,f))return}if(!Y.extname(m||"")&&$t(o,Y.join(l,"index.html")))return}}w(o,404,{error:"not found"});return}if(u.length===2){if(c!=="GET"){w(o,405,{error:"method not allowed"});return}let l=re(a,e.getConfig),m=n.list(),f=l==="full"?m:m.map(Po);if(a.searchParams.get("stream")==="ndjson"){o.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});for(let d of f)o.write(JSON.stringify(d)+`
59
+ `);o.end();return}if(a.searchParams.get("explain")==="1"){let d=e.getConfig?.(),g={format:l};if(d){let{discoverApps:T}=await Promise.resolve().then(()=>(Ct(),be)),E={scanned:0,rejected:{}},y=[];T(d,{warnings:y,stats:E});let N=d.searchRoots.map(C=>typeof C=="string"?C:C.path);g={format:l,searchRoots:N,scanned:E.scanned,rejected:E.rejected,warnings:y,suggestion:f.length===0?N.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."}}w(o,200,{apps:f,_meta:g});return}w(o,200,f);return}let p=decodeURIComponent(u[2]),v=u[3],b=u[4];if(!v){if(c!=="GET"){w(o,405,{error:"method not allowed"});return}let l=n.summary(p);if(!l){w(o,404,{error:"unknown app"});return}re(a,e.getConfig)==="full"?w(o,200,{...l,_meta:{format:"full"}}):w(o,200,{...xt(l),_meta:{format:"compact"}});return}if(v==="errors"&&b==="since-last"&&c==="GET"){let l=a.searchParams.get("client")||"default",m=r.getErrorCursor(l,p),f=n.errorsSince(p,m);if(f==null){w(o,404,{error:"unknown app"});return}let d=f.reduce((T,E)=>Math.max(T,E.lastSeen),m);d>m&&r.setErrorCursor(l,p,d);let g=re(a,e.getConfig);w(o,200,g==="full"?f:f.map(Ie));return}if(v==="errors"&&!b&&c==="GET"){let l=a.searchParams.get("since"),m=re(a,e.getConfig);if(l){let{sinceMs:d,sinceTs:g}=Oo(l),T=g??(d!=null?Date.now()-d:0),E=n.errorsSince(p,T);if(E==null){w(o,404,{error:"unknown app"});return}w(o,200,m==="full"?E:E.map(Ie));return}let f=n.errors(p);if(f==null){w(o,404,{error:"unknown app"});return}w(o,200,m==="full"?f:f.map(Ie));return}if(v==="logs"&&u[4]==="stream"&&c==="GET"){if(!n.summary(p)){w(o,404,{error:"unknown app"});return}o.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"});let l=n.logs(p,{tail:50})??[];for(let E of l)o.write(`data: ${JSON.stringify({ts:Date.now(),line:E})}
50
60
 
51
- `);let m=[],g=0,d=()=>{for(;m.length&&o.write(m.shift()););},y=E=>{E.name===p&&(m.length>=200&&(g++,m.shift()),m.push(`data: ${JSON.stringify({ts:E.ts,line:E.line})}
61
+ `);let m=[],f=0,d=()=>{for(;m.length&&o.write(m.shift()););},g=E=>{E.name===p&&(m.length>=200&&(f++,m.shift()),m.push(`data: ${JSON.stringify({ts:E.ts,line:E.line})}
52
62
 
53
- `),d())};n.on("log",y);let k=setInterval(()=>o.write(`: ping
63
+ `),d())};n.on("log",g);let T=setInterval(()=>o.write(`: ping
54
64
 
55
- `),3e4);i.on("close",()=>{n.off("log",y),clearInterval(k)});return}if(b==="logs"&&u==="GET"){let l=a.searchParams.get("tail"),m=a.searchParams.get("since"),g=n.logs(p,{tail:l?Number(l):void 0,sinceMs:ct(m)});if(g==null){w(o,404,{error:"unknown app"});return}w(o,200,{lines:g});return}if(b==="wait"&&u==="GET"){if(!n.summary(p)){w(o,404,{error:"unknown app"});return}let l=(a.searchParams.get("until")||"serving").toLowerCase();if(!["serving","healthy","stopped","error"].includes(l)){w(o,400,{error:"until must be one of serving|healthy|stopped|error"});return}let m=a.searchParams.get("timeout"),g=m?Number(m):120;(!Number.isFinite(g)||g<=0)&&(g=120),g=Math.min(g,600);let d=await n.waitFor(p,l,g*1e3);w(o,200,d);return}if(b==="ensure"&&u==="POST"){let l=n.summary(p);if(!l){w(o,404,{error:"unknown app"});return}let m=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(m)){w(o,400,{error:"until must be serving|healthy"});return}let g=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),d=g?Number(g):18e4;(!Number.isFinite(d)||d<=0)&&(d=18e4),d=Math.min(d,6e5);let y=e.getConfig?.().healthProbe?.enabled??!0,k=m,E;if(k==="healthy"&&!y&&(k="serving",E="no health probe; treated serving as terminal"),k==="serving"&&l.status==="serving"||k==="healthy"&&l.status==="serving"&&l.health==="healthy"){w(o,200,{...Ft(l),_meta:{format:"compact",startedFromState:null,warning:E,waitedMs:0}});return}let O=l.status;l.status!=="starting"&&l.status!=="compiling"&&await n.start(p);let _=await n.waitFor(p,k,d),T=n.summary(p),f=T?Ft(T):{name:p,status:_.status,port:null,url:null,health:_.health,errCount:0,lastChangeMs:null,uptime:null};if(_.timedOut){w(o,200,{error:"timeout",state:f,_meta:{format:"compact",startedFromState:O,warning:E,waitedMs:_.waitedMs,timedOut:!0}});return}w(o,200,{...f,_meta:{format:"compact",startedFromState:O,warning:E,waitedMs:_.waitedMs}});return}if(b==="start"&&u==="POST"){if(a.searchParams.get("withDeps")==="1"){let g=await n.startWithDeps(p);w(o,g.ok?200:400,g);return}let m=await n.start(p);w(o,m.ok?200:400,m);return}if(b==="start-with-deps"&&u==="POST"){let l=await n.startWithDeps(p);w(o,l.ok?200:400,l);return}if(b==="tasks"&&u==="GET"&&!S){let l=n.listTasks(p);if(l==null){w(o,404,{error:"unknown app"});return}w(o,200,{tasks:l,watching:n.listWatchTasks(p)});return}if(b==="run"&&S&&u==="POST"){let l={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(d=>{let y=[];i.on("data",k=>y.push(k)),i.on("end",()=>{try{l=JSON.parse(Buffer.concat(y).toString("utf8"))}catch{}d()})});let m=Array.isArray(l.args)?l.args.map(String):[];if(l.watch){let d=n.startWatchTask(p,S,m);w(o,d.ok?200:400,d);return}let g=await n.runTask(p,S,m);if("error"in g){w(o,404,g);return}w(o,200,g);return}if(b==="run-stop"&&S&&u==="POST"){let l=await n.stopWatchTask(p,S);w(o,200,l);return}if(b==="env"&&u==="GET"){let m=n.getConfig().envFiles?.[p]??[],g=n.getState(p);w(o,200,{candidates:m,active:g?.activeEnvFile??null});return}if(b==="env"&&u==="POST"){let l={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(g=>{let d=[];i.on("data",y=>d.push(y)),i.on("end",()=>{try{l=JSON.parse(Buffer.concat(d).toString("utf8"))}catch{}g()})}),n.setActiveEnvFile(p,l.use??null);let m=n.getState(p);w(o,200,{active:m?.activeEnvFile??null});return}if(b==="requests"&&u==="GET"){if(!e.requestLog){w(o,200,[]);return}let l=ct(a.searchParams.get("since"));w(o,200,e.requestLog.requests(p,l));return}if(b==="clean"&&u==="POST"){let l=a.searchParams.get("deep")==="1",m=a.searchParams.get("yes")==="1",g=me(n,p,l);if(!g){w(o,404,{error:"unknown app"});return}if(g.ranOnServing){w(o,409,{error:"refusing: app is currently running",plan:g});return}if(!m){w(o,200,{plan:g,hint:"pass --yes to delete"});return}let d=gr(n,p,l);w(o,200,d);return}if(b==="snapshot"&&u==="POST"){if(a.searchParams.get("write")==="1"){let g=dr(n,p);if(!g){w(o,404,{error:"unknown app"});return}w(o,200,{snapshot:g.path});return}let m=de(n,p);if(!m){w(o,404,{error:"unknown app"});return}w(o,200,m);return}if(b==="stop"&&u==="POST"){let l=await n.stop(p);w(o,l.ok?200:400,l);return}if(b==="restart"&&u==="POST"){let l=await n.restart(p);w(o,l.ok?200:400,l);return}if(u==="GET"&&!a.pathname.startsWith("/api/")&&!a.pathname.startsWith("/metrics")){let l=ge();if(l){let m=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(m){let g=F.resolve(l,m);if(g.startsWith(l)&&bt(o,g))return}if(!F.extname(m||"")&&bt(o,F.join(l,"index.html")))return}}w(o,404,{error:"not found"})}catch(a){w(o,500,{error:a?.message||String(a)})}});return s.listen(t,"127.0.0.1"),s}import Es from"node:http";import Ts from"node:https";var As=1e3,Cs=500;function Rs(n,t,e,r,s){if(t)return[t];let i=n.path||"/",o=n.fallbackHosts&&n.fallbackHosts.length?n.fallbackHosts:["127.0.0.1"];if(n.host||n.scheme){let u=e?Bt(e):null,c=n.scheme||u?.protocol?.replace(":","")||"http",h=n.host||u?.hostname||(r?o[0]:"127.0.0.1"),p=r??(u?.port?Number(u.port):null);return[Or(c,h,p,i)]}if(e){let u=Bt(e);if(u)return u.pathname=i,[u.toString()]}let a=[];s&&a.push(s);for(let u of o)a.includes(u)||a.push(u);return a.map(u=>Or("http",u,r,i))}function Bt(n){try{return new URL(n)}catch{return null}}function Or(n,t,e,r){let s=t.includes(":")&&!t.startsWith("[")?`[${t}]`:t,i=e?`:${e}`:"";return`${n}://${s}${i}${r.startsWith("/")?r:"/"+r}`}var Ht=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)},Cs);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=Rs(this.cfg,r,e.announcedUrl,e.port,e.cachedProbeHost);if(s.length===0){this.registry.setLastHealthError(t,"no probe URL available"),this.registry.setHealth(t,"unhealthy");return}let i=null;for(let a of s){let u=await this.tryProbe(a);if(u.ok){let c=Bt(a);c&&this.registry.setCachedProbeHost(t,c.hostname.replace(/^\[|\]$/g,"")),this.registry.setResolvedUrl(t,a),this.registry.setLastHealthError(t,null),this.registry.setHealth(t,"healthy");return}i||(i=`${u.error} ${a}`)}let o=this.freshness.get(t);if(o&&!o.retried){o.retried=!0,setTimeout(()=>{this.probe(t)},As);return}this.registry.setLastHealthError(t,i||"unknown probe failure"),this.registry.setHealth(t,"unhealthy")}tryProbe(t){return new Promise(e=>{let r=!1,s=u=>{r||(r=!0,e(u))},i=t.startsWith("https://"),o=i?Ts:Es,a={timeout:this.cfg.timeoutMs};if(i){let c=Bt(t)?.hostname?.replace(/^\[|\]$/g,"")??"",h=c==="127.0.0.1"||c==="::1"||c==="localhost";a.rejectUnauthorized=h?!1:!!this.cfg.rejectUnauthorized}try{let u=o.get(t,a,c=>{let h=c.statusCode??0;c.resume(),h>=200&&h<500?s({ok:!0}):s({ok:!1,error:`http ${h}`})});u.on("timeout",()=>u.destroy(new Error("timeout"))),u.on("error",c=>s({ok:!1,error:c?.code||c?.message||"error"}))}catch(u){s({ok:!1,error:u?.message||"throw"})}})}};import Ps from"pidusage";var Ut=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 i=await Ps(s),o=this.registry.getState(r);if(!o)return;let a=Math.round(i.cpu*10)/10,u=Math.round(i.memory/(1024*1024));(o.cpu!==a||o.memMB!==u)&&(o.cpu=a,o.memMB=u,e=!0)}catch{let i=this.registry.getState(r);i&&(i.cpu!=null||i.memMB!=null)&&(i.cpu=null,i.memMB=null,e=!0)}})),e&&this.registry.emit("change")}};var Wt=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 i=this.registry.getState(t);if(!i)return;let o=Date.now();if((i.restartWindowStart==null||o-i.restartWindowStart>this.cfg.windowMs)&&(i.restartWindowStart=o,i.restartAttempts=0),i.restartAttempts+=1,i.restartAttempts>this.cfg.maxAttempts){i.lastStatusMessage=`auto-restart aborted (${i.restartAttempts-1}/${this.cfg.maxAttempts} within window)`,i.nextRestartAt=null,this.registry.recordEvent({app:t,type:"restart-scheduled",message:i.lastStatusMessage}),this.registry.emit("change");return}let a=Math.min(2**(i.restartAttempts-1)*1e3,3e4);i.nextRestartAt=o+a,i.lastStatusMessage=`restarting in ${Math.round(a/1e3)}s (attempt ${i.restartAttempts}/${this.cfg.maxAttempts})`,this.registry.recordEvent({app:t,type:"restart-scheduled",message:i.lastStatusMessage}),this.registry.emit("change");let u=setTimeout(()=>{this.timers.delete(t);let c=this.registry.getState(t);c&&(c.nextRestartAt=null),this.registry.start(t)},a);this.timers.set(t,u)}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 Se from"node:fs";import jr from"node:path";import Os from"node:os";var ke=jr.join(Os.homedir(),".daimon","state.json");function $r(){try{let n=Se.readFileSync(ke,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.ports&&typeof t.ports=="object")return{ports:t.ports}}catch{}return{ports:{}}}var we=null,be=null;function Nr(n){be=n,!we&&(we=setTimeout(()=>{we=null;let t=be;if(be=null,!!t)try{Se.mkdirSync(jr.dirname(ke),{recursive:!0}),Se.writeFileSync(ke,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: state write failed: ${e.message}
56
- `)}},500))}he();import Mr from"node:fs";import js from"node:os";import _r from"node:path";import{createRequire as $s}from"node:module";var Ns=$s(import.meta.url),Ms=6e4,Jt=class{constructor(t,e){this.registry=t;this.cfg=e;this.logFile=_r.join(js.homedir(),".daimon","notifications.log");try{Mr.mkdirSync(_r.dirname(this.logFile),{recursive:!0})}catch{}if(!e.enabled){this.audit("init","disabled by config");return}try{let r=Ns("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}
57
- `;try{Mr.appendFileSync(this.logFile,r)}catch{}}warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] notifier: ${t}
58
- `))}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 i=`${t}::${e}`,o=this.lastSent.get(i)??0,a=Date.now();if(a-o<Ms){this.audit("throttled",`${i}`);return}this.lastSent.set(i,a);let u={title:`daimon: ${r}`,message:s,wait:!1,appID:"daimon"},c=(h,p)=>{h?(this.audit("fail",`${i} :: ${h?.message||h}`),this.warnOnce(`notify failed: ${h?.message||h}`)):this.audit("ok",`${i} :: ${r} :: ${p??"(no response)"}`)};try{this.audit("attempt",`${i} :: ${r}`),(this.toaster??this.notifier).notify(u,c)}catch(h){this.audit("throw",`${i} :: ${h?.message||h}`),this.warnOnce(`notify threw: ${h?.message||h}`)}}};import Lr from"node:fs";import xe from"node:path";var _s=5e3,Ls=3e4,Ds=new Set(["node_modules","dist",".angular",".nx",".git","tmp","out-tsc","coverage"]),Fs=new Set([".ts",".tsx",".html",".scss",".css",".js",".jsx",".json"]),Gt=class{constructor(t,e){this.registry=t;this.cfg=e;e.enabled&&(this.timer=setInterval(()=>this.tick(),_s),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,i=Date.now()-s;if(i<this.cfg.silentMs){e.stale&&this.registry.setStale(t,!1);return}let o=e.lastCompileAt??e.startedAt;this.hasSourceChange(r.workspaceRoot,o,e.lastCompileAt)&&(e.stale||(this.registry.setStale(t,!0),this.registry.recordEvent({app:t,type:"stale",message:`no output in ${Math.round(i/1e3)}s despite source changes`})))}hasSourceChange(t,e,r){let s=this.caches.get(t);if(!s||Date.now()-s.ts>Ls||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,i)=>{if(i>8||e.length>4e3)return;let o;try{o=Lr.readdirSync(s,{withFileTypes:!0})}catch{return}for(let a of o)if(!a.name.startsWith(".git")){if(a.isDirectory()){if(Ds.has(a.name))continue;r(xe.join(s,a.name),i+1)}else if(a.isFile()){let u=xe.extname(a.name);if(!Fs.has(u))continue;try{let c=xe.join(s,a.name),h=Lr.statSync(c);e.push({path:c,mtime:h.mtimeMs})}catch{}}}};return r(t,0),e}};import Dr from"node:http";var qt=200,Xt=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=[],i=Dr.createServer((o,a)=>{let u=Date.now(),c={hostname:"127.0.0.1",port:e,method:o.method,path:o.url,headers:{...o.headers,host:`127.0.0.1:${e}`}},h=Dr.request(c,p=>{a.writeHead(p.statusCode||502,p.headers),p.pipe(a);let b=()=>{s.push({ts:Date.now(),method:o.method||"GET",path:o.url||"/",status:p.statusCode||0,durationMs:Date.now()-u}),s.length>qt&&s.splice(0,s.length-qt)};p.on("end",b),p.on("error",b)});h.on("error",()=>{a.writeHead(502).end("upstream error"),s.push({ts:Date.now(),method:o.method||"GET",path:o.url||"/",status:502,durationMs:Date.now()-u}),s.length>qt&&s.splice(0,s.length-qt)}),o.pipe(h)});i.on("error",o=>{o?.code==="EADDRINUSE"&&process.stderr.write(`[daimon] requestLog: port ${r} in use for ${t}; disabling proxy
59
- `),this.proxies.delete(t)}),i.listen(r,"127.0.0.1",()=>{this.proxies.set(t,{app:t,proxyPort:r,server:i,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(i=>i.ts>=s)}return[...r.buffer]}proxyPortFor(t){return this.proxies.get(t)?.proxyPort??null}};Q();kt();ht();import Ee from"node:fs";var Is=new Set(["command","port","env","url"]);function Fr(n){let t=Ee.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 Ir(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]=Ir(e[r],s);return e}function Bs(n,t){let e=n+"."+process.pid+".tmp";Ee.writeFileSync(e,t,"utf8"),Ee.renameSync(e,n)}function Hs(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 Br(n){let t=Fr(n.configPath),e=Ir(t,n.patch);if(!e||typeof e!="object")throw new Error("patch produced non-object config");let r=Vt(e,n.configPath);return Bs(n.configPath,JSON.stringify(e,null,2)+`
60
- `),{config:r,raw:e,applied:Hs(t,e),prevRaw:t}}function Te(n){let t=Fr(n.configPath),e=Vt(t,n.configPath);return Us(n.registry,e)}function Us(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=mt(e),i=new Set(s.map(c=>c.name)),o=[],a=[];for(let c of s)r.has(c.name)?n.updateDiscoveredApp(c):(n.addDiscoveredApp(c),o.push(c.name));for(let c of r)i.has(c)||a.push(c);let u=[];for(let c of n.names()){let h=n.getState(c);if(h&&(h.status==="serving"||h.status==="compiling")){let p=e.overrides?.[c];if(!p)continue;for(let b of Is)if(b in p){u.push(c);break}}}return{addedApps:o,removedApps:a,restartRequired:u,config:e}}At();Q();import Hr from"node:fs";import Ws from"node:os";import Ur from"node:path";var Js=/key|secret|token|password|pass/i;function Gs(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))Js.test(s)&&(r[s]="***")}return t}function qs(n,t=200){if(!n)return[];let e=[];for(let r of n.names()){let s=n.getState(r);if(s)for(let i of s.logBuffer)e.push({ts:i.ts,line:`[${r}] ${i.line}`})}return e.sort((r,s)=>r.ts-s.ts),e.slice(-t).map(r=>r.line)}function Xs(){let n=Ur.join(Y(),"crashes");return Hr.mkdirSync(n,{recursive:!0}),n}function Ks(n,t,e){let r=new Date().toISOString().replace(/[:.]/g,"-"),s=Ur.join(Xs(),`${r}.txt`),i=n,o=[`daimon crash dump @ ${new Date().toISOString()}`,`version: ${st}`,`node: ${process.version}`,`platform: ${process.platform} ${Ws.release()}`,`cwd: ${process.cwd()}`,`pid: ${process.pid}`,"","ERROR:",i?.stack||String(i),"","CONFIG (redacted):",JSON.stringify(Gs(e),null,2),"","RECENT LOG (last 200 lines across apps):",...qs(t,200)];try{Hr.writeFileSync(s,o.join(`
61
- `))}catch{}return s}function Wr(n){let t=e=>{let r=null;try{r=Ks(e,n.getRegistry(),n.getConfig())}catch{}try{process.stderr.write(`[daimon] fatal: ${e?.stack||e}
65
+ `),3e4);i.on("close",()=>{n.off("log",g),clearInterval(T)});return}if(v==="logs"&&c==="GET"){let l=a.searchParams.get("tail"),m=a.searchParams.get("since"),f=n.logs(p,{tail:l?Number(l):void 0,sinceMs:kt(m)});if(f==null){w(o,404,{error:"unknown app"});return}w(o,200,{lines:f});return}if(v==="focus"&&c==="POST"){let l=n.summary(p);if(!l){w(o,404,{error:"unknown app"});return}let m=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy","stable"].includes(m)){w(o,400,{error:"until must be one of serving|healthy|stable"});return}let f=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),d=f?Number(f):18e4;(!Number.isFinite(d)||d<=0)&&(d=18e4),d=Math.min(d,6e5);let g=a.searchParams.get("stableMs"),T=g&&Number.isFinite(Number(g))?Math.max(1e3,Number(g)):5e3;o.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8","cache-control":"no-cache",connection:"keep-alive"});let E=$=>{try{o.write(JSON.stringify($)+`
66
+ `)}catch{}};E({kind:"subscribed",app:p,until:m,ts:Date.now(),state:xt(l)});let y=Date.now(),N=Date.now(),C=!1,S=$=>{if(C)return;C=!0,n.off("event",M),clearInterval(x),clearInterval(L),clearTimeout(H);let J=n.summary(p);E({kind:"done",reason:$,ts:Date.now(),state:J?xt(J):null,waitedMs:Date.now()-y});try{o.end()}catch{}},R=()=>{let $=n.summary(p);if(!$)return!1;if(m==="serving")return $.status==="serving";if(m==="healthy")return $.status==="serving"&&$.health==="healthy";if(m==="stable"){let J=Date.now()-N;return $.status==="serving"&&$.health==="healthy"&&J>=T}return!1},M=$=>{if($.app===p)if(N=Date.now(),$.type==="status")E({kind:"status",from:$.from,to:$.to,ts:$.ts}),m!=="stable"&&R()&&S("reached");else if($.type==="error-new"||$.type==="error-recur"){let I=(n.errors(p)??[])[0];I&&E({kind:"error",message:I.message,parsed:I.parsed??null,ts:$.ts})}else $.type==="health"&&(E({kind:"health",from:$.from,to:$.to,ts:$.ts}),m!=="stable"&&R()&&S("reached"))};n.on("event",M);let x=setInterval(()=>{R()&&S("reached")},1e3),L=setInterval(()=>{try{o.write(`
67
+ `)}catch{}},3e4),H=setTimeout(()=>S("timeout"),d);i.on("close",()=>S("closed")),R()&&S("reached");return}if(v==="health"&&b==="pin"&&c==="POST"){let l=n.getState(p);if(!l){w(o,404,{error:"unknown app"});return}let m={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(C=>{let S=[];i.on("data",R=>S.push(R)),i.on("end",()=>{try{m=JSON.parse(Buffer.concat(S).toString("utf8"))}catch{}C()})});let f=typeof m.path=="string"&&m.path?m.path:l.discoveredHealthPath??null;if(!f){w(o,400,{error:"no path supplied and no discoveredHealthPath on app"});return}let{configLookupPaths:d}=await Promise.resolve().then(()=>(Rt(),ar)),{local:g,user:T}=d(),E=ft.existsSync(g)?g:T,y={};try{y=JSON.parse(ft.readFileSync(E,"utf8"))}catch{}(!y.overrides||typeof y.overrides!="object")&&(y.overrides={}),(!y.overrides[p]||typeof y.overrides[p]!="object")&&(y.overrides[p]={});let N=y.overrides[p].healthProbePath??null;if(y.overrides[p].healthProbePath=f,ft.writeFileSync(E,JSON.stringify(y,null,2)+`
68
+ `,"utf8"),e.reloadConfig)try{await e.reloadConfig()}catch{}w(o,200,{pinned:f,app:p,configPath:E,previous:N});return}if(v==="try-fix"&&c==="POST"){let l=n.summary(p);if(!l){w(o,404,{error:"unknown app"});return}let m=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(m)){w(o,400,{error:"until must be serving|healthy"});return}let f=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),d=f?Number(f):18e4;(!Number.isFinite(d)||d<=0)&&(d=18e4),d=Math.min(d,6e5);let g={status:l.status,health:l.health,errCount:l.errorCount,firstError:(n.errors(p)??[])[0]?.parsed??null},{runAutoFix:T,ALL_AUTO_FIX:E}=await Promise.resolve().then(()=>(Nt(),jt)),N=e.getConfig?.()?.doctor?.autoFix?.permitted??E,C={ran:[],skipped:[],errors:[]};try{C=await T({permitted:N,dryRun:!1})}catch(I){C.errors.push({name:"auto-fix",error:I?.message??String(I)})}let S=(C.ran??[]).map(I=>I.name),R=null;try{let I=await n.restart(p);I?.ok||(R=I?.error??"restart failed")}catch(I){R=I?.message??String(I)}let M=await n.waitFor(p,m,d),x=n.summary(p),H=(n.errors(p)??[]).slice(0,5).map(I=>({file:I.parsed?.file??null,line:I.parsed?.line??null,code:I.parsed?.code??null,tool:I.parsed?.tool??null,message:I.parsed?.message??I.message})),$=x?{status:x.status,health:x.health,errCount:x.errorCount}:{status:M.status,health:M.health,errCount:0},J=m==="serving"&&$.status==="serving"||m==="healthy"&&$.status==="serving"&&$.health==="healthy";w(o,200,{before:g,after:$,fixed:S,stillFailing:H,reached:J,waitedMs:M.waitedMs,_meta:{autoFix:C,restartErr:R,timedOut:M.timedOut}});return}if(v==="wait"&&c==="GET"){if(!n.summary(p)){w(o,404,{error:"unknown app"});return}let l=(a.searchParams.get("until")||"serving").toLowerCase();if(!["serving","healthy","stopped","error"].includes(l)){w(o,400,{error:"until must be one of serving|healthy|stopped|error"});return}let m=a.searchParams.get("timeout"),f=m?Number(m):120;(!Number.isFinite(f)||f<=0)&&(f=120),f=Math.min(f,600);let d=await n.waitFor(p,l,f*1e3);w(o,200,d);return}if(v==="ensure"&&c==="POST"){let l=n.summary(p);if(!l){w(o,404,{error:"unknown app"});return}let m=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(m)){w(o,400,{error:"until must be serving|healthy"});return}let f=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),d=f?Number(f):18e4;(!Number.isFinite(d)||d<=0)&&(d=18e4),d=Math.min(d,6e5);let g=e.getConfig?.().healthProbe?.enabled??!0,T=m,E;if(T==="healthy"&&!g&&(T="serving",E="no health probe; treated serving as terminal"),T==="serving"&&l.status==="serving"||T==="healthy"&&l.status==="serving"&&l.health==="healthy"){w(o,200,{...xt(l),_meta:{format:"compact",startedFromState:null,warning:E,waitedMs:0}});return}let N=l.status;l.status!=="starting"&&l.status!=="compiling"&&await n.start(p);let C=await n.waitFor(p,T,d),S=n.summary(p),R=S?xt(S):{name:p,status:C.status,port:null,url:null,health:C.health,errCount:0,lastChangeMs:null,uptime:null};if(C.timedOut){w(o,200,{error:"timeout",state:R,_meta:{format:"compact",startedFromState:N,warning:E,waitedMs:C.waitedMs,timedOut:!0}});return}w(o,200,{...R,_meta:{format:"compact",startedFromState:N,warning:E,waitedMs:C.waitedMs}});return}if(v==="start"&&c==="POST"){if(a.searchParams.get("withDeps")==="1"){let f=await n.startWithDeps(p);w(o,f.ok?200:400,f);return}let m=await n.start(p);w(o,m.ok?200:400,m);return}if(v==="start-with-deps"&&c==="POST"){let l=await n.startWithDeps(p);w(o,l.ok?200:400,l);return}if(v==="tasks"&&c==="GET"&&!b){let l=n.listTasks(p);if(l==null){w(o,404,{error:"unknown app"});return}w(o,200,{tasks:l,watching:n.listWatchTasks(p)});return}if(v==="run"&&b&&c==="POST"){let l={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(d=>{let g=[];i.on("data",T=>g.push(T)),i.on("end",()=>{try{l=JSON.parse(Buffer.concat(g).toString("utf8"))}catch{}d()})});let m=Array.isArray(l.args)?l.args.map(String):[];if(l.watch){let d=n.startWatchTask(p,b,m);w(o,d.ok?200:400,d);return}let f=await n.runTask(p,b,m);if("error"in f){w(o,404,f);return}w(o,200,f);return}if(v==="run-stop"&&b&&c==="POST"){let l=await n.stopWatchTask(p,b);w(o,200,l);return}if(v==="env"&&c==="GET"){let m=n.getConfig().envFiles?.[p]??[],f=n.getState(p);w(o,200,{candidates:m,active:f?.activeEnvFile??null});return}if(v==="env"&&c==="POST"){let l={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(f=>{let d=[];i.on("data",g=>d.push(g)),i.on("end",()=>{try{l=JSON.parse(Buffer.concat(d).toString("utf8"))}catch{}f()})}),n.setActiveEnvFile(p,l.use??null);let m=n.getState(p);w(o,200,{active:m?.activeEnvFile??null});return}if(v==="requests"&&c==="GET"){if(!e.requestLog){w(o,200,[]);return}let l=kt(a.searchParams.get("since"));w(o,200,e.requestLog.requests(p,l));return}if(v==="clean"&&c==="POST"){let l=a.searchParams.get("deep")==="1",m=a.searchParams.get("yes")==="1",f=Ne(n,p,l);if(!f){w(o,404,{error:"unknown app"});return}if(f.ranOnServing){w(o,409,{error:"refusing: app is currently running",plan:f});return}if(!m){w(o,200,{plan:f,hint:"pass --yes to delete"});return}let d=Gr(n,p,l);w(o,200,d);return}if(v==="snapshot"&&c==="POST"){if(a.searchParams.get("write")==="1"){let f=Hr(n,p);if(!f){w(o,404,{error:"unknown app"});return}w(o,200,{snapshot:f.path});return}let m=je(n,p);if(!m){w(o,404,{error:"unknown app"});return}w(o,200,m);return}if(v==="stop"&&c==="POST"){let l=await n.stop(p);w(o,l.ok?200:400,l);return}if(v==="restart"&&c==="POST"){let l=await n.restart(p);w(o,l.ok?200:400,l);return}if(c==="GET"&&!a.pathname.startsWith("/api/")&&!a.pathname.startsWith("/metrics")){let l=Fe();if(l){let m=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(m){let f=Y.resolve(l,m);if(f.startsWith(l)&&$t(o,f))return}if(!Y.extname(m||"")&&$t(o,Y.join(l,"index.html")))return}}w(o,404,{error:"not found"})}catch(a){w(o,500,{error:a?.message||String(a)})}});return s.listen(t,"127.0.0.1"),s}import No from"node:http";import $o from"node:https";var _o=1e3,Lo=500,Do=["/","/health","/-/health","/api/health","/ready","/healthz"];function un(n,t,e,r,s){if(t)return[t];let i=n.path||"/",o=n.fallbackHosts&&n.fallbackHosts.length?n.fallbackHosts:["127.0.0.1"];if(n.host||n.scheme){let c=e?ne(e):null,u=n.scheme||c?.protocol?.replace(":","")||"http",h=n.host||c?.hostname||(r?o[0]:"127.0.0.1"),p=r??(c?.port?Number(c.port):null);return[pn(u,h,p,i)]}if(e){let c=ne(e);if(c)return c.pathname=i,[c.toString()]}let a=[];s&&a.push(s);for(let c of o)a.includes(c)||a.push(c);return a.map(c=>pn("http",c,r,i))}function ne(n){try{return new URL(n)}catch{return null}}function pn(n,t,e,r){let s=t.includes(":")&&!t.startsWith("[")?`[${t}]`:t,i=e?`:${e}`:"";return`${n}://${s}${i}${r.startsWith("/")?r:"/"+r}`}var se=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)},Lo);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,i=this.cfg;s?i={...this.cfg,path:s}:e.discoveredHealthPath&&(i={...this.cfg,path:e.discoveredHealthPath});let o=un(i,r,e.announcedUrl,e.port,e.cachedProbeHost);if(!r&&!s&&!e.discoveredHealthPath&&(this.cfg.path==="/"||!this.cfg.path)&&e.health!=="healthy"&&this.discoverPath(t),o.length===0){this.registry.setLastHealthError(t,"no probe URL available"),this.registry.setHealth(t,"unhealthy");return}let a=null;for(let u of o){let h=await this.tryProbe(u);if(h.ok){let p=ne(u);p&&this.registry.setCachedProbeHost(t,p.hostname.replace(/^\[|\]$/g,"")),this.registry.setResolvedUrl(t,u),this.registry.setLastHealthError(t,null),this.registry.setHealth(t,"healthy");return}a||(a=`${h.error} ${u}`)}let c=this.freshness.get(t);if(c&&!c.retried){c.retried=!0,setTimeout(()=>{this.probe(t)},_o);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 Do){let s={...this.cfg,path:r},i=un(s,void 0,e.announcedUrl,e.port,e.cachedProbeHost);for(let o of i)if((await this.tryProbe(o,{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,i=h=>{s||(s=!0,r(h))},o=t.startsWith("https://"),a=o?$o:No,c={timeout:this.cfg.timeoutMs};if(o){let p=ne(t)?.hostname?.replace(/^\[|\]$/g,"")??"",v=p==="127.0.0.1"||p==="::1"||p==="localhost";c.rejectUnauthorized=v?!1:!!this.cfg.rejectUnauthorized}let u=e.strict2xx?300:500;try{let h=a.get(t,c,p=>{let v=p.statusCode??0;p.resume(),v>=200&&v<u?i({ok:!0}):i({ok:!1,error:`http ${v}`})});h.on("timeout",()=>h.destroy(new Error("timeout"))),h.on("error",p=>i({ok:!1,error:p?.code||p?.message||"error"}))}catch(h){i({ok:!1,error:h?.message||"throw"})}})}};import Fo from"pidusage";var oe=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 i=await Fo(s),o=this.registry.getState(r);if(!o)return;let a=Math.round(i.cpu*10)/10,c=Math.round(i.memory/(1024*1024));(o.cpu!==a||o.memMB!==c)&&(o.cpu=a,o.memMB=c,e=!0)}catch{let i=this.registry.getState(r);i&&(i.cpu!=null||i.memMB!=null)&&(i.cpu=null,i.memMB=null,e=!0)}})),e&&this.registry.emit("change")}};var ie=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 i=this.registry.getState(t);if(!i)return;let o=Date.now();if((i.restartWindowStart==null||o-i.restartWindowStart>this.cfg.windowMs)&&(i.restartWindowStart=o,i.restartAttempts=0),i.restartAttempts+=1,i.restartAttempts>this.cfg.maxAttempts){i.lastStatusMessage=`auto-restart aborted (${i.restartAttempts-1}/${this.cfg.maxAttempts} within window)`,i.nextRestartAt=null,this.registry.recordEvent({app:t,type:"restart-scheduled",message:i.lastStatusMessage}),this.registry.emit("change");return}let a=Math.min(2**(i.restartAttempts-1)*1e3,3e4);i.nextRestartAt=o+a,i.lastStatusMessage=`restarting in ${Math.round(a/1e3)}s (attempt ${i.restartAttempts}/${this.cfg.maxAttempts})`,this.registry.recordEvent({app:t,type:"restart-scheduled",message:i.lastStatusMessage}),this.registry.emit("change");let c=setTimeout(()=>{this.timers.delete(t);let u=this.registry.getState(t);u&&(u.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 We from"node:fs";import dn from"node:path";import Io from"node:os";var Ge=dn.join(Io.homedir(),".daimon","state.json");function fn(){try{let n=We.readFileSync(Ge,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.ports&&typeof t.ports=="object")return{ports:t.ports}}catch{}return{ports:{}}}var He=null,Ue=null;function mn(n){Ue=n,!He&&(He=setTimeout(()=>{He=null;let t=Ue;if(Ue=null,!!t)try{We.mkdirSync(dn.dirname(Ge),{recursive:!0}),We.writeFileSync(Ge,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: state write failed: ${e.message}
69
+ `)}},500))}$e();Gt();import hn from"node:fs";import Bo from"node:os";import gn from"node:path";import{createRequire as Ho}from"node:module";var Uo=Ho(import.meta.url),Wo=6e4,ae=class{constructor(t,e){this.registry=t;this.cfg=e;this.logFile=gn.join(Bo.homedir(),".daimon","notifications.log");try{hn.mkdirSync(gn.dirname(this.logFile),{recursive:!0})}catch{}if(!e.enabled){this.audit("init","disabled by config");return}try{let r=Uo("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}
70
+ `;try{hn.appendFileSync(this.logFile,r)}catch{}}warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] notifier: ${t}
71
+ `))}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 i=`${t}::${e}`,o=this.lastSent.get(i)??0,a=Date.now();if(a-o<Wo){this.audit("throttled",`${i}`);return}this.lastSent.set(i,a);let c={title:`daimon: ${r}`,message:s,wait:!1,appID:"daimon"},u=(h,p)=>{h?(this.audit("fail",`${i} :: ${h?.message||h}`),this.warnOnce(`notify failed: ${h?.message||h}`)):this.audit("ok",`${i} :: ${r} :: ${p??"(no response)"}`)};try{this.audit("attempt",`${i} :: ${r}`),(this.toaster??this.notifier).notify(c,u)}catch(h){this.audit("throw",`${i} :: ${h?.message||h}`),this.warnOnce(`notify threw: ${h?.message||h}`)}}};import yn from"node:fs";import Je from"node:path";var Go=5e3,Jo=3e4,qo=new Set(["node_modules","dist",".angular",".nx",".git","tmp","out-tsc","coverage"]),Ko=new Set([".ts",".tsx",".html",".scss",".css",".js",".jsx",".json"]),ce=class{constructor(t,e){this.registry=t;this.cfg=e;e.enabled&&(this.timer=setInterval(()=>this.tick(),Go),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,i=Date.now()-s;if(i<this.cfg.silentMs){e.stale&&this.registry.setStale(t,!1);return}let o=e.lastCompileAt??e.startedAt;this.hasSourceChange(r.workspaceRoot,o,e.lastCompileAt)&&(e.stale||(this.registry.setStale(t,!0),this.registry.recordEvent({app:t,type:"stale",message:`no output in ${Math.round(i/1e3)}s despite source changes`})))}hasSourceChange(t,e,r){let s=this.caches.get(t);if(!s||Date.now()-s.ts>Jo||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,i)=>{if(i>8||e.length>4e3)return;let o;try{o=yn.readdirSync(s,{withFileTypes:!0})}catch{return}for(let a of o)if(!a.name.startsWith(".git")){if(a.isDirectory()){if(qo.has(a.name))continue;r(Je.join(s,a.name),i+1)}else if(a.isFile()){let c=Je.extname(a.name);if(!Ko.has(c))continue;try{let u=Je.join(s,a.name),h=yn.statSync(u);e.push({path:u,mtime:h.mtimeMs})}catch{}}}};return r(t,0),e}};import vn from"node:http";var le=200,ue=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=[],i=vn.createServer((o,a)=>{let c=Date.now(),u={hostname:"127.0.0.1",port:e,method:o.method,path:o.url,headers:{...o.headers,host:`127.0.0.1:${e}`}},h=vn.request(u,p=>{a.writeHead(p.statusCode||502,p.headers),p.pipe(a);let v=()=>{s.push({ts:Date.now(),method:o.method||"GET",path:o.url||"/",status:p.statusCode||0,durationMs:Date.now()-c}),s.length>le&&s.splice(0,s.length-le)};p.on("end",v),p.on("error",v)});h.on("error",()=>{a.writeHead(502).end("upstream error"),s.push({ts:Date.now(),method:o.method||"GET",path:o.url||"/",status:502,durationMs:Date.now()-c}),s.length>le&&s.splice(0,s.length-le)}),o.pipe(h)});i.on("error",o=>{o?.code==="EADDRINUSE"&&process.stderr.write(`[daimon] requestLog: port ${r} in use for ${t}; disabling proxy
72
+ `),this.proxies.delete(t)}),i.listen(r,"127.0.0.1",()=>{this.proxies.set(t,{app:t,proxyPort:r,server:i,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(i=>i.ts>=s)}return[...r.buffer]}proxyPortFor(t){return this.proxies.get(t)?.proxyPort??null}};dt();Rt();Ct();import qe from"node:fs";var Xo=new Set(["command","port","env","url"]);function bn(n){let t=qe.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 wn(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]=wn(e[r],s);return e}function zo(n,t){let e=n+"."+process.pid+".tmp";qe.writeFileSync(e,t,"utf8"),qe.renameSync(e,n)}function Yo(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 Sn(n){let t=bn(n.configPath),e=wn(t,n.patch);if(!e||typeof e!="object")throw new Error("patch produced non-object config");let r=Ft(e,n.configPath);return zo(n.configPath,JSON.stringify(e,null,2)+`
73
+ `),{config:r,raw:e,applied:Yo(t,e),prevRaw:t}}function Ke(n){let t=bn(n.configPath),e=Ft(t,n.configPath);return Vo(n.registry,e)}function Vo(n,t){let e=n.getConfig();for(let u of Object.keys(e))e[u]=void 0;Object.assign(e,t);let r=new Set(n.names()),s=At(e),i=new Set(s.map(u=>u.name)),o=[],a=[];for(let u of s)r.has(u.name)?n.updateDiscoveredApp(u):(n.addDiscoveredApp(u),o.push(u.name));for(let u of r)i.has(u)||a.push(u);let c=[];for(let u of n.names()){let h=n.getState(u);if(h&&(h.status==="serving"||h.status==="compiling")){let p=e.overrides?.[u];if(!p)continue;for(let v of Xo)if(v in p){c.push(u);break}}}return{addedApps:o,removedApps:a,restartRequired:c,config:e}}Jt();dt();import xn from"node:fs";import Zo from"node:os";import kn from"node:path";var Qo=/key|secret|token|password|pass/i;function ti(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))Qo.test(s)&&(r[s]="***")}return t}function ei(n,t=200){if(!n)return[];let e=[];for(let r of n.names()){let s=n.getState(r);if(s)for(let i of s.logBuffer)e.push({ts:i.ts,line:`[${r}] ${i.line}`})}return e.sort((r,s)=>r.ts-s.ts),e.slice(-t).map(r=>r.line)}function ri(){let n=kn.join(ot(),"crashes");return xn.mkdirSync(n,{recursive:!0}),n}function ni(n,t,e){let r=new Date().toISOString().replace(/[:.]/g,"-"),s=kn.join(ri(),`${r}.txt`),i=n,o=[`daimon crash dump @ ${new Date().toISOString()}`,`version: ${yt}`,`node: ${process.version}`,`platform: ${process.platform} ${Zo.release()}`,`cwd: ${process.cwd()}`,`pid: ${process.pid}`,"","ERROR:",i?.stack||String(i),"","CONFIG (redacted):",JSON.stringify(ti(e),null,2),"","RECENT LOG (last 200 lines across apps):",...ei(t,200)];try{xn.writeFileSync(s,o.join(`
74
+ `))}catch{}return s}function Tn(n){let t=e=>{let r=null;try{r=ni(e,n.getRegistry(),n.getConfig())}catch{}try{process.stderr.write(`[daimon] fatal: ${e?.stack||e}
62
75
  `)}catch{}if(r)try{process.stderr.write(`[daimon] crash dump: ${r}
63
- `)}catch{}process.exit(1)};process.on("uncaughtException",t),process.on("unhandledRejection",t)}import x,{useEffect as to,useState as J}from"react";import Ce from"node:fs";import eo from"node:os";import ro from"node:path";import{Box as H,Text as R,useApp as no,useInput as so,useStdout as oo}from"ink";import Re from"ink-text-input";import{spawn as Pe,spawnSync as io}from"node:child_process";import L,{useEffect as Ys,useMemo as zs,useState as lt}from"react";import{Box as St,Text as I,useInput as Vs,useStdout as Qs}from"ink";import Zs from"ink-text-input";function Ae({registry:n,appName:t,onExit:e}){let{stdout:r}=Qs(),[s,i]=lt(0),[o,a]=lt(!1),[u,c]=lt(""),[h,p]=lt(""),[b,S]=lt(0),[l,m]=lt(0);Ys(()=>{let f=()=>i(P=>P+1);n.on("change",f);let C=setInterval(()=>i(P=>P+1),500);return()=>{n.off("change",f),clearInterval(C)}},[n]);let d=n.getState(t)?.logBuffer.map(f=>f.line)??[],y=(r.rows||30)-4,k=zs(()=>{if(!h)return[];let f=h.toLowerCase();return d.reduce((C,P,M)=>(P.toLowerCase().includes(f)&&C.push(M),C),[])},[d,h,s]);Vs((f,C)=>{if(o){if(C.escape){a(!1),c("");return}return}if(f==="q"||C.escape){e();return}if(f==="/"){a(!0);return}if(f==="g"){S(Math.max(0,d.length-y));return}if(f==="G"){S(0);return}if(C.pageUp){S(P=>Math.min(Math.max(0,d.length-y),P+y));return}if(C.pageDown){S(P=>Math.max(0,P-y));return}if(C.upArrow){S(P=>Math.min(Math.max(0,d.length-y),P+1));return}if(C.downArrow){S(P=>Math.max(0,P-1));return}if((f==="n"||f==="N")&&k.length){let P=f==="n"?(l+1)%k.length:(l-1+k.length)%k.length;m(P);let M=k[P],Z=d.length-b,A=Z-y;(M<A||M>=Z)&&S(Math.max(0,d.length-M-Math.floor(y/2)));return}});let E=f=>{p(f),a(!1),c(""),m(0)},v=d.length-b,O=Math.max(0,v-y),_=d.slice(O,v),T=(f,C)=>{if(!h)return L.createElement(I,{key:C},L.createElement(I,{dimColor:!0},String(C+1).padStart(5)," "),f);let P=h,M=f.toLowerCase(),Z=P.toLowerCase(),A=[],$=0,j=0;for(;$<f.length;){let D=M.indexOf(Z,$);if(D<0){A.push(L.createElement(I,{key:j++},f.slice($)));break}D>$&&A.push(L.createElement(I,{key:j++},f.slice($,D))),A.push(L.createElement(I,{key:j++,backgroundColor:"yellow",color:"black"},f.slice(D,D+P.length))),$=D+P.length}let N=k[l]===C;return L.createElement(I,{key:C},L.createElement(I,{color:N?"cyan":void 0,dimColor:!N},String(C+1).padStart(5)," "),A)};return L.createElement(St,{flexDirection:"column"},L.createElement(St,null,L.createElement(I,{bold:!0},"full log: ",L.createElement(I,{color:"cyan"},t)),L.createElement(I,{dimColor:!0}," (",d.length," lines",h?`, ${k.length} matches for "${h}"`:"",", scroll=",b,")")),L.createElement(St,{flexDirection:"column"},_.length===0?L.createElement(I,{dimColor:!0},"(no log yet)"):_.map((f,C)=>T(f,O+C))),L.createElement(St,null,o?L.createElement(St,null,L.createElement(I,null,"/"),L.createElement(Zs,{value:u,onChange:c,onSubmit:E})):L.createElement(I,{dimColor:!0},"[/] search [n/N] next/prev [g/G] bottom/top [PgUp/PgDn] [\u2191\u2193] [q/Esc] back")))}function ao(n){try{process.platform==="win32"?Pe("cmd",["/c","start","",n],{detached:!0,stdio:"ignore",windowsHide:!0}).unref():process.platform==="darwin"?Pe("open",[n],{detached:!0,stdio:"ignore"}).unref():Pe("xdg-open",[n],{detached:!0,stdio:"ignore"}).unref()}catch{}}var Jr={stopped:"gray",starting:"yellow",compiling:"yellow",serving:"green",error:"red"},Gr={healthy:"green",unhealthy:"red",unknown:"gray"};function co(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 Oe({registry:n,apiPort:t,onQuit:e}){let{exit:r}=no(),{stdout:s}=oo(),[i,o]=J(n.list()),[a,u]=J(0),[c,h]=J(!1),[p,b]=J(0),[S,l]=J(!1),[m,g]=J([]),[d,y]=J(!1),[k,E]=J(""),[v,O]=J(null),[,_]=J(0);to(()=>{let A=()=>o(n.list());n.on("change",A);let $=setInterval(()=>{o(n.list()),_(j=>j+1)},1e3);return()=>{n.off("change",A),clearInterval($)}},[n]),so((A,$)=>{if(S)return;if(v){if($.escape){O(null);return}if($.tab){let N=v.field==="command"?"port":v.field==="port"?"env":"command";O({...v,field:N});return}return}if(d){if($.escape){y(!1),E("");return}if($.return){let N=k.trim();g(N?N.split(/[\s,]+/).filter(Boolean):[]),y(!1),E("");return}if($.backspace||$.delete){E(N=>N.slice(0,-1));return}A&&!$.ctrl&&E(N=>N+A);return}if(A==="q"||$.ctrl&&A==="c"){e(),r();return}if(i.length===0)return;if($.upArrow){u(N=>Math.max(0,N-1)),b(0);return}if($.downArrow){u(N=>Math.min(i.length-1,N+1)),b(0);return}let j=i[a];if(j)if(A==="s")n.start(j.name);else if(A==="x")n.stop(j.name);else if(A==="r")n.restart(j.name);else if(A==="L")l(!0);else if(A==="t")y(!0),E(m.join(" "));else if(A==="e"){let N=n.getConfig(),D=n.getApp(j.name),G=n.getState(j.name)?.sessionOverrides??null,ut=G?.env??N.overrides?.[j.name]?.env??{},z=Object.entries(ut).map(([Kt,Yt])=>`${Kt}=${Yt}`).join(`
64
- `);O({name:j.name,field:"command",cmd:G?.command??D?.command??"",port:String(G?.port??N.overrides?.[j.name]?.port??j.port??""),env:z})}else if(A==="E"){let D=n.getConfig().envFiles?.[j.name]??[];if(!D.length)return;let G=n.getState(j.name)?.activeEnvFile??null,ut=G?D.indexOf(G):-1,z=D[(ut+1)%D.length];n.setActiveEnvFile(j.name,z)}else if(A==="V"){let N=process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),D=ro.join(eo.tmpdir(),`daimon-${j.name}-${Date.now()}.json`),G=n.getConfig(),ut=n.getApp(j.name),z=n.getState(j.name)?.sessionOverrides??null,Kt={command:z?.command??ut?.command,port:z?.port??G.overrides?.[j.name]?.port??null,env:z?.env??G.overrides?.[j.name]?.env??{}};try{Ce.writeFileSync(D,JSON.stringify(Kt,null,2)),io(N,[D],{stdio:"inherit",shell:!0});let Yt=Ce.readFileSync(D,"utf8"),V=JSON.parse(Yt);n.setSessionOverride(j.name,{command:typeof V.command=="string"?V.command:void 0,port:typeof V.port=="number"?V.port:void 0,env:V.env&&typeof V.env=="object"?V.env:void 0}),Ce.unlinkSync(D)}catch{}}else A==="l"?h(N=>!N):A==="o"?j.url&&ao(j.url):$.pageUp?b(N=>N+5):$.pageDown&&b(N=>Math.max(0,N-5))});let T=m.length===0?i:i.filter(A=>m.every($=>A.tags.includes($))),f=T[Math.min(a,Math.max(0,T.length-1))],C=f?n.getState(f.name):null,P=C?C.logBuffer.slice(Math.max(0,C.logBuffer.length-12-p),C.logBuffer.length-p).map(A=>A.line):[],M=s.columns||100,Z=Math.min(36,Math.floor(M*.4));return S&&f?x.createElement(Ae,{registry:n,appName:f.name,onExit:()=>l(!1)}):x.createElement(H,{flexDirection:"column",width:M},x.createElement(H,{borderStyle:"round",borderColor:"cyan",paddingX:1},x.createElement(R,{bold:!0,color:"cyan"},"daimon"),x.createElement(R,{dimColor:!0}," \u2022 api http://127.0.0.1:",t)),x.createElement(H,{flexDirection:"row"},x.createElement(H,{flexDirection:"column",width:Z,borderStyle:"single",borderColor:"gray",paddingX:1},x.createElement(R,{bold:!0},"Apps ",m.length?x.createElement(R,{dimColor:!0},"(tags: ",m.join(", "),")"):null),T.length===0?x.createElement(R,{dimColor:!0},i.length===0?"(no apps discovered)":"(no apps match tag filter)"):T.map((A,$)=>{let j=$===a;return x.createElement(H,{key:A.name},x.createElement(R,{color:j?"cyan":void 0},j?"\u25B8 ":" "),x.createElement(R,{color:j?"cyan":void 0},((n.getState(A.name)?.sessionOverrides?"*":"")+A.name).padEnd(20).slice(0,20)),x.createElement(R,{color:Jr[A.status]}," ",A.status.padEnd(9)),x.createElement(R,{color:Gr[A.health]},A.status==="serving"?"\u25CF":" "),x.createElement(R,{dimColor:!0},A.port?` :${A.port}`:""),M>=100&&A.cpu!=null?x.createElement(R,{dimColor:!0}," ",String(A.cpu).padStart(5),"% ",String(A.memMB??0).padStart(5),"MB"):null)})),x.createElement(H,{flexDirection:"column",flexGrow:1,borderStyle:"single",borderColor:"gray",paddingX:1},f&&C?x.createElement(x.Fragment,null,x.createElement(R,null,"Selected: ",x.createElement(R,{bold:!0},f.name)),x.createElement(R,null,"Status: ",x.createElement(R,{color:Jr[f.status]},f.status)," ",x.createElement(R,{color:Gr[f.health]},"\u25CF")," ",x.createElement(R,{dimColor:!0},f.health)),x.createElement(R,null,"Port: ",f.port??"-"),x.createElement(R,null,"URL: ",f.url??"-"),f.announcedUrl&&f.announcedUrl!==f.url?x.createElement(R,{dimColor:!0},"Announced: ",f.announcedUrl):null,f.lastHealthError?x.createElement(R,{color:"red"},"HealthErr: ",f.lastHealthError):null,f.stale?x.createElement(R,{color:"yellow"},"\u26A0 stale (best guess)"):null,x.createElement(R,null,"Errors: ",x.createElement(R,{color:f.errorCount?"red":void 0},f.errorCount)),x.createElement(R,null,"Uptime: ",co(f.uptimeMs)),f.cpu!=null||f.memMB!=null?x.createElement(R,null,"Usage: ",f.cpu??"-","% ",f.memMB??"-"," MB"):null,f.compileHistoryMs.length>0?x.createElement(R,null,"Recent compile: ",f.compileHistoryMs.slice(-5).map(A=>(A/1e3).toFixed(1)+"s").join(" \xB7 ")):null,f.bundle?x.createElement(R,null,"Bundle: ",f.bundle.initialKB,"KB initial \xB7 ",f.bundle.lazyKB,"KB lazy",f.bundleRegressionPct!=null&&f.bundleRegressionPct>10?x.createElement(R,{color:"red"}," (+",f.bundleRegressionPct,"% \u26A0)"):null):null,C.lastStatusMessage?x.createElement(R,{dimColor:!0},"Note: ",C.lastStatusMessage):null,x.createElement(R,null,"\u2500\u2500\u2500\u2500 recent log ",c?"(focused)":""," \u2500\u2500\u2500\u2500"),P.length===0?x.createElement(R,{dimColor:!0},"(no output yet)"):P.map((A,$)=>x.createElement(R,{key:$,wrap:"truncate-end"},A))):x.createElement(R,{dimColor:!0},"No app selected."))),x.createElement(H,{flexDirection:"column"},d?x.createElement(R,null,"tag filter (space-separated, Enter to apply, Esc to cancel): ",x.createElement(R,{color:"cyan"},k)):null,v?x.createElement(H,{flexDirection:"column",borderStyle:"round",borderColor:"yellow",paddingX:1},x.createElement(R,{bold:!0,color:"yellow"},"edit ",v.name," (session-only) Tab=next field Enter=save Esc=cancel"),x.createElement(H,null,x.createElement(R,null,v.field==="command"?"> ":" ","command: "),v.field==="command"?x.createElement(Re,{value:v.cmd,onChange:A=>O({...v,cmd:A}),onSubmit:()=>O({...v,field:"port"})}):x.createElement(R,{dimColor:!0},v.cmd)),x.createElement(H,null,x.createElement(R,null,v.field==="port"?"> ":" ","port: "),v.field==="port"?x.createElement(Re,{value:v.port,onChange:A=>O({...v,port:A}),onSubmit:()=>O({...v,field:"env"})}):x.createElement(R,{dimColor:!0},v.port)),x.createElement(H,null,x.createElement(R,null,v.field==="env"?"> ":" ","env (k=v;): "),v.field==="env"?x.createElement(Re,{value:v.env.replace(/\n/g,";"),onChange:A=>O({...v,env:A.replace(/;/g,`
65
- `)}),onSubmit:()=>{let A=Number(v.port),$={};for(let j of v.env.split(/\n/)){let N=j.match(/^\s*([^=]+)=(.*)$/);N&&($[N[1].trim()]=N[2])}n.setSessionOverride(v.name,{command:v.cmd||void 0,port:Number.isFinite(A)&&A>0?A:void 0,env:Object.keys($).length?$:void 0}),O(null)}}):x.createElement(R,{dimColor:!0},v.env))):null,x.createElement(R,{dimColor:!0},"[s] start [x] stop [r] restart [o] open URL [t] tag filter [e] edit [E] cycle env [V] $EDITOR [l] log focus [Shift+L] full log [PgUp/PgDn] scroll [q] quit")))}async function fo(n={}){let t=null,e=null;Wr({getRegistry:()=>t,getConfig:()=>e});let r;try{r=et()}catch(T){process.stderr.write(`[daimon] config error: ${T.message}
66
- `),process.exit(1)}if(r.kind==="stub-created"){let T=ft();process.stdout.write(`[daimon] no config found. Created stub at:
76
+ `)}catch{}process.exit(1)};process.on("uncaughtException",t),process.on("unhandledRejection",t)}import A,{useEffect as ui,useState as q}from"react";import ze from"node:fs";import pi from"node:os";import di from"node:path";import{Box as X,Text as j,useApp as fi,useInput as mi,useStdout as hi}from"ink";import Ye from"ink-text-input";import{spawn as Ve,spawnSync as gi}from"node:child_process";import G,{useEffect as si,useMemo as oi,useState as Tt}from"react";import{Box as _t,Text as Z,useInput as ii,useStdout as ai}from"ink";import ci from"ink-text-input";function Xe({registry:n,appName:t,onExit:e}){let{stdout:r}=ai(),[s,i]=Tt(0),[o,a]=Tt(!1),[c,u]=Tt(""),[h,p]=Tt(""),[v,b]=Tt(0),[l,m]=Tt(0);si(()=>{let R=()=>i(x=>x+1);n.on("change",R);let M=setInterval(()=>i(x=>x+1),500);return()=>{n.off("change",R),clearInterval(M)}},[n]);let d=n.getState(t)?.logBuffer.map(R=>R.line)??[],g=(r.rows||30)-4,T=oi(()=>{if(!h)return[];let R=h.toLowerCase();return d.reduce((M,x,L)=>(x.toLowerCase().includes(R)&&M.push(L),M),[])},[d,h,s]);ii((R,M)=>{if(o){if(M.escape){a(!1),u("");return}return}if(R==="q"||M.escape){e();return}if(R==="/"){a(!0);return}if(R==="g"){b(Math.max(0,d.length-g));return}if(R==="G"){b(0);return}if(M.pageUp){b(x=>Math.min(Math.max(0,d.length-g),x+g));return}if(M.pageDown){b(x=>Math.max(0,x-g));return}if(M.upArrow){b(x=>Math.min(Math.max(0,d.length-g),x+1));return}if(M.downArrow){b(x=>Math.max(0,x-1));return}if((R==="n"||R==="N")&&T.length){let x=R==="n"?(l+1)%T.length:(l-1+T.length)%T.length;m(x);let L=T[x],H=d.length-v,$=H-g;(L<$||L>=H)&&b(Math.max(0,d.length-L-Math.floor(g/2)));return}});let E=R=>{p(R),a(!1),u(""),m(0)},y=d.length-v,N=Math.max(0,y-g),C=d.slice(N,y),S=(R,M)=>{if(!h)return G.createElement(Z,{key:M},G.createElement(Z,{dimColor:!0},String(M+1).padStart(5)," "),R);let x=h,L=R.toLowerCase(),H=x.toLowerCase(),$=[],J=0,I=0;for(;J<R.length;){let et=L.indexOf(H,J);if(et<0){$.push(G.createElement(Z,{key:I++},R.slice(J)));break}et>J&&$.push(G.createElement(Z,{key:I++},R.slice(J,et))),$.push(G.createElement(Z,{key:I++,backgroundColor:"yellow",color:"black"},R.slice(et,et+x.length))),J=et+x.length}let it=T[l]===M;return G.createElement(Z,{key:M},G.createElement(Z,{color:it?"cyan":void 0,dimColor:!it},String(M+1).padStart(5)," "),$)};return G.createElement(_t,{flexDirection:"column"},G.createElement(_t,null,G.createElement(Z,{bold:!0},"full log: ",G.createElement(Z,{color:"cyan"},t)),G.createElement(Z,{dimColor:!0}," (",d.length," lines",h?`, ${T.length} matches for "${h}"`:"",", scroll=",v,")")),G.createElement(_t,{flexDirection:"column"},C.length===0?G.createElement(Z,{dimColor:!0},"(no log yet)"):C.map((R,M)=>S(R,N+M))),G.createElement(_t,null,o?G.createElement(_t,null,G.createElement(Z,null,"/"),G.createElement(ci,{value:c,onChange:u,onSubmit:E})):G.createElement(Z,{dimColor:!0},"[/] search [n/N] next/prev [g/G] bottom/top [PgUp/PgDn] [\u2191\u2193] [q/Esc] back")))}var En={stopped:1,serving:2,compiling:3,starting:3,error:4},li={"":"\xB7",stopped:"\u2591",serving:"\u2593",compiling:"\u2592",starting:"\u2592",error:"\u2588"};function Rn(n,t,e=Date.now()){let r=e-36e5,s=36e5/20,i=new Array(20).fill("");for(let o of n){if(o.type!=="status"||o.app!==t||!o.to||o.ts<r||o.ts>e)continue;let a=Math.min(19,Math.floor((o.ts-r)/s)),c=i[a];(!c||(En[o.to]??0)>(En[c]??0))&&(i[a]=o.to)}return i}function An(n){return n.map(t=>li[t]??"\xB7").join("")}function yi(n){try{process.platform==="win32"?Ve("cmd",["/c","start","",n],{detached:!0,stdio:"ignore",windowsHide:!0}).unref():process.platform==="darwin"?Ve("open",[n],{detached:!0,stdio:"ignore"}).unref():Ve("xdg-open",[n],{detached:!0,stdio:"ignore"}).unref()}catch{}}var Cn={stopped:"gray",starting:"yellow",compiling:"yellow",serving:"green",error:"red"},Pn={healthy:"green",unhealthy:"red",unknown:"gray"};function vi(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 Ze({registry:n,apiPort:t,onQuit:e}){let{exit:r}=fi(),{stdout:s}=hi(),[i,o]=q(n.list()),[a,c]=q(0),[u,h]=q(!1),[p,v]=q(0),[b,l]=q(!1),[m,f]=q([]),[d,g]=q(!1),[T,E]=q(""),[y,N]=q(null),[,C]=q(0),[S,R]=q(null),[M,x]=q(""),[L,H]=q(!1),[$,J]=q(null),[I,it]=q(""),[et,pe]=q(!1),[Qe,tr]=q(null),[On,er]=q(n.events({sinceMs:3600*1e3}));ui(()=>{let k=()=>o(n.list()),O=()=>er(n.events({sinceMs:36e5}));n.on("change",k),n.on("event",O);let D=setInterval(()=>{o(n.list()),er(n.events({sinceMs:3600*1e3})),C(P=>P+1)},1e3);return()=>{n.off("change",k),n.off("event",O),clearInterval(D)}},[n]),mi((k,O)=>{if(b)return;if(y){if(O.escape){N(null);return}if(O.tab){let P=y.field==="command"?"port":y.field==="port"?"env":"command";N({...y,field:P});return}return}if(d){if(O.escape){g(!1),E("");return}if(O.return){let P=T.trim();f(P?P.split(/[\s,]+/).filter(Boolean):[]),g(!1),E("");return}if(O.backspace||O.delete){E(P=>P.slice(0,-1));return}k&&!O.ctrl&&E(P=>P+k);return}if(L){if(O.escape){H(!1);return}if(O.return){H(!1);return}if(O.backspace||O.delete){x(P=>P.slice(0,-1));return}k&&!O.ctrl&&x(P=>P+k);return}if(et){if(O.escape){pe(!1),it("");return}if(O.return){let P=I.trim();pe(!1),it(""),P&&Nn(P);return}if(O.backspace||O.delete){it(P=>P.slice(0,-1));return}k&&!O.ctrl&&it(P=>P+k);return}if($){if(k==="y"||k==="Y"){let P=$;J(null),n.restart(P),K(`restarted ${P}`)}else(k==="n"||k==="N"||O.escape)&&J(null);return}if(k==="q"||O.ctrl&&k==="c"){e(),r();return}if(i.length===0)return;if(S==="g"){R(null);let P=k.toLowerCase();P==="a"?K("view: apps (only TUI view)"):P==="e"?K("view: errors \u2014 selected app errors shown in detail pane"):P==="v"?K("view: events \u2014 recent registry events shown in log pane"):P==="s"?K("view: settings \u2014 edit `daimon.config.json`"):P==="n"&&K("view: sessions \u2014 `daimon record` to toggle recording");return}if(O.upArrow||k==="k"){c(P=>Math.max(0,P-1)),v(0);return}if(O.downArrow||k==="j"){c(P=>Math.min(i.length-1,P+1)),v(0);return}let D=i[a];if(D){if(k==="g"){R("g"),setTimeout(()=>R(P=>P==="g"?null:P),1200);return}if(k==="/"){H(!0);return}if(k==="s")n.start(D.name);else if(k==="S")n.stop(D.name);else if(k==="r")J(D.name);else if(k==="f")jn(D.name);else if(k==="x")Mn(D.name);else if(k==="O")pe(!0);else if(k==="L")l(!0);else if(k==="t")g(!0),E(m.join(" "));else if(k==="e"){let P=n.getConfig(),U=n.getApp(D.name),V=n.getState(D.name)?.sessionOverrides??null,ct=V?.env??P.overrides?.[D.name]?.env??{},lt=Object.entries(ct).map(([fe,me])=>`${fe}=${me}`).join(`
77
+ `);N({name:D.name,field:"command",cmd:V?.command??U?.command??"",port:String(V?.port??P.overrides?.[D.name]?.port??D.port??""),env:lt})}else if(k==="E"){let U=n.getConfig().envFiles?.[D.name]??[];if(!U.length)return;let V=n.getState(D.name)?.activeEnvFile??null,ct=V?U.indexOf(V):-1,lt=U[(ct+1)%U.length];n.setActiveEnvFile(D.name,lt)}else if(k==="V"){let P=process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),U=di.join(pi.tmpdir(),`daimon-${D.name}-${Date.now()}.json`),V=n.getConfig(),ct=n.getApp(D.name),lt=n.getState(D.name)?.sessionOverrides??null,fe={command:lt?.command??ct?.command,port:lt?.port??V.overrides?.[D.name]?.port??null,env:lt?.env??V.overrides?.[D.name]?.env??{}};try{ze.writeFileSync(U,JSON.stringify(fe,null,2)),gi(P,[U],{stdio:"inherit",shell:!0});let me=ze.readFileSync(U,"utf8"),ut=JSON.parse(me);n.setSessionOverride(D.name,{command:typeof ut.command=="string"?ut.command:void 0,port:typeof ut.port=="number"?ut.port:void 0,env:ut.env&&typeof ut.env=="object"?ut.env:void 0}),ze.unlinkSync(U)}catch{}}else k==="l"?h(P=>!P):k==="o"?D.url&&yi(D.url):O.pageUp?v(P=>P+5):O.pageDown&&v(P=>Math.max(0,P-5))}});let K=k=>{tr(k),setTimeout(()=>tr(O=>O===k?null:O),4e3)},Mn=async k=>{K(`try-fix ${k}\u2026`);try{let{runAutoFix:O,ALL_AUTO_FIX:D}=await Promise.resolve().then(()=>(Nt(),jt)),U=n.getConfig().doctor?.autoFix?.permitted??D,V=await O({permitted:U,dryRun:!1});await n.restart(k);let ct=await n.waitFor(k,"healthy",6e4);K(`try-fix ${k}: ${ct.timedOut?"timeout":"reached"} \xB7 fixed ${V.ran.length}`)}catch(O){K(`try-fix ${k} failed: ${O?.message??O}`)}},jn=async k=>{K(`focus ${k} until stable\u2026`);try{let O=Date.now(),D=Date.now(),P=U=>{U.app===k&&(D=Date.now())};n.on("event",P);try{for(;Date.now()-O<18e4;){let U=n.summary(k);if(U&&U.status==="serving"&&U.health==="healthy"&&Date.now()-D>=5e3){K(`focus ${k}: stable after ${Math.round((Date.now()-O)/1e3)}s`);return}await new Promise(V=>setTimeout(V,500))}}finally{n.off("event",P)}K(`focus ${k}: timed out`)}catch(O){K(`focus ${k} failed: ${O?.message??O}`)}},Nn=async k=>{K(`orchestrate ${k}\u2026`);try{let{orchestrateProfile:O}=await Promise.resolve().then(()=>(De(),Le)),D=await O(n,n.getConfig(),{profile:k,goal:"healthy",timeoutMs:3e5});if(D.error){K(`orchestrate ${k}: ${D.error}`);return}let P=D.allReached;K(`orchestrate ${k}: ${P?"all reached":"some failing"} \xB7 ${Math.round(D.totalMs/1e3)}s`)}catch(O){K(`orchestrate ${k} failed: ${O?.message??O}`)}},rr=M.trim().toLowerCase(),Lt=(m.length===0?i:i.filter(k=>m.every(O=>k.tags.includes(O)))).filter(k=>!rr||k.name.toLowerCase().includes(rr)),F=Lt[Math.min(a,Math.max(0,Lt.length-1))],at=F?n.getState(F.name):null,nr=at?at.logBuffer.slice(Math.max(0,at.logBuffer.length-12-p),at.logBuffer.length-p).map(k=>k.line):[],de=s.columns||100,$n=Math.min(36,Math.floor(de*.4));return b&&F?A.createElement(Xe,{registry:n,appName:F.name,onExit:()=>l(!1)}):A.createElement(X,{flexDirection:"column",width:de},A.createElement(X,{borderStyle:"round",borderColor:"cyan",paddingX:1},A.createElement(j,{bold:!0,color:"cyan"},"daimon"),A.createElement(j,{dimColor:!0}," \u2022 api http://127.0.0.1:",t)),A.createElement(X,{flexDirection:"row"},A.createElement(X,{flexDirection:"column",width:$n,borderStyle:"single",borderColor:"gray",paddingX:1},A.createElement(j,{bold:!0},"Apps ",m.length?A.createElement(j,{dimColor:!0},"(tags: ",m.join(", "),")"):null),Lt.length===0?A.createElement(j,{dimColor:!0},i.length===0?"(no apps discovered)":"(no apps match filter)"):Lt.map((k,O)=>{let D=O===a,P=Rn(On,k.name),U=An(P);return A.createElement(X,{key:k.name,flexDirection:"column"},A.createElement(X,null,A.createElement(j,{color:D?"cyan":void 0},D?"\u25B8 ":" "),A.createElement(j,{color:D?"cyan":void 0},((n.getState(k.name)?.sessionOverrides?"*":"")+k.name).padEnd(20).slice(0,20)),A.createElement(j,{color:Cn[k.status]}," ",k.status.padEnd(9)),A.createElement(j,{color:Pn[k.health]},k.status==="serving"?"\u25CF":" "),A.createElement(j,{dimColor:!0},k.port?` :${k.port}`:""),de>=100&&k.cpu!=null?A.createElement(j,{dimColor:!0}," ",String(k.cpu).padStart(5),"% ",String(k.memMB??0).padStart(5),"MB"):null),A.createElement(X,null,A.createElement(j,{dimColor:!0}," "),A.createElement(j,{dimColor:!0},U)))})),A.createElement(X,{flexDirection:"column",flexGrow:1,borderStyle:"single",borderColor:"gray",paddingX:1},F&&at?A.createElement(A.Fragment,null,A.createElement(j,null,"Selected: ",A.createElement(j,{bold:!0},F.name)),A.createElement(j,null,"Status: ",A.createElement(j,{color:Cn[F.status]},F.status)," ",A.createElement(j,{color:Pn[F.health]},"\u25CF")," ",A.createElement(j,{dimColor:!0},F.health)),A.createElement(j,null,"Port: ",F.port??"-"),A.createElement(j,null,"URL: ",F.url??"-"),F.announcedUrl&&F.announcedUrl!==F.url?A.createElement(j,{dimColor:!0},"Announced: ",F.announcedUrl):null,F.lastHealthError?A.createElement(j,{color:"red"},"HealthErr: ",F.lastHealthError):null,F.stale?A.createElement(j,{color:"yellow"},"\u26A0 stale (best guess)"):null,A.createElement(j,null,"Errors: ",A.createElement(j,{color:F.errorCount?"red":void 0},F.errorCount)),A.createElement(j,null,"Uptime: ",vi(F.uptimeMs)),F.cpu!=null||F.memMB!=null?A.createElement(j,null,"Usage: ",F.cpu??"-","% ",F.memMB??"-"," MB"):null,F.compileHistoryMs.length>0?A.createElement(j,null,"Recent compile: ",F.compileHistoryMs.slice(-5).map(k=>(k/1e3).toFixed(1)+"s").join(" \xB7 ")):null,F.bundle?A.createElement(j,null,"Bundle: ",F.bundle.initialKB,"KB initial \xB7 ",F.bundle.lazyKB,"KB lazy",F.bundleRegressionPct!=null&&F.bundleRegressionPct>10?A.createElement(j,{color:"red"}," (+",F.bundleRegressionPct,"% \u26A0)"):null):null,at.lastStatusMessage?A.createElement(j,{dimColor:!0},"Note: ",at.lastStatusMessage):null,A.createElement(j,null,"\u2500\u2500\u2500\u2500 recent log ",u?"(focused)":""," \u2500\u2500\u2500\u2500"),nr.length===0?A.createElement(j,{dimColor:!0},"(no output yet)"):nr.map((k,O)=>A.createElement(j,{key:O,wrap:"truncate-end"},k))):A.createElement(j,{dimColor:!0},"No app selected."))),A.createElement(X,{flexDirection:"column"},d?A.createElement(j,null,"tag filter (space-separated, Enter to apply, Esc to cancel): ",A.createElement(j,{color:"cyan"},T)):null,y?A.createElement(X,{flexDirection:"column",borderStyle:"round",borderColor:"yellow",paddingX:1},A.createElement(j,{bold:!0,color:"yellow"},"edit ",y.name," (session-only) Tab=next field Enter=save Esc=cancel"),A.createElement(X,null,A.createElement(j,null,y.field==="command"?"> ":" ","command: "),y.field==="command"?A.createElement(Ye,{value:y.cmd,onChange:k=>N({...y,cmd:k}),onSubmit:()=>N({...y,field:"port"})}):A.createElement(j,{dimColor:!0},y.cmd)),A.createElement(X,null,A.createElement(j,null,y.field==="port"?"> ":" ","port: "),y.field==="port"?A.createElement(Ye,{value:y.port,onChange:k=>N({...y,port:k}),onSubmit:()=>N({...y,field:"env"})}):A.createElement(j,{dimColor:!0},y.port)),A.createElement(X,null,A.createElement(j,null,y.field==="env"?"> ":" ","env (k=v;): "),y.field==="env"?A.createElement(Ye,{value:y.env.replace(/\n/g,";"),onChange:k=>N({...y,env:k.replace(/;/g,`
78
+ `)}),onSubmit:()=>{let k=Number(y.port),O={};for(let D of y.env.split(/\n/)){let P=D.match(/^\s*([^=]+)=(.*)$/);P&&(O[P[1].trim()]=P[2])}n.setSessionOverride(y.name,{command:y.cmd||void 0,port:Number.isFinite(k)&&k>0?k:void 0,env:Object.keys(O).length?O:void 0}),N(null)}}):A.createElement(j,{dimColor:!0},y.env))):null,$?A.createElement(X,{borderStyle:"round",borderColor:"yellow",paddingX:1},A.createElement(j,{color:"yellow",bold:!0},"Restart ",$,"? "),A.createElement(j,{dimColor:!0},"[y]es [n]o / Esc")):null,L?A.createElement(j,null,"filter (Enter to apply, Esc to clear): ",A.createElement(j,{color:"cyan"},M)):null,et?A.createElement(X,{borderStyle:"round",borderColor:"cyan",paddingX:1},A.createElement(j,{bold:!0,color:"cyan"},"orchestrate profile (Enter to run, Esc to cancel): "),A.createElement(j,{color:"cyan"},I)):null,Qe?A.createElement(j,{color:"cyan"},"[i] ",Qe):null,A.createElement(j,{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")))}async function xi(n={}){let t=null,e=null;Tn({getRegistry:()=>t,getConfig:()=>e});let r;try{r=Q()}catch(S){process.stderr.write(`[daimon] config error: ${S.message}
79
+ `),process.exit(1)}if(r.kind==="stub-created"){let S=pt();process.stdout.write(`[daimon] no config found. Created stub at:
67
80
  ${r.path}
68
81
  `),process.stdout.write(`[daimon] Edit it to add "searchRoots" pointing at your Nx/Angular workspace, then run again.
69
- `),process.stdout.write(`[daimon] (Local override path: ${T.local})
82
+ `),process.stdout.write(`[daimon] (Local override path: ${S.local})
70
83
  `),process.exit(0)}let{config:s,path:i}=r;if(process.stdout.write(`[daimon] config: ${i}
71
- `),s.depends&&Object.keys(s.depends).length){let T=He(s.depends);T&&(process.stderr.write(`[daimon] config error: depends graph has a cycle: ${T.join(" -> ")}
72
- `),process.exit(1))}let o=mt(s);o.length===0&&process.stdout.write(`[daimon] no serveable projects discovered in: ${s.searchRoots.join(", ")||"(none)"}
73
- `);let a=$r(),u=new nt(s.portRange,{initial:a.ports,onChange:T=>Nr({ports:T})}),c=new Ot(s,o,u);t=c,e=s;let h=new at(s.history);c.setHistory(h);let p=new Ht(c,s.healthProbe,s),b=new Ut(c),S=new Wt(c,s.autoRestart),l=new Jt(c,s.notifications),m=new Gt(c,s.staleDetect),g=new Xt(c,s.requestLog);c.on("childExit",({name:T,code:f,signal:C,stopping:P})=>S.onExit(T,f,C,P)),c.on("userStop",({name:T})=>S.onUserStop(T));let d=Tr();if(d&&d.apps.length){process.stdout.write(`[daimon] state-handoff: restoring ${d.apps.map(T=>T.name).join(", ")}
74
- `);for(let T of d.apps)u.pin(T.name,T.port);for(let T of d.apps)c.names().includes(T.name)&&c.start(T.name)}if(s.autoStart&&s.autoStart.length){let T=new Set(c.names());for(let f of s.autoStart){if(!T.has(f)){process.stderr.write(`[daimon] warning: autoStart references unknown app "${f}"
75
- `);continue}s.depends&&s.depends[f]&&s.depends[f].length?c.startWithDeps(f):c.start(f)}}let y=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):s.apiPort,k=!!n.headless||!!s.headless||process.argv.includes("--headless"),E=!1,v=async()=>{if(!E){E=!0;try{p.stop()}catch{}try{b.stop()}catch{}try{S.stop()}catch{}try{l.stop()}catch{}try{m.stop()}catch{}try{g.stop()}catch{}try{h.close()}catch{}try{await c.stopAll(3e3)}catch{}try{O.close()}catch{}try{yt()}catch{}process.exit(0)}},O=Pr(c,y,{metricsEnabled:s.metrics.enabled,requestLog:g,onShutdown:()=>{v()},configPath:i,getConfig:()=>c.getConfig(),patchConfig:T=>{try{let f=Br({configPath:i,patch:T}),C=Te({configPath:i,registry:c});return{ok:!0,applied:f.applied,addedApps:C.addedApps,removedApps:C.removedApps,restartRequired:C.restartRequired}}catch(f){return{ok:!1,error:f?.message||String(f)}}},reloadConfig:async()=>{let T=Te({configPath:i,registry:c});return{ok:!0,addedApps:T.addedApps,removedApps:T.removedApps,restartRequired:T.restartRequired}}});process.stdout.write(`[daimon] api: http://127.0.0.1:${y}
76
- `);try{nr(or(y,k,i))}catch(T){process.stderr.write(`[daimon] warning: could not write daemon.lock: ${T?.message||T}
77
- `)}if(process.on("SIGINT",()=>{v()}),process.on("SIGTERM",()=>{v()}),process.on("beforeExit",()=>{v()}),k){process.stdout.write(`[daimon] headless mode \u2014 TUI suppressed. Dashboard: http://127.0.0.1:${y}
78
- `);let T="",f=setInterval(()=>{let C=c.list().map(M=>({name:M.name,status:M.status,health:M.health,port:M.port})),P=JSON.stringify(C);P!==T&&(process.stderr.write(P+`
79
- `),T=P)},6e4);await new Promise(()=>{}),clearInterval(f);return}await uo(lo.createElement(Oe,{registry:c,apiPort:y,onQuit:()=>{v()}})).waitUntilExit(),await v()}var mo=(()=>{try{return import.meta.url===po(process.argv[1]||"").href}catch{return!1}})();mo&&fo().catch(n=>{process.stderr.write(`[daimon] fatal: ${n?.stack||n}
80
- `),process.exit(1)});export{fo as startInProcess};
84
+ `),s.depends&&Object.keys(s.depends).length){let S=yr(s.depends);S&&(process.stderr.write(`[daimon] config error: depends graph has a cycle: ${S.join(" -> ")}
85
+ `),process.exit(1))}let o=At(s);o.length===0&&process.stdout.write(`[daimon] no serveable projects discovered in: ${s.searchRoots.join(", ")||"(none)"}
86
+ `);let a=fn(),c=new ht(s.portRange,{initial:a.ports,onChange:S=>mn({ports:S})}),u=new zt(s,o,c);t=u,e=s;let h=new St(s.history);u.setHistory(h);let p=new se(u,s.healthProbe,s),v=new oe(u),b=new ie(u,s.autoRestart),l=new ae(u,s.notifications),m=new ce(u,s.staleDetect),f=new ue(u,s.requestLog);u.on("childExit",({name:S,code:R,signal:M,stopping:x})=>b.onExit(S,R,M,x)),u.on("userStop",({name:S})=>b.onUserStop(S));let d=Qr();if(d&&d.apps.length){process.stdout.write(`[daimon] state-handoff: restoring ${d.apps.map(S=>S.name).join(", ")}
87
+ `);for(let S of d.apps)c.pin(S.name,S.port);for(let S of d.apps)u.names().includes(S.name)&&u.start(S.name)}if(s.autoStart&&s.autoStart.length){let S=new Set(u.names());for(let R of s.autoStart){if(!S.has(R)){process.stderr.write(`[daimon] warning: autoStart references unknown app "${R}"
88
+ `);continue}s.depends&&s.depends[R]&&s.depends[R].length?u.startWithDeps(R):u.start(R)}}let g=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):s.apiPort,T=!!n.headless||!!s.headless||process.argv.includes("--headless"),E=!1,y=async()=>{if(!E){E=!0;try{p.stop()}catch{}try{v.stop()}catch{}try{b.stop()}catch{}try{l.stop()}catch{}try{m.stop()}catch{}try{f.stop()}catch{}try{h.close()}catch{}try{await u.stopAll(3e3)}catch{}try{N.close()}catch{}try{Pt()}catch{}process.exit(0)}},N=ln(u,g,{metricsEnabled:s.metrics.enabled,requestLog:f,onShutdown:()=>{y()},configPath:i,getConfig:()=>u.getConfig(),patchConfig:S=>{try{let R=Sn({configPath:i,patch:S}),M=Ke({configPath:i,registry:u});return{ok:!0,applied:R.applied,addedApps:M.addedApps,removedApps:M.removedApps,restartRequired:M.restartRequired}}catch(R){return{ok:!1,error:R?.message||String(R)}}},reloadConfig:async()=>{let S=Ke({configPath:i,registry:u});return{ok:!0,addedApps:S.addedApps,removedApps:S.removedApps,restartRequired:S.restartRequired}}});process.stdout.write(`[daimon] api: http://127.0.0.1:${g}
89
+ `);try{Mr(Nr(g,T,i))}catch(S){process.stderr.write(`[daimon] warning: could not write daemon.lock: ${S?.message||S}
90
+ `)}if(process.on("SIGINT",()=>{y()}),process.on("SIGTERM",()=>{y()}),process.on("beforeExit",()=>{y()}),T){process.stdout.write(`[daimon] headless mode \u2014 TUI suppressed. Dashboard: http://127.0.0.1:${g}
91
+ `);let S="",R=setInterval(()=>{let M=u.list().map(L=>({name:L.name,status:L.status,health:L.health,port:L.port})),x=JSON.stringify(M);x!==S&&(process.stderr.write(x+`
92
+ `),S=x)},6e4);await new Promise(()=>{}),clearInterval(R);return}await wi(bi.createElement(Ze,{registry:u,apiPort:g,onQuit:()=>{y()}})).waitUntilExit(),await y()}var ki=(()=>{try{return import.meta.url===Si(process.argv[1]||"").href}catch{return!1}})();ki&&xi().catch(n=>{process.stderr.write(`[daimon] fatal: ${n?.stack||n}
93
+ `),process.exit(1)});export{xi as startInProcess};