daimon 0.4.3 → 0.5.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 +177 -0
- package/dist/cli.js +67 -58
- package/dist/dashboard/3rdpartylicenses.txt +461 -0
- package/dist/dashboard/browser/chunk-3TYCIBMV.js +1 -0
- package/dist/dashboard/browser/chunk-5UAN6ETO.js +1 -0
- package/dist/dashboard/browser/chunk-AEERNAF7.js +1 -0
- package/dist/dashboard/browser/chunk-AX3RJNG4.js +1 -0
- package/dist/dashboard/browser/chunk-BADBUP5C.js +3 -0
- package/dist/dashboard/browser/chunk-BF6RQFHS.js +2 -0
- package/dist/dashboard/browser/chunk-C65CUT7O.js +4 -0
- package/dist/dashboard/browser/chunk-CNIZYK4A.js +1 -0
- package/dist/dashboard/browser/chunk-D4BFRQ63.js +4 -0
- package/dist/dashboard/browser/chunk-E235WGFQ.js +3 -0
- package/dist/dashboard/browser/chunk-F2EDJ6FT.js +4 -0
- package/dist/dashboard/browser/chunk-HFAARBWL.js +1 -0
- package/dist/dashboard/browser/chunk-HFJ25UTJ.js +4 -0
- package/dist/dashboard/browser/chunk-JX3IOOXU.js +4 -0
- package/dist/dashboard/browser/chunk-LQNYSOSZ.js +1 -0
- package/dist/dashboard/browser/chunk-MBVVV35N.js +1 -0
- package/dist/dashboard/browser/chunk-NC2VPB4Y.js +2 -0
- package/dist/dashboard/browser/chunk-NXNVIINH.js +1 -0
- package/dist/dashboard/browser/chunk-Q7R63OUT.js +3 -0
- package/dist/dashboard/browser/chunk-QLKOKZDG.js +9 -0
- package/dist/dashboard/browser/chunk-QQSPJIPQ.js +1 -0
- package/dist/dashboard/browser/chunk-SCAIGUJL.js +6 -0
- package/dist/dashboard/browser/chunk-SLQ2WBUA.js +1 -0
- package/dist/dashboard/browser/chunk-TSB6OOH2.js +6 -0
- package/dist/dashboard/browser/chunk-WAN7TQQW.js +1 -0
- package/dist/dashboard/browser/chunk-WWUKM5OG.js +1 -0
- package/dist/dashboard/browser/chunk-ZVU34B5S.js +1 -0
- package/dist/dashboard/browser/chunk-ZYE3XQS4.js +2 -0
- package/dist/dashboard/browser/index.html +15 -0
- package/dist/dashboard/browser/main-Z6L5VPBT.js +4 -0
- package/dist/dashboard/browser/styles-SIPYJLMG.css +1 -0
- package/dist/dashboard/prerendered-routes.json +3 -0
- package/dist/main.js +49 -44
- package/dist/mcp.js +2 -2
- package/package.json +5 -4
- package/src/templates/claude/skill.md.tmpl +23 -31
- package/src/dashboard.html +0 -451
- package/src/templates/claude/commands/doctor.md.tmpl +0 -10
- package/src/templates/claude/commands/errors.md.tmpl +0 -10
- package/src/templates/claude/commands/logs.md.tmpl +0 -10
- package/src/templates/claude/commands/restart.md.tmpl +0 -10
- package/src/templates/claude/commands/start.md.tmpl +0 -12
- package/src/templates/claude/commands/status.md.tmpl +0 -10
- package/src/templates/claude/commands/stop.md.tmpl +0 -10
- package/src/templates/claude/commands/up.md.tmpl +0 -10
- package/src/templates/claude/commands/wait.md.tmpl +0 -10
- package/src/templates/claude/commands/why.md.tmpl +0 -10
package/dist/main.js
CHANGED
|
@@ -1,25 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
`,"utf8"),{kind:"stub-created",path:t}}import
|
|
3
|
-
`);return[...e.values()].filter(
|
|
4
|
-
`);if(o<0)return;let i=s.slice(0,o),a=s.slice(o+1);e==="stdout"?this.stdoutBuf=a:this.stderrBuf=a;let{state:l}=this.deps,c=!1;for(let f of i.split(/\r?\n/)){if(!f.length)continue;let u=Jr(f),y=Date.now();l.lastLogTs=y,l.stale&&(l.stale=!1),l.logBuffer.push({ts:y,line:u}),l.logBuffer.length>ye&&l.logBuffer.splice(0,l.logBuffer.length-ye),this.deps.onLogLine?.(u);let b=l.status,p=he(l,u);p?.statusChanged&&(c=!0,this.deps.onStatusChange?.(b,l.status)),p?.error&&this.deps.onErrorRecorded?.(p.error.entry,p.error.isNew),p?.compileMs!=null&&this.deps.onCompile?.(p.compileMs),p?.bundleUpdated&&this.deps.onBundleUpdate?.()}(c||i.length>0)&&this.deps.onStateChange()}async stop(){if(!this.child||this.stopping)return;this.stopping=!0;let t=this.child.pid;if(!t){this.child=null,this.stopping=!1;return}await new Promise(e=>{let r=!1,s=()=>{r||(r=!0,e())},o=()=>s();this.child?.once("exit",o),ge(t,"SIGTERM",()=>{});let i=setTimeout(()=>{ge(t,"SIGKILL",()=>{})},2e3),a=setTimeout(()=>{clearTimeout(i),s()},3e3);this.child?.once("exit",()=>{clearTimeout(i),clearTimeout(a),s()})})}};import qr from"node:net";var z=class{assigned=new Map;min;max;onChange;constructor(t,e={}){if(this.min=t[0],this.max=t[1],this.onChange=e.onChange,e.initial){let r=new Set;for(let[s,o]of Object.entries(e.initial))typeof o=="number"&&(o<this.min||o>this.max||r.has(o)||(r.add(o),this.assigned.set(s,o)))}}snapshot(){return Object.fromEntries(this.assigned)}getAssigned(t){return this.assigned.get(t)}pin(t,e){this.assigned.set(t,e),this.onChange?.(this.snapshot())}async allocate(t,e){let r=this.assigned.get(t);if(e!==void 0)return this.assigned.set(t,e),this.onChange?.(this.snapshot()),e;if(r!==void 0)return r;let s=new Set(this.assigned.values());for(let o=this.min;o<=this.max;o++){if(s.has(o))continue;if(await at(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 at(t)}};function at(n){return new Promise(t=>{let e=qr.createServer();e.unref(),e.once("error",()=>t(!1)),e.listen({port:n,host:"127.0.0.1",exclusive:!0},()=>{e.close(()=>t(!0))})})}import B from"node:fs";import Xr from"node:path";var ct=class{constructor(t,e){this.appName=t;this.cfg=e;this.filePath=Xr.join(e.dir,`${t}.log`),this.open()}appName;cfg;fd=null;bytes=0;warned=!1;filePath;open(){try{B.mkdirSync(this.cfg.dir,{recursive:!0});try{this.bytes=B.statSync(this.filePath).size}catch{this.bytes=0}this.fd=B.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}
|
|
5
|
-
`,r=Buffer.from(e,"utf8");B.writeSync(this.fd,r),this.bytes+=r.length,this.bytes>=this.cfg.maxBytesPerFile&&this.rotate()}catch(e){this.warn(`write failed: ${e.message}`)}}close(){if(this.fd!=null){try{B.closeSync(this.fd)}catch{}this.fd=null}}rotate(){try{this.close();for(let t=this.cfg.maxFiles-1;t>=1;t--){let e=`${this.filePath}.${t}`,r=`${this.filePath}.${t+1}`;if(t+1>this.cfg.maxFiles-1){try{B.rmSync(e,{force:!0})}catch{}continue}try{B.existsSync(e)&&B.renameSync(e,r)}catch{}}try{let t=`${this.filePath}.1`;B.existsSync(this.filePath)&&B.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}
|
|
6
|
-
`))}};function ve(n){let s=new Map,o=new Map,i=null,a=l=>{if(!i){s.set(l,1);for(let c of n[l]||[]){let f=s.get(c)??0;if(f===1){let u=[c,l],y=o.get(l);for(;y&&y!==c;)u.push(y),y=o.get(y);y===c&&u.push(c),i=u.reverse();return}if(f===0&&(o.set(c,l),a(c),i))return}s.set(l,2)}};for(let l of Object.keys(n))if((s.get(l)??0)===0&&(o.set(l,null),a(l),i))return i;return null}function we(n,t){let e=new Set,r=[t];for(;r.length;){let s=r.pop();if(!e.has(s)){e.add(s);for(let o of n[s]||[])r.push(o)}}return[...e]}function be(n,t){let e=new Set(t),r=new Map,s=new Map;for(let a of t)r.set(a,0),s.set(a,[]);for(let a of t)for(let l of n[a]||[])e.has(l)&&(s.get(l).push(a),r.set(a,(r.get(a)??0)+1));let o=[],i=t.filter(a=>(r.get(a)??0)===0);for(;i.length;){o.push([...i].sort());let a=[];for(let l of i)for(let c of s.get(l)??[])r.set(c,(r.get(c)??1)-1),r.get(c)===0&&a.push(c);i=a}return o}function Se(n,t){let e=[];for(let[r,s]of Object.entries(n))s.includes(t)&&e.push(r);return e}import{spawn as Te}from"node:child_process";import Ee from"tree-kill";import ke from"strip-ansi";var Kr=/Tests:\s+(?:(\d+)\s+failed,\s+)?(\d+)\s+passed(?:,\s+(\d+)\s+total)?/,Yr=/Executed (\d+) of (\d+)(?:\s*\((\d+)\s*FAILED\))?/,zr=/(\d+)\s+passed(?:.*?(\d+)\s+failed)?/i;function Vr(n){let t=n.match(Kr);if(t){let s=t[1]?Number(t[1]):0,o=Number(t[2]),i=t[3]?Number(t[3]):o+s;return{passed:o,failed:s,total:i}}let e=n.match(Yr);if(e){let s=Number(e[1]),o=Number(e[2]),i=e[3]?Number(e[3]):0;return{passed:s-i,failed:i,total:o}}let r=n.match(zr);if(r){let s=Number(r[1]),o=r[2]?Number(r[2]):0;return{passed:s,failed:o,total:s+o}}return null}function xe(n,t,e){let r=e.length?" -- "+e.join(" "):"";return n.workspaceType==="nx"?`npx nx run ${n.name}:${t}${r}`:n.workspaceType==="angular"?`npx ng run ${n.name}:${t}${r}`:`npx ${t}${r}`}function Ae(n,t,e=[]){return new Promise(r=>{let s=Date.now(),o=xe(n,t,e),i=Te(o,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),a=[],l="",c=f=>{l+=f.toString("utf8");let u=l.lastIndexOf(`
|
|
7
|
-
`);if(u<0)return;let y=l.slice(0,u);l=l.slice(u+1);for(let b of y.split(/\r?\n/)){if(!b.length)continue;let p=ke(b);a.push(p),a.length>1e3&&a.splice(0,a.length-1e3)}};i.stdout?.on("data",c),i.stderr?.on("data",c),i.on("exit",f=>{let u=Date.now()-s,y=a.join(`
|
|
8
|
-
`)+(l?`
|
|
9
|
-
`+l:""),b=Vr(y);r({app:n.name,task:t,exitCode:f,durationMs:u,summary:b,outputTail:a.slice(-50)})}),i.on("error",()=>{r({app:n.name,task:t,exitCode:-1,durationMs:Date.now()-s,summary:null,outputTail:[...a,"[daimon] task spawn error"]})})})}function Ce(n,t,e=[]){let r=xe(n,t,e),s=Te(r,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),o=[],i="",a=c=>{i+=c.toString("utf8");let f=i.lastIndexOf(`
|
|
10
|
-
`);if(f<0)return;let u=i.slice(0,f);i=i.slice(f+1);for(let y of u.split(/\r?\n/))y.length&&(o.push(ke(y)),o.length>500&&o.splice(0,o.length-500))};return s.stdout?.on("data",a),s.stderr?.on("data",a),{app:n.name,task:t,pid:s.pid??null,child:s,startedAt:Date.now(),logs:o,stop:()=>new Promise(c=>{if(!s.pid){c();return}let f=!1,u=()=>{f||(f=!0,c())};s.once("exit",u),Ee(s.pid,"SIGTERM",()=>{}),setTimeout(()=>{s.pid&&Ee(s.pid,"SIGKILL",()=>{})},2e3),setTimeout(u,3500)})}}import{spawnSync as Lt}from"node:child_process";import so from"tree-kill";function Re(n){if(process.platform==="win32"){let o=Lt("powershell",["-NoProfile","-Command",`Get-NetTCPConnection -LocalPort ${n} -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty OwningProcess`],{encoding:"utf8",windowsHide:!0});if(o.status!==0)return null;let i=Number((o.stdout||"").trim().split(/\s+/)[0]);if(!Number.isFinite(i)||i<=0)return null;let a=Lt("powershell",["-NoProfile","-Command",`Get-CimInstance Win32_Process -Filter "ProcessId=${i}" | Select-Object -Property Name,CommandLine | ConvertTo-Json -Compress`],{encoding:"utf8",windowsHide:!0}),l,c;try{let f=JSON.parse((a.stdout||"").trim()||"{}");l=typeof f.Name=="string"?f.Name:void 0,c=typeof f.CommandLine=="string"?f.CommandLine:void 0}catch{}return{pid:i,name:l,cmd:c}}let t=Lt("lsof",["-nP","-iTCP:"+n,"-sTCP:LISTEN"],{encoding:"utf8"});if(t.status!==0)return null;let e=(t.stdout||"").split(/\r?\n/).filter(o=>o.trim()&&!o.startsWith("COMMAND"));if(!e.length)return null;let r=e[0].split(/\s+/);return{pid:Number(r[1]),name:r[0]}}function Pe(n,t){if(!t)return`port ${n} already in use`;let e=[`port ${n} in use by`];return t.name&&e.push(t.name),e.push(`(pid ${t.pid}`),t.cmd&&(e[e.length-1]+=`, cmd: ${t.cmd.slice(0,120)}`),e[e.length-1]+=")",e.join(" ")}import Ne from"node:fs";import Oe from"node:path";function $e(n){let t={},e;try{e=Ne.readFileSync(n,"utf8")}catch{return t}for(let r of e.split(/\r?\n/)){let s=r.trim();if(!s||s.startsWith("#"))continue;let o=s.indexOf("=");if(o<0)continue;let i=s.slice(0,o).trim(),a=s.slice(o+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),i&&(t[i]=a)}return t}function jt(n,t){return Oe.isAbsolute(t)?t:Oe.join(n,t)}function Mt(n,t){return t.filter(e=>Ne.existsSync(jt(n,e)))}import rn from"node:fs";import nn from"node:path";import pt from"node:fs";import je from"node:path";import en from"node:os";import Qr from"node:fs";import _t from"node:path";import{fileURLToPath as Zr}from"node:url";var Le=_t.dirname(Zr(import.meta.url));function tn(){let n=[_t.resolve(Le,"..","package.json"),_t.resolve(Le,"..","..","package.json")];for(let t of n)try{return JSON.parse(Qr.readFileSync(t,"utf8"))}catch{}return{}}var lt=tn().version||"0.0.0";var It=je.join(en.homedir(),".daimon"),Dt=je.join(It,"daemon.lock");function q(){return It}function Me(n){pt.mkdirSync(It,{recursive:!0});let t=Dt+"."+process.pid+".tmp";pt.writeFileSync(t,JSON.stringify(n)),pt.renameSync(t,Dt)}function _e(){try{pt.unlinkSync(Dt)}catch{}}function De(n,t){return{pid:process.pid,apiPort:n,version:lt,startedAt:Date.now(),headless:t}}function sn(){return nn.join(q(),"secrets.json")}function Ie(){try{let n=rn.readFileSync(sn(),"utf8");n.charCodeAt(0)===65279&&(n=n.slice(1));let t=JSON.parse(n);if(!t||typeof t!="object")return{};let e={};for(let[r,s]of Object.entries(t))typeof s=="string"&&(e[r]=s);return e}catch{return{}}}function Fe(n,t){let e={};for(let[r,s]of Object.entries(n))e[r]=s.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,(o,i)=>t[i]??`\${${i}}`);return e}import Ft from"node:fs";import on from"node:os";import Be from"node:path";var ut=class{file=null;startTs=0;isRecording(){return this.file!=null}start(){if(this.file)return{path:this.file};let t=Be.join(on.homedir(),".daimon","sessions");Ft.mkdirSync(t,{recursive:!0});let e=Be.join(t,`${new Date().toISOString().replace(/[:.]/g,"-")}.jsonl`);return Ft.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})+`
|
|
11
|
-
`;try{Ft.appendFileSync(this.file,e)}catch{}}};var He=500,ft=class extends an{entries=new Map;portAlloc;config;eventBuffer=[];history=null;watchTasks=new Map;sessionRecorder=new ut;constructor(t,e,r){super(),this.config=t,this.portAlloc=r??new z(t.portRange);for(let s of e)this.entries.set(s.name,{app:s,state:this.freshState(s.name,s.tags,s.workspaceLabel??null),proc:null})}getConfig(){return this.config}addDiscoveredApp(t){this.entries.has(t.name)||(this.entries.set(t.name,{app:t,state:this.freshState(t.name,t.tags,t.workspaceLabel??null),proc:null}),this.emit("change"))}updateDiscoveredApp(t){let e=this.entries.get(t.name);e&&(e.app=t,e.state.tags=t.tags,e.state.workspaceLabel=t.workspaceLabel??null,e.state.dependsOn=this.config.depends?.[t.name]??[],this.emit("change"))}getPortAllocator(){return this.portAlloc}setHistory(t){this.history=t}getHistory(){return this.history}freshState(t,e,r=null){return{name:t,status:"stopped",port:null,pid:null,startedAt:null,compileStartedAt:null,lastCompileMs:null,lastCompileAt:null,logBuffer:[],errors:new Map,compileHistory:[],health:"unknown",lastHealthAt:null,cpu:null,memMB:null,restartAttempts:0,restartWindowStart:null,nextRestartAt:null,tags:e,announcedUrl:null,lastHealthError:null,cachedProbeHost:null,lastLogTs:null,stale:!1,bundle:null,bundleRegressionPct:null,activeEnvFile:null,sessionOverrides:null,dependsOn:this.config.depends?.[t]??[],workspaceLabel:r}}names(){return[...this.entries.keys()]}list(){return this.names().map(t=>this.summary(t))}summary(t){let e=this.entries.get(t);if(!e)return null;let r=e.state,s=r.startedAt&&(r.status==="serving"||r.status==="compiling"||r.status==="starting")?Date.now()-r.startedAt:null,i=this.config.overrides?.[t]?.url||e.resolvedUrl||r.announcedUrl||(r.port?`http://127.0.0.1:${r.port}`:null);return{name:r.name,status:r.status,port:r.port,url:i,errorCount:[...r.errors.values()].reduce((a,l)=>a+l.count,0),uptimeMs:s,lastCompileMs:r.lastCompileMs,health:r.health,lastHealthAt:r.lastHealthAt,cpu:r.cpu,memMB:r.memMB,compileHistoryMs:[...r.compileHistory],tags:[...r.tags],restartAttempts:r.restartAttempts,nextRestartAt:r.nextRestartAt,announcedUrl:r.announcedUrl,lastHealthError:r.lastHealthError,stale:r.stale,bundle:r.bundle,bundleRegressionPct:r.bundleRegressionPct,dependsOn:[...r.dependsOn],activeEnvFile:r.activeEnvFile,workspaceLabel:r.workspaceLabel}}getState(t){return this.entries.get(t)?.state??null}getApp(t){return this.entries.get(t)?.app??null}errors(t){let e=this.getState(t);return e?[...e.errors.values()].sort((r,s)=>s.lastSeen-r.lastSeen):null}errorsSince(t,e){let r=this.getState(t);return r?[...r.errors.values()].filter(s=>s.lastSeen>e).sort((s,o)=>o.lastSeen-s.lastSeen):null}logs(t,e={}){let r=this.getState(t);if(!r)return null;let s=r.logBuffer;if(e.sinceMs&&e.sinceMs>0){let o=Date.now()-e.sinceMs;s=s.filter(i=>i.ts>=o)}return e.tail&&e.tail>0&&(s=s.slice(-e.tail)),s.map(o=>o.line)}events(t={}){let e=t.sinceMs&&t.sinceMs>0?Date.now()-t.sinceMs:0;return this.eventBuffer.filter(r=>r.ts>=e&&(!t.app||r.app===t.app))}recordEvent(t){let e={ts:t.ts??Date.now(),...t};this.eventBuffer.push(e),this.eventBuffer.length>He&&this.eventBuffer.splice(0,this.eventBuffer.length-He),this.history?.recordEvent(e),this.emit("event",e)}setHealth(t,e){let r=this.entries.get(t);if(!r)return;let s=r.state;if(s.lastHealthAt=Date.now(),s.health===e)return;let o=s.health;s.health=e,e==="healthy"&&(r.prevHealthyAt=Date.now(),r.cascadeArmed&&(r.cascadeArmed=!1,this.triggerCascadeRestart(t))),this.recordEvent({app:t,type:"health",from:o,to:e}),this.emit("change")}armCascade(t){let e=this.entries.get(t);e&&this.config.cascadeRestart&&e.prevHealthyAt!=null&&(e.cascadeArmed=!0)}setLastHealthError(t,e){let r=this.getState(t);r&&r.lastHealthError!==e&&(r.lastHealthError=e,this.emit("change"))}setResolvedUrl(t,e){let r=this.entries.get(t);r&&r.resolvedUrl!==e&&(r.resolvedUrl=e,this.emit("change"))}setCachedProbeHost(t,e){let r=this.getState(t);r&&(r.cachedProbeHost=e)}setStale(t,e){let r=this.getState(t);r&&r.stale!==e&&(r.stale=e,this.emit("change"))}setSessionOverride(t,e){let r=this.getState(t);r&&(r.sessionOverrides=e,this.emit("change"))}setActiveEnvFile(t,e){let r=this.getState(t);r&&(r.activeEnvFile=e,this.emit("change"))}async start(t){this.sessionRecorder.append({kind:"start",app:t});let e=this.entries.get(t);if(!e)return{ok:!1,status:"unknown",error:"unknown app"};if(e.proc?.isRunning())return{ok:!0,status:e.state.status};let r=e.state.status,s;try{s=await this.portAlloc.allocate(t,e.app.pinnedPort)}catch(b){return e.state.status="error",e.state.lastStatusMessage=b.message,this.recordEvent({app:t,type:"status",from:r,to:"error",message:b.message}),this.emit("change"),{ok:!1,status:"error",error:b.message}}if(!await at(s)){let b=Re(s),p=Pe(s,b);return e.state.status="error",e.state.port=s,e.state.lastStatusMessage=p,this.recordEvent({app:t,type:"status",from:r,to:"error",message:p}),this.emit("change"),{ok:!1,status:"error",error:p}}e.state.health="unknown",e.state.lastHealthAt=null,e.state.announcedUrl=null,e.state.lastHealthError=null,e.state.cachedProbeHost=null,e.state.stale=!1,e.state.lastLogTs=null,e.resolvedUrl=void 0,!e.logger&&this.config.logs.enabled&&(e.logger=new ct(t,this.config.logs));let i=e.state.sessionOverrides,a=this.config.envFiles?.[t]??[],l={};if(a.length){let b=e.state.activeEnvFile;(!b||!Mt(e.app.workspaceRoot,[b]).length)&&(b=Mt(e.app.workspaceRoot,a)[0]??null,b&&(e.state.activeEnvFile=b)),b&&(l=$e(jt(e.app.workspaceRoot,b)))}let c={...l,...this.config.overrides?.[t]?.env??{},...i?.env??{}},f=Ie(),u=Fe(c,f),y=new it({state:e.state,app:e.app,port:s,envOverride:Object.keys(u).length?u:void 0,commandOverride:i?.command,onStateChange:()=>this.emit("change"),onStatusChange:(b,p,m)=>{this.recordEvent({app:t,type:"status",from:b,to:p,message:m}),(p==="stopped"||p==="error")&&(b==="serving"||b==="compiling")&&this.armCascade(t)},onErrorRecorded:(b,p)=>this.recordEvent({app:t,type:p?"error-new":"error-recur",message:b.message}),onExit:(b,p,m)=>this.emit("childExit",{name:t,code:b,signal:p,stopping:m}),onLogLine:b=>{e.logger?.write(b),this.emit("log",{name:t,ts:Date.now(),line:b})},onCompile:b=>{this.history?.recordCompile(t,b);let p=this.getState(t),m=e.lastBundleInitialKB;if(p.bundle&&p.bundle.initialKB>0){if(m&&m>0){let g=(p.bundle.initialKB-m)/m*100;p.bundleRegressionPct=Math.round(g*10)/10,g>10&&this.recordEvent({app:t,type:"bundle-regression",message:`initialKB +${p.bundleRegressionPct}% (${m}->${p.bundle.initialKB})`})}else p.bundleRegressionPct=null;e.lastBundleInitialKB=p.bundle.initialKB}this.checkCompileRegression(t,b),this.emit("compile",{name:t,ms:b})},onBundleUpdate:()=>this.emit("bundleUpdate",{name:t})});return e.proc=y,this.recordEvent({app:t,type:"status",from:r,to:"starting"}),y.start(),{ok:!0,status:e.state.status}}async stop(t){this.sessionRecorder.append({kind:"stop",app:t});let e=this.entries.get(t);if(!e)return{ok:!1,status:"unknown",error:"unknown app"};if(this.emit("userStop",{name:t}),!e.proc||!e.proc.isRunning())return e.state.status!=="stopped"&&this.recordEvent({app:t,type:"status",from:e.state.status,to:"stopped"}),e.state.status="stopped",e.state.pid=null,e.state.health="unknown",this.emit("change"),{ok:!0,status:"stopped"};let r=e.state.status;return await e.proc.stop(),e.proc=null,e.state.status!==r&&this.recordEvent({app:t,type:"status",from:r,to:e.state.status}),{ok:!0,status:e.state.status}}async restart(t){return this.sessionRecorder.append({kind:"restart",app:t}),await this.stop(t),this.start(t)}async startWithDeps(t,e={}){if(!this.entries.has(t))return{ok:!1,results:[{name:t,status:"unknown",health:"unknown",error:"unknown app"}]};let r=we(this.config.depends??{},t).filter(a=>this.entries.has(a)),s=be(this.config.depends??{},r),o=[],i=e.waitMs??6e4;for(let a of s){let l=await Promise.all(a.map(f=>this.start(f)));for(let f=0;f<a.length;f++){let u=l[f];if(!u.ok)return o.push({name:a[f],status:u.status,health:"unknown",error:u.error}),{ok:!1,results:o}}let c=await Promise.all(a.map(f=>this.waitFor(f,"healthy",i)));for(let f=0;f<a.length;f++){let u=c[f],y=!u.timedOut&&u.status==="serving"&&u.health==="healthy";if(o.push({name:u.name,status:u.status,health:u.health,error:y?void 0:u.timedOut?"timeout waiting for healthy":"did not reach healthy"}),!y)return{ok:!1,results:o}}}return{ok:!0,results:o}}triggerCascadeRestart(t){if(!this.config.cascadeRestart)return;let e=Se(this.config.depends??{},t);for(let r of e){let s=this.getState(r);s&&(s.status==="serving"||s.status==="compiling"||s.status==="starting")&&this.restart(r)}}async stopAll(t=3e3){let e=[];for(let r of this.entries.values())r.proc?.isRunning()&&e.push(r.proc.stop());for(let r of this.watchTasks.values())e.push(r.stop());await Promise.race([Promise.all(e),new Promise(r=>setTimeout(r,t))]);for(let r of this.entries.values())r.logger?.close()}listTasks(t){let e=this.getApp(t);return e?[...e.tasks??[]]:null}async runTask(t,e,r=[]){this.sessionRecorder.append({kind:"run",app:t,task:e,args:r});let s=this.getApp(t);if(!s)return{error:"unknown app"};let o=await Ae(s,e,r);return this.history?.recordTaskRun(t,e,o.exitCode,o.durationMs,o.summary),this.recordEvent({app:t,type:"task-run",message:`${e} exit=${o.exitCode} duration=${o.durationMs}ms`}),this.emit("taskRun",{name:t,task:e,result:o}),o}startWatchTask(t,e,r=[]){let s=this.getApp(t);if(!s)return{ok:!1,error:"unknown app"};let o=`${t}::${e}`;if(this.watchTasks.has(o))return{ok:!0,pid:this.watchTasks.get(o).pid};let i=Ce(s,e,r);return this.watchTasks.set(o,i),i.child.on("exit",()=>this.watchTasks.delete(o)),{ok:!0,pid:i.pid}}async stopWatchTask(t,e){let r=`${t}::${e}`,s=this.watchTasks.get(r);return s?(await s.stop(),this.watchTasks.delete(r),{ok:!0}):{ok:!0}}listWatchTasks(t){let e=[];for(let r of this.watchTasks.values())t&&r.app!==t||e.push({app:r.app,task:r.task,pid:r.pid,startedAt:r.startedAt});return e}checkCompileRegression(t,e){let r=this.history;if(!r)return;let o=r.queryCompiles({app:t,limit:31}).filter(l=>l.ms!==e).slice(0,30).map(l=>l.ms);if(o.length<10)return;let i=[...o].sort((l,c)=>l-c),a=i[Math.floor((i.length-1)*.5)];e>2*a&&this.recordEvent({app:t,type:"compile-regression",message:`${(e/1e3).toFixed(1)}s vs p50 ${(a/1e3).toFixed(1)}s`})}watchTaskLogs(t,e,r){let s=this.watchTasks.get(`${t}::${e}`);if(!s)return null;let o=s.logs;return r?o.slice(-r):[...o]}waitFor(t,e,r){return new Promise(s=>{let o=Date.now(),i=this.entries.get(t),a=()=>{if(!i)return!0;let u=i.state;return e==="serving"&&u.status==="serving"||e==="healthy"&&u.status==="serving"&&u.health==="healthy"||e==="stopped"&&u.status==="stopped"||e==="error"&&u.status==="error"},l=u=>{this.off("change",c),clearTimeout(f);let y=i?.state;s({name:t,status:y?.status??"unknown",health:y?.health??"unknown",timedOut:u,waitedMs:Date.now()-o})},c=()=>{a()&&l(!1)};if(a()){s({name:t,status:i.state.status,health:i.state.health,timedOut:!1,waitedMs:0});return}let f=setTimeout(()=>l(!0),r);this.on("change",c)})}};import Tn from"node:http";import kn from"node:crypto";import Kt from"node:fs";import Xt from"node:path";import{fileURLToPath as xn}from"node:url";import Ut from"node:fs";import Ue from"node:path";import cn from"node:os";var Wt=Ue.join(cn.homedir(),".daimon","cursors.json");function ln(){try{let n=Ut.readFileSync(Wt,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.errors&&typeof t.errors=="object")return{errors:t.errors}}catch{}return{errors:{}}}var Bt=null,Ht=null;function pn(n){Ht=n,!Bt&&(Bt=setTimeout(()=>{Bt=null;let t=Ht;if(Ht=null,!!t)try{Ut.mkdirSync(Ue.dirname(Wt),{recursive:!0}),Ut.writeFileSync(Wt,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: cursor write failed: ${e.message}
|
|
12
|
-
`)}},500))}var dt=class{data=ln();getErrorCursor(t,e){return this.data.errors[`${t}:${e}`]??0}setErrorCursor(t,e,r){this.data.errors[`${t}:${e}`]=r,pn(this.data)}};import We from"node:fs";import un from"node:os";import Ge from"node:path";var fn=/key|secret|token|password|api[-_]?key/i;function dn(n){let t={};for(let[e,r]of Object.entries(n))typeof r=="string"&&(t[e]=fn.test(e)?"***":r);return t}function Gt(n,t){let e=n.summary(t);if(!e)return null;let r=n.getState(t),s=n.getApp(t),o=n.getConfig(),i=o.overrides?.[t]??{},a={...process.env,...s.env??{},...r.sessionOverrides?.env??{}},l=n.getHistory(),c=l?l.queryEvents({app:t,limit:50}):[];return{takenAt:new Date().toISOString(),summary:e,logs:r.logBuffer.slice(-500).map(f=>({ts:f.ts,line:f.line})),errors:[...r.errors.entries()].map(([f,u])=>({hash:f,message:u.message,count:u.count,firstSeen:u.firstSeen,lastSeen:u.lastSeen})),env:dn(a),configSlice:{command:r.sessionOverrides?.command??i.command??s.command,port:r.sessionOverrides?.port??i.port??null,workspaceRoot:s.workspaceRoot,workspaceType:s.workspaceType,tags:s.tags,depends:o.depends?.[t]??[],envFiles:o.envFiles?.[t]??[]},events:c}}function Je(n,t){let e=Gt(n,t);if(!e)return null;let r=Ge.join(un.homedir(),".daimon","snapshots");We.mkdirSync(r,{recursive:!0});let s=e.takenAt.replace(/[:.]/g,"-"),o=Ge.join(r,`${t}-${s}.json`);return We.writeFileSync(o,JSON.stringify(e,null,2)),{path:o,payload:e}}import mt from"node:fs";import qe from"node:path";var mn=["dist",".angular/cache","tmp","out-tsc"],hn=["node_modules"];function Xe(n){let t=0;try{let e=mt.readdirSync(n,{withFileTypes:!0});for(let r of e){let s=qe.join(n,r.name);try{r.isDirectory()?t+=Xe(s):r.isFile()&&(t+=mt.statSync(s).size)}catch{}}}catch{}return t}function Jt(n,t,e){let r=n.getApp(t);if(!r)return null;let s=n.getState(t),o=s?s.status==="serving"||s.status==="compiling"||s.status==="starting":!1,a=[...mn,...e?hn:[]].map(l=>{let c=qe.join(r.workspaceRoot,l),f=mt.existsSync(c);return{path:c,exists:f,sizeBytes:f?Xe(c):0}});return{app:t,workspace:r.workspaceRoot,targets:a,ranOnServing:o}}function Ke(n,t,e){let r=Jt(n,t,e);if(!r)return{error:"unknown app"};if(r.ranOnServing)return{error:"app is currently running; stop it first"};let s=[],o=[];for(let i of r.targets)if(i.exists)try{mt.rmSync(i.path,{recursive:!0,force:!0}),s.push(i.path)}catch(a){o.push({path:i.path,error:a?.message||String(a)})}return{ok:o.length===0,removed:s,failed:o}}function rt(n){return n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}var gn=["stopped","starting","compiling","serving","error"];function Ye(n){let t=[];t.push("# HELP daimon_up daimon daemon up"),t.push("# TYPE daimon_up gauge"),t.push("daimon_up 1"),t.push("# HELP daimon_app_status app status one-hot"),t.push("# TYPE daimon_app_status gauge");let e=n.list();for(let r of e)for(let s of gn)t.push(`daimon_app_status{name="${rt(r.name)}",status="${s}"} ${r.status===s?1:0}`);t.push("# HELP daimon_compile_seconds last successful compile duration in seconds"),t.push("# TYPE daimon_compile_seconds gauge");for(let r of e)r.lastCompileMs!=null&&t.push(`daimon_compile_seconds{name="${rt(r.name)}"} ${(r.lastCompileMs/1e3).toFixed(3)}`);t.push("# HELP daimon_error_total cumulative deduped error count"),t.push("# TYPE daimon_error_total counter");for(let r of e)t.push(`daimon_error_total{name="${rt(r.name)}"} ${r.errorCount}`);t.push("# HELP daimon_cpu_percent app CPU percent"),t.push("# TYPE daimon_cpu_percent gauge");for(let r of e)r.cpu!=null&&t.push(`daimon_cpu_percent{name="${rt(r.name)}"} ${r.cpu}`);t.push("# HELP daimon_mem_mb app resident memory MB"),t.push("# TYPE daimon_mem_mb gauge");for(let r of e)r.memMB!=null&&t.push(`daimon_mem_mb{name="${rt(r.name)}"} ${r.memMB}`);return t.join(`
|
|
13
|
-
`)+`
|
|
14
|
-
`}import nt from"node:fs";import yn from"node:crypto";import ze from"node:path";var vn=1e6;function wn(){return ze.join(q(),"audit.log")}function bn(n){try{if(nt.statSync(n).size>vn){let e=n+".1";try{nt.unlinkSync(e)}catch{}nt.renameSync(n,e)}}catch{}}function Ve(n,t,e,r){let s=wn();nt.mkdirSync(ze.dirname(s),{recursive:!0}),bn(s);let o=JSON.stringify({prev:t,next:e}),i=yn.createHash("sha1").update(o).digest("hex").slice(0,12),a=`${new Date().toISOString()} ${n} ${i} ${r.join(",")}
|
|
15
|
-
`;try{nt.appendFileSync(s,a)}catch{}}import ht from"node:fs";import gt from"node:path";import{fileURLToPath as Sn}from"node:url";var Qe=gt.dirname(Sn(import.meta.url));function En(){let n=[gt.resolve(Qe,"templates","presets"),gt.resolve(Qe,"..","src","templates","presets")];for(let t of n)if(ht.existsSync(t))return t;return n[0]}function Ze(){let n=En();if(!ht.existsSync(n))return[];let t=ht.readdirSync(n).filter(r=>r.endsWith(".json")),e=[];for(let r of t)try{let s=ht.readFileSync(gt.join(n,r),"utf8");s.charCodeAt(0)===65279&&(s=s.slice(1)),e.push(JSON.parse(s))}catch{}return e}import yt from"node:fs";import tr from"node:path";function er(){return tr.join(q(),"state-handoff.json")}function rr(n){let t=[];for(let s of n.names()){let o=n.getState(s);o&&(o.status==="serving"||o.status==="compiling"||o.status==="starting")&&o.port&&t.push({name:s,port:o.port})}let e={ts:Date.now(),apps:t},r=er();return yt.mkdirSync(tr.dirname(r),{recursive:!0}),yt.writeFileSync(r,JSON.stringify(e)),r}function nr(n=6e4){let t=er();try{let e=yt.readFileSync(t,"utf8"),r=JSON.parse(e);return yt.unlinkSync(t),!r||typeof r.ts!="number"||Date.now()-r.ts>n?null:r}catch{return null}}var An=xn(import.meta.url),sr=Xt.dirname(An);function Cn(){return[Xt.resolve(sr,"dashboard.html"),Xt.resolve(sr,"..","src","dashboard.html")].find(t=>Kt.existsSync(t))??null}function w(n,t,e){let r=JSON.stringify(e);n.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(r)}),n.end(r)}function V(n){if(!n)return;let t=n.match(/^(\d+)(ms|s|m|h)?$/);if(!t)return;let e=Number(t[1]);switch(t[2]||"ms"){case"ms":return e;case"s":return e*1e3;case"m":return e*60*1e3;case"h":return e*60*60*1e3}}function Rn(n){if(!n)return{};if(/^\d{10,}$/.test(n))return{sinceTs:Number(n)};let t=V(n);return t!=null?{sinceMs:t}:{}}var Pn=/key|secret|token|password|pass/i;function On(n){let t=JSON.parse(JSON.stringify(n));if(t.apiToken&&(t.apiToken="***"),t.overrides&&typeof t.overrides=="object")for(let e of Object.keys(t.overrides)){let r=t.overrides[e]?.env;if(r&&typeof r=="object")for(let s of Object.keys(r))Pn.test(s)&&(r[s]="***")}return t}function qt(n){if(!n)return"";try{let t=Kt.readFileSync(n);return kn.createHash("sha1").update(t).digest("hex")}catch{return""}}function or(n,t,e={}){let r=new dt,s=Tn.createServer(async(o,i)=>{try{let a=new URL(o.url||"/","http://127.0.0.1"),l=o.method||"GET",c=a.pathname.replace(/\/$/,"").split("/").filter(Boolean),f=()=>{let m=(e.getConfig?e.getConfig():null)?.apiToken??null;if(!m)return!0;let g=o.headers.authorization;return typeof g=="string"&&g.toLowerCase().startsWith("bearer ")&&g.slice(7).trim()===m?!0:(w(i,401,{error:"unauthorized"}),!1)};if(l==="POST"&&a.pathname==="/api/shutdown"){if(!f())return;w(i,200,{ok:!0}),e.onShutdown&&setImmediate(()=>{try{e.onShutdown()}catch{}});return}if(a.pathname==="/api/config"&&e.getConfig){if(l==="GET"){let p=e.getConfig(),m=qt(e.configPath);i.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:m}),i.end(JSON.stringify({etag:m,config:On(p)}));return}if(l==="PATCH"&&e.patchConfig){if(!f())return;let p=o.headers["if-match"]?.trim(),m=qt(e.configPath);if(!p||p!==m){w(i,412,{error:"etag mismatch",current:m});return}let g={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(A=>{let $=[];o.on("data",S=>$.push(S)),o.on("end",()=>{try{g=JSON.parse(Buffer.concat($).toString("utf8"))}catch{}A()})});let d=e.patchConfig(g);if(!d.ok){w(i,400,{error:d.error});return}let v=qt(e.configPath);try{let A=o.socket.remoteAddress||"127.0.0.1";Ve(A,g,g,d.applied)}catch{}i.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:v}),i.end(JSON.stringify({etag:v,applied:d.applied,addedApps:d.addedApps,removedApps:d.removedApps,restartRequired:d.restartRequired}));return}w(i,405,{error:"method not allowed"});return}if(a.pathname==="/api/presets"&&l==="GET"){w(i,200,Ze());return}if(a.pathname==="/api/snapshot-state"&&l==="POST"){if(!f())return;let p=rr(n);w(i,200,{ok:!0,path:p});return}if(a.pathname==="/api/config/reload"&&l==="POST"&&e.reloadConfig){if(!f())return;try{let p=await e.reloadConfig();w(i,200,p)}catch(p){w(i,400,{error:p?.message||String(p)})}return}if(l==="GET"&&a.pathname==="/metrics"&&e.metricsEnabled){let p=Ye(n);i.writeHead(200,{"content-type":"text/plain; version=0.0.4","content-length":Buffer.byteLength(p)}),i.end(p);return}if(l!=="GET"&&a.pathname.startsWith("/api/")&&a.pathname!=="/api/shutdown"&&a.pathname!=="/api/config"&&a.pathname!=="/api/config/reload"&&!f())return;if(l==="GET"&&a.pathname==="/"){let p=Cn();if(!p){i.writeHead(404).end("dashboard not found");return}let m=Kt.readFileSync(p);i.writeHead(200,{"content-type":"text/html; charset=utf-8","content-length":m.length}),i.end(m);return}if(c[0]==="api"&&c[1]==="events"&&c.length===2){if(l!=="GET"){w(i,405,{error:"method not allowed"});return}let p=V(a.searchParams.get("since")),m=a.searchParams.get("app")||void 0,g=n.events({sinceMs:p,app:m}),d=n.getHistory();if(d&&p&&g.length<500){let v=Date.now()-p,A=d.queryEvents({app:m,since:v,limit:1e3}),$=new Set(g.map(S=>`${S.ts}|${S.app}|${S.type}|${S.from??""}|${S.to??""}|${S.message??""}`));for(let S of A){let L=`${S.ts}|${S.app}|${S.type}|${S.from_state??""}|${S.to_state??""}|${S.message??""}`;$.has(L)||g.push({ts:S.ts,app:S.app,type:S.type,from:S.from_state??void 0,to:S.to_state??void 0,message:S.message??void 0})}g.sort((S,L)=>S.ts-L.ts)}w(i,200,g);return}if(c[0]==="api"&&c[1]==="session"){if(c[2]==="record"&&l==="POST"){let p=a.searchParams.get("action")||"toggle";if(p==="start"||p==="toggle"&&!n.sessionRecorder.isRecording()){let m=n.sessionRecorder.start();w(i,200,{recording:!0,path:m.path});return}if(p==="stop"||p==="toggle"&&n.sessionRecorder.isRecording()){let m=n.sessionRecorder.stop();w(i,200,{recording:!1,path:m.path});return}w(i,400,{error:"invalid action"});return}if(c[2]==="status"&&l==="GET"){w(i,200,{recording:n.sessionRecorder.isRecording()});return}w(i,404,{error:"not found"});return}if(c[0]==="api"&&c[1]==="history"){if(l!=="GET"){w(i,405,{error:"method not allowed"});return}let p=n.getHistory();if(!p){w(i,200,[]);return}let m=c[2],g=a.searchParams.get("app")||void 0,d=a.searchParams.get("since"),v=a.searchParams.get("until"),A=a.searchParams.get("limit"),$=d?/^\d{10,}$/.test(d)?Number(d):Date.now()-(V(d)??0):void 0,S=v?/^\d{10,}$/.test(v)?Number(v):Date.now()-(V(v)??0):void 0,L=A?Number(A):void 0;if(m==="events"){w(i,200,p.queryEvents({app:g,since:$,until:S,type:a.searchParams.get("type")||void 0,limit:L}));return}if(m==="compile-times"){w(i,200,p.queryCompiles({app:g,since:$,until:S,limit:L}));return}if(m==="tasks"){w(i,200,p.queryTasks({app:g,task:a.searchParams.get("task")||void 0,since:$,limit:L}));return}if(m==="summary"&&c.length>=4){let U=decodeURIComponent(c[3]);w(i,200,p.summary(U));return}if(m==="why"&&c.length>=4){let U=decodeURIComponent(c[3]);w(i,200,p.why(U));return}w(i,404,{error:"not found"});return}if(c[0]!=="api"||c[1]!=="apps"){w(i,404,{error:"not found"});return}if(c.length===2){if(l!=="GET"){w(i,405,{error:"method not allowed"});return}w(i,200,n.list());return}let u=decodeURIComponent(c[2]),y=c[3],b=c[4];if(!y){if(l!=="GET"){w(i,405,{error:"method not allowed"});return}let p=n.summary(u);if(!p){w(i,404,{error:"unknown app"});return}w(i,200,p);return}if(y==="errors"&&b==="since-last"&&l==="GET"){let p=a.searchParams.get("client")||"default",m=r.getErrorCursor(p,u),g=n.errorsSince(u,m);if(g==null){w(i,404,{error:"unknown app"});return}let d=g.reduce((v,A)=>Math.max(v,A.lastSeen),m);d>m&&r.setErrorCursor(p,u,d),w(i,200,g);return}if(y==="errors"&&!b&&l==="GET"){let p=a.searchParams.get("since");if(p){let{sinceMs:g,sinceTs:d}=Rn(p),v=d??(g!=null?Date.now()-g:0),A=n.errorsSince(u,v);if(A==null){w(i,404,{error:"unknown app"});return}w(i,200,A);return}let m=n.errors(u);if(m==null){w(i,404,{error:"unknown app"});return}w(i,200,m);return}if(y==="logs"&&c[4]==="stream"&&l==="GET"){if(!n.summary(u)){w(i,404,{error:"unknown app"});return}i.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"});let p=n.logs(u,{tail:50})??[];for(let $ of p)i.write(`data: ${JSON.stringify({ts:Date.now(),line:$})}
|
|
16
|
-
|
|
17
|
-
`);let m=[],g=0,d=()=>{for(;m.length&&i.write(m.shift()););},v=$=>{$.name===u&&(m.length>=200&&(g++,m.shift()),m.push(`data: ${JSON.stringify({ts:$.ts,line:$.line})}
|
|
18
|
-
|
|
19
|
-
`),d())};n.on("log",v);let A=setInterval(()=>i.write(`: ping
|
|
20
|
-
|
|
21
|
-
`),3e4);o.on("close",()=>{n.off("log",v),clearInterval(A)});return}if(y==="logs"&&l==="GET"){let p=a.searchParams.get("tail"),m=a.searchParams.get("since"),g=n.logs(u,{tail:p?Number(p):void 0,sinceMs:V(m)});if(g==null){w(i,404,{error:"unknown app"});return}w(i,200,{lines:g});return}if(y==="wait"&&l==="GET"){if(!n.summary(u)){w(i,404,{error:"unknown app"});return}let p=(a.searchParams.get("until")||"serving").toLowerCase();if(!["serving","healthy","stopped","error"].includes(p)){w(i,400,{error:"until must be one of serving|healthy|stopped|error"});return}let m=a.searchParams.get("timeout"),g=m?Number(m):120;(!Number.isFinite(g)||g<=0)&&(g=120),g=Math.min(g,600);let d=await n.waitFor(u,p,g*1e3);w(i,200,d);return}if(y==="start"&&l==="POST"){if(a.searchParams.get("withDeps")==="1"){let g=await n.startWithDeps(u);w(i,g.ok?200:400,g);return}let m=await n.start(u);w(i,m.ok?200:400,m);return}if(y==="start-with-deps"&&l==="POST"){let p=await n.startWithDeps(u);w(i,p.ok?200:400,p);return}if(y==="tasks"&&l==="GET"&&!b){let p=n.listTasks(u);if(p==null){w(i,404,{error:"unknown app"});return}w(i,200,{tasks:p,watching:n.listWatchTasks(u)});return}if(y==="run"&&b&&l==="POST"){let p={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(d=>{let v=[];o.on("data",A=>v.push(A)),o.on("end",()=>{try{p=JSON.parse(Buffer.concat(v).toString("utf8"))}catch{}d()})});let m=Array.isArray(p.args)?p.args.map(String):[];if(p.watch){let d=n.startWatchTask(u,b,m);w(i,d.ok?200:400,d);return}let g=await n.runTask(u,b,m);if("error"in g){w(i,404,g);return}w(i,200,g);return}if(y==="run-stop"&&b&&l==="POST"){let p=await n.stopWatchTask(u,b);w(i,200,p);return}if(y==="env"&&l==="GET"){let m=n.getConfig().envFiles?.[u]??[],g=n.getState(u);w(i,200,{candidates:m,active:g?.activeEnvFile??null});return}if(y==="env"&&l==="POST"){let p={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(g=>{let d=[];o.on("data",v=>d.push(v)),o.on("end",()=>{try{p=JSON.parse(Buffer.concat(d).toString("utf8"))}catch{}g()})}),n.setActiveEnvFile(u,p.use??null);let m=n.getState(u);w(i,200,{active:m?.activeEnvFile??null});return}if(y==="requests"&&l==="GET"){if(!e.requestLog){w(i,200,[]);return}let p=V(a.searchParams.get("since"));w(i,200,e.requestLog.requests(u,p));return}if(y==="clean"&&l==="POST"){let p=a.searchParams.get("deep")==="1",m=a.searchParams.get("yes")==="1",g=Jt(n,u,p);if(!g){w(i,404,{error:"unknown app"});return}if(g.ranOnServing){w(i,409,{error:"refusing: app is currently running",plan:g});return}if(!m){w(i,200,{plan:g,hint:"pass --yes to delete"});return}let d=Ke(n,u,p);w(i,200,d);return}if(y==="snapshot"&&l==="POST"){if(a.searchParams.get("write")==="1"){let g=Je(n,u);if(!g){w(i,404,{error:"unknown app"});return}w(i,200,{snapshot:g.path});return}let m=Gt(n,u);if(!m){w(i,404,{error:"unknown app"});return}w(i,200,m);return}if(y==="stop"&&l==="POST"){let p=await n.stop(u);w(i,p.ok?200:400,p);return}if(y==="restart"&&l==="POST"){let p=await n.restart(u);w(i,p.ok?200:400,p);return}w(i,404,{error:"not found"})}catch(a){w(i,500,{error:a?.message||String(a)})}});return s.listen(t,"127.0.0.1"),s}import Nn from"node:http";import $n from"node:https";var Ln=1e3,jn=500;function Mn(n,t,e,r,s){if(t)return[t];let o=n.path||"/",i=n.fallbackHosts&&n.fallbackHosts.length?n.fallbackHosts:["127.0.0.1"];if(n.host||n.scheme){let l=e?Yt(e):null,c=n.scheme||l?.protocol?.replace(":","")||"http",f=n.host||l?.hostname||(r?i[0]:"127.0.0.1"),u=r??(l?.port?Number(l.port):null);return[ir(c,f,u,o)]}if(e){let l=Yt(e);if(l)return l.pathname=o,[l.toString()]}let a=[];s&&a.push(s);for(let l of i)a.includes(l)||a.push(l);return a.map(l=>ir("http",l,r,o))}function Yt(n){try{return new URL(n)}catch{return null}}function ir(n,t,e,r){let s=t.includes(":")&&!t.startsWith("[")?`[${t}]`:t,o=e?`:${e}`:"";return`${n}://${s}${o}${r.startsWith("/")?r:"/"+r}`}var vt=class{constructor(t,e,r){this.registry=t;this.cfg=e;this.fullConfig=r;if(e.enabled){t.on("change",this.onChange);for(let s of t.names())this.evaluate(s)}}registry;cfg;fullConfig;timers=new Map;starting=new Map;freshness=new Map;stopped=!1;stop(){this.stopped=!0,this.registry.off("change",this.onChange);for(let t of this.timers.values())clearInterval(t);for(let t of this.starting.values())clearTimeout(t);this.timers.clear(),this.starting.clear()}onChange=()=>{if(!this.stopped)for(let t of this.registry.names())this.evaluate(t)};evaluate(t){let e=this.registry.getState(t);if(e)if(e.status==="serving"){if(this.timers.has(t)||this.starting.has(t))return;this.freshness.set(t,{retried:!1});let r=setTimeout(()=>{this.starting.delete(t),this.probe(t);let s=setInterval(()=>{this.probe(t)},this.cfg.intervalMs);this.timers.set(t,s)},jn);this.starting.set(t,r)}else{let r=this.timers.get(t);r&&(clearInterval(r),this.timers.delete(t));let s=this.starting.get(t);s&&(clearTimeout(s),this.starting.delete(t)),this.freshness.delete(t),e.health!=="unknown"&&(e.status==="stopped"||e.status==="error")&&this.registry.setHealth(t,"unknown")}}async probe(t){let e=this.registry.getState(t);if(!e||e.status!=="serving")return;let r=this.fullConfig?.overrides?.[t]?.url,s=Mn(this.cfg,r,e.announcedUrl,e.port,e.cachedProbeHost);if(s.length===0){this.registry.setLastHealthError(t,"no probe URL available"),this.registry.setHealth(t,"unhealthy");return}let o=null;for(let a of s){let l=await this.tryProbe(a);if(l.ok){let c=Yt(a);c&&this.registry.setCachedProbeHost(t,c.hostname.replace(/^\[|\]$/g,"")),this.registry.setResolvedUrl(t,a),this.registry.setLastHealthError(t,null),this.registry.setHealth(t,"healthy");return}o||(o=`${l.error} ${a}`)}let i=this.freshness.get(t);if(i&&!i.retried){i.retried=!0,setTimeout(()=>{this.probe(t)},Ln);return}this.registry.setLastHealthError(t,o||"unknown probe failure"),this.registry.setHealth(t,"unhealthy")}tryProbe(t){return new Promise(e=>{let r=!1,s=l=>{r||(r=!0,e(l))},o=t.startsWith("https://"),i=o?$n:Nn,a={timeout:this.cfg.timeoutMs};o&&(a.rejectUnauthorized=!!this.cfg.rejectUnauthorized);try{let l=i.get(t,a,c=>{let f=c.statusCode??0;c.resume(),f>=200&&f<500?s({ok:!0}):s({ok:!1,error:`http ${f}`})});l.on("timeout",()=>l.destroy(new Error("timeout"))),l.on("error",c=>s({ok:!1,error:c?.code||c?.message||"error"}))}catch(l){s({ok:!1,error:l?.message||"throw"})}})}};import _n from"pidusage";var wt=class{constructor(t,e=2e3){this.registry=t;this.intervalMs=e;this.timer=setInterval(()=>this.tick(),e)}registry;intervalMs;timer=null;stopped=!1;stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}async tick(){if(this.stopped)return;let t=[];for(let r of this.registry.names()){let s=this.registry.getState(r);s?.pid&&t.push({name:r,pid:s.pid})}if(!t.length)return;let e=!1;await Promise.all(t.map(async({name:r,pid:s})=>{try{let o=await _n(s),i=this.registry.getState(r);if(!i)return;let a=Math.round(o.cpu*10)/10,l=Math.round(o.memory/(1024*1024));(i.cpu!==a||i.memMB!==l)&&(i.cpu=a,i.memMB=l,e=!0)}catch{let o=this.registry.getState(r);o&&(o.cpu!=null||o.memMB!=null)&&(o.cpu=null,o.memMB=null,e=!0)}})),e&&this.registry.emit("change")}};var bt=class{constructor(t,e){this.registry=t;this.cfg=e}registry;cfg;timers=new Map;stopped=!1;stop(){this.stopped=!0;for(let t of this.timers.values())clearTimeout(t);this.timers.clear()}onExit(t,e,r,s){if(this.stopped||s||!this.cfg.enabled||e===0&&!r)return;let o=this.registry.getState(t);if(!o)return;let i=Date.now();if((o.restartWindowStart==null||i-o.restartWindowStart>this.cfg.windowMs)&&(o.restartWindowStart=i,o.restartAttempts=0),o.restartAttempts+=1,o.restartAttempts>this.cfg.maxAttempts){o.lastStatusMessage=`auto-restart aborted (${o.restartAttempts-1}/${this.cfg.maxAttempts} within window)`,o.nextRestartAt=null,this.registry.recordEvent({app:t,type:"restart-scheduled",message:o.lastStatusMessage}),this.registry.emit("change");return}let a=Math.min(2**(o.restartAttempts-1)*1e3,3e4);o.nextRestartAt=i+a,o.lastStatusMessage=`restarting in ${Math.round(a/1e3)}s (attempt ${o.restartAttempts}/${this.cfg.maxAttempts})`,this.registry.recordEvent({app:t,type:"restart-scheduled",message:o.lastStatusMessage}),this.registry.emit("change");let l=setTimeout(()=>{this.timers.delete(t);let c=this.registry.getState(t);c&&(c.nextRestartAt=null),this.registry.start(t)},a);this.timers.set(t,l)}onUserStop(t){let e=this.timers.get(t);e&&(clearTimeout(e),this.timers.delete(t));let r=this.registry.getState(t);r&&(r.restartAttempts=0,r.restartWindowStart=null,r.nextRestartAt=null)}};import Qt from"node:fs";import ar from"node:path";import Dn from"node:os";var Zt=ar.join(Dn.homedir(),".daimon","state.json");function cr(){try{let n=Qt.readFileSync(Zt,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.ports&&typeof t.ports=="object")return{ports:t.ports}}catch{}return{ports:{}}}var zt=null,Vt=null;function lr(n){Vt=n,!zt&&(zt=setTimeout(()=>{zt=null;let t=Vt;if(Vt=null,!!t)try{Qt.mkdirSync(ar.dirname(Zt),{recursive:!0}),Qt.writeFileSync(Zt,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: state write failed: ${e.message}
|
|
22
|
-
`)}},500))}import In from"node:fs";import Fn from"node:path";import{createRequire as Bn}from"node:module";var Hn=Bn(import.meta.url),Un=200,Wn=360*60*1e3,Gn=1e4,St=class{constructor(t){this.cfg=t;if(t.enabled)try{In.mkdirSync(Fn.dirname(t.path),{recursive:!0});let e=Hn("better-sqlite3");this.db=new e(t.path),this.db.pragma("journal_mode = WAL"),this.migrate(),this.flushTimer=setInterval(()=>this.flush(),Un),this.retentionStart=setTimeout(()=>this.runRetention(),Gn),this.retentionTimer=setInterval(()=>this.runRetention(),Wn)}catch(e){this.warnOnce(`failed to open history db: ${e?.message||e}`),this.db=null}}cfg;db=null;queue=[];flushTimer=null;retentionTimer=null;retentionStart=null;warned=!1;warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] history: ${t}
|
|
1
|
+
var qr=Object.defineProperty;var tt=(n,t)=>()=>(n&&(t=n(n=0)),t);var je=(n,t)=>{for(var e in t)qr(n,e,{get:t[e],enumerable:!0})};import K from"node:fs";import q from"node:path";import pt from"node:os";import{fileURLToPath as Xr}from"node:url";function Me(){return{searchRoots:[],portRange:[4200,4299],apiPort:4999,overrides:{},autoStart:[],profiles:{},tags:{},autoRestart:{enabled:!1,maxAttempts:5,windowMs:3e5},healthProbe:{enabled:!0,intervalMs:3e4,timeoutMs:2e3,path:"/",host:null,scheme:null,rejectUnauthorized:!1,fallbackHosts:["127.0.0.1","::1"]},logs:{enabled:!1,dir:q.join(pt.homedir(),".daimon","logs"),maxFiles:5,maxBytesPerFile:1e7},depends:{},cascadeRestart:!1,history:{enabled:!0,path:q.join(pt.homedir(),".daimon","history.db"),retentionDays:30},notifications:{enabled:!0,onError:!0,onUnhealthy:!0,tray:!1},staleDetect:{enabled:!0,silentMs:3e4},headless:!1,envFiles:{},requestLog:{enabled:!1,portOffset:1e3},metrics:{enabled:!1},editor:{scheme:"vscode"},apiToken:null,output:{format:"compact",ndjson:!1},doctor:{autoFix:{onInit:!1,permitted:["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db"]}},dashboard:{theme:"auto",density:"comfortable"}}}function Ne(n){return n.startsWith("~/")||n.startsWith("~\\")?q.join(pt.homedir(),n.slice(2)):n==="~"?pt.homedir():n}function Vt(n,t){return zt(n,t)}function zt(n,t){if(!n||typeof n!="object")throw new Error(`Config at ${t} is not a JSON object`);let e=n,r=Me();if(e.searchRoots!==void 0){if(!Array.isArray(e.searchRoots)||!e.searchRoots.every(s=>typeof s=="string"||s&&typeof s=="object"&&typeof s.path=="string"))throw new Error(`Config "searchRoots" must be an array of strings or { path, viteSubfolders? } objects (${t})`);r.searchRoots=e.searchRoots}if(e.portRange!==void 0){if(!Array.isArray(e.portRange)||e.portRange.length!==2||typeof e.portRange[0]!="number"||typeof e.portRange[1]!="number"||e.portRange[0]>e.portRange[1])throw new Error(`Config "portRange" must be [min, max] numbers (${t})`);r.portRange=[e.portRange[0],e.portRange[1]]}if(e.apiPort!==void 0){if(typeof e.apiPort!="number")throw new Error(`Config "apiPort" must be a number (${t})`);r.apiPort=e.apiPort}if(e.overrides!==void 0){if(typeof e.overrides!="object"||e.overrides===null||Array.isArray(e.overrides))throw new Error(`Config "overrides" must be an object (${t})`);r.overrides=e.overrides}if(e.autoStart!==void 0){if(!Array.isArray(e.autoStart)||!e.autoStart.every(s=>typeof s=="string"))throw new Error(`Config "autoStart" must be an array of strings (${t})`);r.autoStart=e.autoStart}if(e.profiles!==void 0){if(typeof e.profiles!="object"||e.profiles===null||Array.isArray(e.profiles))throw new Error(`Config "profiles" must be an object (${t})`);for(let[s,i]of Object.entries(e.profiles))if(!Array.isArray(i)||!i.every(o=>typeof o=="string"))throw new Error(`Config "profiles.${s}" must be an array of strings (${t})`);r.profiles=e.profiles}if(e.tags!==void 0){if(typeof e.tags!="object"||e.tags===null||Array.isArray(e.tags))throw new Error(`Config "tags" must be an object (${t})`);r.tags=e.tags}if(e.autoRestart&&typeof e.autoRestart=="object"&&(r.autoRestart={...r.autoRestart,...e.autoRestart}),e.healthProbe&&typeof e.healthProbe=="object"&&(r.healthProbe={...r.healthProbe,...e.healthProbe}),e.logs&&typeof e.logs=="object"&&(r.logs={...r.logs,...e.logs},r.logs.dir=Ne(r.logs.dir)),e.depends&&typeof e.depends=="object"&&!Array.isArray(e.depends)){for(let[s,i]of Object.entries(e.depends))if(!Array.isArray(i)||!i.every(o=>typeof o=="string"))throw new Error(`Config "depends.${s}" must be an array of strings (${t})`);r.depends=e.depends}if(typeof e.cascadeRestart=="boolean"&&(r.cascadeRestart=e.cascadeRestart),e.history&&typeof e.history=="object"&&(r.history={...r.history,...e.history},r.history.path=Ne(r.history.path)),e.notifications&&typeof e.notifications=="object"&&(r.notifications={...r.notifications,...e.notifications}),e.staleDetect&&typeof e.staleDetect=="object"&&(r.staleDetect={...r.staleDetect,...e.staleDetect}),typeof e.headless=="boolean"&&(r.headless=e.headless),e.envFiles&&typeof e.envFiles=="object"&&!Array.isArray(e.envFiles)&&(r.envFiles=e.envFiles),e.requestLog&&typeof e.requestLog=="object"&&(r.requestLog={...r.requestLog,...e.requestLog}),e.metrics&&typeof e.metrics=="object"&&(r.metrics={...r.metrics,...e.metrics}),e.editor&&typeof e.editor=="object"){let s=e.editor.scheme;typeof s=="string"&&s.trim()&&(r.editor={scheme:s.trim()})}if((typeof e.apiToken=="string"||e.apiToken===null)&&(r.apiToken=e.apiToken),e.output&&typeof e.output=="object"){let s=e.output;(s.format==="compact"||s.format==="full")&&(r.output.format=s.format),typeof s.ndjson=="boolean"&&(r.output.ndjson=s.ndjson)}if(e.doctor&&typeof e.doctor=="object"){let s=e.doctor.autoFix;s&&typeof s=="object"&&(typeof s.onInit=="boolean"&&(r.doctor.autoFix.onInit=s.onInit),Array.isArray(s.permitted)&&(r.doctor.autoFix.permitted=s.permitted.filter(i=>typeof i=="string")))}if(e.dashboard&&typeof e.dashboard=="object"){let s=e.dashboard;(s.theme==="auto"||s.theme==="light"||s.theme==="dark")&&(r.dashboard.theme=s.theme),(s.density==="comfortable"||s.density==="compact")&&(r.dashboard.density=s.density)}return r}function ft(){return{local:q.join(process.cwd(),"daimon.config.json"),user:q.join(pt.homedir(),".daimon","config.json")}}function et(){let{local:n,user:t}=ft();if(K.existsSync(n)){let s=JSON.parse(K.readFileSync(n,"utf8"));return{kind:"loaded",config:zt(s,n),path:n}}if(K.existsSync(t)){let s=JSON.parse(K.readFileSync(t,"utf8"));return{kind:"loaded",config:zt(s,t),path:t}}let r=[q.resolve($e,"..","daimon.config.example.json"),q.resolve($e,"..","..","daimon.config.example.json")].find(s=>K.existsSync(s));return K.mkdirSync(q.dirname(t),{recursive:!0}),r?K.copyFileSync(r,t):K.writeFileSync(t,JSON.stringify(Me(),null,2)+`
|
|
2
|
+
`,"utf8"),{kind:"stub-created",path:t}}var Kr,$e,kt=tt(()=>{"use strict";Kr=Xr(import.meta.url),$e=q.dirname(Kr)});var te={};je(te,{discoverApps:()=>mt});import dt from"node:fs";import U from"node:path";import Qt from"fast-glob";function _e(n){try{return JSON.parse(dt.readFileSync(n,"utf8"))}catch{return null}}function Le(n){return!n||typeof n!="object"?!1:!!(n.targets?.serve||n.architect?.serve)}function De(n){if(!n||typeof n!="object")return[];let t=n.targets??n.architect??{};return Object.keys(t).filter(e=>e!=="serve").sort()}function Zt(n){return n.replace(/\\/g,"/")}function rt(n,t){n&&(n.rejected[t]=(n.rejected[t]??0)+1)}function mt(n,t={}){let e=new Map,r=t.warnings??[],s=t.warnings===void 0;for(let i of n.searchRoots){let o=typeof i=="string"?i:i.path,a=typeof i=="string"?!1:!!i.viteSubfolders,u=typeof i=="string"?void 0:i.label,c=U.resolve(o);if(!dt.existsSync(c)){r.push(`searchRoot does not exist: ${c}`),rt(t.stats,"searchRoot missing");continue}let h=U.join(c,"nx.json"),p=U.join(c,"angular.json");if(dt.existsSync(h)){let m=Qt.sync("**/project.json",{cwd:Zt(c),ignore:["**/node_modules/**","**/dist/**","**/.nx/**","**/.git/**"],absolute:!0,dot:!1});for(let g of m){t.stats&&(t.stats.scanned+=1);let d=_e(g);if(!d){rt(t.stats,"unreadable project.json");continue}if(!Le(d)){rt(t.stats,"no serve target");continue}let y=d.name||U.basename(U.dirname(g));if(!y){rt(t.stats,"project has no name");continue}if(e.has(y)){r.push(`duplicate project name "${y}" \u2014 keeping first`),rt(t.stats,"duplicate name");continue}e.set(y,{name:y,workspaceRoot:c,workspaceType:"nx",command:`npx nx serve ${y}`,hidden:!1,tags:[],tasks:De(d),workspaceLabel:u})}continue}if(dt.existsSync(p)){let g=_e(p)?.projects||{};for(let[d,y]of Object.entries(g))if(Le(y)){if(e.has(d)){r.push(`duplicate project name "${d}" \u2014 keeping first`);continue}e.set(d,{name:d,workspaceRoot:c,workspaceType:"angular",command:`npx ng serve ${d}`,hidden:!1,tags:[],tasks:De(y),workspaceLabel:u})}continue}let b=Qt.sync("vite.config.{ts,js,mjs,cjs}",{cwd:Zt(c),absolute:!0,deep:1}),S=dt.existsSync(U.join(c,".storybook")),l=!1;if(b.length>0){let m=U.basename(c);if(e.has(m)||e.set(m,{name:m,workspaceRoot:c,workspaceType:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:u}),l=!0,a){let g=Qt.sync("*/vite.config.{ts,js,mjs,cjs}",{cwd:Zt(c),absolute:!0});for(let d of g){let y=U.dirname(d),k=U.basename(y);k===m||e.has(k)||e.set(k,{name:k,workspaceRoot:y,workspaceType:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:u})}}}if(S){let m=`${U.basename(c)}-storybook`;e.has(m)||e.set(m,{name:m,workspaceRoot:c,workspaceType:"storybook",command:"npx storybook dev --no-open",hidden:!1,tags:[],workspaceLabel:u}),l=!0}l||(r.push(`searchRoot has none of nx.json/angular.json/vite.config.*/.storybook: ${c}`),rt(t.stats,"no project markers"))}for(let[i,o]of Object.entries(n.overrides||{})){let a=e.get(i);a?(o.command&&(a.command=o.command),typeof o.hidden=="boolean"&&(a.hidden=o.hidden),typeof o.port=="number"&&(a.pinnedPort=o.port),o.env&&(a.env=o.env)):o.command&&e.set(i,{name:i,workspaceRoot:process.cwd(),workspaceType:"nx",command:o.command,hidden:o.hidden??!1,pinnedPort:o.port,env:o.env,tags:[]})}for(let i of e.values())i.tags=n.tags?.[i.name]??[];if(s&&r.length)for(let i of r)process.stderr.write(`[daimon] warning: ${i}
|
|
3
|
+
`);return[...e.values()].filter(i=>!i.hidden)}var ht=tt(()=>{"use strict"});import Tn from"node:fs";import se from"node:path";import{fileURLToPath as An}from"node:url";function Cn(){let n=[se.resolve(rr,"..","package.json"),se.resolve(rr,"..","..","package.json")];for(let t of n)try{return JSON.parse(Tn.readFileSync(t,"utf8"))}catch{}return{}}var rr,st,At=tt(()=>{"use strict";rr=se.dirname(An(import.meta.url));st=Cn().version||"0.0.0"});import ot from"node:fs";import Ct from"node:path";import Rn from"node:os";import{spawn as Pn}from"node:child_process";import{fileURLToPath as On}from"node:url";function Y(){return ie}function Rt(){return it}function oe(n){try{return process.kill(n,0),!0}catch(t){return t&&t.code==="EPERM"}}function gt(){try{let n=ot.readFileSync(it,"utf8"),t=JSON.parse(n);if(!t||typeof t.pid!="number")return null;if(!oe(t.pid)){try{ot.unlinkSync(it)}catch{}return null}return t}catch{return null}}function nr(n){ot.mkdirSync(ie,{recursive:!0});let t=it+"."+process.pid+".tmp";ot.writeFileSync(t,JSON.stringify(n)),ot.renameSync(t,it)}function yt(){try{ot.unlinkSync(it)}catch{}}function jn(){let n=Ct.dirname(On(import.meta.url));return Ct.join(n,"main.js")}async function ae(n={}){let t={...process.env};n.port&&(t.DAIMON_PORT=String(n.port)),Pn(process.execPath,[jn(),"--headless"],{detached:!0,stdio:"ignore",env:t,windowsHide:!0}).unref();let r=Date.now();for(;Date.now()-r<5e3;){let s=gt();if(s&&(!n.port||s.apiPort===n.port))return s;await new Promise(i=>setTimeout(i,100))}throw new Error("daemon failed to start within 5s")}async function sr(n,t){let e=Date.now();for(;Date.now()-e<t;){if(!oe(n))return!0;await new Promise(r=>setTimeout(r,100))}return!oe(n)}function or(n,t,e){return{pid:process.pid,apiPort:n,version:st,startedAt:Date.now(),headless:t,cwd:process.cwd(),configPath:e}}var ie,it,Q=tt(()=>{"use strict";At();ie=Ct.join(Rn.homedir(),".daimon"),it=Ct.join(ie,"daemon.lock")});import Qn from"node:fs";import Zn from"node:path";import{createRequire as ts}from"node:module";var es,rs,ns,ss,at,he=tt(()=>{"use strict";es=ts(import.meta.url),rs=200,ns=360*60*1e3,ss=1e4,at=class{constructor(t){this.cfg=t;if(t.enabled)try{Qn.mkdirSync(Zn.dirname(t.path),{recursive:!0});let e=es("better-sqlite3");this.db=new e(t.path),this.db.pragma("journal_mode = WAL"),this.migrate(),this.flushTimer=setInterval(()=>this.flush(),rs),this.retentionStart=setTimeout(()=>this.runRetention(),ss),this.retentionTimer=setInterval(()=>this.runRetention(),ns)}catch(e){this.warnOnce(`failed to open history db: ${e?.message||e}`),this.db=null}}cfg;db=null;queue=[];flushTimer=null;retentionTimer=null;retentionStart=null;warned=!1;warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] history: ${t}
|
|
23
4
|
`))}migrate(){this.db&&this.db.exec(`
|
|
24
5
|
CREATE TABLE IF NOT EXISTS events (
|
|
25
6
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -48,28 +29,52 @@ import Ts from"react";import{render as ks}from"ink";import{pathToFileURL as xs}f
|
|
|
48
29
|
summary TEXT
|
|
49
30
|
);
|
|
50
31
|
CREATE INDEX IF NOT EXISTS task_runs_app_ts ON task_runs(app, ts);
|
|
51
|
-
`)}recordEvent(t){this.db&&this.queue.push({kind:"event",row:{ts:t.ts,app:t.app,type:t.type,from_state:t.from??null,to_state:t.to??null,message:t.message??null}})}recordCompile(t,e,r=Date.now()){this.db&&this.queue.push({kind:"compile",row:{ts:r,app:t,ms:e}})}recordTaskRun(t,e,r,s,o
|
|
52
|
-
`;try{
|
|
53
|
-
`)
|
|
54
|
-
|
|
55
|
-
`)
|
|
56
|
-
`))
|
|
32
|
+
`)}recordEvent(t){this.db&&this.queue.push({kind:"event",row:{ts:t.ts,app:t.app,type:t.type,from_state:t.from??null,to_state:t.to??null,message:t.message??null}})}recordCompile(t,e,r=Date.now()){this.db&&this.queue.push({kind:"compile",row:{ts:r,app:t,ms:e}})}recordTaskRun(t,e,r,s,i,o=Date.now()){this.db&&this.queue.push({kind:"task",row:{ts:o,app:t,task:e,exit_code:r,duration_ms:s,summary:i==null?null:JSON.stringify(i)}})}flush(){if(!this.db||this.queue.length===0)return;let t=this.queue;this.queue=[];try{let e=this.db.prepare("INSERT INTO events (ts,app,type,from_state,to_state,message) VALUES (?,?,?,?,?,?)"),r=this.db.prepare("INSERT INTO compile_times (ts,app,ms) VALUES (?,?,?)"),s=this.db.prepare("INSERT INTO task_runs (ts,app,task,exit_code,duration_ms,summary) VALUES (?,?,?,?,?,?)");this.db.transaction(o=>{for(let a of o)a.kind==="event"?e.run(a.row.ts,a.row.app,a.row.type,a.row.from_state,a.row.to_state,a.row.message):a.kind==="compile"?r.run(a.row.ts,a.row.app,a.row.ms):s.run(a.row.ts,a.row.app,a.row.task,a.row.exit_code,a.row.duration_ms,a.row.summary)})(t)}catch(e){this.warnOnce(`history write failed: ${e?.message||e}`)}}runRetention(){if(this.db)try{let t=Date.now()-this.cfg.retentionDays*864e5;this.db.prepare("DELETE FROM events WHERE ts < ?").run(t),this.db.prepare("DELETE FROM compile_times WHERE ts < ?").run(t),this.db.prepare("DELETE FROM task_runs WHERE ts < ?").run(t)}catch(t){this.warnOnce(`retention failed: ${t?.message||t}`)}}queryEvents(t){if(!this.db)return[];let e=[],r=[];t.app&&(e.push("app = ?"),r.push(t.app)),t.since!=null&&(e.push("ts >= ?"),r.push(t.since)),t.until!=null&&(e.push("ts <= ?"),r.push(t.until)),t.type&&(e.push("type = ?"),r.push(t.type));let s=`SELECT * FROM events ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??500),this.db.prepare(s).all(...r)}queryCompiles(t){if(!this.db)return[];let e=[],r=[];t.app&&(e.push("app = ?"),r.push(t.app)),t.since!=null&&(e.push("ts >= ?"),r.push(t.since)),t.until!=null&&(e.push("ts <= ?"),r.push(t.until));let s=`SELECT * FROM compile_times ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??1e3),this.db.prepare(s).all(...r)}queryTasks(t){if(!this.db)return[];let e=[],r=[];t.app&&(e.push("app = ?"),r.push(t.app)),t.task&&(e.push("task = ?"),r.push(t.task)),t.since!=null&&(e.push("ts >= ?"),r.push(t.since));let s=`SELECT * FROM task_runs ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return r.push(t.limit??200),this.db.prepare(s).all(...r)}summary(t){if(!this.db)return{uptimePct24h:0,restartCount24h:0,compileP50:null,compileP95:null,topErrors:[]};let e=Date.now()-24*3600*1e3,r=this.queryEvents({app:t,since:e,limit:5e3}),s=0,i=e,o=!1,a=null,u=[...r].sort((d,y)=>d.ts-y.ts);for(let d of u)d.type==="status"&&(d.to_state==="serving"&&!o?(o=!0,a=d.ts):o&&d.to_state!=="serving"&&a!=null&&(s+=d.ts-a,o=!1,a=null));o&&a!=null&&(s+=Date.now()-a);let c=Math.round(s/(24*3600*1e3)*1e3)/10,h=r.filter(d=>d.type==="status"&&d.to_state==="starting"&&(d.from_state==="serving"||d.from_state==="error"||d.from_state==="compiling")).length,p=this.queryCompiles({app:t,since:e,limit:1e3}).map(d=>d.ms).sort((d,y)=>d-y),b=(d,y)=>{if(d.length===0)return null;let k=Math.min(d.length-1,Math.floor((d.length-1)*y));return d[k]},S=b(p,.5),l=b(p,.95),m=new Map;for(let d of r)if(d.type==="error-new"||d.type==="error-recur"){let y=d.message??"";if(!y)continue;m.set(y,(m.get(y)??0)+1)}let g=[...m.entries()].sort((d,y)=>y[1]-d[1]).slice(0,5).map(([d,y])=>({message:d,count:y}));return{uptimePct24h:c,restartCount24h:h,compileP50:S,compileP95:l,topErrors:g}}why(t){let e=this.queryEvents({app:t,limit:200}),r=e.find(a=>a.type==="status"&&(a.to_state==="error"||a.from_state==="error"||a.to_state==="serving")),s=r?{ts:r.ts,app:r.app,type:r.type,from:r.from_state??void 0,to:r.to_state??void 0,message:r.message??void 0}:null,i=s?s.ts:Date.now(),o=e.filter(a=>a.ts<i).slice(0,5);return{trigger:s,preceding:o.map(a=>({ts:a.ts,app:a.app,type:a.type,from:a.from_state??void 0,to:a.to_state??void 0,message:a.message??void 0}))}}quickCheck(){if(!this.db)return!1;try{return this.db.prepare("PRAGMA quick_check").get()?.quick_check==="ok"}catch{return!1}}close(){if(this.flushTimer&&clearInterval(this.flushTimer),this.retentionTimer&&clearInterval(this.retentionTimer),this.retentionStart&&clearTimeout(this.retentionStart),this.flush(),this.db){try{this.db.close()}catch{}this.db=null}}}});var Cr={};je(Cr,{ALL_AUTO_FIX:()=>Ar,runAutoFix:()=>ms});import B from"node:fs";import X from"node:path";function os(){let n=gt();if(!n)return{detected:!1,description:"no daemon running"};let t=process.cwd(),e=X.join(t,"daimon.config.json");if(!B.existsSync(e))return{detected:!1,description:"no local daimon.config.json in cwd"};let r=n.cwd,s=n.configPath,i=r&&X.resolve(r)===X.resolve(t),o=s&&X.resolve(s)===X.resolve(e);return i||o?{detected:!1,description:"daemon already running from this cwd/config"}:{detected:!0,description:`daemon (pid ${n.pid}) is running from ${r??"(unknown)"} but local daimon.config.json exists at ${t}`,lockCwd:r}}async function is(){let n=gt();if(!n)return"no daemon running; nothing to do";try{await fetch(`http://127.0.0.1:${n.apiPort}/api/snapshot-state`,{method:"POST"})}catch{}try{await fetch(`http://127.0.0.1:${n.apiPort}/api/shutdown`,{method:"POST"})}catch{}return await sr(n.pid,5e3),yt(),`respawned daemon at pid ${(await ae({})).pid} from ${process.cwd()}; previous pid ${n.pid} (cwd ${n.cwd??"unknown"}) was shut down with state handoff. To undo: stop with 'daimon daemon stop' and start from the prior directory.`}function as(){let n;try{n=B.readFileSync(Rt(),"utf8")}catch{return{detected:!1,description:"no lock file present"}}let t;try{t=JSON.parse(n)}catch{return{detected:!0,description:"lock file is malformed JSON"}}if(!t||typeof t.pid!="number")return{detected:!0,description:"lock file has no pid"};try{return process.kill(t.pid,0),{detected:!1,description:`lock file owner pid ${t.pid} is alive`}}catch(e){return e?.code==="EPERM"?{detected:!1,description:`lock file owner pid ${t.pid} alive (EPERM)`}:{detected:!0,description:`lock file claims pid ${t.pid} but the process is gone`}}}async function cs(){let n="(unknown)";try{let e=JSON.parse(B.readFileSync(Rt(),"utf8"));n=String(e?.pid??"?")}catch{}yt();let t=await ae({});return`removed stale ${Rt()} (prior pid ${n} was dead); spawned fresh daemon at pid ${t.pid}.`}function ls(){let n=process.cwd(),e=["nx.json","angular.json","vite.config.ts","vite.config.js","vite.config.mjs","vite.config.cjs",".storybook"].filter(o=>B.existsSync(X.join(n,o)));if(!e.length)return{detected:!1,description:"no nx.json/angular.json/vite.config.*/.storybook in cwd"};let r=et();return r.kind!=="loaded"?{detected:!0,description:`${e.join(", ")} present but no config is loaded`,markerFiles:e}:r.config.searchRoots.map(o=>X.resolve(typeof o=="string"?o:o.path)).some(o=>n.startsWith(o))?{detected:!1,description:`${e.join(", ")} present and a configured searchRoot covers ${n}`}:{detected:!0,description:`${e.join(", ")} present in ${n} but no searchRoot covers it`,markerFiles:e}}function us(){let n=process.cwd(),{local:t,user:e}=ft(),r=B.existsSync(t)?t:e,s={};try{s=JSON.parse(B.readFileSync(r,"utf8"))}catch{}if(s.searchRoots=Array.isArray(s.searchRoots)?s.searchRoots:[],!s.searchRoots.some(o=>(typeof o=="string"?o:o?.path)===n)){let o;try{let a=JSON.parse(B.readFileSync(X.join(n,"package.json"),"utf8"));typeof a.name=="string"&&(o=a.name)}catch{}s.searchRoots.push(o?{path:n,label:o}:n)}B.mkdirSync(X.dirname(r),{recursive:!0}),B.writeFileSync(r,JSON.stringify(s,null,2)+`
|
|
33
|
+
`,"utf8");let i=gt();if(i)try{fetch(`http://127.0.0.1:${i.apiPort}/api/config/reload`,{method:"POST"})}catch{}return`appended ${n} as a searchRoot in ${r}; triggered soft-reload of the running daemon.`}function ps(){let n=et();if(n.kind!=="loaded"||!n.config.history.enabled)return{detected:!1,description:"history disabled"};let t=n.config.history.path;if(!B.existsSync(t))return{detected:!1,description:"history db does not exist (will be created on next start)"};try{let e=new at(n.config.history),r=e.quickCheck();return e.close(),r?{detected:!1,description:"history db quick_check passed"}:{detected:!0,description:`quick_check failed on ${t}`,dbPath:t}}catch(e){return{detected:!0,description:`cannot open ${t}: ${e?.message??String(e)}`,dbPath:t}}}function fs(){let n=et();if(n.kind!=="loaded")return"no config; cannot determine history path";let t=n.config.history.path,e=`${t}.corrupt-${Date.now()}`;for(let r of["","-wal","-shm"])try{B.renameSync(t+r,e+r)}catch{}return`rotated ${t} \u2192 ${e} (and -wal/-shm siblings). The daemon will rebuild an empty history db on next start.`}async function ms(n){let t={ran:[],skipped:[],errors:[]};for(let e of Ar){if(!n.permitted.includes(e))continue;let r=ds[e],s;try{s=await r.detect()}catch(i){t.errors.push({name:e,error:i?.message??String(i)});continue}if(!s.detected){t.skipped.push({name:e,detected:!1,description:s.description});continue}if(n.dryRun){t.ran.push({name:e,detected:!0,description:`(dry-run) would fix: ${s.description}`});continue}try{let i=await r.fix();t.ran.push({name:e,detected:!0,description:`${s.description} \u2014 ${i}`})}catch(i){t.errors.push({name:e,error:i?.message??String(i)})}}return t}var Ar,ds,Rr=tt(()=>{"use strict";Q();kt();he();Ar=["orphan-daemon","stale-lock","missing-search-root","corrupt-history-db"];ds={"orphan-daemon":{detect:os,fix:is},"stale-lock":{detect:as,fix:cs},"missing-search-root":{detect:ls,fix:us},"corrupt-history-db":{detect:ps,fix:fs}}});kt();ht();import lo from"react";import{render as uo}from"ink";import{pathToFileURL as po}from"node:url";import{EventEmitter as Ln}from"node:events";import{spawn as yn}from"node:child_process";import Ie from"tree-kill";import vn from"strip-ansi";import Yr from"node:crypto";var zr=[/Local:\s+http/i,/Application bundle generation complete/i,/compiled successfully/i,/webpack compiled/i,/Angular Live Development Server is listening/i],Vr=[/Building\.\.\./i,/Compilation started/i,/Initial chunk files/i,/Compiling/i],Qr=[/^\s*ERROR\b/,/\berror TS\d+/,/✘/,/\[ERROR\]/,/Cannot find module/i],Zr=/\berror TS(\d+)/,tn=/✘\s*\[ERROR\]\s*TS(\d+)/,en=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte)):(\d+):(\d+)/,rn=/^\s+([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte)):(\d+):(\d+):?\s*$/,nn=/Local:\s+(https?:\/\/\S+)/i,sn=/Server running at\s+(https?:\/\/\S+)/i,on=/listening on\s+(https?:\/\/\S+)/i,an=/(?:listening|listen)\s+(https?:\/\/\S+)/i,cn=/Initial chunk files/i,ln=/Lazy chunk files/i,un=/(Initial total|Lazy total)\s*\|?\s*([\d.]+)\s*(kB|MB|B)\b/i,pn=/^\s*\|?\s*([^\s|][^|]*?)\s*\|\s*([^|]+?)\s*\|\s*([\d.]+)\s*(kB|MB|B)\b/i;function fn(n){return Yr.createHash("sha1").update(n).digest("hex").slice(0,16)}function dn(n){let t={message:n},e=n.match(tn)||n.match(Zr);e&&(t.code=`TS${e[1]}`);let r=n.match(en);return r&&(t.file=r[1],t.line=Number(r[2]),t.col=Number(r[3])),t}function mn(n,t){try{let e=new URL(n);return e.hostname==="0.0.0.0"||e.hostname==="[::]"?(e.hostname=t.includes(":")?`[${t}]`:t,e.toString().replace(/\/$/,"")):n.replace(/\/$/,"")}catch{return n}}function hn(n,t="127.0.0.1"){let e=n.match(nn)||n.match(sn)||n.match(on)||n.match(an);if(!e)return null;let r=e[1].replace(/[),.;]+$/,"");return mn(r,t)}function gn(n,t){if(cn.test(t))return n.bundle||(n.bundle={initialKB:0,lazyKB:0,files:[]}),n._bundleSection="initial",!1;if(ln.test(t))return n.bundle||(n.bundle={initialKB:0,lazyKB:0,files:[]}),n._bundleSection="lazy",!1;let e=t.match(un);if(e&&n.bundle){let s=parseFloat(e[2]),i=e[3].toUpperCase(),o=Math.round(i==="MB"?s*1024:i==="B"?s/1024:s);return/Initial/i.test(e[1])?n.bundle.initialKB=o:n.bundle.lazyKB=o,!0}let r=t.match(pn);if(r&&n.bundle){let s=r[1].trim();if(/^(Initial|Lazy)\s+(total|chunk)/i.test(s))return!1;let i=r[4].toUpperCase(),o=parseFloat(r[3]),a=i==="MB"?o*1024:i==="B"?o/1024:o;return n.bundle.files.push({name:s,sizeKB:Math.round(a*10)/10}),!1}return!1}function Fe(n,t){let e=t.match(rn);if(e&&n.lastErrorHash){let p=n.errors.get(n.lastErrorHash);p&&!p.parsed?.file&&(p.parsed={...p.parsed??{message:p.message},file:e[1],line:Number(e[2]),col:Number(e[3])})}let r=t.trim();if(!r)return null;let s=n.status,i=!1,o,a=hn(r);a&&!n.announcedUrl&&(n.announcedUrl=a,o=a);let u=gn(n,r),c;if(zr.some(p=>p.test(r))){let p=n.status==="error"||!!n.recoveringFromError;if(n.status==="compiling"||n.status==="starting"||n.status==="error"){let b=Date.now();n.compileStartedAt!=null?(c=b-n.compileStartedAt,n.lastCompileMs=c,n.lastCompileAt=b,n.compileStartedAt=null,n.compileHistory.push(c),n.compileHistory.length>20&&n.compileHistory.splice(0,n.compileHistory.length-20)):n.lastCompileAt=b}n.status="serving",p&&(n.errors.clear(),n.recoveringFromError=!1)}else Vr.some(p=>p.test(r))&&(n.status==="starting"||n.status==="serving"||n.status==="error")&&(n.status==="error"&&(n.recoveringFromError=!0),n.compileStartedAt=Date.now(),n.status="compiling");let h;if(Qr.some(p=>p.test(r))){let p=fn(r),b=Date.now(),S=n.errors.get(p),l=!1,m;S?(S.count+=1,S.lastSeen=b,m=S):(m={message:r,count:1,firstSeen:b,lastSeen:b,parsed:dn(r)},n.errors.set(p,m),l=!0),n.lastErrorHash=p,h={entry:m,isNew:l},n.status="error"}return i=n.status!==s,{statusChanged:i,error:h,announcedUrl:o,bundleUpdated:u,compileMs:c}}var Be=500,xt=class{child=null;stdoutBuf="";stderrBuf="";deps;stopping=!1;constructor(t){this.deps=t}isRunning(){return this.child!==null&&this.child.exitCode===null&&!this.stopping}start(){if(this.isRunning())return;let{app:t,port:e,state:r}=this.deps,s=Date.now();r.status="starting",r.startedAt=s,r.compileStartedAt=s,r.lastCompileMs=null,r.lastCompileAt=null,r.errors.clear(),r.logBuffer.length=0,r.lastStatusMessage=void 0;let o=`${this.deps.commandOverride||t.command} --port ${e}`,a={...process.env,...t.env||{},...this.deps.envOverride||{},PORT:String(e),FORCE_COLOR:"0"},u=yn(o,[],{cwd:t.workspaceRoot,shell:!0,env:a,windowsHide:!0});this.child=u,r.pid=u.pid??null,r.port=e,u.stdout?.on("data",c=>this.handleChunk(c,"stdout")),u.stderr?.on("data",c=>this.handleChunk(c,"stderr")),u.on("exit",(c,h)=>{let p=r.status,b=this.stopping;b?(r.status="stopped",r.lastStatusMessage=`stopped (code=${c??"null"}${h?`, ${h}`:""})`):c!==0?(r.status="error",r.lastStatusMessage=`process exited with code ${c}${h?` (${h})`:""}`):r.status="stopped",r.pid=null,r.health="unknown",this.child=null,this.stopping=!1,p!==r.status&&this.deps.onStatusChange?.(p,r.status,r.lastStatusMessage),this.deps.onExit?.(c,h,b),this.deps.onStateChange()}),u.on("error",c=>{r.status="error",r.lastStatusMessage=`spawn error: ${c.message}`,this.deps.onStateChange()}),this.deps.onStateChange()}handleChunk(t,e){let r=t.toString("utf8"),s=this[e==="stdout"?"stdoutBuf":"stderrBuf"]+=r,i=s.lastIndexOf(`
|
|
34
|
+
`);if(i<0)return;let o=s.slice(0,i),a=s.slice(i+1);e==="stdout"?this.stdoutBuf=a:this.stderrBuf=a;let{state:u}=this.deps,c=!1;for(let h of o.split(/\r?\n/)){if(!h.length)continue;let p=vn(h),b=Date.now();u.lastLogTs=b,u.stale&&(u.stale=!1),u.logBuffer.push({ts:b,line:p}),u.logBuffer.length>Be&&u.logBuffer.splice(0,u.logBuffer.length-Be),this.deps.onLogLine?.(p);let S=u.status,l=Fe(u,p);l?.statusChanged&&(c=!0,this.deps.onStatusChange?.(S,u.status)),l?.error&&this.deps.onErrorRecorded?.(l.error.entry,l.error.isNew),l?.compileMs!=null&&this.deps.onCompile?.(l.compileMs),l?.bundleUpdated&&this.deps.onBundleUpdate?.()}(c||o.length>0)&&this.deps.onStateChange()}async stop(){if(!this.child||this.stopping)return;this.stopping=!0;let t=this.child.pid;if(!t){this.child=null,this.stopping=!1;return}await new Promise(e=>{let r=!1,s=()=>{r||(r=!0,e())},i=()=>s();this.child?.once("exit",i),Ie(t,"SIGTERM",()=>{});let o=setTimeout(()=>{Ie(t,"SIGKILL",()=>{})},2e3),a=setTimeout(()=>{clearTimeout(o),s()},3e3);this.child?.once("exit",()=>{clearTimeout(o),clearTimeout(a),s()})})}};import wn from"node:net";var nt=class{assigned=new Map;min;max;onChange;constructor(t,e={}){if(this.min=t[0],this.max=t[1],this.onChange=e.onChange,e.initial){let r=new Set;for(let[s,i]of Object.entries(e.initial))typeof i=="number"&&(i<this.min||i>this.max||r.has(i)||(r.add(i),this.assigned.set(s,i)))}}snapshot(){return Object.fromEntries(this.assigned)}getAssigned(t){return this.assigned.get(t)}pin(t,e){this.assigned.set(t,e),this.onChange?.(this.snapshot())}async allocate(t,e){let r=this.assigned.get(t);if(e!==void 0)return this.assigned.set(t,e),this.onChange?.(this.snapshot()),e;if(r!==void 0)return r;let s=new Set(this.assigned.values());for(let i=this.min;i<=this.max;i++){if(s.has(i))continue;if(await Et(i))return this.assigned.set(t,i),this.onChange?.(this.snapshot()),i}throw new Error(`No free ports in range ${this.min}-${this.max}`)}async isPortAvailableForUse(t){return Et(t)}};function Et(n){return new Promise(t=>{let e=wn.createServer();e.unref(),e.once("error",()=>t(!1)),e.listen({port:n,host:"127.0.0.1",exclusive:!0},()=>{e.close(()=>t(!0))})})}import W from"node:fs";import bn from"node:path";var Tt=class{constructor(t,e){this.appName=t;this.cfg=e;this.filePath=bn.join(e.dir,`${t}.log`),this.open()}appName;cfg;fd=null;bytes=0;warned=!1;filePath;open(){try{W.mkdirSync(this.cfg.dir,{recursive:!0});try{this.bytes=W.statSync(this.filePath).size}catch{this.bytes=0}this.fd=W.openSync(this.filePath,"a")}catch(t){this.warn(`open failed: ${t.message}`),this.fd=null}}write(t){if(this.fd!=null)try{let e=`${new Date().toISOString()} ${t}
|
|
35
|
+
`,r=Buffer.from(e,"utf8");W.writeSync(this.fd,r),this.bytes+=r.length,this.bytes>=this.cfg.maxBytesPerFile&&this.rotate()}catch(e){this.warn(`write failed: ${e.message}`)}}close(){if(this.fd!=null){try{W.closeSync(this.fd)}catch{}this.fd=null}}rotate(){try{this.close();for(let t=this.cfg.maxFiles-1;t>=1;t--){let e=`${this.filePath}.${t}`,r=`${this.filePath}.${t+1}`;if(t+1>this.cfg.maxFiles-1){try{W.rmSync(e,{force:!0})}catch{}continue}try{W.existsSync(e)&&W.renameSync(e,r)}catch{}}try{let t=`${this.filePath}.1`;W.existsSync(this.filePath)&&W.renameSync(this.filePath,t)}catch{}this.open()}catch(t){this.warn(`rotate failed: ${t.message}`)}}warn(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] warning: diskLogger(${this.appName}) ${t}
|
|
36
|
+
`))}};function He(n){let s=new Map,i=new Map,o=null,a=u=>{if(!o){s.set(u,1);for(let c of n[u]||[]){let h=s.get(c)??0;if(h===1){let p=[c,u],b=i.get(u);for(;b&&b!==c;)p.push(b),b=i.get(b);b===c&&p.push(c),o=p.reverse();return}if(h===0&&(i.set(c,u),a(c),o))return}s.set(u,2)}};for(let u of Object.keys(n))if((s.get(u)??0)===0&&(i.set(u,null),a(u),o))return o;return null}function Ue(n,t){let e=new Set,r=[t];for(;r.length;){let s=r.pop();if(!e.has(s)){e.add(s);for(let i of n[s]||[])r.push(i)}}return[...e]}function We(n,t){let e=new Set(t),r=new Map,s=new Map;for(let a of t)r.set(a,0),s.set(a,[]);for(let a of t)for(let u of n[a]||[])e.has(u)&&(s.get(u).push(a),r.set(a,(r.get(a)??0)+1));let i=[],o=t.filter(a=>(r.get(a)??0)===0);for(;o.length;){i.push([...o].sort());let a=[];for(let u of o)for(let c of s.get(u)??[])r.set(c,(r.get(c)??1)-1),r.get(c)===0&&a.push(c);o=a}return i}function Je(n,t){let e=[];for(let[r,s]of Object.entries(n))s.includes(t)&&e.push(r);return e}import{spawn as qe}from"node:child_process";import Ge from"tree-kill";import Xe from"strip-ansi";var Sn=/Tests:\s+(?:(\d+)\s+failed,\s+)?(\d+)\s+passed(?:,\s+(\d+)\s+total)?/,kn=/Executed (\d+) of (\d+)(?:\s*\((\d+)\s*FAILED\))?/,xn=/(\d+)\s+passed(?:.*?(\d+)\s+failed)?/i;function En(n){let t=n.match(Sn);if(t){let s=t[1]?Number(t[1]):0,i=Number(t[2]),o=t[3]?Number(t[3]):i+s;return{passed:i,failed:s,total:o}}let e=n.match(kn);if(e){let s=Number(e[1]),i=Number(e[2]),o=e[3]?Number(e[3]):0;return{passed:s-o,failed:o,total:i}}let r=n.match(xn);if(r){let s=Number(r[1]),i=r[2]?Number(r[2]):0;return{passed:s,failed:i,total:s+i}}return null}function Ke(n,t,e){let r=e.length?" -- "+e.join(" "):"";return n.workspaceType==="nx"?`npx nx run ${n.name}:${t}${r}`:n.workspaceType==="angular"?`npx ng run ${n.name}:${t}${r}`:`npx ${t}${r}`}function Ye(n,t,e=[]){return new Promise(r=>{let s=Date.now(),i=Ke(n,t,e),o=qe(i,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),a=[],u="",c=h=>{u+=h.toString("utf8");let p=u.lastIndexOf(`
|
|
37
|
+
`);if(p<0)return;let b=u.slice(0,p);u=u.slice(p+1);for(let S of b.split(/\r?\n/)){if(!S.length)continue;let l=Xe(S);a.push(l),a.length>1e3&&a.splice(0,a.length-1e3)}};o.stdout?.on("data",c),o.stderr?.on("data",c),o.on("exit",h=>{let p=Date.now()-s,b=a.join(`
|
|
38
|
+
`)+(u?`
|
|
39
|
+
`+u:""),S=En(b);r({app:n.name,task:t,exitCode:h,durationMs:p,summary:S,outputTail:a.slice(-50)})}),o.on("error",()=>{r({app:n.name,task:t,exitCode:-1,durationMs:Date.now()-s,summary:null,outputTail:[...a,"[daimon] task spawn error"]})})})}function ze(n,t,e=[]){let r=Ke(n,t,e),s=qe(r,[],{cwd:n.workspaceRoot,shell:!0,env:{...process.env,...n.env||{},FORCE_COLOR:"0"},windowsHide:!0}),i=[],o="",a=c=>{o+=c.toString("utf8");let h=o.lastIndexOf(`
|
|
40
|
+
`);if(h<0)return;let p=o.slice(0,h);o=o.slice(h+1);for(let b of p.split(/\r?\n/))b.length&&(i.push(Xe(b)),i.length>500&&i.splice(0,i.length-500))};return s.stdout?.on("data",a),s.stderr?.on("data",a),{app:n.name,task:t,pid:s.pid??null,child:s,startedAt:Date.now(),logs:i,stop:()=>new Promise(c=>{if(!s.pid){c();return}let h=!1,p=()=>{h||(h=!0,c())};s.once("exit",p),Ge(s.pid,"SIGTERM",()=>{}),setTimeout(()=>{s.pid&&Ge(s.pid,"SIGKILL",()=>{})},2e3),setTimeout(p,3500)})}}import{spawnSync as ee}from"node:child_process";import Go from"tree-kill";function Ve(n){if(process.platform==="win32"){let i=ee("powershell",["-NoProfile","-Command",`Get-NetTCPConnection -LocalPort ${n} -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty OwningProcess`],{encoding:"utf8",windowsHide:!0});if(i.status!==0)return null;let o=Number((i.stdout||"").trim().split(/\s+/)[0]);if(!Number.isFinite(o)||o<=0)return null;let a=ee("powershell",["-NoProfile","-Command",`Get-CimInstance Win32_Process -Filter "ProcessId=${o}" | Select-Object -Property Name,CommandLine | ConvertTo-Json -Compress`],{encoding:"utf8",windowsHide:!0}),u,c;try{let h=JSON.parse((a.stdout||"").trim()||"{}");u=typeof h.Name=="string"?h.Name:void 0,c=typeof h.CommandLine=="string"?h.CommandLine:void 0}catch{}return{pid:o,name:u,cmd:c}}let t=ee("lsof",["-nP","-iTCP:"+n,"-sTCP:LISTEN"],{encoding:"utf8"});if(t.status!==0)return null;let e=(t.stdout||"").split(/\r?\n/).filter(i=>i.trim()&&!i.startsWith("COMMAND"));if(!e.length)return null;let r=e[0].split(/\s+/);return{pid:Number(r[1]),name:r[0]}}function Qe(n,t){if(!t)return`port ${n} already in use`;let e=[`port ${n} in use by`];return t.name&&e.push(t.name),e.push(`(pid ${t.pid}`),t.cmd&&(e[e.length-1]+=`, cmd: ${t.cmd.slice(0,120)}`),e[e.length-1]+=")",e.join(" ")}import tr from"node:fs";import Ze from"node:path";function er(n){let t={},e;try{e=tr.readFileSync(n,"utf8")}catch{return t}for(let r of e.split(/\r?\n/)){let s=r.trim();if(!s||s.startsWith("#"))continue;let i=s.indexOf("=");if(i<0)continue;let o=s.slice(0,i).trim(),a=s.slice(i+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),o&&(t[o]=a)}return t}function re(n,t){return Ze.isAbsolute(t)?t:Ze.join(n,t)}function ne(n,t){return t.filter(e=>tr.existsSync(re(n,e)))}Q();import $n from"node:fs";import Nn from"node:path";function Mn(){return Nn.join(Y(),"secrets.json")}function ir(){try{let n=$n.readFileSync(Mn(),"utf8");n.charCodeAt(0)===65279&&(n=n.slice(1));let t=JSON.parse(n);if(!t||typeof t!="object")return{};let e={};for(let[r,s]of Object.entries(t))typeof s=="string"&&(e[r]=s);return e}catch{return{}}}function ar(n,t){let e={};for(let[r,s]of Object.entries(n))e[r]=s.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,(i,o)=>t[o]??`\${${o}}`);return e}import ce from"node:fs";import _n from"node:os";import cr from"node:path";var Pt=class{file=null;startTs=0;isRecording(){return this.file!=null}start(){if(this.file)return{path:this.file};let t=cr.join(_n.homedir(),".daimon","sessions");ce.mkdirSync(t,{recursive:!0});let e=cr.join(t,`${new Date().toISOString().replace(/[:.]/g,"-")}.jsonl`);return ce.writeFileSync(e,""),this.file=e,this.startTs=Date.now(),{path:e}}stop(){let t={path:this.file};return this.file=null,this.startTs=0,t}append(t){if(!this.file)return;let e=JSON.stringify({ts:Date.now()-this.startTs,...t})+`
|
|
41
|
+
`;try{ce.appendFileSync(this.file,e)}catch{}}};var lr=500,Ot=class extends Ln{entries=new Map;portAlloc;config;eventBuffer=[];history=null;watchTasks=new Map;sessionRecorder=new Pt;constructor(t,e,r){super(),this.config=t,this.portAlloc=r??new nt(t.portRange);for(let s of e)this.entries.set(s.name,{app:s,state:this.freshState(s.name,s.tags,s.workspaceLabel??null),proc:null})}getConfig(){return this.config}addDiscoveredApp(t){this.entries.has(t.name)||(this.entries.set(t.name,{app:t,state:this.freshState(t.name,t.tags,t.workspaceLabel??null),proc:null}),this.emit("change"))}updateDiscoveredApp(t){let e=this.entries.get(t.name);e&&(e.app=t,e.state.tags=t.tags,e.state.workspaceLabel=t.workspaceLabel??null,e.state.dependsOn=this.config.depends?.[t.name]??[],this.emit("change"))}getPortAllocator(){return this.portAlloc}setHistory(t){this.history=t}getHistory(){return this.history}freshState(t,e,r=null){return{name:t,status:"stopped",port:null,pid:null,startedAt:null,compileStartedAt:null,lastCompileMs:null,lastCompileAt:null,logBuffer:[],errors:new Map,compileHistory:[],health:"unknown",lastHealthAt:null,cpu:null,memMB:null,restartAttempts:0,restartWindowStart:null,nextRestartAt:null,tags:e,announcedUrl:null,lastHealthError:null,cachedProbeHost:null,lastLogTs:null,stale:!1,bundle:null,bundleRegressionPct:null,activeEnvFile:null,sessionOverrides:null,dependsOn:this.config.depends?.[t]??[],workspaceLabel:r}}names(){return[...this.entries.keys()]}list(){return this.names().map(t=>this.summary(t))}summary(t){let e=this.entries.get(t);if(!e)return null;let r=e.state,s=r.startedAt&&(r.status==="serving"||r.status==="compiling"||r.status==="starting")?Date.now()-r.startedAt:null,o=this.config.overrides?.[t]?.url||e.resolvedUrl||r.announcedUrl||(r.port?`http://127.0.0.1:${r.port}`:null),a;for(let u=this.eventBuffer.length-1;u>=0;u--){let c=this.eventBuffer[u];if(c.app===t&&c.type==="status"){a=Date.now()-c.ts;break}}return{name:r.name,status:r.status,port:r.port,url:o,errorCount:[...r.errors.values()].reduce((u,c)=>u+c.count,0),uptimeMs:s,lastCompileMs:r.lastCompileMs,health:r.health,lastHealthAt:r.lastHealthAt,cpu:r.cpu,memMB:r.memMB,compileHistoryMs:[...r.compileHistory],tags:[...r.tags],restartAttempts:r.restartAttempts,nextRestartAt:r.nextRestartAt,announcedUrl:r.announcedUrl,lastHealthError:r.lastHealthError,stale:r.stale,bundle:r.bundle,bundleRegressionPct:r.bundleRegressionPct,dependsOn:[...r.dependsOn],activeEnvFile:r.activeEnvFile,workspaceLabel:r.workspaceLabel,lastChangeMs:a}}getState(t){return this.entries.get(t)?.state??null}getApp(t){return this.entries.get(t)?.app??null}errors(t){let e=this.getState(t);return e?[...e.errors.values()].sort((r,s)=>s.lastSeen-r.lastSeen):null}errorsSince(t,e){let r=this.getState(t);return r?[...r.errors.values()].filter(s=>s.lastSeen>e).sort((s,i)=>i.lastSeen-s.lastSeen):null}logs(t,e={}){let r=this.getState(t);if(!r)return null;let s=r.logBuffer;if(e.sinceMs&&e.sinceMs>0){let i=Date.now()-e.sinceMs;s=s.filter(o=>o.ts>=i)}return e.tail&&e.tail>0&&(s=s.slice(-e.tail)),s.map(i=>i.line)}events(t={}){let e=t.sinceMs&&t.sinceMs>0?Date.now()-t.sinceMs:0;return this.eventBuffer.filter(r=>r.ts>=e&&(!t.app||r.app===t.app))}recordEvent(t){let e={ts:t.ts??Date.now(),...t};this.eventBuffer.push(e),this.emit("event",e),this.eventBuffer.length>lr&&this.eventBuffer.splice(0,this.eventBuffer.length-lr),this.history?.recordEvent(e),this.emit("event",e)}setHealth(t,e){let r=this.entries.get(t);if(!r)return;let s=r.state;if(s.lastHealthAt=Date.now(),s.health===e)return;let i=s.health;s.health=e,e==="healthy"&&(r.prevHealthyAt=Date.now(),r.cascadeArmed&&(r.cascadeArmed=!1,this.triggerCascadeRestart(t))),this.recordEvent({app:t,type:"health",from:i,to:e}),this.emit("change")}armCascade(t){let e=this.entries.get(t);e&&this.config.cascadeRestart&&e.prevHealthyAt!=null&&(e.cascadeArmed=!0)}setLastHealthError(t,e){let r=this.getState(t);r&&r.lastHealthError!==e&&(r.lastHealthError=e,this.emit("change"))}setResolvedUrl(t,e){let r=this.entries.get(t);r&&r.resolvedUrl!==e&&(r.resolvedUrl=e,this.emit("change"))}setCachedProbeHost(t,e){let r=this.getState(t);r&&(r.cachedProbeHost=e)}setStale(t,e){let r=this.getState(t);r&&r.stale!==e&&(r.stale=e,this.emit("change"))}setSessionOverride(t,e){let r=this.getState(t);r&&(r.sessionOverrides=e,this.emit("change"))}setActiveEnvFile(t,e){let r=this.getState(t);r&&(r.activeEnvFile=e,this.emit("change"))}async start(t){this.sessionRecorder.append({kind:"start",app:t});let e=this.entries.get(t);if(!e)return{ok:!1,status:"unknown",error:"unknown app"};if(e.proc?.isRunning())return{ok:!0,status:e.state.status};let r=e.state.status,s;try{s=await this.portAlloc.allocate(t,e.app.pinnedPort)}catch(S){return e.state.status="error",e.state.lastStatusMessage=S.message,this.recordEvent({app:t,type:"status",from:r,to:"error",message:S.message}),this.emit("change"),{ok:!1,status:"error",error:S.message}}if(!await Et(s)){let S=Ve(s),l=Qe(s,S);return e.state.status="error",e.state.port=s,e.state.lastStatusMessage=l,this.recordEvent({app:t,type:"status",from:r,to:"error",message:l}),this.emit("change"),{ok:!1,status:"error",error:l}}e.state.health="unknown",e.state.lastHealthAt=null,e.state.announcedUrl=null,e.state.lastHealthError=null,e.state.cachedProbeHost=null,e.state.stale=!1,e.state.lastLogTs=null,e.resolvedUrl=void 0,!e.logger&&this.config.logs.enabled&&(e.logger=new Tt(t,this.config.logs));let o=e.state.sessionOverrides,a=this.config.envFiles?.[t]??[],u={};if(a.length){let S=e.state.activeEnvFile;(!S||!ne(e.app.workspaceRoot,[S]).length)&&(S=ne(e.app.workspaceRoot,a)[0]??null,S&&(e.state.activeEnvFile=S)),S&&(u=er(re(e.app.workspaceRoot,S)))}let c={...u,...this.config.overrides?.[t]?.env??{},...o?.env??{}},h=ir(),p=ar(c,h),b=new xt({state:e.state,app:e.app,port:s,envOverride:Object.keys(p).length?p:void 0,commandOverride:o?.command,onStateChange:()=>this.emit("change"),onStatusChange:(S,l,m)=>{this.recordEvent({app:t,type:"status",from:S,to:l,message:m}),(l==="stopped"||l==="error")&&(S==="serving"||S==="compiling")&&this.armCascade(t)},onErrorRecorded:(S,l)=>this.recordEvent({app:t,type:l?"error-new":"error-recur",message:S.message}),onExit:(S,l,m)=>this.emit("childExit",{name:t,code:S,signal:l,stopping:m}),onLogLine:S=>{e.logger?.write(S),this.emit("log",{name:t,ts:Date.now(),line:S})},onCompile:S=>{this.history?.recordCompile(t,S);let l=this.getState(t),m=e.lastBundleInitialKB;if(l.bundle&&l.bundle.initialKB>0){if(m&&m>0){let g=(l.bundle.initialKB-m)/m*100;l.bundleRegressionPct=Math.round(g*10)/10,g>10&&this.recordEvent({app:t,type:"bundle-regression",message:`initialKB +${l.bundleRegressionPct}% (${m}->${l.bundle.initialKB})`})}else l.bundleRegressionPct=null;e.lastBundleInitialKB=l.bundle.initialKB}this.checkCompileRegression(t,S),this.emit("compile",{name:t,ms:S})},onBundleUpdate:()=>this.emit("bundleUpdate",{name:t})});return e.proc=b,this.recordEvent({app:t,type:"status",from:r,to:"starting"}),b.start(),{ok:!0,status:e.state.status}}async stop(t){this.sessionRecorder.append({kind:"stop",app:t});let e=this.entries.get(t);if(!e)return{ok:!1,status:"unknown",error:"unknown app"};if(this.emit("userStop",{name:t}),!e.proc||!e.proc.isRunning())return e.state.status!=="stopped"&&this.recordEvent({app:t,type:"status",from:e.state.status,to:"stopped"}),e.state.status="stopped",e.state.pid=null,e.state.health="unknown",this.emit("change"),{ok:!0,status:"stopped"};let r=e.state.status;return await e.proc.stop(),e.proc=null,e.state.status!==r&&this.recordEvent({app:t,type:"status",from:r,to:e.state.status}),{ok:!0,status:e.state.status}}async restart(t){return this.sessionRecorder.append({kind:"restart",app:t}),await this.stop(t),this.start(t)}async startWithDeps(t,e={}){if(!this.entries.has(t))return{ok:!1,results:[{name:t,status:"unknown",health:"unknown",error:"unknown app"}]};let r=Ue(this.config.depends??{},t).filter(a=>this.entries.has(a)),s=We(this.config.depends??{},r),i=[],o=e.waitMs??6e4;for(let a of s){let u=await Promise.all(a.map(h=>this.start(h)));for(let h=0;h<a.length;h++){let p=u[h];if(!p.ok)return i.push({name:a[h],status:p.status,health:"unknown",error:p.error}),{ok:!1,results:i}}let c=await Promise.all(a.map(h=>this.waitFor(h,"healthy",o)));for(let h=0;h<a.length;h++){let p=c[h],b=!p.timedOut&&p.status==="serving"&&p.health==="healthy";if(i.push({name:p.name,status:p.status,health:p.health,error:b?void 0:p.timedOut?"timeout waiting for healthy":"did not reach healthy"}),!b)return{ok:!1,results:i}}}return{ok:!0,results:i}}triggerCascadeRestart(t){if(!this.config.cascadeRestart)return;let e=Je(this.config.depends??{},t);for(let r of e){let s=this.getState(r);s&&(s.status==="serving"||s.status==="compiling"||s.status==="starting")&&this.restart(r)}}async stopAll(t=3e3){let e=[];for(let r of this.entries.values())r.proc?.isRunning()&&e.push(r.proc.stop());for(let r of this.watchTasks.values())e.push(r.stop());await Promise.race([Promise.all(e),new Promise(r=>setTimeout(r,t))]);for(let r of this.entries.values())r.logger?.close()}listTasks(t){let e=this.getApp(t);return e?[...e.tasks??[]]:null}async runTask(t,e,r=[]){this.sessionRecorder.append({kind:"run",app:t,task:e,args:r});let s=this.getApp(t);if(!s)return{error:"unknown app"};let i=await Ye(s,e,r);return this.history?.recordTaskRun(t,e,i.exitCode,i.durationMs,i.summary),this.recordEvent({app:t,type:"task-run",message:`${e} exit=${i.exitCode} duration=${i.durationMs}ms`}),this.emit("taskRun",{name:t,task:e,result:i}),i}startWatchTask(t,e,r=[]){let s=this.getApp(t);if(!s)return{ok:!1,error:"unknown app"};let i=`${t}::${e}`;if(this.watchTasks.has(i))return{ok:!0,pid:this.watchTasks.get(i).pid};let o=ze(s,e,r);return this.watchTasks.set(i,o),o.child.on("exit",()=>this.watchTasks.delete(i)),{ok:!0,pid:o.pid}}async stopWatchTask(t,e){let r=`${t}::${e}`,s=this.watchTasks.get(r);return s?(await s.stop(),this.watchTasks.delete(r),{ok:!0}):{ok:!0}}listWatchTasks(t){let e=[];for(let r of this.watchTasks.values())t&&r.app!==t||e.push({app:r.app,task:r.task,pid:r.pid,startedAt:r.startedAt});return e}checkCompileRegression(t,e){let r=this.history;if(!r)return;let i=r.queryCompiles({app:t,limit:31}).filter(u=>u.ms!==e).slice(0,30).map(u=>u.ms);if(i.length<10)return;let o=[...i].sort((u,c)=>u-c),a=o[Math.floor((o.length-1)*.5)];e>2*a&&this.recordEvent({app:t,type:"compile-regression",message:`${(e/1e3).toFixed(1)}s vs p50 ${(a/1e3).toFixed(1)}s`})}watchTaskLogs(t,e,r){let s=this.watchTasks.get(`${t}::${e}`);if(!s)return null;let i=s.logs;return r?i.slice(-r):[...i]}waitFor(t,e,r){return new Promise(s=>{let i=Date.now(),o=this.entries.get(t),a=()=>{if(!o)return!0;let p=o.state;return e==="serving"&&p.status==="serving"||e==="healthy"&&p.status==="serving"&&p.health==="healthy"||e==="stopped"&&p.status==="stopped"||e==="error"&&p.status==="error"},u=p=>{this.off("change",c),clearTimeout(h);let b=o?.state;s({name:t,status:b?.status??"unknown",health:b?.health??"unknown",timedOut:p,waitedMs:Date.now()-i})},c=()=>{a()&&u(!1)};if(a()){s({name:t,status:o.state.status,health:o.state.health,timedOut:!1,waitedMs:0});return}let h=setTimeout(()=>u(!0),r);this.on("change",c)})}};import hs from"node:http";import gs from"node:crypto";import It from"node:fs";import F from"node:path";import{fileURLToPath as ys}from"node:url";import pe from"node:fs";import ur from"node:path";import Dn from"node:os";var fe=ur.join(Dn.homedir(),".daimon","cursors.json");function Fn(){try{let n=pe.readFileSync(fe,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.errors&&typeof t.errors=="object")return{errors:t.errors}}catch{}return{errors:{}}}var le=null,ue=null;function In(n){ue=n,!le&&(le=setTimeout(()=>{le=null;let t=ue;if(ue=null,!!t)try{pe.mkdirSync(ur.dirname(fe),{recursive:!0}),pe.writeFileSync(fe,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: cursor write failed: ${e.message}
|
|
42
|
+
`)}},500))}var jt=class{data=Fn();getErrorCursor(t,e){return this.data.errors[`${t}:${e}`]??0}setErrorCursor(t,e,r){this.data.errors[`${t}:${e}`]=r,In(this.data)}};import pr from"node:fs";import Bn from"node:os";import fr from"node:path";var Hn=/key|secret|token|password|api[-_]?key/i;function Un(n){let t={};for(let[e,r]of Object.entries(n))typeof r=="string"&&(t[e]=Hn.test(e)?"***":r);return t}function de(n,t){let e=n.summary(t);if(!e)return null;let r=n.getState(t),s=n.getApp(t),i=n.getConfig(),o=i.overrides?.[t]??{},a={...process.env,...s.env??{},...r.sessionOverrides?.env??{}},u=n.getHistory(),c=u?u.queryEvents({app:t,limit:50}):[];return{takenAt:new Date().toISOString(),summary:e,logs:r.logBuffer.slice(-500).map(h=>({ts:h.ts,line:h.line})),errors:[...r.errors.entries()].map(([h,p])=>({hash:h,message:p.message,count:p.count,firstSeen:p.firstSeen,lastSeen:p.lastSeen})),env:Un(a),configSlice:{command:r.sessionOverrides?.command??o.command??s.command,port:r.sessionOverrides?.port??o.port??null,workspaceRoot:s.workspaceRoot,workspaceType:s.workspaceType,tags:s.tags,depends:i.depends?.[t]??[],envFiles:i.envFiles?.[t]??[]},events:c}}function dr(n,t){let e=de(n,t);if(!e)return null;let r=fr.join(Bn.homedir(),".daimon","snapshots");pr.mkdirSync(r,{recursive:!0});let s=e.takenAt.replace(/[:.]/g,"-"),i=fr.join(r,`${t}-${s}.json`);return pr.writeFileSync(i,JSON.stringify(e,null,2)),{path:i,payload:e}}import $t from"node:fs";import mr from"node:path";var Wn=["dist",".angular/cache","tmp","out-tsc"],Jn=["node_modules"];function hr(n){let t=0;try{let e=$t.readdirSync(n,{withFileTypes:!0});for(let r of e){let s=mr.join(n,r.name);try{r.isDirectory()?t+=hr(s):r.isFile()&&(t+=$t.statSync(s).size)}catch{}}}catch{}return t}function me(n,t,e){let r=n.getApp(t);if(!r)return null;let s=n.getState(t),i=s?s.status==="serving"||s.status==="compiling"||s.status==="starting":!1,a=[...Wn,...e?Jn:[]].map(u=>{let c=mr.join(r.workspaceRoot,u),h=$t.existsSync(c);return{path:c,exists:h,sizeBytes:h?hr(c):0}});return{app:t,workspace:r.workspaceRoot,targets:a,ranOnServing:i}}function gr(n,t,e){let r=me(n,t,e);if(!r)return{error:"unknown app"};if(r.ranOnServing)return{error:"app is currently running; stop it first"};let s=[],i=[];for(let o of r.targets)if(o.exists)try{$t.rmSync(o.path,{recursive:!0,force:!0}),s.push(o.path)}catch(a){i.push({path:o.path,error:a?.message||String(a)})}return{ok:i.length===0,removed:s,failed:i}}function vt(n){return n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}var Gn=["stopped","starting","compiling","serving","error"];function yr(n){let t=[];t.push("# HELP daimon_up daimon daemon up"),t.push("# TYPE daimon_up gauge"),t.push("daimon_up 1"),t.push("# HELP daimon_app_status app status one-hot"),t.push("# TYPE daimon_app_status gauge");let e=n.list();for(let r of e)for(let s of Gn)t.push(`daimon_app_status{name="${vt(r.name)}",status="${s}"} ${r.status===s?1:0}`);t.push("# HELP daimon_compile_seconds last successful compile duration in seconds"),t.push("# TYPE daimon_compile_seconds gauge");for(let r of e)r.lastCompileMs!=null&&t.push(`daimon_compile_seconds{name="${vt(r.name)}"} ${(r.lastCompileMs/1e3).toFixed(3)}`);t.push("# HELP daimon_error_total cumulative deduped error count"),t.push("# TYPE daimon_error_total counter");for(let r of e)t.push(`daimon_error_total{name="${vt(r.name)}"} ${r.errorCount}`);t.push("# HELP daimon_cpu_percent app CPU percent"),t.push("# TYPE daimon_cpu_percent gauge");for(let r of e)r.cpu!=null&&t.push(`daimon_cpu_percent{name="${vt(r.name)}"} ${r.cpu}`);t.push("# HELP daimon_mem_mb app resident memory MB"),t.push("# TYPE daimon_mem_mb gauge");for(let r of e)r.memMB!=null&&t.push(`daimon_mem_mb{name="${vt(r.name)}"} ${r.memMB}`);return t.join(`
|
|
43
|
+
`)+`
|
|
44
|
+
`}Q();import wt from"node:fs";import qn from"node:crypto";import vr from"node:path";var Xn=1e6;function Kn(){return vr.join(Y(),"audit.log")}function Yn(n){try{if(wt.statSync(n).size>Xn){let e=n+".1";try{wt.unlinkSync(e)}catch{}wt.renameSync(n,e)}}catch{}}function wr(n,t,e,r){let s=Kn();wt.mkdirSync(vr.dirname(s),{recursive:!0}),Yn(s);let i=JSON.stringify({prev:t,next:e}),o=qn.createHash("sha1").update(i).digest("hex").slice(0,12),a=`${new Date().toISOString()} ${n} ${o} ${r.join(",")}
|
|
45
|
+
`;try{wt.appendFileSync(s,a)}catch{}}import Nt from"node:fs";import Mt from"node:path";import{fileURLToPath as zn}from"node:url";var br=Mt.dirname(zn(import.meta.url));function Vn(){let n=[Mt.resolve(br,"templates","presets"),Mt.resolve(br,"..","src","templates","presets")];for(let t of n)if(Nt.existsSync(t))return t;return n[0]}function Sr(){let n=Vn();if(!Nt.existsSync(n))return[];let t=Nt.readdirSync(n).filter(r=>r.endsWith(".json")),e=[];for(let r of t)try{let s=Nt.readFileSync(Mt.join(n,r),"utf8");s.charCodeAt(0)===65279&&(s=s.slice(1)),e.push(JSON.parse(s))}catch{}return e}Q();import _t from"node:fs";import kr from"node:path";function xr(){return kr.join(Y(),"state-handoff.json")}function Er(n){let t=[];for(let s of n.names()){let i=n.getState(s);i&&(i.status==="serving"||i.status==="compiling"||i.status==="starting")&&i.port&&t.push({name:s,port:i.port})}let e={ts:Date.now(),apps:t},r=xr();return _t.mkdirSync(kr.dirname(r),{recursive:!0}),_t.writeFileSync(r,JSON.stringify(e)),r}function Tr(n=6e4){let t=xr();try{let e=_t.readFileSync(t,"utf8"),r=JSON.parse(e);return _t.unlinkSync(t),!r||typeof r.ts!="number"||Date.now()-r.ts>n?null:r}catch{return null}}At();var vs=ys(import.meta.url),Lt=F.dirname(vs);function ge(){let n=[F.resolve(Lt,"dashboard","browser"),F.resolve(Lt,"dashboard"),F.resolve(Lt,"..","dist","dashboard","browser"),F.resolve(Lt,"..","dist","dashboard")];for(let t of n)if(It.existsSync(F.join(t,"index.html")))return t;return null}var ws={".html":"text/html; charset=utf-8",".js":"application/javascript; charset=utf-8",".mjs":"application/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".ico":"image/x-icon",".json":"application/json; charset=utf-8",".map":"application/json; charset=utf-8",".woff2":"font/woff2",".woff":"font/woff",".ttf":"font/ttf"};function bt(n,t){try{if(!It.statSync(t).isFile())return!1;let r=F.extname(t).toLowerCase(),s=ws[r]??"application/octet-stream",i=It.readFileSync(t);return n.writeHead(200,{"content-type":s,"content-length":i.length,"cache-control":r===".html"?"no-cache":"public, max-age=3600"}),n.end(i),!0}catch{return!1}}function w(n,t,e){let r=JSON.stringify(e);n.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(r)}),n.end(r)}function ct(n){if(!n)return;let t=n.match(/^(\d+)(ms|s|m|h)?$/);if(!t)return;let e=Number(t[1]);switch(t[2]||"ms"){case"ms":return e;case"s":return e*1e3;case"m":return e*60*1e3;case"h":return e*60*60*1e3}}function Dt(n,t){let e=(n.searchParams.get("format")||"").toLowerCase();return e==="full"?"full":e==="compact"?"compact":t?.().output?.format==="full"?"full":"compact"}function bs(n){return{name:n.name,status:n.status,port:n.port,health:n.health,errCount:n.errorCount,lastChangeMs:n.lastChangeMs??null}}function Ft(n){return{name:n.name,status:n.status,port:n.port,url:n.url,health:n.health,errCount:n.errorCount,lastChangeMs:n.lastChangeMs??null,uptime:n.uptimeMs}}function ye(n){let t=n.parsed;return t&&(t.file||t.code)?{file:t.file??null,line:t.line??null,col:t.col??null,code:t.code??null,message:t.message??n.message}:{file:null,line:null,col:null,code:null,message:n.message}}function Ss(n){if(!n)return{};if(/^\d{10,}$/.test(n))return{sinceTs:Number(n)};let t=ct(n);return t!=null?{sinceMs:t}:{}}var ks=/key|secret|token|password|pass/i;function xs(n){let t=JSON.parse(JSON.stringify(n));if(t.apiToken&&(t.apiToken="***"),t.overrides&&typeof t.overrides=="object")for(let e of Object.keys(t.overrides)){let r=t.overrides[e]?.env;if(r&&typeof r=="object")for(let s of Object.keys(r))ks.test(s)&&(r[s]="***")}return t}function ve(n){if(!n)return"";try{let t=It.readFileSync(n);return gs.createHash("sha1").update(t).digest("hex")}catch{return""}}function Pr(n,t,e={}){let r=new jt,s=hs.createServer(async(i,o)=>{try{let a=new URL(i.url||"/","http://127.0.0.1"),u=i.method||"GET",c=a.pathname.replace(/\/$/,"").split("/").filter(Boolean),h=()=>{let m=(e.getConfig?e.getConfig():null)?.apiToken??null;if(!m)return!0;let g=i.headers.authorization;return typeof g=="string"&&g.toLowerCase().startsWith("bearer ")&&g.slice(7).trim()===m?!0:(w(o,401,{error:"unauthorized"}),!1)};if(u==="POST"&&a.pathname==="/api/shutdown"){if(!h())return;w(o,200,{ok:!0}),e.onShutdown&&setImmediate(()=>{try{e.onShutdown()}catch{}});return}if(a.pathname==="/api/config"&&e.getConfig){if(u==="GET"){let l=e.getConfig(),m=ve(e.configPath);o.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:m}),o.end(JSON.stringify({etag:m,config:xs(l)}));return}if(u==="PATCH"&&e.patchConfig){if(!h())return;let l=i.headers["if-match"]?.trim(),m=ve(e.configPath);if(!l||l!==m){w(o,412,{error:"etag mismatch",current:m});return}let g={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(k=>{let E=[];i.on("data",v=>E.push(v)),i.on("end",()=>{try{g=JSON.parse(Buffer.concat(E).toString("utf8"))}catch{}k()})});let d=e.patchConfig(g);if(!d.ok){w(o,400,{error:d.error});return}let y=ve(e.configPath);try{let k=i.socket.remoteAddress||"127.0.0.1";wr(k,g,g,d.applied)}catch{}o.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:y}),o.end(JSON.stringify({etag:y,applied:d.applied,addedApps:d.addedApps,removedApps:d.removedApps,restartRequired:d.restartRequired}));return}w(o,405,{error:"method not allowed"});return}if(a.pathname==="/api/presets"&&u==="GET"){w(o,200,Sr());return}if(a.pathname==="/api/snapshot-state"&&u==="POST"){if(!h())return;let l=Er(n);w(o,200,{ok:!0,path:l});return}if(a.pathname==="/api/config/reload"&&u==="POST"&&e.reloadConfig){if(!h())return;try{let l=await e.reloadConfig();w(o,200,l)}catch(l){w(o,400,{error:l?.message||String(l)})}return}if(u==="GET"&&a.pathname==="/metrics"&&e.metricsEnabled){let l=yr(n);o.writeHead(200,{"content-type":"text/plain; version=0.0.4","content-length":Buffer.byteLength(l)}),o.end(l);return}if(u!=="GET"&&a.pathname.startsWith("/api/")&&a.pathname!=="/api/shutdown"&&a.pathname!=="/api/config"&&a.pathname!=="/api/config/reload"&&!h())return;if(u==="GET"&&a.pathname==="/"){let l=ge();if(l&&bt(o,F.join(l,"index.html")))return;o.writeHead(404).end('dashboard not found \u2014 run "npm run build:dashboard" in the daimon repo');return}if(c[0]==="api"&&c[1]==="events"&&c.length===2){if(u!=="GET"){w(o,405,{error:"method not allowed"});return}let l=ct(a.searchParams.get("since")),m=a.searchParams.get("app")||void 0;if(a.searchParams.get("stream")==="ndjson"){o.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});let y=n.events({sinceMs:l,app:m});for(let v of y)o.write(JSON.stringify(v)+`
|
|
46
|
+
`);let k=v=>{m&&v.app!==m||o.write(JSON.stringify(v)+`
|
|
47
|
+
`)};n.on("event",k);let E=setInterval(()=>{try{o.write(`
|
|
48
|
+
`)}catch{}},3e4);i.on("close",()=>{n.off("event",k),clearInterval(E);try{o.end()}catch{}});return}let g=n.events({sinceMs:l,app:m}),d=n.getHistory();if(d&&l&&g.length<500){let y=Date.now()-l,k=d.queryEvents({app:m,since:y,limit:1e3}),E=new Set(g.map(v=>`${v.ts}|${v.app}|${v.type}|${v.from??""}|${v.to??""}|${v.message??""}`));for(let v of k){let O=`${v.ts}|${v.app}|${v.type}|${v.from_state??""}|${v.to_state??""}|${v.message??""}`;E.has(O)||g.push({ts:v.ts,app:v.app,type:v.type,from:v.from_state??void 0,to:v.to_state??void 0,message:v.message??void 0})}g.sort((v,O)=>v.ts-O.ts)}w(o,200,g);return}if(c[0]==="api"&&c[1]==="session"){if(c[2]==="record"&&u==="POST"){let l=a.searchParams.get("action")||"toggle";if(l==="start"||l==="toggle"&&!n.sessionRecorder.isRecording()){let m=n.sessionRecorder.start();w(o,200,{recording:!0,path:m.path});return}if(l==="stop"||l==="toggle"&&n.sessionRecorder.isRecording()){let m=n.sessionRecorder.stop();w(o,200,{recording:!1,path:m.path});return}w(o,400,{error:"invalid action"});return}if(c[2]==="status"&&u==="GET"){w(o,200,{recording:n.sessionRecorder.isRecording()});return}w(o,404,{error:"not found"});return}if(c[0]==="api"&&c[1]==="history"){if(u!=="GET"){w(o,405,{error:"method not allowed"});return}let l=n.getHistory();if(!l){w(o,200,[]);return}let m=c[2],g=a.searchParams.get("app")||void 0,d=a.searchParams.get("since"),y=a.searchParams.get("until"),k=a.searchParams.get("limit"),E=d?/^\d{10,}$/.test(d)?Number(d):Date.now()-(ct(d)??0):void 0,v=y?/^\d{10,}$/.test(y)?Number(y):Date.now()-(ct(y)??0):void 0,O=k?Number(k):void 0;if(m==="events"){w(o,200,l.queryEvents({app:g,since:E,until:v,type:a.searchParams.get("type")||void 0,limit:O}));return}if(m==="compile-times"){w(o,200,l.queryCompiles({app:g,since:E,until:v,limit:O}));return}if(m==="tasks"){w(o,200,l.queryTasks({app:g,task:a.searchParams.get("task")||void 0,since:E,limit:O}));return}if(m==="summary"&&c.length>=4){let _=decodeURIComponent(c[3]);w(o,200,l.summary(_));return}if(m==="why"&&c.length>=4){let _=decodeURIComponent(c[3]);w(o,200,l.why(_));return}w(o,404,{error:"not found"});return}if(c[0]==="api"&&c[1]==="profiles"&&c[3]==="ensure-up"&&u==="POST"){let l=decodeURIComponent(c[2]),m=e.getConfig?.(),g=m?.profiles?.[l];if(!g){w(o,404,{error:"unknown profile"});return}let d=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(d)){w(o,400,{error:"until must be serving|healthy"});return}let y=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),k=y?Number(y):3e5;(!Number.isFinite(k)||k<=0)&&(k=3e5),k=Math.min(k,12e5);let E=m?.healthProbe?.enabled??!0,v=d==="healthy"&&!E?"serving":d,O=Date.now();for(let T of g){let f=n.summary(T);f&&f.status!=="serving"&&f.status!=="starting"&&f.status!=="compiling"&&await n.startWithDeps(T)}let _=await Promise.all(g.map(async T=>{let f=Math.max(1e3,k-(Date.now()-O));if(!n.summary(T))return{name:T,state:null,until:v,reachedTargetMs:null,timedOut:!1,error:"unknown"};let P=await n.waitFor(T,v,f),M=n.summary(T);return{name:T,state:M?Ft(M):null,until:v,reachedTargetMs:P.timedOut?null:P.waitedMs,timedOut:P.timedOut}}));w(o,200,{profile:l,apps:_,_meta:{totalMs:Date.now()-O,until:v}});return}if(c[0]==="api"&&c[1]==="discovery"&&c[2]==="explain"&&u==="GET"){let l=e.getConfig?.();if(!l){w(o,200,{searchRoots:[],scanned:0,rejected:{},warnings:[],suggestion:"no config loaded"});return}let{discoverApps:m}=await Promise.resolve().then(()=>(ht(),te)),g={scanned:0,rejected:{}},d=[],y=m(l,{warnings:d,stats:g}),k=l.searchRoots.map(E=>typeof E=="string"?E:E.path);w(o,200,{searchRoots:k,scanned:g.scanned,rejected:g.rejected,warnings:d,appsFound:y.length,suggestion:y.length===0?k.length===0?"no searchRoots configured. Run 'daimon init --auto' from a workspace folder.":"discovery returned no apps. Check that searchRoots contain nx.json / angular.json / vite.config.* / .storybook.":`${y.length} apps discovered`});return}if(c[0]==="api"&&c[1]==="doctor"&&c[2]==="auto-fix"&&u==="POST"){if(!h())return;let l={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(E=>{let v=[];i.on("data",O=>v.push(O)),i.on("end",()=>{try{l=JSON.parse(Buffer.concat(v).toString("utf8"))}catch{}E()})});let{runAutoFix:m,ALL_AUTO_FIX:g}=await Promise.resolve().then(()=>(Rr(),Cr)),y=e.getConfig?.()?.doctor?.autoFix?.permitted??g,k=Array.isArray(l.permitted)&&l.permitted.length?l.permitted:y;try{let E=await m({permitted:k,dryRun:!!l.dryRun});w(o,200,E)}catch(E){w(o,500,{error:E?.message??String(E)})}return}if(c[0]==="api"&&c[1]==="overview"&&u==="GET"){let l=e.getConfig?.(),m=n.list(),g=a.searchParams.get("workspace"),d=a.searchParams.get("profile"),y=m;if(g&&(y=y.filter(f=>f.workspaceLabel===g)),d){let f=l?.profiles?.[d]??null;f&&(y=y.filter(C=>f.includes(C.name)))}let k={apps:y.length,serving:y.filter(f=>f.status==="serving").length,errors:y.filter(f=>f.status==="error").length,stopped:y.filter(f=>f.status==="stopped").length,totalErrCount:y.reduce((f,C)=>f+C.errorCount,0),totalCpuPct:Math.round(y.reduce((f,C)=>f+(C.cpu??0),0)*10)/10,totalMemMb:Math.round(y.reduce((f,C)=>f+(C.memMB??0),0))},E={};for(let f of y)(E[f.status]??=[]).push(f.name);let v=y.filter(f=>f.status==="error"||f.errorCount>0).map(f=>{let C=n.errors(f.name)??[],P=C[C.length-1],M=P?.parsed;return{name:f.name,status:f.status,errCount:f.errorCount,firstError:M?{file:M.file??null,line:M.line??null,code:M.code??null,message:M.message??P?.message??""}:P?{file:null,line:null,code:null,message:P.message}:null}}),O=Date.now()-5*6e4,_=n.events({sinceMs:5*6e4}).filter(f=>f.type==="status"&&f.ts>=O).filter(f=>g?y.some(C=>C.name===f.app):!0).filter(f=>d?y.some(C=>C.name===f.app):!0).slice(-5).map(f=>({name:f.app,transition:`${f.from??"?"}\u2192${f.to??"?"}`,msAgo:Date.now()-f.ts})),T={ts:Date.now(),version:st,totals:k,byStatus:E,needsAttention:v,recentlyChanged:_};k.apps===0&&(T._meta={suggestion:"no apps registered. run 'daimon doctor' for recommended next step, or 'daimon init --auto' from a workspace folder."}),w(o,200,T);return}if(c[0]!=="api"||c[1]!=="apps"){if(u==="GET"&&!a.pathname.startsWith("/metrics")){let l=ge();if(l){let m=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(m){let g=F.resolve(l,m);if(g.startsWith(l)&&bt(o,g))return}if(!F.extname(m||"")&&bt(o,F.join(l,"index.html")))return}}w(o,404,{error:"not found"});return}if(c.length===2){if(u!=="GET"){w(o,405,{error:"method not allowed"});return}let l=Dt(a,e.getConfig),m=n.list(),g=l==="full"?m:m.map(bs);if(a.searchParams.get("stream")==="ndjson"){o.writeHead(200,{"content-type":"application/x-ndjson; charset=utf-8"});for(let d of g)o.write(JSON.stringify(d)+`
|
|
49
|
+
`);o.end();return}if(a.searchParams.get("explain")==="1"){let d=e.getConfig?.(),y={format:l};if(d){let{discoverApps:k}=await Promise.resolve().then(()=>(ht(),te)),E={scanned:0,rejected:{}},v=[];k(d,{warnings:v,stats:E});let O=d.searchRoots.map(_=>typeof _=="string"?_:_.path);y={format:l,searchRoots:O,scanned:E.scanned,rejected:E.rejected,warnings:v,suggestion:g.length===0?O.length===0?"no searchRoots configured. Run 'daimon init --auto' from a workspace folder to add the current cwd.":"discovery returned no apps. Check that searchRoots contain nx.json / angular.json / vite.config.* / .storybook, then run 'daimon doctor'.":"apps discovered; _meta is informational."}}w(o,200,{apps:g,_meta:y});return}w(o,200,g);return}let p=decodeURIComponent(c[2]),b=c[3],S=c[4];if(!b){if(u!=="GET"){w(o,405,{error:"method not allowed"});return}let l=n.summary(p);if(!l){w(o,404,{error:"unknown app"});return}Dt(a,e.getConfig)==="full"?w(o,200,{...l,_meta:{format:"full"}}):w(o,200,{...Ft(l),_meta:{format:"compact"}});return}if(b==="errors"&&S==="since-last"&&u==="GET"){let l=a.searchParams.get("client")||"default",m=r.getErrorCursor(l,p),g=n.errorsSince(p,m);if(g==null){w(o,404,{error:"unknown app"});return}let d=g.reduce((k,E)=>Math.max(k,E.lastSeen),m);d>m&&r.setErrorCursor(l,p,d);let y=Dt(a,e.getConfig);w(o,200,y==="full"?g:g.map(ye));return}if(b==="errors"&&!S&&u==="GET"){let l=a.searchParams.get("since"),m=Dt(a,e.getConfig);if(l){let{sinceMs:d,sinceTs:y}=Ss(l),k=y??(d!=null?Date.now()-d:0),E=n.errorsSince(p,k);if(E==null){w(o,404,{error:"unknown app"});return}w(o,200,m==="full"?E:E.map(ye));return}let g=n.errors(p);if(g==null){w(o,404,{error:"unknown app"});return}w(o,200,m==="full"?g:g.map(ye));return}if(b==="logs"&&c[4]==="stream"&&u==="GET"){if(!n.summary(p)){w(o,404,{error:"unknown app"});return}o.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"});let l=n.logs(p,{tail:50})??[];for(let E of l)o.write(`data: ${JSON.stringify({ts:Date.now(),line:E})}
|
|
50
|
+
|
|
51
|
+
`);let m=[],g=0,d=()=>{for(;m.length&&o.write(m.shift()););},y=E=>{E.name===p&&(m.length>=200&&(g++,m.shift()),m.push(`data: ${JSON.stringify({ts:E.ts,line:E.line})}
|
|
52
|
+
|
|
53
|
+
`),d())};n.on("log",y);let k=setInterval(()=>o.write(`: ping
|
|
54
|
+
|
|
55
|
+
`),3e4);i.on("close",()=>{n.off("log",y),clearInterval(k)});return}if(b==="logs"&&u==="GET"){let l=a.searchParams.get("tail"),m=a.searchParams.get("since"),g=n.logs(p,{tail:l?Number(l):void 0,sinceMs:ct(m)});if(g==null){w(o,404,{error:"unknown app"});return}w(o,200,{lines:g});return}if(b==="wait"&&u==="GET"){if(!n.summary(p)){w(o,404,{error:"unknown app"});return}let l=(a.searchParams.get("until")||"serving").toLowerCase();if(!["serving","healthy","stopped","error"].includes(l)){w(o,400,{error:"until must be one of serving|healthy|stopped|error"});return}let m=a.searchParams.get("timeout"),g=m?Number(m):120;(!Number.isFinite(g)||g<=0)&&(g=120),g=Math.min(g,600);let d=await n.waitFor(p,l,g*1e3);w(o,200,d);return}if(b==="ensure"&&u==="POST"){let l=n.summary(p);if(!l){w(o,404,{error:"unknown app"});return}let m=(a.searchParams.get("until")||"healthy").toLowerCase();if(!["serving","healthy"].includes(m)){w(o,400,{error:"until must be serving|healthy"});return}let g=a.searchParams.get("timeoutMs")||a.searchParams.get("timeout"),d=g?Number(g):18e4;(!Number.isFinite(d)||d<=0)&&(d=18e4),d=Math.min(d,6e5);let y=e.getConfig?.().healthProbe?.enabled??!0,k=m,E;if(k==="healthy"&&!y&&(k="serving",E="no health probe; treated serving as terminal"),k==="serving"&&l.status==="serving"||k==="healthy"&&l.status==="serving"&&l.health==="healthy"){w(o,200,{...Ft(l),_meta:{format:"compact",startedFromState:null,warning:E,waitedMs:0}});return}let O=l.status;l.status!=="starting"&&l.status!=="compiling"&&await n.start(p);let _=await n.waitFor(p,k,d),T=n.summary(p),f=T?Ft(T):{name:p,status:_.status,port:null,url:null,health:_.health,errCount:0,lastChangeMs:null,uptime:null};if(_.timedOut){w(o,200,{error:"timeout",state:f,_meta:{format:"compact",startedFromState:O,warning:E,waitedMs:_.waitedMs,timedOut:!0}});return}w(o,200,{...f,_meta:{format:"compact",startedFromState:O,warning:E,waitedMs:_.waitedMs}});return}if(b==="start"&&u==="POST"){if(a.searchParams.get("withDeps")==="1"){let g=await n.startWithDeps(p);w(o,g.ok?200:400,g);return}let m=await n.start(p);w(o,m.ok?200:400,m);return}if(b==="start-with-deps"&&u==="POST"){let l=await n.startWithDeps(p);w(o,l.ok?200:400,l);return}if(b==="tasks"&&u==="GET"&&!S){let l=n.listTasks(p);if(l==null){w(o,404,{error:"unknown app"});return}w(o,200,{tasks:l,watching:n.listWatchTasks(p)});return}if(b==="run"&&S&&u==="POST"){let l={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(d=>{let y=[];i.on("data",k=>y.push(k)),i.on("end",()=>{try{l=JSON.parse(Buffer.concat(y).toString("utf8"))}catch{}d()})});let m=Array.isArray(l.args)?l.args.map(String):[];if(l.watch){let d=n.startWatchTask(p,S,m);w(o,d.ok?200:400,d);return}let g=await n.runTask(p,S,m);if("error"in g){w(o,404,g);return}w(o,200,g);return}if(b==="run-stop"&&S&&u==="POST"){let l=await n.stopWatchTask(p,S);w(o,200,l);return}if(b==="env"&&u==="GET"){let m=n.getConfig().envFiles?.[p]??[],g=n.getState(p);w(o,200,{candidates:m,active:g?.activeEnvFile??null});return}if(b==="env"&&u==="POST"){let l={};i.headers["content-length"]&&i.headers["content-length"]!=="0"&&await new Promise(g=>{let d=[];i.on("data",y=>d.push(y)),i.on("end",()=>{try{l=JSON.parse(Buffer.concat(d).toString("utf8"))}catch{}g()})}),n.setActiveEnvFile(p,l.use??null);let m=n.getState(p);w(o,200,{active:m?.activeEnvFile??null});return}if(b==="requests"&&u==="GET"){if(!e.requestLog){w(o,200,[]);return}let l=ct(a.searchParams.get("since"));w(o,200,e.requestLog.requests(p,l));return}if(b==="clean"&&u==="POST"){let l=a.searchParams.get("deep")==="1",m=a.searchParams.get("yes")==="1",g=me(n,p,l);if(!g){w(o,404,{error:"unknown app"});return}if(g.ranOnServing){w(o,409,{error:"refusing: app is currently running",plan:g});return}if(!m){w(o,200,{plan:g,hint:"pass --yes to delete"});return}let d=gr(n,p,l);w(o,200,d);return}if(b==="snapshot"&&u==="POST"){if(a.searchParams.get("write")==="1"){let g=dr(n,p);if(!g){w(o,404,{error:"unknown app"});return}w(o,200,{snapshot:g.path});return}let m=de(n,p);if(!m){w(o,404,{error:"unknown app"});return}w(o,200,m);return}if(b==="stop"&&u==="POST"){let l=await n.stop(p);w(o,l.ok?200:400,l);return}if(b==="restart"&&u==="POST"){let l=await n.restart(p);w(o,l.ok?200:400,l);return}if(u==="GET"&&!a.pathname.startsWith("/api/")&&!a.pathname.startsWith("/metrics")){let l=ge();if(l){let m=a.pathname.replace(/^\/dashboard\//,"/").replace(/^\//,"");if(m){let g=F.resolve(l,m);if(g.startsWith(l)&&bt(o,g))return}if(!F.extname(m||"")&&bt(o,F.join(l,"index.html")))return}}w(o,404,{error:"not found"})}catch(a){w(o,500,{error:a?.message||String(a)})}});return s.listen(t,"127.0.0.1"),s}import Es from"node:http";import Ts from"node:https";var As=1e3,Cs=500;function Rs(n,t,e,r,s){if(t)return[t];let i=n.path||"/",o=n.fallbackHosts&&n.fallbackHosts.length?n.fallbackHosts:["127.0.0.1"];if(n.host||n.scheme){let u=e?Bt(e):null,c=n.scheme||u?.protocol?.replace(":","")||"http",h=n.host||u?.hostname||(r?o[0]:"127.0.0.1"),p=r??(u?.port?Number(u.port):null);return[Or(c,h,p,i)]}if(e){let u=Bt(e);if(u)return u.pathname=i,[u.toString()]}let a=[];s&&a.push(s);for(let u of o)a.includes(u)||a.push(u);return a.map(u=>Or("http",u,r,i))}function Bt(n){try{return new URL(n)}catch{return null}}function Or(n,t,e,r){let s=t.includes(":")&&!t.startsWith("[")?`[${t}]`:t,i=e?`:${e}`:"";return`${n}://${s}${i}${r.startsWith("/")?r:"/"+r}`}var Ht=class{constructor(t,e,r){this.registry=t;this.cfg=e;this.fullConfig=r;if(e.enabled){t.on("change",this.onChange);for(let s of t.names())this.evaluate(s)}}registry;cfg;fullConfig;timers=new Map;starting=new Map;freshness=new Map;stopped=!1;stop(){this.stopped=!0,this.registry.off("change",this.onChange);for(let t of this.timers.values())clearInterval(t);for(let t of this.starting.values())clearTimeout(t);this.timers.clear(),this.starting.clear()}onChange=()=>{if(!this.stopped)for(let t of this.registry.names())this.evaluate(t)};evaluate(t){let e=this.registry.getState(t);if(e)if(e.status==="serving"){if(this.timers.has(t)||this.starting.has(t))return;this.freshness.set(t,{retried:!1});let r=setTimeout(()=>{this.starting.delete(t),this.probe(t);let s=setInterval(()=>{this.probe(t)},this.cfg.intervalMs);this.timers.set(t,s)},Cs);this.starting.set(t,r)}else{let r=this.timers.get(t);r&&(clearInterval(r),this.timers.delete(t));let s=this.starting.get(t);s&&(clearTimeout(s),this.starting.delete(t)),this.freshness.delete(t),e.health!=="unknown"&&(e.status==="stopped"||e.status==="error")&&this.registry.setHealth(t,"unknown")}}async probe(t){let e=this.registry.getState(t);if(!e||e.status!=="serving")return;let r=this.fullConfig?.overrides?.[t]?.url,s=Rs(this.cfg,r,e.announcedUrl,e.port,e.cachedProbeHost);if(s.length===0){this.registry.setLastHealthError(t,"no probe URL available"),this.registry.setHealth(t,"unhealthy");return}let i=null;for(let a of s){let u=await this.tryProbe(a);if(u.ok){let c=Bt(a);c&&this.registry.setCachedProbeHost(t,c.hostname.replace(/^\[|\]$/g,"")),this.registry.setResolvedUrl(t,a),this.registry.setLastHealthError(t,null),this.registry.setHealth(t,"healthy");return}i||(i=`${u.error} ${a}`)}let o=this.freshness.get(t);if(o&&!o.retried){o.retried=!0,setTimeout(()=>{this.probe(t)},As);return}this.registry.setLastHealthError(t,i||"unknown probe failure"),this.registry.setHealth(t,"unhealthy")}tryProbe(t){return new Promise(e=>{let r=!1,s=u=>{r||(r=!0,e(u))},i=t.startsWith("https://"),o=i?Ts:Es,a={timeout:this.cfg.timeoutMs};if(i){let c=Bt(t)?.hostname?.replace(/^\[|\]$/g,"")??"",h=c==="127.0.0.1"||c==="::1"||c==="localhost";a.rejectUnauthorized=h?!1:!!this.cfg.rejectUnauthorized}try{let u=o.get(t,a,c=>{let h=c.statusCode??0;c.resume(),h>=200&&h<500?s({ok:!0}):s({ok:!1,error:`http ${h}`})});u.on("timeout",()=>u.destroy(new Error("timeout"))),u.on("error",c=>s({ok:!1,error:c?.code||c?.message||"error"}))}catch(u){s({ok:!1,error:u?.message||"throw"})}})}};import Ps from"pidusage";var Ut=class{constructor(t,e=2e3){this.registry=t;this.intervalMs=e;this.timer=setInterval(()=>this.tick(),e)}registry;intervalMs;timer=null;stopped=!1;stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}async tick(){if(this.stopped)return;let t=[];for(let r of this.registry.names()){let s=this.registry.getState(r);s?.pid&&t.push({name:r,pid:s.pid})}if(!t.length)return;let e=!1;await Promise.all(t.map(async({name:r,pid:s})=>{try{let i=await Ps(s),o=this.registry.getState(r);if(!o)return;let a=Math.round(i.cpu*10)/10,u=Math.round(i.memory/(1024*1024));(o.cpu!==a||o.memMB!==u)&&(o.cpu=a,o.memMB=u,e=!0)}catch{let i=this.registry.getState(r);i&&(i.cpu!=null||i.memMB!=null)&&(i.cpu=null,i.memMB=null,e=!0)}})),e&&this.registry.emit("change")}};var Wt=class{constructor(t,e){this.registry=t;this.cfg=e}registry;cfg;timers=new Map;stopped=!1;stop(){this.stopped=!0;for(let t of this.timers.values())clearTimeout(t);this.timers.clear()}onExit(t,e,r,s){if(this.stopped||s||!this.cfg.enabled||e===0&&!r)return;let i=this.registry.getState(t);if(!i)return;let o=Date.now();if((i.restartWindowStart==null||o-i.restartWindowStart>this.cfg.windowMs)&&(i.restartWindowStart=o,i.restartAttempts=0),i.restartAttempts+=1,i.restartAttempts>this.cfg.maxAttempts){i.lastStatusMessage=`auto-restart aborted (${i.restartAttempts-1}/${this.cfg.maxAttempts} within window)`,i.nextRestartAt=null,this.registry.recordEvent({app:t,type:"restart-scheduled",message:i.lastStatusMessage}),this.registry.emit("change");return}let a=Math.min(2**(i.restartAttempts-1)*1e3,3e4);i.nextRestartAt=o+a,i.lastStatusMessage=`restarting in ${Math.round(a/1e3)}s (attempt ${i.restartAttempts}/${this.cfg.maxAttempts})`,this.registry.recordEvent({app:t,type:"restart-scheduled",message:i.lastStatusMessage}),this.registry.emit("change");let u=setTimeout(()=>{this.timers.delete(t);let c=this.registry.getState(t);c&&(c.nextRestartAt=null),this.registry.start(t)},a);this.timers.set(t,u)}onUserStop(t){let e=this.timers.get(t);e&&(clearTimeout(e),this.timers.delete(t));let r=this.registry.getState(t);r&&(r.restartAttempts=0,r.restartWindowStart=null,r.nextRestartAt=null)}};import Se from"node:fs";import jr from"node:path";import Os from"node:os";var ke=jr.join(Os.homedir(),".daimon","state.json");function $r(){try{let n=Se.readFileSync(ke,"utf8"),t=JSON.parse(n);if(t&&typeof t=="object"&&t.ports&&typeof t.ports=="object")return{ports:t.ports}}catch{}return{ports:{}}}var we=null,be=null;function Nr(n){be=n,!we&&(we=setTimeout(()=>{we=null;let t=be;if(be=null,!!t)try{Se.mkdirSync(jr.dirname(ke),{recursive:!0}),Se.writeFileSync(ke,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: state write failed: ${e.message}
|
|
56
|
+
`)}},500))}he();import Mr from"node:fs";import js from"node:os";import _r from"node:path";import{createRequire as $s}from"node:module";var Ns=$s(import.meta.url),Ms=6e4,Jt=class{constructor(t,e){this.registry=t;this.cfg=e;this.logFile=_r.join(js.homedir(),".daimon","notifications.log");try{Mr.mkdirSync(_r.dirname(this.logFile),{recursive:!0})}catch{}if(!e.enabled){this.audit("init","disabled by config");return}try{let r=Ns("node-notifier");if(this.notifier=r,process.platform==="win32")try{let s=r.WindowsToaster;s&&(this.toaster=new s({withFallback:!0}))}catch(s){this.audit("init",`WindowsToaster unavailable: ${s?.message||s}`)}this.audit("init",`node-notifier loaded${this.toaster?" (+WindowsToaster fallback)":""}`)}catch(r){this.warnOnce(`node-notifier unavailable: ${r?.message||r}`),this.audit("init",`node-notifier load failed: ${r?.message||r}`);return}t.on("event",this.onEvent)}registry;cfg;notifier=null;toaster=null;lastSent=new Map;warned=!1;logFile;audit(t,e){let r=`${new Date().toISOString()} ${t} ${e}
|
|
57
|
+
`;try{Mr.appendFileSync(this.logFile,r)}catch{}}warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] notifier: ${t}
|
|
58
|
+
`))}stop(){this.registry.off("event",this.onEvent)}onEvent=t=>{this.notifier&&(t.type==="status"&&t.to==="error"&&this.cfg.onError?this.fire(t.app,"error",`${t.app} \u2192 error`,t.message||"app entered error state"):t.type==="health"&&t.to==="unhealthy"&&this.cfg.onUnhealthy?this.fire(t.app,"unhealthy",`${t.app} unhealthy`,"health probe failing"):t.type==="stale"?this.fire(t.app,"stale",`${t.app} stale`,t.message||"no output despite source changes"):t.type==="compile-regression"?this.fire(t.app,"compile-regression",`${t.app} slow compile`,t.message||"compile time regression"):t.type==="bundle-regression"?this.fire(t.app,"bundle-regression",`${t.app} bundle grew`,t.message||"bundle size regression"):t.type==="task-run"&&/exit=[1-9]/.test(t.message||"")&&this.fire(t.app,"task-fail",`${t.app} task failed`,t.message||""))};fire(t,e,r,s){if(!this.notifier)return;let i=`${t}::${e}`,o=this.lastSent.get(i)??0,a=Date.now();if(a-o<Ms){this.audit("throttled",`${i}`);return}this.lastSent.set(i,a);let u={title:`daimon: ${r}`,message:s,wait:!1,appID:"daimon"},c=(h,p)=>{h?(this.audit("fail",`${i} :: ${h?.message||h}`),this.warnOnce(`notify failed: ${h?.message||h}`)):this.audit("ok",`${i} :: ${r} :: ${p??"(no response)"}`)};try{this.audit("attempt",`${i} :: ${r}`),(this.toaster??this.notifier).notify(u,c)}catch(h){this.audit("throw",`${i} :: ${h?.message||h}`),this.warnOnce(`notify threw: ${h?.message||h}`)}}};import Lr from"node:fs";import xe from"node:path";var _s=5e3,Ls=3e4,Ds=new Set(["node_modules","dist",".angular",".nx",".git","tmp","out-tsc","coverage"]),Fs=new Set([".ts",".tsx",".html",".scss",".css",".js",".jsx",".json"]),Gt=class{constructor(t,e){this.registry=t;this.cfg=e;e.enabled&&(this.timer=setInterval(()=>this.tick(),_s),t.on("compile",this.onCompile))}registry;cfg;timer=null;caches=new Map;stop(){this.timer&&clearInterval(this.timer),this.registry.off("compile",this.onCompile)}onCompile=t=>{let e=this.registry.getApp(t.name);e&&this.caches.delete(e.workspaceRoot)};tick(){for(let t of this.registry.names())this.evaluate(t)}evaluate(t){let e=this.registry.getState(t),r=this.registry.getApp(t);if(!e||!r)return;if(e.status!=="serving"){e.stale&&this.registry.setStale(t,!1);return}if(e.startedAt==null)return;let s=e.lastLogTs??e.startedAt,i=Date.now()-s;if(i<this.cfg.silentMs){e.stale&&this.registry.setStale(t,!1);return}let o=e.lastCompileAt??e.startedAt;this.hasSourceChange(r.workspaceRoot,o,e.lastCompileAt)&&(e.stale||(this.registry.setStale(t,!0),this.registry.recordEvent({app:t,type:"stale",message:`no output in ${Math.round(i/1e3)}s despite source changes`})))}hasSourceChange(t,e,r){let s=this.caches.get(t);if(!s||Date.now()-s.ts>Ls||r!=null&&s.ts<r){let a=this.scan(t);this.caches.set(t,{ts:Date.now(),files:a})}return this.caches.get(t).files.some(a=>a.mtime>e)}scan(t){let e=[],r=(s,i)=>{if(i>8||e.length>4e3)return;let o;try{o=Lr.readdirSync(s,{withFileTypes:!0})}catch{return}for(let a of o)if(!a.name.startsWith(".git")){if(a.isDirectory()){if(Ds.has(a.name))continue;r(xe.join(s,a.name),i+1)}else if(a.isFile()){let u=xe.extname(a.name);if(!Fs.has(u))continue;try{let c=xe.join(s,a.name),h=Lr.statSync(c);e.push({path:c,mtime:h.mtimeMs})}catch{}}}};return r(t,0),e}};import Dr from"node:http";var qt=200,Xt=class{constructor(t,e){this.registry=t;this.cfg=e;e.enabled&&(t.on("change",this.onChange),this.tick())}registry;cfg;proxies=new Map;stopped=!1;stop(){this.stopped=!0,this.registry.off("change",this.onChange);for(let t of this.proxies.values())try{t.server.close()}catch{}this.proxies.clear()}onChange=()=>{this.stopped||this.tick()};tick(){for(let t of this.registry.names()){let e=this.registry.getState(t);if(!e)continue;let r=this.proxies.has(t);e.status==="serving"&&e.port&&!r?this.startProxy(t,e.port):e.status!=="serving"&&r&&this.stopProxy(t)}}stopProxy(t){let e=this.proxies.get(t);if(e){try{e.server.close()}catch{}this.proxies.delete(t)}}startProxy(t,e){let r=e+this.cfg.portOffset,s=[],i=Dr.createServer((o,a)=>{let u=Date.now(),c={hostname:"127.0.0.1",port:e,method:o.method,path:o.url,headers:{...o.headers,host:`127.0.0.1:${e}`}},h=Dr.request(c,p=>{a.writeHead(p.statusCode||502,p.headers),p.pipe(a);let b=()=>{s.push({ts:Date.now(),method:o.method||"GET",path:o.url||"/",status:p.statusCode||0,durationMs:Date.now()-u}),s.length>qt&&s.splice(0,s.length-qt)};p.on("end",b),p.on("error",b)});h.on("error",()=>{a.writeHead(502).end("upstream error"),s.push({ts:Date.now(),method:o.method||"GET",path:o.url||"/",status:502,durationMs:Date.now()-u}),s.length>qt&&s.splice(0,s.length-qt)}),o.pipe(h)});i.on("error",o=>{o?.code==="EADDRINUSE"&&process.stderr.write(`[daimon] requestLog: port ${r} in use for ${t}; disabling proxy
|
|
59
|
+
`),this.proxies.delete(t)}),i.listen(r,"127.0.0.1",()=>{this.proxies.set(t,{app:t,proxyPort:r,server:i,buffer:s})})}requests(t,e){let r=this.proxies.get(t);if(!r)return[];if(e){let s=Date.now()-e;return r.buffer.filter(i=>i.ts>=s)}return[...r.buffer]}proxyPortFor(t){return this.proxies.get(t)?.proxyPort??null}};Q();kt();ht();import Ee from"node:fs";var Is=new Set(["command","port","env","url"]);function Fr(n){let t=Ee.readFileSync(n,"utf8");t.charCodeAt(0)===65279&&(t=t.slice(1));let e=JSON.parse(t);if(!e||typeof e!="object"||Array.isArray(e))throw new Error("config must be a JSON object");return e}function Ir(n,t){if(t===null)return null;if(typeof t!="object"||Array.isArray(t))return t;let e=n&&typeof n=="object"&&!Array.isArray(n)?{...n}:{};for(let[r,s]of Object.entries(t))s===null?delete e[r]:e[r]=Ir(e[r],s);return e}function Bs(n,t){let e=n+"."+process.pid+".tmp";Ee.writeFileSync(e,t,"utf8"),Ee.renameSync(e,n)}function Hs(n,t){let e=new Set;for(let r of Object.keys(t))JSON.stringify(n?.[r])!==JSON.stringify(t[r])&&e.add(r);for(let r of Object.keys(n||{}))r in t||e.add(r);return[...e]}function Br(n){let t=Fr(n.configPath),e=Ir(t,n.patch);if(!e||typeof e!="object")throw new Error("patch produced non-object config");let r=Vt(e,n.configPath);return Bs(n.configPath,JSON.stringify(e,null,2)+`
|
|
60
|
+
`),{config:r,raw:e,applied:Hs(t,e),prevRaw:t}}function Te(n){let t=Fr(n.configPath),e=Vt(t,n.configPath);return Us(n.registry,e)}function Us(n,t){let e=n.getConfig();for(let c of Object.keys(e))e[c]=void 0;Object.assign(e,t);let r=new Set(n.names()),s=mt(e),i=new Set(s.map(c=>c.name)),o=[],a=[];for(let c of s)r.has(c.name)?n.updateDiscoveredApp(c):(n.addDiscoveredApp(c),o.push(c.name));for(let c of r)i.has(c)||a.push(c);let u=[];for(let c of n.names()){let h=n.getState(c);if(h&&(h.status==="serving"||h.status==="compiling")){let p=e.overrides?.[c];if(!p)continue;for(let b of Is)if(b in p){u.push(c);break}}}return{addedApps:o,removedApps:a,restartRequired:u,config:e}}At();Q();import Hr from"node:fs";import Ws from"node:os";import Ur from"node:path";var Js=/key|secret|token|password|pass/i;function Gs(n){if(!n)return null;let t=JSON.parse(JSON.stringify(n));if(t.apiToken&&(t.apiToken="***"),t.overrides)for(let e of Object.keys(t.overrides)){let r=t.overrides[e]?.env;if(r)for(let s of Object.keys(r))Js.test(s)&&(r[s]="***")}return t}function qs(n,t=200){if(!n)return[];let e=[];for(let r of n.names()){let s=n.getState(r);if(s)for(let i of s.logBuffer)e.push({ts:i.ts,line:`[${r}] ${i.line}`})}return e.sort((r,s)=>r.ts-s.ts),e.slice(-t).map(r=>r.line)}function Xs(){let n=Ur.join(Y(),"crashes");return Hr.mkdirSync(n,{recursive:!0}),n}function Ks(n,t,e){let r=new Date().toISOString().replace(/[:.]/g,"-"),s=Ur.join(Xs(),`${r}.txt`),i=n,o=[`daimon crash dump @ ${new Date().toISOString()}`,`version: ${st}`,`node: ${process.version}`,`platform: ${process.platform} ${Ws.release()}`,`cwd: ${process.cwd()}`,`pid: ${process.pid}`,"","ERROR:",i?.stack||String(i),"","CONFIG (redacted):",JSON.stringify(Gs(e),null,2),"","RECENT LOG (last 200 lines across apps):",...qs(t,200)];try{Hr.writeFileSync(s,o.join(`
|
|
61
|
+
`))}catch{}return s}function Wr(n){let t=e=>{let r=null;try{r=Ks(e,n.getRegistry(),n.getConfig())}catch{}try{process.stderr.write(`[daimon] fatal: ${e?.stack||e}
|
|
57
62
|
`)}catch{}if(r)try{process.stderr.write(`[daimon] crash dump: ${r}
|
|
58
|
-
`)}catch{}process.exit(1)};process.on("uncaughtException",t),process.on("unhandledRejection",t)}import
|
|
59
|
-
`);
|
|
60
|
-
`)}),onSubmit:()=>{let
|
|
61
|
-
`),process.exit(1)}if(r.kind==="stub-created"){let
|
|
63
|
+
`)}catch{}process.exit(1)};process.on("uncaughtException",t),process.on("unhandledRejection",t)}import x,{useEffect as to,useState as J}from"react";import Ce from"node:fs";import eo from"node:os";import ro from"node:path";import{Box as H,Text as R,useApp as no,useInput as so,useStdout as oo}from"ink";import Re from"ink-text-input";import{spawn as Pe,spawnSync as io}from"node:child_process";import L,{useEffect as Ys,useMemo as zs,useState as lt}from"react";import{Box as St,Text as I,useInput as Vs,useStdout as Qs}from"ink";import Zs from"ink-text-input";function Ae({registry:n,appName:t,onExit:e}){let{stdout:r}=Qs(),[s,i]=lt(0),[o,a]=lt(!1),[u,c]=lt(""),[h,p]=lt(""),[b,S]=lt(0),[l,m]=lt(0);Ys(()=>{let f=()=>i(P=>P+1);n.on("change",f);let C=setInterval(()=>i(P=>P+1),500);return()=>{n.off("change",f),clearInterval(C)}},[n]);let d=n.getState(t)?.logBuffer.map(f=>f.line)??[],y=(r.rows||30)-4,k=zs(()=>{if(!h)return[];let f=h.toLowerCase();return d.reduce((C,P,M)=>(P.toLowerCase().includes(f)&&C.push(M),C),[])},[d,h,s]);Vs((f,C)=>{if(o){if(C.escape){a(!1),c("");return}return}if(f==="q"||C.escape){e();return}if(f==="/"){a(!0);return}if(f==="g"){S(Math.max(0,d.length-y));return}if(f==="G"){S(0);return}if(C.pageUp){S(P=>Math.min(Math.max(0,d.length-y),P+y));return}if(C.pageDown){S(P=>Math.max(0,P-y));return}if(C.upArrow){S(P=>Math.min(Math.max(0,d.length-y),P+1));return}if(C.downArrow){S(P=>Math.max(0,P-1));return}if((f==="n"||f==="N")&&k.length){let P=f==="n"?(l+1)%k.length:(l-1+k.length)%k.length;m(P);let M=k[P],Z=d.length-b,A=Z-y;(M<A||M>=Z)&&S(Math.max(0,d.length-M-Math.floor(y/2)));return}});let E=f=>{p(f),a(!1),c(""),m(0)},v=d.length-b,O=Math.max(0,v-y),_=d.slice(O,v),T=(f,C)=>{if(!h)return L.createElement(I,{key:C},L.createElement(I,{dimColor:!0},String(C+1).padStart(5)," "),f);let P=h,M=f.toLowerCase(),Z=P.toLowerCase(),A=[],$=0,j=0;for(;$<f.length;){let D=M.indexOf(Z,$);if(D<0){A.push(L.createElement(I,{key:j++},f.slice($)));break}D>$&&A.push(L.createElement(I,{key:j++},f.slice($,D))),A.push(L.createElement(I,{key:j++,backgroundColor:"yellow",color:"black"},f.slice(D,D+P.length))),$=D+P.length}let N=k[l]===C;return L.createElement(I,{key:C},L.createElement(I,{color:N?"cyan":void 0,dimColor:!N},String(C+1).padStart(5)," "),A)};return L.createElement(St,{flexDirection:"column"},L.createElement(St,null,L.createElement(I,{bold:!0},"full log: ",L.createElement(I,{color:"cyan"},t)),L.createElement(I,{dimColor:!0}," (",d.length," lines",h?`, ${k.length} matches for "${h}"`:"",", scroll=",b,")")),L.createElement(St,{flexDirection:"column"},_.length===0?L.createElement(I,{dimColor:!0},"(no log yet)"):_.map((f,C)=>T(f,O+C))),L.createElement(St,null,o?L.createElement(St,null,L.createElement(I,null,"/"),L.createElement(Zs,{value:u,onChange:c,onSubmit:E})):L.createElement(I,{dimColor:!0},"[/] search [n/N] next/prev [g/G] bottom/top [PgUp/PgDn] [\u2191\u2193] [q/Esc] back")))}function ao(n){try{process.platform==="win32"?Pe("cmd",["/c","start","",n],{detached:!0,stdio:"ignore",windowsHide:!0}).unref():process.platform==="darwin"?Pe("open",[n],{detached:!0,stdio:"ignore"}).unref():Pe("xdg-open",[n],{detached:!0,stdio:"ignore"}).unref()}catch{}}var Jr={stopped:"gray",starting:"yellow",compiling:"yellow",serving:"green",error:"red"},Gr={healthy:"green",unhealthy:"red",unknown:"gray"};function co(n){if(n==null)return"";let t=Math.floor(n/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60);return e<60?`${e}m ${t%60}s`:`${Math.floor(e/60)}h ${e%60}m`}function Oe({registry:n,apiPort:t,onQuit:e}){let{exit:r}=no(),{stdout:s}=oo(),[i,o]=J(n.list()),[a,u]=J(0),[c,h]=J(!1),[p,b]=J(0),[S,l]=J(!1),[m,g]=J([]),[d,y]=J(!1),[k,E]=J(""),[v,O]=J(null),[,_]=J(0);to(()=>{let A=()=>o(n.list());n.on("change",A);let $=setInterval(()=>{o(n.list()),_(j=>j+1)},1e3);return()=>{n.off("change",A),clearInterval($)}},[n]),so((A,$)=>{if(S)return;if(v){if($.escape){O(null);return}if($.tab){let N=v.field==="command"?"port":v.field==="port"?"env":"command";O({...v,field:N});return}return}if(d){if($.escape){y(!1),E("");return}if($.return){let N=k.trim();g(N?N.split(/[\s,]+/).filter(Boolean):[]),y(!1),E("");return}if($.backspace||$.delete){E(N=>N.slice(0,-1));return}A&&!$.ctrl&&E(N=>N+A);return}if(A==="q"||$.ctrl&&A==="c"){e(),r();return}if(i.length===0)return;if($.upArrow){u(N=>Math.max(0,N-1)),b(0);return}if($.downArrow){u(N=>Math.min(i.length-1,N+1)),b(0);return}let j=i[a];if(j)if(A==="s")n.start(j.name);else if(A==="x")n.stop(j.name);else if(A==="r")n.restart(j.name);else if(A==="L")l(!0);else if(A==="t")y(!0),E(m.join(" "));else if(A==="e"){let N=n.getConfig(),D=n.getApp(j.name),G=n.getState(j.name)?.sessionOverrides??null,ut=G?.env??N.overrides?.[j.name]?.env??{},z=Object.entries(ut).map(([Kt,Yt])=>`${Kt}=${Yt}`).join(`
|
|
64
|
+
`);O({name:j.name,field:"command",cmd:G?.command??D?.command??"",port:String(G?.port??N.overrides?.[j.name]?.port??j.port??""),env:z})}else if(A==="E"){let D=n.getConfig().envFiles?.[j.name]??[];if(!D.length)return;let G=n.getState(j.name)?.activeEnvFile??null,ut=G?D.indexOf(G):-1,z=D[(ut+1)%D.length];n.setActiveEnvFile(j.name,z)}else if(A==="V"){let N=process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),D=ro.join(eo.tmpdir(),`daimon-${j.name}-${Date.now()}.json`),G=n.getConfig(),ut=n.getApp(j.name),z=n.getState(j.name)?.sessionOverrides??null,Kt={command:z?.command??ut?.command,port:z?.port??G.overrides?.[j.name]?.port??null,env:z?.env??G.overrides?.[j.name]?.env??{}};try{Ce.writeFileSync(D,JSON.stringify(Kt,null,2)),io(N,[D],{stdio:"inherit",shell:!0});let Yt=Ce.readFileSync(D,"utf8"),V=JSON.parse(Yt);n.setSessionOverride(j.name,{command:typeof V.command=="string"?V.command:void 0,port:typeof V.port=="number"?V.port:void 0,env:V.env&&typeof V.env=="object"?V.env:void 0}),Ce.unlinkSync(D)}catch{}}else A==="l"?h(N=>!N):A==="o"?j.url&&ao(j.url):$.pageUp?b(N=>N+5):$.pageDown&&b(N=>Math.max(0,N-5))});let T=m.length===0?i:i.filter(A=>m.every($=>A.tags.includes($))),f=T[Math.min(a,Math.max(0,T.length-1))],C=f?n.getState(f.name):null,P=C?C.logBuffer.slice(Math.max(0,C.logBuffer.length-12-p),C.logBuffer.length-p).map(A=>A.line):[],M=s.columns||100,Z=Math.min(36,Math.floor(M*.4));return S&&f?x.createElement(Ae,{registry:n,appName:f.name,onExit:()=>l(!1)}):x.createElement(H,{flexDirection:"column",width:M},x.createElement(H,{borderStyle:"round",borderColor:"cyan",paddingX:1},x.createElement(R,{bold:!0,color:"cyan"},"daimon"),x.createElement(R,{dimColor:!0}," \u2022 api http://127.0.0.1:",t)),x.createElement(H,{flexDirection:"row"},x.createElement(H,{flexDirection:"column",width:Z,borderStyle:"single",borderColor:"gray",paddingX:1},x.createElement(R,{bold:!0},"Apps ",m.length?x.createElement(R,{dimColor:!0},"(tags: ",m.join(", "),")"):null),T.length===0?x.createElement(R,{dimColor:!0},i.length===0?"(no apps discovered)":"(no apps match tag filter)"):T.map((A,$)=>{let j=$===a;return x.createElement(H,{key:A.name},x.createElement(R,{color:j?"cyan":void 0},j?"\u25B8 ":" "),x.createElement(R,{color:j?"cyan":void 0},((n.getState(A.name)?.sessionOverrides?"*":"")+A.name).padEnd(20).slice(0,20)),x.createElement(R,{color:Jr[A.status]}," ",A.status.padEnd(9)),x.createElement(R,{color:Gr[A.health]},A.status==="serving"?"\u25CF":" "),x.createElement(R,{dimColor:!0},A.port?` :${A.port}`:""),M>=100&&A.cpu!=null?x.createElement(R,{dimColor:!0}," ",String(A.cpu).padStart(5),"% ",String(A.memMB??0).padStart(5),"MB"):null)})),x.createElement(H,{flexDirection:"column",flexGrow:1,borderStyle:"single",borderColor:"gray",paddingX:1},f&&C?x.createElement(x.Fragment,null,x.createElement(R,null,"Selected: ",x.createElement(R,{bold:!0},f.name)),x.createElement(R,null,"Status: ",x.createElement(R,{color:Jr[f.status]},f.status)," ",x.createElement(R,{color:Gr[f.health]},"\u25CF")," ",x.createElement(R,{dimColor:!0},f.health)),x.createElement(R,null,"Port: ",f.port??"-"),x.createElement(R,null,"URL: ",f.url??"-"),f.announcedUrl&&f.announcedUrl!==f.url?x.createElement(R,{dimColor:!0},"Announced: ",f.announcedUrl):null,f.lastHealthError?x.createElement(R,{color:"red"},"HealthErr: ",f.lastHealthError):null,f.stale?x.createElement(R,{color:"yellow"},"\u26A0 stale (best guess)"):null,x.createElement(R,null,"Errors: ",x.createElement(R,{color:f.errorCount?"red":void 0},f.errorCount)),x.createElement(R,null,"Uptime: ",co(f.uptimeMs)),f.cpu!=null||f.memMB!=null?x.createElement(R,null,"Usage: ",f.cpu??"-","% ",f.memMB??"-"," MB"):null,f.compileHistoryMs.length>0?x.createElement(R,null,"Recent compile: ",f.compileHistoryMs.slice(-5).map(A=>(A/1e3).toFixed(1)+"s").join(" \xB7 ")):null,f.bundle?x.createElement(R,null,"Bundle: ",f.bundle.initialKB,"KB initial \xB7 ",f.bundle.lazyKB,"KB lazy",f.bundleRegressionPct!=null&&f.bundleRegressionPct>10?x.createElement(R,{color:"red"}," (+",f.bundleRegressionPct,"% \u26A0)"):null):null,C.lastStatusMessage?x.createElement(R,{dimColor:!0},"Note: ",C.lastStatusMessage):null,x.createElement(R,null,"\u2500\u2500\u2500\u2500 recent log ",c?"(focused)":""," \u2500\u2500\u2500\u2500"),P.length===0?x.createElement(R,{dimColor:!0},"(no output yet)"):P.map((A,$)=>x.createElement(R,{key:$,wrap:"truncate-end"},A))):x.createElement(R,{dimColor:!0},"No app selected."))),x.createElement(H,{flexDirection:"column"},d?x.createElement(R,null,"tag filter (space-separated, Enter to apply, Esc to cancel): ",x.createElement(R,{color:"cyan"},k)):null,v?x.createElement(H,{flexDirection:"column",borderStyle:"round",borderColor:"yellow",paddingX:1},x.createElement(R,{bold:!0,color:"yellow"},"edit ",v.name," (session-only) Tab=next field Enter=save Esc=cancel"),x.createElement(H,null,x.createElement(R,null,v.field==="command"?"> ":" ","command: "),v.field==="command"?x.createElement(Re,{value:v.cmd,onChange:A=>O({...v,cmd:A}),onSubmit:()=>O({...v,field:"port"})}):x.createElement(R,{dimColor:!0},v.cmd)),x.createElement(H,null,x.createElement(R,null,v.field==="port"?"> ":" ","port: "),v.field==="port"?x.createElement(Re,{value:v.port,onChange:A=>O({...v,port:A}),onSubmit:()=>O({...v,field:"env"})}):x.createElement(R,{dimColor:!0},v.port)),x.createElement(H,null,x.createElement(R,null,v.field==="env"?"> ":" ","env (k=v;): "),v.field==="env"?x.createElement(Re,{value:v.env.replace(/\n/g,";"),onChange:A=>O({...v,env:A.replace(/;/g,`
|
|
65
|
+
`)}),onSubmit:()=>{let A=Number(v.port),$={};for(let j of v.env.split(/\n/)){let N=j.match(/^\s*([^=]+)=(.*)$/);N&&($[N[1].trim()]=N[2])}n.setSessionOverride(v.name,{command:v.cmd||void 0,port:Number.isFinite(A)&&A>0?A:void 0,env:Object.keys($).length?$:void 0}),O(null)}}):x.createElement(R,{dimColor:!0},v.env))):null,x.createElement(R,{dimColor:!0},"[s] start [x] stop [r] restart [o] open URL [t] tag filter [e] edit [E] cycle env [V] $EDITOR [l] log focus [Shift+L] full log [PgUp/PgDn] scroll [q] quit")))}async function fo(n={}){let t=null,e=null;Wr({getRegistry:()=>t,getConfig:()=>e});let r;try{r=et()}catch(T){process.stderr.write(`[daimon] config error: ${T.message}
|
|
66
|
+
`),process.exit(1)}if(r.kind==="stub-created"){let T=ft();process.stdout.write(`[daimon] no config found. Created stub at:
|
|
62
67
|
${r.path}
|
|
63
68
|
`),process.stdout.write(`[daimon] Edit it to add "searchRoots" pointing at your Nx/Angular workspace, then run again.
|
|
64
|
-
`),process.stdout.write(`[daimon] (Local override path: ${
|
|
65
|
-
`),process.exit(0)}let{config:s,path:
|
|
66
|
-
`),s.depends&&Object.keys(s.depends).length){let
|
|
67
|
-
`),process.exit(1))}let
|
|
68
|
-
`);let a
|
|
69
|
-
`);for(let
|
|
70
|
-
`);continue}s.depends&&s.depends[
|
|
71
|
-
`);try{
|
|
72
|
-
`)}if(process.on("SIGINT",()=>{
|
|
73
|
-
`);let
|
|
74
|
-
`),
|
|
75
|
-
`),process.exit(1)});export{
|
|
69
|
+
`),process.stdout.write(`[daimon] (Local override path: ${T.local})
|
|
70
|
+
`),process.exit(0)}let{config:s,path:i}=r;if(process.stdout.write(`[daimon] config: ${i}
|
|
71
|
+
`),s.depends&&Object.keys(s.depends).length){let T=He(s.depends);T&&(process.stderr.write(`[daimon] config error: depends graph has a cycle: ${T.join(" -> ")}
|
|
72
|
+
`),process.exit(1))}let o=mt(s);o.length===0&&process.stdout.write(`[daimon] no serveable projects discovered in: ${s.searchRoots.join(", ")||"(none)"}
|
|
73
|
+
`);let a=$r(),u=new nt(s.portRange,{initial:a.ports,onChange:T=>Nr({ports:T})}),c=new Ot(s,o,u);t=c,e=s;let h=new at(s.history);c.setHistory(h);let p=new Ht(c,s.healthProbe,s),b=new Ut(c),S=new Wt(c,s.autoRestart),l=new Jt(c,s.notifications),m=new Gt(c,s.staleDetect),g=new Xt(c,s.requestLog);c.on("childExit",({name:T,code:f,signal:C,stopping:P})=>S.onExit(T,f,C,P)),c.on("userStop",({name:T})=>S.onUserStop(T));let d=Tr();if(d&&d.apps.length){process.stdout.write(`[daimon] state-handoff: restoring ${d.apps.map(T=>T.name).join(", ")}
|
|
74
|
+
`);for(let T of d.apps)u.pin(T.name,T.port);for(let T of d.apps)c.names().includes(T.name)&&c.start(T.name)}if(s.autoStart&&s.autoStart.length){let T=new Set(c.names());for(let f of s.autoStart){if(!T.has(f)){process.stderr.write(`[daimon] warning: autoStart references unknown app "${f}"
|
|
75
|
+
`);continue}s.depends&&s.depends[f]&&s.depends[f].length?c.startWithDeps(f):c.start(f)}}let y=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):s.apiPort,k=!!n.headless||!!s.headless||process.argv.includes("--headless"),E=!1,v=async()=>{if(!E){E=!0;try{p.stop()}catch{}try{b.stop()}catch{}try{S.stop()}catch{}try{l.stop()}catch{}try{m.stop()}catch{}try{g.stop()}catch{}try{h.close()}catch{}try{await c.stopAll(3e3)}catch{}try{O.close()}catch{}try{yt()}catch{}process.exit(0)}},O=Pr(c,y,{metricsEnabled:s.metrics.enabled,requestLog:g,onShutdown:()=>{v()},configPath:i,getConfig:()=>c.getConfig(),patchConfig:T=>{try{let f=Br({configPath:i,patch:T}),C=Te({configPath:i,registry:c});return{ok:!0,applied:f.applied,addedApps:C.addedApps,removedApps:C.removedApps,restartRequired:C.restartRequired}}catch(f){return{ok:!1,error:f?.message||String(f)}}},reloadConfig:async()=>{let T=Te({configPath:i,registry:c});return{ok:!0,addedApps:T.addedApps,removedApps:T.removedApps,restartRequired:T.restartRequired}}});process.stdout.write(`[daimon] api: http://127.0.0.1:${y}
|
|
76
|
+
`);try{nr(or(y,k,i))}catch(T){process.stderr.write(`[daimon] warning: could not write daemon.lock: ${T?.message||T}
|
|
77
|
+
`)}if(process.on("SIGINT",()=>{v()}),process.on("SIGTERM",()=>{v()}),process.on("beforeExit",()=>{v()}),k){process.stdout.write(`[daimon] headless mode \u2014 TUI suppressed. Dashboard: http://127.0.0.1:${y}
|
|
78
|
+
`);let T="",f=setInterval(()=>{let C=c.list().map(M=>({name:M.name,status:M.status,health:M.health,port:M.port})),P=JSON.stringify(C);P!==T&&(process.stderr.write(P+`
|
|
79
|
+
`),T=P)},6e4);await new Promise(()=>{}),clearInterval(f);return}await uo(lo.createElement(Oe,{registry:c,apiPort:y,onQuit:()=>{v()}})).waitUntilExit(),await v()}var mo=(()=>{try{return import.meta.url===po(process.argv[1]||"").href}catch{return!1}})();mo&&fo().catch(n=>{process.stderr.write(`[daimon] fatal: ${n?.stack||n}
|
|
80
|
+
`),process.exit(1)});export{fo as startInProcess};
|