daimon 0.9.0 → 0.10.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.
- package/CHANGELOG.md +83 -0
- package/dist/cli.js +98 -88
- package/dist/dashboard/browser/chunk-2LMH5KDX.js +5 -0
- package/dist/dashboard/browser/{chunk-6Z4FDREI.js → chunk-2QORICNU.js} +1 -1
- package/dist/dashboard/browser/{chunk-UUJWPV5O.js → chunk-36JZZZCV.js} +1 -1
- package/dist/dashboard/browser/{chunk-4KVYA2AQ.js → chunk-3S7OJ77P.js} +1 -1
- package/dist/dashboard/browser/{chunk-TGSV7ZHM.js → chunk-42QQHEGP.js} +1 -1
- package/dist/dashboard/browser/chunk-4L223A7A.js +1 -0
- package/dist/dashboard/browser/{chunk-EBGPIJ7S.js → chunk-532NB4ME.js} +1 -1
- package/dist/dashboard/browser/{chunk-X4RGWMLE.js → chunk-6CP6NCA6.js} +2 -2
- package/dist/dashboard/browser/chunk-6OMBXV4F.js +1 -0
- package/dist/dashboard/browser/chunk-6YXOOFGY.js +1 -0
- package/dist/dashboard/browser/{chunk-VMW35ZNT.js → chunk-AHO3BCLI.js} +1 -1
- package/dist/dashboard/browser/{chunk-CIQNXWDY.js → chunk-ASK7FG27.js} +1 -1
- package/dist/dashboard/browser/{chunk-AGN2F6JP.js → chunk-BCGQJHY3.js} +1 -1
- package/dist/dashboard/browser/{chunk-ACPSBF55.js → chunk-BDTAVYPH.js} +1 -1
- package/dist/dashboard/browser/{chunk-FZLMX6EY.js → chunk-BFBXHJEF.js} +1 -1
- package/dist/dashboard/browser/{chunk-B2DPS6BL.js → chunk-BKYXU3OY.js} +1 -1
- package/dist/dashboard/browser/{chunk-UC7AWK4C.js → chunk-BPUIUSAU.js} +1 -1
- package/dist/dashboard/browser/{chunk-6MTVWBQQ.js → chunk-C6SNIY22.js} +1 -1
- package/dist/dashboard/browser/{chunk-3ZFFKHPU.js → chunk-CCRYWDXZ.js} +1 -1
- package/dist/dashboard/browser/{chunk-JWXROQJJ.js → chunk-DNHNU64I.js} +1 -1
- package/dist/dashboard/browser/{chunk-FRKUCFVI.js → chunk-DRBVSI3B.js} +1 -1
- package/dist/dashboard/browser/{chunk-RNUJZTKS.js → chunk-EXOJOB6H.js} +2 -2
- package/dist/dashboard/browser/chunk-EYOED3X7.js +2 -0
- package/dist/dashboard/browser/{chunk-3EPFSBJ2.js → chunk-G3IBZZQH.js} +1 -1
- package/dist/dashboard/browser/chunk-H3HRZLHG.js +4 -0
- package/dist/dashboard/browser/chunk-H5GKWN4K.js +1 -0
- package/dist/dashboard/browser/{chunk-KRC72WWY.js → chunk-HVK4GEK7.js} +1 -1
- package/dist/dashboard/browser/{chunk-7LKM244H.js → chunk-HYIZY5FQ.js} +1 -1
- package/dist/dashboard/browser/chunk-ITSOVQEA.js +1 -0
- package/dist/dashboard/browser/{chunk-WOMCRDMJ.js → chunk-JODWQVMA.js} +1 -1
- package/dist/dashboard/browser/chunk-LAMOHX23.js +1 -0
- package/dist/dashboard/browser/chunk-NMKAKRON.js +1 -0
- package/dist/dashboard/browser/{chunk-F3FCHBFQ.js → chunk-NY5IR366.js} +1 -1
- package/dist/dashboard/browser/{chunk-NVL5HFLU.js → chunk-OOQPWG6B.js} +1 -1
- package/dist/dashboard/browser/{chunk-SR4HVFOB.js → chunk-P3Q7RWT5.js} +1 -1
- package/dist/dashboard/browser/{chunk-YHBNUNU3.js → chunk-PVPELZPO.js} +1 -1
- package/dist/dashboard/browser/{chunk-66VYPESU.js → chunk-QHXOUNPA.js} +1 -1
- package/dist/dashboard/browser/{chunk-VHALTUPL.js → chunk-RMV7CR6Y.js} +1 -1
- package/dist/dashboard/browser/chunk-RQSDQXNY.js +1 -0
- package/dist/dashboard/browser/chunk-RWX5JIT4.js +1 -0
- package/dist/dashboard/browser/{chunk-R7VSXL63.js → chunk-SXE7REUK.js} +1 -1
- package/dist/dashboard/browser/chunk-TLCLILNG.js +4 -0
- package/dist/dashboard/browser/chunk-UAIWZYHN.js +1 -0
- package/dist/dashboard/browser/chunk-UFTWVSEC.js +2 -0
- package/dist/dashboard/browser/{chunk-RWXAGDGT.js → chunk-UXLEE3F2.js} +1 -1
- package/dist/dashboard/browser/{chunk-K6PUQAFE.js → chunk-XPP3TYS2.js} +1 -1
- package/dist/dashboard/browser/{chunk-PRLUGTKR.js → chunk-YFYMS5EE.js} +1 -1
- package/dist/dashboard/browser/chunk-YPVVBWNF.js +1 -0
- package/dist/dashboard/browser/{chunk-BBTQXZIS.js → chunk-Z3XFJOYG.js} +1 -1
- package/dist/dashboard/browser/index.html +2 -2
- package/dist/dashboard/browser/main-EENULCI5.js +1 -0
- package/dist/main.js +55 -51
- package/dist/mcp.js +3 -3
- package/package.json +4 -2
- package/dist/dashboard/browser/chunk-55AO3FMG.js +0 -1
- package/dist/dashboard/browser/chunk-FD3BW2ZN.js +0 -1
- package/dist/dashboard/browser/chunk-GMEW64AS.js +0 -1
- package/dist/dashboard/browser/chunk-HXX2OUOE.js +0 -1
- package/dist/dashboard/browser/chunk-HZNVO3JE.js +0 -1
- package/dist/dashboard/browser/chunk-K2SFF47Z.js +0 -5
- package/dist/dashboard/browser/chunk-K5WKBG55.js +0 -1
- package/dist/dashboard/browser/chunk-LBWOIG7N.js +0 -5
- package/dist/dashboard/browser/chunk-O76B43BY.js +0 -4
- package/dist/dashboard/browser/chunk-QYIYT4YU.js +0 -1
- package/dist/dashboard/browser/chunk-RXOAYCKI.js +0 -2
- package/dist/dashboard/browser/chunk-WRX32YWH.js +0 -1
- package/dist/dashboard/browser/main-YAROJLJV.js +0 -1
package/dist/main.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
`,"utf8"),{kind:"stub-created",path:t}}var
|
|
3
|
-
`);return[...e.values()].filter(
|
|
1
|
+
var fs=Object.defineProperty;var ut=(r,t)=>()=>(r&&(t=r(r=0)),t);var Ft=(r,t)=>{for(var e in t)fs(r,e,{get:t[e],enumerable:!0})};var Er={};Ft(Er,{configLookupPaths:()=>yt,loadConfig:()=>ct,validateConfig:()=>Vt});import gt from"node:fs";import ht from"node:path";import Bt from"node:os";import{fileURLToPath as ms}from"node:url";function Tr(){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:ht.join(Bt.homedir(),".daimon","logs"),maxFiles:5,maxBytesPerFile:1e7},depends:{},cascadeRestart:!1,history:{enabled:!0,path:ht.join(Bt.homedir(),".daimon","history.db"),retentionDays:30},notifications:{enabled:!0,onError:!0,onUnhealthy:!0,tray:!1},staleDetect:{enabled:!0,silentMs:3e4},headless:!1,envFiles:{},requestLog:{enabled:!1,portOffset:1e3},metrics:{enabled:!1},editor:{scheme:"vscode"},apiToken:null,output:{format:"compact",ndjson:!1},doctor:{autoFix:{onInit:!1,permitted:["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root"]}},dashboard:{theme:"auto",density:"comfortable"},errorRetention:{maxAgeMs:864e5},plugins:{dir:null},webhooks:[]}}function Ne(r){return r.startsWith("~/")||r.startsWith("~\\")?ht.join(Bt.homedir(),r.slice(2)):r==="~"?Bt.homedir():r}function Vt(r,t){return $e(r,t)}function $e(r,t){if(!r||typeof r!="object")throw new Error(`Config at ${t} is not a JSON object`);let e=r,n=Tr();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})`);n.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})`);n.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})`);n.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})`);n.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})`);n.autoStart=e.autoStart}if(e.profiles!==void 0){if(typeof e.profiles!="object"||e.profiles===null||Array.isArray(e.profiles))throw new Error(`Config "profiles" must be an object (${t})`);for(let[s,o]of Object.entries(e.profiles))if(!Array.isArray(o)||!o.every(a=>typeof a=="string"))throw new Error(`Config "profiles.${s}" must be an array of strings (${t})`);n.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})`);n.tags=e.tags}if(e.autoRestart&&typeof e.autoRestart=="object"&&(n.autoRestart={...n.autoRestart,...e.autoRestart}),e.healthProbe&&typeof e.healthProbe=="object"&&(n.healthProbe={...n.healthProbe,...e.healthProbe}),e.logs&&typeof e.logs=="object"&&(n.logs={...n.logs,...e.logs},n.logs.dir=Ne(n.logs.dir)),e.depends&&typeof e.depends=="object"&&!Array.isArray(e.depends)){for(let[s,o]of Object.entries(e.depends))if(!Array.isArray(o)||!o.every(a=>typeof a=="string"))throw new Error(`Config "depends.${s}" must be an array of strings (${t})`);n.depends=e.depends}if(typeof e.cascadeRestart=="boolean"&&(n.cascadeRestart=e.cascadeRestart),e.history&&typeof e.history=="object"&&(n.history={...n.history,...e.history},n.history.path=Ne(n.history.path)),e.notifications&&typeof e.notifications=="object"&&(n.notifications={...n.notifications,...e.notifications}),e.staleDetect&&typeof e.staleDetect=="object"&&(n.staleDetect={...n.staleDetect,...e.staleDetect}),typeof e.headless=="boolean"&&(n.headless=e.headless),e.envFiles&&typeof e.envFiles=="object"&&!Array.isArray(e.envFiles)&&(n.envFiles=e.envFiles),e.requestLog&&typeof e.requestLog=="object"&&(n.requestLog={...n.requestLog,...e.requestLog}),e.metrics&&typeof e.metrics=="object"&&(n.metrics={...n.metrics,...e.metrics}),e.editor&&typeof e.editor=="object"){let s=e.editor.scheme;typeof s=="string"&&s.trim()&&(n.editor={scheme:s.trim()})}if((typeof e.apiToken=="string"||e.apiToken===null)&&(n.apiToken=e.apiToken),e.output&&typeof e.output=="object"){let s=e.output;(s.format==="compact"||s.format==="full")&&(n.output.format=s.format),typeof s.ndjson=="boolean"&&(n.output.ndjson=s.ndjson)}if(e.doctor&&typeof e.doctor=="object"){let s=e.doctor.autoFix;s&&typeof s=="object"&&(typeof s.onInit=="boolean"&&(n.doctor.autoFix.onInit=s.onInit),Array.isArray(s.permitted)&&(n.doctor.autoFix.permitted=s.permitted.filter(o=>typeof o=="string")))}if(e.dashboard&&typeof e.dashboard=="object"){let s=e.dashboard;(s.theme==="auto"||s.theme==="light"||s.theme==="dark")&&(n.dashboard.theme=s.theme),(s.density==="comfortable"||s.density==="compact")&&(n.dashboard.density=s.density)}if(e.errorRetention&&typeof e.errorRetention=="object"){let s=e.errorRetention;typeof s.maxAgeMs=="number"&&s.maxAgeMs>0&&(n.errorRetention.maxAgeMs=s.maxAgeMs)}if(e.plugins&&typeof e.plugins=="object"){let s=e.plugins;typeof s.dir=="string"&&s.dir.trim()?n.plugins.dir=Ne(s.dir):s.dir===null&&(n.plugins.dir=null)}if(Array.isArray(e.webhooks)){let s=[];for(let o of e.webhooks){if(!o||typeof o!="object")continue;let a=o;if(typeof a.url!="string"||!a.url.trim())continue;let c={url:a.url};if(Array.isArray(a.events)&&(c.events=a.events.filter(i=>typeof i=="string")),a.headers&&typeof a.headers=="object"){let i={};for(let[l,u]of Object.entries(a.headers))typeof u=="string"&&(i[l]=u);c.headers=i}if(a.filter&&typeof a.filter=="object"){let i={};for(let l of["to","from","app"])Array.isArray(a.filter[l])&&(i[l]=a.filter[l].filter(u=>typeof u=="string"));c.filter=i}s.push(c)}n.webhooks=s}return n}function yt(){return{local:ht.join(process.cwd(),"daimon.config.json"),user:ht.join(Bt.homedir(),".daimon","config.json")}}function ct(){let{local:r,user:t}=yt();if(gt.existsSync(r)){let s=JSON.parse(gt.readFileSync(r,"utf8"));return{kind:"loaded",config:$e(s,r),path:r}}if(gt.existsSync(t)){let s=JSON.parse(gt.readFileSync(t,"utf8"));return{kind:"loaded",config:$e(s,t),path:t}}let n=[ht.resolve(xr,"..","daimon.config.example.json"),ht.resolve(xr,"..","..","daimon.config.example.json")].find(s=>gt.existsSync(s));return gt.mkdirSync(ht.dirname(t),{recursive:!0}),n?gt.copyFileSync(n,t):gt.writeFileSync(t,JSON.stringify(Tr(),null,2)+`
|
|
2
|
+
`,"utf8"),{kind:"stub-created",path:t}}var hs,xr,Ht=ut(()=>{"use strict";hs=ms(import.meta.url),xr=ht.dirname(hs)});var De={};Ft(De,{discoverApps:()=>Et});import st from"node:fs";import tt from"node:path";import _e from"fast-glob";function Rr(r){try{return JSON.parse(st.readFileSync(r,"utf8"))}catch{return null}}function Ar(r){return!r||typeof r!="object"?!1:!!(r.targets?.serve||r.architect?.serve)}function Pr(r){if(!r||typeof r!="object")return[];let t=r.targets??r.architect??{};return Object.keys(t).filter(e=>e!=="serve").sort()}function Le(r){return r.replace(/\\/g,"/")}function Ct(r,t){r&&(r.rejected[t]=(r.rejected[t]??0)+1)}function gs(r,t,e,n){if(!r.has(t))return{key:t,collided:!1};if(r.get(t).workspaceRoot===n)return{key:t,collided:!0};let o=e||tt.basename(n),a=`${t}@${o}`,c=2;for(;r.has(a);)a=`${t}@${o}-${c++}`;return{key:a,collided:!1}}function je(r,t){try{return t.test(st.readFileSync(r,"utf8"))}catch{return!1}}function dt(r,t,e){let{key:n,collided:s}=gs(r,t,e.workspaceLabel,e.workspaceRoot);return s?!1:(r.set(n,{name:n,baseName:t,...e}),!0)}function ys(r,t,e){let n=tt.basename(r),s=!1,o=tt.join(r,"manage.py");st.existsSync(o)&&je(o,/\bdjango\b/i)&&(dt(e,n,{workspaceRoot:r,workspaceType:"polyglot",serverProfile:"django",command:"python manage.py runserver",hidden:!1,tags:[],workspaceLabel:t}),s=!0);let a=tt.join(r,"bin","rails"),c=tt.join(r,"Gemfile");st.existsSync(a)&&st.existsSync(c)&&(dt(e,n,{workspaceRoot:r,workspaceType:"polyglot",serverProfile:"rails",command:"bin/rails server",hidden:!1,tags:[],workspaceLabel:t}),s=!0);let i=tt.join(r,"pyproject.toml"),l=tt.join(r,"requirements.txt");(st.existsSync(i)&&je(i,/\bfastapi\b/i)||st.existsSync(l)&&je(l,/\bfastapi\b/i))&&(dt(e,n,{workspaceRoot:r,workspaceType:"polyglot",serverProfile:"fastapi",command:"uvicorn main:app --reload",hidden:!1,tags:[],workspaceLabel:t}),s=!0),(st.existsSync(tt.join(r,".air.toml"))||st.existsSync(tt.join(r,"air.toml")))&&(dt(e,n,{workspaceRoot:r,workspaceType:"polyglot",serverProfile:"go-air",command:"air",hidden:!1,tags:[],workspaceLabel:t}),s=!0);let g=tt.join(r,"Trunk.toml");return st.existsSync(g)&&(dt(e,n,{workspaceRoot:r,workspaceType:"polyglot",serverProfile:"rust-trunk",command:"trunk serve",hidden:!1,tags:[],workspaceLabel:t}),s=!0),s}function Et(r,t={}){let e=new Map,n=t.warnings??[],s=t.warnings===void 0;for(let o of r.searchRoots){let a=typeof o=="string"?o:o.path,c=typeof o=="string"?!1:!!o.viteSubfolders,i=typeof o=="string"?void 0:o.label,l=tt.resolve(a);if(!st.existsSync(l)){n.push(`searchRoot does not exist: ${l}`),Ct(t.stats,"searchRoot missing");continue}let u=tt.join(l,"nx.json"),d=tt.join(l,"angular.json");if(st.existsSync(u)){let E=_e.sync("**/project.json",{cwd:Le(l),ignore:["**/node_modules/**","**/dist/**","**/.nx/**","**/.git/**"],absolute:!0,dot:!1});for(let C of E){t.stats&&(t.stats.scanned+=1);let y=Rr(C);if(!y){Ct(t.stats,"unreadable project.json");continue}if(!Ar(y)){Ct(t.stats,"no serve target");continue}let P=y.name||tt.basename(tt.dirname(C));if(!P){Ct(t.stats,"project has no name");continue}dt(e,P,{workspaceRoot:l,workspaceType:"nx",serverProfile:"nx",command:`npx nx serve ${P}`,hidden:!1,tags:[],tasks:Pr(y),workspaceLabel:i})||(n.push(`duplicate project name "${P}" within ${l} \u2014 keeping first`),Ct(t.stats,"duplicate name"))}continue}if(st.existsSync(d)){let C=Rr(d)?.projects||{};for(let[y,P]of Object.entries(C)){if(!Ar(P))continue;dt(e,y,{workspaceRoot:l,workspaceType:"angular",serverProfile:"angular",command:`npx ng serve ${y}`,hidden:!1,tags:[],tasks:Pr(P),workspaceLabel:i})||n.push(`duplicate project name "${y}" within ${l} \u2014 keeping first`)}continue}let g=_e.sync("vite.config.{ts,js,mjs,cjs}",{cwd:Le(l),absolute:!0,deep:1}),v=st.existsSync(tt.join(l,".storybook")),A=!1;if(g.length>0){let E=tt.basename(l);if(dt(e,E,{workspaceRoot:l,workspaceType:"vite",serverProfile:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:i}),A=!0,c){let C=_e.sync("*/vite.config.{ts,js,mjs,cjs}",{cwd:Le(l),absolute:!0});for(let y of C){let P=tt.dirname(y),I=tt.basename(P);I!==E&&dt(e,I,{workspaceRoot:P,workspaceType:"vite",serverProfile:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:i})}}}if(v){let E=`${tt.basename(l)}-storybook`;dt(e,E,{workspaceRoot:l,workspaceType:"storybook",serverProfile:"storybook",command:"npx storybook dev --no-open",hidden:!1,tags:[],workspaceLabel:i}),A=!0}A||ys(l,i,e)||(n.push(`searchRoot has none of nx.json/angular.json/vite.config.*/.storybook/polyglot markers: ${l}`),Ct(t.stats,"no project markers"))}for(let[o,a]of Object.entries(r.overrides||{})){let c=[...e.values()].filter(i=>(i.baseName??i.name)===o);if(c.length>0)for(let i of c)a.command&&(i.command=a.command),typeof a.hidden=="boolean"&&(i.hidden=a.hidden),typeof a.port=="number"&&(i.pinnedPort=a.port),a.env&&(i.env=a.env);else a.command&&e.set(o,{name:o,baseName:o,workspaceRoot:process.cwd(),workspaceType:"nx",command:a.command,hidden:a.hidden??!1,pinnedPort:a.port,env:a.env,tags:[]})}for(let o of e.values())o.tags=r.tags?.[o.baseName??o.name]??[];if(s&&n.length)for(let o of n)process.stderr.write(`[daimon] warning: ${o}
|
|
3
|
+
`);return[...e.values()].filter(o=>!o.hidden)}var Mt=ut(()=>{"use strict"});import zs from"node:net";function Nt(r){return new Promise(t=>{let e=zs.createServer();e.unref(),e.once("error",()=>t(!1)),e.listen({port:r,host:"127.0.0.1",exclusive:!0},()=>{e.close(()=>t(!0))})})}var Ot,Qt=ut(()=>{"use strict";Ot=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 n=new Set;for(let[s,o]of Object.entries(e.initial))typeof o=="number"&&(o<this.min||o>this.max||n.has(o)||(n.add(o),this.assigned.set(s,o)))}}snapshot(){return Object.fromEntries(this.assigned)}getAssigned(t){return this.assigned.get(t)}pin(t,e){this.assigned.set(t,e),this.onChange?.(this.snapshot())}async allocate(t,e){let n=this.assigned.get(t);if(e!==void 0)return this.assigned.set(t,e),this.onChange?.(this.snapshot()),e;if(n!==void 0)return n;let s=new Set(this.assigned.values());for(let o=this.min;o<=this.max;o++){if(s.has(o))continue;if(await Nt(o))return this.assigned.set(t,o),this.onChange?.(this.snapshot()),o}throw new Error(`No free ports in range ${this.min}-${this.max}`)}async isPortAvailableForUse(t){return Nt(t)}}});function jr(r){let s=new Map,o=new Map,a=null,c=i=>{if(!a){s.set(i,1);for(let l of r[i]||[]){let u=s.get(l)??0;if(u===1){let d=[l,i],g=o.get(i);for(;g&&g!==l;)d.push(g),g=o.get(g);g===l&&d.push(l),a=d.reverse();return}if(u===0&&(o.set(l,i),c(l),a))return}s.set(i,2)}};for(let i of Object.keys(r))if((s.get(i)??0)===0&&(o.set(i,null),c(i),a))return a;return null}function ee(r,t){let e=new Set,n=[t];for(;n.length;){let s=n.pop();if(!e.has(s)){e.add(s);for(let o of r[s]||[])n.push(o)}}return[...e]}function re(r,t){let e=new Set(t),n=new Map,s=new Map;for(let c of t)n.set(c,0),s.set(c,[]);for(let c of t)for(let i of r[c]||[])e.has(i)&&(s.get(i).push(c),n.set(c,(n.get(c)??0)+1));let o=[],a=t.filter(c=>(n.get(c)??0)===0);for(;a.length;){o.push([...a].sort());let c=[];for(let i of a)for(let l of s.get(i)??[])n.set(l,(n.get(l)??1)-1),n.get(l)===0&&c.push(l);a=c}return o}function Dr(r,t){let e=[];for(let[n,s]of Object.entries(r))s.includes(t)&&e.push(n);return e}var ne=ut(()=>{"use strict"});import po from"node:fs";import We from"node:path";import{fileURLToPath as fo}from"node:url";function mo(){let r=[We.resolve(zr,"..","package.json"),We.resolve(zr,"..","..","package.json")];for(let t of r)try{return JSON.parse(po.readFileSync(t,"utf8"))}catch{}return{}}var zr,bt,Ut=ut(()=>{"use strict";zr=We.dirname(fo(import.meta.url));bt=mo().version||"0.0.0"});import $t from"node:fs";import se from"node:path";import ho from"node:os";import{spawn as go}from"node:child_process";import{fileURLToPath as yo}from"node:url";function wt(){return Ge}function oe(){return _t}function qe(r){try{return process.kill(r,0),!0}catch(t){return t&&t.code==="EPERM"}}function Rt(){try{let r=$t.readFileSync(_t,"utf8"),t=JSON.parse(r);if(!t||typeof t.pid!="number")return null;if(!qe(t.pid)){try{$t.unlinkSync(_t)}catch{}return null}return t}catch{return null}}function Yr(r){$t.mkdirSync(Ge,{recursive:!0});let t=_t+"."+process.pid+".tmp";$t.writeFileSync(t,JSON.stringify(r)),$t.renameSync(t,_t)}function Wt(){try{$t.unlinkSync(_t)}catch{}}function bo(){let r=se.dirname(yo(import.meta.url));return se.join(r,"main.js")}async function Je(r={}){let t={...process.env};r.port&&(t.DAIMON_PORT=String(r.port)),go(process.execPath,[bo(),"--headless"],{detached:!0,stdio:"ignore",env:t,windowsHide:!0}).unref();let n=Date.now();for(;Date.now()-n<5e3;){let s=Rt();if(s&&(!r.port||s.apiPort===r.port))return s;await new Promise(o=>setTimeout(o,100))}throw new Error("daemon failed to start within 5s")}async function Vr(r,t){let e=Date.now();for(;Date.now()-e<t;){if(!qe(r))return!0;await new Promise(n=>setTimeout(n,100))}return!qe(r)}function Zr(r,t,e){return{pid:process.pid,apiPort:r,version:bt,startedAt:Date.now(),headless:t,cwd:process.cwd(),configPath:e}}var Ge,_t,At=ut(()=>{"use strict";Ut();Ge=se.join(ho.homedir(),".daimon"),_t=se.join(Ge,"daemon.lock")});var xn={};Ft(xn,{analyseRestartCadence:()=>Wo,suggestProfiles:()=>Ho});function Ho(r,t={}){let e=t.windowMs??6e4,n=t.minOccurrences??5,s=t.minApps??2,o=t.existingProfiles??{},a=r.filter(d=>d.type==="status"&&(d.to_state==="starting"||d.to==="starting")).sort((d,g)=>d.ts-g.ts),c=[];for(let d of a){let g=c[c.length-1];g&&d.ts-g.lastTs<=e?(g.apps.includes(d.app)||g.apps.push(d.app),g.lastTs=d.ts):c.push({apps:[d.app],firstTs:d.ts,lastTs:d.ts})}let i=new Map;for(let d of c){if(d.apps.length<s)continue;let g=[...d.apps].sort().join("\0"),v=i.get(g);v?(v.count++,v.lastSeen=Math.max(v.lastSeen,d.lastTs)):i.set(g,{apps:[...d.apps].sort(),count:1,lastSeen:d.lastTs})}let l=new Set;for(let d of Object.values(o))l.add([...d].sort().join("\0"));let u=[];for(let[d,g]of i)g.count<n||l.has(d)||u.push({name:Uo(g.apps,o),apps:g.apps,cooccurrences:g.count,lastSeenMs:g.lastSeen,reason:`started together within ${Math.round(e/1e3)}s \xB7 ${g.count} times`});return u.sort((d,g)=>g.cooccurrences-d.cooccurrences),u}function Uo(r,t){let s=r.map(c=>c.split(/[-_\s.]/).filter(Boolean)).reduce((c,i,l)=>l===0?i:c.filter(u=>i.includes(u)),[])[0]??`stack-${r.length}`;s||(s=`stack-${r.length}`),s=s.toLowerCase();let o=s,a=2;for(;t[o];)o=`${s}-${a++}`;return o}function Wo(r,t=7,e=5,n=Date.now()){let s=n-t*24*60*6e4,o=new Map;for(let c of r){if(c.ts<s||c.type!=="status")continue;let i=c.to_state??c.to,l=c.from_state??c.from;(i==="starting"||i==="compiling")&&l&&l!=="stopped"&&o.set(c.app,(o.get(c.app)??0)+1)}let a=[];for(let[c,i]of o){let l=i/t;l>=e&&a.push({app:c,restartsPerDay:Math.round(l*10)/10,totalRestarts:i,windowDays:t,reason:`${i} restarts in last ${t}d (~${Math.round(l)}\xD7 / day) \u2014 review restartPolicy / autoRestart for this app`})}return a.sort((c,i)=>i.restartsPerDay-c.restartsPerDay)}var Tn=ut(()=>{"use strict"});import Jt from"node:fs";import qo from"node:path";import{createRequire as Go}from"node:module";var Jo,Xo,Ko,zo,Lt,er=ut(()=>{"use strict";Jo=Go(import.meta.url),Xo=200,Ko=360*60*1e3,zo=1e4,Lt=class{constructor(t){this.cfg=t;if(t.enabled)try{Jt.mkdirSync(qo.dirname(t.path),{recursive:!0});let e=Jo("better-sqlite3"),n,s=o=>{let a=new Date().toISOString().replace(/[:.]/g,"-"),c=`${t.path}.corrupt-${a}`;try{Jt.existsSync(t.path)&&Jt.renameSync(t.path,c);try{Jt.unlinkSync(t.path+"-wal")}catch{}try{Jt.unlinkSync(t.path+"-shm")}catch{}this.archivedCorruptPath=c,process.stderr.write(`[daimon] history: archived corrupt db (${o}) -> ${c}
|
|
4
|
+
`)}catch(i){this.warnOnce(`failed to archive corrupt history db: ${i?.message||i}`)}};try{n=new e(t.path);let o=n.prepare("PRAGMA integrity_check").get();if(!(o&&(o.integrity_check==="ok"||o.integrity_check==="ok"))){try{n.close()}catch{}s("integrity_check failed"),n=new e(t.path)}}catch(o){s(`open failed: ${o?.message||o}`),n=new e(t.path)}this.db=n,this.db.pragma("journal_mode = WAL"),this.migrate(),this.flushTimer=setInterval(()=>this.flush(),Xo),this.retentionStart=setTimeout(()=>this.runRetention(),zo),this.retentionTimer=setInterval(()=>this.runRetention(),Ko)}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;archivedCorruptPath=null;archivedCorruptDbPath(){return this.archivedCorruptPath}warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] history: ${t}
|
|
4
5
|
`))}migrate(){this.db&&this.db.exec(`
|
|
5
6
|
CREATE TABLE IF NOT EXISTS events (
|
|
6
7
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -12,6 +13,7 @@ var ts=Object.defineProperty;var ot=(r,t)=>()=>(r&&(t=r(r=0)),t);var Jt=(r,t)=>{
|
|
|
12
13
|
message TEXT
|
|
13
14
|
);
|
|
14
15
|
CREATE INDEX IF NOT EXISTS events_ts_app ON events(ts, app);
|
|
16
|
+
CREATE INDEX IF NOT EXISTS events_app_ts ON events(app, ts);
|
|
15
17
|
CREATE TABLE IF NOT EXISTS compile_times (
|
|
16
18
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
17
19
|
ts INTEGER NOT NULL,
|
|
@@ -47,58 +49,60 @@ var ts=Object.defineProperty;var ot=(r,t)=>()=>(r&&(t=r(r=0)),t);var Jt=(r,t)=>{
|
|
|
47
49
|
historyQueryP95Ms REAL NOT NULL
|
|
48
50
|
);
|
|
49
51
|
CREATE INDEX IF NOT EXISTS self_metrics_ts ON self_metrics(ts);
|
|
50
|
-
`)}recordSelfMetric(t,e,n,s,i=Date.now()){if(this.db)try{this.db.prepare("INSERT INTO self_metrics (ts,rssMB,heapUsedMB,eventLoopLagMs,historyQueryP95Ms) VALUES (?,?,?,?,?)").run(i,t,e,n,s)}catch(o){this.warnOnce(`self_metrics write failed: ${o?.message||o}`)}}querySelfMetrics(t={}){if(!this.db)return[];let e=[],n=[];t.since!=null&&(e.push("ts >= ?"),n.push(t.since));let s=`SELECT ts, rssMB, heapUsedMB, eventLoopLagMs, historyQueryP95Ms FROM self_metrics ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??60),this.db.prepare(s).all(...n)}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,n=Date.now()){this.db&&this.queue.push({kind:"compile",row:{ts:n,app:t,ms:e}})}recordBundle(t,e,n,s,i=Date.now()){this.db&&this.queue.push({kind:"bundle",row:{ts:i,app:t,initialKB:e,lazyKB:n,fileCount:s}})}recordTaskRun(t,e,n,s,i,o=Date.now()){this.db&&this.queue.push({kind:"task",row:{ts:o,app:t,task:e,exit_code:n,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 (?,?,?,?,?,?)"),n=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"?n.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),this.db.prepare("DELETE FROM self_metrics WHERE ts < ?").run(t)}catch(t){this.warnOnce(`retention failed: ${t?.message||t}`)}}queryEvents(t){if(!this.db)return[];let e=[],n=[];t.app&&(e.push("app = ?"),n.push(t.app)),t.since!=null&&(e.push("ts >= ?"),n.push(t.since)),t.until!=null&&(e.push("ts <= ?"),n.push(t.until)),t.type&&(e.push("type = ?"),n.push(t.type));let s=`SELECT * FROM events ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??500),this.db.prepare(s).all(...n)}queryCompiles(t){if(!this.db)return[];let e=[],n=[];t.app&&(e.push("app = ?"),n.push(t.app)),t.since!=null&&(e.push("ts >= ?"),n.push(t.since)),t.until!=null&&(e.push("ts <= ?"),n.push(t.until));let s=`SELECT * FROM compile_times ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??1e3),this.db.prepare(s).all(...n)}queryBundles(t){if(!this.db)return[];let e=[],n=[];t.app&&(e.push("app = ?"),n.push(t.app)),t.since!=null&&(e.push("ts >= ?"),n.push(t.since)),t.until!=null&&(e.push("ts <= ?"),n.push(t.until));let s=`SELECT * FROM bundles ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??1e3),this.db.prepare(s).all(...n)}trends(t){if(!this.db)return{points:[],count:0};let e=Date.now()-t.sinceMs,n=t.bucketMs,s=new Map,i=(p,h)=>{let m=Math.floor(p/n)*n,b=s.get(m)??{sum:0,n:0};b.sum+=h,b.n+=1,s.set(m,b)},o=p=>{let h=Math.floor(p/n)*n,m=s.get(h)??{sum:0,n:0};m.sum+=1,m.n+=1,s.set(h,m)},a=0;if(t.metric==="compile"){let p=this.queryCompiles({app:t.app,since:e,limit:1e4});a=p.length;for(let h of p)i(h.ts,h.ms)}else if(t.metric==="bundle"){let p=this.queryBundles({app:t.app,since:e,limit:1e4});a=p.length;for(let h of p){let m=Math.floor(h.ts/n)*n,b=s.get(m)??{sum:0,n:0,sum2:0};b.sum+=h.initialKB,b.sum2=(b.sum2??0)+h.lazyKB,b.n+=1,s.set(m,b)}}else if(t.metric==="errors"){let p=this.queryEvents({app:t.app,since:e,limit:1e4});for(let h of p)(h.type==="error-new"||h.type==="error-recur")&&(o(h.ts),a++)}else{let p=this.queryEvents({app:t.app,since:e,limit:1e4});for(let h of p)h.type==="status"&&h.to_state==="starting"&&(h.from_state==="error"||h.from_state==="serving"||h.from_state==="compiling")&&(o(h.ts),a++)}let c=[],l=[...s.entries()].sort((p,h)=>p[0]-h[0]);for(let[p,h]of l)t.metric==="compile"||t.metric==="bundle"?c.push({t:p,v:Math.round(h.sum/h.n),...h.sum2!=null?{v2:Math.round(h.sum2/h.n)}:{}}):c.push({t:p,v:h.sum});return{points:c,count:a}}queryTimeline(t){if(!this.db)return[];let e=t.limit??5e3,n=t.since,s=t.kinds,i=[],o=!s||s.has("status"),a=!s||s.has("error"),c=!s||s.has("warning"),l=!s||s.has("lint"),p=!s||s.has("health"),h=!s||s.has("bundle"),m=!s||s.has("task"),b=!s||s.has("restart");if(o||a||c||l||p||b){let M=this.queryEvents({app:t.app,since:n,limit:e});for(let E of M){let g=null;if(E.type==="status"&&o?g="status":(E.type==="error-new"||E.type==="error-recur")&&a?g="error":(E.type==="warning-new"||E.type==="warning-recur")&&c?g="warning":(E.type==="lint-new"||E.type==="lint-recur")&&l?g="lint":E.type==="health"&&p?g="health":(E.type==="restart-scheduled"||E.type==="bundle-regression"||E.type==="compile-regression"||E.type==="stale"||E.type==="self-warn")&&b&&(g="restart"),!g)continue;let v=g==="status"?`${E.from_state??"?"} \u2192 ${E.to_state??"?"}`:E.message??E.type;i.push({ts:E.ts,app:E.app,kind:g,summary:v,payload:E})}}if(h){let M=this.queryBundles({app:t.app,since:n,limit:e});for(let E of M)i.push({ts:E.ts,app:E.app,kind:"bundle",summary:`initial ${E.initialKB}KB \xB7 lazy ${E.lazyKB}KB`,payload:E})}if(m){let M=this.queryCompiles({app:t.app,since:n,limit:e});for(let g of M)i.push({ts:g.ts,app:g.app,kind:"compile",summary:`compile ${(g.ms/1e3).toFixed(1)}s`,payload:g});let E=this.queryTasks({app:t.app,since:n,limit:e});for(let g of E){let v=g.duration_ms??0;i.push({ts:g.ts,app:g.app,kind:"task",summary:`${g.task} exit=${g.exit_code} ${(v/1e3).toFixed(1)}s`,payload:g})}}return i.sort((M,E)=>E.ts-M.ts),i.slice(0,e)}queryTasks(t){if(!this.db)return[];let e=[],n=[];t.app&&(e.push("app = ?"),n.push(t.app)),t.task&&(e.push("task = ?"),n.push(t.task)),t.since!=null&&(e.push("ts >= ?"),n.push(t.since));let s=`SELECT * FROM task_runs ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??200),this.db.prepare(s).all(...n)}summary(t){if(!this.db)return{uptimePct24h:0,restartCount24h:0,compileP50:null,compileP95:null,topErrors:[]};let e=Date.now()-24*3600*1e3,n=this.queryEvents({app:t,since:e,limit:5e3}),s=0,i=e,o=!1,a=null,c=[...n].sort((v,N)=>v.ts-N.ts);for(let v of c)v.type==="status"&&(v.to_state==="serving"&&!o?(o=!0,a=v.ts):o&&v.to_state!=="serving"&&a!=null&&(s+=v.ts-a,o=!1,a=null));o&&a!=null&&(s+=Date.now()-a);let l=Math.round(s/(24*3600*1e3)*1e3)/10,p=n.filter(v=>v.type==="status"&&v.to_state==="starting"&&(v.from_state==="serving"||v.from_state==="error"||v.from_state==="compiling")).length,h=this.queryCompiles({app:t,since:e,limit:1e3}).map(v=>v.ms).sort((v,N)=>v-N),m=(v,N)=>{if(v.length===0)return null;let u=Math.min(v.length-1,Math.floor((v.length-1)*N));return v[u]},b=m(h,.5),M=m(h,.95),E=new Map;for(let v of n)if(v.type==="error-new"||v.type==="error-recur"){let N=v.message??"";if(!N)continue;E.set(N,(E.get(N)??0)+1)}let g=[...E.entries()].sort((v,N)=>N[1]-v[1]).slice(0,5).map(([v,N])=>({message:v,count:N}));return{uptimePct24h:l,restartCount24h:p,compileP50:b,compileP95:M,topErrors:g}}why(t){let e=this.queryEvents({app:t,limit:200}),n=e.find(a=>a.type==="status"&&(a.to_state==="error"||a.from_state==="error"||a.to_state==="serving")),s=n?{ts:n.ts,app:n.app,type:n.type,from:n.from_state??void 0,to:n.to_state??void 0,message:n.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}))}}_flushForTest(){this.flush()}quickCheck(){if(!this.db)return!1;try{return this.db.prepare("PRAGMA quick_check").get()?.quick_check==="ok"}catch{return!1}}close(){if(this.flushTimer&&clearInterval(this.flushTimer),this.retentionTimer&&clearInterval(this.retentionTimer),this.retentionStart&&clearTimeout(this.retentionStart),this.flush(),this.db){try{this.db.close()}catch{}this.db=null}}}});function le(r){return r?$o[r]??null:null}function fn(r){return r===200||r===301||r===302||r===304||r===307||r===308||r===401}function mn(r){return r?r==="ECONNREFUSED"||r==="ECONNRESET"||r==="EHOSTUNREACH":!1}var $o,Ke=ot(()=>{"use strict";$o={django:"/admin/login/",rails:"/up",fastapi:"/docs","go-air":"/","rust-trunk":"/"}});var It={};Jt(It,{ALL_AUTO_FIX:()=>hn,runAutoFix:()=>ti});import F from"node:fs";import G from"node:path";function jo(){let r=wt();if(!r)return{detected:!1,description:"no daemon running"};let t=process.cwd(),e=G.join(t,"daimon.config.json");if(!F.existsSync(e))return{detected:!1,description:"no local daimon.config.json in cwd"};let n=r.cwd,s=r.configPath,i=n&&G.resolve(n)===G.resolve(t),o=s&&G.resolve(s)===G.resolve(e);return i||o?{detected:!1,description:"daemon already running from this cwd/config"}:{detected:!0,description:`daemon (pid ${r.pid}) is running from ${n??"(unknown)"} but local daimon.config.json exists at ${t}`,lockCwd:n}}async function Lo(){let r=wt();if(!r)return"no daemon running; nothing to do";try{await fetch(`http://127.0.0.1:${r.apiPort}/api/snapshot-state`,{method:"POST"})}catch{}try{await fetch(`http://127.0.0.1:${r.apiPort}/api/shutdown`,{method:"POST"})}catch{}return await Gr(r.pid,5e3),_t(),`respawned daemon at pid ${(await Ie({})).pid} from ${process.cwd()}; previous pid ${r.pid} (cwd ${r.cwd??"unknown"}) was shut down with state handoff. To undo: stop with 'daimon daemon stop' and start from the prior directory.`}function _o(){let r;try{r=F.readFileSync(ee(),"utf8")}catch{return{detected:!1,description:"no lock file present"}}let t;try{t=JSON.parse(r)}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 Do(){let r="(unknown)";try{let e=JSON.parse(F.readFileSync(ee(),"utf8"));r=String(e?.pid??"?")}catch{}_t();let t=await Ie({});return`removed stale ${ee()} (prior pid ${r} was dead); spawned fresh daemon at pid ${t.pid}.`}function Fo(){let r=process.cwd(),e=["nx.json","angular.json","vite.config.ts","vite.config.js","vite.config.mjs","vite.config.cjs",".storybook"].filter(o=>F.existsSync(G.join(r,o)));if(!e.length)return{detected:!1,description:"no nx.json/angular.json/vite.config.*/.storybook in cwd"};let n=st();return n.kind!=="loaded"?{detected:!0,description:`${e.join(", ")} present but no config is loaded`,markerFiles:e}:n.config.searchRoots.map(o=>G.resolve(typeof o=="string"?o:o.path)).some(o=>r.startsWith(o))?{detected:!1,description:`${e.join(", ")} present and a configured searchRoot covers ${r}`}:{detected:!0,description:`${e.join(", ")} present in ${r} but no searchRoot covers it`,markerFiles:e}}function Io(){let r=process.cwd(),{local:t,user:e}=pt(),n=F.existsSync(t)?t:e,s={};try{s=JSON.parse(F.readFileSync(n,"utf8"))}catch{}if(s.searchRoots=Array.isArray(s.searchRoots)?s.searchRoots:[],!s.searchRoots.some(o=>(typeof o=="string"?o:o?.path)===r)){let o;try{let a=JSON.parse(F.readFileSync(G.join(r,"package.json"),"utf8"));typeof a.name=="string"&&(o=a.name)}catch{}s.searchRoots.push(o?{path:r,label:o}:r)}F.mkdirSync(G.dirname(n),{recursive:!0}),F.writeFileSync(n,JSON.stringify(s,null,2)+`
|
|
51
|
-
`,"utf8");let
|
|
52
|
-
`,"utf8");let
|
|
53
|
-
`,"utf8");let o=wt();if(o)try{fetch(`http://127.0.0.1:${o.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`wrote healthProbePath to overrides in ${n} for: ${i.join(", ")}; triggered soft-reload. To undo: edit ${n}.`}async function ti(r){let t={ran:[],skipped:[],errors:[]};for(let e of hn){if(!r.permitted.includes(e))continue;let n=Qo[e],s;try{s=await n.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(r.dryRun){t.ran.push({name:e,detected:!0,description:`(dry-run) would fix: ${s.description}`});continue}try{let i=await n.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 hn,Qo,Bt=ot(()=>{"use strict";St();jt();Xe();zt();xt();Ke();hn=["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root","health-probe-missing"];Qo={"orphan-daemon":{detect:jo,fix:Lo},"stale-lock":{detect:_o,fix:Do},"missing-search-root":{detect:Fo,fix:Io},"corrupt-history-db":{detect:Bo,fix:Ho},"port-conflict-pred":{detect:Uo,fix:Wo},"node-version-mismatch":{detect:Go,fix:qo},"orphan-node-modules":{detect:gn,fix:Xo},"orphan-venv":{detect:yn,fix:Ko},"orphan-bundler-cache":{detect:bn,fix:zo},"orphan-cargo-target":{detect:vn,fix:Yo},"dead-search-root":{detect:wn,fix:Vo},"health-probe-missing":{detect:Sn,fix:Zo}}});var Ye={};Jt(Ye,{orchestrateProfile:()=>ni});function kn(r,t,e,n,s){let i=r.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()-n;return i.status==="serving"&&i.health==="healthy"&&o>=s}async function xn(r,t,e,n,s){let i=Date.now();if(e!=="stable"){let c=await r.waitFor(t,e==="serving"?"serving":"healthy",n);return{reached:!c.timedOut,waitedMs:c.waitedMs}}let o=Date.now(),a=c=>{c?.app===t&&(o=Date.now())};r.on("event",a);try{for(;Date.now()-i<n;){if(kn(r,t,e,o,s))return{reached:!0,waitedMs:Date.now()-i};await new Promise(c=>setTimeout(c,500))}return{reached:kn(r,t,e,o,s),waitedMs:Date.now()-i}}finally{r.off("event",a)}}async function ni(r,t,e){let n=Date.now(),s=t.profiles?.[e.profile];if(!s)return{error:`unknown profile: ${e.profile}`};let i=s.filter(g=>r.summary(g)!=null),o=Array.from(new Set(i.flatMap(g=>Vt(t.depends??{},g)))).filter(g=>r.summary(g)!=null),a=Zt(t.depends??{},o),c=[];for(let g of o){let v=r.summary(g);v&&(e.goal==="serving"&&v.status==="serving"||(e.goal==="healthy"||e.goal==="stable")&&v.status==="serving"&&v.health==="healthy")&&c.push(g)}if(e.dryRun){let g=o.filter(v=>!c.includes(v));return{profile:e.profile,goal:e.goal,perApp:g.map(v=>({name:v,reached:!1,tries:0})),totalMs:Date.now()-n,allReached:g.length===0,dryRun:!0,plannedOrder:a,alreadyHealthy:c}}let l=Math.max(5e3,Math.floor(e.timeoutMs/2)),p=e.stableMs??5e3,h=new Map;for(let g of o)h.set(g,{name:g,reached:!1,tries:0});for(let g of a)await Promise.all(g.map(async v=>{let N=r.summary(v);if(!N){h.set(v,{name:v,reached:!1,tries:0,error:"unknown app"});return}if(c.includes(v)){h.set(v,{name:v,reached:!0,tries:0});return}N.status!=="starting"&&N.status!=="compiling"&&N.status!=="serving"&&await r.start(v)})),await Promise.all(g.map(async v=>{if(h.get(v)?.reached)return;let N=await xn(r,v,e.goal,l,p),u=h.get(v);u.tries=1,u.waitedMs=N.waitedMs,u.reached=N.reached,h.set(v,u)}));let m=[...h.values()].filter(g=>!g.reached);if(m.length>0){let{runAutoFix:g,ALL_AUTO_FIX:v}=await Promise.resolve().then(()=>(Bt(),It)),N=t.doctor?.autoFix?.permitted??v,u=Math.max(5e3,e.timeoutMs-(Date.now()-n)),d=Math.max(5e3,Math.floor(u/Math.max(m.length,1))),f={ran:[]};try{f=await g({permitted:N,dryRun:!1})}catch{}let S=(f.ran??[]).map(T=>T.name);await Promise.all(m.map(async T=>{let P=h.get(T.name);P.tries=2;try{let x=await r.restart(T.name);x?.ok||(P.error=x?.error??"restart failed")}catch(x){P.error=x?.message??String(x)}let k=await xn(r,T.name,e.goal,d,p);if(P.waitedMs=(P.waitedMs??0)+k.waitedMs,P.reached=k.reached,!P.reached){let x=r.errors(T.name)??[];P.stillFailing=x.slice(0,3).map(C=>({file:C.parsed?.file??null,line:C.parsed?.line??null,code:C.parsed?.code??null,tool:C.parsed?.tool??null,message:C.parsed?.message??C.message}))}P.fixed=S,h.set(T.name,P)}))}let b=[...h.values()],M=b.every(g=>g.reached),E={profile:e.profile,goal:e.goal,perApp:b,totalMs:Date.now()-n,allReached:M};if(typeof e.budgetTokens=="number"&&e.budgetTokens>0){let g=e.budgetTokens,v=0,N=0;for(let u of b)if(u.stillFailing){let d=u.stillFailing.length*ei;d>g?(v+=u.stillFailing.length,delete u.stillFailing):g-=d}for(;g<0||b.length*ri>Math.max(g,e.budgetTokens/4);){let u=b.findIndex(d=>d.reached);if(u===-1)break;b.splice(u,1),N++}(v||N)&&(E._meta={omitted:{}},v&&(E._meta.omitted.stillFailing=v),N&&(E._meta.omitted.perApp=N))}return E}var ei,ri,Ve=ot(()=>{"use strict";Qt();ei=60,ri=25});jt();xt();import ia from"react";import aa from"node:path";import{render as ca}from"ink";import{pathToFileURL as la}from"node:url";import{EventEmitter as lo}from"node:events";import Oe from"node:path";function kr(r){let t=Oe.resolve(r);return process.platform==="win32"?t.toLowerCase():t}function at(r,t){let e=kr(r),n=kr(t);if(e===n)return!0;let s=n.endsWith(Oe.sep)?n:n+Oe.sep;return e.startsWith(s)}import{spawn as js}from"node:child_process";import Pr from"tree-kill";import Ls from"strip-ansi";import os from"node:crypto";var is=[/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],as=[/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],cs=[/^\s+\d+:\d+\s{2,}(?:warning|error)\s{2,}\S/i,/\blint\/[a-z][a-z0-9-]+\/[a-z][a-zA-Z0-9-]+\b/,/^\s*\S+\.py:\d+:\d+:\s+[A-Z]\d{3,}\b/,/^warning:\s.*clippy::/i,/^\s*=\s+note:\s+`#\[warn\(clippy::/],ls=[/^\s*(?:▲\s*)?\[WARNING\]/,/\bwarning TS\d+/i,/^\s*\[(?:warning|warn)\]\s+/i,/^\s*warning\s+\S+\s+is\s+/i,/^\s*\S+:\d+:\s*(?:Deprecation|User|Future|Pending|Resource|Runtime|Syntax)Warning:/,/^WARNING in\s+/,/^\s*\[vite\]\s+warning/i],us=[/^\s*ERROR\b/,/\berror TS\d+/,/✘/,/\[ERROR\]/,/Cannot find module/i,/^FAIL\s+\S+/,/^\s*●\s+/,/^\s*(?:>\s+)?NX\s+.*failed/i,/^\s*Failed tasks:/,/^\s*Task\s+"[^"]+"\s+is continuous but exited with code\s+\d+/,/\bModule not found:/,/\[vite\]\s+(?:Internal server error|Pre-transform error)/i,/\[plugin:[^\]]+\]/i,/^\s*ERR!\s+/,/^\s*(?:Uncaught\s+)?(?:Error|TypeError|SyntaxError|ReferenceError|RangeError):\s+/,/^Traceback \(most recent call last\):/,/^\s*[A-Z][a-zA-Z]*Error:\s+/,/^\s*\[error\]\s+/i,/^panic:\s+/,/^thread\s+'[^']+'\s+panicked at/,/^error\[E\d+\]:/,/^\S+\.(?:go|rb|py|rs):\d+:\d+:/,/^\s*[A-Z][a-zA-Z]*\.[A-Z][a-zA-Z]*:\s+/,/^[A-Z][a-zA-Z]+(?:::[A-Z][a-zA-Z]+)+\s*[(:]/,/^[A-Z][a-zA-Z]*Error\s*\(/],ps=/\berror TS(\d+)/,ds=/✘\s*\[ERROR\]\s*TS(\d+)/,fs=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte|py|rb|go|rs)):(\d+):(\d+)/,xr=/\(([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte|py|rb|go|rs)):(\d+):(\d+)\)/,ms=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte))\((\d+),(\d+)\)\s*:/,Tr=/File\s+"([^"]+\.py)",\s+line\s+(\d+)/,Er=/^\s*-->\s+([^\s:]+\.rs):(\d+):(\d+)/,hs=/^([^\s:()]+\.rb):(\d+):in\b/,gs=/^FAIL\s+(\S+\.(?:tsx?|jsx?|mjs|cjs))(?:\s|$)/,ys=/^ERROR in\s+(\S+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte))(?:[:\s](\d+):(\d+))?/,bs=/^\s+([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte)):(\d+):(\d+):?\s*$/,vs=[{tool:"vite",rx:/\[vite\]|\[plugin:vite:|transformWithEsbuild/i},{tool:"storybook",rx:/\bstorybook\b|^\s*ERR!\s|builder-vite/i},{tool:"jest",rx:/^FAIL\s|^\s*●\s+|\bjest\b/i},{tool:"nx",rx:/(?:>\s+)?NX\s+(?:\w|.*failed)|Failed tasks:|Nx errored|exited with code\s+\d+/i},{tool:"webpack",rx:/\bModule not found:|webpack compiled|webpack-dev-server/i},{tool:"esbuild",rx:/✘\s*\[ERROR\]|esbuild/i},{tool:"typescript",rx:/\berror TS\d+/},{tool:"django",rx:/\bdjango\b|StatReloader|manage\.py runserver/i},{tool:"rails",rx:/\brails\b|Puma starting|Booting (?:Puma|Rails)|ActionController|NameError\s*\(|\.rb:\d+:in/i},{tool:"fastapi",rx:/\buvicorn\b|fastapi|ASGI/i},{tool:"go-air",rx:/\bair v\d|building\.{3}|\.go:\d+:\d+/i},{tool:"rust-trunk",rx:/\btrunk\b|^error\[E\d+\]|^\s*-->\s+\S+\.rs:/i},{tool:"python",rx:/^Traceback \(most recent call last\):|^\s*File "[^"]+\.py"|[A-Z][a-zA-Z]*Error:\s/},{tool:"node",rx:/^\s*(?:Uncaught\s+)?(?:Error|TypeError|SyntaxError|ReferenceError|RangeError):/}];function ws(r){for(let{tool:t,rx:e}of vs)if(e.test(r))return t}var Ss=/Local:\s+(https?:\/\/\S+)/i,ks=/Server running at\s+(https?:\/\/\S+)/i,xs=/listening on\s+(https?:\/\/\S+)/i,Ts=/(?:listening|listen)\s+(https?:\/\/\S+)/i,Es=/Initial chunk files/i,Rs=/Lazy chunk files/i,Ps=/(Initial total|Lazy total)\s*\|?\s*([\d.]+)\s*(kB|MB|B)\b/i,As=/^\s*\|?\s*([^\s|][^|]*?)\s*\|\s*([^|]+?)\s*\|\s*([\d.]+)\s*(kB|MB|B)\b/i;function Cs(r){return os.createHash("sha1").update(r).digest("hex").slice(0,16)}function Ms(r){let t={message:r},e=r.match(ds)||r.match(ps);e&&(t.code=`TS${e[1]}`);let n=r.match(ms)||r.match(xr)||r.match(fs);if(n)t.file=n[1],t.line=Number(n[2]),t.col=Number(n[3]);else{let i=r.match(ys);if(i)t.file=i[1],i[2]&&(t.line=Number(i[2])),i[3]&&(t.col=Number(i[3]));else{let o=r.match(gs);if(o)t.file=o[1];else{let a=r.match(Er);if(a)t.file=a[1],t.line=Number(a[2]),t.col=Number(a[3]);else{let c=r.match(Tr);c&&(t.file=c[1],t.line=Number(c[2]))}}}}let s=ws(r);return s&&(t.tool=s),t}function Os(r,t){try{let e=new URL(r);return e.hostname==="0.0.0.0"||e.hostname==="[::]"?(e.hostname=t.includes(":")?`[${t}]`:t,e.toString().replace(/\/$/,"")):r.replace(/\/$/,"")}catch{return r}}function Ns(r,t="127.0.0.1"){let e=r.match(Ss)||r.match(ks)||r.match(xs)||r.match(Ts);if(!e)return null;let n=e[1].replace(/[),.;]+$/,"");return Os(n,t)}function $s(r,t){if(Es.test(t))return r.bundle||(r.bundle={initialKB:0,lazyKB:0,files:[]}),r._bundleSection="initial",!1;if(Rs.test(t))return r.bundle||(r.bundle={initialKB:0,lazyKB:0,files:[]}),r._bundleSection="lazy",!1;let e=t.match(Ps);if(e&&r.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])?r.bundle.initialKB=o:r.bundle.lazyKB=o,!0}let n=t.match(As);if(n&&r.bundle){let s=n[1].trim();if(/^(Initial|Lazy)\s+(total|chunk)/i.test(s))return!1;let i=n[4].toUpperCase(),o=parseFloat(n[3]),a=i==="MB"?o*1024:i==="B"?o/1024:o;return r.bundle.files.push({name:s,sizeKB:Math.round(a*10)/10}),!1}return!1}function Rr(r,t){let e=t.match(bs),n=e?null:t.match(xr),s=!e&&!n?t.match(Er):null,i=e??n??s;if(i&&r.lastErrorHash){let v=r.errors.get(r.lastErrorHash);v&&!v.parsed?.file&&(v.parsed={...v.parsed??{message:v.message},file:i[1],line:Number(i[2]),col:Number(i[3])})}else if(r.lastErrorHash){let v=t.match(Tr),N=v?null:t.match(hs);if(v||N){let u=r.errors.get(r.lastErrorHash);if(u&&!u.parsed?.file){let d=v??N;u.parsed={...u.parsed??{message:u.message},file:d[1],line:Number(d[2])}}}}let o=t.trim();if(!o)return null;let a=r.status,c=!1,l,p=Ns(o);p&&!r.announcedUrl&&(r.announcedUrl=p,l=p);let h=$s(r,o),m;if(is.some(v=>v.test(o))){let v=r.status==="error"||!!r.recoveringFromError;if(r.status==="compiling"||r.status==="starting"||r.status==="error"){let N=Date.now();r.compileStartedAt!=null?(m=N-r.compileStartedAt,r.lastCompileMs=m,r.lastCompileAt=N,r.compileStartedAt=null,r.compileHistory.push(m),r.compileHistory.length>20&&r.compileHistory.splice(0,r.compileHistory.length-20)):r.lastCompileAt=N}r.status="serving",v&&(r.errors.clear(),r.recoveringFromError=!1)}else as.some(v=>v.test(o))&&(r.status==="starting"||r.status==="serving"||r.status==="error")&&(r.status==="error"&&(r.recoveringFromError=!0),r.compileStartedAt=Date.now(),r.status="compiling");let b,M=cs.some(v=>v.test(t)),E=!M&&us.some(v=>v.test(o)),g=!M&&!E&&ls.some(v=>v.test(o));if(E||g||M){let v=Cs(o),N=Date.now(),u=r.errors.get(v),d=!1,f;u?(u.count+=1,u.lastSeen=N,f=u):(f={message:o,count:1,firstSeen:N,lastSeen:N,parsed:Ms(o),level:M?"lint":g?"warning":"error"},r.errors.set(v,f),d=!0),r.lastErrorHash=v,b={entry:f,isNew:d},E&&(r.status="error")}return c=r.status!==a,{statusChanged:c,error:b,announcedUrl:l,bundleUpdated:h,compileMs:m}}var Ar=500,Kt=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:n}=this.deps,s=Date.now();n.status="starting",n.startedAt=s,n.compileStartedAt=s,n.lastCompileMs=null,n.lastCompileAt=null,n.errors.clear(),n.logBuffer.length=0,n.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=js(o,[],{cwd:t.workspaceRoot,shell:!0,env:a,windowsHide:!0});this.child=c,n.pid=c.pid??null,n.port=e,c.stdout?.on("data",l=>this.handleChunk(l,"stdout")),c.stderr?.on("data",l=>this.handleChunk(l,"stderr")),c.on("exit",(l,p)=>{let h=n.status,m=this.stopping;m?(n.status="stopped",n.lastStatusMessage=`stopped (code=${l??"null"}${p?`, ${p}`:""})`):l!==0?(n.status="error",n.lastStatusMessage=`process exited with code ${l}${p?` (${p})`:""}`):n.status="stopped",n.pid=null,n.health="unknown",this.child=null,this.stopping=!1,h!==n.status&&this.deps.onStatusChange?.(h,n.status,n.lastStatusMessage),this.deps.onExit?.(l,p,m),this.deps.onStateChange()}),c.on("error",l=>{n.status="error",n.lastStatusMessage=`spawn error: ${l.message}`,this.deps.onStateChange()}),this.deps.onStateChange()}handleChunk(t,e){let n=t.toString("utf8"),s=this[e==="stdout"?"stdoutBuf":"stderrBuf"]+=n,i=s.lastIndexOf(`
|
|
54
|
-
`);if(
|
|
55
|
-
`,n=Buffer.from(e,"utf8");
|
|
56
|
-
`))}};
|
|
57
|
-
`);if(
|
|
58
|
-
`)+(
|
|
59
|
-
`+
|
|
60
|
-
`);if(
|
|
61
|
-
`;try{Be.appendFileSync(this.file,e)}catch{}}};var zr=500,ne=class extends lo{entries=new Map;portAlloc;config;eventBuffer=[];history=null;watchTasks=new Map;sessionRecorder=new re;constructor(t,e,n){super(),this.config=t,this.portAlloc=n??new Tt(t.portRange);for(let s of e)this.entries.set(s.name,{app:s,state:this.freshState(s.name,s.baseName??s.name,s.tags,s.workspaceLabel??null,s.workspaceRoot??null),proc:null})}getConfig(){return this.config}addDiscoveredApp(t){this.entries.has(t.name)||(this.entries.set(t.name,{app:t,state:this.freshState(t.name,t.baseName??t.name,t.tags,t.workspaceLabel??null,t.workspaceRoot??null),proc:null}),this.emit("change"))}updateDiscoveredApp(t){let e=this.entries.get(t.name);e&&(e.app=t,e.state.tags=t.tags,e.state.workspaceLabel=t.workspaceLabel??null,e.state.workspaceRoot=t.workspaceRoot??null,e.state.baseName=t.baseName??t.name,e.state.dependsOn=this.config.depends?.[t.baseName??t.name]??[],this.emit("change"))}getPortAllocator(){return this.portAlloc}setHistory(t){this.history=t}getHistory(){return this.history}freshState(t,e,n,s=null,i=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:n,announcedUrl:null,lastHealthError:null,cachedProbeHost:null,lastLogTs:null,stale:!1,bundle:null,bundleRegressionPct:null,activeEnvFile:null,sessionOverrides:null,dependsOn:this.config.depends?.[e]??[],workspaceLabel:s,workspaceRoot:i,baseName:e,discoveredHealthPath:null}}names(){return[...this.entries.keys()]}resolveByCwd(t,e){let s=[...this.entries.values()].filter(o=>o.state.name===t||(o.state.baseName??o.state.name)===t);e&&(s=s.filter(o=>{let a=o.app.workspaceRoot;return a?at(a,e)||at(e,a):!1}));let i=s.map(o=>({name:o.state.name,baseName:o.state.baseName??o.state.name,workspaceLabel:o.state.workspaceLabel,workspaceRoot:o.state.workspaceRoot??o.app.workspaceRoot??null}));return s.length===0?{kind:"none",candidates:i}:s.length>1?{kind:"collision",candidates:i}:{kind:"unique",key:s[0].state.name,candidates:i}}pruneOldErrors(t=Date.now()){let e=this.config.errorRetention?.maxAgeMs??864e5,n=0;for(let s of this.entries.values())for(let[i,o]of s.state.errors)t-o.lastSeen>e&&(s.state.errors.delete(i),n++);return n}list(){return this.names().map(t=>this.summary(t))}summary(t){let e=this.entries.get(t);if(!e)return null;let n=e.state,s=n.startedAt&&(n.status==="serving"||n.status==="compiling"||n.status==="starting")?Date.now()-n.startedAt:null,o=this.config.overrides?.[t]?.url||e.resolvedUrl||n.announcedUrl||(n.port?`http://127.0.0.1:${n.port}`:null),a;for(let c=this.eventBuffer.length-1;c>=0;c--){let l=this.eventBuffer[c];if(l.app===t&&l.type==="status"){a=Date.now()-l.ts;break}}return{name:n.name,status:n.status,port:n.port,url:o,errorCount:[...n.errors.values()].reduce((c,l)=>{let p=l.level??"error";return c+(p==="error"?l.count:0)},0),warningCount:[...n.errors.values()].reduce((c,l)=>c+(l.level==="warning"?l.count:0),0),lintCount:[...n.errors.values()].reduce((c,l)=>c+(l.level==="lint"?l.count:0),0),uptimeMs:s,lastCompileMs:n.lastCompileMs,health:n.health,lastHealthAt:n.lastHealthAt,cpu:n.cpu,memMB:n.memMB,compileHistoryMs:[...n.compileHistory],tags:[...n.tags],restartAttempts:n.restartAttempts,nextRestartAt:n.nextRestartAt,announcedUrl:n.announcedUrl,lastHealthError:n.lastHealthError,stale:n.stale,bundle:n.bundle,bundleRegressionPct:n.bundleRegressionPct,dependsOn:[...n.dependsOn],activeEnvFile:n.activeEnvFile,workspaceLabel:n.workspaceLabel,workspaceRoot:n.workspaceRoot,baseName:n.baseName??n.name,lastChangeMs:a}}getState(t){return this.entries.get(t)?.state??null}getApp(t){return this.entries.get(t)?.app??null}errors(t){let e=this.getState(t);return e?[...e.errors.values()].sort((n,s)=>s.lastSeen-n.lastSeen):null}errorsSince(t,e){let n=this.getState(t);return n?[...n.errors.values()].filter(s=>s.lastSeen>e).sort((s,i)=>i.lastSeen-s.lastSeen):null}logs(t,e={}){let n=this.getState(t);if(!n)return null;let s=n.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(n=>n.ts>=e&&(!t.app||n.app===t.app))}recordEvent(t){let e={ts:t.ts??Date.now(),...t};this.eventBuffer.push(e),this.emit("event",e),this.eventBuffer.length>zr&&this.eventBuffer.splice(0,this.eventBuffer.length-zr),this.history?.recordEvent(e),this.emit("event",e)}setHealth(t,e){let n=this.entries.get(t);if(!n)return;let s=n.state;if(s.lastHealthAt=Date.now(),s.health===e)return;let i=s.health;s.health=e,e==="healthy"&&(n.prevHealthyAt=Date.now(),n.cascadeArmed&&(n.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 n=this.getState(t);n&&n.lastHealthError!==e&&(n.lastHealthError=e,this.emit("change"))}setResolvedUrl(t,e){let n=this.entries.get(t);n&&n.resolvedUrl!==e&&(n.resolvedUrl=e,this.emit("change"))}setCachedProbeHost(t,e){let n=this.getState(t);n&&(n.cachedProbeHost=e)}setStale(t,e){let n=this.getState(t);n&&n.stale!==e&&(n.stale=e,this.emit("change"))}setSessionOverride(t,e){let n=this.getState(t);n&&(n.sessionOverrides=e,this.emit("change"))}setActiveEnvFile(t,e){let n=this.getState(t);n&&(n.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 n=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:n,to:"error",message:b.message}),this.emit("change"),{ok:!1,status:"error",error:b.message}}if(!await Et(s)){let b=Dr(s),M=Fr(s,b);return e.state.status="error",e.state.port=s,e.state.lastStatusMessage=M,this.recordEvent({app:t,type:"status",from:n,to:"error",message:M}),this.emit("change"),{ok:!1,status:"error",error:M}}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 Yt(t,this.config.logs));let o=e.state.sessionOverrides,a=this.config.envFiles?.[t]??[],c={};if(a.length){let b=e.state.activeEnvFile;(!b||!Le(e.app.workspaceRoot,[b]).length)&&(b=Le(e.app.workspaceRoot,a)[0]??null,b&&(e.state.activeEnvFile=b)),b&&(c=Hr(je(e.app.workspaceRoot,b)))}let l={...c,...this.config.overrides?.[t]?.env??{},...o?.env??{}},p=Jr(),h=Xr(l,p),m=new Kt({state:e.state,app:e.app,port:s,envOverride:Object.keys(h).length?h:void 0,commandOverride:o?.command,onStateChange:()=>this.emit("change"),onStatusChange:(b,M,E)=>{this.recordEvent({app:t,type:"status",from:b,to:M,message:E}),(M==="stopped"||M==="error")&&(b==="serving"||b==="compiling")&&this.armCascade(t)},onErrorRecorded:(b,M)=>{let E=b.level??"error",g;E==="lint"?g=M?"lint-new":"lint-recur":E==="warning"?g=M?"warning-new":"warning-recur":g=M?"error-new":"error-recur",this.recordEvent({app:t,type:g,message:b.message})},onExit:(b,M,E)=>this.emit("childExit",{name:t,code:b,signal:M,stopping:E}),onLogLine:b=>{e.logger?.write(b),this.emit("log",{name:t,ts:Date.now(),line:b})},onCompile:b=>{this.history?.recordCompile(t,b);let M=this.getState(t),E=e.lastBundleInitialKB;if(M.bundle&&M.bundle.initialKB>0){if(E&&E>0){let g=(M.bundle.initialKB-E)/E*100;M.bundleRegressionPct=Math.round(g*10)/10,g>10&&this.recordEvent({app:t,type:"bundle-regression",message:`initialKB +${M.bundleRegressionPct}% (${E}->${M.bundle.initialKB})`})}else M.bundleRegressionPct=null;e.lastBundleInitialKB=M.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=m,this.recordEvent({app:t,type:"status",from:n,to:"starting"}),m.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 n=e.state.status;return await e.proc.stop(),e.proc=null,e.state.status!==n&&this.recordEvent({app:t,type:"status",from:n,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 n=Vt(this.config.depends??{},t).filter(a=>this.entries.has(a)),s=Zt(this.config.depends??{},n),i=[],o=e.waitMs??6e4;for(let a of s){let c=await Promise.all(a.map(p=>this.start(p)));for(let p=0;p<a.length;p++){let h=c[p];if(!h.ok)return i.push({name:a[p],status:h.status,health:"unknown",error:h.error}),{ok:!1,results:i}}let l=await Promise.all(a.map(p=>this.waitFor(p,"healthy",o)));for(let p=0;p<a.length;p++){let h=l[p],m=!h.timedOut&&h.status==="serving"&&h.health==="healthy";if(i.push({name:h.name,status:h.status,health:h.health,error:m?void 0:h.timedOut?"timeout waiting for healthy":"did not reach healthy"}),!m)return{ok:!1,results:i}}}return{ok:!0,results:i}}triggerCascadeRestart(t){if(!this.config.cascadeRestart)return;let e=Mr(this.config.depends??{},t);for(let n of e){let s=this.getState(n);s&&(s.status==="serving"||s.status==="compiling"||s.status==="starting")&&this.restart(n)}}async stopAll(t=3e3){let e=[];for(let n of this.entries.values())n.proc?.isRunning()&&e.push(n.proc.stop());for(let n of this.watchTasks.values())e.push(n.stop());await Promise.race([Promise.all(e),new Promise(n=>setTimeout(n,t))]);for(let n of this.entries.values())n.logger?.close()}listTasks(t){let e=this.getApp(t);return e?[...e.tasks??[]]:null}async runTask(t,e,n=[]){this.sessionRecorder.append({kind:"run",app:t,task:e,args:n});let s=this.getApp(t);if(!s)return{error:"unknown app"};let i=await Lr(s,e,n);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,n=[]){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=_r(s,e,n);return this.watchTasks.set(i,o),o.child.on("exit",()=>this.watchTasks.delete(i)),{ok:!0,pid:o.pid}}async stopWatchTask(t,e){let n=`${t}::${e}`,s=this.watchTasks.get(n);return s?(await s.stop(),this.watchTasks.delete(n),{ok:!0}):{ok:!0}}listWatchTasks(t){let e=[];for(let n of this.watchTasks.values())t&&n.app!==t||e.push({app:n.app,task:n.task,pid:n.pid,startedAt:n.startedAt});return e}checkCompileRegression(t,e){let n=this.history;if(!n)return;let i=n.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,l)=>c-l),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,n){let s=this.watchTasks.get(`${t}::${e}`);if(!s)return null;let i=s.logs;return n?i.slice(-n):[...i]}waitFor(t,e,n){return new Promise(s=>{let i=Date.now(),o=this.entries.get(t),a=()=>{if(!o)return!0;let h=o.state;return e==="serving"&&h.status==="serving"||e==="healthy"&&h.status==="serving"&&h.health==="healthy"||e==="stopped"&&h.status==="stopped"||e==="error"&&h.status==="error"},c=h=>{this.off("change",l),clearTimeout(p);let m=o?.state;s({name:t,status:m?.status??"unknown",health:m?.health??"unknown",timedOut:h,waitedMs:Date.now()-i})},l=()=>{a()&&c(!1)};if(a()){s({name:t,status:o.state.status,health:o.state.health,timedOut:!1,waitedMs:0});return}let p=setTimeout(()=>c(!0),n);this.on("change",l)})}};zt();import si from"node:http";import oi from"node:crypto";import mt from"node:fs";import tt from"node:path";import{fileURLToPath as ii}from"node:url";import We from"node:fs";import Yr from"node:path";import uo from"node:os";var Ge=Yr.join(uo.homedir(),".daimon","cursors.json");function po(){try{let r=We.readFileSync(Ge,"utf8"),t=JSON.parse(r);if(t&&typeof t=="object"&&t.errors&&typeof t.errors=="object")return{errors:t.errors}}catch{}return{errors:{}}}var He=null,Ue=null;function fo(r){Ue=r,!He&&(He=setTimeout(()=>{He=null;let t=Ue;if(Ue=null,!!t)try{We.mkdirSync(Yr.dirname(Ge),{recursive:!0}),We.writeFileSync(Ge,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: cursor write failed: ${e.message}
|
|
62
|
-
`)}},500))}var
|
|
52
|
+
`)}recordSelfMetric(t,e,n,s,o=Date.now()){if(this.db)try{this.db.prepare("INSERT INTO self_metrics (ts,rssMB,heapUsedMB,eventLoopLagMs,historyQueryP95Ms) VALUES (?,?,?,?,?)").run(o,t,e,n,s)}catch(a){this.warnOnce(`self_metrics write failed: ${a?.message||a}`)}}querySelfMetrics(t={}){if(!this.db)return[];let e=[],n=[];t.since!=null&&(e.push("ts >= ?"),n.push(t.since));let s=`SELECT ts, rssMB, heapUsedMB, eventLoopLagMs, historyQueryP95Ms FROM self_metrics ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??60),this.db.prepare(s).all(...n)}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,n=Date.now()){this.db&&this.queue.push({kind:"compile",row:{ts:n,app:t,ms:e}})}recordBundle(t,e,n,s,o=Date.now()){this.db&&this.queue.push({kind:"bundle",row:{ts:o,app:t,initialKB:e,lazyKB:n,fileCount:s}})}recordTaskRun(t,e,n,s,o,a=Date.now()){this.db&&this.queue.push({kind:"task",row:{ts:a,app:t,task:e,exit_code:n,duration_ms:s,summary:o==null?null:JSON.stringify(o)}})}flush(){if(!this.db||this.queue.length===0)return;let t=this.queue;this.queue=[];try{let e=this.db.prepare("INSERT INTO events (ts,app,type,from_state,to_state,message) VALUES (?,?,?,?,?,?)"),n=this.db.prepare("INSERT INTO compile_times (ts,app,ms) VALUES (?,?,?)"),s=this.db.prepare("INSERT INTO task_runs (ts,app,task,exit_code,duration_ms,summary) VALUES (?,?,?,?,?,?)"),o=this.db.prepare("INSERT INTO bundles (ts,app,initialKB,lazyKB,fileCount) VALUES (?,?,?,?,?)");this.db.transaction(c=>{for(let i of c)i.kind==="event"?e.run(i.row.ts,i.row.app,i.row.type,i.row.from_state,i.row.to_state,i.row.message):i.kind==="compile"?n.run(i.row.ts,i.row.app,i.row.ms):i.kind==="bundle"?o.run(i.row.ts,i.row.app,i.row.initialKB,i.row.lazyKB,i.row.fileCount):s.run(i.row.ts,i.row.app,i.row.task,i.row.exit_code,i.row.duration_ms,i.row.summary)})(t)}catch(e){this.warnOnce(`history write failed: ${e?.message||e}`)}}runRetention(){if(this.db)try{let t=Date.now()-this.cfg.retentionDays*864e5;this.db.prepare("DELETE FROM events WHERE ts < ?").run(t),this.db.prepare("DELETE FROM compile_times WHERE ts < ?").run(t),this.db.prepare("DELETE FROM task_runs WHERE ts < ?").run(t),this.db.prepare("DELETE FROM bundles WHERE ts < ?").run(t),this.db.prepare("DELETE FROM self_metrics WHERE ts < ?").run(t)}catch(t){this.warnOnce(`retention failed: ${t?.message||t}`)}}queryEvents(t){if(!this.db)return[];let e=[],n=[];t.app&&(e.push("app = ?"),n.push(t.app)),t.since!=null&&(e.push("ts >= ?"),n.push(t.since)),t.until!=null&&(e.push("ts <= ?"),n.push(t.until)),t.type&&(e.push("type = ?"),n.push(t.type));let s=`SELECT * FROM events ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??500),this.db.prepare(s).all(...n)}queryCompiles(t){if(!this.db)return[];let e=[],n=[];t.app&&(e.push("app = ?"),n.push(t.app)),t.since!=null&&(e.push("ts >= ?"),n.push(t.since)),t.until!=null&&(e.push("ts <= ?"),n.push(t.until));let s=`SELECT * FROM compile_times ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??1e3),this.db.prepare(s).all(...n)}queryBundles(t){if(!this.db)return[];let e=[],n=[];t.app&&(e.push("app = ?"),n.push(t.app)),t.since!=null&&(e.push("ts >= ?"),n.push(t.since)),t.until!=null&&(e.push("ts <= ?"),n.push(t.until));let s=`SELECT * FROM bundles ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??1e3),this.db.prepare(s).all(...n)}trends(t){if(!this.db)return{points:[],count:0};let e=Date.now()-t.sinceMs,n=t.bucketMs,s=new Map,o=(u,d)=>{let g=Math.floor(u/n)*n,v=s.get(g)??{sum:0,n:0};v.sum+=d,v.n+=1,s.set(g,v)},a=u=>{let d=Math.floor(u/n)*n,g=s.get(d)??{sum:0,n:0};g.sum+=1,g.n+=1,s.set(d,g)},c=0;if(t.metric==="compile"){let u=this.queryCompiles({app:t.app,since:e,limit:1e4});c=u.length;for(let d of u)o(d.ts,d.ms)}else if(t.metric==="bundle"){let u=this.queryBundles({app:t.app,since:e,limit:1e4});c=u.length;for(let d of u){let g=Math.floor(d.ts/n)*n,v=s.get(g)??{sum:0,n:0,sum2:0};v.sum+=d.initialKB,v.sum2=(v.sum2??0)+d.lazyKB,v.n+=1,s.set(g,v)}}else if(t.metric==="errors"){let u=this.queryEvents({app:t.app,since:e,limit:1e4});for(let d of u)(d.type==="error-new"||d.type==="error-recur")&&(a(d.ts),c++)}else{let u=this.queryEvents({app:t.app,since:e,limit:1e4});for(let d of u)d.type==="status"&&d.to_state==="starting"&&(d.from_state==="error"||d.from_state==="serving"||d.from_state==="compiling")&&(a(d.ts),c++)}let i=[],l=[...s.entries()].sort((u,d)=>u[0]-d[0]);for(let[u,d]of l)t.metric==="compile"||t.metric==="bundle"?i.push({t:u,v:Math.round(d.sum/d.n),...d.sum2!=null?{v2:Math.round(d.sum2/d.n)}:{}}):i.push({t:u,v:d.sum});return{points:i,count:c}}queryTimeline(t){if(!this.db)return[];let e=t.limit??5e3,n=t.since,s=t.kinds,o=[],a=!s||s.has("status"),c=!s||s.has("error"),i=!s||s.has("warning"),l=!s||s.has("lint"),u=!s||s.has("health"),d=!s||s.has("bundle"),g=!s||s.has("task"),v=!s||s.has("restart");if(a||c||i||l||u||v){let A=this.queryEvents({app:t.app,since:n,limit:e});for(let E of A){let C=null;if(E.type==="status"&&a?C="status":(E.type==="error-new"||E.type==="error-recur")&&c?C="error":(E.type==="warning-new"||E.type==="warning-recur")&&i?C="warning":(E.type==="lint-new"||E.type==="lint-recur")&&l?C="lint":E.type==="health"&&u?C="health":(E.type==="restart-scheduled"||E.type==="bundle-regression"||E.type==="compile-regression"||E.type==="stale"||E.type==="self-warn")&&v&&(C="restart"),!C)continue;let y=C==="status"?`${E.from_state??"?"} \u2192 ${E.to_state??"?"}`:E.message??E.type;o.push({ts:E.ts,app:E.app,kind:C,summary:y,payload:E})}}if(d){let A=this.queryBundles({app:t.app,since:n,limit:e});for(let E of A)o.push({ts:E.ts,app:E.app,kind:"bundle",summary:`initial ${E.initialKB}KB \xB7 lazy ${E.lazyKB}KB`,payload:E})}if(g){let A=this.queryCompiles({app:t.app,since:n,limit:e});for(let C of A)o.push({ts:C.ts,app:C.app,kind:"compile",summary:`compile ${(C.ms/1e3).toFixed(1)}s`,payload:C});let E=this.queryTasks({app:t.app,since:n,limit:e});for(let C of E){let y=C.duration_ms??0;o.push({ts:C.ts,app:C.app,kind:"task",summary:`${C.task} exit=${C.exit_code} ${(y/1e3).toFixed(1)}s`,payload:C})}}return o.sort((A,E)=>E.ts-A.ts),o.slice(0,e)}queryTasks(t){if(!this.db)return[];let e=[],n=[];t.app&&(e.push("app = ?"),n.push(t.app)),t.task&&(e.push("task = ?"),n.push(t.task)),t.since!=null&&(e.push("ts >= ?"),n.push(t.since));let s=`SELECT * FROM task_runs ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??200),this.db.prepare(s).all(...n)}summary(t){if(!this.db)return{uptimePct24h:0,restartCount24h:0,compileP50:null,compileP95:null,topErrors:[]};let e=Date.now()-24*3600*1e3,n=this.queryEvents({app:t,since:e,limit:5e3}),s=0,o=e,a=!1,c=null,i=[...n].sort((y,P)=>y.ts-P.ts);for(let y of i)y.type==="status"&&(y.to_state==="serving"&&!a?(a=!0,c=y.ts):a&&y.to_state!=="serving"&&c!=null&&(s+=y.ts-c,a=!1,c=null));a&&c!=null&&(s+=Date.now()-c);let l=Math.round(s/(24*3600*1e3)*1e3)/10,u=n.filter(y=>y.type==="status"&&y.to_state==="starting"&&(y.from_state==="serving"||y.from_state==="error"||y.from_state==="compiling")).length,d=this.queryCompiles({app:t,since:e,limit:1e3}).map(y=>y.ms).sort((y,P)=>y-P),g=(y,P)=>{if(y.length===0)return null;let I=Math.min(y.length-1,Math.floor((y.length-1)*P));return y[I]},v=g(d,.5),A=g(d,.95),E=new Map;for(let y of n)if(y.type==="error-new"||y.type==="error-recur"){let P=y.message??"";if(!P)continue;E.set(P,(E.get(P)??0)+1)}let C=[...E.entries()].sort((y,P)=>P[1]-y[1]).slice(0,5).map(([y,P])=>({message:y,count:P}));return{uptimePct24h:l,restartCount24h:u,compileP50:v,compileP95:A,topErrors:C}}why(t){let e=this.queryEvents({app:t,limit:200}),n=e.find(c=>c.type==="status"&&(c.to_state==="error"||c.from_state==="error"||c.to_state==="serving")),s=n?{ts:n.ts,app:n.app,type:n.type,from:n.from_state??void 0,to:n.to_state??void 0,message:n.message??void 0}:null,o=s?s.ts:Date.now(),a=e.filter(c=>c.ts<o).slice(0,5);return{trigger:s,preceding:a.map(c=>({ts:c.ts,app:c.app,type:c.type,from:c.from_state??void 0,to:c.to_state??void 0,message:c.message??void 0}))}}_flushForTest(){this.flush()}quickCheck(){if(!this.db)return!1;try{return this.db.prepare("PRAGMA quick_check").get()?.quick_check==="ok"}catch{return!1}}close(){if(this.flushTimer&&clearInterval(this.flushTimer),this.retentionTimer&&clearInterval(this.retentionTimer),this.retentionStart&&clearTimeout(this.retentionStart),this.flush(),this.db){try{this.db.pragma("wal_checkpoint(TRUNCATE)")}catch{}try{this.db.close()}catch{}this.db=null}}}});function he(r){return r?Yo[r]??null:null}function En(r){return r===200||r===301||r===302||r===304||r===307||r===308||r===401}function Rn(r){return r?r==="ECONNREFUSED"||r==="ECONNRESET"||r==="EHOSTUNREACH":!1}var Yo,rr=ut(()=>{"use strict";Yo={django:"/admin/login/",rails:"/up",fastapi:"/docs","go-air":"/","rust-trunk":"/"}});var Xt={};Ft(Xt,{ALL_AUTO_FIX:()=>An,runAutoFix:()=>yi});import F from"node:fs";import X from"node:path";function Vo(){let r=Rt();if(!r)return{detected:!1,description:"no daemon running"};let t=process.cwd(),e=X.join(t,"daimon.config.json");if(!F.existsSync(e))return{detected:!1,description:"no local daimon.config.json in cwd"};let n=r.cwd,s=r.configPath,o=n&&X.resolve(n)===X.resolve(t),a=s&&X.resolve(s)===X.resolve(e);return o||a?{detected:!1,description:"daemon already running from this cwd/config"}:{detected:!0,description:`daemon (pid ${r.pid}) is running from ${n??"(unknown)"} but local daimon.config.json exists at ${t}`,lockCwd:n}}async function Zo(){let r=Rt();if(!r)return"no daemon running; nothing to do";try{await fetch(`http://127.0.0.1:${r.apiPort}/api/snapshot-state`,{method:"POST"})}catch{}try{await fetch(`http://127.0.0.1:${r.apiPort}/api/shutdown`,{method:"POST"})}catch{}return await Vr(r.pid,5e3),Wt(),`respawned daemon at pid ${(await Je({})).pid} from ${process.cwd()}; previous pid ${r.pid} (cwd ${r.cwd??"unknown"}) was shut down with state handoff. To undo: stop with 'daimon daemon stop' and start from the prior directory.`}function Qo(){let r;try{r=F.readFileSync(oe(),"utf8")}catch{return{detected:!1,description:"no lock file present"}}let t;try{t=JSON.parse(r)}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 ti(){let r="(unknown)";try{let e=JSON.parse(F.readFileSync(oe(),"utf8"));r=String(e?.pid??"?")}catch{}Wt();let t=await Je({});return`removed stale ${oe()} (prior pid ${r} was dead); spawned fresh daemon at pid ${t.pid}.`}function ei(){let r=process.cwd(),e=["nx.json","angular.json","vite.config.ts","vite.config.js","vite.config.mjs","vite.config.cjs",".storybook"].filter(a=>F.existsSync(X.join(r,a)));if(!e.length)return{detected:!1,description:"no nx.json/angular.json/vite.config.*/.storybook in cwd"};let n=ct();return n.kind!=="loaded"?{detected:!0,description:`${e.join(", ")} present but no config is loaded`,markerFiles:e}:n.config.searchRoots.map(a=>X.resolve(typeof a=="string"?a:a.path)).some(a=>r.startsWith(a))?{detected:!1,description:`${e.join(", ")} present and a configured searchRoot covers ${r}`}:{detected:!0,description:`${e.join(", ")} present in ${r} but no searchRoot covers it`,markerFiles:e}}function ri(){let r=process.cwd(),{local:t,user:e}=yt(),n=F.existsSync(t)?t:e,s={};try{s=JSON.parse(F.readFileSync(n,"utf8"))}catch{}if(s.searchRoots=Array.isArray(s.searchRoots)?s.searchRoots:[],!s.searchRoots.some(a=>(typeof a=="string"?a:a?.path)===r)){let a;try{let c=JSON.parse(F.readFileSync(X.join(r,"package.json"),"utf8"));typeof c.name=="string"&&(a=c.name)}catch{}s.searchRoots.push(a?{path:r,label:a}:r)}F.mkdirSync(X.dirname(n),{recursive:!0}),F.writeFileSync(n,JSON.stringify(s,null,2)+`
|
|
53
|
+
`,"utf8");let o=Rt();if(o)try{fetch(`http://127.0.0.1:${o.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`appended ${r} as a searchRoot in ${n}; triggered soft-reload of the running daemon.`}function ni(){let r=ct();if(r.kind!=="loaded"||!r.config.history.enabled)return{detected:!1,description:"history disabled"};let t=r.config.history.path;if(!F.existsSync(t))return{detected:!1,description:"history db does not exist (will be created on next start)"};try{let e=new Lt(r.config.history),n=e.quickCheck();return e.close(),n?{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 si(){let r=ct();if(r.kind!=="loaded")return"no config; cannot determine history path";let t=r.config.history.path,e=`${t}.corrupt-${Date.now()}`;for(let n of["","-wal","-shm"])try{F.renameSync(t+n,e+n)}catch{}return`rotated ${t} \u2192 ${e} (and -wal/-shm siblings). The daemon will rebuild an empty history db on next start.`}async function oi(){let r=ct();if(r.kind!=="loaded")return{detected:!1,description:"no config loaded"};let[t,e]=r.config.portRange??[4200,4299],n=r.config.overrides??{},s=Object.values(n).map(c=>c.port).filter(c=>typeof c=="number"),o=Array.from(new Set([...s,t,e])),a=[];for(let c of o)if(!(!Number.isFinite(c)||c<=0))try{await Nt(c)||a.push(c)}catch{}return a.length?{detected:!0,description:`ports already LISTEN: ${a.join(", ")} (range ${t}-${e} + pinned overrides)`,conflicts:a}:{detected:!1,description:`all checked ports free (range ${t}-${e} + pinned)`}}function ii(){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 ai(){let r=process.cwd(),t=process.versions.node,e=X.join(r,".nvmrc");if(F.existsSync(e)){let s=F.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 n=X.join(r,"package.json");if(F.existsSync(n))try{let o=JSON.parse(F.readFileSync(n,"utf8"))?.engines?.node;if(typeof o=="string"&&o.trim()){let a=o.match(/(\d+)(?:\.(\d+))?/);if(a){let c=Number(a[1]),i=Number(t.split(".")[0]);if(Number.isFinite(c)&&Number.isFinite(i)&&i<c)return{detected:!0,description:`package.json engines.node = "${o}" but running ${t}`,expected:o,actual:t}}}}catch{}return{detected:!1,description:`node ${t} satisfies .nvmrc / engines.node (or neither is present)`}}function ci(){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 li(){let r=ct();if(r.kind!=="loaded")return[];let t=[],e=new Set;for(let n of r.config.searchRoots){let s=typeof n=="string"?n:n.path;if(!s||!F.existsSync(s)||e.has(s))continue;e.add(s);let o=X.join(s,"package.json");if(!F.existsSync(o))continue;let a=null;for(let c of["package-lock.json","pnpm-lock.yaml","yarn.lock"]){let i=X.join(s,c);if(F.existsSync(i)){a=i;break}}t.push({name:X.basename(s),root:s,pkgPath:o,lockPath:a,nmPath:X.join(s,"node_modules")})}return t}function Pn(){let r=li();if(!r.length)return{detected:!1,description:"no searchRoots with package.json found"};let t=[];for(let n of r){if(!F.existsSync(n.nmPath)){t.push({root:n.root,reason:"missing"});continue}if(n.lockPath)try{let s=F.statSync(n.lockPath).mtimeMs,o=F.statSync(n.nmPath).mtimeMs;s>o+1e3&&t.push({root:n.root,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`node_modules issues \u2014 ${t.map(n=>`${n.reason}: ${n.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every searchRoot package.json has a fresh node_modules"}}function ui(){let r=Pn();return!r.detected||!r.entries?"nothing to suggest":`would suggest: ${r.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 nr(){let r=ct();if(r.kind!=="loaded")return[];let t=[],e=new Set;for(let n of r.config.searchRoots){let s=typeof n=="string"?n:n?.path;!s||!F.existsSync(s)||e.has(s)||(e.add(s),t.push(s))}return t}function Cn(){let r=nr();if(!r.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let n of r){let s=X.join(n,"pyproject.toml"),o=X.join(n,"requirements.txt"),a=X.join(n,"manage.py");if(!(F.existsSync(s)||F.existsSync(o)||F.existsSync(a)))continue;let i=[".venv","venv","env"].map(u=>X.join(n,u)).find(u=>F.existsSync(u));if(!i){t.push({root:n,reason:"missing"});continue}let l=[];for(let u of[s,o])if(F.existsSync(u))try{l.push(F.statSync(u).mtimeMs)}catch{}if(l.length)try{let u=F.statSync(i).mtimeMs;Math.max(...l)>u+1e3&&t.push({root:n,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`venv issues \u2014 ${t.map(n=>`${n.reason}: ${n.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every Python searchRoot has a fresh venv (or no Python markers)"}}function pi(){let r=Cn();return!r.detected||!r.entries?"nothing to suggest":`would suggest: ${r.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 Mn(){let r=nr();if(!r.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let n of r){let s=X.join(n,"Gemfile");if(!F.existsSync(s))continue;let o=X.join(n,"Gemfile.lock"),a=X.join(n,"vendor","bundle"),c=X.join(n,".bundle"),i=F.existsSync(a)?a:F.existsSync(c)?c:null;if(!i){t.push({root:n,reason:"missing"});continue}if(F.existsSync(o))try{let l=F.statSync(o).mtimeMs,u=F.statSync(i).mtimeMs;l>u+1e3&&t.push({root:n,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`bundler cache issues \u2014 ${t.map(n=>`${n.reason}: ${n.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every Ruby searchRoot has a fresh bundle cache (or no Gemfile)"}}function di(){let r=Mn();return!r.detected||!r.entries?"nothing to suggest":`would suggest: ${r.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 On(){let r=nr();if(!r.length)return{detected:!1,description:"no searchRoots resolved on disk"};let t=[];for(let n of r){let s=X.join(n,"Cargo.toml");if(!F.existsSync(s))continue;let o=X.join(n,"Cargo.lock"),a=X.join(n,"target");if(!F.existsSync(a)){t.push({root:n,reason:"missing"});continue}if(F.existsSync(o))try{let c=F.statSync(o).mtimeMs,i=F.statSync(a).mtimeMs;c>i+1e3&&t.push({root:n,reason:"stale"})}catch{}}return t.length?{detected:!0,description:`cargo target issues \u2014 ${t.map(n=>`${n.reason}: ${n.root}`).join(" \xB7 ")}`,entries:t}:{detected:!1,description:"every Rust searchRoot has a fresh target/ (or no Cargo.toml)"}}function fi(){let r=On();return!r.detected||!r.entries?"nothing to suggest":`would suggest: ${r.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 Nn(){let r=ct();if(r.kind!=="loaded")return{detected:!1,description:"no config loaded"};let t=[];for(let e of r.config.searchRoots){let n=typeof e=="string"?e:e.path;n&&(F.existsSync(n)||t.push(n))}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 mi(){let r=Nn();if(!r.detected||!r.dead||!r.dead.length)return"nothing to remove";let{local:t,user:e}=yt(),n=F.existsSync(t)?t:e,s={};try{s=JSON.parse(F.readFileSync(n,"utf8"))}catch{}if(!Array.isArray(s.searchRoots))return"config has no searchRoots array; nothing removed";let o=new Set(r.dead),a=s.searchRoots.length;s.searchRoots=s.searchRoots.filter(l=>{let u=typeof l=="string"?l:l?.path;return!o.has(u)});let c=a-s.searchRoots.length;F.writeFileSync(n,JSON.stringify(s,null,2)+`
|
|
54
|
+
`,"utf8");let i=Rt();if(i)try{fetch(`http://127.0.0.1:${i.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`removed ${c} dead searchRoot entr${c===1?"y":"ies"} from ${n} (${[...o].join(", ")}); triggered soft-reload. To undo: edit ${n} and re-add the path(s).`}function $n(){let r=ct();if(r.kind!=="loaded")return{detected:!1,description:"no config loaded"};let t=Et(r.config,{}),e=r.config.overrides??{},n=[];for(let o of t){if(!o.serverProfile)continue;let a=o.baseName??o.name;if(e[o.name]?.healthProbePath??e[a]?.healthProbePath)continue;let i=he(o.serverProfile);!i||i==="/"||n.push({name:o.name,profile:o.serverProfile,path:i})}return n.length?{detected:!0,description:`apps missing a profile-aware health probe path: ${n.map(o=>`${o.name} (${o.profile} \u2192 ${o.path})`).join(" \xB7 ")}`,entries:n}:{detected:!1,description:"every app with a known framework profile already has a probe path resolved"}}function hi(){let r=$n();if(!r.detected||!r.entries)return"nothing to set";let{local:t,user:e}=yt(),n=F.existsSync(t)?t:e,s={};try{s=JSON.parse(F.readFileSync(n,"utf8"))}catch{}(!s.overrides||typeof s.overrides!="object")&&(s.overrides={});let o=[];for(let c of r.entries)(!s.overrides[c.name]||typeof s.overrides[c.name]!="object")&&(s.overrides[c.name]={}),!s.overrides[c.name].healthProbePath&&(s.overrides[c.name].healthProbePath=c.path,o.push(`${c.name} \u2192 ${c.path}`));if(!o.length)return"every detected app already had a healthProbePath in overrides; nothing changed.";F.mkdirSync(X.dirname(n),{recursive:!0}),F.writeFileSync(n,JSON.stringify(s,null,2)+`
|
|
55
|
+
`,"utf8");let a=Rt();if(a)try{fetch(`http://127.0.0.1:${a.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`wrote healthProbePath to overrides in ${n} for: ${o.join(", ")}; triggered soft-reload. To undo: edit ${n}.`}async function yi(r){let t={ran:[],skipped:[],errors:[]};for(let e of An){if(!r.permitted.includes(e))continue;let n=gi[e],s;try{s=await n.detect()}catch(o){t.errors.push({name:e,error:o?.message??String(o)});continue}if(!s.detected){t.skipped.push({name:e,detected:!1,description:s.description});continue}if(r.dryRun){t.ran.push({name:e,detected:!0,description:`(dry-run) would fix: ${s.description}`});continue}try{let o=await n.fix();t.ran.push({name:e,detected:!0,description:`${s.description} \u2014 ${o}`})}catch(o){t.errors.push({name:e,error:o?.message??String(o)})}}return t}var An,gi,Kt=ut(()=>{"use strict";At();Ht();er();Qt();Mt();rr();An=["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root","health-probe-missing"];gi={"orphan-daemon":{detect:Vo,fix:Zo},"stale-lock":{detect:Qo,fix:ti},"missing-search-root":{detect:ei,fix:ri},"corrupt-history-db":{detect:ni,fix:si},"port-conflict-pred":{detect:oi,fix:ii},"node-version-mismatch":{detect:ai,fix:ci},"orphan-node-modules":{detect:Pn,fix:ui},"orphan-venv":{detect:Cn,fix:pi},"orphan-bundler-cache":{detect:Mn,fix:di},"orphan-cargo-target":{detect:On,fix:fi},"dead-search-root":{detect:Nn,fix:mi},"health-probe-missing":{detect:$n,fix:hi}}});var sr={};Ft(sr,{orchestrateProfile:()=>vi});function _n(r,t,e,n,s){let o=r.summary(t);if(!o)return!1;if(e==="serving")return o.status==="serving";if(e==="healthy")return o.status==="serving"&&o.health==="healthy";let a=Date.now()-n;return o.status==="serving"&&o.health==="healthy"&&a>=s}async function Ln(r,t,e,n,s){let o=Date.now();if(e!=="stable"){let i=await r.waitFor(t,e==="serving"?"serving":"healthy",n);return{reached:!i.timedOut,waitedMs:i.waitedMs}}let a=Date.now(),c=i=>{i?.app===t&&(a=Date.now())};r.on("event",c);try{for(;Date.now()-o<n;){if(_n(r,t,e,a,s))return{reached:!0,waitedMs:Date.now()-o};await new Promise(i=>setTimeout(i,500))}return{reached:_n(r,t,e,a,s),waitedMs:Date.now()-o}}finally{r.off("event",c)}}async function vi(r,t,e){let n=Date.now(),s=t.profiles?.[e.profile];if(!s)return{error:`unknown profile: ${e.profile}`};let o=s.filter(C=>r.summary(C)!=null),a=Array.from(new Set(o.flatMap(C=>ee(t.depends??{},C)))).filter(C=>r.summary(C)!=null),c=re(t.depends??{},a),i=[];for(let C of a){let y=r.summary(C);y&&(e.goal==="serving"&&y.status==="serving"||(e.goal==="healthy"||e.goal==="stable")&&y.status==="serving"&&y.health==="healthy")&&i.push(C)}if(e.dryRun){let C=a.filter(y=>!i.includes(y));return{profile:e.profile,goal:e.goal,perApp:C.map(y=>({name:y,reached:!1,tries:0})),totalMs:Date.now()-n,allReached:C.length===0,dryRun:!0,plannedOrder:c,alreadyHealthy:i}}let l=Math.max(5e3,Math.floor(e.timeoutMs/2)),u=e.stableMs??5e3,d=new Map;for(let C of a)d.set(C,{name:C,reached:!1,tries:0});for(let C of c)await Promise.all(C.map(async y=>{let P=r.summary(y);if(!P){d.set(y,{name:y,reached:!1,tries:0,error:"unknown app"});return}if(i.includes(y)){d.set(y,{name:y,reached:!0,tries:0});return}P.status!=="starting"&&P.status!=="compiling"&&P.status!=="serving"&&await r.start(y)})),await Promise.all(C.map(async y=>{if(d.get(y)?.reached)return;let P=await Ln(r,y,e.goal,l,u),I=d.get(y);I.tries=1,I.waitedMs=P.waitedMs,I.reached=P.reached,d.set(y,I)}));let g=[...d.values()].filter(C=>!C.reached);if(g.length>0){let{runAutoFix:C,ALL_AUTO_FIX:y}=await Promise.resolve().then(()=>(Kt(),Xt)),P=t.doctor?.autoFix?.permitted??y,I=Math.max(5e3,e.timeoutMs-(Date.now()-n)),J=Math.max(5e3,Math.floor(I/Math.max(g.length,1))),S={ran:[]};try{S=await C({permitted:P,dryRun:!1})}catch{}let Q=(S.ran??[]).map(Y=>Y.name);await Promise.all(g.map(async Y=>{let z=d.get(Y.name);z.tries=2;try{let f=await r.restart(Y.name);f?.ok||(z.error=f?.error??"restart failed")}catch(f){z.error=f?.message??String(f)}let p=await Ln(r,Y.name,e.goal,J,u);if(z.waitedMs=(z.waitedMs??0)+p.waitedMs,z.reached=p.reached,!z.reached){let f=r.errors(Y.name)??[];z.stillFailing=f.slice(0,3).map(h=>({file:h.parsed?.file??null,line:h.parsed?.line??null,code:h.parsed?.code??null,tool:h.parsed?.tool??null,message:h.parsed?.message??h.message}))}z.fixed=Q,d.set(Y.name,z)}))}let v=[...d.values()],A=v.every(C=>C.reached),E={profile:e.profile,goal:e.goal,perApp:v,totalMs:Date.now()-n,allReached:A};if(typeof e.budgetTokens=="number"&&e.budgetTokens>0){let C=e.budgetTokens,y=0,P=0;for(let I of v)if(I.stillFailing){let J=I.stillFailing.length*bi;J>C?(y+=I.stillFailing.length,delete I.stillFailing):C-=J}for(;C<0||v.length*wi>Math.max(C,e.budgetTokens/4);){let I=v.findIndex(J=>J.reached);if(I===-1)break;v.splice(I,1),P++}(y||P)&&(E._meta={omitted:{}},y&&(E._meta.omitted.stillFailing=y),P&&(E._meta.omitted.perApp=P))}return E}var bi,wi,or=ut(()=>{"use strict";ne();bi=60,wi=25});Ht();Mt();import Na from"react";import $a from"node:path";import{render as _a}from"ink";import{pathToFileURL as La}from"node:url";import{EventEmitter as To}from"node:events";import Ie from"node:path";function Cr(r){let t=Ie.resolve(r);return process.platform==="win32"?t.toLowerCase():t}function ft(r,t){let e=Cr(r),n=Cr(t);if(e===n)return!0;let s=n.endsWith(Ie.sep)?n:n+Ie.sep;return e.startsWith(s)}import{spawn as Xs}from"node:child_process";import _r from"tree-kill";import Ks from"strip-ansi";import bs from"node:crypto";var ws=[/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],vs=[/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],Ss=[/^\s+\d+:\d+\s{2,}(?:warning|error)\s{2,}\S/i,/\blint\/[a-z][a-z0-9-]+\/[a-z][a-zA-Z0-9-]+\b/,/^\s*\S+\.py:\d+:\d+:\s+[A-Z]\d{3,}\b/,/^warning:\s.*clippy::/i,/^\s*=\s+note:\s+`#\[warn\(clippy::/],ks=[/^\s*(?:▲\s*)?\[WARNING\]/,/\bwarning TS\d+/i,/^\s*\[(?:warning|warn)\]\s+/i,/^\s*warning\s+\S+\s+is\s+/i,/^\s*\S+:\d+:\s*(?:Deprecation|User|Future|Pending|Resource|Runtime|Syntax)Warning:/,/^WARNING in\s+/,/^\s*\[vite\]\s+warning/i],xs=[/^\s*ERROR\b/,/\berror TS\d+/,/✘/,/\[ERROR\]/,/Cannot find module/i,/^FAIL\s+\S+/,/^\s*●\s+/,/^\s*(?:>\s+)?NX\s+.*failed/i,/^\s*Failed tasks:/,/^\s*Task\s+"[^"]+"\s+is continuous but exited with code\s+\d+/,/\bModule not found:/,/\[vite\]\s+(?:Internal server error|Pre-transform error)/i,/\[plugin:[^\]]+\]/i,/^\s*ERR!\s+/,/^\s*(?:Uncaught\s+)?(?:Error|TypeError|SyntaxError|ReferenceError|RangeError):\s+/,/^Traceback \(most recent call last\):/,/^\s*[A-Z][a-zA-Z]*Error:\s+/,/^\s*\[error\]\s+/i,/^panic:\s+/,/^thread\s+'[^']+'\s+panicked at/,/^error\[E\d+\]:/,/^\S+\.(?:go|rb|py|rs):\d+:\d+:/,/^\s*[A-Z][a-zA-Z]*\.[A-Z][a-zA-Z]*:\s+/,/^[A-Z][a-zA-Z]+(?:::[A-Z][a-zA-Z]+)+\s*[(:]/,/^[A-Z][a-zA-Z]*Error\s*\(/],Ts=/\berror TS(\d+)/,Es=/✘\s*\[ERROR\]\s*TS(\d+)/,Rs=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte|py|rb|go|rs)):(\d+):(\d+)/,Mr=/\(([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte|py|rb|go|rs)):(\d+):(\d+)\)/,As=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte))\((\d+),(\d+)\)\s*:/,Or=/File\s+"([^"]+\.py)",\s+line\s+(\d+)/,Nr=/^\s*-->\s+([^\s:]+\.rs):(\d+):(\d+)/,Ps=/^([^\s:()]+\.rb):(\d+):in\b/,Cs=/^FAIL\s+(\S+\.(?:tsx?|jsx?|mjs|cjs))(?:\s|$)/,Ms=/^ERROR in\s+(\S+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte))(?:[:\s](\d+):(\d+))?/,Os=/^\s+([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte)):(\d+):(\d+):?\s*$/,Ns=[{tool:"vite",rx:/\[vite\]|\[plugin:vite:|transformWithEsbuild/i},{tool:"storybook",rx:/\bstorybook\b|^\s*ERR!\s|builder-vite/i},{tool:"jest",rx:/^FAIL\s|^\s*●\s+|\bjest\b/i},{tool:"nx",rx:/(?:>\s+)?NX\s+(?:\w|.*failed)|Failed tasks:|Nx errored|exited with code\s+\d+/i},{tool:"webpack",rx:/\bModule not found:|webpack compiled|webpack-dev-server/i},{tool:"esbuild",rx:/✘\s*\[ERROR\]|esbuild/i},{tool:"typescript",rx:/\berror TS\d+/},{tool:"django",rx:/\bdjango\b|StatReloader|manage\.py runserver/i},{tool:"rails",rx:/\brails\b|Puma starting|Booting (?:Puma|Rails)|ActionController|NameError\s*\(|\.rb:\d+:in/i},{tool:"fastapi",rx:/\buvicorn\b|fastapi|ASGI/i},{tool:"go-air",rx:/\bair v\d|building\.{3}|\.go:\d+:\d+/i},{tool:"rust-trunk",rx:/\btrunk\b|^error\[E\d+\]|^\s*-->\s+\S+\.rs:/i},{tool:"python",rx:/^Traceback \(most recent call last\):|^\s*File "[^"]+\.py"|[A-Z][a-zA-Z]*Error:\s/},{tool:"node",rx:/^\s*(?:Uncaught\s+)?(?:Error|TypeError|SyntaxError|ReferenceError|RangeError):/}];function $s(r){for(let{tool:t,rx:e}of Ns)if(e.test(r))return t}var _s=/Local:\s+(https?:\/\/\S+)/i,Ls=/Server running at\s+(https?:\/\/\S+)/i,js=/listening on\s+(https?:\/\/\S+)/i,Ds=/(?:listening|listen)\s+(https?:\/\/\S+)/i,Is=/Initial chunk files/i,Fs=/Lazy chunk files/i,Bs=/(Initial total|Lazy total)\s*\|?\s*([\d.]+)\s*(kB|MB|B)\b/i,Hs=/^\s*\|?\s*([^\s|][^|]*?)\s*\|\s*([^|]+?)\s*\|\s*([\d.]+)\s*(kB|MB|B)\b/i;function Us(r){return bs.createHash("sha1").update(r).digest("hex").slice(0,16)}function Ws(r){let t={message:r},e=r.match(Es)||r.match(Ts);e&&(t.code=`TS${e[1]}`);let n=r.match(As)||r.match(Mr)||r.match(Rs);if(n)t.file=n[1],t.line=Number(n[2]),t.col=Number(n[3]);else{let o=r.match(Ms);if(o)t.file=o[1],o[2]&&(t.line=Number(o[2])),o[3]&&(t.col=Number(o[3]));else{let a=r.match(Cs);if(a)t.file=a[1];else{let c=r.match(Nr);if(c)t.file=c[1],t.line=Number(c[2]),t.col=Number(c[3]);else{let i=r.match(Or);i&&(t.file=i[1],t.line=Number(i[2]))}}}}let s=$s(r);return s&&(t.tool=s),t}function qs(r,t){try{let e=new URL(r);return e.hostname==="0.0.0.0"||e.hostname==="[::]"?(e.hostname=t.includes(":")?`[${t}]`:t,e.toString().replace(/\/$/,"")):r.replace(/\/$/,"")}catch{return r}}function Gs(r,t="127.0.0.1"){let e=r.match(_s)||r.match(Ls)||r.match(js)||r.match(Ds);if(!e)return null;let n=e[1].replace(/[),.;]+$/,"");return qs(n,t)}function Js(r,t){if(Is.test(t))return r.bundle||(r.bundle={initialKB:0,lazyKB:0,files:[]}),r._bundleSection="initial",!1;if(Fs.test(t))return r.bundle||(r.bundle={initialKB:0,lazyKB:0,files:[]}),r._bundleSection="lazy",!1;let e=t.match(Bs);if(e&&r.bundle){let s=parseFloat(e[2]),o=e[3].toUpperCase(),a=Math.round(o==="MB"?s*1024:o==="B"?s/1024:s);return/Initial/i.test(e[1])?r.bundle.initialKB=a:r.bundle.lazyKB=a,!0}let n=t.match(Hs);if(n&&r.bundle){let s=n[1].trim();if(/^(Initial|Lazy)\s+(total|chunk)/i.test(s))return!1;let o=n[4].toUpperCase(),a=parseFloat(n[3]),c=o==="MB"?a*1024:o==="B"?a/1024:a;return r.bundle.files.push({name:s,sizeKB:Math.round(c*10)/10}),!1}return!1}function $r(r,t){let e=t.match(Os),n=e?null:t.match(Mr),s=!e&&!n?t.match(Nr):null,o=e??n??s;if(o&&r.lastErrorHash){let y=r.errors.get(r.lastErrorHash);y&&!y.parsed?.file&&(y.parsed={...y.parsed??{message:y.message},file:o[1],line:Number(o[2]),col:Number(o[3])})}else if(r.lastErrorHash){let y=t.match(Or),P=y?null:t.match(Ps);if(y||P){let I=r.errors.get(r.lastErrorHash);if(I&&!I.parsed?.file){let J=y??P;I.parsed={...I.parsed??{message:I.message},file:J[1],line:Number(J[2])}}}}let a=t.trim();if(!a)return null;let c=r.status,i=!1,l,u=Gs(a);u&&!r.announcedUrl&&(r.announcedUrl=u,l=u);let d=Js(r,a),g;if(ws.some(y=>y.test(a))){let y=r.status==="error"||!!r.recoveringFromError;if(r.status==="compiling"||r.status==="starting"||r.status==="error"){let P=Date.now();r.compileStartedAt!=null?(g=P-r.compileStartedAt,r.lastCompileMs=g,r.lastCompileAt=P,r.compileStartedAt=null,r.compileHistory.push(g),r.compileHistory.length>20&&r.compileHistory.splice(0,r.compileHistory.length-20)):r.lastCompileAt=P}r.status="serving",y&&(r.errors.clear(),r.recoveringFromError=!1)}else vs.some(y=>y.test(a))&&(r.status==="starting"||r.status==="serving"||r.status==="error")&&(r.status==="error"&&(r.recoveringFromError=!0),r.compileStartedAt=Date.now(),r.status="compiling");let v,A=Ss.some(y=>y.test(t)),E=!A&&xs.some(y=>y.test(a)),C=!A&&!E&&ks.some(y=>y.test(a));if(E||C||A){let y=Us(a),P=Date.now(),I=r.errors.get(y),J=!1,S;I?(I.count+=1,I.lastSeen=P,S=I):(S={message:a,count:1,firstSeen:P,lastSeen:P,parsed:Ws(a),level:A?"lint":C?"warning":"error"},r.errors.set(y,S),J=!0),r.lastErrorHash=y,v={entry:S,isNew:J},E&&(r.status="error")}return i=r.status!==c,{statusChanged:i,error:v,announcedUrl:l,bundleUpdated:d,compileMs:g}}var Lr=500,Zt=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:n}=this.deps,s=Date.now();n.status="starting",n.startedAt=s,n.compileStartedAt=s,n.lastCompileMs=null,n.lastCompileAt=null,n.errors.clear(),n.logBuffer.length=0,n.lastStatusMessage=void 0;let a=`${this.deps.commandOverride||t.command} --port ${e}`,c={...process.env,...t.env||{},...this.deps.envOverride||{},PORT:String(e),FORCE_COLOR:"0"},i=Xs(a,[],{cwd:t.workspaceRoot,shell:!0,env:c,windowsHide:!0});this.child=i,n.pid=i.pid??null,n.port=e,i.stdout?.on("data",l=>this.handleChunk(l,"stdout")),i.stderr?.on("data",l=>this.handleChunk(l,"stderr")),i.on("exit",(l,u)=>{let d=n.status,g=this.stopping;g?(n.status="stopped",n.lastStatusMessage=`stopped (code=${l??"null"}${u?`, ${u}`:""})`):l!==0?(n.status="error",n.lastStatusMessage=`process exited with code ${l}${u?` (${u})`:""}`):n.status="stopped",n.pid=null,n.health="unknown",this.child=null,this.stopping=!1,d!==n.status&&this.deps.onStatusChange?.(d,n.status,n.lastStatusMessage),this.deps.onExit?.(l,u,g),this.deps.onStateChange()}),i.on("error",l=>{n.status="error",n.lastStatusMessage=`spawn error: ${l.message}`,this.deps.onStateChange()}),this.deps.onStateChange()}handleChunk(t,e){let n=t.toString("utf8"),s=this[e==="stdout"?"stdoutBuf":"stderrBuf"]+=n,o=s.lastIndexOf(`
|
|
56
|
+
`);if(o<0)return;let a=s.slice(0,o),c=s.slice(o+1);e==="stdout"?this.stdoutBuf=c:this.stderrBuf=c;let{state:i}=this.deps,l=!1;for(let u of a.split(/\r?\n/)){if(!u.length)continue;let d=Ks(u),g=Date.now();i.lastLogTs=g,i.stale&&(i.stale=!1),i.logBuffer.push({ts:g,line:d}),i.logBuffer.length>Lr&&i.logBuffer.splice(0,i.logBuffer.length-Lr),this.deps.onLogLine?.(d);let v=i.status,A=$r(i,d);A?.statusChanged&&(l=!0,this.deps.onStatusChange?.(v,i.status)),A?.error&&this.deps.onErrorRecorded?.(A.error.entry,A.error.isNew),A?.compileMs!=null&&this.deps.onCompile?.(A.compileMs),A?.bundleUpdated&&this.deps.onBundleUpdate?.()}(l||a.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 n=!1,s=()=>{n||(n=!0,e())},o=()=>s();this.child?.once("exit",o),_r(t,"SIGTERM",()=>{});let a=setTimeout(()=>{_r(t,"SIGKILL",()=>{})},2e3),c=setTimeout(()=>{clearTimeout(a),s()},3e3);this.child?.once("exit",()=>{clearTimeout(a),clearTimeout(c),s()})})}};Qt();import mt from"node:fs";import Ys from"node:path";var te=class{constructor(t,e){this.appName=t;this.cfg=e;this.filePath=Ys.join(e.dir,`${t}.log`),this.open()}appName;cfg;fd=null;bytes=0;warned=!1;filePath;open(){try{mt.mkdirSync(this.cfg.dir,{recursive:!0});try{this.bytes=mt.statSync(this.filePath).size}catch{this.bytes=0}this.fd=mt.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}
|
|
57
|
+
`,n=Buffer.from(e,"utf8");mt.writeSync(this.fd,n),this.bytes+=n.length,this.bytes>=this.cfg.maxBytesPerFile&&this.rotate()}catch(e){this.warn(`write failed: ${e.message}`)}}close(){if(this.fd!=null){try{mt.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}`,n=`${this.filePath}.${t+1}`;if(t+1>this.cfg.maxFiles-1){try{mt.rmSync(e,{force:!0})}catch{}continue}try{mt.existsSync(e)&&mt.renameSync(e,n)}catch{}}try{let t=`${this.filePath}.1`;mt.existsSync(this.filePath)&&mt.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}
|
|
58
|
+
`))}};ne();import{spawn as Fr}from"node:child_process";import Ir from"tree-kill";import Br from"strip-ansi";var Vs=/Tests:\s+(?:(\d+)\s+failed,\s+)?(?:(\d+)\s+skipped,\s+)?(\d+)\s+passed(?:,\s+(\d+)\s+total)?/,Zs=/Test Suites:\s+(?:(\d+)\s+failed,\s+)?(\d+)\s+passed(?:,\s+(\d+)\s+total)?/,Qs=/Executed (\d+) of (\d+)(?:\s*\((\d+)\s*FAILED\))?/,to=/(\d+)\s+passed(?:.*?(\d+)\s+failed)?/i,eo=/Tests\s+(?:(\d+)\s+failed\s*\|\s*)?(\d+)\s+passed(?:\s*\((\d+)\))?/,ro=/Test Files\s+(?:(\d+)\s+failed\s*\|\s*)?(\d+)\s+passed(?:\s*\((\d+)\))?/,no=/(?:(\d+)\s+failed,\s+)?(\d+)\s+passed(?:,\s+\d+\s+skipped)?\s+in\s+([\d.]+)s/,so=/(\d+)\s+examples?,\s+(\d+)\s+failures?/,oo=/^(ok|FAIL|---\s+FAIL)\s+\S+\s+([\d.]+)s/,io=/test result:\s*(?:ok|FAILED)\.\s+(\d+)\s+passed;\s+(\d+)\s+failed/,ao=/^\s*✕\s+(.+?)(?:\s+\((\d+)\s*ms\))?$/,co=/^\s*FAIL\s+(\S+\.(?:tsx?|jsx?|mjs|cjs|spec\.[a-z]+))/,lo=/^FAILED\s+(\S+)::([^\s]+)/;function Fe(r){let t=[],e;for(let n of r.split(/\r?\n/)){let s=n.match(co);if(s){e=s[1];continue}let o=n.match(ao);if(o){t.push({name:o[1].trim(),file:e});continue}let a=n.match(lo);if(a){t.push({name:a[2],file:a[1]});continue}}return t.slice(0,50)}function uo(r){let t=r.match(Vs);if(t){let g=t[1]?Number(t[1]):0,v=Number(t[3]),A=t[4]?Number(t[4]):v+g,E=r.match(Zs);return{passed:v,failed:g,total:A,suites:E?Number(E[3]??E[2]):void 0,framework:"jest",failedTests:g>0?Fe(r):void 0}}let e=r.match(eo);if(e){let g=e[1]?Number(e[1]):0,v=Number(e[2]),A=e[3]?Number(e[3]):v+g,E=r.match(ro);return{passed:v,failed:g,total:A,suites:E?Number(E[3]??E[2]):void 0,framework:"vitest",failedTests:g>0?Fe(r):void 0}}let n=r.match(Qs);if(n){let g=Number(n[1]),v=Number(n[2]),A=n[3]?Number(n[3]):0;return{passed:g-A,failed:A,total:v,framework:"karma"}}let s=r.match(to);if(s&&/playwright/i.test(r)){let g=Number(s[1]),v=s[2]?Number(s[2]):0;return{passed:g,failed:v,total:g+v,framework:"playwright"}}let o=r.match(no);if(o){let g=o[1]?Number(o[1]):0,v=Number(o[2]);return{passed:v,failed:g,total:v+g,durationMs:Math.round(Number(o[3])*1e3),framework:"pytest",failedTests:g>0?Fe(r):void 0}}let a=r.match(so);if(a){let g=Number(a[1]),v=Number(a[2]);return{passed:g-v,failed:v,total:g,framework:"rspec"}}let c=r.match(io);if(c){let g=Number(c[1]),v=Number(c[2]);return{passed:g,failed:v,total:g+v,framework:"cargo"}}let i=0,l=0,u=0,d=!1;for(let g of r.split(/\r?\n/)){let v=g.match(oo);v&&(d=!0,u+=Math.round(Number(v[2])*1e3),v[1]==="ok"?i++:l++)}if(d)return{passed:i,failed:l,total:i+l,durationMs:u,framework:"go"};if(s){let g=Number(s[1]),v=s[2]?Number(s[2]):0;return{passed:g,failed:v,total:g+v,framework:"playwright"}}return null}function Hr(r,t,e){let n=e.length?" -- "+e.join(" "):"";return r.workspaceType==="nx"?`npx nx run ${r.name}:${t}${n}`:r.workspaceType==="angular"?`npx ng run ${r.name}:${t}${n}`:`npx ${t}${n}`}function Ur(r,t,e=[]){return new Promise(n=>{let s=Date.now(),o=Hr(r,t,e),a=Fr(o,[],{cwd:r.workspaceRoot,shell:!0,env:{...process.env,...r.env||{},FORCE_COLOR:"0"},windowsHide:!0}),c=[],i="",l=u=>{i+=u.toString("utf8");let d=i.lastIndexOf(`
|
|
59
|
+
`);if(d<0)return;let g=i.slice(0,d);i=i.slice(d+1);for(let v of g.split(/\r?\n/)){if(!v.length)continue;let A=Br(v);c.push(A),c.length>1e3&&c.splice(0,c.length-1e3)}};a.stdout?.on("data",l),a.stderr?.on("data",l),a.on("exit",u=>{let d=Date.now()-s,g=c.join(`
|
|
60
|
+
`)+(i?`
|
|
61
|
+
`+i:""),v=uo(g);n({app:r.name,task:t,exitCode:u,durationMs:d,summary:v,outputTail:c.slice(-50)})}),a.on("error",()=>{n({app:r.name,task:t,exitCode:-1,durationMs:Date.now()-s,summary:null,outputTail:[...c,"[daimon] task spawn error"]})})})}function Wr(r,t,e=[]){let n=Hr(r,t,e),s=Fr(n,[],{cwd:r.workspaceRoot,shell:!0,env:{...process.env,...r.env||{},FORCE_COLOR:"0"},windowsHide:!0}),o=[],a="",c=l=>{a+=l.toString("utf8");let u=a.lastIndexOf(`
|
|
62
|
+
`);if(u<0)return;let d=a.slice(0,u);a=a.slice(u+1);for(let g of d.split(/\r?\n/))g.length&&(o.push(Br(g)),o.length>500&&o.splice(0,o.length-500))};return s.stdout?.on("data",c),s.stderr?.on("data",c),{app:r.name,task:t,pid:s.pid??null,child:s,startedAt:Date.now(),logs:o,stop:()=>new Promise(l=>{if(!s.pid){l();return}let u=!1,d=()=>{u||(u=!0,l())};s.once("exit",d),Ir(s.pid,"SIGTERM",()=>{}),setTimeout(()=>{s.pid&&Ir(s.pid,"SIGKILL",()=>{})},2e3),setTimeout(d,3500)})}}import{spawnSync as Be}from"node:child_process";import hc from"tree-kill";function qr(r){if(process.platform==="win32"){let o=Be("powershell",["-NoProfile","-Command",`Get-NetTCPConnection -LocalPort ${r} -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty OwningProcess`],{encoding:"utf8",windowsHide:!0});if(o.status!==0)return null;let a=Number((o.stdout||"").trim().split(/\s+/)[0]);if(!Number.isFinite(a)||a<=0)return null;let c=Be("powershell",["-NoProfile","-Command",`Get-CimInstance Win32_Process -Filter "ProcessId=${a}" | Select-Object -Property Name,CommandLine | ConvertTo-Json -Compress`],{encoding:"utf8",windowsHide:!0}),i,l;try{let u=JSON.parse((c.stdout||"").trim()||"{}");i=typeof u.Name=="string"?u.Name:void 0,l=typeof u.CommandLine=="string"?u.CommandLine:void 0}catch{}return{pid:a,name:i,cmd:l}}let t=Be("lsof",["-nP","-iTCP:"+r,"-sTCP:LISTEN"],{encoding:"utf8"});if(t.status!==0)return null;let e=(t.stdout||"").split(/\r?\n/).filter(o=>o.trim()&&!o.startsWith("COMMAND"));if(!e.length)return null;let n=e[0].split(/\s+/);return{pid:Number(n[1]),name:n[0]}}function Gr(r,t){if(!t)return`port ${r} already in use`;let e=[`port ${r} 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 Xr from"node:fs";import Jr from"node:path";function Kr(r){let t={},e;try{e=Xr.readFileSync(r,"utf8")}catch{return t}for(let n of e.split(/\r?\n/)){let s=n.trim();if(!s||s.startsWith("#"))continue;let o=s.indexOf("=");if(o<0)continue;let a=s.slice(0,o).trim(),c=s.slice(o+1).trim();(c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'"))&&(c=c.slice(1,-1)),a&&(t[a]=c)}return t}function He(r,t){return Jr.isAbsolute(t)?t:Jr.join(r,t)}function Ue(r,t){return t.filter(e=>Xr.existsSync(He(r,e)))}At();import wo from"node:fs";import vo from"node:path";function So(){return vo.join(wt(),"secrets.json")}function Qr(){try{let r=wo.readFileSync(So(),"utf8");r.charCodeAt(0)===65279&&(r=r.slice(1));let t=JSON.parse(r);if(!t||typeof t!="object")return{};let e={};for(let[n,s]of Object.entries(t))typeof s=="string"&&(e[n]=s);return e}catch{return{}}}function tn(r,t){let e={};for(let[n,s]of Object.entries(r))e[n]=s.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,(o,a)=>t[a]??`\${${a}}`);return e}import Xe from"node:fs";import ko from"node:os";import en from"node:path";var ie=class{file=null;startTs=0;isRecording(){return this.file!=null}start(){if(this.file)return{path:this.file};let t=en.join(ko.homedir(),".daimon","sessions");Xe.mkdirSync(t,{recursive:!0});let e=en.join(t,`${new Date().toISOString().replace(/[:.]/g,"-")}.jsonl`);return Xe.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})+`
|
|
63
|
+
`;try{Xe.appendFileSync(this.file,e)}catch{}}};import{execFileSync as xo}from"node:child_process";function rn(r,t,e=2){if(r.length<10)return null;let n=[...r].sort((a,c)=>a-c),s=n[Math.floor((n.length-1)*.5)];if(s<=0)return null;let o=t/s;return o<e?null:{kind:"compile",factor:Math.round(o*100)/100,baseline:s,current:t}}function nn(r,t,e=1.1){if(r==null||r<=0)return null;let n=t/r;return n<e?null:{kind:"bundle",factor:Math.round(n*100)/100,baseline:r,current:t}}function Ke(r){if(!r)return null;try{let t=xo("git",["log","-1","--format=%h:%s"],{cwd:r,stdio:["ignore","pipe","ignore"],timeout:1500,maxBuffer:4096}).toString("utf8").trim();return t?t.slice(0,160):null}catch{return null}}var sn=500,ae=class extends To{entries=new Map;portAlloc;config;eventBuffer=[];history=null;watchTasks=new Map;sessionRecorder=new ie;constructor(t,e,n){super(),this.config=t,this.portAlloc=n??new Ot(t.portRange);for(let s of e)this.entries.set(s.name,{app:s,state:this.freshState(s.name,s.baseName??s.name,s.tags,s.workspaceLabel??null,s.workspaceRoot??null),proc:null})}getConfig(){return this.config}addDiscoveredApp(t){this.entries.has(t.name)||(this.entries.set(t.name,{app:t,state:this.freshState(t.name,t.baseName??t.name,t.tags,t.workspaceLabel??null,t.workspaceRoot??null),proc:null}),this.emit("change"))}updateDiscoveredApp(t){let e=this.entries.get(t.name);e&&(e.app=t,e.state.tags=t.tags,e.state.workspaceLabel=t.workspaceLabel??null,e.state.workspaceRoot=t.workspaceRoot??null,e.state.baseName=t.baseName??t.name,e.state.dependsOn=this.config.depends?.[t.baseName??t.name]??[],this.emit("change"))}getPortAllocator(){return this.portAlloc}setHistory(t){this.history=t}getHistory(){return this.history}freshState(t,e,n,s=null,o=null){return{name:t,status:"stopped",port:null,pid:null,startedAt:null,compileStartedAt:null,lastCompileMs:null,lastCompileAt:null,logBuffer:[],errors:new Map,compileHistory:[],health:"unknown",lastHealthAt:null,cpu:null,memMB:null,restartAttempts:0,restartWindowStart:null,nextRestartAt:null,tags:n,announcedUrl:null,lastHealthError:null,cachedProbeHost:null,lastLogTs:null,stale:!1,bundle:null,bundleRegressionPct:null,activeEnvFile:null,sessionOverrides:null,dependsOn:this.config.depends?.[e]??[],workspaceLabel:s,workspaceRoot:o,baseName:e,discoveredHealthPath:null}}names(){return[...this.entries.keys()]}resolveByCwd(t,e){let s=[...this.entries.values()].filter(a=>a.state.name===t||(a.state.baseName??a.state.name)===t);e&&(s=s.filter(a=>{let c=a.app.workspaceRoot;return c?ft(c,e)||ft(e,c):!1}));let o=s.map(a=>({name:a.state.name,baseName:a.state.baseName??a.state.name,workspaceLabel:a.state.workspaceLabel,workspaceRoot:a.state.workspaceRoot??a.app.workspaceRoot??null}));return s.length===0?{kind:"none",candidates:o}:s.length>1?{kind:"collision",candidates:o}:{kind:"unique",key:s[0].state.name,candidates:o}}pruneOldErrors(t=Date.now()){let e=this.config.errorRetention?.maxAgeMs??864e5,n=0;for(let s of this.entries.values())for(let[o,a]of s.state.errors)t-a.lastSeen>e&&(s.state.errors.delete(o),n++);return n}list(){return this.names().map(t=>this.summary(t))}summary(t){let e=this.entries.get(t);if(!e)return null;let n=e.state,s=n.startedAt&&(n.status==="serving"||n.status==="compiling"||n.status==="starting")?Date.now()-n.startedAt:null,a=this.config.overrides?.[t]?.url||e.resolvedUrl||n.announcedUrl||(n.port?`http://127.0.0.1:${n.port}`:null),c;for(let l=this.eventBuffer.length-1;l>=0;l--){let u=this.eventBuffer[l];if(u.app===t&&u.type==="status"){c=Date.now()-u.ts;break}}let i;if(n.status==="compiling"&&n.compileStartedAt&&n.compileHistory.length>=3){let l=n.compileHistory.slice(-10).slice().sort((d,g)=>d-g),u=l[Math.floor((l.length-1)*.5)];u>0&&(i=n.compileStartedAt+u)}return{name:n.name,status:n.status,port:n.port,url:a,errorCount:[...n.errors.values()].reduce((l,u)=>{let d=u.level??"error";return l+(d==="error"?u.count:0)},0),warningCount:[...n.errors.values()].reduce((l,u)=>l+(u.level==="warning"?u.count:0),0),lintCount:[...n.errors.values()].reduce((l,u)=>l+(u.level==="lint"?u.count:0),0),uptimeMs:s,lastCompileMs:n.lastCompileMs,health:n.health,lastHealthAt:n.lastHealthAt,cpu:n.cpu,memMB:n.memMB,compileHistoryMs:[...n.compileHistory],tags:[...n.tags],restartAttempts:n.restartAttempts,nextRestartAt:n.nextRestartAt,announcedUrl:n.announcedUrl,lastHealthError:n.lastHealthError,stale:n.stale,bundle:n.bundle,bundleRegressionPct:n.bundleRegressionPct,dependsOn:[...n.dependsOn],activeEnvFile:n.activeEnvFile,workspaceLabel:n.workspaceLabel,workspaceRoot:n.workspaceRoot,baseName:n.baseName??n.name,lastChangeMs:c,estimatedReadyAtMs:i}}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((n,s)=>s.lastSeen-n.lastSeen):null}errorsSince(t,e){let n=this.getState(t);return n?[...n.errors.values()].filter(s=>s.lastSeen>e).sort((s,o)=>o.lastSeen-s.lastSeen):null}logs(t,e={}){let n=this.getState(t);if(!n)return null;let s=n.logBuffer;if(e.sinceMs&&e.sinceMs>0){let o=Date.now()-e.sinceMs;s=s.filter(a=>a.ts>=o)}return e.tail&&e.tail>0&&(s=s.slice(-e.tail)),s.map(o=>o.line)}events(t={}){let e=t.sinceMs&&t.sinceMs>0?Date.now()-t.sinceMs:0;return this.eventBuffer.filter(n=>n.ts>=e&&(!t.app||n.app===t.app))}recordEvent(t){let e={ts:t.ts??Date.now(),...t};this.eventBuffer.push(e),this.emit("event",e),this.eventBuffer.length>sn&&this.eventBuffer.splice(0,this.eventBuffer.length-sn),this.history?.recordEvent(e),this.emit("event",e)}setHealth(t,e){let n=this.entries.get(t);if(!n)return;let s=n.state;if(s.lastHealthAt=Date.now(),s.health===e)return;let o=s.health;s.health=e,e==="healthy"&&(n.prevHealthyAt=Date.now(),n.cascadeArmed&&(n.cascadeArmed=!1,this.triggerCascadeRestart(t))),this.recordEvent({app:t,type:"health",from:o,to:e}),this.emit("change")}armCascade(t){let e=this.entries.get(t);e&&this.config.cascadeRestart&&e.prevHealthyAt!=null&&(e.cascadeArmed=!0)}setLastHealthError(t,e){let n=this.getState(t);n&&n.lastHealthError!==e&&(n.lastHealthError=e,this.emit("change"))}setResolvedUrl(t,e){let n=this.entries.get(t);n&&n.resolvedUrl!==e&&(n.resolvedUrl=e,this.emit("change"))}setCachedProbeHost(t,e){let n=this.getState(t);n&&(n.cachedProbeHost=e)}setStale(t,e){let n=this.getState(t);n&&n.stale!==e&&(n.stale=e,this.emit("change"))}setSessionOverride(t,e){let n=this.getState(t);n&&(n.sessionOverrides=e,this.emit("change"))}setActiveEnvFile(t,e){let n=this.getState(t);n&&(n.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 n=e.state.status,s;try{s=await this.portAlloc.allocate(t,e.app.pinnedPort)}catch(v){return e.state.status="error",e.state.lastStatusMessage=v.message,this.recordEvent({app:t,type:"status",from:n,to:"error",message:v.message}),this.emit("change"),{ok:!1,status:"error",error:v.message}}if(!await Nt(s)){let v=qr(s),A=Gr(s,v);return e.state.status="error",e.state.port=s,e.state.lastStatusMessage=A,this.recordEvent({app:t,type:"status",from:n,to:"error",message:A}),this.emit("change"),{ok:!1,status:"error",error:A}}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 te(t,this.config.logs));let a=e.state.sessionOverrides,c=this.config.envFiles?.[t]??[],i={};if(c.length){let v=e.state.activeEnvFile;(!v||!Ue(e.app.workspaceRoot,[v]).length)&&(v=Ue(e.app.workspaceRoot,c)[0]??null,v&&(e.state.activeEnvFile=v)),v&&(i=Kr(He(e.app.workspaceRoot,v)))}let l={...i,...this.config.overrides?.[t]?.env??{},...a?.env??{}},u=Qr(),d=tn(l,u),g=new Zt({state:e.state,app:e.app,port:s,envOverride:Object.keys(d).length?d:void 0,commandOverride:a?.command,onStateChange:()=>this.emit("change"),onStatusChange:(v,A,E)=>{this.recordEvent({app:t,type:"status",from:v,to:A,message:E}),(A==="stopped"||A==="error")&&(v==="serving"||v==="compiling")&&this.armCascade(t)},onErrorRecorded:(v,A)=>{let E=v.level??"error",C;E==="lint"?C=A?"lint-new":"lint-recur":E==="warning"?C=A?"warning-new":"warning-recur":C=A?"error-new":"error-recur",this.recordEvent({app:t,type:C,message:v.message})},onExit:(v,A,E)=>this.emit("childExit",{name:t,code:v,signal:A,stopping:E}),onLogLine:v=>{e.logger?.write(v),this.emit("log",{name:t,ts:Date.now(),line:v})},onCompile:v=>{this.history?.recordCompile(t,v);let A=this.getState(t),E=e.lastBundleInitialKB;if(A.bundle&&A.bundle.initialKB>0){if(E&&E>0){let C=(A.bundle.initialKB-E)/E*100;A.bundleRegressionPct=Math.round(C*10)/10;let y=nn(E,A.bundle.initialKB,1.1);if(y){this.recordEvent({app:t,type:"bundle-regression",message:`initialKB +${A.bundleRegressionPct}% (${E}->${A.bundle.initialKB})`});let P=Ke(e.app.workspaceRoot);this.recordEvent({app:t,type:"regression-detected",message:JSON.stringify({...y,suspectCommit:P})})}}else A.bundleRegressionPct=null;e.lastBundleInitialKB=A.bundle.initialKB}this.checkCompileRegression(t,v),this.emit("compile",{name:t,ms:v})},onBundleUpdate:()=>{let v=this.getState(t);v?.bundle&&(v.bundle.initialKB>0||v.bundle.lazyKB>0)&&this.history?.recordBundle(t,v.bundle.initialKB,v.bundle.lazyKB,v.bundle.files.length),this.emit("bundleUpdate",{name:t})}});return e.proc=g,this.recordEvent({app:t,type:"status",from:n,to:"starting"}),g.start(),{ok:!0,status:e.state.status}}async stop(t){this.sessionRecorder.append({kind:"stop",app:t});let e=this.entries.get(t);if(!e)return{ok:!1,status:"unknown",error:"unknown app"};if(this.emit("userStop",{name:t}),!e.proc||!e.proc.isRunning())return e.state.status!=="stopped"&&this.recordEvent({app:t,type:"status",from:e.state.status,to:"stopped"}),e.state.status="stopped",e.state.pid=null,e.state.health="unknown",this.emit("change"),{ok:!0,status:"stopped"};let n=e.state.status;return await e.proc.stop(),e.proc=null,e.state.status!==n&&this.recordEvent({app:t,type:"status",from:n,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 n=ee(this.config.depends??{},t).filter(c=>this.entries.has(c)),s=re(this.config.depends??{},n),o=[],a=e.waitMs??6e4;for(let c of s){let i=await Promise.all(c.map(u=>this.start(u)));for(let u=0;u<c.length;u++){let d=i[u];if(!d.ok)return o.push({name:c[u],status:d.status,health:"unknown",error:d.error}),{ok:!1,results:o}}let l=await Promise.all(c.map(u=>this.waitFor(u,"healthy",a)));for(let u=0;u<c.length;u++){let d=l[u],g=!d.timedOut&&d.status==="serving"&&d.health==="healthy";if(o.push({name:d.name,status:d.status,health:d.health,error:g?void 0:d.timedOut?"timeout waiting for healthy":"did not reach healthy"}),!g)return{ok:!1,results:o}}}return{ok:!0,results:o}}triggerCascadeRestart(t){if(!this.config.cascadeRestart)return;let e=Dr(this.config.depends??{},t);for(let n of e){let s=this.getState(n);s&&(s.status==="serving"||s.status==="compiling"||s.status==="starting")&&this.restart(n)}}async stopAll(t=3e3){let e=[];for(let n of this.entries.values())n.proc?.isRunning()&&e.push(n.proc.stop());for(let n of this.watchTasks.values())e.push(n.stop());await Promise.race([Promise.all(e),new Promise(n=>setTimeout(n,t))]);for(let n of this.entries.values())n.logger?.close()}listTasks(t){let e=this.getApp(t);return e?[...e.tasks??[]]:null}async runTask(t,e,n=[]){this.sessionRecorder.append({kind:"run",app:t,task:e,args:n});let s=this.getApp(t);if(!s)return{error:"unknown app"};let o=await Ur(s,e,n);return this.history?.recordTaskRun(t,e,o.exitCode,o.durationMs,o.summary),this.recordEvent({app:t,type:"task-run",message:`${e} exit=${o.exitCode} duration=${o.durationMs}ms`}),this.emit("taskRun",{name:t,task:e,result:o}),o}startWatchTask(t,e,n=[]){let s=this.getApp(t);if(!s)return{ok:!1,error:"unknown app"};let o=`${t}::${e}`;if(this.watchTasks.has(o))return{ok:!0,pid:this.watchTasks.get(o).pid};let a=Wr(s,e,n);return this.watchTasks.set(o,a),a.child.on("exit",()=>this.watchTasks.delete(o)),{ok:!0,pid:a.pid}}async stopWatchTask(t,e){let n=`${t}::${e}`,s=this.watchTasks.get(n);return s?(await s.stop(),this.watchTasks.delete(n),{ok:!0}):{ok:!0}}listWatchTasks(t){let e=[];for(let n of this.watchTasks.values())t&&n.app!==t||e.push({app:n.app,task:n.task,pid:n.pid,startedAt:n.startedAt});return e}checkCompileRegression(t,e){let n=this.history;if(!n)return;let o=n.queryCompiles({app:t,limit:21}).filter(l=>l.ms!==e).slice(0,20).map(l=>l.ms),a=rn(o,e,2);if(!a)return;this.recordEvent({app:t,type:"compile-regression",message:`${(e/1e3).toFixed(1)}s vs baseline ${(a.baseline/1e3).toFixed(1)}s (\xD7${a.factor})`});let c=this.getApp(t),i=Ke(c?.workspaceRoot??null);this.recordEvent({app:t,type:"regression-detected",message:JSON.stringify({...a,suspectCommit:i})})}watchTaskLogs(t,e,n){let s=this.watchTasks.get(`${t}::${e}`);if(!s)return null;let o=s.logs;return n?o.slice(-n):[...o]}waitFor(t,e,n){return new Promise(s=>{let o=Date.now(),a=this.entries.get(t),c=()=>{if(!a)return!0;let d=a.state;return e==="serving"&&d.status==="serving"||e==="healthy"&&d.status==="serving"&&d.health==="healthy"||e==="stopped"&&d.status==="stopped"||e==="error"&&d.status==="error"},i=d=>{this.off("change",l),clearTimeout(u);let g=a?.state;s({name:t,status:g?.status??"unknown",health:g?.health??"unknown",timedOut:d,waitedMs:Date.now()-o})},l=()=>{c()&&i(!1)};if(c()){s({name:t,status:a.state.status,health:a.state.health,timedOut:!1,waitedMs:0});return}let u=setTimeout(()=>i(!0),n);this.on("change",l)})}};Qt();import Si from"node:http";import ki from"node:crypto";import vt from"node:fs";import ot from"node:path";import{fileURLToPath as xi}from"node:url";import Ve from"node:fs";import on from"node:path";import Eo from"node:os";var Ze=on.join(Eo.homedir(),".daimon","cursors.json");function Ro(){try{let r=Ve.readFileSync(Ze,"utf8"),t=JSON.parse(r);if(t&&typeof t=="object"&&t.errors&&typeof t.errors=="object")return{errors:t.errors}}catch{}return{errors:{}}}var ze=null,Ye=null;function Ao(r){Ye=r,!ze&&(ze=setTimeout(()=>{ze=null;let t=Ye;if(Ye=null,!!t)try{Ve.mkdirSync(on.dirname(Ze),{recursive:!0}),Ve.writeFileSync(Ze,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: cursor write failed: ${e.message}
|
|
64
|
+
`)}},500))}var ce=class{data=Ro();getErrorCursor(t,e){return this.data.errors[`${t}:${e}`]??0}setErrorCursor(t,e,n){this.data.errors[`${t}:${e}`]=n,Ao(this.data)}};import an from"node:fs";import Po from"node:os";import cn from"node:path";var Co=/key|secret|token|password|api[-_]?key/i;function Mo(r){let t={};for(let[e,n]of Object.entries(r))typeof n=="string"&&(t[e]=Co.test(e)?"***":n);return t}function Qe(r,t){let e=r.summary(t);if(!e)return null;let n=r.getState(t),s=r.getApp(t),o=r.getConfig(),a=o.overrides?.[t]??{},c={...process.env,...s.env??{},...n.sessionOverrides?.env??{}},i=r.getHistory(),l=i?i.queryEvents({app:t,limit:50}):[],u=i?i.queryBundles({app:t,limit:100}):[],d=i?i.querySelfMetrics({limit:60}):[];return{takenAt:new Date().toISOString(),summary:e,logs:n.logBuffer.slice(-500).map(g=>({ts:g.ts,line:g.line})),errors:[...n.errors.entries()].map(([g,v])=>({hash:g,message:v.message,count:v.count,firstSeen:v.firstSeen,lastSeen:v.lastSeen})),env:Mo(c),configSlice:{command:n.sessionOverrides?.command??a.command??s.command,port:n.sessionOverrides?.port??a.port??null,workspaceRoot:s.workspaceRoot,workspaceType:s.workspaceType,tags:s.tags,depends:o.depends?.[t]??[],envFiles:o.envFiles?.[t]??[]},events:l,bundles:u,selfMetrics:d}}function ln(r,t){let e=Qe(r,t);if(!e)return null;let n=cn.join(Po.homedir(),".daimon","snapshots");an.mkdirSync(n,{recursive:!0});let s=e.takenAt.replace(/[:.]/g,"-"),o=cn.join(n,`${t}-${s}.json`);return an.writeFileSync(o,JSON.stringify(e,null,2)),{path:o,payload:e}}import le from"node:fs";import un from"node:path";var Oo=["dist",".angular/cache","tmp","out-tsc"],No=["node_modules"];function pn(r){let t=0;try{let e=le.readdirSync(r,{withFileTypes:!0});for(let n of e){let s=un.join(r,n.name);try{n.isDirectory()?t+=pn(s):n.isFile()&&(t+=le.statSync(s).size)}catch{}}}catch{}return t}function tr(r,t,e){let n=r.getApp(t);if(!n)return null;let s=r.getState(t),o=s?s.status==="serving"||s.status==="compiling"||s.status==="starting":!1,c=[...Oo,...e?No:[]].map(i=>{let l=un.join(n.workspaceRoot,i),u=le.existsSync(l);return{path:l,exists:u,sizeBytes:u?pn(l):0}});return{app:t,workspace:n.workspaceRoot,targets:c,ranOnServing:o}}function dn(r,t,e){let n=tr(r,t,e);if(!n)return{error:"unknown app"};if(n.ranOnServing)return{error:"app is currently running; stop it first"};let s=[],o=[];for(let a of n.targets)if(a.exists)try{le.rmSync(a.path,{recursive:!0,force:!0}),s.push(a.path)}catch(c){o.push({path:a.path,error:c?.message||String(c)})}return{ok:o.length===0,removed:s,failed:o}}function qt(r){return r.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}var $o=["stopped","starting","compiling","serving","error"];function fn(r){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=r.list();for(let n of e)for(let s of $o)t.push(`daimon_app_status{name="${qt(n.name)}",status="${s}"} ${n.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 n of e)n.lastCompileMs!=null&&t.push(`daimon_compile_seconds{name="${qt(n.name)}"} ${(n.lastCompileMs/1e3).toFixed(3)}`);t.push("# HELP daimon_error_total cumulative deduped error count"),t.push("# TYPE daimon_error_total counter");for(let n of e)t.push(`daimon_error_total{name="${qt(n.name)}"} ${n.errorCount}`);t.push("# HELP daimon_cpu_percent app CPU percent"),t.push("# TYPE daimon_cpu_percent gauge");for(let n of e)n.cpu!=null&&t.push(`daimon_cpu_percent{name="${qt(n.name)}"} ${n.cpu}`);t.push("# HELP daimon_mem_mb app resident memory MB"),t.push("# TYPE daimon_mem_mb gauge");for(let n of e)n.memMB!=null&&t.push(`daimon_mem_mb{name="${qt(n.name)}"} ${n.memMB}`);return t.join(`
|
|
63
65
|
`)+`
|
|
64
|
-
`}
|
|
65
|
-
`;try{Ft.appendFileSync(i,c)}catch{}}import ie from"node:fs";import ae from"node:path";import{fileURLToPath as To}from"node:url";var an=ae.dirname(To(import.meta.url));function Eo(){let r=[ae.resolve(an,"templates","presets"),ae.resolve(an,"..","src","templates","presets")];for(let t of r)if(ie.existsSync(t))return t;return r[0]}function cn(){let r=Eo();if(!ie.existsSync(r))return[];let t=ie.readdirSync(r).filter(n=>n.endsWith(".json")),e=[];for(let n of t)try{let s=ie.readFileSync(ae.join(r,n),"utf8");s.charCodeAt(0)===65279&&(s=s.slice(1)),e.push(JSON.parse(s))}catch{}return e}St();import ce from"node:fs";import ln from"node:path";function un(){return ln.join(ft(),"state-handoff.json")}function pn(r){let t=[];for(let s of r.names()){let i=r.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},n=un();return ce.mkdirSync(ln.dirname(n),{recursive:!0}),ce.writeFileSync(n,JSON.stringify(e)),n}function dn(r=6e4){let t=un();try{let e=ce.readFileSync(t,"utf8"),n=JSON.parse(e);return ce.unlinkSync(t),!n||typeof n.ts!="number"||Date.now()-n.ts>r?null:n}catch{return null}}Lt();var ai=ii(import.meta.url),ue=tt.dirname(ai);function Ze(){let r=[tt.resolve(ue,"dashboard","browser"),tt.resolve(ue,"dashboard"),tt.resolve(ue,"..","dist","dashboard","browser"),tt.resolve(ue,"..","dist","dashboard")];for(let t of r)if(mt.existsSync(tt.join(t,"index.html")))return t;return null}var ci={".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 Ht(r,t){try{if(!mt.statSync(t).isFile())return!1;let n=tt.extname(t).toLowerCase(),s=ci[n]??"application/octet-stream",i=mt.readFileSync(t);return r.writeHead(200,{"content-type":s,"content-length":i.length,"cache-control":n===".html"?"no-cache":"public, max-age=3600"}),r.end(i),!0}catch{return!1}}function w(r,t,e){let n=JSON.stringify(e);r.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(n)}),r.end(n)}function Mt(r){if(!r)return;let t=r.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 pe(r,t){let e=(r.searchParams.get("format")||"").toLowerCase();return e==="full"?"full":e==="compact"?"compact":t?.().output?.format==="full"?"full":"compact"}function li(r){return{name:r.name,status:r.status,port:r.port,health:r.health,errCount:r.errorCount,lastChangeMs:r.lastChangeMs??null}}function Ct(r){return{name:r.name,status:r.status,port:r.port,url:r.url,health:r.health,errCount:r.errorCount,lastChangeMs:r.lastChangeMs??null,uptime:r.uptimeMs}}function Qe(r){let t=r.parsed,e=r.level??"error";return t&&(t.file||t.code)?{file:t.file??null,line:t.line??null,col:t.col??null,code:t.code??null,message:t.message??r.message,level:e}:{file:null,line:null,col:null,code:null,message:r.message,level:e}}function Tn(r){if(!r)return{};if(/^\d{10,}$/.test(r))return{sinceTs:Number(r)};let t=Mt(r);return t!=null?{sinceMs:t}:{}}var ui=/key|secret|token|password|pass/i;function pi(r){let t=JSON.parse(JSON.stringify(r));if(t.apiToken&&(t.apiToken="***"),t.overrides&&typeof t.overrides=="object")for(let e of Object.keys(t.overrides)){let n=t.overrides[e]?.env;if(n&&typeof n=="object")for(let s of Object.keys(n))ui.test(s)&&(n[s]="***")}return t}function tr(r){if(!r)return"";try{let t=mt.readFileSync(r);return oi.createHash("sha1").update(t).digest("hex")}catch{return""}}function En(r,t,e={}){let n=new se,s=si.createServer(async(i,o)=>{try{let a=new URL(i.url||"/","http://127.0.0.1"),c=i.method||"GET",l=a.pathname.replace(/\/$/,"").split("/").filter(Boolean),p=()=>{let d=(e.getConfig?e.getConfig():null)?.apiToken??null;if(!d)return!0;let f=i.headers.authorization;return typeof f=="string"&&f.toLowerCase().startsWith("bearer ")&&f.slice(7).trim()===d?!0:(w(o,401,{error:"unauthorized"}),!1)};if(c==="POST"&&a.pathname==="/api/shutdown"){if(!p())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 u=e.getConfig(),d=tr(e.configPath);o.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:d}),o.end(JSON.stringify({etag:d,config:pi(u)}));return}if(c==="PATCH"&&e.patchConfig){if(!p())return;let u=i.headers["if-match"]?.trim(),d=tr(e.configPath);if(!u||u!==d){w(o,412,{error:"etag mismatch",current:d});return}let f={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(P=>{let k=[];i.on("data",x=>k.push(x)),i.on("end",()=>{try{f=JSON.parse(Buffer.concat(k).toString("utf8"))}catch{}P()})});let S=e.patchConfig(f);if(!S.ok){w(o,400,{error:S.error});return}let T=tr(e.configPath);try{let P=i.socket.remoteAddress||"127.0.0.1",k=i.headers["x-daimon-cwd"]||null;on(P,f,f,S.applied,k)}catch{}o.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:T}),o.end(JSON.stringify({etag:T,applied:S.applied,addedApps:S.addedApps,removedApps:S.removedApps,restartRequired:S.restartRequired}));return}w(o,405,{error:"method not allowed"});return}if(a.pathname==="/api/presets"&&c==="GET"){w(o,200,cn());return}if(a.pathname==="/api/self"&&c==="GET"){if(!e.selfMetrics){w(o,503,{error:"self-metrics collector not attached"});return}w(o,200,e.selfMetrics.snapshot());return}if(a.pathname==="/api/plugins"&&c==="GET"){let u=e.getPlugins?e.getPlugins():[];w(o,200,u.map(d=>({name:d.name,description:d.description??null,file:d.file,status:d.status,error:d.error??null,findings:d.lastFindings??[]})));return}if(a.pathname==="/api/plugins/scan"&&c==="POST"){if(!p())return;if(!e.runPluginScans){w(o,503,{error:"plug-in scan not available"});return}try{await e.runPluginScans()}catch(d){w(o,500,{error:d?.message||String(d)});return}let u=e.getPlugins?e.getPlugins():[];w(o,200,u);return}if(a.pathname==="/api/self/history"&&c==="GET"){let u=Tn(a.searchParams.get("since")),d=u.sinceMs??3600*1e3,f=u.sinceTs??Date.now()-d,S=r.getHistory(),T=S?S.querySelfMetrics({since:f,limit:1440}):[];w(o,200,T);return}if(a.pathname==="/api/snapshot-state"&&c==="POST"){if(!p())return;let u=pn(r);w(o,200,{ok:!0,path:u});return}if(a.pathname==="/api/config/reload"&&c==="POST"&&e.reloadConfig){if(!p())return;try{let u=await e.reloadConfig();w(o,200,u)}catch(u){w(o,400,{error:u?.message||String(u)})}return}if(a.pathname==="/api/workspaces"&&c==="GET"&&e.getConfig){let u=e.getConfig(),d=r.list(),f=u.searchRoots.map(S=>{let T=typeof S=="string"?S:S.path,P=typeof S=="string"?null:S.label??null,k=d.filter(x=>{let C=x.workspaceRoot;return!!C&&at(C,T)});return{path:T,label:P,appCount:k.length,apps:k.map(x=>x.name)}});w(o,200,f);return}if(a.pathname==="/api/workspaces/resolve"&&c==="GET"&&e.getConfig){let u=a.searchParams.get("cwd");if(!u){w(o,400,{error:"cwd query param required"});return}let S=e.getConfig().searchRoots.map(T=>typeof T=="string"?{path:T,label:null}:{path:T.path,label:T.label??null}).find(T=>at(u,T.path));if(!S){w(o,404,{error:"no workspace covers cwd",cwd:u});return}w(o,200,{path:S.path,label:S.label,cwd:u});return}if(a.pathname==="/api/workspaces/remove"&&c==="POST"&&e.getConfig&&e.patchConfig){if(!p())return;let u={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(x=>{let C=[];i.on("data",y=>C.push(y)),i.on("end",()=>{try{u=JSON.parse(Buffer.concat(C).toString("utf8"))}catch{}x()})});let d=typeof u?.path=="string"?u.path:"";if(!d){w(o,400,{error:"path is required"});return}let f=e.getConfig(),S=x=>typeof x=="string"?x:x.path,T=f.searchRoots.map(S),P=f.searchRoots.filter(x=>S(x)!==d);if(P.length===T.length){w(o,404,{error:`not a registered searchRoot: ${d}`});return}let k=e.patchConfig({searchRoots:P});if(!k.ok){w(o,400,{error:k.error});return}w(o,200,{removed:d,removedApps:k.removedApps??[]});return}if(a.pathname==="/api/workspaces/ensure"&&c==="POST"&&e.getConfig&&e.patchConfig){if(!p())return;let u={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(y=>{let A=[];i.on("data",_=>A.push(_)),i.on("end",()=>{try{u=JSON.parse(Buffer.concat(A).toString("utf8"))}catch{}y()})});let d=typeof u?.path=="string"?u.path:"",f=typeof u?.label=="string"&&u.label?u.label:null;if(!d){w(o,400,{error:"path is required"});return}if(!mt.existsSync(d)){w(o,400,{error:`path does not exist: ${d}`});return}let S=e.getConfig(),T=S.searchRoots.map(y=>typeof y=="string"?y:y.path);if(T.some(y=>at(d,y))){let y=T.find(A=>at(d,A));w(o,200,{added:!1,root:y,reason:"already covered"});return}let k=f?{path:d,label:f}:d,x=[...S.searchRoots,k],C=e.patchConfig({searchRoots:x});if(!C.ok){w(o,400,{error:C.error});return}w(o,200,{added:!0,root:d,label:f,addedApps:C.addedApps??[]});return}if(c==="GET"&&a.pathname==="/metrics"&&e.metricsEnabled){let u=nn(r);o.writeHead(200,{"content-type":"text/plain; version=0.0.4","content-length":Buffer.byteLength(u)}),o.end(u);return}if(c!=="GET"&&a.pathname.startsWith("/api/")&&a.pathname!=="/api/shutdown"&&a.pathname!=="/api/config"&&a.pathname!=="/api/config/reload"&&!p())return;if(c==="GET"&&a.pathname==="/"){let u=Ze();if(u&&Ht(o,tt.join(u,"index.html")))return;o.writeHead(404).end('dashboard not found \u2014 run "npm run build:dashboard" in the daimon repo');return}if(l[0]==="api"&&l[1]==="events"&&l.length===2){if(c!=="GET"){w(o,405,{error:"method not allowed"});return}let u=Mt(a.searchParams.get("since")),d=a.searchParams.get("app")||void 0;if(a.searchParams.get("stream")==="ndjson"){o.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});let T=r.events({sinceMs:u,app:d});for(let x of T)o.write(JSON.stringify(x)+`
|
|
66
|
-
`);let
|
|
67
|
-
`)};r.on("event",
|
|
68
|
-
`)}catch{}},3e4);i.on("close",()=>{r.off("event",P),clearInterval(k);try{o.end()}catch{}});return}let f=r.events({sinceMs:u,app:d}),S=r.getHistory();if(S&&u&&f.length<500){let T=Date.now()-u,P=S.queryEvents({app:d,since:T,limit:1e3}),k=new Set(f.map(x=>`${x.ts}|${x.app}|${x.type}|${x.from??""}|${x.to??""}|${x.message??""}`));for(let x of P){let C=`${x.ts}|${x.app}|${x.type}|${x.from_state??""}|${x.to_state??""}|${x.message??""}`;k.has(C)||f.push({ts:x.ts,app:x.app,type:x.type,from:x.from_state??void 0,to:x.to_state??void 0,message:x.message??void 0})}f.sort((x,C)=>x.ts-C.ts)}w(o,200,f);return}if(l[0]==="api"&&l[1]==="session"){if(l[2]==="record"&&c==="POST"){let u=a.searchParams.get("action")||"toggle";if(u==="start"||u==="toggle"&&!r.sessionRecorder.isRecording()){let d=r.sessionRecorder.start();w(o,200,{recording:!0,path:d.path});return}if(u==="stop"||u==="toggle"&&r.sessionRecorder.isRecording()){let d=r.sessionRecorder.stop();w(o,200,{recording:!1,path:d.path});return}w(o,400,{error:"invalid action"});return}if(l[2]==="status"&&c==="GET"){w(o,200,{recording:r.sessionRecorder.isRecording()});return}w(o,404,{error:"not found"});return}if(l[0]==="api"&&l[1]==="history"){if(c!=="GET"){w(o,405,{error:"method not allowed"});return}let u=r.getHistory();if(!u){w(o,200,[]);return}let d=l[2],f=a.searchParams.get("app")||void 0,S=a.searchParams.get("since"),T=a.searchParams.get("until"),P=a.searchParams.get("limit"),k=S?/^\d{10,}$/.test(S)?Number(S):Date.now()-(Mt(S)??0):void 0,x=T?/^\d{10,}$/.test(T)?Number(T):Date.now()-(Mt(T)??0):void 0,C=P?Number(P):void 0;if(d==="events"){w(o,200,u.queryEvents({app:f,since:k,until:x,type:a.searchParams.get("type")||void 0,limit:C}));return}if(d==="compile-times"){w(o,200,u.queryCompiles({app:f,since:k,until:x,limit:C}));return}if(d==="tasks"){w(o,200,u.queryTasks({app:f,task:a.searchParams.get("task")||void 0,since:k,limit:C}));return}if(d==="timeline"){let y=a.searchParams.get("kinds"),A=y?new Set(y.split(",").map(U=>U.trim()).filter(Boolean)):void 0,_=u.queryTimeline({app:f,since:k,kinds:A,limit:C??5e3});w(o,200,_);return}if(d==="bundles"){w(o,200,u.queryBundles({app:f,since:k,until:x,limit:C}));return}if(d==="trends"){let y=(a.searchParams.get("since")||"24h").toLowerCase(),A={"24h":24*3600*1e3,"7d":7*86400*1e3,"30d":30*86400*1e3},_=A[y]??A["24h"],U=y==="24h"?3600*1e3:86400*1e3,$=a.searchParams.get("metrics");if($){let nt=$.split(",").map(X=>X.trim()).filter(Boolean),q=["compile","bundle","errors","restarts"],Wt=nt.filter(X=>q.includes(X));if(!Wt.length){w(o,400,{error:"metrics must include at least one of compile|bundle|errors|restarts"});return}let Nt={};for(let X of Wt){let Gt=u.trends({app:f,metric:X,sinceMs:_,bucketMs:U});Nt[X]={points:Gt.points,count:Gt.count}}w(o,200,{app:f??null,since:y,metrics:Nt,_meta:{aggregation:y==="24h"?"hour":"day"}});return}let H=a.searchParams.get("metric")||"compile";if(!["compile","bundle","errors","restarts"].includes(H)){w(o,400,{error:"metric must be compile|bundle|errors|restarts"});return}let{points:J,count:B}=u.trends({app:f,metric:H,sinceMs:_,bucketMs:U});w(o,200,{app:f??null,metric:H,since:y,points:J,_meta:{aggregation:y==="24h"?"hour":"day",count:B}});return}if(d==="summary"&&l.length>=4){let y=decodeURIComponent(l[3]);w(o,200,u.summary(y));return}if(d==="why"&&l.length>=4){let y=decodeURIComponent(l[3]);w(o,200,u.why(y));return}w(o,404,{error:"not found"});return}if(l[0]==="api"&&l[1]==="profiles"&&l[3]==="ensure-up"&&c==="POST"){let u=decodeURIComponent(l[2]),d=e.getConfig?.(),f=d?.profiles?.[u];if(!f){w(o,404,{error:"unknown profile"});return}let S=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(S)){w(o,400,{error:"until must be serving|healthy"});return}let T=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),P=T?Number(T):3e5;(!Number.isFinite(P)||P<=0)&&(P=3e5),P=Math.min(P,12e5);let k=d?.healthProbe?.enabled??!0,x=S==="healthy"&&!k?"serving":S,C=Date.now();for(let A of f){let _=r.summary(A);_&&_.status!=="serving"&&_.status!=="starting"&&_.status!=="compiling"&&await r.startWithDeps(A)}let y=await Promise.all(f.map(async A=>{let _=Math.max(1e3,P-(Date.now()-C));if(!r.summary(A))return{name:A,state:null,until:x,reachedTargetMs:null,timedOut:!1,error:"unknown"};let $=await r.waitFor(A,x,_),H=r.summary(A);return{name:A,state:H?Ct(H):null,until:x,reachedTargetMs:$.timedOut?null:$.waitedMs,timedOut:$.timedOut}}));w(o,200,{profile:u,apps:y,_meta:{totalMs:Date.now()-C,until:x}});return}if(l[0]==="api"&&l[1]==="orchestrate"&&c==="POST"){let u=e.getConfig?.();if(!u){w(o,500,{error:"no config loaded"});return}let d=a.searchParams.get("profile");if(!d){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 S=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),T=S?Number(S):3e5;(!Number.isFinite(T)||T<=0)&&(T=3e5),T=Math.min(T,12e5);let P=a.searchParams.get("dryRun")==="true"||a.searchParams.get("dry-run")==="true",k=a.searchParams.get("budget"),x=k&&Number.isFinite(Number(k))?Number(k):void 0,{orchestrateProfile:C}=await Promise.resolve().then(()=>(Ve(),Ye)),y=await C(r,u,{profile:d,goal:f,timeoutMs:T,dryRun:P,budgetTokens:x});if(y.error){w(o,404,y);return}w(o,200,y);return}if(l[0]==="api"&&l[1]==="discovery"&&l[2]==="explain"&&c==="GET"){let u=e.getConfig?.();if(!u){w(o,200,{searchRoots:[],scanned:0,rejected:{},warnings:[],suggestion:"no config loaded"});return}let{discoverApps:d}=await Promise.resolve().then(()=>(xt(),Me)),f={scanned:0,rejected:{}},S=[],T=d(u,{warnings:S,stats:f}),P=u.searchRoots.map(y=>typeof y=="string"?y:y.path),k=T.filter(y=>y.workspaceType==="polyglot"),x=T.map(y=>({name:y.name,workspaceType:y.workspaceType,serverProfile:y.serverProfile??y.workspaceType,workspaceRoot:y.workspaceRoot})),C=k.length>0?` \xB7 ${k.length} polyglot app${k.length===1?"":"s"} found (${[...new Set(k.map(y=>y.serverProfile))].join(", ")})`:"";w(o,200,{searchRoots:P,scanned:f.scanned,rejected:f.rejected,warnings:S,appsFound:T.length,apps:x,suggestion:T.length===0?P.length===0?"no searchRoots configured. Run 'daimon init --auto' from a workspace folder.":"discovery returned no apps. Check that searchRoots contain nx.json / angular.json / vite.config.* / .storybook / manage.py / Gemfile / pyproject.toml (fastapi) / .air.toml / Trunk.toml.":`${T.length} apps discovered${C}`});return}if(l[0]==="api"&&l[1]==="doctor"&&l[2]==="auto-fix"&&c==="POST"){if(!p())return;let u={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(k=>{let x=[];i.on("data",C=>x.push(C)),i.on("end",()=>{try{u=JSON.parse(Buffer.concat(x).toString("utf8"))}catch{}k()})});let{runAutoFix:d,ALL_AUTO_FIX:f}=await Promise.resolve().then(()=>(Bt(),It)),T=e.getConfig?.()?.doctor?.autoFix?.permitted??f,P=Array.isArray(u.permitted)&&u.permitted.length?u.permitted:T;try{let k=await d({permitted:P,dryRun:!!u.dryRun});w(o,200,k)}catch(k){w(o,500,{error:k?.message??String(k)})}return}if(l[0]==="api"&&l[1]==="overview"&&c==="GET"){let u=e.getConfig?.(),d=r.list(),f=a.searchParams.get("workspace"),S=a.searchParams.get("profile"),T=d;if(f&&(T=T.filter($=>$.workspaceLabel===f)),S){let $=u?.profiles?.[S]??null;$&&(T=T.filter(H=>$.includes(H.name)))}let P={apps:T.length,serving:T.filter($=>$.status==="serving").length,errors:T.filter($=>$.status==="error").length,stopped:T.filter($=>$.status==="stopped").length,totalErrCount:T.reduce(($,H)=>$+H.errorCount,0),totalCpuPct:Math.round(T.reduce(($,H)=>$+(H.cpu??0),0)*10)/10,totalMemMb:Math.round(T.reduce(($,H)=>$+(H.memMB??0),0))},k={};for(let $ of T)(k[$.status]??=[]).push($.name);let x=T.filter($=>$.status==="error"||$.errorCount>0).map($=>{let H=r.errors($.name)??[],J=H[H.length-1],B=J?.parsed;return{name:$.name,status:$.status,errCount:$.errorCount,firstError:B?{file:B.file??null,line:B.line??null,code:B.code??null,message:B.message??J?.message??""}:J?{file:null,line:null,code:null,message:J.message}:null}}),C=Date.now()-5*6e4,y=r.events({sinceMs:5*6e4}).filter($=>$.type==="status"&&$.ts>=C).filter($=>f?T.some(H=>H.name===$.app):!0).filter($=>S?T.some(H=>H.name===$.app):!0).slice(-5).map($=>({name:$.app,transition:`${$.from??"?"}\u2192${$.to??"?"}`,msAgo:Date.now()-$.ts})),A={ts:Date.now(),version:dt,totals:P,byStatus:k,needsAttention:x,recentlyChanged:y};P.apps===0&&(A._meta={suggestion:"no apps registered. run 'daimon doctor' for recommended next step, or 'daimon init --auto' from a workspace folder."});let _=a.searchParams.get("budget"),U=_?Math.max(64,Number(_)|0):null;if(U){let $=U*4,H=0,J=0;for(;JSON.stringify(A).length>$&&(A.needsAttention.length||A.recentlyChanged.length);)if(A.needsAttention.length>1)A.needsAttention.pop(),H++;else if(A.recentlyChanged.length)A.recentlyChanged.pop(),J++;else if(A.needsAttention.length===1)A.needsAttention.pop(),H++;else break;H||J?A._meta={...A._meta??{},budget:U,omitted:{needsAttention:H,recentlyChanged:J}}:A._meta={...A._meta??{},budget:U}}w(o,200,A);return}if(l[0]!=="api"||l[1]!=="apps"){if(c==="GET"&&!a.pathname.startsWith("/metrics")){let u=Ze();if(u){let d=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(d){let f=tt.resolve(u,d);if(f.startsWith(u)&&Ht(o,f))return}if(!tt.extname(d||"")&&Ht(o,tt.join(u,"index.html")))return}}w(o,404,{error:"not found"});return}if(l.length===2){if(c!=="GET"){w(o,405,{error:"method not allowed"});return}let u=pe(a,e.getConfig),d=r.list(),f=a.searchParams.get("cwd"),S=f&&f.length>0?f:null;S&&(d=d.filter(P=>{let k=r.getApp(P.name);return k?at(k.workspaceRoot,S)||at(S,k.workspaceRoot):!1}));let T=u==="full"?d:d.map(li);if(a.searchParams.get("stream")==="ndjson"){o.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});for(let P of T)o.write(JSON.stringify(P)+`
|
|
69
|
-
`);
|
|
66
|
+
`}At();import Gt from"node:fs";import _o from"node:crypto";import mn from"node:path";var Lo=1e6;function jo(){return mn.join(wt(),"audit.log")}function Do(r){try{if(Gt.statSync(r).size>Lo){let e=r+".1";try{Gt.unlinkSync(e)}catch{}Gt.renameSync(r,e)}}catch{}}function hn(r,t,e,n,s=null,o=null){let a=jo();Gt.mkdirSync(mn.dirname(a),{recursive:!0}),Do(a);let c=JSON.stringify({prev:t,next:e}),i=_o.createHash("sha1").update(c).digest("hex").slice(0,12),l=`${new Date().toISOString()} ${r} ${i} ${n.join(",")} ${s??""} ${o??""}
|
|
67
|
+
`;try{Gt.appendFileSync(a,l)}catch{}}import ue from"node:fs";import pe from"node:path";import{fileURLToPath as Io}from"node:url";var gn=pe.dirname(Io(import.meta.url));function Fo(){let r=[pe.resolve(gn,"templates","presets"),pe.resolve(gn,"..","src","templates","presets")];for(let t of r)if(ue.existsSync(t))return t;return r[0]}function yn(){let r=Fo();if(!ue.existsSync(r))return[];let t=ue.readdirSync(r).filter(n=>n.endsWith(".json")),e=[];for(let n of t)try{let s=ue.readFileSync(pe.join(r,n),"utf8");s.charCodeAt(0)===65279&&(s=s.slice(1)),e.push(JSON.parse(s))}catch{}return e}At();import de from"node:fs";import bn from"node:path";function wn(){return bn.join(wt(),"state-handoff.json")}function vn(r){let t=[];for(let s of r.names()){let o=r.getState(s);o&&(o.status==="serving"||o.status==="compiling"||o.status==="starting")&&o.port&&t.push({name:s,port:o.port})}let e={ts:Date.now(),apps:t},n=wn();return de.mkdirSync(bn.dirname(n),{recursive:!0}),de.writeFileSync(n,JSON.stringify(e)),n}function Sn(r=6e4){let t=wn();try{let e=de.readFileSync(t,"utf8"),n=JSON.parse(e);return de.unlinkSync(t),!n||typeof n.ts!="number"||Date.now()-n.ts>r?null:n}catch{return null}}Ut();var kn=5*6e4,Bo=3e4;var fe=class{agents=new Map;touch(t,e,n=Date.now()){let s=this.agents.get(t);return s||(s={id:t,firstSeen:n,lastSeen:n,cwd:e,callCount:0},this.agents.set(t,s)),s.lastSeen=n,e&&(s.cwd=e),s.callCount++,s}list(t=Date.now()){let e=[];for(let n of this.agents.values())t-n.lastSeen<=kn&&e.push({...n});return e.sort((n,s)=>s.lastSeen-n.lastSeen)}prune(t=Date.now()){let e=0;for(let[n,s]of this.agents)t-s.lastSeen>kn*2&&(this.agents.delete(n),e++);return e}},me=class{constructor(t=Bo){this.ttlMs=t}ttlMs;locks=new Map;history=new Map;acquire(t,e,n,s=Date.now()){this.recordInteraction(t,e,n,s);let o=this.locks.get(t);if(o&&o.expiresAt>s&&o.agent!==e)return{...o};let a={app:t,agent:e,lockedAt:s,expiresAt:s+this.ttlMs};return this.locks.set(t,a),null}steal(t,e,n,s=Date.now()){this.recordInteraction(t,e,n,s);let o={app:t,agent:e,lockedAt:s,expiresAt:s+this.ttlMs};return this.locks.set(t,o),o}handoff(t,e,n,s=Date.now()){this.recordInteraction(t,e,`handoff${n?`<-${n}`:""}`,s);let o={app:t,agent:e,lockedAt:s,expiresAt:s+this.ttlMs};return this.locks.set(t,o),o}current(t,e=Date.now()){let n=this.locks.get(t);return n?n.expiresAt<=e?(this.locks.delete(t),null):{...n}:null}list(t=Date.now()){let e=[];for(let n of this.locks.values())n.expiresAt>t&&e.push({...n});return e}recentInteractions(t,e=3){return(this.history.get(t)??[]).slice(-e).reverse()}recordInteraction(t,e,n,s){let o=this.history.get(t)??[];for(o.push({agent:e,at:s,action:n});o.length>16;)o.shift();this.history.set(t,o)}};var Ti=xi(import.meta.url),ge=ot.dirname(Ti);function ir(){let r=[ot.resolve(ge,"dashboard","browser"),ot.resolve(ge,"dashboard"),ot.resolve(ge,"..","dist","dashboard","browser"),ot.resolve(ge,"..","dist","dashboard")];for(let t of r)if(vt.existsSync(ot.join(t,"index.html")))return t;return null}var Ei={".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 zt(r,t){try{if(!vt.statSync(t).isFile())return!1;let n=ot.extname(t).toLowerCase(),s=Ei[n]??"application/octet-stream",o=vt.readFileSync(t);return r.writeHead(200,{"content-type":s,"content-length":o.length,"cache-control":n===".html"?"no-cache":"public, max-age=3600"}),r.end(o),!0}catch{return!1}}function b(r,t,e){let n=JSON.stringify(e);r.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(n)}),r.end(n)}function Pt(r){if(!r)return;let t=r.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 ye(r,t){let e=(r.searchParams.get("format")||"").toLowerCase();return e==="full"?"full":e==="compact"?"compact":t?.().output?.format==="full"?"full":"compact"}function Ri(r){return{name:r.name,status:r.status,port:r.port,health:r.health,errCount:r.errorCount,lastChangeMs:r.lastChangeMs??null}}function jt(r){let t={name:r.name,status:r.status,port:r.port,url:r.url,health:r.health,errCount:r.errorCount,lastChangeMs:r.lastChangeMs??null,uptime:r.uptimeMs};return r.estimatedReadyAtMs!=null&&(t.estimatedReadyAtMs=r.estimatedReadyAtMs),t}function ar(r){let t=r.parsed,e=r.level??"error";return t&&(t.file||t.code)?{file:t.file??null,line:t.line??null,col:t.col??null,code:t.code??null,message:t.message??r.message,level:e}:{file:null,line:null,col:null,code:null,message:r.message,level:e}}function jn(r){if(!r)return{};if(/^\d{10,}$/.test(r))return{sinceTs:Number(r)};let t=Pt(r);return t!=null?{sinceMs:t}:{}}var Ai=/key|secret|token|password|pass/i;function Pi(r){let t=JSON.parse(JSON.stringify(r));if(t.apiToken&&(t.apiToken="***"),t.overrides&&typeof t.overrides=="object")for(let e of Object.keys(t.overrides)){let n=t.overrides[e]?.env;if(n&&typeof n=="object")for(let s of Object.keys(n))Ai.test(s)&&(n[s]="***")}return t}function cr(r){if(!r)return"";try{let t=vt.readFileSync(r);return ki.createHash("sha1").update(t).digest("hex")}catch{return""}}function Dn(r,t,e={}){let n=new ce,s=new fe,o=new me,a=Si.createServer(async(c,i)=>{try{let l=new URL(c.url||"/","http://127.0.0.1"),u=c.method||"GET",d=l.pathname.replace(/\/$/,"").split("/").filter(Boolean),g=c.headers["x-daimon-agent"]?.trim(),v=c.headers["x-daimon-cwd"]?.trim()||null,A=g&&g.length?g:"unknown";s.touch(A,v);let E=()=>{let f=(e.getConfig?e.getConfig():null)?.apiToken??null;if(!f)return!0;let h=c.headers.authorization;return typeof h=="string"&&h.toLowerCase().startsWith("bearer ")&&h.slice(7).trim()===f?!0:(b(i,401,{error:"unauthorized"}),!1)};if(u==="POST"&&l.pathname==="/api/shutdown"){if(!E())return;b(i,200,{ok:!0}),e.onShutdown&&setImmediate(()=>{try{e.onShutdown()}catch{}});return}if(l.pathname==="/api/config"&&e.getConfig){if(u==="GET"){let p=e.getConfig(),f=cr(e.configPath);i.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:f}),i.end(JSON.stringify({etag:f,config:Pi(p)}));return}if(u==="PATCH"&&e.patchConfig){if(!E())return;let p=c.headers["if-match"]?.trim(),f=cr(e.configPath);if(!p||p!==f){b(i,412,{error:"etag mismatch",current:f});return}let h={};c.headers["content-length"]&&c.headers["content-length"]!=="0"&&await new Promise(T=>{let k=[];c.on("data",x=>k.push(x)),c.on("end",()=>{try{h=JSON.parse(Buffer.concat(k).toString("utf8"))}catch{}T()})});let w=e.patchConfig(h);if(!w.ok){b(i,400,{error:w.error});return}let m=cr(e.configPath);try{let T=c.socket.remoteAddress||"127.0.0.1";hn(T,h,h,w.applied,v,A==="unknown"?null:A)}catch{}i.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:m}),i.end(JSON.stringify({etag:m,applied:w.applied,addedApps:w.addedApps,removedApps:w.removedApps,restartRequired:w.restartRequired}));return}b(i,405,{error:"method not allowed"});return}if(l.pathname==="/api/presets"&&u==="GET"){b(i,200,yn());return}if(l.pathname==="/api/self"&&u==="GET"){if(!e.selfMetrics){b(i,503,{error:"self-metrics collector not attached"});return}b(i,200,e.selfMetrics.snapshot());return}if(l.pathname==="/api/plugins"&&u==="GET"){let p=e.getPlugins?e.getPlugins():[];b(i,200,p.map(f=>({name:f.name,description:f.description??null,file:f.file,status:f.status,error:f.error??null,findings:f.lastFindings??[]})));return}if(l.pathname==="/api/plugins/scan"&&u==="POST"){if(!E())return;if(!e.runPluginScans){b(i,503,{error:"plug-in scan not available"});return}try{await e.runPluginScans()}catch(f){b(i,500,{error:f?.message||String(f)});return}let p=e.getPlugins?e.getPlugins():[];b(i,200,p);return}if(l.pathname==="/api/agents"&&u==="GET"){let p=s.list(),f=o.list(),h={};for(let w of f)h[w.app]={agent:w.agent,lockedAt:w.lockedAt,expiresAt:w.expiresAt};b(i,200,{agents:p,locks:h,self:A==="unknown"?null:A});return}if(l.pathname==="/api/self/history"&&u==="GET"){let p=jn(l.searchParams.get("since")),f=p.sinceMs??3600*1e3,h=p.sinceTs??Date.now()-f,w=r.getHistory(),m=w?w.querySelfMetrics({since:h,limit:1440}):[];b(i,200,m);return}if(l.pathname==="/api/snapshot-state"&&u==="POST"){if(!E())return;let p=vn(r);b(i,200,{ok:!0,path:p});return}if(l.pathname==="/api/config/reload"&&u==="POST"&&e.reloadConfig){if(!E())return;try{let p=await e.reloadConfig();b(i,200,p)}catch(p){b(i,400,{error:p?.message||String(p)})}return}if(l.pathname==="/api/workspaces"&&u==="GET"&&e.getConfig){let p=e.getConfig(),f=r.list(),h=p.searchRoots.map(w=>{let m=typeof w=="string"?w:w.path,T=typeof w=="string"?null:w.label??null,k=f.filter(x=>{let $=x.workspaceRoot;return!!$&&ft($,m)});return{path:m,label:T,appCount:k.length,apps:k.map(x=>x.name)}});b(i,200,h);return}if(l.pathname==="/api/workspaces/resolve"&&u==="GET"&&e.getConfig){let p=l.searchParams.get("cwd");if(!p){b(i,400,{error:"cwd query param required"});return}let w=e.getConfig().searchRoots.map(m=>typeof m=="string"?{path:m,label:null}:{path:m.path,label:m.label??null}).find(m=>ft(p,m.path));if(!w){b(i,404,{error:"no workspace covers cwd",cwd:p});return}b(i,200,{path:w.path,label:w.label,cwd:p});return}if(l.pathname==="/api/workspaces/remove"&&u==="POST"&&e.getConfig&&e.patchConfig){if(!E())return;let p={};c.headers["content-length"]&&c.headers["content-length"]!=="0"&&await new Promise(x=>{let $=[];c.on("data",M=>$.push(M)),c.on("end",()=>{try{p=JSON.parse(Buffer.concat($).toString("utf8"))}catch{}x()})});let f=typeof p?.path=="string"?p.path:"";if(!f){b(i,400,{error:"path is required"});return}let h=e.getConfig(),w=x=>typeof x=="string"?x:x.path,m=h.searchRoots.map(w),T=h.searchRoots.filter(x=>w(x)!==f);if(T.length===m.length){b(i,404,{error:`not a registered searchRoot: ${f}`});return}let k=e.patchConfig({searchRoots:T});if(!k.ok){b(i,400,{error:k.error});return}b(i,200,{removed:f,removedApps:k.removedApps??[]});return}if(l.pathname==="/api/workspaces/ensure"&&u==="POST"&&e.getConfig&&e.patchConfig){if(!E())return;let p={};c.headers["content-length"]&&c.headers["content-length"]!=="0"&&await new Promise(M=>{let L=[];c.on("data",W=>L.push(W)),c.on("end",()=>{try{p=JSON.parse(Buffer.concat(L).toString("utf8"))}catch{}M()})});let f=typeof p?.path=="string"?p.path:"",h=typeof p?.label=="string"&&p.label?p.label:null;if(!f){b(i,400,{error:"path is required"});return}if(!vt.existsSync(f)){b(i,400,{error:`path does not exist: ${f}`});return}let w=e.getConfig(),m=w.searchRoots.map(M=>typeof M=="string"?M:M.path);if(m.some(M=>ft(f,M))){let M=m.find(L=>ft(f,L));b(i,200,{added:!1,root:M,reason:"already covered"});return}let k=h?{path:f,label:h}:f,x=[...w.searchRoots,k],$=e.patchConfig({searchRoots:x});if(!$.ok){b(i,400,{error:$.error});return}b(i,200,{added:!0,root:f,label:h,addedApps:$.addedApps??[]});return}if(u==="GET"&&l.pathname==="/metrics"&&e.metricsEnabled){let p=fn(r);i.writeHead(200,{"content-type":"text/plain; version=0.0.4","content-length":Buffer.byteLength(p)}),i.end(p);return}if(u!=="GET"&&l.pathname.startsWith("/api/")&&l.pathname!=="/api/shutdown"&&l.pathname!=="/api/config"&&l.pathname!=="/api/config/reload"&&!E())return;if(u==="GET"&&l.pathname==="/"){let p=ir();if(p&&zt(i,ot.join(p,"index.html")))return;i.writeHead(404).end('dashboard not found \u2014 run "npm run build:dashboard" in the daimon repo');return}if(d[0]==="api"&&d[1]==="events"&&d.length===2){if(u!=="GET"){b(i,405,{error:"method not allowed"});return}let p=Pt(l.searchParams.get("since")),f=l.searchParams.get("app")||void 0;if(l.searchParams.get("stream")==="ndjson"){i.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});let m=r.events({sinceMs:p,app:f});for(let x of m)i.write(JSON.stringify(x)+`
|
|
68
|
+
`);let T=x=>{f&&x.app!==f||i.write(JSON.stringify(x)+`
|
|
69
|
+
`)};r.on("event",T);let k=setInterval(()=>{try{i.write(`
|
|
70
|
+
`)}catch{}},3e4);c.on("close",()=>{r.off("event",T),clearInterval(k);try{i.end()}catch{}});return}let h=r.events({sinceMs:p,app:f}),w=r.getHistory();if(w&&p&&h.length<500){let m=Date.now()-p,T=w.queryEvents({app:f,since:m,limit:1e3}),k=new Set(h.map(x=>`${x.ts}|${x.app}|${x.type}|${x.from??""}|${x.to??""}|${x.message??""}`));for(let x of T){let $=`${x.ts}|${x.app}|${x.type}|${x.from_state??""}|${x.to_state??""}|${x.message??""}`;k.has($)||h.push({ts:x.ts,app:x.app,type:x.type,from:x.from_state??void 0,to:x.to_state??void 0,message:x.message??void 0})}h.sort((x,$)=>x.ts-$.ts)}b(i,200,h);return}if(d[0]==="api"&&d[1]==="session"){if(d[2]==="record"&&u==="POST"){let p=l.searchParams.get("action")||"toggle";if(p==="start"||p==="toggle"&&!r.sessionRecorder.isRecording()){let f=r.sessionRecorder.start();b(i,200,{recording:!0,path:f.path});return}if(p==="stop"||p==="toggle"&&r.sessionRecorder.isRecording()){let f=r.sessionRecorder.stop();b(i,200,{recording:!1,path:f.path});return}b(i,400,{error:"invalid action"});return}if(d[2]==="status"&&u==="GET"){b(i,200,{recording:r.sessionRecorder.isRecording()});return}b(i,404,{error:"not found"});return}if(d[0]==="api"&&d[1]==="history"){if(u!=="GET"){b(i,405,{error:"method not allowed"});return}let p=r.getHistory();if(!p){b(i,200,[]);return}let f=d[2],h=l.searchParams.get("app")||void 0,w=l.searchParams.get("since"),m=l.searchParams.get("until"),T=l.searchParams.get("limit"),k=w?/^\d{10,}$/.test(w)?Number(w):Date.now()-(Pt(w)??0):void 0,x=m?/^\d{10,}$/.test(m)?Number(m):Date.now()-(Pt(m)??0):void 0,$=T?Number(T):void 0;if(f==="events"){b(i,200,p.queryEvents({app:h,since:k,until:x,type:l.searchParams.get("type")||void 0,limit:$}));return}if(f==="compile-times"){b(i,200,p.queryCompiles({app:h,since:k,until:x,limit:$}));return}if(f==="tasks"){b(i,200,p.queryTasks({app:h,task:l.searchParams.get("task")||void 0,since:k,limit:$}));return}if(f==="timeline"){let M=l.searchParams.get("kinds"),L=M?new Set(M.split(",").map(V=>V.trim()).filter(Boolean)):void 0,W=p.queryTimeline({app:h,since:k,kinds:L,limit:$??5e3});b(i,200,W);return}if(f==="bundles"){b(i,200,p.queryBundles({app:h,since:k,until:x,limit:$}));return}if(f==="trends"){let M=(l.searchParams.get("since")||"24h").toLowerCase(),L={"24h":24*3600*1e3,"7d":7*86400*1e3,"30d":30*86400*1e3},W=L[M]??L["24h"],V=M==="24h"?3600*1e3:86400*1e3,_=l.searchParams.get("metrics");if(_){let lt=_.split(",").map(B=>B.trim()).filter(Boolean),K=["compile","bundle","errors","restarts"],It=lt.filter(B=>K.includes(B));if(!It.length){b(i,400,{error:"metrics must include at least one of compile|bundle|errors|restarts"});return}let St={};for(let B of It){let pt=p.trends({app:h,metric:B,sinceMs:W,bucketMs:V});St[B]={points:pt.points,count:pt.count}}b(i,200,{app:h??null,since:M,metrics:St,_meta:{aggregation:M==="24h"?"hour":"day"}});return}let q=l.searchParams.get("metric")||"compile";if(!["compile","bundle","errors","restarts"].includes(q)){b(i,400,{error:"metric must be compile|bundle|errors|restarts"});return}let{points:G,count:U}=p.trends({app:h,metric:q,sinceMs:W,bucketMs:V});b(i,200,{app:h??null,metric:q,since:M,points:G,_meta:{aggregation:M==="24h"?"hour":"day",count:U}});return}if(f==="summary"&&d.length>=4){let M=decodeURIComponent(d[3]);b(i,200,p.summary(M));return}if(f==="why"&&d.length>=4){let M=decodeURIComponent(d[3]);b(i,200,p.why(M));return}b(i,404,{error:"not found"});return}if(d[0]==="api"&&d[1]==="profiles"&&d[3]==="ensure-up"&&u==="POST"){let p=decodeURIComponent(d[2]),f=e.getConfig?.(),h=f?.profiles?.[p];if(!h){b(i,404,{error:"unknown profile"});return}let w=(l.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(w)){b(i,400,{error:"until must be serving|healthy"});return}let m=l.searchParams.get("timeoutMs")||l.searchParams.get("timeout"),T=m?Number(m):3e5;(!Number.isFinite(T)||T<=0)&&(T=3e5),T=Math.min(T,12e5);let k=f?.healthProbe?.enabled??!0,x=w==="healthy"&&!k?"serving":w,$=Date.now();for(let L of h){let W=r.summary(L);W&&W.status!=="serving"&&W.status!=="starting"&&W.status!=="compiling"&&await r.startWithDeps(L)}let M=await Promise.all(h.map(async L=>{let W=Math.max(1e3,T-(Date.now()-$));if(!r.summary(L))return{name:L,state:null,until:x,reachedTargetMs:null,timedOut:!1,error:"unknown"};let _=await r.waitFor(L,x,W),q=r.summary(L);return{name:L,state:q?jt(q):null,until:x,reachedTargetMs:_.timedOut?null:_.waitedMs,timedOut:_.timedOut}}));b(i,200,{profile:p,apps:M,_meta:{totalMs:Date.now()-$,until:x}});return}if(d[0]==="api"&&d[1]==="profiles"&&d[2]==="suggest"&&u==="GET"){let p=e.getConfig?.(),f=r.getHistory();if(!f){b(i,200,{suggestions:[],reason:"history disabled"});return}let h=Pt(l.searchParams.get("since"))??720*60*6e4,w=Number(l.searchParams.get("minOccurrences")??5)||5,m=f.queryEvents({since:Date.now()-h,type:"status",limit:2e4}),{suggestProfiles:T}=await Promise.resolve().then(()=>(Tn(),xn)),k=T(m.map(x=>({ts:x.ts,app:x.app,to_state:x.to_state,type:x.type})),{minOccurrences:w,existingProfiles:p?.profiles??{}});b(i,200,{suggestions:k,windowDays:Math.round(h/(1440*6e4))});return}if(d[0]==="api"&&d[1]==="orchestrate"&&u==="POST"){let p=e.getConfig?.();if(!p){b(i,500,{error:"no config loaded"});return}let f=l.searchParams.get("profile");if(!f){b(i,400,{error:"profile query param required"});return}let h=(l.searchParams.get("goal")||"healthy").toLowerCase();if(!["serving","healthy","stable"].includes(h)){b(i,400,{error:"goal must be serving|healthy|stable"});return}let w=l.searchParams.get("timeoutMs")||l.searchParams.get("timeout"),m=w?Number(w):3e5;(!Number.isFinite(m)||m<=0)&&(m=3e5),m=Math.min(m,12e5);let T=l.searchParams.get("dryRun")==="true"||l.searchParams.get("dry-run")==="true",k=l.searchParams.get("budget"),x=k&&Number.isFinite(Number(k))?Number(k):void 0,{orchestrateProfile:$}=await Promise.resolve().then(()=>(or(),sr)),M=await $(r,p,{profile:f,goal:h,timeoutMs:m,dryRun:T,budgetTokens:x});if(M.error){b(i,404,M);return}b(i,200,M);return}if(d[0]==="api"&&d[1]==="discovery"&&d[2]==="explain"&&u==="GET"){let p=e.getConfig?.();if(!p){b(i,200,{searchRoots:[],scanned:0,rejected:{},warnings:[],suggestion:"no config loaded"});return}let{discoverApps:f}=await Promise.resolve().then(()=>(Mt(),De)),h={scanned:0,rejected:{}},w=[],m=f(p,{warnings:w,stats:h}),T=p.searchRoots.map(M=>typeof M=="string"?M:M.path),k=m.filter(M=>M.workspaceType==="polyglot"),x=m.map(M=>({name:M.name,workspaceType:M.workspaceType,serverProfile:M.serverProfile??M.workspaceType,workspaceRoot:M.workspaceRoot})),$=k.length>0?` \xB7 ${k.length} polyglot app${k.length===1?"":"s"} found (${[...new Set(k.map(M=>M.serverProfile))].join(", ")})`:"";b(i,200,{searchRoots:T,scanned:h.scanned,rejected:h.rejected,warnings:w,appsFound:m.length,apps:x,suggestion:m.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.":`${m.length} apps discovered${$}`});return}if(d[0]==="api"&&d[1]==="doctor"&&d[2]==="auto-fix"&&u==="POST"){if(!E())return;let p={};c.headers["content-length"]&&c.headers["content-length"]!=="0"&&await new Promise(k=>{let x=[];c.on("data",$=>x.push($)),c.on("end",()=>{try{p=JSON.parse(Buffer.concat(x).toString("utf8"))}catch{}k()})});let{runAutoFix:f,ALL_AUTO_FIX:h}=await Promise.resolve().then(()=>(Kt(),Xt)),m=e.getConfig?.()?.doctor?.autoFix?.permitted??h,T=Array.isArray(p.permitted)&&p.permitted.length?p.permitted:m;try{let k=await f({permitted:T,dryRun:!!p.dryRun});b(i,200,k)}catch(k){b(i,500,{error:k?.message??String(k)})}return}if(d[0]==="api"&&d[1]==="overview"&&u==="GET"){let p=e.getConfig?.(),f=r.list(),h=l.searchParams.get("workspace"),w=l.searchParams.get("profile"),m=f;if(h&&(m=m.filter(_=>_.workspaceLabel===h)),w){let _=p?.profiles?.[w]??null;_&&(m=m.filter(q=>_.includes(q.name)))}let T={apps:m.length,serving:m.filter(_=>_.status==="serving").length,errors:m.filter(_=>_.status==="error").length,stopped:m.filter(_=>_.status==="stopped").length,totalErrCount:m.reduce((_,q)=>_+q.errorCount,0),totalCpuPct:Math.round(m.reduce((_,q)=>_+(q.cpu??0),0)*10)/10,totalMemMb:Math.round(m.reduce((_,q)=>_+(q.memMB??0),0))},k={};for(let _ of m)(k[_.status]??=[]).push(_.name);let x=m.filter(_=>_.status==="error"||_.errorCount>0).map(_=>{let q=r.errors(_.name)??[],G=q[q.length-1],U=G?.parsed;return{name:_.name,status:_.status,errCount:_.errorCount,firstError:U?{file:U.file??null,line:U.line??null,code:U.code??null,message:U.message??G?.message??""}:G?{file:null,line:null,code:null,message:G.message}:null}}),$=Date.now()-5*6e4,M=r.events({sinceMs:5*6e4}).filter(_=>_.type==="status"&&_.ts>=$).filter(_=>h?m.some(q=>q.name===_.app):!0).filter(_=>w?m.some(q=>q.name===_.app):!0).slice(-5).map(_=>({name:_.app,transition:`${_.from??"?"}\u2192${_.to??"?"}`,msAgo:Date.now()-_.ts})),L={ts:Date.now(),version:bt,totals:T,byStatus:k,needsAttention:x,recentlyChanged:M};T.apps===0&&(L._meta={suggestion:"no apps registered. run 'daimon doctor' for recommended next step, or 'daimon init --auto' from a workspace folder."});let W=l.searchParams.get("budget"),V=W?Math.max(64,Number(W)|0):null;if(V){let _=V*4,q=0,G=0;for(;JSON.stringify(L).length>_&&(L.needsAttention.length||L.recentlyChanged.length);)if(L.needsAttention.length>1)L.needsAttention.pop(),q++;else if(L.recentlyChanged.length)L.recentlyChanged.pop(),G++;else if(L.needsAttention.length===1)L.needsAttention.pop(),q++;else break;q||G?L._meta={...L._meta??{},budget:V,omitted:{needsAttention:q,recentlyChanged:G}}:L._meta={...L._meta??{},budget:V}}b(i,200,L);return}if(d[0]!=="api"||d[1]!=="apps"){if(u==="GET"&&!l.pathname.startsWith("/metrics")){let p=ir();if(p){let f=l.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(f){let h=ot.resolve(p,f);if(h.startsWith(p)&&zt(i,h))return}if(!ot.extname(f||"")&&zt(i,ot.join(p,"index.html")))return}}b(i,404,{error:"not found"});return}if(d.length===2){if(u!=="GET"){b(i,405,{error:"method not allowed"});return}let p=ye(l,e.getConfig),f=r.list(),h=l.searchParams.get("cwd"),w=h&&h.length>0?h:null;w&&(f=f.filter(T=>{let k=r.getApp(T.name);return k?ft(k.workspaceRoot,w)||ft(w,k.workspaceRoot):!1}));let m=p==="full"?f:f.map(Ri);if(l.searchParams.get("stream")==="ndjson"){i.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});for(let T of m)i.write(JSON.stringify(T)+`
|
|
71
|
+
`);i.end();return}if(l.searchParams.get("explain")==="1"){let T=e.getConfig?.(),k={format:p};if(T){let{discoverApps:x}=await Promise.resolve().then(()=>(Mt(),De)),$={scanned:0,rejected:{}},M=[];x(T,{warnings:M,stats:$});let L=T.searchRoots.map(W=>typeof W=="string"?W:W.path);k={format:p,searchRoots:L,scanned:$.scanned,rejected:$.rejected,warnings:M,...w?{cwdScope:w}:{},suggestion:m.length===0?L.length===0?"no searchRoots configured. Run 'daimon init --auto' from a workspace folder to add the current cwd.":w?`no apps under cwd '${w}'. Run 'daimon list --all' to see apps from other workspaces, or 'daimon init --auto' to register this dir.`:"discovery returned no apps. Check that searchRoots contain nx.json / angular.json / vite.config.* / .storybook, then run 'daimon doctor'.":"apps discovered; _meta is informational."}}b(i,200,{apps:m,_meta:k});return}b(i,200,m);return}let C=decodeURIComponent(d[2]),y=d[3],P=d[4],I=l.searchParams.get("cwd")||null,J=r.resolveByCwd(C,I),S=C;if(J.kind==="unique"&&J.key)S=J.key;else if(J.kind==="none"&&I){b(i,404,{error:`no app named '${C}' under cwd '${I}'`,hint:"use --all (or omit cwd) to broaden the search, or --workspace <label> to target a specific workspace"});return}else if(J.kind==="collision"){b(i,412,{error:"name-collision",candidates:J.candidates,hint:I?"multiple apps under that cwd share this name \u2014 use --workspace <label> to disambiguate":"multiple workspaces share this app name \u2014 pass --cwd or --workspace <label>"});return}if(!y){if(u!=="GET"){b(i,405,{error:"method not allowed"});return}let p=r.summary(S);if(!p){b(i,404,{error:"unknown app"});return}ye(l,e.getConfig)==="full"?b(i,200,{...p,_meta:{format:"full"}}):b(i,200,{...jt(p),_meta:{format:"compact"}});return}let Q=(l.searchParams.get("level")||"error").toLowerCase(),Y=p=>{let f=p.level??"error";return Q==="all"?!0:Q==="warning"?f==="warning":Q==="lint"?f==="lint":f==="error"};if(y==="errors"&&P==="since-last"&&u==="GET"){let p=l.searchParams.get("client")||"default",f=n.getErrorCursor(p,S),h=r.errorsSince(S,f);if(h==null){b(i,404,{error:"unknown app"});return}let w=h.filter(Y),m=w.reduce((k,x)=>Math.max(k,x.lastSeen),f);m>f&&n.setErrorCursor(p,S,m);let T=ye(l,e.getConfig);b(i,200,T==="full"?w:w.map(ar));return}if(y==="errors"&&!P&&u==="GET"){let p=l.searchParams.get("since"),f=ye(l,e.getConfig);if(p){let{sinceMs:m,sinceTs:T}=jn(p),k=T??(m!=null?Date.now()-m:0),x=r.errorsSince(S,k);if(x==null){b(i,404,{error:"unknown app"});return}let $=x.filter(Y);b(i,200,f==="full"?$:$.map(ar));return}let h=r.errors(S);if(h==null){b(i,404,{error:"unknown app"});return}let w=h.filter(Y);b(i,200,f==="full"?w:w.map(ar));return}if(y==="logs"&&d[4]==="stream"&&u==="GET"){if(!r.summary(S)){b(i,404,{error:"unknown app"});return}i.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"});let p=r.logs(S,{tail:50})??[];for(let k of p)i.write(`data: ${JSON.stringify({ts:Date.now(),line:k})}
|
|
70
72
|
|
|
71
|
-
`);let
|
|
73
|
+
`);let f=[],h=0,w=()=>{for(;f.length&&i.write(f.shift()););},m=k=>{k.name===S&&(f.length>=200&&(h++,f.shift()),f.push(`data: ${JSON.stringify({ts:k.ts,line:k.line})}
|
|
72
74
|
|
|
73
|
-
`),
|
|
75
|
+
`),w())};r.on("log",m);let T=setInterval(()=>i.write(`: ping
|
|
74
76
|
|
|
75
|
-
`),3e4);
|
|
76
|
-
`)}catch{}};k({kind:"subscribed",app:
|
|
77
|
-
`)}catch{}},3e4),
|
|
78
|
-
`,"utf8"),e.reloadConfig)try{await e.reloadConfig()}catch{}w(o,200,{pinned:f,app:g,configPath:k,previous:C});return}if(m==="try-fix"&&c==="POST"){let u=r.summary(g);if(!u){w(o,404,{error:"unknown app"});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 f=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),S=f?Number(f):18e4;(!Number.isFinite(S)||S<=0)&&(S=18e4),S=Math.min(S,6e5);let T={status:u.status,health:u.health,errCount:u.errorCount,firstError:(r.errors(g)??[])[0]?.parsed??null},{runAutoFix:P,ALL_AUTO_FIX:k}=await Promise.resolve().then(()=>(Bt(),It)),C=e.getConfig?.()?.doctor?.autoFix?.permitted??k,y={ran:[],skipped:[],errors:[]};try{y=await P({permitted:C,dryRun:!1})}catch(q){y.errors.push({name:"auto-fix",error:q?.message??String(q)})}let A=(y.ran??[]).map(q=>q.name),_=null;try{let q=await r.restart(g);q?.ok||(_=q?.error??"restart failed")}catch(q){_=q?.message??String(q)}let U=await r.waitFor(g,d,S),$=r.summary(g),J=(r.errors(g)??[]).slice(0,5).map(q=>({file:q.parsed?.file??null,line:q.parsed?.line??null,code:q.parsed?.code??null,tool:q.parsed?.tool??null,message:q.parsed?.message??q.message})),B=$?{status:$.status,health:$.health,errCount:$.errorCount}:{status:U.status,health:U.health,errCount:0},nt=d==="serving"&&B.status==="serving"||d==="healthy"&&B.status==="serving"&&B.health==="healthy";w(o,200,{before:T,after:B,fixed:A,stillFailing:J,reached:nt,waitedMs:U.waitedMs,_meta:{autoFix:y,restartErr:_,timedOut:U.timedOut}});return}if(m==="wait"&&c==="GET"){if(!r.summary(g)){w(o,404,{error:"unknown app"});return}let u=(a.searchParams.get("until")||"serving").toLowerCase();if(!["serving","healthy","stopped","error"].includes(u)){w(o,400,{error:"until must be one of serving|healthy|stopped|error"});return}let d=a.searchParams.get("timeout"),f=d?Number(d):120;(!Number.isFinite(f)||f<=0)&&(f=120),f=Math.min(f,600);let S=await r.waitFor(g,u,f*1e3);w(o,200,S);return}if(m==="ensure"&&c==="POST"){let u=r.summary(g);if(!u){w(o,404,{error:"unknown app"});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 f=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),S=f?Number(f):18e4;(!Number.isFinite(S)||S<=0)&&(S=18e4),S=Math.min(S,6e5);let T=e.getConfig?.().healthProbe?.enabled??!0,P=d,k;if(P==="healthy"&&!T&&(P="serving",k="no health probe; treated serving as terminal"),P==="serving"&&u.status==="serving"||P==="healthy"&&u.status==="serving"&&u.health==="healthy"){w(o,200,{...Ct(u),_meta:{format:"compact",startedFromState:null,warning:k,waitedMs:0}});return}let C=u.status;u.status!=="starting"&&u.status!=="compiling"&&await r.start(g);let y=await r.waitFor(g,P,S),A=r.summary(g),_=A?Ct(A):{name:g,status:y.status,port:null,url:null,health:y.health,errCount:0,lastChangeMs:null,uptime:null};if(y.timedOut){w(o,200,{error:"timeout",state:_,_meta:{format:"compact",startedFromState:C,warning:k,waitedMs:y.waitedMs,timedOut:!0}});return}w(o,200,{..._,_meta:{format:"compact",startedFromState:C,warning:k,waitedMs:y.waitedMs}});return}if(m==="start"&&c==="POST"){if(a.searchParams.get("withDeps")==="1"){let f=await r.startWithDeps(g);w(o,f.ok?200:400,f);return}let d=await r.start(g);w(o,d.ok?200:400,d);return}if(m==="start-with-deps"&&c==="POST"){let u=await r.startWithDeps(g);w(o,u.ok?200:400,u);return}if(m==="tasks"&&c==="GET"&&!b){let u=r.listTasks(g);if(u==null){w(o,404,{error:"unknown app"});return}w(o,200,{tasks:u,watching:r.listWatchTasks(g)});return}if(m==="run"&&b&&c==="POST"){let u={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(S=>{let T=[];i.on("data",P=>T.push(P)),i.on("end",()=>{try{u=JSON.parse(Buffer.concat(T).toString("utf8"))}catch{}S()})});let d=Array.isArray(u.args)?u.args.map(String):[];if(u.watch){let S=r.startWatchTask(g,b,d);w(o,S.ok?200:400,S);return}let f=await r.runTask(g,b,d);if("error"in f){w(o,404,f);return}w(o,200,f);return}if(m==="run-stop"&&b&&c==="POST"){let u=await r.stopWatchTask(g,b);w(o,200,u);return}if(m==="env"&&c==="GET"){let d=r.getConfig().envFiles?.[g]??[],f=r.getState(g);w(o,200,{candidates:d,active:f?.activeEnvFile??null});return}if(m==="env"&&c==="POST"){let u={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(f=>{let S=[];i.on("data",T=>S.push(T)),i.on("end",()=>{try{u=JSON.parse(Buffer.concat(S).toString("utf8"))}catch{}f()})}),r.setActiveEnvFile(g,u.use??null);let d=r.getState(g);w(o,200,{active:d?.activeEnvFile??null});return}if(m==="requests"&&c==="GET"){if(!e.requestLog){w(o,200,[]);return}let u=Mt(a.searchParams.get("since"));w(o,200,e.requestLog.requests(g,u));return}if(m==="clean"&&c==="POST"){let u=a.searchParams.get("deep")==="1",d=a.searchParams.get("yes")==="1",f=Je(r,g,u);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(!d){w(o,200,{plan:f,hint:"pass --yes to delete"});return}let S=rn(r,g,u);w(o,200,S);return}if(m==="snapshot"&&c==="POST"){if(a.searchParams.get("write")==="1"){let f=Qr(r,g);if(!f){w(o,404,{error:"unknown app"});return}w(o,200,{snapshot:f.path});return}let d=qe(r,g);if(!d){w(o,404,{error:"unknown app"});return}w(o,200,d);return}if(m==="stop"&&c==="POST"){let u=await r.stop(g);w(o,u.ok?200:400,u);return}if(m==="restart"&&c==="POST"){let u=await r.restart(g);w(o,u.ok?200:400,u);return}if(c==="GET"&&!a.pathname.startsWith("/api/")&&!a.pathname.startsWith("/metrics")){let u=Ze();if(u){let d=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(d){let f=tt.resolve(u,d);if(f.startsWith(u)&&Ht(o,f))return}if(!tt.extname(d||"")&&Ht(o,tt.join(u,"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}Ke();import di from"node:http";import fi from"node:https";var mi=1e3,hi=500,gi=["/","/health","/-/health","/api/health","/ready","/healthz"];function Rn(r,t,e,n,s){if(t)return[t];let i=r.path||"/",o=r.fallbackHosts&&r.fallbackHosts.length?r.fallbackHosts:["127.0.0.1"];if(r.host||r.scheme){let c=e?de(e):null,l=r.scheme||c?.protocol?.replace(":","")||"http",p=r.host||c?.hostname||(n?o[0]:"127.0.0.1"),h=n??(c?.port?Number(c.port):null);return[Pn(l,p,h,i)]}if(e){let c=de(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,n,i))}function de(r){try{return new URL(r)}catch{return null}}function Pn(r,t,e,n){let s=t.includes(":")&&!t.startsWith("[")?`[${t}]`:t,i=e?`:${e}`:"";return`${r}://${s}${i}${n.startsWith("/")?n:"/"+n}`}var fe=class{constructor(t,e,n){this.registry=t;this.cfg=e;this.fullConfig=n;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 n=setTimeout(()=>{this.starting.delete(t),this.probe(t);let s=setInterval(()=>{this.probe(t)},this.cfg.intervalMs);this.timers.set(t,s)},hi);this.starting.set(t,n)}else{let n=this.timers.get(t);n&&(clearInterval(n),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 n=this.fullConfig?.overrides?.[t]?.url,s=this.registry.getApp(t),i=e.baseName??t,o=this.fullConfig?.overrides?.[t]?.healthProbePath??this.fullConfig?.overrides?.[i]?.healthProbePath,a=le(s?.serverProfile),c=this.cfg;o?c={...this.cfg,path:o}:e.discoveredHealthPath?c={...this.cfg,path:e.discoveredHealthPath}:a&&(this.cfg.path==="/"||!this.cfg.path)&&(c={...this.cfg,path:a});let l=Rn(c,n,e.announcedUrl,e.port,e.cachedProbeHost);if(!n&&!o&&!e.discoveredHealthPath&&(this.cfg.path==="/"||!this.cfg.path)&&e.health!=="healthy"&&this.discoverPath(t),l.length===0){this.registry.setLastHealthError(t,"no probe URL available"),this.registry.setHealth(t,"unhealthy");return}let p=null;for(let m of l){let b=await this.tryProbe(m);if(b.ok){let M=de(m);M&&this.registry.setCachedProbeHost(t,M.hostname.replace(/^\[|\]$/g,"")),this.registry.setResolvedUrl(t,m),this.registry.setLastHealthError(t,null),this.registry.setHealth(t,"healthy");return}p||(p=`${b.error} ${m}`)}let h=this.freshness.get(t);if(h&&!h.retried){h.retried=!0,setTimeout(()=>{this.probe(t)},mi);return}this.registry.setLastHealthError(t,p||"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 n of gi){let s={...this.cfg,path:n},i=Rn(s,void 0,e.announcedUrl,e.port,e.cachedProbeHost);for(let o of i)if((await this.tryProbe(o,{strict2xx:!0})).ok){e.discoveredHealthPath=n,this.registry.recordEvent({app:t,type:"health",message:`discovered probe path: ${n} (pin via POST /api/apps/${encodeURIComponent(t)}/health/pin or daimon pin-health ${t} --accept)`});return}}}tryProbe(t,e={}){return new Promise(n=>{let s=!1,i=p=>{s||(s=!0,n(p))},o=t.startsWith("https://"),a=o?fi:di,c={timeout:this.cfg.timeoutMs};if(o){let h=de(t)?.hostname?.replace(/^\[|\]$/g,"")??"",m=h==="127.0.0.1"||h==="::1"||h==="localhost";c.rejectUnauthorized=m?!1:!!this.cfg.rejectUnauthorized}let l=e.strict2xx?300:500;try{let p=a.get(t,c,h=>{let m=h.statusCode??0;h.resume(),e.strict2xx?m>=200&&m<l?i({ok:!0}):i({ok:!1,error:`http ${m}`}):fn(m)||m>=200&&m<l?i({ok:!0}):i({ok:!1,error:`http ${m}`})});p.on("timeout",()=>p.destroy(new Error("timeout"))),p.on("error",h=>{let m=h?.code||h?.message||"error";mn(h?.code)?i({ok:!1,error:`${m} (server not responding)`}):i({ok:!1,error:m})})}catch(p){i({ok:!1,error:p?.message||"throw"})}})}};import yi from"pidusage";var me=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 n of this.registry.names()){let s=this.registry.getState(n);s?.pid&&t.push({name:n,pid:s.pid})}if(!t.length)return;let e=!1;await Promise.all(t.map(async({name:n,pid:s})=>{try{let i=await yi(s),o=this.registry.getState(n);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(n);i&&(i.cpu!=null||i.memMB!=null)&&(i.cpu=null,i.memMB=null,e=!0)}})),e&&this.registry.emit("change")}};var he=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,n,s){if(this.stopped||s||!this.cfg.enabled||e===0&&!n)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 l=this.registry.getState(t);l&&(l.nextRestartAt=null),this.registry.start(t)},a);this.timers.set(t,c)}onUserStop(t){let e=this.timers.get(t);e&&(clearTimeout(e),this.timers.delete(t));let n=this.registry.getState(t);n&&(n.restartAttempts=0,n.restartWindowStart=null,n.nextRestartAt=null)}};import nr from"node:fs";import An from"node:path";import bi from"node:os";var sr=An.join(bi.homedir(),".daimon","state.json");function Cn(){try{let r=nr.readFileSync(sr,"utf8"),t=JSON.parse(r);if(t&&typeof t=="object"&&t.ports&&typeof t.ports=="object")return{ports:t.ports}}catch{}return{ports:{}}}var er=null,rr=null;function Mn(r){rr=r,!er&&(er=setTimeout(()=>{er=null;let t=rr;if(rr=null,!!t)try{nr.mkdirSync(An.dirname(sr),{recursive:!0}),nr.writeFileSync(sr,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: state write failed: ${e.message}
|
|
79
|
-
`)}},500))}
|
|
80
|
-
`;try{
|
|
81
|
-
`))}stop(){this.registry.off("event",this.onEvent)}onEvent=t=>{this.notifier&&(t.type==="status"&&t.to==="error"&&this.cfg.onError?this.fire(t.app,"error",`${t.app} \u2192 error`,t.message||"app entered error state"):t.type==="health"&&t.to==="unhealthy"&&this.cfg.onUnhealthy?this.fire(t.app,"unhealthy",`${t.app} unhealthy`,"health probe failing"):t.type==="stale"?this.fire(t.app,"stale",`${t.app} stale`,t.message||"no output despite source changes"):t.type==="compile-regression"?this.fire(t.app,"compile-regression",`${t.app} slow compile`,t.message||"compile time regression"):t.type==="bundle-regression"?this.fire(t.app,"bundle-regression",`${t.app} bundle grew`,t.message||"bundle size regression"):t.type==="task-run"&&/exit=[1-9]/.test(t.message||"")&&this.fire(t.app,"task-fail",`${t.app} task failed`,t.message||""))};fire(t,e,n,s){if(!this.notifier)return;let
|
|
82
|
-
`),this.proxies.delete(t)}),
|
|
83
|
-
`),{config:n,raw:e,applied:
|
|
84
|
-
`))}catch{}return s}function
|
|
77
|
+
`),3e4);c.on("close",()=>{r.off("log",m),clearInterval(T)});return}if(y==="logs"&&u==="GET"){let p=l.searchParams.get("tail"),f=l.searchParams.get("since"),h=r.logs(S,{tail:p?Number(p):void 0,sinceMs:Pt(f)});if(h==null){b(i,404,{error:"unknown app"});return}b(i,200,{lines:h});return}if(y==="focus"&&u==="POST"){let p=r.summary(S);if(!p){b(i,404,{error:"unknown app"});return}let f=(l.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy","stable"].includes(f)){b(i,400,{error:"until must be one of serving|healthy|stable"});return}let h=l.searchParams.get("timeoutMs")||l.searchParams.get("timeout"),w=h?Number(h):18e4;(!Number.isFinite(w)||w<=0)&&(w=18e4),w=Math.min(w,6e5);let m=l.searchParams.get("stableMs"),T=m&&Number.isFinite(Number(m))?Math.max(1e3,Number(m)):5e3;i.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8","cache-control":"no-cache",connection:"keep-alive"});let k=U=>{try{i.write(JSON.stringify(U)+`
|
|
78
|
+
`)}catch{}};k({kind:"subscribed",app:S,until:f,ts:Date.now(),state:jt(p)});let x=Date.now(),$=Date.now(),M=!1,L=U=>{if(M)return;M=!0,r.off("event",V),clearInterval(_),clearInterval(q),clearTimeout(G);let lt=r.summary(S);k({kind:"done",reason:U,ts:Date.now(),state:lt?jt(lt):null,waitedMs:Date.now()-x});try{i.end()}catch{}},W=()=>{let U=r.summary(S);if(!U)return!1;if(f==="serving")return U.status==="serving";if(f==="healthy")return U.status==="serving"&&U.health==="healthy";if(f==="stable"){let lt=Date.now()-$;return U.status==="serving"&&U.health==="healthy"&<>=T}return!1},V=U=>{if(U.app===S)if($=Date.now(),U.type==="status")k({kind:"status",from:U.from,to:U.to,ts:U.ts}),f!=="stable"&&W()&&L("reached");else if(U.type==="error-new"||U.type==="error-recur"){let K=(r.errors(S)??[])[0];K&&k({kind:"error",message:K.message,parsed:K.parsed??null,ts:U.ts})}else U.type==="health"&&(k({kind:"health",from:U.from,to:U.to,ts:U.ts}),f!=="stable"&&W()&&L("reached"))};r.on("event",V);let _=setInterval(()=>{W()&&L("reached")},1e3),q=setInterval(()=>{try{i.write(`
|
|
79
|
+
`)}catch{}},3e4),G=setTimeout(()=>L("timeout"),w);c.on("close",()=>L("closed")),W()&&L("reached");return}if(y==="health"&&P==="pin"&&u==="POST"){let p=r.getState(S);if(!p){b(i,404,{error:"unknown app"});return}let f={};c.headers["content-length"]&&c.headers["content-length"]!=="0"&&await new Promise(M=>{let L=[];c.on("data",W=>L.push(W)),c.on("end",()=>{try{f=JSON.parse(Buffer.concat(L).toString("utf8"))}catch{}M()})});let h=typeof f.path=="string"&&f.path?f.path:p.discoveredHealthPath??null;if(!h){b(i,400,{error:"no path supplied and no discoveredHealthPath on app"});return}let{configLookupPaths:w}=await Promise.resolve().then(()=>(Ht(),Er)),{local:m,user:T}=w(),k=vt.existsSync(m)?m:T,x={};try{x=JSON.parse(vt.readFileSync(k,"utf8"))}catch{}(!x.overrides||typeof x.overrides!="object")&&(x.overrides={}),(!x.overrides[S]||typeof x.overrides[S]!="object")&&(x.overrides[S]={});let $=x.overrides[S].healthProbePath??null;if(x.overrides[S].healthProbePath=h,vt.writeFileSync(k,JSON.stringify(x,null,2)+`
|
|
80
|
+
`,"utf8"),e.reloadConfig)try{await e.reloadConfig()}catch{}b(i,200,{pinned:h,app:S,configPath:k,previous:$});return}if(y==="try-fix"&&u==="POST"){let p=r.summary(S);if(!p){b(i,404,{error:"unknown app"});return}let f=(l.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(f)){b(i,400,{error:"until must be serving|healthy"});return}let h=l.searchParams.get("timeoutMs")||l.searchParams.get("timeout"),w=h?Number(h):18e4;(!Number.isFinite(w)||w<=0)&&(w=18e4),w=Math.min(w,6e5);let m={status:p.status,health:p.health,errCount:p.errorCount,firstError:(r.errors(S)??[])[0]?.parsed??null},{runAutoFix:T,ALL_AUTO_FIX:k}=await Promise.resolve().then(()=>(Kt(),Xt)),$=e.getConfig?.()?.doctor?.autoFix?.permitted??k,M={ran:[],skipped:[],errors:[]};try{M=await T({permitted:$,dryRun:!1})}catch(K){M.errors.push({name:"auto-fix",error:K?.message??String(K)})}let L=(M.ran??[]).map(K=>K.name),W=null;try{let K=await r.restart(S);K?.ok||(W=K?.error??"restart failed")}catch(K){W=K?.message??String(K)}let V=await r.waitFor(S,f,w),_=r.summary(S),G=(r.errors(S)??[]).slice(0,5).map(K=>({file:K.parsed?.file??null,line:K.parsed?.line??null,code:K.parsed?.code??null,tool:K.parsed?.tool??null,message:K.parsed?.message??K.message})),U=_?{status:_.status,health:_.health,errCount:_.errorCount}:{status:V.status,health:V.health,errCount:0},lt=f==="serving"&&U.status==="serving"||f==="healthy"&&U.status==="serving"&&U.health==="healthy";b(i,200,{before:m,after:U,fixed:L,stillFailing:G,reached:lt,waitedMs:V.waitedMs,_meta:{autoFix:M,restartErr:W,timedOut:V.timedOut}});return}if(y==="wait"&&u==="GET"){if(!r.summary(S)){b(i,404,{error:"unknown app"});return}let p=(l.searchParams.get("until")||"serving").toLowerCase();if(!["serving","healthy","stopped","error"].includes(p)){b(i,400,{error:"until must be one of serving|healthy|stopped|error"});return}let f=l.searchParams.get("timeout"),h=f?Number(f):120;(!Number.isFinite(h)||h<=0)&&(h=120),h=Math.min(h,600);let w=await r.waitFor(S,p,h*1e3);b(i,200,w);return}if(y==="ensure"&&u==="POST"){let p=r.summary(S);if(!p){b(i,404,{error:"unknown app"});return}let f=(l.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(f)){b(i,400,{error:"until must be serving|healthy"});return}let h=l.searchParams.get("timeoutMs")||l.searchParams.get("timeout"),w=h?Number(h):18e4;(!Number.isFinite(w)||w<=0)&&(w=18e4),w=Math.min(w,6e5);let m=e.getConfig?.().healthProbe?.enabled??!0,T=f,k;if(T==="healthy"&&!m&&(T="serving",k="no health probe; treated serving as terminal"),T==="serving"&&p.status==="serving"||T==="healthy"&&p.status==="serving"&&p.health==="healthy"){b(i,200,{...jt(p),_meta:{format:"compact",startedFromState:null,warning:k,waitedMs:0}});return}let $=p.status;p.status!=="starting"&&p.status!=="compiling"&&await r.start(S);let M=await r.waitFor(S,T,w),L=r.summary(S),W=L?jt(L):{name:S,status:M.status,port:null,url:null,health:M.health,errCount:0,lastChangeMs:null,uptime:null};if(M.timedOut){b(i,200,{error:"timeout",state:W,_meta:{format:"compact",startedFromState:$,warning:k,waitedMs:M.waitedMs,timedOut:!0}});return}b(i,200,{...W,_meta:{format:"compact",startedFromState:$,warning:k,waitedMs:M.waitedMs}});return}let z=p=>{let f=l.searchParams.get("steal");if(f==="1"||f==="true")return o.steal(S,A,p),!0;let w=o.acquire(S,A,p);return w?(b(i,409,{error:"locked-by-other-agent",agent:w.agent,lockedAt:w.lockedAt,expiresAt:w.expiresAt,hint:"pass ?steal=1 to override, or wait for the lock to expire"}),!1):!0};if(y==="lock"&&u==="GET"){if(!r.summary(S)){b(i,404,{error:"unknown app"});return}let p=o.current(S),f=o.recentInteractions(S,3);b(i,200,{app:S,current:p,recent:f});return}if(y==="handoff"&&u==="POST"){if(!r.summary(S)){b(i,404,{error:"unknown app"});return}let p={};c.headers["content-length"]&&c.headers["content-length"]!=="0"&&await new Promise(m=>{let T=[];c.on("data",k=>T.push(k)),c.on("end",()=>{try{p=JSON.parse(Buffer.concat(T).toString("utf8"))}catch{}m()})});let f=typeof p?.to=="string"?p.to.trim():"";if(!f){b(i,400,{error:"body { to: <agentId> } required"});return}let h=o.current(S),w=o.handoff(S,f,A==="unknown"?null:A);b(i,200,{handedOff:S,from:h?.agent??null,to:w.agent,lockedAt:w.lockedAt,expiresAt:w.expiresAt});return}if(y==="start"&&u==="POST"){if(!z("start"))return;if(l.searchParams.get("withDeps")==="1"){let h=await r.startWithDeps(S);b(i,h.ok?200:400,h);return}let f=await r.start(S);b(i,f.ok?200:400,f);return}if(y==="start-with-deps"&&u==="POST"){if(!z("start-with-deps"))return;let p=await r.startWithDeps(S);b(i,p.ok?200:400,p);return}if(y==="tasks"&&u==="GET"&&!P){let p=r.listTasks(S);if(p==null){b(i,404,{error:"unknown app"});return}b(i,200,{tasks:p,watching:r.listWatchTasks(S)});return}if(y==="run"&&P&&u==="POST"){let p={};c.headers["content-length"]&&c.headers["content-length"]!=="0"&&await new Promise(w=>{let m=[];c.on("data",T=>m.push(T)),c.on("end",()=>{try{p=JSON.parse(Buffer.concat(m).toString("utf8"))}catch{}w()})});let f=Array.isArray(p.args)?p.args.map(String):[];if(p.watch){let w=r.startWatchTask(S,P,f);b(i,w.ok?200:400,w);return}let h=await r.runTask(S,P,f);if("error"in h){b(i,404,h);return}b(i,200,h);return}if(y==="run-stop"&&P&&u==="POST"){let p=await r.stopWatchTask(S,P);b(i,200,p);return}if(y==="env"&&u==="GET"){let f=r.getConfig().envFiles?.[S]??[],h=r.getState(S);b(i,200,{candidates:f,active:h?.activeEnvFile??null});return}if(y==="env"&&u==="POST"){let p={};c.headers["content-length"]&&c.headers["content-length"]!=="0"&&await new Promise(h=>{let w=[];c.on("data",m=>w.push(m)),c.on("end",()=>{try{p=JSON.parse(Buffer.concat(w).toString("utf8"))}catch{}h()})}),r.setActiveEnvFile(S,p.use??null);let f=r.getState(S);b(i,200,{active:f?.activeEnvFile??null});return}if(y==="requests"&&u==="GET"){if(!e.requestLog){b(i,200,[]);return}let p=Pt(l.searchParams.get("since"));b(i,200,e.requestLog.requests(S,p));return}if(y==="clean"&&u==="POST"){let p=l.searchParams.get("deep")==="1",f=l.searchParams.get("yes")==="1",h=tr(r,S,p);if(!h){b(i,404,{error:"unknown app"});return}if(h.ranOnServing){b(i,409,{error:"refusing: app is currently running",plan:h});return}if(!f){b(i,200,{plan:h,hint:"pass --yes to delete"});return}let w=dn(r,S,p);b(i,200,w);return}if(y==="snapshot"&&u==="POST"){if(l.searchParams.get("write")==="1"){let h=ln(r,S);if(!h){b(i,404,{error:"unknown app"});return}b(i,200,{snapshot:h.path});return}let f=Qe(r,S);if(!f){b(i,404,{error:"unknown app"});return}b(i,200,f);return}if(y==="stop"&&u==="POST"){if(!z("stop"))return;let p=await r.stop(S);b(i,p.ok?200:400,p);return}if(y==="restart"&&u==="POST"){if(!z("restart"))return;let p=await r.restart(S);b(i,p.ok?200:400,p);return}if(u==="GET"&&!l.pathname.startsWith("/api/")&&!l.pathname.startsWith("/metrics")){let p=ir();if(p){let f=l.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(f){let h=ot.resolve(p,f);if(h.startsWith(p)&&zt(i,h))return}if(!ot.extname(f||"")&&zt(i,ot.join(p,"index.html")))return}}b(i,404,{error:"not found"})}catch(l){b(i,500,{error:l?.message||String(l)})}});return a.listen(t,"127.0.0.1"),a}rr();import Ci from"node:http";import Mi from"node:https";var Oi=1e3,Ni=500,$i=["/","/health","/-/health","/api/health","/ready","/healthz"];function In(r,t,e,n,s){if(t)return[t];let o=r.path||"/",a=r.fallbackHosts&&r.fallbackHosts.length?r.fallbackHosts:["127.0.0.1"];if(r.host||r.scheme){let i=e?be(e):null,l=r.scheme||i?.protocol?.replace(":","")||"http",u=r.host||i?.hostname||(n?a[0]:"127.0.0.1"),d=n??(i?.port?Number(i.port):null);return[Fn(l,u,d,o)]}if(e){let i=be(e);if(i)return i.pathname=o,[i.toString()]}let c=[];s&&c.push(s);for(let i of a)c.includes(i)||c.push(i);return c.map(i=>Fn("http",i,n,o))}function be(r){try{return new URL(r)}catch{return null}}function Fn(r,t,e,n){let s=t.includes(":")&&!t.startsWith("[")?`[${t}]`:t,o=e?`:${e}`:"";return`${r}://${s}${o}${n.startsWith("/")?n:"/"+n}`}var we=class{constructor(t,e,n){this.registry=t;this.cfg=e;this.fullConfig=n;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 n=setTimeout(()=>{this.starting.delete(t),this.probe(t);let s=setInterval(()=>{this.probe(t)},this.cfg.intervalMs);this.timers.set(t,s)},Ni);this.starting.set(t,n)}else{let n=this.timers.get(t);n&&(clearInterval(n),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 n=this.fullConfig?.overrides?.[t]?.url,s=this.registry.getApp(t),o=e.baseName??t,a=this.fullConfig?.overrides?.[t]?.healthProbePath??this.fullConfig?.overrides?.[o]?.healthProbePath,c=he(s?.serverProfile),i=this.cfg;a?i={...this.cfg,path:a}:e.discoveredHealthPath?i={...this.cfg,path:e.discoveredHealthPath}:c&&(this.cfg.path==="/"||!this.cfg.path)&&(i={...this.cfg,path:c});let l=In(i,n,e.announcedUrl,e.port,e.cachedProbeHost);if(!n&&!a&&!e.discoveredHealthPath&&(this.cfg.path==="/"||!this.cfg.path)&&e.health!=="healthy"&&this.discoverPath(t),l.length===0){this.registry.setLastHealthError(t,"no probe URL available"),this.registry.setHealth(t,"unhealthy");return}let u=null;for(let g of l){let v=await this.tryProbe(g);if(v.ok){let A=be(g);A&&this.registry.setCachedProbeHost(t,A.hostname.replace(/^\[|\]$/g,"")),this.registry.setResolvedUrl(t,g),this.registry.setLastHealthError(t,null),this.registry.setHealth(t,"healthy");return}u||(u=`${v.error} ${g}`)}let d=this.freshness.get(t);if(d&&!d.retried){d.retried=!0,setTimeout(()=>{this.probe(t)},Oi);return}this.registry.setLastHealthError(t,u||"unknown probe failure"),this.registry.setHealth(t,"unhealthy")}async discoverPath(t){let e=this.registry.getState(t);if(!(!e||e.status!=="serving")&&!e.discoveredHealthPath)for(let n of $i){let s={...this.cfg,path:n},o=In(s,void 0,e.announcedUrl,e.port,e.cachedProbeHost);for(let a of o)if((await this.tryProbe(a,{strict2xx:!0})).ok){e.discoveredHealthPath=n,this.registry.recordEvent({app:t,type:"health",message:`discovered probe path: ${n} (pin via POST /api/apps/${encodeURIComponent(t)}/health/pin or daimon pin-health ${t} --accept)`});return}}}tryProbe(t,e={}){return new Promise(n=>{let s=!1,o=u=>{s||(s=!0,n(u))},a=t.startsWith("https://"),c=a?Mi:Ci,i={timeout:this.cfg.timeoutMs};if(a){let d=be(t)?.hostname?.replace(/^\[|\]$/g,"")??"",g=d==="127.0.0.1"||d==="::1"||d==="localhost";i.rejectUnauthorized=g?!1:!!this.cfg.rejectUnauthorized}let l=e.strict2xx?300:500;try{let u=c.get(t,i,d=>{let g=d.statusCode??0;d.resume(),e.strict2xx?g>=200&&g<l?o({ok:!0}):o({ok:!1,error:`http ${g}`}):En(g)||g>=200&&g<l?o({ok:!0}):o({ok:!1,error:`http ${g}`})});u.on("timeout",()=>u.destroy(new Error("timeout"))),u.on("error",d=>{let g=d?.code||d?.message||"error";Rn(d?.code)?o({ok:!1,error:`${g} (server not responding)`}):o({ok:!1,error:g})})}catch(u){o({ok:!1,error:u?.message||"throw"})}})}};import _i from"pidusage";var ve=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 n of this.registry.names()){let s=this.registry.getState(n);s?.pid&&t.push({name:n,pid:s.pid})}if(!t.length)return;let e=!1;await Promise.all(t.map(async({name:n,pid:s})=>{try{let o=await _i(s),a=this.registry.getState(n);if(!a)return;let c=Math.round(o.cpu*10)/10,i=Math.round(o.memory/(1024*1024));(a.cpu!==c||a.memMB!==i)&&(a.cpu=c,a.memMB=i,e=!0)}catch{let o=this.registry.getState(n);o&&(o.cpu!=null||o.memMB!=null)&&(o.cpu=null,o.memMB=null,e=!0)}})),e&&this.registry.emit("change")}};var Se=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,n,s){if(this.stopped||s||!this.cfg.enabled||e===0&&!n)return;let o=this.registry.getState(t);if(!o)return;let a=Date.now();if((o.restartWindowStart==null||a-o.restartWindowStart>this.cfg.windowMs)&&(o.restartWindowStart=a,o.restartAttempts=0),o.restartAttempts+=1,o.restartAttempts>this.cfg.maxAttempts){o.lastStatusMessage=`auto-restart aborted (${o.restartAttempts-1}/${this.cfg.maxAttempts} within window)`,o.nextRestartAt=null,this.registry.recordEvent({app:t,type:"restart-scheduled",message:o.lastStatusMessage}),this.registry.emit("change");return}let c=Math.min(2**(o.restartAttempts-1)*1e3,3e4);o.nextRestartAt=a+c,o.lastStatusMessage=`restarting in ${Math.round(c/1e3)}s (attempt ${o.restartAttempts}/${this.cfg.maxAttempts})`,this.registry.recordEvent({app:t,type:"restart-scheduled",message:o.lastStatusMessage}),this.registry.emit("change");let i=setTimeout(()=>{this.timers.delete(t);let l=this.registry.getState(t);l&&(l.nextRestartAt=null),this.registry.start(t)},c);this.timers.set(t,i)}onUserStop(t){let e=this.timers.get(t);e&&(clearTimeout(e),this.timers.delete(t));let n=this.registry.getState(t);n&&(n.restartAttempts=0,n.restartWindowStart=null,n.nextRestartAt=null)}};import pr from"node:fs";import Bn from"node:path";import Li from"node:os";var dr=Bn.join(Li.homedir(),".daimon","state.json");function Hn(){try{let r=pr.readFileSync(dr,"utf8"),t=JSON.parse(r);if(t&&typeof t=="object"&&t.ports&&typeof t.ports=="object")return{ports:t.ports}}catch{}return{ports:{}}}var lr=null,ur=null;function Un(r){ur=r,!lr&&(lr=setTimeout(()=>{lr=null;let t=ur;if(ur=null,!!t)try{pr.mkdirSync(Bn.dirname(dr),{recursive:!0}),pr.writeFileSync(dr,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: state write failed: ${e.message}
|
|
81
|
+
`)}},500))}er();ne();import Wn from"node:fs";import ji from"node:os";import qn from"node:path";import{createRequire as Di}from"node:module";var Ii=Di(import.meta.url),Fi=6e4,ke=class{constructor(t,e){this.registry=t;this.cfg=e;this.logFile=qn.join(ji.homedir(),".daimon","notifications.log");try{Wn.mkdirSync(qn.dirname(this.logFile),{recursive:!0})}catch{}if(!e.enabled){this.audit("init","disabled by config");return}try{let n=Ii("node-notifier");if(this.notifier=n,process.platform==="win32")try{let s=n.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(n){this.warnOnce(`node-notifier unavailable: ${n?.message||n}`),this.audit("init",`node-notifier load failed: ${n?.message||n}`);return}t.on("event",this.onEvent)}registry;cfg;notifier=null;toaster=null;lastSent=new Map;warned=!1;logFile;audit(t,e){let n=`${new Date().toISOString()} ${t} ${e}
|
|
82
|
+
`;try{Wn.appendFileSync(this.logFile,n)}catch{}}warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] notifier: ${t}
|
|
83
|
+
`))}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,n,s){if(!this.notifier)return;let o=`${t}::${e}`,a=this.lastSent.get(o)??0,c=Date.now();if(c-a<Fi){this.audit("throttled",`${o}`);return}this.lastSent.set(o,c);let i={title:`daimon: ${n}`,message:s,wait:!1,appID:"daimon"},l=(u,d)=>{u?(this.audit("fail",`${o} :: ${u?.message||u}`),this.warnOnce(`notify failed: ${u?.message||u}`)):this.audit("ok",`${o} :: ${n} :: ${d??"(no response)"}`)};try{this.audit("attempt",`${o} :: ${n}`),(this.toaster??this.notifier).notify(i,l)}catch(u){this.audit("throw",`${o} :: ${u?.message||u}`),this.warnOnce(`notify threw: ${u?.message||u}`)}}};import Gn from"node:fs";import fr from"node:path";var Bi=5e3,Hi=3e4,Ui=new Set(["node_modules","dist",".angular",".nx",".git","tmp","out-tsc","coverage"]),Wi=new Set([".ts",".tsx",".html",".scss",".css",".js",".jsx",".json"]),xe=class{constructor(t,e){this.registry=t;this.cfg=e;e.enabled&&(this.timer=setInterval(()=>this.tick(),Bi),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),n=this.registry.getApp(t);if(!e||!n)return;if(e.status!=="serving"){e.stale&&this.registry.setStale(t,!1);return}if(e.startedAt==null)return;let s=e.lastLogTs??e.startedAt,o=Date.now()-s;if(o<this.cfg.silentMs){e.stale&&this.registry.setStale(t,!1);return}let a=e.lastCompileAt??e.startedAt;this.hasSourceChange(n.workspaceRoot,a,e.lastCompileAt)&&(e.stale||(this.registry.setStale(t,!0),this.registry.recordEvent({app:t,type:"stale",message:`no output in ${Math.round(o/1e3)}s despite source changes`})))}hasSourceChange(t,e,n){let s=this.caches.get(t);if(!s||Date.now()-s.ts>Hi||n!=null&&s.ts<n){let c=this.scan(t);this.caches.set(t,{ts:Date.now(),files:c})}return this.caches.get(t).files.some(c=>c.mtime>e)}scan(t){let e=[],n=(s,o)=>{if(o>8||e.length>4e3)return;let a;try{a=Gn.readdirSync(s,{withFileTypes:!0})}catch{return}for(let c of a)if(!c.name.startsWith(".git")){if(c.isDirectory()){if(Ui.has(c.name))continue;n(fr.join(s,c.name),o+1)}else if(c.isFile()){let i=fr.extname(c.name);if(!Wi.has(i))continue;try{let l=fr.join(s,c.name),u=Gn.statSync(l);e.push({path:l,mtime:u.mtimeMs})}catch{}}}};return n(t,0),e}};import Jn from"node:http";var Te=200,Ee=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 n=this.proxies.has(t);e.status==="serving"&&e.port&&!n?this.startProxy(t,e.port):e.status!=="serving"&&n&&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 n=e+this.cfg.portOffset,s=[],o=Jn.createServer((a,c)=>{let i=Date.now(),l={hostname:"127.0.0.1",port:e,method:a.method,path:a.url,headers:{...a.headers,host:`127.0.0.1:${e}`}},u=Jn.request(l,d=>{c.writeHead(d.statusCode||502,d.headers),d.pipe(c);let g=()=>{s.push({ts:Date.now(),method:a.method||"GET",path:a.url||"/",status:d.statusCode||0,durationMs:Date.now()-i}),s.length>Te&&s.splice(0,s.length-Te)};d.on("end",g),d.on("error",g)});u.on("error",()=>{c.writeHead(502).end("upstream error"),s.push({ts:Date.now(),method:a.method||"GET",path:a.url||"/",status:502,durationMs:Date.now()-i}),s.length>Te&&s.splice(0,s.length-Te)}),a.pipe(u)});o.on("error",a=>{a?.code==="EADDRINUSE"&&process.stderr.write(`[daimon] requestLog: port ${n} in use for ${t}; disabling proxy
|
|
84
|
+
`),this.proxies.delete(t)}),o.listen(n,"127.0.0.1",()=>{this.proxies.set(t,{app:t,proxyPort:n,server:o,buffer:s})})}requests(t,e){let n=this.proxies.get(t);if(!n)return[];if(e){let s=Date.now()-e;return n.buffer.filter(o=>o.ts>=s)}return[...n.buffer]}proxyPortFor(t){return this.proxies.get(t)?.proxyPort??null}};At();Ht();Mt();import mr from"node:fs";var qi=new Set(["command","port","env","url"]);function Xn(r){let t=mr.readFileSync(r,"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 Kn(r,t){if(t===null)return null;if(typeof t!="object"||Array.isArray(t))return t;let e=r&&typeof r=="object"&&!Array.isArray(r)?{...r}:{};for(let[n,s]of Object.entries(t))s===null?delete e[n]:e[n]=Kn(e[n],s);return e}function Gi(r,t){let e=r+"."+process.pid+".tmp";mr.writeFileSync(e,t,"utf8"),mr.renameSync(e,r)}function Ji(r,t){let e=new Set;for(let n of Object.keys(t))JSON.stringify(r?.[n])!==JSON.stringify(t[n])&&e.add(n);for(let n of Object.keys(r||{}))n in t||e.add(n);return[...e]}function zn(r){let t=Xn(r.configPath),e=Kn(t,r.patch);if(!e||typeof e!="object")throw new Error("patch produced non-object config");let n=Vt(e,r.configPath);return Gi(r.configPath,JSON.stringify(e,null,2)+`
|
|
85
|
+
`),{config:n,raw:e,applied:Ji(t,e),prevRaw:t}}function hr(r){let t=Xn(r.configPath),e=Vt(t,r.configPath);return Xi(r.registry,e)}function Xi(r,t){let e=r.getConfig();for(let l of Object.keys(e))e[l]=void 0;Object.assign(e,t);let n=new Set(r.names()),s=Et(e),o=new Set(s.map(l=>l.name)),a=[],c=[];for(let l of s)n.has(l.name)?r.updateDiscoveredApp(l):(r.addDiscoveredApp(l),a.push(l.name));for(let l of n)o.has(l)||c.push(l);let i=[];for(let l of r.names()){let u=r.getState(l);if(u&&(u.status==="serving"||u.status==="compiling")){let d=e.overrides?.[l];if(!d)continue;for(let g of qi)if(g in d){i.push(l);break}}}return{addedApps:a,removedApps:c,restartRequired:i,config:e}}Ut();At();import Yn from"node:fs";import Ki from"node:os";import Vn from"node:path";var zi=/key|secret|token|password|pass/i;function Yi(r){if(!r)return null;let t=JSON.parse(JSON.stringify(r));if(t.apiToken&&(t.apiToken="***"),t.overrides)for(let e of Object.keys(t.overrides)){let n=t.overrides[e]?.env;if(n)for(let s of Object.keys(n))zi.test(s)&&(n[s]="***")}return t}function Vi(r,t=200){if(!r)return[];let e=[];for(let n of r.names()){let s=r.getState(n);if(s)for(let o of s.logBuffer)e.push({ts:o.ts,line:`[${n}] ${o.line}`})}return e.sort((n,s)=>n.ts-s.ts),e.slice(-t).map(n=>n.line)}function Zi(){let r=Vn.join(wt(),"crashes");return Yn.mkdirSync(r,{recursive:!0}),r}function Qi(r,t,e){let n=new Date().toISOString().replace(/[:.]/g,"-"),s=Vn.join(Zi(),`${n}.txt`),o=r,a=[`daimon crash dump @ ${new Date().toISOString()}`,`version: ${bt}`,`node: ${process.version}`,`platform: ${process.platform} ${Ki.release()}`,`cwd: ${process.cwd()}`,`pid: ${process.pid}`,"","ERROR:",o?.stack||String(o),"","CONFIG (redacted):",JSON.stringify(Yi(e),null,2),"","RECENT LOG (last 200 lines across apps):",...Vi(t,200)];try{Yn.writeFileSync(s,a.join(`
|
|
86
|
+
`))}catch{}return s}function Zn(r){let t=e=>{let n=null;try{n=Qi(e,r.getRegistry(),r.getConfig())}catch{}try{process.stderr.write(`[daimon] fatal: ${e?.stack||e}
|
|
85
87
|
`)}catch{}if(n)try{process.stderr.write(`[daimon] crash dump: ${n}
|
|
86
|
-
`)}catch{}process.exit(1)};process.on("uncaughtException",t),process.on("unhandledRejection",t)}Lt();var cr=1e3,Di=60,Fi=256;function we(r,t){if(r.length===0)return 0;let e=[...r].sort((s,i)=>s-i),n=Math.min(e.length-1,Math.floor((e.length-1)*t));return Math.round(e[n]*100)/100}var Se=class{constructor(t){this.history=t;this.start()}history;startMs=Date.now();lagTimer=null;lagSamples=[];querySamples=[];lockContentionCount=0;lastTickAt=Date.now();highLagStreak=0;warnedAtStreak=0;onSelfWarn=null;start(){let t=performance.now();this.lagTimer=setInterval(()=>{let e=performance.now(),n=Math.max(0,e-t-cr);t=e,this.lagSamples.push(n),this.lagSamples.length>Di&&this.lagSamples.shift(),this.lastTickAt=Date.now(),n>100?(this.highLagStreak++,this.highLagStreak>=5&&this.highLagStreak>this.warnedAtStreak&&this.onSelfWarn&&(this.warnedAtStreak=this.highLagStreak,this.onSelfWarn(`event loop lag sustained: ${Math.round(n)}ms (${this.highLagStreak} consecutive ticks)`))):(this.highLagStreak=0,this.warnedAtStreak=0)},cr),this.lagTimer.unref&&this.lagTimer.unref()}setSelfWarnHandler(t){this.onSelfWarn=t}recordQueryMs(t){this.querySamples.push(t),this.querySamples.length>Fi&&this.querySamples.shift()}incLockContention(){this.lockContentionCount++}snapshot(){let t=process.memoryUsage(),e=1024*1024;return{pid:process.pid,version:dt,uptimeMs:Date.now()-this.startMs,rssMB:Math.round(t.rss/e*10)/10,heapUsedMB:Math.round(t.heapUsed/e*10)/10,heapTotalMB:Math.round(t.heapTotal/e*10)/10,eventLoopLagMs:this.lagSamples.length?Math.round(this.lagSamples[this.lagSamples.length-1]*100)/100:0,eventLoopLagP95Ms:we(this.lagSamples,.95),historyDbQueryMs:{p50:we(this.querySamples,.5),p95:we(this.querySamples,.95),p99:we(this.querySamples,.99)},lockContentionCount:this.lockContentionCount,tickIntervalMs:cr,lastTickAt:this.lastTickAt}}stop(){this.lagTimer&&clearInterval(this.lagTimer),this.lagTimer=null}};import Ii from"node:fs";import Hn from"node:path";import Bi from"node:os";import{pathToFileURL as Hi}from"node:url";function Un(r){return r&&typeof r=="string"&&r.trim()?r:Hn.join(Bi.homedir(),".daimon","plugins")}function Ui(r){return r.startsWith("doctor-")&&r.endsWith(".mjs")}function Wi(r){if(!r||typeof r!="object")return{ok:!1,error:"module has no default export"};let t=r.default??r;return t?typeof t.name!="string"||!t.name.length?{ok:!1,error:"plugin.name must be a non-empty string"}:/^[a-z][a-z0-9-]*$/.test(t.name)?typeof t.scan!="function"?{ok:!1,error:"plugin.scan must be a function"}:t.fix!==void 0&&typeof t.fix!="function"?{ok:!1,error:"plugin.fix, if present, must be a function"}:t.undo!==void 0&&typeof t.undo!="function"?{ok:!1,error:"plugin.undo, if present, must be a function"}:{ok:!0,plugin:t}:{ok:!1,error:`plugin.name must be kebab-case (got "${t.name}")`}:{ok:!1,error:"plugin shape is null"}}var Gi=new Set(["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root"]);async function Wn(r){let t=[],e;try{e=Ii.readdirSync(r).filter(Ui).sort()}catch{return t}let n=new Set;for(let s of e){let i=Hn.join(r,s);try{let o=await import(Hi(i).href+`?t=${Date.now()}`),a=Wi(o);if(!a.ok){t.push({name:s,file:i,status:"failed",error:a.error});continue}let c=a.plugin;if(Gi.has(c.name)){t.push({name:c.name,file:i,status:"failed",error:`name collides with built-in rule "${c.name}"`});continue}if(n.has(c.name)){t.push({name:c.name,file:i,status:"failed",error:"duplicate plug-in name"});continue}n.add(c.name),t.push({name:c.name,description:c.description,file:i,status:"ok",module:c})}catch(o){t.push({name:s,file:i,status:"failed",error:o?.message??String(o)})}}return t}async function Gn(r,t){for(let e of r)if(!(e.status!=="ok"||!e.module))try{e.lastFindings=await e.module.scan(t),Array.isArray(e.lastFindings)||(e.lastFindings=[])}catch(n){e.status="failed",e.error=`scan failed: ${n?.message??String(n)}`,e.lastFindings=[]}return r}function qn(r){return{config:r.config,apps:r.apps,history:r.history&&typeof r.history.querySelfMetrics=="function"?{querySelfMetrics:r.history.querySelfMetrics.bind(r.history)}:null,mutations:{setOverride:()=>{throw new Error("mutations.setOverride is not implemented in v0.8 \u2014 fix functions are advisory until M44 wires the M36 patch surface")}}}}import O,{useEffect as Vi,useState as V}from"react";import ur from"node:fs";import Zi from"node:os";import Qi from"node:path";import{Box as Z,Text as D,useApp as ta,useInput as ea,useStdout as ra}from"ink";import pr from"ink-text-input";import{spawn as dr,spawnSync as na}from"node:child_process";import Y,{useEffect as qi,useMemo as Ji,useState as Ot}from"react";import{Box as Ut,Text as rt,useInput as Xi,useStdout as Ki}from"ink";import zi from"ink-text-input";function lr({registry:r,appName:t,onExit:e}){let{stdout:n}=Ki(),[s,i]=Ot(0),[o,a]=Ot(!1),[c,l]=Ot(""),[p,h]=Ot(""),[m,b]=Ot(0),[M,E]=Ot(0);qi(()=>{let k=()=>i(C=>C+1);r.on("change",k);let x=setInterval(()=>i(C=>C+1),500);return()=>{r.off("change",k),clearInterval(x)}},[r]);let v=r.getState(t)?.logBuffer.map(k=>k.line)??[],N=(n.rows||30)-4,u=Ji(()=>{if(!p)return[];let k=p.toLowerCase();return v.reduce((x,C,y)=>(C.toLowerCase().includes(k)&&x.push(y),x),[])},[v,p,s]);Xi((k,x)=>{if(o){if(x.escape){a(!1),l("");return}return}if(k==="q"||x.escape){e();return}if(k==="/"){a(!0);return}if(k==="g"){b(Math.max(0,v.length-N));return}if(k==="G"){b(0);return}if(x.pageUp){b(C=>Math.min(Math.max(0,v.length-N),C+N));return}if(x.pageDown){b(C=>Math.max(0,C-N));return}if(x.upArrow){b(C=>Math.min(Math.max(0,v.length-N),C+1));return}if(x.downArrow){b(C=>Math.max(0,C-1));return}if((k==="n"||k==="N")&&u.length){let C=k==="n"?(M+1)%u.length:(M-1+u.length)%u.length;E(C);let y=u[C],A=v.length-m,_=A-N;(y<_||y>=A)&&b(Math.max(0,v.length-y-Math.floor(N/2)));return}});let d=k=>{h(k),a(!1),l(""),E(0)},f=v.length-m,S=Math.max(0,f-N),T=v.slice(S,f),P=(k,x)=>{if(!p)return Y.createElement(rt,{key:x},Y.createElement(rt,{dimColor:!0},String(x+1).padStart(5)," "),k);let C=p,y=k.toLowerCase(),A=C.toLowerCase(),_=[],U=0,$=0;for(;U<k.length;){let J=y.indexOf(A,U);if(J<0){_.push(Y.createElement(rt,{key:$++},k.slice(U)));break}J>U&&_.push(Y.createElement(rt,{key:$++},k.slice(U,J))),_.push(Y.createElement(rt,{key:$++,backgroundColor:"yellow",color:"black"},k.slice(J,J+C.length))),U=J+C.length}let H=u[M]===x;return Y.createElement(rt,{key:x},Y.createElement(rt,{color:H?"cyan":void 0,dimColor:!H},String(x+1).padStart(5)," "),_)};return Y.createElement(Ut,{flexDirection:"column"},Y.createElement(Ut,null,Y.createElement(rt,{bold:!0},"full log: ",Y.createElement(rt,{color:"cyan"},t)),Y.createElement(rt,{dimColor:!0}," (",v.length," lines",p?`, ${u.length} matches for "${p}"`:"",", scroll=",m,")")),Y.createElement(Ut,{flexDirection:"column"},T.length===0?Y.createElement(rt,{dimColor:!0},"(no log yet)"):T.map((k,x)=>P(k,S+x))),Y.createElement(Ut,null,o?Y.createElement(Ut,null,Y.createElement(rt,null,"/"),Y.createElement(zi,{value:c,onChange:l,onSubmit:d})):Y.createElement(rt,{dimColor:!0},"[/] search [n/N] next/prev [g/G] bottom/top [PgUp/PgDn] [\u2191\u2193] [q/Esc] back")))}var Jn={stopped:1,serving:2,compiling:3,starting:3,error:4},Yi={"":"\xB7",stopped:"\u2591",serving:"\u2593",compiling:"\u2592",starting:"\u2592",error:"\u2588"};function Xn(r,t,e=Date.now()){let n=e-36e5,s=36e5/20,i=new Array(20).fill("");for(let o of r){if(o.type!=="status"||o.app!==t||!o.to||o.ts<n||o.ts>e)continue;let a=Math.min(19,Math.floor((o.ts-n)/s)),c=i[a];(!c||(Jn[o.to]??0)>(Jn[c]??0))&&(i[a]=o.to)}return i}function Kn(r){return r.map(t=>Yi[t]??"\xB7").join("")}function sa(r){try{process.platform==="win32"?dr("cmd",["/c","start","",r],{detached:!0,stdio:"ignore",windowsHide:!0}).unref():process.platform==="darwin"?dr("open",[r],{detached:!0,stdio:"ignore"}).unref():dr("xdg-open",[r],{detached:!0,stdio:"ignore"}).unref()}catch{}}var zn={stopped:"gray",starting:"yellow",compiling:"yellow",serving:"green",error:"red"},Yn={healthy:"green",unhealthy:"red",unknown:"gray"};function oa(r){if(r==null)return"";let t=Math.floor(r/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 fr({registry:r,apiPort:t,onQuit:e}){let{exit:n}=ta(),{stdout:s}=ra(),[i,o]=V(r.list()),[a,c]=V(0),[l,p]=V(!1),[h,m]=V(0),[b,M]=V(!1),[E,g]=V([]),[v,N]=V(!1),[u,d]=V(""),[f,S]=V(null),[,T]=V(0),[P,k]=V(null),[x,C]=V(""),[y,A]=V(!1),[_,U]=V(null),[$,H]=V(""),[J,B]=V(!1),[nt,q]=V(null),[Wt,Nt]=V(r.events({sinceMs:3600*1e3}));Vi(()=>{let R=()=>o(r.list()),L=()=>Nt(r.events({sinceMs:36e5}));r.on("change",R),r.on("event",L);let I=setInterval(()=>{o(r.list()),Nt(r.events({sinceMs:3600*1e3})),T(j=>j+1)},1e3);return()=>{r.off("change",R),r.off("event",L),clearInterval(I)}},[r]),ea((R,L)=>{if(b)return;if(f){if(L.escape){S(null);return}if(L.tab){let j=f.field==="command"?"port":f.field==="port"?"env":"command";S({...f,field:j});return}return}if(v){if(L.escape){N(!1),d("");return}if(L.return){let j=u.trim();g(j?j.split(/[\s,]+/).filter(Boolean):[]),N(!1),d("");return}if(L.backspace||L.delete){d(j=>j.slice(0,-1));return}R&&!L.ctrl&&d(j=>j+R);return}if(y){if(L.escape){A(!1);return}if(L.return){A(!1);return}if(L.backspace||L.delete){C(j=>j.slice(0,-1));return}R&&!L.ctrl&&C(j=>j+R);return}if(J){if(L.escape){B(!1),H("");return}if(L.return){let j=$.trim();B(!1),H(""),j&&Zn(j);return}if(L.backspace||L.delete){H(j=>j.slice(0,-1));return}R&&!L.ctrl&&H(j=>j+R);return}if(_){if(R==="y"||R==="Y"){let j=_;U(null),r.restart(j),X(`restarted ${j}`)}else(R==="n"||R==="N"||L.escape)&&U(null);return}if(R==="q"||L.ctrl&&R==="c"){e(),n();return}if(i.length===0)return;if(P==="g"){k(null);let j=R.toLowerCase();j==="a"?X("view: apps (only TUI view)"):j==="e"?X("view: errors \u2014 selected app errors shown in detail pane"):j==="v"?X("view: events \u2014 recent registry events shown in log pane"):j==="s"?X("view: settings \u2014 edit `daimon.config.json`"):j==="n"&&X("view: sessions \u2014 `daimon record` to toggle recording");return}if(L.upArrow||R==="k"){c(j=>Math.max(0,j-1)),m(0);return}if(L.downArrow||R==="j"){c(j=>Math.min(i.length-1,j+1)),m(0);return}let I=i[a];if(I){if(R==="g"){k("g"),setTimeout(()=>k(j=>j==="g"?null:j),1200);return}if(R==="/"){A(!0);return}if(R==="s")r.start(I.name);else if(R==="S")r.stop(I.name);else if(R==="r")U(I.name);else if(R==="f")Vn(I.name);else if(R==="x")Gt(I.name);else if(R==="O")B(!0);else if(R==="L")M(!0);else if(R==="t")N(!0),d(E.join(" "));else if(R==="e"){let j=r.getConfig(),K=r.getApp(I.name),et=r.getState(I.name)?.sessionOverrides??null,gt=et?.env??j.overrides?.[I.name]?.env??{},yt=Object.entries(gt).map(([xe,Te])=>`${xe}=${Te}`).join(`
|
|
87
|
-
|
|
88
|
-
`)
|
|
89
|
-
`),
|
|
88
|
+
`)}catch{}process.exit(1)};process.on("uncaughtException",t),process.on("unhandledRejection",t)}Ut();var gr=1e3,ta=60,ea=256;function Re(r,t){if(r.length===0)return 0;let e=[...r].sort((s,o)=>s-o),n=Math.min(e.length-1,Math.floor((e.length-1)*t));return Math.round(e[n]*100)/100}var Ae=class{constructor(t){this.history=t;this.start()}history;startMs=Date.now();lagTimer=null;lagSamples=[];querySamples=[];lockContentionCount=0;lastTickAt=Date.now();highLagStreak=0;warnedAtStreak=0;onSelfWarn=null;start(){let t=performance.now();this.lagTimer=setInterval(()=>{let e=performance.now(),n=Math.max(0,e-t-gr);t=e,this.lagSamples.push(n),this.lagSamples.length>ta&&this.lagSamples.shift(),this.lastTickAt=Date.now(),n>100?(this.highLagStreak++,this.highLagStreak>=5&&this.highLagStreak>this.warnedAtStreak&&this.onSelfWarn&&(this.warnedAtStreak=this.highLagStreak,this.onSelfWarn(`event loop lag sustained: ${Math.round(n)}ms (${this.highLagStreak} consecutive ticks)`))):(this.highLagStreak=0,this.warnedAtStreak=0)},gr),this.lagTimer.unref&&this.lagTimer.unref()}setSelfWarnHandler(t){this.onSelfWarn=t}recordQueryMs(t){this.querySamples.push(t),this.querySamples.length>ea&&this.querySamples.shift()}incLockContention(){this.lockContentionCount++}snapshot(){let t=process.memoryUsage(),e=1024*1024;return{pid:process.pid,version:bt,uptimeMs:Date.now()-this.startMs,rssMB:Math.round(t.rss/e*10)/10,heapUsedMB:Math.round(t.heapUsed/e*10)/10,heapTotalMB:Math.round(t.heapTotal/e*10)/10,eventLoopLagMs:this.lagSamples.length?Math.round(this.lagSamples[this.lagSamples.length-1]*100)/100:0,eventLoopLagP95Ms:Re(this.lagSamples,.95),historyDbQueryMs:{p50:Re(this.querySamples,.5),p95:Re(this.querySamples,.95),p99:Re(this.querySamples,.99)},lockContentionCount:this.lockContentionCount,tickIntervalMs:gr,lastTickAt:this.lastTickAt}}stop(){this.lagTimer&&clearInterval(this.lagTimer),this.lagTimer=null}};import ra from"node:fs";import Qn from"node:path";import na from"node:os";import{pathToFileURL as sa}from"node:url";function ts(r){return r&&typeof r=="string"&&r.trim()?r:Qn.join(na.homedir(),".daimon","plugins")}function oa(r){return r.startsWith("doctor-")&&r.endsWith(".mjs")}function ia(r){if(!r||typeof r!="object")return{ok:!1,error:"module has no default export"};let t=r.default??r;return t?typeof t.name!="string"||!t.name.length?{ok:!1,error:"plugin.name must be a non-empty string"}:/^[a-z][a-z0-9-]*$/.test(t.name)?typeof t.scan!="function"?{ok:!1,error:"plugin.scan must be a function"}:t.fix!==void 0&&typeof t.fix!="function"?{ok:!1,error:"plugin.fix, if present, must be a function"}:t.undo!==void 0&&typeof t.undo!="function"?{ok:!1,error:"plugin.undo, if present, must be a function"}:{ok:!0,plugin:t}:{ok:!1,error:`plugin.name must be kebab-case (got "${t.name}")`}:{ok:!1,error:"plugin shape is null"}}var aa=new Set(["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db","port-conflict-pred","node-version-mismatch","orphan-node-modules","orphan-venv","orphan-bundler-cache","orphan-cargo-target","dead-search-root"]);async function es(r){let t=[],e;try{e=ra.readdirSync(r).filter(oa).sort()}catch{return t}let n=new Set;for(let s of e){let o=Qn.join(r,s);try{let a=await import(sa(o).href+`?t=${Date.now()}`),c=ia(a);if(!c.ok){t.push({name:s,file:o,status:"failed",error:c.error});continue}let i=c.plugin;if(aa.has(i.name)){t.push({name:i.name,file:o,status:"failed",error:`name collides with built-in rule "${i.name}"`});continue}if(n.has(i.name)){t.push({name:i.name,file:o,status:"failed",error:"duplicate plug-in name"});continue}n.add(i.name),t.push({name:i.name,description:i.description,file:o,status:"ok",module:i})}catch(a){t.push({name:s,file:o,status:"failed",error:a?.message??String(a)})}}return t}async function rs(r,t){for(let e of r)if(!(e.status!=="ok"||!e.module))try{e.lastFindings=await e.module.scan(t),Array.isArray(e.lastFindings)||(e.lastFindings=[])}catch(n){e.status="failed",e.error=`scan failed: ${n?.message??String(n)}`,e.lastFindings=[]}return r}function ns(r){return{config:r.config,apps:r.apps,history:r.history&&typeof r.history.querySelfMetrics=="function"?{querySelfMetrics:r.history.querySelfMetrics.bind(r.history)}:null,mutations:{setOverride:()=>{throw new Error("mutations.setOverride is not implemented in v0.8 \u2014 fix functions are advisory until M44 wires the M36 patch surface")}}}}import ca from"node:http";import la from"node:https";import{URL as is}from"node:url";var ss=3,ua=1,pa=64,da=1e3/ua,fa=5e3,Pe=class{constructor(t,e,n={}){this.registry=t;this.webhooks=e;this.opts=n;this.listener=s=>this.handleEvent(s),t.on("event",this.listener),this.timer=setInterval(()=>this.tick(),da),this.timer.unref&&this.timer.unref()}registry;webhooks;opts;queue=[];timer=null;droppedCount=0;deliveries=0;failures=0;listener;setWebhooks(t){this.webhooks=t}stats(){return{queued:this.queue.length,dropped:this.droppedCount,deliveries:this.deliveries,failures:this.failures}}stop(){this.timer&&(clearInterval(this.timer),this.timer=null),this.registry.off("event",this.listener)}handleEvent(t){for(let e of this.webhooks)this.matches(e,t)&&(this.queue.length>=pa&&(this.queue.shift(),this.droppedCount++,this.opts.onLog?.(`webhooks: dropped oldest (queue full, total dropped=${this.droppedCount})`)),this.queue.push({cfg:e,event:t,enqueuedAt:Date.now()}))}matches(t,e){if(t.events&&t.events.length){let n=ma(e.type);if(!t.events.includes(e.type)&&!t.events.includes(n))return!1}return!(t.filter&&(t.filter.app&&t.filter.app.length&&!t.filter.app.includes(e.app)||t.filter.to&&t.filter.to.length&&(!e.to||!t.filter.to.includes(e.to))||t.filter.from&&t.filter.from.length&&(!e.from||!t.filter.from.includes(e.from))))}tick(){let t=this.queue.shift();if(!t)return;let e=this.opts.sendFn??ga,n=ha(t.cfg.url,t.event);this.attemptDelivery(e,t.cfg,n,0).then(s=>{s?this.deliveries++:this.failures++})}async attemptDelivery(t,e,n,s){try{let o=await t(e.url,n,e.headers??{});if(o.status>=200&&o.status<300)return!0;if(s>=ss)return this.opts.onLog?.(`webhooks: ${e.url} -> HTTP ${o.status} (after ${s+1} attempts)`),!1;let a=500*Math.pow(2,s);return await new Promise(c=>setTimeout(c,a)),this.attemptDelivery(t,e,n,s+1)}catch(o){if(s>=ss)return this.opts.onLog?.(`webhooks: ${e.url} -> ${o?.message||o} (after ${s+1} attempts)`),!1;let a=500*Math.pow(2,s);return await new Promise(c=>setTimeout(c,a)),this.attemptDelivery(t,e,n,s+1)}}};function ma(r){return r==="error-new"||r==="error-recur"?"error":r==="warning-new"||r==="warning-recur"?"warning":r==="lint-new"||r==="lint-recur"?"lint":r}function ha(r,t){let e={event:t.type,app:t.app,ts:t.ts,from:t.from??null,to:t.to??null,message:t.message??null},n="";try{n=new is(r).hostname}catch{return e}if(n.endsWith("slack.com")){let s=`*[${t.app}]* ${t.type}${t.to?` \u2192 ${t.to}`:""}`,o=t.message??"";return{text:o?`${s}
|
|
89
|
+
${o}`:s,attachments:[{color:os(t.type),fields:[{title:"app",value:t.app,short:!0},{title:"type",value:t.type,short:!0},...t.from?[{title:"from",value:t.from,short:!0}]:[],...t.to?[{title:"to",value:t.to,short:!0}]:[],...o?[{title:"message",value:o,short:!1}]:[]],ts:Math.round(t.ts/1e3)}]}}if(n.endsWith("discord.com")||n.endsWith("discordapp.com")){let s=`${t.app} \xB7 ${t.type}${t.to?` \u2192 ${t.to}`:""}`;return{content:s,embeds:[{title:s,description:t.message??void 0,color:parseInt(os(t.type).replace("#",""),16)||void 0,timestamp:new Date(t.ts).toISOString()}]}}return e}function os(r){return r==="error-new"||r==="error-recur"||r==="regression-detected"?"#ef4444":r==="warning-new"||r==="warning-recur"?"#f59e0b":r==="status"?"#3b82f6":"#94a3b8"}function ga(r,t,e){return new Promise((n,s)=>{let o;try{o=new is(r)}catch(l){s(l);return}let a=Buffer.from(JSON.stringify(t)),i=(o.protocol==="https:"?la:ca).request({method:"POST",hostname:o.hostname,port:o.port||(o.protocol==="https:"?443:80),path:o.pathname+(o.search||""),headers:{"content-type":"application/json","content-length":a.length,"user-agent":"daimon-webhooks/1",...e},timeout:fa},l=>{l.resume(),l.on("end",()=>n({status:l.statusCode||0}))});i.on("timeout",()=>i.destroy(new Error("delivery timeout"))),i.on("error",s),i.write(a),i.end()})}import O,{useEffect as xa,useState as rt}from"react";import br from"node:fs";import Ta from"node:os";import Ea from"node:path";import{Box as nt,Text as D,useApp as Ra,useInput as Aa,useStdout as Pa}from"ink";import wr from"ink-text-input";import{spawn as vr,spawnSync as Ca}from"node:child_process";import et,{useEffect as ya,useMemo as ba,useState as Dt}from"react";import{Box as Yt,Text as at,useInput as wa,useStdout as va}from"ink";import Sa from"ink-text-input";function yr({registry:r,appName:t,onExit:e}){let{stdout:n}=va(),[s,o]=Dt(0),[a,c]=Dt(!1),[i,l]=Dt(""),[u,d]=Dt(""),[g,v]=Dt(0),[A,E]=Dt(0);ya(()=>{let p=()=>o(h=>h+1);r.on("change",p);let f=setInterval(()=>o(h=>h+1),500);return()=>{r.off("change",p),clearInterval(f)}},[r]);let y=r.getState(t)?.logBuffer.map(p=>p.line)??[],P=(n.rows||30)-4,I=ba(()=>{if(!u)return[];let p=u.toLowerCase();return y.reduce((f,h,w)=>(h.toLowerCase().includes(p)&&f.push(w),f),[])},[y,u,s]);wa((p,f)=>{if(a){if(f.escape){c(!1),l("");return}return}if(p==="q"||f.escape){e();return}if(p==="/"){c(!0);return}if(p==="g"){v(Math.max(0,y.length-P));return}if(p==="G"){v(0);return}if(f.pageUp){v(h=>Math.min(Math.max(0,y.length-P),h+P));return}if(f.pageDown){v(h=>Math.max(0,h-P));return}if(f.upArrow){v(h=>Math.min(Math.max(0,y.length-P),h+1));return}if(f.downArrow){v(h=>Math.max(0,h-1));return}if((p==="n"||p==="N")&&I.length){let h=p==="n"?(A+1)%I.length:(A-1+I.length)%I.length;E(h);let w=I[h],m=y.length-g,T=m-P;(w<T||w>=m)&&v(Math.max(0,y.length-w-Math.floor(P/2)));return}});let J=p=>{d(p),c(!1),l(""),E(0)},S=y.length-g,Q=Math.max(0,S-P),Y=y.slice(Q,S),z=(p,f)=>{if(!u)return et.createElement(at,{key:f},et.createElement(at,{dimColor:!0},String(f+1).padStart(5)," "),p);let h=u,w=p.toLowerCase(),m=h.toLowerCase(),T=[],k=0,x=0;for(;k<p.length;){let M=w.indexOf(m,k);if(M<0){T.push(et.createElement(at,{key:x++},p.slice(k)));break}M>k&&T.push(et.createElement(at,{key:x++},p.slice(k,M))),T.push(et.createElement(at,{key:x++,backgroundColor:"yellow",color:"black"},p.slice(M,M+h.length))),k=M+h.length}let $=I[A]===f;return et.createElement(at,{key:f},et.createElement(at,{color:$?"cyan":void 0,dimColor:!$},String(f+1).padStart(5)," "),T)};return et.createElement(Yt,{flexDirection:"column"},et.createElement(Yt,null,et.createElement(at,{bold:!0},"full log: ",et.createElement(at,{color:"cyan"},t)),et.createElement(at,{dimColor:!0}," (",y.length," lines",u?`, ${I.length} matches for "${u}"`:"",", scroll=",g,")")),et.createElement(Yt,{flexDirection:"column"},Y.length===0?et.createElement(at,{dimColor:!0},"(no log yet)"):Y.map((p,f)=>z(p,Q+f))),et.createElement(Yt,null,a?et.createElement(Yt,null,et.createElement(at,null,"/"),et.createElement(Sa,{value:i,onChange:l,onSubmit:J})):et.createElement(at,{dimColor:!0},"[/] search [n/N] next/prev [g/G] bottom/top [PgUp/PgDn] [\u2191\u2193] [q/Esc] back")))}var as={stopped:1,serving:2,compiling:3,starting:3,error:4},ka={"":"\xB7",stopped:"\u2591",serving:"\u2593",compiling:"\u2592",starting:"\u2592",error:"\u2588"};function cs(r,t,e=Date.now()){let n=e-36e5,s=36e5/20,o=new Array(20).fill("");for(let a of r){if(a.type!=="status"||a.app!==t||!a.to||a.ts<n||a.ts>e)continue;let c=Math.min(19,Math.floor((a.ts-n)/s)),i=o[c];(!i||(as[a.to]??0)>(as[i]??0))&&(o[c]=a.to)}return o}function ls(r){return r.map(t=>ka[t]??"\xB7").join("")}function Ma(r){try{process.platform==="win32"?vr("cmd",["/c","start","",r],{detached:!0,stdio:"ignore",windowsHide:!0}).unref():process.platform==="darwin"?vr("open",[r],{detached:!0,stdio:"ignore"}).unref():vr("xdg-open",[r],{detached:!0,stdio:"ignore"}).unref()}catch{}}var us={stopped:"gray",starting:"yellow",compiling:"yellow",serving:"green",error:"red"},ps={healthy:"green",unhealthy:"red",unknown:"gray"};function Oa(r){if(r==null)return"";let t=Math.floor(r/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60);return e<60?`${e}m ${t%60}s`:`${Math.floor(e/60)}h ${e%60}m`}function Sr({registry:r,apiPort:t,onQuit:e}){let{exit:n}=Ra(),{stdout:s}=Pa(),[o,a]=rt(r.list()),[c,i]=rt(0),[l,u]=rt(!1),[d,g]=rt(0),[v,A]=rt(!1),[E,C]=rt([]),[y,P]=rt(!1),[I,J]=rt(""),[S,Q]=rt(null),[,Y]=rt(0),[z,p]=rt(null),[f,h]=rt(""),[w,m]=rt(!1),[T,k]=rt(null),[x,$]=rt(""),[M,L]=rt(!1),[W,V]=rt(null),[_,q]=rt(r.events({sinceMs:3600*1e3}));xa(()=>{let R=()=>a(r.list()),j=()=>q(r.events({sinceMs:36e5}));r.on("change",R),r.on("event",j);let H=setInterval(()=>{a(r.list()),q(r.events({sinceMs:3600*1e3})),Y(N=>N+1)},1e3);return()=>{r.off("change",R),r.off("event",j),clearInterval(H)}},[r]),Aa((R,j)=>{if(v)return;if(S){if(j.escape){Q(null);return}if(j.tab){let N=S.field==="command"?"port":S.field==="port"?"env":"command";Q({...S,field:N});return}return}if(y){if(j.escape){P(!1),J("");return}if(j.return){let N=I.trim();C(N?N.split(/[\s,]+/).filter(Boolean):[]),P(!1),J("");return}if(j.backspace||j.delete){J(N=>N.slice(0,-1));return}R&&!j.ctrl&&J(N=>N+R);return}if(w){if(j.escape){m(!1);return}if(j.return){m(!1);return}if(j.backspace||j.delete){h(N=>N.slice(0,-1));return}R&&!j.ctrl&&h(N=>N+R);return}if(M){if(j.escape){L(!1),$("");return}if(j.return){let N=x.trim();L(!1),$(""),N&&K(N);return}if(j.backspace||j.delete){$(N=>N.slice(0,-1));return}R&&!j.ctrl&&$(N=>N+R);return}if(T){if(R==="y"||R==="Y"){let N=T;k(null),r.restart(N),G(`restarted ${N}`)}else(R==="n"||R==="N"||j.escape)&&k(null);return}if(R==="q"||j.ctrl&&R==="c"){e(),n();return}if(o.length===0)return;if(z==="g"){p(null);let N=R.toLowerCase();N==="a"?G("view: apps (only TUI view)"):N==="e"?G("view: errors \u2014 selected app errors shown in detail pane"):N==="v"?G("view: events \u2014 recent registry events shown in log pane"):N==="s"?G("view: settings \u2014 edit `daimon.config.json`"):N==="n"&&G("view: sessions \u2014 `daimon record` to toggle recording");return}if(j.upArrow||R==="k"){i(N=>Math.max(0,N-1)),g(0);return}if(j.downArrow||R==="j"){i(N=>Math.min(o.length-1,N+1)),g(0);return}let H=o[c];if(H){if(R==="g"){p("g"),setTimeout(()=>p(N=>N==="g"?null:N),1200);return}if(R==="/"){m(!0);return}if(R==="s")r.start(H.name);else if(R==="S")r.stop(H.name);else if(R==="r")k(H.name);else if(R==="f")lt(H.name);else if(R==="x")U(H.name);else if(R==="O")L(!0);else if(R==="L")A(!0);else if(R==="t")P(!0),J(E.join(" "));else if(R==="e"){let N=r.getConfig(),Z=r.getApp(H.name),it=r.getState(H.name)?.sessionOverrides??null,kt=it?.env??N.overrides?.[H.name]?.env??{},xt=Object.entries(kt).map(([Me,Oe])=>`${Me}=${Oe}`).join(`
|
|
90
|
+
`);Q({name:H.name,field:"command",cmd:it?.command??Z?.command??"",port:String(it?.port??N.overrides?.[H.name]?.port??H.port??""),env:xt})}else if(R==="E"){let Z=r.getConfig().envFiles?.[H.name]??[];if(!Z.length)return;let it=r.getState(H.name)?.activeEnvFile??null,kt=it?Z.indexOf(it):-1,xt=Z[(kt+1)%Z.length];r.setActiveEnvFile(H.name,xt)}else if(R==="V"){let N=process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),Z=Ea.join(Ta.tmpdir(),`daimon-${H.name}-${Date.now()}.json`),it=r.getConfig(),kt=r.getApp(H.name),xt=r.getState(H.name)?.sessionOverrides??null,Me={command:xt?.command??kt?.command,port:xt?.port??it.overrides?.[H.name]?.port??null,env:xt?.env??it.overrides?.[H.name]?.env??{}};try{br.writeFileSync(Z,JSON.stringify(Me,null,2)),Ca(N,[Z],{stdio:"inherit",shell:!0});let Oe=br.readFileSync(Z,"utf8"),Tt=JSON.parse(Oe);r.setSessionOverride(H.name,{command:typeof Tt.command=="string"?Tt.command:void 0,port:typeof Tt.port=="number"?Tt.port:void 0,env:Tt.env&&typeof Tt.env=="object"?Tt.env:void 0}),br.unlinkSync(Z)}catch{}}else R==="l"?u(N=>!N):R==="o"?H.url&&Ma(H.url):j.pageUp?g(N=>N+5):j.pageDown&&g(N=>Math.max(0,N-5))}});let G=R=>{V(R),setTimeout(()=>V(j=>j===R?null:j),4e3)},U=async R=>{G(`try-fix ${R}\u2026`);try{let{runAutoFix:j,ALL_AUTO_FIX:H}=await Promise.resolve().then(()=>(Kt(),Xt)),Z=r.getConfig().doctor?.autoFix?.permitted??H,it=await j({permitted:Z,dryRun:!1});await r.restart(R);let kt=await r.waitFor(R,"healthy",6e4);G(`try-fix ${R}: ${kt.timedOut?"timeout":"reached"} \xB7 fixed ${it.ran.length}`)}catch(j){G(`try-fix ${R} failed: ${j?.message??j}`)}},lt=async R=>{G(`focus ${R} until stable\u2026`);try{let j=Date.now(),H=Date.now(),N=Z=>{Z.app===R&&(H=Date.now())};r.on("event",N);try{for(;Date.now()-j<18e4;){let Z=r.summary(R);if(Z&&Z.status==="serving"&&Z.health==="healthy"&&Date.now()-H>=5e3){G(`focus ${R}: stable after ${Math.round((Date.now()-j)/1e3)}s`);return}await new Promise(it=>setTimeout(it,500))}}finally{r.off("event",N)}G(`focus ${R}: timed out`)}catch(j){G(`focus ${R} failed: ${j?.message??j}`)}},K=async R=>{G(`orchestrate ${R}\u2026`);try{let{orchestrateProfile:j}=await Promise.resolve().then(()=>(or(),sr)),H=await j(r,r.getConfig(),{profile:R,goal:"healthy",timeoutMs:3e5});if(H.error){G(`orchestrate ${R}: ${H.error}`);return}let N=H.allReached;G(`orchestrate ${R}: ${N?"all reached":"some failing"} \xB7 ${Math.round(H.totalMs/1e3)}s`)}catch(j){G(`orchestrate ${R} failed: ${j?.message??j}`)}},It=f.trim().toLowerCase(),St=(E.length===0?o:o.filter(R=>E.every(j=>R.tags.includes(j)))).filter(R=>!It||R.name.toLowerCase().includes(It)),B=St[Math.min(c,Math.max(0,St.length-1))],pt=B?r.getState(B.name):null,kr=pt?pt.logBuffer.slice(Math.max(0,pt.logBuffer.length-12-d),pt.logBuffer.length-d).map(R=>R.line):[],Ce=s.columns||100,ds=Math.min(36,Math.floor(Ce*.4));return v&&B?O.createElement(yr,{registry:r,appName:B.name,onExit:()=>A(!1)}):O.createElement(nt,{flexDirection:"column",width:Ce},O.createElement(nt,{borderStyle:"round",borderColor:"cyan",paddingX:1},O.createElement(D,{bold:!0,color:"cyan"},"daimon"),O.createElement(D,{dimColor:!0}," \u2022 api http://127.0.0.1:",t)),O.createElement(nt,{flexDirection:"row"},O.createElement(nt,{flexDirection:"column",width:ds,borderStyle:"single",borderColor:"gray",paddingX:1},O.createElement(D,{bold:!0},"Apps ",E.length?O.createElement(D,{dimColor:!0},"(tags: ",E.join(", "),")"):null),St.length===0?O.createElement(D,{dimColor:!0},o.length===0?"(no apps discovered)":"(no apps match filter)"):St.map((R,j)=>{let H=j===c,N=cs(_,R.name),Z=ls(N);return O.createElement(nt,{key:R.name,flexDirection:"column"},O.createElement(nt,null,O.createElement(D,{color:H?"cyan":void 0},H?"\u25B8 ":" "),O.createElement(D,{color:H?"cyan":void 0},((r.getState(R.name)?.sessionOverrides?"*":"")+R.name).padEnd(20).slice(0,20)),O.createElement(D,{color:us[R.status]}," ",R.status.padEnd(9)),O.createElement(D,{color:ps[R.health]},R.status==="serving"?"\u25CF":" "),O.createElement(D,{dimColor:!0},R.port?` :${R.port}`:""),Ce>=100&&R.cpu!=null?O.createElement(D,{dimColor:!0}," ",String(R.cpu).padStart(5),"% ",String(R.memMB??0).padStart(5),"MB"):null),O.createElement(nt,null,O.createElement(D,{dimColor:!0}," "),O.createElement(D,{dimColor:!0},Z)))})),O.createElement(nt,{flexDirection:"column",flexGrow:1,borderStyle:"single",borderColor:"gray",paddingX:1},B&&pt?O.createElement(O.Fragment,null,O.createElement(D,null,"Selected: ",O.createElement(D,{bold:!0},B.name)),O.createElement(D,null,"Status: ",O.createElement(D,{color:us[B.status]},B.status)," ",O.createElement(D,{color:ps[B.health]},"\u25CF")," ",O.createElement(D,{dimColor:!0},B.health)),O.createElement(D,null,"Port: ",B.port??"-"),O.createElement(D,null,"URL: ",B.url??"-"),B.announcedUrl&&B.announcedUrl!==B.url?O.createElement(D,{dimColor:!0},"Announced: ",B.announcedUrl):null,B.lastHealthError?O.createElement(D,{color:"red"},"HealthErr: ",B.lastHealthError):null,B.stale?O.createElement(D,{color:"yellow"},"\u26A0 stale (best guess)"):null,O.createElement(D,null,"Errors: ",O.createElement(D,{color:B.errorCount?"red":void 0},B.errorCount)),O.createElement(D,null,"Uptime: ",Oa(B.uptimeMs)),B.cpu!=null||B.memMB!=null?O.createElement(D,null,"Usage: ",B.cpu??"-","% ",B.memMB??"-"," MB"):null,B.compileHistoryMs.length>0?O.createElement(D,null,"Recent compile: ",B.compileHistoryMs.slice(-5).map(R=>(R/1e3).toFixed(1)+"s").join(" \xB7 ")):null,B.bundle?O.createElement(D,null,"Bundle: ",B.bundle.initialKB,"KB initial \xB7 ",B.bundle.lazyKB,"KB lazy",B.bundleRegressionPct!=null&&B.bundleRegressionPct>10?O.createElement(D,{color:"red"}," (+",B.bundleRegressionPct,"% \u26A0)"):null):null,pt.lastStatusMessage?O.createElement(D,{dimColor:!0},"Note: ",pt.lastStatusMessage):null,O.createElement(D,null,"\u2500\u2500\u2500\u2500 recent log ",l?"(focused)":""," \u2500\u2500\u2500\u2500"),kr.length===0?O.createElement(D,{dimColor:!0},"(no output yet)"):kr.map((R,j)=>O.createElement(D,{key:j,wrap:"truncate-end"},R))):O.createElement(D,{dimColor:!0},"No app selected."))),O.createElement(nt,{flexDirection:"column"},y?O.createElement(D,null,"tag filter (space-separated, Enter to apply, Esc to cancel): ",O.createElement(D,{color:"cyan"},I)):null,S?O.createElement(nt,{flexDirection:"column",borderStyle:"round",borderColor:"yellow",paddingX:1},O.createElement(D,{bold:!0,color:"yellow"},"edit ",S.name," (session-only) Tab=next field Enter=save Esc=cancel"),O.createElement(nt,null,O.createElement(D,null,S.field==="command"?"> ":" ","command: "),S.field==="command"?O.createElement(wr,{value:S.cmd,onChange:R=>Q({...S,cmd:R}),onSubmit:()=>Q({...S,field:"port"})}):O.createElement(D,{dimColor:!0},S.cmd)),O.createElement(nt,null,O.createElement(D,null,S.field==="port"?"> ":" ","port: "),S.field==="port"?O.createElement(wr,{value:S.port,onChange:R=>Q({...S,port:R}),onSubmit:()=>Q({...S,field:"env"})}):O.createElement(D,{dimColor:!0},S.port)),O.createElement(nt,null,O.createElement(D,null,S.field==="env"?"> ":" ","env (k=v;): "),S.field==="env"?O.createElement(wr,{value:S.env.replace(/\n/g,";"),onChange:R=>Q({...S,env:R.replace(/;/g,`
|
|
91
|
+
`)}),onSubmit:()=>{let R=Number(S.port),j={};for(let H of S.env.split(/\n/)){let N=H.match(/^\s*([^=]+)=(.*)$/);N&&(j[N[1].trim()]=N[2])}r.setSessionOverride(S.name,{command:S.cmd||void 0,port:Number.isFinite(R)&&R>0?R:void 0,env:Object.keys(j).length?j:void 0}),Q(null)}}):O.createElement(D,{dimColor:!0},S.env))):null,T?O.createElement(nt,{borderStyle:"round",borderColor:"yellow",paddingX:1},O.createElement(D,{color:"yellow",bold:!0},"Restart ",T,"? "),O.createElement(D,{dimColor:!0},"[y]es [n]o / Esc")):null,w?O.createElement(D,null,"filter (Enter to apply, Esc to clear): ",O.createElement(D,{color:"cyan"},f)):null,M?O.createElement(nt,{borderStyle:"round",borderColor:"cyan",paddingX:1},O.createElement(D,{bold:!0,color:"cyan"},"orchestrate profile (Enter to run, Esc to cancel): "),O.createElement(D,{color:"cyan"},x)):null,W?O.createElement(D,{color:"cyan"},"[i] ",W):null,O.createElement(D,{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 ja(r={}){let t=null,e=null;Zn({getRegistry:()=>t,getConfig:()=>e});let n;try{n=ct()}catch(m){process.stderr.write(`[daimon] config error: ${m.message}
|
|
92
|
+
`),process.exit(1)}if(n.kind==="stub-created"){let m=yt();process.stdout.write(`[daimon] no config found. Created stub at:
|
|
90
93
|
${n.path}
|
|
91
94
|
`),process.stdout.write(`[daimon] Edit it to add "searchRoots" pointing at your Nx/Angular workspace, then run again.
|
|
92
|
-
`),process.stdout.write(`[daimon] (Local override path: ${
|
|
93
|
-
`),process.exit(0)}let{config:s,path:
|
|
94
|
-
`),s.depends&&Object.keys(s.depends).length){let
|
|
95
|
-
`),process.exit(1))}let
|
|
96
|
-
`);let
|
|
97
|
-
`);for(let
|
|
98
|
-
`);continue}s.depends&&s.depends[
|
|
99
|
-
`)}catch{}let
|
|
100
|
-
`);try{
|
|
101
|
-
`)
|
|
102
|
-
`)
|
|
103
|
-
`),
|
|
104
|
-
`),process.
|
|
95
|
+
`),process.stdout.write(`[daimon] (Local override path: ${m.local})
|
|
96
|
+
`),process.exit(0)}let{config:s,path:o}=n;if(process.stdout.write(`[daimon] config: ${o}
|
|
97
|
+
`),s.depends&&Object.keys(s.depends).length){let m=jr(s.depends);m&&(process.stderr.write(`[daimon] config error: depends graph has a cycle: ${m.join(" -> ")}
|
|
98
|
+
`),process.exit(1))}let a=Et(s);a.length===0&&process.stdout.write(`[daimon] no serveable projects discovered in: ${s.searchRoots.join(", ")||"(none)"}
|
|
99
|
+
`);let c=Hn(),i=new Ot(s.portRange,{initial:c.ports,onChange:m=>Un({ports:m})}),l=new ae(s,a,i);t=l,e=s;let u=new Lt(s.history);l.setHistory(u);let d=new we(l,s.healthProbe,s),g=new ve(l),v=new Se(l,s.autoRestart),A=new ke(l,s.notifications),E=new xe(l,s.staleDetect),C=new Ee(l,s.requestLog);l.on("childExit",({name:m,code:T,signal:k,stopping:x})=>v.onExit(m,T,k,x)),l.on("userStop",({name:m})=>v.onUserStop(m));let y=Sn();if(y&&y.apps.length){process.stdout.write(`[daimon] state-handoff: restoring ${y.apps.map(m=>m.name).join(", ")}
|
|
100
|
+
`);for(let m of y.apps)i.pin(m.name,m.port);for(let m of y.apps)l.names().includes(m.name)&&l.start(m.name)}if(s.autoStart&&s.autoStart.length){let m=new Set(l.names());for(let T of s.autoStart){if(!m.has(T)){process.stderr.write(`[daimon] warning: autoStart references unknown app "${T}"
|
|
101
|
+
`);continue}s.depends&&s.depends[T]&&s.depends[T].length?l.startWithDeps(T):l.start(T)}}let P=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):s.apiPort,I=!!r.headless||!!s.headless||process.argv.includes("--headless"),J=setInterval(()=>{try{l.pruneOldErrors()}catch{}},3600*1e3),S=[];try{S=await es(ts(s.plugins?.dir??void 0));for(let m of S)m.status==="failed"&&process.stderr.write(`[daimon] plug-in skipped: ${$a.basename(m.file)} \u2014 ${m.error}
|
|
102
|
+
`)}catch{}let Q=s.webhooks&&s.webhooks.length?new Pe(l,s.webhooks,{onLog:m=>process.stderr.write(`[daimon] ${m}
|
|
103
|
+
`)}):null,Y=new Ae(u);Y.setSelfWarnHandler(m=>{try{l.recordEvent({app:"__daemon__",type:"self-warn",message:m})}catch{}});let z=setInterval(()=>{let m=Y.snapshot();u.recordSelfMetric(m.rssMB,m.heapUsedMB,m.eventLoopLagMs,m.historyDbQueryMs.p95)},60*1e3);z.unref&&z.unref();let p=!1,f=async()=>{if(!p){p=!0;try{clearInterval(J)}catch{}try{clearInterval(z)}catch{}try{Y.stop()}catch{}try{d.stop()}catch{}try{g.stop()}catch{}try{v.stop()}catch{}try{A.stop()}catch{}try{E.stop()}catch{}try{C.stop()}catch{}try{Q?.stop()}catch{}try{u.close()}catch{}try{await l.stopAll(3e3)}catch{}try{h.close()}catch{}try{Wt()}catch{}process.exit(0)}},h=Dn(l,P,{metricsEnabled:s.metrics.enabled,requestLog:C,onShutdown:()=>{f()},configPath:o,getConfig:()=>l.getConfig(),patchConfig:m=>{try{let T=zn({configPath:o,patch:m}),k=hr({configPath:o,registry:l});return{ok:!0,applied:T.applied,addedApps:k.addedApps,removedApps:k.removedApps,restartRequired:k.restartRequired}}catch(T){return{ok:!1,error:T?.message||String(T)}}},reloadConfig:async()=>{let m=hr({configPath:o,registry:l});return{ok:!0,addedApps:m.addedApps,removedApps:m.removedApps,restartRequired:m.restartRequired}},selfMetrics:Y,getPlugins:()=>S.map(m=>({name:m.name,description:m.description,file:m.file,status:m.status,error:m.error,lastFindings:m.lastFindings})),runPluginScans:async()=>{let m=ns({config:l.getConfig(),apps:l.names().map(T=>({name:T,workspaceRoot:l.getApp(T)?.workspaceRoot??""})),history:u});await rs(S,m)}});process.stdout.write(`[daimon] api: http://127.0.0.1:${P}
|
|
104
|
+
`);try{Yr(Zr(P,I,o))}catch(m){process.stderr.write(`[daimon] warning: could not write daemon.lock: ${m?.message||m}
|
|
105
|
+
`)}if(process.on("SIGINT",()=>{f()}),process.on("SIGTERM",()=>{f()}),process.on("beforeExit",()=>{f()}),I){process.stdout.write(`[daimon] headless mode \u2014 TUI suppressed. Dashboard: http://127.0.0.1:${P}
|
|
106
|
+
`);let m="",T=setInterval(()=>{let k=l.list().map($=>({name:$.name,status:$.status,health:$.health,port:$.port})),x=JSON.stringify(k);x!==m&&(process.stderr.write(x+`
|
|
107
|
+
`),m=x)},6e4);await new Promise(()=>{}),clearInterval(T);return}await _a(Na.createElement(Sr,{registry:l,apiPort:P,onQuit:()=>{f()}})).waitUntilExit(),await f()}var Da=(()=>{try{return import.meta.url===La(process.argv[1]||"").href}catch{return!1}})();Da&&ja().catch(r=>{process.stderr.write(`[daimon] fatal: ${r?.stack||r}
|
|
108
|
+
`),process.exit(1)});export{ja as startInProcess};
|