daimon 0.4.2
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/LICENSE +131 -0
- package/README.md +196 -0
- package/dist/cli.js +127 -0
- package/dist/main.js +75 -0
- package/dist/mcp.js +3 -0
- package/package.json +73 -0
- package/src/dashboard.html +451 -0
- package/src/templates/claude/agent.md.tmpl +33 -0
- package/src/templates/claude/commands/doctor.md.tmpl +10 -0
- package/src/templates/claude/commands/errors.md.tmpl +10 -0
- package/src/templates/claude/commands/logs.md.tmpl +10 -0
- package/src/templates/claude/commands/restart.md.tmpl +10 -0
- package/src/templates/claude/commands/start.md.tmpl +12 -0
- package/src/templates/claude/commands/status.md.tmpl +10 -0
- package/src/templates/claude/commands/stop.md.tmpl +10 -0
- package/src/templates/claude/commands/up.md.tmpl +10 -0
- package/src/templates/claude/commands/wait.md.tmpl +10 -0
- package/src/templates/claude/commands/why.md.tmpl +10 -0
- package/src/templates/claude/skill.md.tmpl +44 -0
- package/src/templates/presets/nx-fullstack.json +10 -0
- package/src/templates/presets/vite-storybook.json +9 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var Es=Object.defineProperty;var R=(r,t)=>()=>(r&&(t=r(r=0)),t);var Ct=(r,t)=>{for(var e in t)Es(r,e,{get:t[e],enumerable:!0})};import st from"node:fs";import et from"node:path";import Pt from"node:os";import{fileURLToPath as As}from"node:url";function fn(){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:et.join(Pt.homedir(),".daimon","logs"),maxFiles:5,maxBytesPerFile:1e7},depends:{},cascadeRestart:!1,history:{enabled:!0,path:et.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}}function dn(r){return r.startsWith("~/")||r.startsWith("~\\")?et.join(Pt.homedir(),r.slice(2)):r==="~"?Pt.homedir():r}function ve(r,t){return we(r,t)}function we(r,t){if(!r||typeof r!="object")throw new Error(`Config at ${t} is not a JSON object`);let e=r,n=fn();if(e.searchRoots!==void 0){if(!Array.isArray(e.searchRoots)||!e.searchRoots.every(s=>typeof s=="string"||s&&typeof s=="object"&&typeof s.path=="string"))throw new Error(`Config "searchRoots" must be an array of strings or { path, viteSubfolders? } objects (${t})`);n.searchRoots=e.searchRoots}if(e.portRange!==void 0){if(!Array.isArray(e.portRange)||e.portRange.length!==2||typeof e.portRange[0]!="number"||typeof e.portRange[1]!="number"||e.portRange[0]>e.portRange[1])throw new Error(`Config "portRange" must be [min, max] numbers (${t})`);n.portRange=[e.portRange[0],e.portRange[1]]}if(e.apiPort!==void 0){if(typeof e.apiPort!="number")throw new Error(`Config "apiPort" must be a number (${t})`);n.apiPort=e.apiPort}if(e.overrides!==void 0){if(typeof e.overrides!="object"||e.overrides===null||Array.isArray(e.overrides))throw new Error(`Config "overrides" must be an object (${t})`);n.overrides=e.overrides}if(e.autoStart!==void 0){if(!Array.isArray(e.autoStart)||!e.autoStart.every(s=>typeof s=="string"))throw new Error(`Config "autoStart" must be an array of strings (${t})`);n.autoStart=e.autoStart}if(e.profiles!==void 0){if(typeof e.profiles!="object"||e.profiles===null||Array.isArray(e.profiles))throw new Error(`Config "profiles" must be an object (${t})`);for(let[s,o]of Object.entries(e.profiles))if(!Array.isArray(o)||!o.every(i=>typeof i=="string"))throw new Error(`Config "profiles.${s}" must be an array of strings (${t})`);n.profiles=e.profiles}if(e.tags!==void 0){if(typeof e.tags!="object"||e.tags===null||Array.isArray(e.tags))throw new Error(`Config "tags" must be an object (${t})`);n.tags=e.tags}if(e.autoRestart&&typeof e.autoRestart=="object"&&(n.autoRestart={...n.autoRestart,...e.autoRestart}),e.healthProbe&&typeof e.healthProbe=="object"&&(n.healthProbe={...n.healthProbe,...e.healthProbe}),e.logs&&typeof e.logs=="object"&&(n.logs={...n.logs,...e.logs},n.logs.dir=dn(n.logs.dir)),e.depends&&typeof e.depends=="object"&&!Array.isArray(e.depends)){for(let[s,o]of Object.entries(e.depends))if(!Array.isArray(o)||!o.every(i=>typeof i=="string"))throw new Error(`Config "depends.${s}" must be an array of strings (${t})`);n.depends=e.depends}if(typeof e.cascadeRestart=="boolean"&&(n.cascadeRestart=e.cascadeRestart),e.history&&typeof e.history=="object"&&(n.history={...n.history,...e.history},n.history.path=dn(n.history.path)),e.notifications&&typeof e.notifications=="object"&&(n.notifications={...n.notifications,...e.notifications}),e.staleDetect&&typeof e.staleDetect=="object"&&(n.staleDetect={...n.staleDetect,...e.staleDetect}),typeof e.headless=="boolean"&&(n.headless=e.headless),e.envFiles&&typeof e.envFiles=="object"&&!Array.isArray(e.envFiles)&&(n.envFiles=e.envFiles),e.requestLog&&typeof e.requestLog=="object"&&(n.requestLog={...n.requestLog,...e.requestLog}),e.metrics&&typeof e.metrics=="object"&&(n.metrics={...n.metrics,...e.metrics}),e.editor&&typeof e.editor=="object"){let s=e.editor.scheme;typeof s=="string"&&s.trim()&&(n.editor={scheme:s.trim()})}return(typeof e.apiToken=="string"||e.apiToken===null)&&(n.apiToken=e.apiToken),n}function be(){return{local:et.join(process.cwd(),"daimon.config.json"),user:et.join(Pt.homedir(),".daimon","config.json")}}function ft(){let{local:r,user:t}=be();if(st.existsSync(r)){let s=JSON.parse(st.readFileSync(r,"utf8"));return{kind:"loaded",config:we(s,r),path:r}}if(st.existsSync(t)){let s=JSON.parse(st.readFileSync(t,"utf8"));return{kind:"loaded",config:we(s,t),path:t}}let n=[et.resolve(pn,"..","daimon.config.example.json"),et.resolve(pn,"..","..","daimon.config.example.json")].find(s=>st.existsSync(s));return st.mkdirSync(et.dirname(t),{recursive:!0}),n?st.copyFileSync(n,t):st.writeFileSync(t,JSON.stringify(fn(),null,2)+`
|
|
3
|
+
`,"utf8"),{kind:"stub-created",path:t}}var Cs,pn,It=R(()=>{"use strict";Cs=As(import.meta.url),pn=et.dirname(Cs)});import Ot from"node:fs";import z from"node:path";import Se from"fast-glob";function mn(r){try{return JSON.parse(Ot.readFileSync(r,"utf8"))}catch{return null}}function hn(r){return!r||typeof r!="object"?!1:!!(r.targets?.serve||r.architect?.serve)}function gn(r){if(!r||typeof r!="object")return[];let t=r.targets??r.architect??{};return Object.keys(t).filter(e=>e!=="serve").sort()}function ke(r){return r.replace(/\\/g,"/")}function mt(r,t={}){let e=new Map,n=t.warnings??[],s=t.warnings===void 0;for(let o of r.searchRoots){let i=typeof o=="string"?o:o.path,a=typeof o=="string"?!1:!!o.viteSubfolders,c=typeof o=="string"?void 0:o.label,l=z.resolve(i);if(!Ot.existsSync(l)){n.push(`searchRoot does not exist: ${l}`);continue}let d=z.join(l,"nx.json"),p=z.join(l,"angular.json");if(Ot.existsSync(d)){let m=Se.sync("**/project.json",{cwd:ke(l),ignore:["**/node_modules/**","**/dist/**","**/.nx/**","**/.git/**"],absolute:!0,dot:!1});for(let y of m){let f=mn(y);if(!f||!hn(f))continue;let b=f.name||z.basename(z.dirname(y));if(b){if(e.has(b)){n.push(`duplicate project name "${b}" \u2014 keeping first`);continue}e.set(b,{name:b,workspaceRoot:l,workspaceType:"nx",command:`npx nx serve ${b}`,hidden:!1,tags:[],tasks:gn(f),workspaceLabel:c})}}continue}if(Ot.existsSync(p)){let y=mn(p)?.projects||{};for(let[f,b]of Object.entries(y))if(hn(b)){if(e.has(f)){n.push(`duplicate project name "${f}" \u2014 keeping first`);continue}e.set(f,{name:f,workspaceRoot:l,workspaceType:"angular",command:`npx ng serve ${f}`,hidden:!1,tags:[],tasks:gn(b),workspaceLabel:c})}continue}let g=Se.sync("vite.config.{ts,js,mjs,cjs}",{cwd:ke(l),absolute:!0,deep:1}),w=Ot.existsSync(z.join(l,".storybook")),u=!1;if(g.length>0){let m=z.basename(l);if(e.has(m)||e.set(m,{name:m,workspaceRoot:l,workspaceType:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:c}),u=!0,a){let y=Se.sync("*/vite.config.{ts,js,mjs,cjs}",{cwd:ke(l),absolute:!0});for(let f of y){let b=z.dirname(f),O=z.basename(b);O===m||e.has(O)||e.set(O,{name:O,workspaceRoot:b,workspaceType:"vite",command:"npx vite",hidden:!1,tags:[],workspaceLabel:c})}}}if(w){let m=`${z.basename(l)}-storybook`;e.has(m)||e.set(m,{name:m,workspaceRoot:l,workspaceType:"storybook",command:"npx storybook dev --no-open",hidden:!1,tags:[],workspaceLabel:c}),u=!0}u||n.push(`searchRoot has none of nx.json/angular.json/vite.config.*/.storybook: ${l}`)}for(let[o,i]of Object.entries(r.overrides||{})){let a=e.get(o);a?(i.command&&(a.command=i.command),typeof i.hidden=="boolean"&&(a.hidden=i.hidden),typeof i.port=="number"&&(a.pinnedPort=i.port),i.env&&(a.env=i.env)):i.command&&e.set(o,{name:o,workspaceRoot:process.cwd(),workspaceType:"nx",command:i.command,hidden:i.hidden??!1,pinnedPort:i.port,env:i.env,tags:[]})}for(let o of e.values())o.tags=r.tags?.[o.name]??[];if(s&&n.length)for(let o of n)process.stderr.write(`[daimon] warning: ${o}
|
|
4
|
+
`);return[...e.values()].filter(o=>!o.hidden)}var Lt=R(()=>{"use strict"});function _t(r){let s=new Map,o=new Map,i=null,a=c=>{if(!i){s.set(c,1);for(let l of r[c]||[]){let d=s.get(l)??0;if(d===1){let p=[l,c],g=o.get(c);for(;g&&g!==l;)p.push(g),g=o.get(g);g===l&&p.push(l),i=p.reverse();return}if(d===0&&(o.set(l,c),a(l),i))return}s.set(c,2)}};for(let c of Object.keys(r))if((s.get(c)??0)===0&&(o.set(c,null),a(c),i))return i;return null}function yn(r,t){let e=new Set,n=[t];for(;n.length;){let s=n.pop();if(!e.has(s)){e.add(s);for(let o of r[s]||[])n.push(o)}}return[...e]}function wn(r,t){let e=new Set(t),n=new Map,s=new Map;for(let a of t)n.set(a,0),s.set(a,[]);for(let a of t)for(let c of r[a]||[])e.has(c)&&(s.get(c).push(a),n.set(a,(n.get(a)??0)+1));let o=[],i=t.filter(a=>(n.get(a)??0)===0);for(;i.length;){o.push([...i].sort());let a=[];for(let c of i)for(let l of s.get(c)??[])n.set(l,(n.get(l)??1)-1),n.get(l)===0&&a.push(l);i=a}return o}function vn(r,t){let e=[];for(let[n,s]of Object.entries(r))s.includes(t)&&e.push(n);return e}var Ft=R(()=>{"use strict"});import Ps from"node:net";function gt(r){return new Promise(t=>{let e=Ps.createServer();e.unref(),e.once("error",()=>t(!1)),e.listen({port:r,host:"127.0.0.1",exclusive:!0},()=>{e.close(()=>t(!0))})})}var ht,Bt=R(()=>{"use strict";ht=class{assigned=new Map;min;max;onChange;constructor(t,e={}){if(this.min=t[0],this.max=t[1],this.onChange=e.onChange,e.initial){let n=new Set;for(let[s,o]of Object.entries(e.initial))typeof o=="number"&&(o<this.min||o>this.max||n.has(o)||(n.add(o),this.assigned.set(s,o)))}}snapshot(){return Object.fromEntries(this.assigned)}getAssigned(t){return this.assigned.get(t)}pin(t,e){this.assigned.set(t,e),this.onChange?.(this.snapshot())}async allocate(t,e){let n=this.assigned.get(t);if(e!==void 0)return this.assigned.set(t,e),this.onChange?.(this.snapshot()),e;if(n!==void 0)return n;let s=new Set(this.assigned.values());for(let o=this.min;o<=this.max;o++){if(s.has(o))continue;if(await gt(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 gt(t)}}});import Os from"node:fs";import Rs from"node:path";import{createRequire as Ns}from"node:module";var $s,Ds,Ms,js,yt,xe=R(()=>{"use strict";$s=Ns(import.meta.url),Ds=200,Ms=360*60*1e3,js=1e4,yt=class{constructor(t){this.cfg=t;if(t.enabled)try{Os.mkdirSync(Rs.dirname(t.path),{recursive:!0});let e=$s("better-sqlite3");this.db=new e(t.path),this.db.pragma("journal_mode = WAL"),this.migrate(),this.flushTimer=setInterval(()=>this.flush(),Ds),this.retentionStart=setTimeout(()=>this.runRetention(),js),this.retentionTimer=setInterval(()=>this.runRetention(),Ms)}catch(e){this.warnOnce(`failed to open history db: ${e?.message||e}`),this.db=null}}cfg;db=null;queue=[];flushTimer=null;retentionTimer=null;retentionStart=null;warned=!1;warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] history: ${t}
|
|
5
|
+
`))}migrate(){this.db&&this.db.exec(`
|
|
6
|
+
CREATE TABLE IF NOT EXISTS events (
|
|
7
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
8
|
+
ts INTEGER NOT NULL,
|
|
9
|
+
app TEXT NOT NULL,
|
|
10
|
+
type TEXT NOT NULL,
|
|
11
|
+
from_state TEXT,
|
|
12
|
+
to_state TEXT,
|
|
13
|
+
message TEXT
|
|
14
|
+
);
|
|
15
|
+
CREATE INDEX IF NOT EXISTS events_ts_app ON events(ts, app);
|
|
16
|
+
CREATE TABLE IF NOT EXISTS compile_times (
|
|
17
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
18
|
+
ts INTEGER NOT NULL,
|
|
19
|
+
app TEXT NOT NULL,
|
|
20
|
+
ms INTEGER NOT NULL
|
|
21
|
+
);
|
|
22
|
+
CREATE INDEX IF NOT EXISTS compile_app_ts ON compile_times(app, ts);
|
|
23
|
+
CREATE TABLE IF NOT EXISTS task_runs (
|
|
24
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
25
|
+
ts INTEGER NOT NULL,
|
|
26
|
+
app TEXT NOT NULL,
|
|
27
|
+
task TEXT NOT NULL,
|
|
28
|
+
exit_code INTEGER,
|
|
29
|
+
duration_ms INTEGER,
|
|
30
|
+
summary TEXT
|
|
31
|
+
);
|
|
32
|
+
CREATE INDEX IF NOT EXISTS task_runs_app_ts ON task_runs(app, ts);
|
|
33
|
+
`)}recordEvent(t){this.db&&this.queue.push({kind:"event",row:{ts:t.ts,app:t.app,type:t.type,from_state:t.from??null,to_state:t.to??null,message:t.message??null}})}recordCompile(t,e,n=Date.now()){this.db&&this.queue.push({kind:"compile",row:{ts:n,app:t,ms:e}})}recordTaskRun(t,e,n,s,o,i=Date.now()){this.db&&this.queue.push({kind:"task",row:{ts:i,app:t,task:e,exit_code:n,duration_ms:s,summary:o==null?null:JSON.stringify(o)}})}flush(){if(!this.db||this.queue.length===0)return;let t=this.queue;this.queue=[];try{let e=this.db.prepare("INSERT INTO events (ts,app,type,from_state,to_state,message) VALUES (?,?,?,?,?,?)"),n=this.db.prepare("INSERT INTO compile_times (ts,app,ms) VALUES (?,?,?)"),s=this.db.prepare("INSERT INTO task_runs (ts,app,task,exit_code,duration_ms,summary) VALUES (?,?,?,?,?,?)");this.db.transaction(i=>{for(let a of i)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"?n.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=[],n=[];t.app&&(e.push("app = ?"),n.push(t.app)),t.since!=null&&(e.push("ts >= ?"),n.push(t.since)),t.until!=null&&(e.push("ts <= ?"),n.push(t.until)),t.type&&(e.push("type = ?"),n.push(t.type));let s=`SELECT * FROM events ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??500),this.db.prepare(s).all(...n)}queryCompiles(t){if(!this.db)return[];let e=[],n=[];t.app&&(e.push("app = ?"),n.push(t.app)),t.since!=null&&(e.push("ts >= ?"),n.push(t.since)),t.until!=null&&(e.push("ts <= ?"),n.push(t.until));let s=`SELECT * FROM compile_times ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??1e3),this.db.prepare(s).all(...n)}queryTasks(t){if(!this.db)return[];let e=[],n=[];t.app&&(e.push("app = ?"),n.push(t.app)),t.task&&(e.push("task = ?"),n.push(t.task)),t.since!=null&&(e.push("ts >= ?"),n.push(t.since));let s=`SELECT * FROM task_runs ${e.length?"WHERE "+e.join(" AND "):""} ORDER BY ts DESC LIMIT ?`;return n.push(t.limit??200),this.db.prepare(s).all(...n)}summary(t){if(!this.db)return{uptimePct24h:0,restartCount24h:0,compileP50:null,compileP95:null,topErrors:[]};let e=Date.now()-24*3600*1e3,n=this.queryEvents({app:t,since:e,limit:5e3}),s=0,o=e,i=!1,a=null,c=[...n].sort((f,b)=>f.ts-b.ts);for(let f of c)f.type==="status"&&(f.to_state==="serving"&&!i?(i=!0,a=f.ts):i&&f.to_state!=="serving"&&a!=null&&(s+=f.ts-a,i=!1,a=null));i&&a!=null&&(s+=Date.now()-a);let l=Math.round(s/(24*3600*1e3)*1e3)/10,d=n.filter(f=>f.type==="status"&&f.to_state==="starting"&&(f.from_state==="serving"||f.from_state==="error"||f.from_state==="compiling")).length,p=this.queryCompiles({app:t,since:e,limit:1e3}).map(f=>f.ms).sort((f,b)=>f-b),g=(f,b)=>{if(f.length===0)return null;let O=Math.min(f.length-1,Math.floor((f.length-1)*b));return f[O]},w=g(p,.5),u=g(p,.95),m=new Map;for(let f of n)if(f.type==="error-new"||f.type==="error-recur"){let b=f.message??"";if(!b)continue;m.set(b,(m.get(b)??0)+1)}let y=[...m.entries()].sort((f,b)=>b[1]-f[1]).slice(0,5).map(([f,b])=>({message:f,count:b}));return{uptimePct24h:l,restartCount24h:d,compileP50:w,compileP95:u,topErrors:y}}why(t){let e=this.queryEvents({app:t,limit:200}),n=e.find(a=>a.type==="status"&&(a.to_state==="error"||a.from_state==="error"||a.to_state==="serving")),s=n?{ts:n.ts,app:n.app,type:n.type,from:n.from_state??void 0,to:n.to_state??void 0,message:n.message??void 0}:null,o=s?s.ts:Date.now(),i=e.filter(a=>a.ts<o).slice(0,5);return{trigger:s,preceding:i.map(a=>({ts:a.ts,app:a.app,type:a.type,from:a.from_state??void 0,to:a.to_state??void 0,message:a.message??void 0}))}}quickCheck(){if(!this.db)return!1;try{return this.db.prepare("PRAGMA quick_check").get()?.quick_check==="ok"}catch{return!1}}close(){if(this.flushTimer&&clearInterval(this.flushTimer),this.retentionTimer&&clearInterval(this.retentionTimer),this.retentionStart&&clearTimeout(this.retentionStart),this.flush(),this.db){try{this.db.close()}catch{}this.db=null}}}});import{spawnSync as Te}from"node:child_process";import Sn from"tree-kill";function Ht(r){if(process.platform==="win32"){let o=Te("powershell",["-NoProfile","-Command",`Get-NetTCPConnection -LocalPort ${r} -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty OwningProcess`],{encoding:"utf8",windowsHide:!0});if(o.status!==0)return null;let i=Number((o.stdout||"").trim().split(/\s+/)[0]);if(!Number.isFinite(i)||i<=0)return null;let a=Te("powershell",["-NoProfile","-Command",`Get-CimInstance Win32_Process -Filter "ProcessId=${i}" | Select-Object -Property Name,CommandLine | ConvertTo-Json -Compress`],{encoding:"utf8",windowsHide:!0}),c,l;try{let d=JSON.parse((a.stdout||"").trim()||"{}");c=typeof d.Name=="string"?d.Name:void 0,l=typeof d.CommandLine=="string"?d.CommandLine:void 0}catch{}return{pid:i,name:c,cmd:l}}let t=Te("lsof",["-nP","-iTCP:"+r,"-sTCP:LISTEN"],{encoding:"utf8"});if(t.status!==0)return null;let e=(t.stdout||"").split(/\r?\n/).filter(o=>o.trim()&&!o.startsWith("COMMAND"));if(!e.length)return null;let n=e[0].split(/\s+/);return{pid:Number(n[1]),name:n[0]}}function kn(r,t){if(!t)return`port ${r} already in use`;let e=[`port ${r} in use by`];return t.name&&e.push(t.name),e.push(`(pid ${t.pid}`),t.cmd&&(e[e.length-1]+=`, cmd: ${t.cmd.slice(0,120)}`),e[e.length-1]+=")",e.join(" ")}function xn(r){return new Promise(t=>{if(!r.pid||r.pid===process.pid){t(!1);return}Sn(r.pid,"SIGTERM",e=>{if(e){setTimeout(()=>Sn(r.pid,"SIGKILL",n=>t(!n)),500);return}t(!0)})})}var Ee=R(()=>{"use strict"});import Ut from"node:fs";import Is from"node:os";import Tn from"node:path";function En(r){return Ut.readFileSync(r,"utf8").split(/\r?\n/).filter(e=>e.trim()).map(e=>JSON.parse(e))}var Jt,Ae=R(()=>{"use strict";Jt=class{file=null;startTs=0;isRecording(){return this.file!=null}start(){if(this.file)return{path:this.file};let t=Tn.join(Is.homedir(),".daimon","sessions");Ut.mkdirSync(t,{recursive:!0});let e=Tn.join(t,`${new Date().toISOString().replace(/[:.]/g,"-")}.jsonl`);return Ut.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})+`
|
|
34
|
+
`;try{Ut.appendFileSync(this.file,e)}catch{}}}});import Ls from"node:fs";import Ce from"node:path";import{fileURLToPath as _s}from"node:url";function Fs(){let r=[Ce.resolve(An,"..","package.json"),Ce.resolve(An,"..","..","package.json")];for(let t of r)try{return JSON.parse(Ls.readFileSync(t,"utf8"))}catch{}return{}}var An,W,Rt=R(()=>{"use strict";An=Ce.dirname(_s(import.meta.url));W=Fs().version||"0.0.0"});import vt from"node:fs";import Gt from"node:path";import Bs from"node:os";import{spawn as Hs}from"node:child_process";import{fileURLToPath as Us}from"node:url";function q(){return Oe}function Pe(r){try{return process.kill(r,0),!0}catch(t){return t&&t.code==="EPERM"}}function nt(){try{let r=vt.readFileSync(Nt,"utf8"),t=JSON.parse(r);if(!t||typeof t.pid!="number")return null;if(!Pe(t.pid)){try{vt.unlinkSync(Nt)}catch{}return null}return t}catch{return null}}function Cn(r){vt.mkdirSync(Oe,{recursive:!0});let t=Nt+"."+process.pid+".tmp";vt.writeFileSync(t,JSON.stringify(r)),vt.renameSync(t,Nt)}function bt(){try{vt.unlinkSync(Nt)}catch{}}function Js(){let r=Gt.dirname(Us(import.meta.url));return Gt.join(r,"main.js")}async function Wt(r={}){let t={...process.env};r.port&&(t.DAIMON_PORT=String(r.port)),Hs(process.execPath,[Js(),"--headless"],{detached:!0,stdio:"ignore",env:t,windowsHide:!0}).unref();let n=Date.now();for(;Date.now()-n<5e3;){let s=nt();if(s&&(!r.port||s.apiPort===r.port))return s;await new Promise(o=>setTimeout(o,100))}throw new Error("daemon failed to start within 5s")}async function qt(r,t){let e=Date.now();for(;Date.now()-e<t;){if(!Pe(r))return!0;await new Promise(n=>setTimeout(n,100))}return!Pe(r)}function Pn(r,t){return{pid:process.pid,apiPort:r,version:W,startedAt:Date.now(),headless:t}}var Oe,Nt,rt=R(()=>{"use strict";Rt();Oe=Gt.join(Bs.homedir(),".daimon"),Nt=Gt.join(Oe,"daemon.lock")});var Fn={};Ct(Fn,{promptClaudeInstall:()=>Qs});import pt,{useState as Ln}from"react";import{Box as _n,render as Ks,Text as zt,useApp as Ys,useInput as zs}from"ink";function Vs({onDone:r}){let{exit:t}=Ys(),[e,n]=Ln(0),[s,o]=Ln({skill:!0,commands:!0,agent:!0}),i=[{key:"skill",label:"Skill (~/.claude/skills/daimon/SKILL.md)"},{key:"commands",label:"Slash commands (~/.claude/commands/daimon-*.md)"},{key:"agent",label:"Subagent (~/.claude/agents/daimon-runner.md)"}];return zs((a,c)=>{if(c.escape||a==="q"&&!c.shift){r(null),t();return}if(c.upArrow)n(l=>Math.max(0,l-1));else if(c.downArrow)n(l=>Math.min(i.length-1,l+1));else if(a===" "){let l=i[e].key;o(d=>({...d,[l]:!d[l]}))}else c.return&&(r(s),t())}),pt.createElement(_n,{flexDirection:"column",paddingX:1},pt.createElement(zt,{bold:!0,color:"cyan"},"Install Claude Code integration artifacts"),pt.createElement(zt,{dimColor:!0},"Space toggles \xB7 Enter confirms \xB7 Esc cancels"),i.map((a,c)=>pt.createElement(_n,{key:a.key},pt.createElement(zt,{color:c===e?"cyan":void 0},c===e?"\u25B8 ":" "),pt.createElement(zt,null,"[",s[a.key]?"x":" ","] ",a.label))))}async function Qs(){return new Promise(r=>{let t=!1;Ks(pt.createElement(Vs,{onDone:n=>{t||(t=!0,r(n))}})).waitUntilExit().then(()=>{t||(t=!0,r(null))})})}var Bn=R(()=>{"use strict"});import Zs from"node:crypto";function ho(r){return Zs.createHash("sha1").update(r).digest("hex").slice(0,16)}function go(r){let t={message:r},e=r.match(so)||r.match(ro);e&&(t.code=`TS${e[1]}`);let n=r.match(oo);return n&&(t.file=n[1],t.line=Number(n[2]),t.col=Number(n[3])),t}function yo(r,t){try{let e=new URL(r);return e.hostname==="0.0.0.0"||e.hostname==="[::]"?(e.hostname=t.includes(":")?`[${t}]`:t,e.toString().replace(/\/$/,"")):r.replace(/\/$/,"")}catch{return r}}function wo(r,t="127.0.0.1"){let e=r.match(io)||r.match(ao)||r.match(lo)||r.match(co);if(!e)return null;let n=e[1].replace(/[),.;]+$/,"");return yo(n,t)}function vo(r,t){if(uo.test(t))return r.bundle||(r.bundle={initialKB:0,lazyKB:0,files:[]}),r._bundleSection="initial",!1;if(po.test(t))return r.bundle||(r.bundle={initialKB:0,lazyKB:0,files:[]}),r._bundleSection="lazy",!1;let e=t.match(fo);if(e&&r.bundle){let s=parseFloat(e[2]),o=e[3].toUpperCase(),i=Math.round(o==="MB"?s*1024:o==="B"?s/1024:s);return/Initial/i.test(e[1])?r.bundle.initialKB=i:r.bundle.lazyKB=i,!0}let n=t.match(mo);if(n&&r.bundle){let s=n[1].trim();if(/^(Initial|Lazy)\s+(total|chunk)/i.test(s))return!1;let o=n[4].toUpperCase(),i=parseFloat(n[3]),a=o==="MB"?i*1024:o==="B"?i/1024:i;return r.bundle.files.push({name:s,sizeKB:Math.round(a*10)/10}),!1}return!1}function Hn(r,t){let e=t.trim();if(!e)return null;let n=r.status,s=!1,o,i=wo(e);i&&!r.announcedUrl&&(r.announcedUrl=i,o=i);let a=vo(r,e),c;if(to.some(d=>d.test(e))){let d=r.status==="error"||!!r.recoveringFromError;if(r.status==="compiling"||r.status==="starting"||r.status==="error"){let p=Date.now();r.compileStartedAt!=null?(c=p-r.compileStartedAt,r.lastCompileMs=c,r.lastCompileAt=p,r.compileStartedAt=null,r.compileHistory.push(c),r.compileHistory.length>20&&r.compileHistory.splice(0,r.compileHistory.length-20)):r.lastCompileAt=p}r.status="serving",d&&(r.errors.clear(),r.recoveringFromError=!1)}else eo.some(d=>d.test(e))&&(r.status==="starting"||r.status==="serving"||r.status==="error")&&(r.status==="error"&&(r.recoveringFromError=!0),r.compileStartedAt=Date.now(),r.status="compiling");let l;if(no.some(d=>d.test(e))){let d=ho(e),p=Date.now(),g=r.errors.get(d),w=!1,u;g?(g.count+=1,g.lastSeen=p,u=g):(u={message:e,count:1,firstSeen:p,lastSeen:p,parsed:go(e)},r.errors.set(d,u),w=!0),l={entry:u,isNew:w},r.status="error"}return s=r.status!==n,{statusChanged:s,error:l,announcedUrl:o,bundleUpdated:a,compileMs:c}}var to,eo,no,ro,so,oo,io,ao,lo,co,uo,po,fo,mo,Un=R(()=>{"use strict";to=[/Local:\s+http/i,/Application bundle generation complete/i,/compiled successfully/i,/webpack compiled/i,/Angular Live Development Server is listening/i],eo=[/Building\.\.\./i,/Compilation started/i,/Initial chunk files/i,/Compiling/i],no=[/^\s*ERROR\b/,/\berror TS\d+/,/✘/,/\[ERROR\]/,/Cannot find module/i],ro=/\berror TS(\d+)/,so=/✘\s*\[ERROR\]\s*TS(\d+)/,oo=/([A-Z]:[\\/][^\s:()]+|[^\s:()]+\.(?:tsx?|jsx?|mjs|cjs|vue|svelte)):(\d+):(\d+)/,io=/Local:\s+(https?:\/\/\S+)/i,ao=/Server running at\s+(https?:\/\/\S+)/i,lo=/listening on\s+(https?:\/\/\S+)/i,co=/(?:listening|listen)\s+(https?:\/\/\S+)/i,uo=/Initial chunk files/i,po=/Lazy chunk files/i,fo=/(Initial total|Lazy total)\s*\|?\s*([\d.]+)\s*(kB|MB|B)\b/i,mo=/^\s*\|?\s*([^\s|][^|]*?)\s*\|\s*([^|]+?)\s*\|\s*([\d.]+)\s*(kB|MB|B)\b/i});import{spawn as bo}from"node:child_process";import Jn from"tree-kill";import So from"strip-ansi";var Gn,Vt,Wn=R(()=>{"use strict";Un();Gn=500,Vt=class{child=null;stdoutBuf="";stderrBuf="";deps;stopping=!1;constructor(t){this.deps=t}isRunning(){return this.child!==null&&this.child.exitCode===null&&!this.stopping}start(){if(this.isRunning())return;let{app:t,port:e,state:n}=this.deps,s=Date.now();n.status="starting",n.startedAt=s,n.compileStartedAt=s,n.lastCompileMs=null,n.lastCompileAt=null,n.errors.clear(),n.logBuffer.length=0,n.lastStatusMessage=void 0;let i=`${this.deps.commandOverride||t.command} --port ${e}`,a={...process.env,...t.env||{},...this.deps.envOverride||{},PORT:String(e),FORCE_COLOR:"0"},c=bo(i,[],{cwd:t.workspaceRoot,shell:!0,env:a,windowsHide:!0});this.child=c,n.pid=c.pid??null,n.port=e,c.stdout?.on("data",l=>this.handleChunk(l,"stdout")),c.stderr?.on("data",l=>this.handleChunk(l,"stderr")),c.on("exit",(l,d)=>{let p=n.status,g=this.stopping;g?(n.status="stopped",n.lastStatusMessage=`stopped (code=${l??"null"}${d?`, ${d}`:""})`):l!==0?(n.status="error",n.lastStatusMessage=`process exited with code ${l}${d?` (${d})`:""}`):n.status="stopped",n.pid=null,n.health="unknown",this.child=null,this.stopping=!1,p!==n.status&&this.deps.onStatusChange?.(p,n.status,n.lastStatusMessage),this.deps.onExit?.(l,d,g),this.deps.onStateChange()}),c.on("error",l=>{n.status="error",n.lastStatusMessage=`spawn error: ${l.message}`,this.deps.onStateChange()}),this.deps.onStateChange()}handleChunk(t,e){let n=t.toString("utf8"),s=this[e==="stdout"?"stdoutBuf":"stderrBuf"]+=n,o=s.lastIndexOf(`
|
|
35
|
+
`);if(o<0)return;let i=s.slice(0,o),a=s.slice(o+1);e==="stdout"?this.stdoutBuf=a:this.stderrBuf=a;let{state:c}=this.deps,l=!1;for(let d of i.split(/\r?\n/)){if(!d.length)continue;let p=So(d),g=Date.now();c.lastLogTs=g,c.stale&&(c.stale=!1),c.logBuffer.push({ts:g,line:p}),c.logBuffer.length>Gn&&c.logBuffer.splice(0,c.logBuffer.length-Gn),this.deps.onLogLine?.(p);let w=c.status,u=Hn(c,p);u?.statusChanged&&(l=!0,this.deps.onStatusChange?.(w,c.status)),u?.error&&this.deps.onErrorRecorded?.(u.error.entry,u.error.isNew),u?.compileMs!=null&&this.deps.onCompile?.(u.compileMs),u?.bundleUpdated&&this.deps.onBundleUpdate?.()}(l||i.length>0)&&this.deps.onStateChange()}async stop(){if(!this.child||this.stopping)return;this.stopping=!0;let t=this.child.pid;if(!t){this.child=null,this.stopping=!1;return}await new Promise(e=>{let n=!1,s=()=>{n||(n=!0,e())},o=()=>s();this.child?.once("exit",o),Jn(t,"SIGTERM",()=>{});let i=setTimeout(()=>{Jn(t,"SIGKILL",()=>{})},2e3),a=setTimeout(()=>{clearTimeout(i),s()},3e3);this.child?.once("exit",()=>{clearTimeout(i),clearTimeout(a),s()})})}}});import V from"node:fs";import ko from"node:path";var Qt,qn=R(()=>{"use strict";Qt=class{constructor(t,e){this.appName=t;this.cfg=e;this.filePath=ko.join(e.dir,`${t}.log`),this.open()}appName;cfg;fd=null;bytes=0;warned=!1;filePath;open(){try{V.mkdirSync(this.cfg.dir,{recursive:!0});try{this.bytes=V.statSync(this.filePath).size}catch{this.bytes=0}this.fd=V.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}
|
|
36
|
+
`,n=Buffer.from(e,"utf8");V.writeSync(this.fd,n),this.bytes+=n.length,this.bytes>=this.cfg.maxBytesPerFile&&this.rotate()}catch(e){this.warn(`write failed: ${e.message}`)}}close(){if(this.fd!=null){try{V.closeSync(this.fd)}catch{}this.fd=null}}rotate(){try{this.close();for(let t=this.cfg.maxFiles-1;t>=1;t--){let e=`${this.filePath}.${t}`,n=`${this.filePath}.${t+1}`;if(t+1>this.cfg.maxFiles-1){try{V.rmSync(e,{force:!0})}catch{}continue}try{V.existsSync(e)&&V.renameSync(e,n)}catch{}}try{let t=`${this.filePath}.1`;V.existsSync(this.filePath)&&V.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}
|
|
37
|
+
`))}}});import{spawn as Kn}from"node:child_process";import Xn from"tree-kill";import Yn from"strip-ansi";function Ao(r){let t=r.match(xo);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=r.match(To);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 n=r.match(Eo);if(n){let s=Number(n[1]),o=n[2]?Number(n[2]):0;return{passed:s,failed:o,total:s+o}}return null}function zn(r,t,e){let n=e.length?" -- "+e.join(" "):"";return r.workspaceType==="nx"?`npx nx run ${r.name}:${t}${n}`:r.workspaceType==="angular"?`npx ng run ${r.name}:${t}${n}`:`npx ${t}${n}`}function Vn(r,t,e=[]){return new Promise(n=>{let s=Date.now(),o=zn(r,t,e),i=Kn(o,[],{cwd:r.workspaceRoot,shell:!0,env:{...process.env,...r.env||{},FORCE_COLOR:"0"},windowsHide:!0}),a=[],c="",l=d=>{c+=d.toString("utf8");let p=c.lastIndexOf(`
|
|
38
|
+
`);if(p<0)return;let g=c.slice(0,p);c=c.slice(p+1);for(let w of g.split(/\r?\n/)){if(!w.length)continue;let u=Yn(w);a.push(u),a.length>1e3&&a.splice(0,a.length-1e3)}};i.stdout?.on("data",l),i.stderr?.on("data",l),i.on("exit",d=>{let p=Date.now()-s,g=a.join(`
|
|
39
|
+
`)+(c?`
|
|
40
|
+
`+c:""),w=Ao(g);n({app:r.name,task:t,exitCode:d,durationMs:p,summary:w,outputTail:a.slice(-50)})}),i.on("error",()=>{n({app:r.name,task:t,exitCode:-1,durationMs:Date.now()-s,summary:null,outputTail:[...a,"[daimon] task spawn error"]})})})}function Qn(r,t,e=[]){let n=zn(r,t,e),s=Kn(n,[],{cwd:r.workspaceRoot,shell:!0,env:{...process.env,...r.env||{},FORCE_COLOR:"0"},windowsHide:!0}),o=[],i="",a=l=>{i+=l.toString("utf8");let d=i.lastIndexOf(`
|
|
41
|
+
`);if(d<0)return;let p=i.slice(0,d);i=i.slice(d+1);for(let g of p.split(/\r?\n/))g.length&&(o.push(Yn(g)),o.length>500&&o.splice(0,o.length-500))};return s.stdout?.on("data",a),s.stderr?.on("data",a),{app:r.name,task:t,pid:s.pid??null,child:s,startedAt:Date.now(),logs:o,stop:()=>new Promise(l=>{if(!s.pid){l();return}let d=!1,p=()=>{d||(d=!0,l())};s.once("exit",p),Xn(s.pid,"SIGTERM",()=>{}),setTimeout(()=>{s.pid&&Xn(s.pid,"SIGKILL",()=>{})},2e3),setTimeout(p,3500)})}}var xo,To,Eo,Zn=R(()=>{"use strict";xo=/Tests:\s+(?:(\d+)\s+failed,\s+)?(\d+)\s+passed(?:,\s+(\d+)\s+total)?/,To=/Executed (\d+) of (\d+)(?:\s*\((\d+)\s*FAILED\))?/,Eo=/(\d+)\s+passed(?:.*?(\d+)\s+failed)?/i});import er from"node:fs";import tr from"node:path";function nr(r){let t={},e;try{e=er.readFileSync(r,"utf8")}catch{return t}for(let n of e.split(/\r?\n/)){let s=n.trim();if(!s||s.startsWith("#"))continue;let o=s.indexOf("=");if(o<0)continue;let 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 Me(r,t){return tr.isAbsolute(t)?t:tr.join(r,t)}function je(r,t){return t.filter(e=>er.existsSync(Me(r,e)))}var rr=R(()=>{"use strict"});import Co from"node:fs";import Po from"node:path";function Oo(){return Po.join(q(),"secrets.json")}function sr(){try{let r=Co.readFileSync(Oo(),"utf8");r.charCodeAt(0)===65279&&(r=r.slice(1));let t=JSON.parse(r);if(!t||typeof t!="object")return{};let e={};for(let[n,s]of Object.entries(t))typeof s=="string"&&(e[n]=s);return e}catch{return{}}}function or(r,t){let e={};for(let[n,s]of Object.entries(r))e[n]=s.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,(o,i)=>t[i]??`\${${i}}`);return e}var ir=R(()=>{"use strict";rt()});import{EventEmitter as Ro}from"node:events";var ar,Zt,lr=R(()=>{"use strict";Wn();Bt();qn();Ft();Zn();Ee();rr();ir();Ae();ar=500,Zt=class extends Ro{entries=new Map;portAlloc;config;eventBuffer=[];history=null;watchTasks=new Map;sessionRecorder=new Jt;constructor(t,e,n){super(),this.config=t,this.portAlloc=n??new ht(t.portRange);for(let s of e)this.entries.set(s.name,{app:s,state:this.freshState(s.name,s.tags,s.workspaceLabel??null),proc:null})}getConfig(){return this.config}addDiscoveredApp(t){this.entries.has(t.name)||(this.entries.set(t.name,{app:t,state:this.freshState(t.name,t.tags,t.workspaceLabel??null),proc:null}),this.emit("change"))}updateDiscoveredApp(t){let e=this.entries.get(t.name);e&&(e.app=t,e.state.tags=t.tags,e.state.workspaceLabel=t.workspaceLabel??null,e.state.dependsOn=this.config.depends?.[t.name]??[],this.emit("change"))}getPortAllocator(){return this.portAlloc}setHistory(t){this.history=t}getHistory(){return this.history}freshState(t,e,n=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:n}}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 n=e.state,s=n.startedAt&&(n.status==="serving"||n.status==="compiling"||n.status==="starting")?Date.now()-n.startedAt:null,i=this.config.overrides?.[t]?.url||e.resolvedUrl||n.announcedUrl||(n.port?`http://127.0.0.1:${n.port}`:null);return{name:n.name,status:n.status,port:n.port,url:i,errorCount:[...n.errors.values()].reduce((a,c)=>a+c.count,0),uptimeMs:s,lastCompileMs:n.lastCompileMs,health:n.health,lastHealthAt:n.lastHealthAt,cpu:n.cpu,memMB:n.memMB,compileHistoryMs:[...n.compileHistory],tags:[...n.tags],restartAttempts:n.restartAttempts,nextRestartAt:n.nextRestartAt,announcedUrl:n.announcedUrl,lastHealthError:n.lastHealthError,stale:n.stale,bundle:n.bundle,bundleRegressionPct:n.bundleRegressionPct,dependsOn:[...n.dependsOn],activeEnvFile:n.activeEnvFile,workspaceLabel:n.workspaceLabel}}getState(t){return this.entries.get(t)?.state??null}getApp(t){return this.entries.get(t)?.app??null}errors(t){let e=this.getState(t);return e?[...e.errors.values()].sort((n,s)=>s.lastSeen-n.lastSeen):null}errorsSince(t,e){let n=this.getState(t);return n?[...n.errors.values()].filter(s=>s.lastSeen>e).sort((s,o)=>o.lastSeen-s.lastSeen):null}logs(t,e={}){let n=this.getState(t);if(!n)return null;let s=n.logBuffer;if(e.sinceMs&&e.sinceMs>0){let o=Date.now()-e.sinceMs;s=s.filter(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(n=>n.ts>=e&&(!t.app||n.app===t.app))}recordEvent(t){let e={ts:t.ts??Date.now(),...t};this.eventBuffer.push(e),this.eventBuffer.length>ar&&this.eventBuffer.splice(0,this.eventBuffer.length-ar),this.history?.recordEvent(e),this.emit("event",e)}setHealth(t,e){let n=this.entries.get(t);if(!n)return;let s=n.state;if(s.lastHealthAt=Date.now(),s.health===e)return;let o=s.health;s.health=e,e==="healthy"&&(n.prevHealthyAt=Date.now(),n.cascadeArmed&&(n.cascadeArmed=!1,this.triggerCascadeRestart(t))),this.recordEvent({app:t,type:"health",from:o,to:e}),this.emit("change")}armCascade(t){let e=this.entries.get(t);e&&this.config.cascadeRestart&&e.prevHealthyAt!=null&&(e.cascadeArmed=!0)}setLastHealthError(t,e){let n=this.getState(t);n&&n.lastHealthError!==e&&(n.lastHealthError=e,this.emit("change"))}setResolvedUrl(t,e){let n=this.entries.get(t);n&&n.resolvedUrl!==e&&(n.resolvedUrl=e,this.emit("change"))}setCachedProbeHost(t,e){let n=this.getState(t);n&&(n.cachedProbeHost=e)}setStale(t,e){let n=this.getState(t);n&&n.stale!==e&&(n.stale=e,this.emit("change"))}setSessionOverride(t,e){let n=this.getState(t);n&&(n.sessionOverrides=e,this.emit("change"))}setActiveEnvFile(t,e){let n=this.getState(t);n&&(n.activeEnvFile=e,this.emit("change"))}async start(t){this.sessionRecorder.append({kind:"start",app:t});let e=this.entries.get(t);if(!e)return{ok:!1,status:"unknown",error:"unknown app"};if(e.proc?.isRunning())return{ok:!0,status:e.state.status};let n=e.state.status,s;try{s=await this.portAlloc.allocate(t,e.app.pinnedPort)}catch(w){return e.state.status="error",e.state.lastStatusMessage=w.message,this.recordEvent({app:t,type:"status",from:n,to:"error",message:w.message}),this.emit("change"),{ok:!1,status:"error",error:w.message}}if(!await gt(s)){let w=Ht(s),u=kn(s,w);return e.state.status="error",e.state.port=s,e.state.lastStatusMessage=u,this.recordEvent({app:t,type:"status",from:n,to:"error",message:u}),this.emit("change"),{ok:!1,status:"error",error:u}}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 Qt(t,this.config.logs));let i=e.state.sessionOverrides,a=this.config.envFiles?.[t]??[],c={};if(a.length){let w=e.state.activeEnvFile;(!w||!je(e.app.workspaceRoot,[w]).length)&&(w=je(e.app.workspaceRoot,a)[0]??null,w&&(e.state.activeEnvFile=w)),w&&(c=nr(Me(e.app.workspaceRoot,w)))}let l={...c,...this.config.overrides?.[t]?.env??{},...i?.env??{}},d=sr(),p=or(l,d),g=new Vt({state:e.state,app:e.app,port:s,envOverride:Object.keys(p).length?p:void 0,commandOverride:i?.command,onStateChange:()=>this.emit("change"),onStatusChange:(w,u,m)=>{this.recordEvent({app:t,type:"status",from:w,to:u,message:m}),(u==="stopped"||u==="error")&&(w==="serving"||w==="compiling")&&this.armCascade(t)},onErrorRecorded:(w,u)=>this.recordEvent({app:t,type:u?"error-new":"error-recur",message:w.message}),onExit:(w,u,m)=>this.emit("childExit",{name:t,code:w,signal:u,stopping:m}),onLogLine:w=>{e.logger?.write(w),this.emit("log",{name:t,ts:Date.now(),line:w})},onCompile:w=>{this.history?.recordCompile(t,w);let u=this.getState(t),m=e.lastBundleInitialKB;if(u.bundle&&u.bundle.initialKB>0){if(m&&m>0){let y=(u.bundle.initialKB-m)/m*100;u.bundleRegressionPct=Math.round(y*10)/10,y>10&&this.recordEvent({app:t,type:"bundle-regression",message:`initialKB +${u.bundleRegressionPct}% (${m}->${u.bundle.initialKB})`})}else u.bundleRegressionPct=null;e.lastBundleInitialKB=u.bundle.initialKB}this.checkCompileRegression(t,w),this.emit("compile",{name:t,ms:w})},onBundleUpdate:()=>this.emit("bundleUpdate",{name:t})});return e.proc=g,this.recordEvent({app:t,type:"status",from:n,to:"starting"}),g.start(),{ok:!0,status:e.state.status}}async stop(t){this.sessionRecorder.append({kind:"stop",app:t});let e=this.entries.get(t);if(!e)return{ok:!1,status:"unknown",error:"unknown app"};if(this.emit("userStop",{name:t}),!e.proc||!e.proc.isRunning())return e.state.status!=="stopped"&&this.recordEvent({app:t,type:"status",from:e.state.status,to:"stopped"}),e.state.status="stopped",e.state.pid=null,e.state.health="unknown",this.emit("change"),{ok:!0,status:"stopped"};let n=e.state.status;return await e.proc.stop(),e.proc=null,e.state.status!==n&&this.recordEvent({app:t,type:"status",from:n,to:e.state.status}),{ok:!0,status:e.state.status}}async restart(t){return this.sessionRecorder.append({kind:"restart",app:t}),await this.stop(t),this.start(t)}async startWithDeps(t,e={}){if(!this.entries.has(t))return{ok:!1,results:[{name:t,status:"unknown",health:"unknown",error:"unknown app"}]};let n=yn(this.config.depends??{},t).filter(a=>this.entries.has(a)),s=wn(this.config.depends??{},n),o=[],i=e.waitMs??6e4;for(let a of s){let c=await Promise.all(a.map(d=>this.start(d)));for(let d=0;d<a.length;d++){let p=c[d];if(!p.ok)return o.push({name:a[d],status:p.status,health:"unknown",error:p.error}),{ok:!1,results:o}}let l=await Promise.all(a.map(d=>this.waitFor(d,"healthy",i)));for(let d=0;d<a.length;d++){let p=l[d],g=!p.timedOut&&p.status==="serving"&&p.health==="healthy";if(o.push({name:p.name,status:p.status,health:p.health,error:g?void 0:p.timedOut?"timeout waiting for healthy":"did not reach healthy"}),!g)return{ok:!1,results:o}}}return{ok:!0,results:o}}triggerCascadeRestart(t){if(!this.config.cascadeRestart)return;let e=vn(this.config.depends??{},t);for(let n of e){let s=this.getState(n);s&&(s.status==="serving"||s.status==="compiling"||s.status==="starting")&&this.restart(n)}}async stopAll(t=3e3){let e=[];for(let n of this.entries.values())n.proc?.isRunning()&&e.push(n.proc.stop());for(let n of this.watchTasks.values())e.push(n.stop());await Promise.race([Promise.all(e),new Promise(n=>setTimeout(n,t))]);for(let n of this.entries.values())n.logger?.close()}listTasks(t){let e=this.getApp(t);return e?[...e.tasks??[]]:null}async runTask(t,e,n=[]){this.sessionRecorder.append({kind:"run",app:t,task:e,args:n});let s=this.getApp(t);if(!s)return{error:"unknown app"};let o=await Vn(s,e,n);return this.history?.recordTaskRun(t,e,o.exitCode,o.durationMs,o.summary),this.recordEvent({app:t,type:"task-run",message:`${e} exit=${o.exitCode} duration=${o.durationMs}ms`}),this.emit("taskRun",{name:t,task:e,result:o}),o}startWatchTask(t,e,n=[]){let s=this.getApp(t);if(!s)return{ok:!1,error:"unknown app"};let o=`${t}::${e}`;if(this.watchTasks.has(o))return{ok:!0,pid:this.watchTasks.get(o).pid};let i=Qn(s,e,n);return this.watchTasks.set(o,i),i.child.on("exit",()=>this.watchTasks.delete(o)),{ok:!0,pid:i.pid}}async stopWatchTask(t,e){let n=`${t}::${e}`,s=this.watchTasks.get(n);return s?(await s.stop(),this.watchTasks.delete(n),{ok:!0}):{ok:!0}}listWatchTasks(t){let e=[];for(let n of this.watchTasks.values())t&&n.app!==t||e.push({app:n.app,task:n.task,pid:n.pid,startedAt:n.startedAt});return e}checkCompileRegression(t,e){let n=this.history;if(!n)return;let o=n.queryCompiles({app:t,limit:31}).filter(c=>c.ms!==e).slice(0,30).map(c=>c.ms);if(o.length<10)return;let i=[...o].sort((c,l)=>c-l),a=i[Math.floor((i.length-1)*.5)];e>2*a&&this.recordEvent({app:t,type:"compile-regression",message:`${(e/1e3).toFixed(1)}s vs p50 ${(a/1e3).toFixed(1)}s`})}watchTaskLogs(t,e,n){let s=this.watchTasks.get(`${t}::${e}`);if(!s)return null;let o=s.logs;return n?o.slice(-n):[...o]}waitFor(t,e,n){return new Promise(s=>{let o=Date.now(),i=this.entries.get(t),a=()=>{if(!i)return!0;let p=i.state;return e==="serving"&&p.status==="serving"||e==="healthy"&&p.status==="serving"&&p.health==="healthy"||e==="stopped"&&p.status==="stopped"||e==="error"&&p.status==="error"},c=p=>{this.off("change",l),clearTimeout(d);let g=i?.state;s({name:t,status:g?.status??"unknown",health:g?.health??"unknown",timedOut:p,waitedMs:Date.now()-o})},l=()=>{a()&&c(!1)};if(a()){s({name:t,status:i.state.status,health:i.state.health,timedOut:!1,waitedMs:0});return}let d=setTimeout(()=>c(!0),n);this.on("change",l)})}}});import _e from"node:fs";import cr from"node:path";import No from"node:os";function $o(){try{let r=_e.readFileSync(Fe,"utf8"),t=JSON.parse(r);if(t&&typeof t=="object"&&t.errors&&typeof t.errors=="object")return{errors:t.errors}}catch{}return{errors:{}}}function Do(r){Le=r,!Ie&&(Ie=setTimeout(()=>{Ie=null;let t=Le;if(Le=null,!!t)try{_e.mkdirSync(cr.dirname(Fe),{recursive:!0}),_e.writeFileSync(Fe,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: cursor write failed: ${e.message}
|
|
42
|
+
`)}},500))}var Fe,Ie,Le,te,ur=R(()=>{"use strict";Fe=cr.join(No.homedir(),".daimon","cursors.json");Ie=null,Le=null;te=class{data=$o();getErrorCursor(t,e){return this.data.errors[`${t}:${e}`]??0}setErrorCursor(t,e,n){this.data.errors[`${t}:${e}`]=n,Do(this.data)}}});import pr from"node:fs";import Mo from"node:os";import dr from"node:path";function Io(r){let t={};for(let[e,n]of Object.entries(r))typeof n=="string"&&(t[e]=jo.test(e)?"***":n);return t}function Be(r,t){let e=r.summary(t);if(!e)return null;let n=r.getState(t),s=r.getApp(t),o=r.getConfig(),i=o.overrides?.[t]??{},a={...process.env,...s.env??{},...n.sessionOverrides?.env??{}},c=r.getHistory(),l=c?c.queryEvents({app:t,limit:50}):[];return{takenAt:new Date().toISOString(),summary:e,logs:n.logBuffer.slice(-500).map(d=>({ts:d.ts,line:d.line})),errors:[...n.errors.entries()].map(([d,p])=>({hash:d,message:p.message,count:p.count,firstSeen:p.firstSeen,lastSeen:p.lastSeen})),env:Io(a),configSlice:{command:n.sessionOverrides?.command??i.command??s.command,port:n.sessionOverrides?.port??i.port??null,workspaceRoot:s.workspaceRoot,workspaceType:s.workspaceType,tags:s.tags,depends:o.depends?.[t]??[],envFiles:o.envFiles?.[t]??[]},events:l}}function fr(r,t){let e=Be(r,t);if(!e)return null;let n=dr.join(Mo.homedir(),".daimon","snapshots");pr.mkdirSync(n,{recursive:!0});let s=e.takenAt.replace(/[:.]/g,"-"),o=dr.join(n,`${t}-${s}.json`);return pr.writeFileSync(o,JSON.stringify(e,null,2)),{path:o,payload:e}}var jo,mr=R(()=>{"use strict";jo=/key|secret|token|password|api[-_]?key/i});import ee from"node:fs";import hr from"node:path";function gr(r){let t=0;try{let e=ee.readdirSync(r,{withFileTypes:!0});for(let n of e){let s=hr.join(r,n.name);try{n.isDirectory()?t+=gr(s):n.isFile()&&(t+=ee.statSync(s).size)}catch{}}}catch{}return t}function He(r,t,e){let n=r.getApp(t);if(!n)return null;let s=r.getState(t),o=s?s.status==="serving"||s.status==="compiling"||s.status==="starting":!1,a=[...Lo,...e?_o:[]].map(c=>{let l=hr.join(n.workspaceRoot,c),d=ee.existsSync(l);return{path:l,exists:d,sizeBytes:d?gr(l):0}});return{app:t,workspace:n.workspaceRoot,targets:a,ranOnServing:o}}function yr(r,t,e){let n=He(r,t,e);if(!n)return{error:"unknown app"};if(n.ranOnServing)return{error:"app is currently running; stop it first"};let s=[],o=[];for(let i of n.targets)if(i.exists)try{ee.rmSync(i.path,{recursive:!0,force:!0}),s.push(i.path)}catch(a){o.push({path:i.path,error:a?.message||String(a)})}return{ok:o.length===0,removed:s,failed:o}}var Lo,_o,wr=R(()=>{"use strict";Lo=["dist",".angular/cache","tmp","out-tsc"],_o=["node_modules"]});function $t(r){return r.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}function vr(r){let t=[];t.push("# HELP daimon_up daimon daemon up"),t.push("# TYPE daimon_up gauge"),t.push("daimon_up 1"),t.push("# HELP daimon_app_status app status one-hot"),t.push("# TYPE daimon_app_status gauge");let e=r.list();for(let n of e)for(let s of Fo)t.push(`daimon_app_status{name="${$t(n.name)}",status="${s}"} ${n.status===s?1:0}`);t.push("# HELP daimon_compile_seconds last successful compile duration in seconds"),t.push("# TYPE daimon_compile_seconds gauge");for(let n of e)n.lastCompileMs!=null&&t.push(`daimon_compile_seconds{name="${$t(n.name)}"} ${(n.lastCompileMs/1e3).toFixed(3)}`);t.push("# HELP daimon_error_total cumulative deduped error count"),t.push("# TYPE daimon_error_total counter");for(let n of e)t.push(`daimon_error_total{name="${$t(n.name)}"} ${n.errorCount}`);t.push("# HELP daimon_cpu_percent app CPU percent"),t.push("# TYPE daimon_cpu_percent gauge");for(let n of e)n.cpu!=null&&t.push(`daimon_cpu_percent{name="${$t(n.name)}"} ${n.cpu}`);t.push("# HELP daimon_mem_mb app resident memory MB"),t.push("# TYPE daimon_mem_mb gauge");for(let n of e)n.memMB!=null&&t.push(`daimon_mem_mb{name="${$t(n.name)}"} ${n.memMB}`);return t.join(`
|
|
43
|
+
`)+`
|
|
44
|
+
`}var Fo,br=R(()=>{"use strict";Fo=["stopped","starting","compiling","serving","error"]});import Dt from"node:fs";import Bo from"node:crypto";import Sr from"node:path";function Uo(){return Sr.join(q(),"audit.log")}function Jo(r){try{if(Dt.statSync(r).size>Ho){let e=r+".1";try{Dt.unlinkSync(e)}catch{}Dt.renameSync(r,e)}}catch{}}function kr(r,t,e,n){let s=Uo();Dt.mkdirSync(Sr.dirname(s),{recursive:!0}),Jo(s);let o=JSON.stringify({prev:t,next:e}),i=Bo.createHash("sha1").update(o).digest("hex").slice(0,12),a=`${new Date().toISOString()} ${r} ${i} ${n.join(",")}
|
|
45
|
+
`;try{Dt.appendFileSync(s,a)}catch{}}var Ho,xr=R(()=>{"use strict";rt();Ho=1e6});import ne from"node:fs";import re from"node:path";import{fileURLToPath as Go}from"node:url";function Wo(){let r=[re.resolve(Tr,"templates","presets"),re.resolve(Tr,"..","src","templates","presets")];for(let t of r)if(ne.existsSync(t))return t;return r[0]}function Er(){let r=Wo();if(!ne.existsSync(r))return[];let t=ne.readdirSync(r).filter(n=>n.endsWith(".json")),e=[];for(let n of t)try{let s=ne.readFileSync(re.join(r,n),"utf8");s.charCodeAt(0)===65279&&(s=s.slice(1)),e.push(JSON.parse(s))}catch{}return e}var Tr,Ar=R(()=>{"use strict";Tr=re.dirname(Go(import.meta.url))});import se from"node:fs";import Cr from"node:path";function Pr(){return Cr.join(q(),"state-handoff.json")}function Or(r){let t=[];for(let s of r.names()){let o=r.getState(s);o&&(o.status==="serving"||o.status==="compiling"||o.status==="starting")&&o.port&&t.push({name:s,port:o.port})}let e={ts:Date.now(),apps:t},n=Pr();return se.mkdirSync(Cr.dirname(n),{recursive:!0}),se.writeFileSync(n,JSON.stringify(e)),n}function Rr(r=6e4){let t=Pr();try{let e=se.readFileSync(t,"utf8"),n=JSON.parse(e);return se.unlinkSync(t),!n||typeof n.ts!="number"||Date.now()-n.ts>r?null:n}catch{return null}}var Ue=R(()=>{"use strict";rt()});import qo from"node:http";import Xo from"node:crypto";import We from"node:fs";import Ge from"node:path";import{fileURLToPath as Ko}from"node:url";function zo(){return[Ge.resolve(Nr,"dashboard.html"),Ge.resolve(Nr,"..","src","dashboard.html")].find(t=>We.existsSync(t))??null}function k(r,t,e){let n=JSON.stringify(e);r.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(n)}),r.end(n)}function xt(r){if(!r)return;let t=r.match(/^(\d+)(ms|s|m|h)?$/);if(!t)return;let e=Number(t[1]);switch(t[2]||"ms"){case"ms":return e;case"s":return e*1e3;case"m":return e*60*1e3;case"h":return e*60*60*1e3}}function Vo(r){if(!r)return{};if(/^\d{10,}$/.test(r))return{sinceTs:Number(r)};let t=xt(r);return t!=null?{sinceMs:t}:{}}function Zo(r){let t=JSON.parse(JSON.stringify(r));if(t.apiToken&&(t.apiToken="***"),t.overrides&&typeof t.overrides=="object")for(let e of Object.keys(t.overrides)){let n=t.overrides[e]?.env;if(n&&typeof n=="object")for(let s of Object.keys(n))Qo.test(s)&&(n[s]="***")}return t}function Je(r){if(!r)return"";try{let t=We.readFileSync(r);return Xo.createHash("sha1").update(t).digest("hex")}catch{return""}}function $r(r,t,e={}){let n=new te,s=qo.createServer(async(o,i)=>{try{let a=new URL(o.url||"/","http://127.0.0.1"),c=o.method||"GET",l=a.pathname.replace(/\/$/,"").split("/").filter(Boolean),d=()=>{let m=(e.getConfig?e.getConfig():null)?.apiToken??null;if(!m)return!0;let y=o.headers.authorization;return typeof y=="string"&&y.toLowerCase().startsWith("bearer ")&&y.slice(7).trim()===m?!0:(k(i,401,{error:"unauthorized"}),!1)};if(c==="POST"&&a.pathname==="/api/shutdown"){if(!d())return;k(i,200,{ok:!0}),e.onShutdown&&setImmediate(()=>{try{e.onShutdown()}catch{}});return}if(a.pathname==="/api/config"&&e.getConfig){if(c==="GET"){let u=e.getConfig(),m=Je(e.configPath);i.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:m}),i.end(JSON.stringify({etag:m,config:Zo(u)}));return}if(c==="PATCH"&&e.patchConfig){if(!d())return;let u=o.headers["if-match"]?.trim(),m=Je(e.configPath);if(!u||u!==m){k(i,412,{error:"etag mismatch",current:m});return}let y={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(O=>{let I=[];o.on("data",S=>I.push(S)),o.on("end",()=>{try{y=JSON.parse(Buffer.concat(I).toString("utf8"))}catch{}O()})});let f=e.patchConfig(y);if(!f.ok){k(i,400,{error:f.error});return}let b=Je(e.configPath);try{let O=o.socket.remoteAddress||"127.0.0.1";kr(O,y,y,f.applied)}catch{}i.writeHead(200,{"content-type":"application/json; charset=utf-8",etag:b}),i.end(JSON.stringify({etag:b,applied:f.applied,addedApps:f.addedApps,removedApps:f.removedApps,restartRequired:f.restartRequired}));return}k(i,405,{error:"method not allowed"});return}if(a.pathname==="/api/presets"&&c==="GET"){k(i,200,Er());return}if(a.pathname==="/api/snapshot-state"&&c==="POST"){if(!d())return;let u=Or(r);k(i,200,{ok:!0,path:u});return}if(a.pathname==="/api/config/reload"&&c==="POST"&&e.reloadConfig){if(!d())return;try{let u=await e.reloadConfig();k(i,200,u)}catch(u){k(i,400,{error:u?.message||String(u)})}return}if(c==="GET"&&a.pathname==="/metrics"&&e.metricsEnabled){let u=vr(r);i.writeHead(200,{"content-type":"text/plain; version=0.0.4","content-length":Buffer.byteLength(u)}),i.end(u);return}if(c!=="GET"&&a.pathname.startsWith("/api/")&&a.pathname!=="/api/shutdown"&&a.pathname!=="/api/config"&&a.pathname!=="/api/config/reload"&&!d())return;if(c==="GET"&&a.pathname==="/"){let u=zo();if(!u){i.writeHead(404).end("dashboard not found");return}let m=We.readFileSync(u);i.writeHead(200,{"content-type":"text/html; charset=utf-8","content-length":m.length}),i.end(m);return}if(l[0]==="api"&&l[1]==="events"&&l.length===2){if(c!=="GET"){k(i,405,{error:"method not allowed"});return}let u=xt(a.searchParams.get("since")),m=a.searchParams.get("app")||void 0,y=r.events({sinceMs:u,app:m}),f=r.getHistory();if(f&&u&&y.length<500){let b=Date.now()-u,O=f.queryEvents({app:m,since:b,limit:1e3}),I=new Set(y.map(S=>`${S.ts}|${S.app}|${S.type}|${S.from??""}|${S.to??""}|${S.message??""}`));for(let S of O){let L=`${S.ts}|${S.app}|${S.type}|${S.from_state??""}|${S.to_state??""}|${S.message??""}`;I.has(L)||y.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})}y.sort((S,L)=>S.ts-L.ts)}k(i,200,y);return}if(l[0]==="api"&&l[1]==="session"){if(l[2]==="record"&&c==="POST"){let u=a.searchParams.get("action")||"toggle";if(u==="start"||u==="toggle"&&!r.sessionRecorder.isRecording()){let m=r.sessionRecorder.start();k(i,200,{recording:!0,path:m.path});return}if(u==="stop"||u==="toggle"&&r.sessionRecorder.isRecording()){let m=r.sessionRecorder.stop();k(i,200,{recording:!1,path:m.path});return}k(i,400,{error:"invalid action"});return}if(l[2]==="status"&&c==="GET"){k(i,200,{recording:r.sessionRecorder.isRecording()});return}k(i,404,{error:"not found"});return}if(l[0]==="api"&&l[1]==="history"){if(c!=="GET"){k(i,405,{error:"method not allowed"});return}let u=r.getHistory();if(!u){k(i,200,[]);return}let m=l[2],y=a.searchParams.get("app")||void 0,f=a.searchParams.get("since"),b=a.searchParams.get("until"),O=a.searchParams.get("limit"),I=f?/^\d{10,}$/.test(f)?Number(f):Date.now()-(xt(f)??0):void 0,S=b?/^\d{10,}$/.test(b)?Number(b):Date.now()-(xt(b)??0):void 0,L=O?Number(O):void 0;if(m==="events"){k(i,200,u.queryEvents({app:y,since:I,until:S,type:a.searchParams.get("type")||void 0,limit:L}));return}if(m==="compile-times"){k(i,200,u.queryCompiles({app:y,since:I,until:S,limit:L}));return}if(m==="tasks"){k(i,200,u.queryTasks({app:y,task:a.searchParams.get("task")||void 0,since:I,limit:L}));return}if(m==="summary"&&l.length>=4){let G=decodeURIComponent(l[3]);k(i,200,u.summary(G));return}if(m==="why"&&l.length>=4){let G=decodeURIComponent(l[3]);k(i,200,u.why(G));return}k(i,404,{error:"not found"});return}if(l[0]!=="api"||l[1]!=="apps"){k(i,404,{error:"not found"});return}if(l.length===2){if(c!=="GET"){k(i,405,{error:"method not allowed"});return}k(i,200,r.list());return}let p=decodeURIComponent(l[2]),g=l[3],w=l[4];if(!g){if(c!=="GET"){k(i,405,{error:"method not allowed"});return}let u=r.summary(p);if(!u){k(i,404,{error:"unknown app"});return}k(i,200,u);return}if(g==="errors"&&w==="since-last"&&c==="GET"){let u=a.searchParams.get("client")||"default",m=n.getErrorCursor(u,p),y=r.errorsSince(p,m);if(y==null){k(i,404,{error:"unknown app"});return}let f=y.reduce((b,O)=>Math.max(b,O.lastSeen),m);f>m&&n.setErrorCursor(u,p,f),k(i,200,y);return}if(g==="errors"&&!w&&c==="GET"){let u=a.searchParams.get("since");if(u){let{sinceMs:y,sinceTs:f}=Vo(u),b=f??(y!=null?Date.now()-y:0),O=r.errorsSince(p,b);if(O==null){k(i,404,{error:"unknown app"});return}k(i,200,O);return}let m=r.errors(p);if(m==null){k(i,404,{error:"unknown app"});return}k(i,200,m);return}if(g==="logs"&&l[4]==="stream"&&c==="GET"){if(!r.summary(p)){k(i,404,{error:"unknown app"});return}i.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"});let u=r.logs(p,{tail:50})??[];for(let I of u)i.write(`data: ${JSON.stringify({ts:Date.now(),line:I})}
|
|
46
|
+
|
|
47
|
+
`);let m=[],y=0,f=()=>{for(;m.length&&i.write(m.shift()););},b=I=>{I.name===p&&(m.length>=200&&(y++,m.shift()),m.push(`data: ${JSON.stringify({ts:I.ts,line:I.line})}
|
|
48
|
+
|
|
49
|
+
`),f())};r.on("log",b);let O=setInterval(()=>i.write(`: ping
|
|
50
|
+
|
|
51
|
+
`),3e4);o.on("close",()=>{r.off("log",b),clearInterval(O)});return}if(g==="logs"&&c==="GET"){let u=a.searchParams.get("tail"),m=a.searchParams.get("since"),y=r.logs(p,{tail:u?Number(u):void 0,sinceMs:xt(m)});if(y==null){k(i,404,{error:"unknown app"});return}k(i,200,{lines:y});return}if(g==="wait"&&c==="GET"){if(!r.summary(p)){k(i,404,{error:"unknown app"});return}let u=(a.searchParams.get("until")||"serving").toLowerCase();if(!["serving","healthy","stopped","error"].includes(u)){k(i,400,{error:"until must be one of serving|healthy|stopped|error"});return}let m=a.searchParams.get("timeout"),y=m?Number(m):120;(!Number.isFinite(y)||y<=0)&&(y=120),y=Math.min(y,600);let f=await r.waitFor(p,u,y*1e3);k(i,200,f);return}if(g==="start"&&c==="POST"){if(a.searchParams.get("withDeps")==="1"){let y=await r.startWithDeps(p);k(i,y.ok?200:400,y);return}let m=await r.start(p);k(i,m.ok?200:400,m);return}if(g==="start-with-deps"&&c==="POST"){let u=await r.startWithDeps(p);k(i,u.ok?200:400,u);return}if(g==="tasks"&&c==="GET"&&!w){let u=r.listTasks(p);if(u==null){k(i,404,{error:"unknown app"});return}k(i,200,{tasks:u,watching:r.listWatchTasks(p)});return}if(g==="run"&&w&&c==="POST"){let u={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(f=>{let b=[];o.on("data",O=>b.push(O)),o.on("end",()=>{try{u=JSON.parse(Buffer.concat(b).toString("utf8"))}catch{}f()})});let m=Array.isArray(u.args)?u.args.map(String):[];if(u.watch){let f=r.startWatchTask(p,w,m);k(i,f.ok?200:400,f);return}let y=await r.runTask(p,w,m);if("error"in y){k(i,404,y);return}k(i,200,y);return}if(g==="run-stop"&&w&&c==="POST"){let u=await r.stopWatchTask(p,w);k(i,200,u);return}if(g==="env"&&c==="GET"){let m=r.getConfig().envFiles?.[p]??[],y=r.getState(p);k(i,200,{candidates:m,active:y?.activeEnvFile??null});return}if(g==="env"&&c==="POST"){let u={};o.headers["content-length"]&&o.headers["content-length"]!=="0"&&await new Promise(y=>{let f=[];o.on("data",b=>f.push(b)),o.on("end",()=>{try{u=JSON.parse(Buffer.concat(f).toString("utf8"))}catch{}y()})}),r.setActiveEnvFile(p,u.use??null);let m=r.getState(p);k(i,200,{active:m?.activeEnvFile??null});return}if(g==="requests"&&c==="GET"){if(!e.requestLog){k(i,200,[]);return}let u=xt(a.searchParams.get("since"));k(i,200,e.requestLog.requests(p,u));return}if(g==="clean"&&c==="POST"){let u=a.searchParams.get("deep")==="1",m=a.searchParams.get("yes")==="1",y=He(r,p,u);if(!y){k(i,404,{error:"unknown app"});return}if(y.ranOnServing){k(i,409,{error:"refusing: app is currently running",plan:y});return}if(!m){k(i,200,{plan:y,hint:"pass --yes to delete"});return}let f=yr(r,p,u);k(i,200,f);return}if(g==="snapshot"&&c==="POST"){if(a.searchParams.get("write")==="1"){let y=fr(r,p);if(!y){k(i,404,{error:"unknown app"});return}k(i,200,{snapshot:y.path});return}let m=Be(r,p);if(!m){k(i,404,{error:"unknown app"});return}k(i,200,m);return}if(g==="stop"&&c==="POST"){let u=await r.stop(p);k(i,u.ok?200:400,u);return}if(g==="restart"&&c==="POST"){let u=await r.restart(p);k(i,u.ok?200:400,u);return}k(i,404,{error:"not found"})}catch(a){k(i,500,{error:a?.message||String(a)})}});return s.listen(t,"127.0.0.1"),s}var Yo,Nr,Qo,Dr=R(()=>{"use strict";ur();mr();wr();br();xr();Ar();Ue();Yo=Ko(import.meta.url),Nr=Ge.dirname(Yo);Qo=/key|secret|token|password|pass/i});import ti from"node:http";import ei from"node:https";function si(r,t,e,n,s){if(t)return[t];let o=r.path||"/",i=r.fallbackHosts&&r.fallbackHosts.length?r.fallbackHosts:["127.0.0.1"];if(r.host||r.scheme){let c=e?qe(e):null,l=r.scheme||c?.protocol?.replace(":","")||"http",d=r.host||c?.hostname||(n?i[0]:"127.0.0.1"),p=n??(c?.port?Number(c.port):null);return[Mr(l,d,p,o)]}if(e){let c=qe(e);if(c)return c.pathname=o,[c.toString()]}let a=[];s&&a.push(s);for(let c of i)a.includes(c)||a.push(c);return a.map(c=>Mr("http",c,n,o))}function qe(r){try{return new URL(r)}catch{return null}}function Mr(r,t,e,n){let s=t.includes(":")&&!t.startsWith("[")?`[${t}]`:t,o=e?`:${e}`:"";return`${r}://${s}${o}${n.startsWith("/")?n:"/"+n}`}var ni,ri,oe,jr=R(()=>{"use strict";ni=1e3,ri=500;oe=class{constructor(t,e,n){this.registry=t;this.cfg=e;this.fullConfig=n;if(e.enabled){t.on("change",this.onChange);for(let s of t.names())this.evaluate(s)}}registry;cfg;fullConfig;timers=new Map;starting=new Map;freshness=new Map;stopped=!1;stop(){this.stopped=!0,this.registry.off("change",this.onChange);for(let t of this.timers.values())clearInterval(t);for(let t of this.starting.values())clearTimeout(t);this.timers.clear(),this.starting.clear()}onChange=()=>{if(!this.stopped)for(let t of this.registry.names())this.evaluate(t)};evaluate(t){let e=this.registry.getState(t);if(e)if(e.status==="serving"){if(this.timers.has(t)||this.starting.has(t))return;this.freshness.set(t,{retried:!1});let n=setTimeout(()=>{this.starting.delete(t),this.probe(t);let s=setInterval(()=>{this.probe(t)},this.cfg.intervalMs);this.timers.set(t,s)},ri);this.starting.set(t,n)}else{let n=this.timers.get(t);n&&(clearInterval(n),this.timers.delete(t));let s=this.starting.get(t);s&&(clearTimeout(s),this.starting.delete(t)),this.freshness.delete(t),e.health!=="unknown"&&(e.status==="stopped"||e.status==="error")&&this.registry.setHealth(t,"unknown")}}async probe(t){let e=this.registry.getState(t);if(!e||e.status!=="serving")return;let n=this.fullConfig?.overrides?.[t]?.url,s=si(this.cfg,n,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 c=await this.tryProbe(a);if(c.ok){let l=qe(a);l&&this.registry.setCachedProbeHost(t,l.hostname.replace(/^\[|\]$/g,"")),this.registry.setResolvedUrl(t,a),this.registry.setLastHealthError(t,null),this.registry.setHealth(t,"healthy");return}o||(o=`${c.error} ${a}`)}let i=this.freshness.get(t);if(i&&!i.retried){i.retried=!0,setTimeout(()=>{this.probe(t)},ni);return}this.registry.setLastHealthError(t,o||"unknown probe failure"),this.registry.setHealth(t,"unhealthy")}tryProbe(t){return new Promise(e=>{let n=!1,s=c=>{n||(n=!0,e(c))},o=t.startsWith("https://"),i=o?ei:ti,a={timeout:this.cfg.timeoutMs};o&&(a.rejectUnauthorized=!!this.cfg.rejectUnauthorized);try{let c=i.get(t,a,l=>{let d=l.statusCode??0;l.resume(),d>=200&&d<500?s({ok:!0}):s({ok:!1,error:`http ${d}`})});c.on("timeout",()=>c.destroy(new Error("timeout"))),c.on("error",l=>s({ok:!1,error:l?.code||l?.message||"error"}))}catch(c){s({ok:!1,error:c?.message||"throw"})}})}}});import oi from"pidusage";var ie,Ir=R(()=>{"use strict";ie=class{constructor(t,e=2e3){this.registry=t;this.intervalMs=e;this.timer=setInterval(()=>this.tick(),e)}registry;intervalMs;timer=null;stopped=!1;stop(){this.stopped=!0,this.timer&&(clearInterval(this.timer),this.timer=null)}async tick(){if(this.stopped)return;let t=[];for(let n of this.registry.names()){let s=this.registry.getState(n);s?.pid&&t.push({name:n,pid:s.pid})}if(!t.length)return;let e=!1;await Promise.all(t.map(async({name:n,pid:s})=>{try{let o=await oi(s),i=this.registry.getState(n);if(!i)return;let a=Math.round(o.cpu*10)/10,c=Math.round(o.memory/(1024*1024));(i.cpu!==a||i.memMB!==c)&&(i.cpu=a,i.memMB=c,e=!0)}catch{let o=this.registry.getState(n);o&&(o.cpu!=null||o.memMB!=null)&&(o.cpu=null,o.memMB=null,e=!0)}})),e&&this.registry.emit("change")}}});var ae,Lr=R(()=>{"use strict";ae=class{constructor(t,e){this.registry=t;this.cfg=e}registry;cfg;timers=new Map;stopped=!1;stop(){this.stopped=!0;for(let t of this.timers.values())clearTimeout(t);this.timers.clear()}onExit(t,e,n,s){if(this.stopped||s||!this.cfg.enabled||e===0&&!n)return;let o=this.registry.getState(t);if(!o)return;let i=Date.now();if((o.restartWindowStart==null||i-o.restartWindowStart>this.cfg.windowMs)&&(o.restartWindowStart=i,o.restartAttempts=0),o.restartAttempts+=1,o.restartAttempts>this.cfg.maxAttempts){o.lastStatusMessage=`auto-restart aborted (${o.restartAttempts-1}/${this.cfg.maxAttempts} within window)`,o.nextRestartAt=null,this.registry.recordEvent({app:t,type:"restart-scheduled",message:o.lastStatusMessage}),this.registry.emit("change");return}let a=Math.min(2**(o.restartAttempts-1)*1e3,3e4);o.nextRestartAt=i+a,o.lastStatusMessage=`restarting in ${Math.round(a/1e3)}s (attempt ${o.restartAttempts}/${this.cfg.maxAttempts})`,this.registry.recordEvent({app:t,type:"restart-scheduled",message:o.lastStatusMessage}),this.registry.emit("change");let c=setTimeout(()=>{this.timers.delete(t);let l=this.registry.getState(t);l&&(l.nextRestartAt=null),this.registry.start(t)},a);this.timers.set(t,c)}onUserStop(t){let e=this.timers.get(t);e&&(clearTimeout(e),this.timers.delete(t));let n=this.registry.getState(t);n&&(n.restartAttempts=0,n.restartWindowStart=null,n.nextRestartAt=null)}}});import Ye from"node:fs";import _r from"node:path";import ii from"node:os";function Fr(){try{let r=Ye.readFileSync(ze,"utf8"),t=JSON.parse(r);if(t&&typeof t=="object"&&t.ports&&typeof t.ports=="object")return{ports:t.ports}}catch{}return{ports:{}}}function Br(r){Ke=r,!Xe&&(Xe=setTimeout(()=>{Xe=null;let t=Ke;if(Ke=null,!!t)try{Ye.mkdirSync(_r.dirname(ze),{recursive:!0}),Ye.writeFileSync(ze,JSON.stringify(t),"utf8")}catch(e){process.stderr.write(`[daimon] warning: state write failed: ${e.message}
|
|
52
|
+
`)}},500))}var ze,Xe,Ke,Hr=R(()=>{"use strict";ze=_r.join(ii.homedir(),".daimon","state.json");Xe=null,Ke=null});import Ur from"node:fs";import ai from"node:os";import Jr from"node:path";import{createRequire as li}from"node:module";var ci,ui,le,Gr=R(()=>{"use strict";ci=li(import.meta.url),ui=6e4,le=class{constructor(t,e){this.registry=t;this.cfg=e;this.logFile=Jr.join(ai.homedir(),".daimon","notifications.log");try{Ur.mkdirSync(Jr.dirname(this.logFile),{recursive:!0})}catch{}if(!e.enabled){this.audit("init","disabled by config");return}try{let n=ci("node-notifier");if(this.notifier=n,process.platform==="win32")try{let s=n.WindowsToaster;s&&(this.toaster=new s({withFallback:!0}))}catch(s){this.audit("init",`WindowsToaster unavailable: ${s?.message||s}`)}this.audit("init",`node-notifier loaded${this.toaster?" (+WindowsToaster fallback)":""}`)}catch(n){this.warnOnce(`node-notifier unavailable: ${n?.message||n}`),this.audit("init",`node-notifier load failed: ${n?.message||n}`);return}t.on("event",this.onEvent)}registry;cfg;notifier=null;toaster=null;lastSent=new Map;warned=!1;logFile;audit(t,e){let n=`${new Date().toISOString()} ${t} ${e}
|
|
53
|
+
`;try{Ur.appendFileSync(this.logFile,n)}catch{}}warnOnce(t){this.warned||(this.warned=!0,process.stderr.write(`[daimon] notifier: ${t}
|
|
54
|
+
`))}stop(){this.registry.off("event",this.onEvent)}onEvent=t=>{this.notifier&&(t.type==="status"&&t.to==="error"&&this.cfg.onError?this.fire(t.app,"error",`${t.app} \u2192 error`,t.message||"app entered error state"):t.type==="health"&&t.to==="unhealthy"&&this.cfg.onUnhealthy?this.fire(t.app,"unhealthy",`${t.app} unhealthy`,"health probe failing"):t.type==="stale"?this.fire(t.app,"stale",`${t.app} stale`,t.message||"no output despite source changes"):t.type==="compile-regression"?this.fire(t.app,"compile-regression",`${t.app} slow compile`,t.message||"compile time regression"):t.type==="bundle-regression"?this.fire(t.app,"bundle-regression",`${t.app} bundle grew`,t.message||"bundle size regression"):t.type==="task-run"&&/exit=[1-9]/.test(t.message||"")&&this.fire(t.app,"task-fail",`${t.app} task failed`,t.message||""))};fire(t,e,n,s){if(!this.notifier)return;let o=`${t}::${e}`,i=this.lastSent.get(o)??0,a=Date.now();if(a-i<ui){this.audit("throttled",`${o}`);return}this.lastSent.set(o,a);let c={title:`daimon: ${n}`,message:s,wait:!1,appID:"daimon"},l=(d,p)=>{d?(this.audit("fail",`${o} :: ${d?.message||d}`),this.warnOnce(`notify failed: ${d?.message||d}`)):this.audit("ok",`${o} :: ${n} :: ${p??"(no response)"}`)};try{this.audit("attempt",`${o} :: ${n}`),(this.toaster??this.notifier).notify(c,l)}catch(d){this.audit("throw",`${o} :: ${d?.message||d}`),this.warnOnce(`notify threw: ${d?.message||d}`)}}}});import Wr from"node:fs";import Ve from"node:path";var pi,di,fi,mi,ce,qr=R(()=>{"use strict";pi=5e3,di=3e4,fi=new Set(["node_modules","dist",".angular",".nx",".git","tmp","out-tsc","coverage"]),mi=new Set([".ts",".tsx",".html",".scss",".css",".js",".jsx",".json"]),ce=class{constructor(t,e){this.registry=t;this.cfg=e;e.enabled&&(this.timer=setInterval(()=>this.tick(),pi),t.on("compile",this.onCompile))}registry;cfg;timer=null;caches=new Map;stop(){this.timer&&clearInterval(this.timer),this.registry.off("compile",this.onCompile)}onCompile=t=>{let e=this.registry.getApp(t.name);e&&this.caches.delete(e.workspaceRoot)};tick(){for(let t of this.registry.names())this.evaluate(t)}evaluate(t){let e=this.registry.getState(t),n=this.registry.getApp(t);if(!e||!n)return;if(e.status!=="serving"){e.stale&&this.registry.setStale(t,!1);return}if(e.startedAt==null)return;let s=e.lastLogTs??e.startedAt,o=Date.now()-s;if(o<this.cfg.silentMs){e.stale&&this.registry.setStale(t,!1);return}let i=e.lastCompileAt??e.startedAt;this.hasSourceChange(n.workspaceRoot,i,e.lastCompileAt)&&(e.stale||(this.registry.setStale(t,!0),this.registry.recordEvent({app:t,type:"stale",message:`no output in ${Math.round(o/1e3)}s despite source changes`})))}hasSourceChange(t,e,n){let s=this.caches.get(t);if(!s||Date.now()-s.ts>di||n!=null&&s.ts<n){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=[],n=(s,o)=>{if(o>8||e.length>4e3)return;let i;try{i=Wr.readdirSync(s,{withFileTypes:!0})}catch{return}for(let a of i)if(!a.name.startsWith(".git")){if(a.isDirectory()){if(fi.has(a.name))continue;n(Ve.join(s,a.name),o+1)}else if(a.isFile()){let c=Ve.extname(a.name);if(!mi.has(c))continue;try{let l=Ve.join(s,a.name),d=Wr.statSync(l);e.push({path:l,mtime:d.mtimeMs})}catch{}}}};return n(t,0),e}}});import Xr from"node:http";var ue,pe,Kr=R(()=>{"use strict";ue=200,pe=class{constructor(t,e){this.registry=t;this.cfg=e;e.enabled&&(t.on("change",this.onChange),this.tick())}registry;cfg;proxies=new Map;stopped=!1;stop(){this.stopped=!0,this.registry.off("change",this.onChange);for(let t of this.proxies.values())try{t.server.close()}catch{}this.proxies.clear()}onChange=()=>{this.stopped||this.tick()};tick(){for(let t of this.registry.names()){let e=this.registry.getState(t);if(!e)continue;let n=this.proxies.has(t);e.status==="serving"&&e.port&&!n?this.startProxy(t,e.port):e.status!=="serving"&&n&&this.stopProxy(t)}}stopProxy(t){let e=this.proxies.get(t);if(e){try{e.server.close()}catch{}this.proxies.delete(t)}}startProxy(t,e){let n=e+this.cfg.portOffset,s=[],o=Xr.createServer((i,a)=>{let c=Date.now(),l={hostname:"127.0.0.1",port:e,method:i.method,path:i.url,headers:{...i.headers,host:`127.0.0.1:${e}`}},d=Xr.request(l,p=>{a.writeHead(p.statusCode||502,p.headers),p.pipe(a);let g=()=>{s.push({ts:Date.now(),method:i.method||"GET",path:i.url||"/",status:p.statusCode||0,durationMs:Date.now()-c}),s.length>ue&&s.splice(0,s.length-ue)};p.on("end",g),p.on("error",g)});d.on("error",()=>{a.writeHead(502).end("upstream error"),s.push({ts:Date.now(),method:i.method||"GET",path:i.url||"/",status:502,durationMs:Date.now()-c}),s.length>ue&&s.splice(0,s.length-ue)}),i.pipe(d)});o.on("error",i=>{i?.code==="EADDRINUSE"&&process.stderr.write(`[daimon] requestLog: port ${n} in use for ${t}; disabling proxy
|
|
55
|
+
`),this.proxies.delete(t)}),o.listen(n,"127.0.0.1",()=>{this.proxies.set(t,{app:t,proxyPort:n,server:o,buffer:s})})}requests(t,e){let n=this.proxies.get(t);if(!n)return[];if(e){let s=Date.now()-e;return n.buffer.filter(o=>o.ts>=s)}return[...n.buffer]}proxyPortFor(t){return this.proxies.get(t)?.proxyPort??null}}});import Qe from"node:fs";function Yr(r){let t=Qe.readFileSync(r,"utf8");t.charCodeAt(0)===65279&&(t=t.slice(1));let e=JSON.parse(t);if(!e||typeof e!="object"||Array.isArray(e))throw new Error("config must be a JSON object");return e}function zr(r,t){if(t===null)return null;if(typeof t!="object"||Array.isArray(t))return t;let e=r&&typeof r=="object"&&!Array.isArray(r)?{...r}:{};for(let[n,s]of Object.entries(t))s===null?delete e[n]:e[n]=zr(e[n],s);return e}function gi(r,t){let e=r+"."+process.pid+".tmp";Qe.writeFileSync(e,t,"utf8"),Qe.renameSync(e,r)}function yi(r,t){let e=new Set;for(let n of Object.keys(t))JSON.stringify(r?.[n])!==JSON.stringify(t[n])&&e.add(n);for(let n of Object.keys(r||{}))n in t||e.add(n);return[...e]}function Vr(r){let t=Yr(r.configPath),e=zr(t,r.patch);if(!e||typeof e!="object")throw new Error("patch produced non-object config");let n=ve(e,r.configPath);return gi(r.configPath,JSON.stringify(e,null,2)+`
|
|
56
|
+
`),{config:n,raw:e,applied:yi(t,e),prevRaw:t}}function Ze(r){let t=Yr(r.configPath),e=ve(t,r.configPath);return wi(r.registry,e)}function wi(r,t){let e=r.getConfig();for(let l of Object.keys(e))e[l]=void 0;Object.assign(e,t);let n=new Set(r.names()),s=mt(e),o=new Set(s.map(l=>l.name)),i=[],a=[];for(let l of s)n.has(l.name)?r.updateDiscoveredApp(l):(r.addDiscoveredApp(l),i.push(l.name));for(let l of n)o.has(l)||a.push(l);let c=[];for(let l of r.names()){let d=r.getState(l);if(d&&(d.status==="serving"||d.status==="compiling")){let p=e.overrides?.[l];if(!p)continue;for(let g of hi)if(g in p){c.push(l);break}}}return{addedApps:i,removedApps:a,restartRequired:c,config:e}}var hi,Qr=R(()=>{"use strict";It();Lt();hi=new Set(["command","port","env","url"])});import Zr from"node:fs";import vi from"node:os";import ts from"node:path";function Si(r){if(!r)return null;let t=JSON.parse(JSON.stringify(r));if(t.apiToken&&(t.apiToken="***"),t.overrides)for(let e of Object.keys(t.overrides)){let n=t.overrides[e]?.env;if(n)for(let s of Object.keys(n))bi.test(s)&&(n[s]="***")}return t}function ki(r,t=200){if(!r)return[];let e=[];for(let n of r.names()){let s=r.getState(n);if(s)for(let o of s.logBuffer)e.push({ts:o.ts,line:`[${n}] ${o.line}`})}return e.sort((n,s)=>n.ts-s.ts),e.slice(-t).map(n=>n.line)}function xi(){let r=ts.join(q(),"crashes");return Zr.mkdirSync(r,{recursive:!0}),r}function Ti(r,t,e){let n=new Date().toISOString().replace(/[:.]/g,"-"),s=ts.join(xi(),`${n}.txt`),o=r,i=[`daimon crash dump @ ${new Date().toISOString()}`,`version: ${W}`,`node: ${process.version}`,`platform: ${process.platform} ${vi.release()}`,`cwd: ${process.cwd()}`,`pid: ${process.pid}`,"","ERROR:",o?.stack||String(o),"","CONFIG (redacted):",JSON.stringify(Si(e),null,2),"","RECENT LOG (last 200 lines across apps):",...ki(t,200)];try{Zr.writeFileSync(s,i.join(`
|
|
57
|
+
`))}catch{}return s}function es(r){let t=e=>{let n=null;try{n=Ti(e,r.getRegistry(),r.getConfig())}catch{}try{process.stderr.write(`[daimon] fatal: ${e?.stack||e}
|
|
58
|
+
`)}catch{}if(n)try{process.stderr.write(`[daimon] crash dump: ${n}
|
|
59
|
+
`)}catch{}process.exit(1)};process.on("uncaughtException",t),process.on("unhandledRejection",t)}var bi,ns=R(()=>{"use strict";Rt();rt();bi=/key|secret|token|password|pass/i});import U,{useEffect as Ei,useMemo as Ai,useState as Tt}from"react";import{Box as Mt,Text as K,useInput as Ci,useStdout as Pi}from"ink";import Oi from"ink-text-input";function tn({registry:r,appName:t,onExit:e}){let{stdout:n}=Pi(),[s,o]=Tt(0),[i,a]=Tt(!1),[c,l]=Tt(""),[d,p]=Tt(""),[g,w]=Tt(0),[u,m]=Tt(0);Ei(()=>{let h=()=>o(P=>P+1);r.on("change",h);let T=setInterval(()=>o(P=>P+1),500);return()=>{r.off("change",h),clearInterval(T)}},[r]);let f=r.getState(t)?.logBuffer.map(h=>h.line)??[],b=(n.rows||30)-4,O=Ai(()=>{if(!d)return[];let h=d.toLowerCase();return f.reduce((T,P,_)=>(P.toLowerCase().includes(h)&&T.push(_),T),[])},[f,d,s]);Ci((h,T)=>{if(i){if(T.escape){a(!1),l("");return}return}if(h==="q"||T.escape){e();return}if(h==="/"){a(!0);return}if(h==="g"){w(Math.max(0,f.length-b));return}if(h==="G"){w(0);return}if(T.pageUp){w(P=>Math.min(Math.max(0,f.length-b),P+b));return}if(T.pageDown){w(P=>Math.max(0,P-b));return}if(T.upArrow){w(P=>Math.min(Math.max(0,f.length-b),P+1));return}if(T.downArrow){w(P=>Math.max(0,P-1));return}if((h==="n"||h==="N")&&O.length){let P=h==="n"?(u+1)%O.length:(u-1+O.length)%O.length;m(P);let _=O[P],Z=f.length-g,E=Z-b;(_<E||_>=Z)&&w(Math.max(0,f.length-_-Math.floor(b/2)));return}});let I=h=>{p(h),a(!1),l(""),m(0)},S=f.length-g,L=Math.max(0,S-b),G=f.slice(L,S),v=(h,T)=>{if(!d)return U.createElement(K,{key:T},U.createElement(K,{dimColor:!0},String(T+1).padStart(5)," "),h);let P=d,_=h.toLowerCase(),Z=P.toLowerCase(),E=[],D=0,$=0;for(;D<h.length;){let J=_.indexOf(Z,D);if(J<0){E.push(U.createElement(K,{key:$++},h.slice(D)));break}J>D&&E.push(U.createElement(K,{key:$++},h.slice(D,J))),E.push(U.createElement(K,{key:$++,backgroundColor:"yellow",color:"black"},h.slice(J,J+P.length))),D=J+P.length}let M=O[u]===T;return U.createElement(K,{key:T},U.createElement(K,{color:M?"cyan":void 0,dimColor:!M},String(T+1).padStart(5)," "),E)};return U.createElement(Mt,{flexDirection:"column"},U.createElement(Mt,null,U.createElement(K,{bold:!0},"full log: ",U.createElement(K,{color:"cyan"},t)),U.createElement(K,{dimColor:!0}," (",f.length," lines",d?`, ${O.length} matches for "${d}"`:"",", scroll=",g,")")),U.createElement(Mt,{flexDirection:"column"},G.length===0?U.createElement(K,{dimColor:!0},"(no log yet)"):G.map((h,T)=>v(h,L+T))),U.createElement(Mt,null,i?U.createElement(Mt,null,U.createElement(K,null,"/"),U.createElement(Oi,{value:c,onChange:l,onSubmit:I})):U.createElement(K,{dimColor:!0},"[/] search [n/N] next/prev [g/G] bottom/top [PgUp/PgDn] [\u2191\u2193] [q/Esc] back")))}var rs=R(()=>{"use strict"});import x,{useEffect as Ri,useState as Q}from"react";import en from"node:fs";import Ni from"node:os";import $i from"node:path";import{Box as Y,Text as A,useApp as Di,useInput as Mi,useStdout as ji}from"ink";import nn from"ink-text-input";import{spawn as rn,spawnSync as Ii}from"node:child_process";function Li(r){try{process.platform==="win32"?rn("cmd",["/c","start","",r],{detached:!0,stdio:"ignore",windowsHide:!0}).unref():process.platform==="darwin"?rn("open",[r],{detached:!0,stdio:"ignore"}).unref():rn("xdg-open",[r],{detached:!0,stdio:"ignore"}).unref()}catch{}}function _i(r){if(r==null)return"";let t=Math.floor(r/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60);return e<60?`${e}m ${t%60}s`:`${Math.floor(e/60)}h ${e%60}m`}function sn({registry:r,apiPort:t,onQuit:e}){let{exit:n}=Di(),{stdout:s}=ji(),[o,i]=Q(r.list()),[a,c]=Q(0),[l,d]=Q(!1),[p,g]=Q(0),[w,u]=Q(!1),[m,y]=Q([]),[f,b]=Q(!1),[O,I]=Q(""),[S,L]=Q(null),[,G]=Q(0);Ri(()=>{let E=()=>i(r.list());r.on("change",E);let D=setInterval(()=>{i(r.list()),G($=>$+1)},1e3);return()=>{r.off("change",E),clearInterval(D)}},[r]),Mi((E,D)=>{if(w)return;if(S){if(D.escape){L(null);return}if(D.tab){let M=S.field==="command"?"port":S.field==="port"?"env":"command";L({...S,field:M});return}return}if(f){if(D.escape){b(!1),I("");return}if(D.return){let M=O.trim();y(M?M.split(/[\s,]+/).filter(Boolean):[]),b(!1),I("");return}if(D.backspace||D.delete){I(M=>M.slice(0,-1));return}E&&!D.ctrl&&I(M=>M+E);return}if(E==="q"||D.ctrl&&E==="c"){e(),n();return}if(o.length===0)return;if(D.upArrow){c(M=>Math.max(0,M-1)),g(0);return}if(D.downArrow){c(M=>Math.min(o.length-1,M+1)),g(0);return}let $=o[a];if($)if(E==="s")r.start($.name);else if(E==="x")r.stop($.name);else if(E==="r")r.restart($.name);else if(E==="L")u(!0);else if(E==="t")b(!0),I(m.join(" "));else if(E==="e"){let M=r.getConfig(),J=r.getApp($.name),tt=r.getState($.name)?.sessionOverrides??null,At=tt?.env??M.overrides?.[$.name]?.env??{},lt=Object.entries(At).map(([ge,ye])=>`${ge}=${ye}`).join(`
|
|
60
|
+
`);L({name:$.name,field:"command",cmd:tt?.command??J?.command??"",port:String(tt?.port??M.overrides?.[$.name]?.port??$.port??""),env:lt})}else if(E==="E"){let J=r.getConfig().envFiles?.[$.name]??[];if(!J.length)return;let tt=r.getState($.name)?.activeEnvFile??null,At=tt?J.indexOf(tt):-1,lt=J[(At+1)%J.length];r.setActiveEnvFile($.name,lt)}else if(E==="V"){let M=process.env.EDITOR||(process.platform==="win32"?"notepad":"vi"),J=$i.join(Ni.tmpdir(),`daimon-${$.name}-${Date.now()}.json`),tt=r.getConfig(),At=r.getApp($.name),lt=r.getState($.name)?.sessionOverrides??null,ge={command:lt?.command??At?.command,port:lt?.port??tt.overrides?.[$.name]?.port??null,env:lt?.env??tt.overrides?.[$.name]?.env??{}};try{en.writeFileSync(J,JSON.stringify(ge,null,2)),Ii(M,[J],{stdio:"inherit",shell:!0});let ye=en.readFileSync(J,"utf8"),ct=JSON.parse(ye);r.setSessionOverride($.name,{command:typeof ct.command=="string"?ct.command:void 0,port:typeof ct.port=="number"?ct.port:void 0,env:ct.env&&typeof ct.env=="object"?ct.env:void 0}),en.unlinkSync(J)}catch{}}else E==="l"?d(M=>!M):E==="o"?$.url&&Li($.url):D.pageUp?g(M=>M+5):D.pageDown&&g(M=>Math.max(0,M-5))});let v=m.length===0?o:o.filter(E=>m.every(D=>E.tags.includes(D))),h=v[Math.min(a,Math.max(0,v.length-1))],T=h?r.getState(h.name):null,P=T?T.logBuffer.slice(Math.max(0,T.logBuffer.length-12-p),T.logBuffer.length-p).map(E=>E.line):[],_=s.columns||100,Z=Math.min(36,Math.floor(_*.4));return w&&h?x.createElement(tn,{registry:r,appName:h.name,onExit:()=>u(!1)}):x.createElement(Y,{flexDirection:"column",width:_},x.createElement(Y,{borderStyle:"round",borderColor:"cyan",paddingX:1},x.createElement(A,{bold:!0,color:"cyan"},"daimon"),x.createElement(A,{dimColor:!0}," \u2022 api http://127.0.0.1:",t)),x.createElement(Y,{flexDirection:"row"},x.createElement(Y,{flexDirection:"column",width:Z,borderStyle:"single",borderColor:"gray",paddingX:1},x.createElement(A,{bold:!0},"Apps ",m.length?x.createElement(A,{dimColor:!0},"(tags: ",m.join(", "),")"):null),v.length===0?x.createElement(A,{dimColor:!0},o.length===0?"(no apps discovered)":"(no apps match tag filter)"):v.map((E,D)=>{let $=D===a;return x.createElement(Y,{key:E.name},x.createElement(A,{color:$?"cyan":void 0},$?"\u25B8 ":" "),x.createElement(A,{color:$?"cyan":void 0},((r.getState(E.name)?.sessionOverrides?"*":"")+E.name).padEnd(20).slice(0,20)),x.createElement(A,{color:ss[E.status]}," ",E.status.padEnd(9)),x.createElement(A,{color:os[E.health]},E.status==="serving"?"\u25CF":" "),x.createElement(A,{dimColor:!0},E.port?` :${E.port}`:""),_>=100&&E.cpu!=null?x.createElement(A,{dimColor:!0}," ",String(E.cpu).padStart(5),"% ",String(E.memMB??0).padStart(5),"MB"):null)})),x.createElement(Y,{flexDirection:"column",flexGrow:1,borderStyle:"single",borderColor:"gray",paddingX:1},h&&T?x.createElement(x.Fragment,null,x.createElement(A,null,"Selected: ",x.createElement(A,{bold:!0},h.name)),x.createElement(A,null,"Status: ",x.createElement(A,{color:ss[h.status]},h.status)," ",x.createElement(A,{color:os[h.health]},"\u25CF")," ",x.createElement(A,{dimColor:!0},h.health)),x.createElement(A,null,"Port: ",h.port??"-"),x.createElement(A,null,"URL: ",h.url??"-"),h.announcedUrl&&h.announcedUrl!==h.url?x.createElement(A,{dimColor:!0},"Announced: ",h.announcedUrl):null,h.lastHealthError?x.createElement(A,{color:"red"},"HealthErr: ",h.lastHealthError):null,h.stale?x.createElement(A,{color:"yellow"},"\u26A0 stale (best guess)"):null,x.createElement(A,null,"Errors: ",x.createElement(A,{color:h.errorCount?"red":void 0},h.errorCount)),x.createElement(A,null,"Uptime: ",_i(h.uptimeMs)),h.cpu!=null||h.memMB!=null?x.createElement(A,null,"Usage: ",h.cpu??"-","% ",h.memMB??"-"," MB"):null,h.compileHistoryMs.length>0?x.createElement(A,null,"Recent compile: ",h.compileHistoryMs.slice(-5).map(E=>(E/1e3).toFixed(1)+"s").join(" \xB7 ")):null,h.bundle?x.createElement(A,null,"Bundle: ",h.bundle.initialKB,"KB initial \xB7 ",h.bundle.lazyKB,"KB lazy",h.bundleRegressionPct!=null&&h.bundleRegressionPct>10?x.createElement(A,{color:"red"}," (+",h.bundleRegressionPct,"% \u26A0)"):null):null,T.lastStatusMessage?x.createElement(A,{dimColor:!0},"Note: ",T.lastStatusMessage):null,x.createElement(A,null,"\u2500\u2500\u2500\u2500 recent log ",l?"(focused)":""," \u2500\u2500\u2500\u2500"),P.length===0?x.createElement(A,{dimColor:!0},"(no output yet)"):P.map((E,D)=>x.createElement(A,{key:D,wrap:"truncate-end"},E))):x.createElement(A,{dimColor:!0},"No app selected."))),x.createElement(Y,{flexDirection:"column"},f?x.createElement(A,null,"tag filter (space-separated, Enter to apply, Esc to cancel): ",x.createElement(A,{color:"cyan"},O)):null,S?x.createElement(Y,{flexDirection:"column",borderStyle:"round",borderColor:"yellow",paddingX:1},x.createElement(A,{bold:!0,color:"yellow"},"edit ",S.name," (session-only) Tab=next field Enter=save Esc=cancel"),x.createElement(Y,null,x.createElement(A,null,S.field==="command"?"> ":" ","command: "),S.field==="command"?x.createElement(nn,{value:S.cmd,onChange:E=>L({...S,cmd:E}),onSubmit:()=>L({...S,field:"port"})}):x.createElement(A,{dimColor:!0},S.cmd)),x.createElement(Y,null,x.createElement(A,null,S.field==="port"?"> ":" ","port: "),S.field==="port"?x.createElement(nn,{value:S.port,onChange:E=>L({...S,port:E}),onSubmit:()=>L({...S,field:"env"})}):x.createElement(A,{dimColor:!0},S.port)),x.createElement(Y,null,x.createElement(A,null,S.field==="env"?"> ":" ","env (k=v;): "),S.field==="env"?x.createElement(nn,{value:S.env.replace(/\n/g,";"),onChange:E=>L({...S,env:E.replace(/;/g,`
|
|
61
|
+
`)}),onSubmit:()=>{let E=Number(S.port),D={};for(let $ of S.env.split(/\n/)){let M=$.match(/^\s*([^=]+)=(.*)$/);M&&(D[M[1].trim()]=M[2])}r.setSessionOverride(S.name,{command:S.cmd||void 0,port:Number.isFinite(E)&&E>0?E:void 0,env:Object.keys(D).length?D:void 0}),L(null)}}):x.createElement(A,{dimColor:!0},S.env))):null,x.createElement(A,{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")))}var ss,os,is=R(()=>{"use strict";rs();ss={stopped:"gray",starting:"yellow",compiling:"yellow",serving:"green",error:"red"},os={healthy:"green",unhealthy:"red",unknown:"gray"}});var ls={};Ct(ls,{startInProcess:()=>as});import Fi from"react";import{render as Bi}from"ink";import{pathToFileURL as Hi}from"node:url";async function as(r={}){let t=null,e=null;es({getRegistry:()=>t,getConfig:()=>e});let n;try{n=ft()}catch(v){process.stderr.write(`[daimon] config error: ${v.message}
|
|
62
|
+
`),process.exit(1)}if(n.kind==="stub-created"){let v=be();process.stdout.write(`[daimon] no config found. Created stub at:
|
|
63
|
+
${n.path}
|
|
64
|
+
`),process.stdout.write(`[daimon] Edit it to add "searchRoots" pointing at your Nx/Angular workspace, then run again.
|
|
65
|
+
`),process.stdout.write(`[daimon] (Local override path: ${v.local})
|
|
66
|
+
`),process.exit(0)}let{config:s,path:o}=n;if(process.stdout.write(`[daimon] config: ${o}
|
|
67
|
+
`),s.depends&&Object.keys(s.depends).length){let v=_t(s.depends);v&&(process.stderr.write(`[daimon] config error: depends graph has a cycle: ${v.join(" -> ")}
|
|
68
|
+
`),process.exit(1))}let i=mt(s);i.length===0&&process.stdout.write(`[daimon] no serveable projects discovered in: ${s.searchRoots.join(", ")||"(none)"}
|
|
69
|
+
`);let a=Fr(),c=new ht(s.portRange,{initial:a.ports,onChange:v=>Br({ports:v})}),l=new Zt(s,i,c);t=l,e=s;let d=new yt(s.history);l.setHistory(d);let p=new oe(l,s.healthProbe,s),g=new ie(l),w=new ae(l,s.autoRestart),u=new le(l,s.notifications),m=new ce(l,s.staleDetect),y=new pe(l,s.requestLog);l.on("childExit",({name:v,code:h,signal:T,stopping:P})=>w.onExit(v,h,T,P)),l.on("userStop",({name:v})=>w.onUserStop(v));let f=Rr();if(f&&f.apps.length){process.stdout.write(`[daimon] state-handoff: restoring ${f.apps.map(v=>v.name).join(", ")}
|
|
70
|
+
`);for(let v of f.apps)c.pin(v.name,v.port);for(let v of f.apps)l.names().includes(v.name)&&l.start(v.name)}if(s.autoStart&&s.autoStart.length){let v=new Set(l.names());for(let h of s.autoStart){if(!v.has(h)){process.stderr.write(`[daimon] warning: autoStart references unknown app "${h}"
|
|
71
|
+
`);continue}s.depends&&s.depends[h]&&s.depends[h].length?l.startWithDeps(h):l.start(h)}}let b=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):s.apiPort,O=!!r.headless||!!s.headless||process.argv.includes("--headless"),I=!1,S=async()=>{if(!I){I=!0;try{p.stop()}catch{}try{g.stop()}catch{}try{w.stop()}catch{}try{u.stop()}catch{}try{m.stop()}catch{}try{y.stop()}catch{}try{d.close()}catch{}try{await l.stopAll(3e3)}catch{}try{L.close()}catch{}try{bt()}catch{}process.exit(0)}},L=$r(l,b,{metricsEnabled:s.metrics.enabled,requestLog:y,onShutdown:()=>{S()},configPath:o,getConfig:()=>l.getConfig(),patchConfig:v=>{try{let h=Vr({configPath:o,patch:v}),T=Ze({configPath:o,registry:l});return{ok:!0,applied:h.applied,addedApps:T.addedApps,removedApps:T.removedApps,restartRequired:T.restartRequired}}catch(h){return{ok:!1,error:h?.message||String(h)}}},reloadConfig:async()=>{let v=Ze({configPath:o,registry:l});return{ok:!0,addedApps:v.addedApps,removedApps:v.removedApps,restartRequired:v.restartRequired}}});process.stdout.write(`[daimon] api: http://127.0.0.1:${b}
|
|
72
|
+
`);try{Cn(Pn(b,O))}catch(v){process.stderr.write(`[daimon] warning: could not write daemon.lock: ${v?.message||v}
|
|
73
|
+
`)}if(process.on("SIGINT",()=>{S()}),process.on("SIGTERM",()=>{S()}),process.on("beforeExit",()=>{S()}),O){process.stdout.write(`[daimon] headless mode \u2014 TUI suppressed. Dashboard: http://127.0.0.1:${b}
|
|
74
|
+
`);let v="",h=setInterval(()=>{let T=l.list().map(_=>({name:_.name,status:_.status,health:_.health,port:_.port})),P=JSON.stringify(T);P!==v&&(process.stderr.write(P+`
|
|
75
|
+
`),v=P)},6e4);await new Promise(()=>{}),clearInterval(h);return}await Bi(Fi.createElement(sn,{registry:l,apiPort:b,onQuit:()=>{S()}})).waitUntilExit(),await S()}var Ui,cs=R(()=>{"use strict";It();Lt();lr();Bt();Dr();jr();Ir();Lr();Hr();xe();Ft();Gr();qr();Kr();rt();Qr();ns();Ue();is();Ui=(()=>{try{return import.meta.url===Hi(process.argv[1]||"").href}catch{return!1}})();Ui&&as().catch(r=>{process.stderr.write(`[daimon] fatal: ${r?.stack||r}
|
|
76
|
+
`),process.exit(1)})});var ds={};Ct(ds,{attachToDaemon:()=>ea});import j,{useEffect as us,useState as it}from"react";import on from"node:fs";import ps from"node:path";import Ji from"node:os";import{Box as Et,render as Gi,Text as B,useApp as Wi,useInput as qi,useStdout as Xi}from"ink";import Ki from"ink-text-input";function Vi(r){if(r==null)return"";let t=Math.floor(r/1e3);if(t<60)return`${t}s`;let e=Math.floor(t/60);return e<60?`${e}m ${t%60}s`:`${Math.floor(e/60)}h ${e%60}m`}function an(r){return ps.join(Ji.homedir(),".daimon",`attach-token.${r}`)}function Qi(r){try{return on.readFileSync(an(r),"utf8").trim()||null}catch{return null}}function Zi(r,t){try{on.mkdirSync(ps.dirname(an(r)),{recursive:!0}),on.writeFileSync(an(r),t,"utf8")}catch{}}function ta({port:r,onExit:t}){let{exit:e}=Wi(),{stdout:n}=Xi(),[s,o]=it([]),[i,a]=it(0),[c,l]=it(!1),[d,p]=it([]),[g,w]=it(null),[u,m]=it(()=>Qi(r)),[y,f]=it(!1),[b,O]=it(""),I=`http://127.0.0.1:${r}`;async function S(v,h={}){try{let T={...h.headers||{}};u&&(T.authorization=`Bearer ${u}`);let P=await fetch(I+v,{...h,headers:T}),_=await P.text(),Z=_;try{Z=JSON.parse(_)}catch{}return{status:P.status,body:Z}}catch(T){return{status:0,body:{error:T?.message||String(T)}}}}if(us(()=>{let v=!1,h=async()=>{let P=await S("/api/apps");if(!v){if(P.status===0){w(P.body?.error||"daemon unreachable");return}if(P.status===401){f(!0);return}w(null),o(Array.isArray(P.body)?P.body:[])}};h();let T=setInterval(h,1e3);return()=>{v=!0,clearInterval(T)}},[u]),us(()=>{if(!c){p([]);return}let v=!1,h=s[i];if(!h)return;let T=async()=>{let _=await S(`/api/apps/${encodeURIComponent(h.name)}/logs?tail=12`);v||Array.isArray(_.body?.lines)&&p(_.body.lines)};T();let P=setInterval(T,1e3);return()=>{v=!0,clearInterval(P)}},[c,i,s.length,u]),qi((v,h)=>{if(y){if(h.escape){f(!1);return}return}if(v==="q"||h.ctrl&&v==="c"){t(),e();return}if(h.upArrow)a(T=>Math.max(0,T-1));else if(h.downArrow)a(T=>Math.min(Math.max(0,s.length-1),T+1));else if(h.return||v===" ")l(T=>!T);else if(v==="s"||v==="x"||v==="r"){let T=s[i];if(!T)return;let P=v==="s"?"start":v==="x"?"stop":"restart";S(`/api/apps/${encodeURIComponent(T.name)}/${P}`,{method:"POST"})}}),y)return j.createElement(Et,{flexDirection:"column",paddingX:1},j.createElement(B,{color:"yellow"},"daemon requires a bearer token. Enter token (Esc to cancel):"),j.createElement(Ki,{value:b,onChange:O,mask:"*",onSubmit:()=>{let v=b.trim();v&&(m(v),Zi(r,v)),O(""),f(!1)}}));let L=n.columns||100,G=s[i];return j.createElement(Et,{flexDirection:"column",width:L},j.createElement(Et,{borderStyle:"round",borderColor:"cyan",paddingX:1},j.createElement(B,{bold:!0,color:"cyan"},"daimon attach"),j.createElement(B,{dimColor:!0}," \u2022 http://127.0.0.1:",r," \u2022 HTTP-client TUI (q detaches, daemon keeps running)")),g?j.createElement(B,{color:"red"},g):null,j.createElement(Et,{flexDirection:"column",borderStyle:"single",borderColor:"gray",paddingX:1},j.createElement(B,{bold:!0},"Apps (",s.length,")"),s.length===0?j.createElement(B,{dimColor:!0},"(no apps)"):s.map((v,h)=>{let T=h===i;return j.createElement(Et,{key:v.name},j.createElement(B,{color:T?"cyan":void 0},T?"\u25B8 ":" "),j.createElement(B,{color:T?"cyan":void 0},v.name.padEnd(20).slice(0,20)),j.createElement(B,{color:Yi[v.status]}," ",v.status.padEnd(9)),j.createElement(B,{color:zi[v.health]},v.status==="serving"?"\u25CF":" "),j.createElement(B,{dimColor:!0},v.port?` :${v.port}`:""),j.createElement(B,{dimColor:!0}," errs=",v.errorCount," up=",Vi(v.uptimeMs)))})),G?j.createElement(Et,{flexDirection:"column",borderStyle:"single",borderColor:"gray",paddingX:1},j.createElement(B,null,"Selected: ",j.createElement(B,{bold:!0},G.name)),j.createElement(B,null,"URL: ",G.url??"-"),G.lastHealthError?j.createElement(B,{color:"red"},"HealthErr: ",G.lastHealthError):null,j.createElement(B,{dimColor:!0},"\u2500\u2500\u2500\u2500 recent log (Enter/Space toggles) \u2500\u2500\u2500\u2500"),c?d.length===0?j.createElement(B,{dimColor:!0},"(loading\u2026)"):d.map((v,h)=>j.createElement(B,{key:h,wrap:"truncate-end"},v)):j.createElement(B,{dimColor:!0},"(press Enter to fetch logs)")):null,j.createElement(B,{dimColor:!0},"[s] start [x] stop [r] restart [Enter] toggle log [q] detach (daemon keeps running)"))}async function ea(r){let t,e=new Promise(s=>{t=s});await Gi(j.createElement(ta,{port:r,onExit:()=>t()})).waitUntilExit(),await e}var Yi,zi,fs=R(()=>{"use strict";Yi={stopped:"gray",starting:"yellow",compiling:"yellow",serving:"green",error:"red"},zi={healthy:"green",unhealthy:"red",unknown:"gray"}});var ys={};Ct(ys,{buildServiceArtifact:()=>gs,installServiceArtifact:()=>ra});import ms from"node:fs";import hs from"node:os";import at from"node:path";import{fileURLToPath as na}from"node:url";function de(){return process.execPath}function fe(){let r=at.dirname(na(import.meta.url));return at.join(r,"main.js")}function gs(){let r=process.platform;if(r==="win32"){let n=`<?xml version="1.0" encoding="UTF-8"?>
|
|
77
|
+
<!-- generated by daimon daemon install-service -->
|
|
78
|
+
<service>
|
|
79
|
+
<id>daimon</id>
|
|
80
|
+
<name>daimon daemon</name>
|
|
81
|
+
<description>Local Angular/Nx/Vite dev server manager (daimon headless daemon)</description>
|
|
82
|
+
<executable>${de()}</executable>
|
|
83
|
+
<arguments>"${fe()}" --headless</arguments>
|
|
84
|
+
<log mode="rotate"/>
|
|
85
|
+
<onfailure action="restart" delay="10 sec"/>
|
|
86
|
+
</service>
|
|
87
|
+
`,s=at.join(q(),"daimon-daemon.xml");return{platform:r,path:s,body:n,installCmd:`nssm install daimon "${de()}" "${fe()}" --headless`}}if(r==="darwin"){let n=`<?xml version="1.0" encoding="UTF-8"?>
|
|
88
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
89
|
+
<plist version="1.0">
|
|
90
|
+
<dict>
|
|
91
|
+
<key>Label</key><string>dev.daimon</string>
|
|
92
|
+
<key>ProgramArguments</key>
|
|
93
|
+
<array>
|
|
94
|
+
<string>${de()}</string>
|
|
95
|
+
<string>${fe()}</string>
|
|
96
|
+
<string>--headless</string>
|
|
97
|
+
</array>
|
|
98
|
+
<key>RunAtLoad</key><true/>
|
|
99
|
+
<key>KeepAlive</key><true/>
|
|
100
|
+
<key>StandardOutPath</key><string>${at.join(q(),"service.out.log")}</string>
|
|
101
|
+
<key>StandardErrorPath</key><string>${at.join(q(),"service.err.log")}</string>
|
|
102
|
+
</dict>
|
|
103
|
+
</plist>
|
|
104
|
+
`,s=at.join(hs.homedir(),"Library","LaunchAgents","dev.daimon.plist");return{platform:r,path:s,body:n,installCmd:`launchctl load ${s}`}}let t=`[Unit]
|
|
105
|
+
Description=daimon daemon (local dev-server manager)
|
|
106
|
+
After=network.target
|
|
107
|
+
|
|
108
|
+
[Service]
|
|
109
|
+
ExecStart=${de()} ${fe()} --headless
|
|
110
|
+
Restart=on-failure
|
|
111
|
+
RestartSec=10
|
|
112
|
+
|
|
113
|
+
[Install]
|
|
114
|
+
WantedBy=default.target
|
|
115
|
+
`,e=at.join(hs.homedir(),".config","systemd","user","daimon.service");return{platform:r,path:e,body:t,installCmd:"systemctl --user enable daimon && systemctl --user start daimon"}}function ra(){let r=gs();return ms.mkdirSync(at.dirname(r.path),{recursive:!0}),ms.writeFileSync(r.path,r.body,"utf8"),{path:r.path,installCmd:r.installCmd,platform:r.platform}}var ws=R(()=>{"use strict";rt()});var vs={};Ct(vs,{runInit:()=>la});import me from"node:fs";import sa from"node:os";import he from"node:path";import oa from"node:readline";function dt(r,t){return new Promise(e=>r.question(t,n=>e(n.trim())))}function aa(r){let t=[];for(let e of ia)me.existsSync(he.join(r,e))&&t.push(e);return t}async function la(r={}){let t=r.cwd??process.cwd(),e=oa.createInterface({input:process.stdin,output:process.stdout});try{let n=aa(t),s=[];if(n.length&&(process.stdout.write(`[daimon init] detected in ${t}: ${n.join(", ")}
|
|
116
|
+
`),(await dt(e,"Add this folder as a searchRoot? [Y/n] ")||"y").toLowerCase().startsWith("y"))){let f=await dt(e,"Optional label for this workspace (blank = none): ");s.push(f?{path:t,label:f}:t)}let o=await dt(e,"Additional searchRoots (comma-separated absolute paths, blank to skip): ");if(o)for(let y of o.split(",").map(f=>f.trim()).filter(Boolean))s.push(y);let a=(await dt(e,"Port range [4200-4299]: ")||"4200-4299").match(/^(\d+)\s*[-,\s]\s*(\d+)$/),c=a?[Number(a[1]),Number(a[2])]:[4200,4299],l=await dt(e,"apiPort [4999]: ")||"4999",d=Number(l)||4999,g=(await dt(e,"Write to (1) ./daimon.config.json or (2) ~/.daimon/config.json? [1] ")||"1").trim()==="2"?he.join(sa.homedir(),".daimon","config.json"):he.join(t,"daimon.config.json");if(me.existsSync(g)&&!r.force)throw new Error(`refusing to overwrite ${g} (pass --force to overwrite)`);let w={searchRoots:s,portRange:c,apiPort:d};me.mkdirSync(he.dirname(g),{recursive:!0}),me.writeFileSync(g,JSON.stringify(w,null,2)+`
|
|
117
|
+
`,"utf8"),process.stdout.write(`[daimon init] wrote ${g}
|
|
118
|
+
`);let m=(await dt(e,"Install Claude Code integration? [Y/n] ")||"y").toLowerCase().startsWith("y");return{path:g,installClaude:m,config:w}}finally{e.close()}}var ia,bs=R(()=>{"use strict";ia=["nx.json","angular.json","vite.config.ts","vite.config.js","vite.config.mjs",".storybook"]});It();Lt();Ft();Bt();xe();import ut from"node:fs";import wt from"node:path";async function bn(r,t){let e=[],n=new Set(t.map(l=>l.name));for(let l of r.searchRoots){let d=typeof l=="string"?l:l.path,p=wt.resolve(d);if(!ut.existsSync(p)){e.push({name:`searchRoot exists: ${p}`,ok:!1,detail:"not found"});continue}let g=ut.existsSync(wt.join(p,"nx.json"))||ut.existsSync(wt.join(p,"angular.json"))||ut.existsSync(wt.join(p,".storybook"))||["ts","js","mjs","cjs"].some(w=>ut.existsSync(wt.join(p,`vite.config.${w}`)));e.push({name:`searchRoot has marker: ${p}`,ok:g,detail:g?void 0:"no nx.json/angular.json/vite.config.*/.storybook"})}for(let[l,d]of Object.entries(r.overrides??{})){let p=n.has(l),g=!!d.command,w=p||g;e.push({name:`override "${l}"`,ok:w,detail:w?void 0:"unknown app and no command override"})}let s=Object.entries(r.overrides??{}).filter(([,l])=>typeof l.port=="number").map(([l,d])=>({name:l,port:d.port})),o=new Map;for(let l of s)o.has(l.port)?e.push({name:`port pin ${l.port}`,ok:!1,detail:`collision: ${o.get(l.port)} and ${l.name}`}):o.set(l.port,l.name);s.length&&!e.some(l=>l.name.startsWith("port pin"))&&e.push({name:"pinned ports",ok:!0});for(let l of r.autoStart??[])e.push({name:`autoStart "${l}"`,ok:n.has(l),detail:n.has(l)?void 0:"unknown app"});for(let[l,d]of Object.entries(r.profiles??{}))for(let p of d)e.push({name:`profile "${l}" entry "${p}"`,ok:n.has(p),detail:n.has(p)?void 0:"unknown app"});if(r.depends&&Object.keys(r.depends).length){for(let[d,p]of Object.entries(r.depends))for(let g of p)n.has(g)||e.push({name:`depends "${d}" -> "${g}"`,ok:!1,detail:"unknown app"});let l=_t(r.depends);l?e.push({name:"depends DAG",ok:!1,detail:`cycle: ${l.join(" -> ")}`}):e.push({name:"depends DAG",ok:!0})}let i=new Set(t.map(l=>l.workspaceRoot));for(let l of i){let d=wt.join(l,"node_modules");e.push({name:`node_modules: ${l}`,ok:ut.existsSync(d),detail:ut.existsSync(d)?void 0:"missing"})}let a=await gt(r.apiPort);if(e.push({name:`apiPort ${r.apiPort}`,ok:a,detail:a?void 0:"in use (may be held by us)"}),r.history.enabled){let l=!1,d;try{let p=new yt(r.history);l=p.quickCheck(),p.close(),l||(d="quick_check failed")}catch(p){d=p?.message||String(p)}e.push({name:"history db",ok:l,detail:d})}return{ok:e.every(l=>l.ok),checks:e}}Ee();Ae();rt();Rt();var ot=[{name:"list",args:"[--tag <name>] [--workspace <label>]",summary:"List apps with current status, port, health.",example:"daimon list",needsDaemon:!0},{name:"status",args:"<name>",summary:"Get the current status of one app.",example:"daimon status web-admin",needsDaemon:!0},{name:"errors",args:"<name> [--since 2m] [--since-last] [--client <id>] [--structured]",summary:"Get deduplicated errors for an app.",example:"daimon errors web-admin --since 5m",needsDaemon:!0},{name:"events",args:"[--since 1h] [--app <name>]",summary:"Get the event log.",example:"daimon events --since 1h",needsDaemon:!0},{name:"wait",args:"<name> [--until serving|healthy|stopped|error] [--timeout 60s]",summary:"Block until app reaches the given state.",example:"daimon wait web-admin --until healthy",needsDaemon:!0},{name:"logs",args:"<name> [--tail N] [--since 30s]",summary:"Recent log lines for an app.",example:"daimon logs web-admin --tail 100",needsDaemon:!0},{name:"start",args:"<name> [--with-deps]",summary:"Start an app.",example:"daimon start web-admin",needsDaemon:!0},{name:"stop",args:"<name>",summary:"Stop an app.",example:"daimon stop web-admin",needsDaemon:!0},{name:"restart",args:"<name>",summary:"Restart an app.",example:"daimon restart web-admin",needsDaemon:!0},{name:"up",args:"[<profile>]",summary:"Start a profile (or autoStart). Waits for each to reach serving.",example:"daimon up fullstack",needsDaemon:!0},{name:"down",args:"[<profile>]",summary:"Stop a profile (or all apps).",example:"daimon down",needsDaemon:!0},{name:"history",args:"<name>",summary:"Summary metrics (uptime%, restarts, compile p50/p95, top errors).",example:"daimon history web-admin",needsDaemon:!0},{name:"why",args:"<name>",summary:"Last status transition + 5 preceding events.",example:"daimon why web-admin",needsDaemon:!0},{name:"tasks",args:"<name>",summary:"List discovered non-serve tasks.",example:"daimon tasks web-admin",needsDaemon:!0},{name:"run",args:"<name> <task> [--watch] [-- args...]",summary:"Run a discovered task.",example:"daimon run web-admin test",needsDaemon:!0},{name:"snapshot",args:"<name>",summary:"Write a snapshot of app state to ~/.daimon/snapshots.",example:"daimon snapshot web-admin",needsDaemon:!0},{name:"env",args:"<name> [--use <file>]",summary:"List or set the active env file for an app.",example:"daimon env web-admin --use .env.staging",needsDaemon:!0},{name:"clean",args:"<name> [--deep] [--yes]",summary:"Remove build artifacts for an app.",example:"daimon clean web-admin --yes",needsDaemon:!0},{name:"record",args:"",summary:"Toggle session recording.",example:"daimon record",needsDaemon:!0},{name:"replay",args:"<session.jsonl> [--speed N]",summary:"Replay a recorded session.",example:"daimon replay session.jsonl",needsDaemon:!0},{name:"doctor",args:"",summary:"Sanity-check the current config and environment.",example:"daimon doctor",needsDaemon:!1},{name:"free-port",args:"<port> [--force]",summary:"Diagnose / free a port.",example:"daimon free-port 4200 --force",needsDaemon:!1},{name:"daemon",args:"start|stop|status|restart|attach|install-service [--detach] [--headless]",summary:"Manage the daimon daemon.",example:"daimon daemon status",needsDaemon:!1},{name:"claude",args:"install|update|uninstall|status [--skill] [--commands] [--agent] [--all] [--dir <path>] [--yes]",summary:"Install/update Claude Code integration artifacts.",example:"daimon claude install --all",needsDaemon:!1},{name:"init",args:"[--force]",summary:"Interactively create a daimon config in cwd.",example:"daimon init",needsDaemon:!1}];function On(r){return ot.find(t=>t.name===r)}function Rn(){let r=Math.max(...ot.map(t=>t.name.length));return ot.map(t=>`${t.name.padEnd(r)} ${t.summary}`).join(`
|
|
119
|
+
`)}function Nn(){return"usage: daimon <"+ot.map(r=>r.name).join("|")+">"}Rt();import X from"node:fs";import Gs from"node:os";import F from"node:path";import{fileURLToPath as Ws}from"node:url";rt();var $n=F.dirname(Ws(import.meta.url)),De=["status","start","stop","restart","errors","logs","up","doctor","why","wait"];function Kt(){return F.join(Gs.homedir(),".claude")}function St(r){return F.join(r,"daimon.installed.json")}function qs(){let r=[F.resolve($n,"templates","claude"),F.resolve($n,"..","src","templates","claude")];for(let t of r)if(X.existsSync(t))return t;throw new Error("claude templates directory not found")}function Re(r){return X.readFileSync(F.join(qs(),r),"utf8")}function Ne(r,t){let e=new Date().toISOString();return r.replace(/\{\{daimon_version\}\}/g,W).replace(/\{\{api_port\}\}/g,String(t)).replace(/\{\{generated_at\}\}/g,e).replace(/\{\{commands_table\}\}/g,Rn())}function Xt(r,t){X.mkdirSync(F.dirname(r),{recursive:!0}),X.writeFileSync(r,t,"utf8")}function kt(r){try{let t=X.readFileSync(St(r),"utf8");return t.charCodeAt(0)===65279&&(t=t.slice(1)),JSON.parse(t)}catch{return null}}function Dn(r,t){Xt(St(r),JSON.stringify(t,null,2)+`
|
|
120
|
+
`)}function Yt(r){let t=[],e=kt(r.dir)??{"daimon-version":W,"installed-at":new Date().toISOString()};if(e["daimon-version"]=W,e["installed-at"]=new Date().toISOString(),r.skill){let n=F.join("skills","daimon","SKILL.md");Xt(F.join(r.dir,n),Ne(Re("skill.md.tmpl"),r.apiPort)),e.skill={path:n.replace(/\\/g,"/")},t.push(n)}if(r.commands){let n=[];for(let s of De){let o=F.join("commands",`daimon-${s}.md`);Xt(F.join(r.dir,o),Ne(Re(F.join("commands",`${s}.md.tmpl`)),r.apiPort)),n.push(s),t.push(o)}e.commands=n}if(r.agent){let n=F.join("agents","daimon-runner.md");Xt(F.join(r.dir,n),Ne(Re("agent.md.tmpl"),r.apiPort)),e.agent={path:n.replace(/\\/g,"/")},t.push(n)}return Dn(r.dir,e),{installed:t,manifestPath:St(r.dir)}}function Mn(r){let t=[],e=kt(r.dir);if(!e)return{removed:t,manifestPath:null};let n=r.selection.all;if((n||r.selection.skill)&&e.skill){let s=F.join(r.dir,e.skill.path);try{X.rmSync(s,{force:!0}),t.push(e.skill.path)}catch{}try{X.rmdirSync(F.dirname(s))}catch{}e.skill=null}if((n||r.selection.commands)&&e.commands){for(let s of e.commands){let o=F.join("commands",`daimon-${s}.md`);try{X.rmSync(F.join(r.dir,o),{force:!0}),t.push(o)}catch{}}e.commands=[]}if((n||r.selection.agent)&&e.agent){try{X.rmSync(F.join(r.dir,e.agent.path),{force:!0}),t.push(e.agent.path)}catch{}e.agent=null}if(!e.skill&&(!e.commands||e.commands.length===0)&&!e.agent){try{X.unlinkSync(St(r.dir))}catch{}return{removed:t,manifestPath:null}}return Dn(r.dir,e),{removed:t,manifestPath:St(r.dir)}}function jn(r){let t=kt(r);return t?{skill:{installed:!!t.skill,version:t.skill?t["daimon-version"]:null,path:t.skill?.path??null},commands:{installed:!!(t.commands&&t.commands.length),version:t.commands&&t.commands.length?t["daimon-version"]:null,names:t.commands??[]},agent:{installed:!!t.agent,version:t.agent?t["daimon-version"]:null,path:t.agent?.path??null},manifestPath:St(r)}:{skill:{installed:!1,version:null,path:null},commands:{installed:!1,version:null,names:[]},agent:{installed:!1,version:null,path:null},manifestPath:null}}var $e=F.join(q(),".claude-nudge"),Xs=1440*60*1e3;function In(){if(process.env.DAIMON_NO_CLAUDE_NUDGE==="1")return;let r=Kt(),t=kt(r);if(t&&t["daimon-version"]!==W){try{let e=X.statSync($e);if(Date.now()-e.mtimeMs<Xs)return}catch{}process.stderr.write(`[daimon] claude integration is from v${t["daimon-version"]} \u2014 run \`daimon claude update\` to refresh
|
|
121
|
+
`);try{X.mkdirSync(F.dirname($e),{recursive:!0}),X.writeFileSync($e,String(Date.now()))}catch{}}}var Ss=Number((process.versions.node||"0").split(".")[0]);Ss&&Ss<20&&(process.stderr.write(`daimon requires Node >= 20
|
|
122
|
+
`),process.exit(1));var ks=!1;function C(r,t=1){process.stderr.write(r.endsWith(`
|
|
123
|
+
`)?r:r+`
|
|
124
|
+
`),process.exit(t)}function N(r){process.stdout.write(JSON.stringify(r)+`
|
|
125
|
+
`)}function un(){if(process.env.DAIMON_PORT){let t=Number(process.env.DAIMON_PORT);if(Number.isFinite(t)&&t>0)return t}let r=nt();if(r)return r.apiPort;try{let t=ft();if(t.kind==="loaded")return t.config.apiPort}catch{}return 4999}async function ca(){try{let r=ft();if(r.kind==="loaded")return{config:r.config}}catch{}return{config:{}}}function xs(){return`http://127.0.0.1:${un()}`}async function Ts(){if(!(ks||process.env.DAIMON_NO_SPAWN==="1")&&!nt())try{let r=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0;await Wt({port:Number.isFinite(r)&&r>0?r:void 0})}catch{}}function jt(){let r=process.env.DAIMON_TOKEN;return r?{authorization:`Bearer ${r}`}:{}}async function H(r,t="GET"){try{let e=await fetch(xs()+r,{method:t,headers:jt()}),n=await e.text(),s=n;try{s=JSON.parse(n)}catch{}return{status:e.status,body:s}}catch{C(JSON.stringify({error:"daimon is not running \u2014 start it with: daimon daemon start --detach"}))}}async function ln(r,t,e){try{let n=await fetch(xs()+r,{method:t,headers:{"content-type":"application/json",...jt()},body:JSON.stringify(e)}),s=await n.text(),o=s;try{o=JSON.parse(s)}catch{}return{status:n.status,body:o}}catch{C(JSON.stringify({error:"daimon is not running \u2014 start it with: daimon daemon start --detach"}))}}function cn(r){let t={tags:[],positional:[],passthrough:[]},e=!1;for(let n=0;n<r.length;n++){let s=r[n];if(e){t.passthrough.push(s);continue}if(s==="--"){e=!0;continue}s==="--tail"?t.tail=Number(r[++n]):s==="--since"?t.since=r[++n]:s==="--since-last"?t.sinceLast=!0:s==="--client"?t.client=r[++n]:s==="--structured"?t.structured=!0:s==="--until"?t.until=r[++n]:s==="--timeout"?t.timeout=r[++n]:s==="--app"?t.app=r[++n]:s==="--tag"?t.tags.push(r[++n]):s==="--with-deps"?t.withDeps=!0:s==="--watch"?t.watch=!0:s==="--force"?t.force=!0:s==="--yes"?t.yes=!0:s==="--deep"?t.deep=!0:s==="--use"?t.use=r[++n]:s==="--speed"?t.speed=Number(r[++n]):s==="--task"?t.task=r[++n]:s==="--headless"?t.headless=!0:s==="--detach"?t.detach=!0:s==="--workspace"?t.workspace=r[++n]:t.positional.push(s)}return t}function ua(r){let t=r.match(/^(\d+)(ms|s|m|h)?$/);if(!t)return null;let e=Number(t[1]);switch(t[2]||"s"){case"ms":return e/1e3;case"s":return e;case"m":return e*60;case"h":return e*60*60}return null}function pa(){let r=Math.max(...ot.map(e=>e.name.length)),t=[`daimon v${W}`,"usage: daimon <command> [args]",""];for(let e of ot)t.push(` ${e.name.padEnd(r)} ${e.summary}`);t.push(""),t.push("Flags: --no-spawn (skip auto-spawn), DAIMON_PORT=N (target a non-default daemon), DAIMON_NO_SPAWN=1"),process.stdout.write(t.join(`
|
|
126
|
+
`)+`
|
|
127
|
+
`)}function da(r){let t={},e=[];for(let n=0;n<r.length;n++){let s=r[n];s==="--skill"?t.skill=!0:s==="--commands"?t.commands=!0:s==="--agent"?t.agent=!0:s==="--all"?t.all=!0:s==="--dir"?t.dir=r[++n]:s==="--yes"?t.yes=!0:e.push(s)}return{positional:e,flags:t}}async function fa(r){let t=r[0];t||C(JSON.stringify({error:"usage: daimon claude <install|update|uninstall|status> [--skill] [--commands] [--agent] [--all] [--dir <path>] [--yes]"}));let{flags:e}=da(r.slice(1)),n=e.dir??Kt(),s=un();if(t==="status"){N(jn(n));return}if(t==="install"){let o,i=e.skill||e.commands||e.agent||e.all;if(e.all||e.yes||!i&&!process.stdin.isTTY)o={skill:!0,commands:!0,agent:!0};else if(i)o={skill:!!e.skill,commands:!!e.commands,agent:!!e.agent};else{let{promptClaudeInstall:c}=await Promise.resolve().then(()=>(Bn(),Fn)),l=await c();if(!l){N({cancelled:!0});return}o=l}let a=Yt({...o,dir:n,apiPort:s});N({installed:a.installed,manifest:a.manifestPath,version:W});return}if(t==="update"){let o=kt(n);o||C(JSON.stringify({error:"no manifest at "+n+" \u2014 run `daimon claude install` first"}));let i={skill:!!o.skill,commands:!!(o.commands&&o.commands.length),agent:!!o.agent},a=Yt({...i,dir:n,apiPort:s});N({updated:a.installed,manifest:a.manifestPath,version:W});return}if(t==="uninstall"){e.skill||e.commands||e.agent||e.all||C(JSON.stringify({error:"usage: daimon claude uninstall [--all|--skill|--commands|--agent]"}));let i=Mn({dir:n,selection:{all:e.all,skill:e.skill,commands:e.commands,agent:e.agent}});N({removed:i.removed,manifest:i.manifestPath});return}C(JSON.stringify({error:`unknown claude subcommand: ${t}`}))}async function ma(r){let t=r[0],e=cn(r.slice(1));switch(t){case"status":{let n=nt();if(!n){N({running:!1});return}let s=Date.now()-n.startedAt;N({running:!0,pid:n.pid,port:n.apiPort,uptime:s,version:n.version,headless:n.headless});return}case"start":{if(e.detach){let s=nt();if(s){N({ok:!0,alreadyRunning:!0,pid:s.pid,port:s.apiPort});return}try{let o=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0,i=await Wt({port:Number.isFinite(o)&&o>0?o:void 0});N({ok:!0,pid:i.pid,port:i.apiPort})}catch(o){C(JSON.stringify({error:o?.message||String(o)}))}return}let{startInProcess:n}=await Promise.resolve().then(()=>(cs(),ls));await n({headless:!!e.headless});return}case"stop":{let n=nt();if(!n){N({ok:!0,wasRunning:!1});return}try{await fetch(`http://127.0.0.1:${n.apiPort}/api/shutdown`,{method:"POST",headers:jt()})}catch{}if(await qt(n.pid,5e3))bt(),N({ok:!0,wasRunning:!0});else{try{process.kill(n.pid,"SIGTERM")}catch{}await qt(n.pid,2e3),bt(),N({ok:!0,wasRunning:!0,forced:!0})}return}case"restart":{let n=nt();if(n){try{await fetch(`http://127.0.0.1:${n.apiPort}/api/snapshot-state`,{method:"POST",headers:jt()})}catch{}try{await fetch(`http://127.0.0.1:${n.apiPort}/api/shutdown`,{method:"POST",headers:jt()})}catch{}await qt(n.pid,5e3),bt()}let s=process.env.DAIMON_PORT?Number(process.env.DAIMON_PORT):void 0,o=await Wt({port:Number.isFinite(s)&&s>0?s:void 0});N({ok:!0,pid:o.pid,port:o.apiPort,handoff:!0});return}case"attach":{await Ts();let n=nt();n||C(JSON.stringify({error:"no daemon running and auto-spawn failed"}));let{attachToDaemon:s}=await Promise.resolve().then(()=>(fs(),ds));await s(n.apiPort);return}case"install-service":{let{installServiceArtifact:n}=await Promise.resolve().then(()=>(ws(),ys)),s=n();N({platform:s.platform,artifact:s.path,installCmd:s.installCmd});return}default:C(JSON.stringify({error:"usage: daimon daemon <start|stop|status|restart|attach|install-service> [--detach] [--headless]"}))}}async function ha(){let r=process.argv.slice(2).filter(o=>o==="--no-spawn"?(ks=!0,!1):!0),[t,...e]=r;try{In()}catch{}if(!t||t==="--help"||t==="-h"||t==="help"){pa();return}if(t==="--version"||t==="-v"){N({version:W});return}if(t==="daemon"){await ma(e);return}if(t==="claude"){await fa(e);return}if(t==="init"){let{runInit:o}=await Promise.resolve().then(()=>(bs(),vs)),i=cn(e);try{let a=await o({force:!!i.force});if(N({path:a.path,installClaude:a.installClaude}),a.installClaude){let c=un(),l=Yt({skill:!0,commands:!0,agent:!0,dir:Kt(),apiPort:c});N({claudeInstalled:l.installed})}}catch(a){C(JSON.stringify({error:a?.message||String(a)}))}return}let n=cn(e);switch(On(t)?.needsDaemon&&await Ts(),t){case"list":{let o=await H("/api/apps"),i=Array.isArray(o.body)?o.body:[];n.tags.length&&(i=i.filter(a=>n.tags.every(c=>(a.tags||[]).includes(c)))),n.workspace&&(i=i.filter(a=>a.workspaceLabel===n.workspace)),N(i);return}case"status":case"stop":case"restart":{let o=n.positional[0];o||C(JSON.stringify({error:`usage: daimon ${t} <name>`}));let i=t==="status"?"":"/"+t,a=t==="status"?"GET":"POST",c=await H(`/api/apps/${encodeURIComponent(o)}${i}`,a);c.status===404&&C(JSON.stringify({error:"unknown app"})),N(c.body);return}case"start":{let o=n.positional[0];o||C(JSON.stringify({error:"usage: daimon start <name> [--with-deps]"}));let i=n.withDeps?"?withDeps=1":"",a=await H(`/api/apps/${encodeURIComponent(o)}/start${i}`,"POST");a.status===404&&C(JSON.stringify({error:"unknown app"})),N(a.body);return}case"history":{let o=n.positional[0];o||C(JSON.stringify({error:"usage: daimon history <name>"}));let i=await H(`/api/history/summary/${encodeURIComponent(o)}`);N(i.body);return}case"why":{let o=n.positional[0];o||C(JSON.stringify({error:"usage: daimon why <name>"}));let i=await H(`/api/history/why/${encodeURIComponent(o)}`);N(i.body);return}case"env":{let o=n.positional[0];if(o||C(JSON.stringify({error:"usage: daimon env <name> [--use <file>]"})),n.use){let a=await ln(`/api/apps/${encodeURIComponent(o)}/env`,"POST",{use:n.use});a.status===404&&C(JSON.stringify({error:"unknown app"})),N(a.body);return}let i=await H(`/api/apps/${encodeURIComponent(o)}/env`);i.status===404&&C(JSON.stringify({error:"unknown app"})),N(i.body);return}case"clean":{let o=n.positional[0];o||C(JSON.stringify({error:"usage: daimon clean <name> [--deep] [--yes]"}));let i=new URLSearchParams;n.deep&&i.set("deep","1"),n.yes&&i.set("yes","1");let a=await H(`/api/apps/${encodeURIComponent(o)}/clean${i.toString()?"?"+i.toString():""}`,"POST");a.status===404&&C(JSON.stringify({error:"unknown app"})),a.status===409&&(N(a.body),process.exit(1)),N(a.body);return}case"record":{let o=await H("/api/session/record?action=toggle","POST");N(o.body);return}case"replay":{let o=n.positional[0];o||C(JSON.stringify({error:"usage: daimon replay <session.jsonl> [--speed N]"}));let i=n.speed&&n.speed>0?n.speed:1,a;try{a=En(o)}catch(l){C(JSON.stringify({error:l?.message||String(l)}))}let c=0;for(let l of a){let d=Math.max(0,(l.ts-c)/i);d>0&&await new Promise(p=>setTimeout(p,d)),c=l.ts,l.kind==="run"?await ln(`/api/apps/${encodeURIComponent(l.app)}/run/${encodeURIComponent(l.task||"")}`,"POST",{args:l.args||[]}):await H(`/api/apps/${encodeURIComponent(l.app)}/${l.kind}`,"POST")}N({replayed:a.length,file:o});return}case"doctor":{let o=ft();o.kind!=="loaded"&&C(JSON.stringify({error:"no config loaded"}));let i=[],a=mt(o.config,{warnings:i}),c=await bn(o.config,a);for(let l of i)c.checks.unshift({name:`discovery: ${l}`,ok:!1,detail:l});i.length&&(c.ok=!1),N(c),c.ok||process.exit(1);return}case"free-port":{let o=Number(n.positional[0]);(!Number.isFinite(o)||o<=0)&&C(JSON.stringify({error:"usage: daimon free-port <port> [--force]"}));let i=Ht(o);if(!i){N({port:o,free:!0});return}if(!n.force){N({port:o,free:!1,holder:i});return}i.pid===process.pid&&C(JSON.stringify({error:"refuse to kill daimon itself",holder:i}));let a=await xn(i);N({port:o,killed:a,holder:i}),a||process.exit(1);return}case"snapshot":{let o=n.positional[0];o||C(JSON.stringify({error:"usage: daimon snapshot <name>"}));let i=await H(`/api/apps/${encodeURIComponent(o)}/snapshot?write=1`,"POST");i.status===404&&C(JSON.stringify({error:"unknown app"})),N(i.body);return}case"tasks":{let o=n.positional[0];o||C(JSON.stringify({error:"usage: daimon tasks <name>"}));let i=await H(`/api/apps/${encodeURIComponent(o)}/tasks`);i.status===404&&C(JSON.stringify({error:"unknown app"})),N(i.body);return}case"run":{let o=n.positional[0],i=n.positional[1];(!o||!i)&&C(JSON.stringify({error:"usage: daimon run <name> <task> [--watch] [-- args...]"}));let a={args:n.passthrough,watch:!!n.watch},c=await ln(`/api/apps/${encodeURIComponent(o)}/run/${encodeURIComponent(i)}`,"POST",a);c.status===404&&C(JSON.stringify({error:"unknown app"})),N(c.body),!n.watch&&typeof c.body?.exitCode=="number"&&process.exit(c.body.exitCode===0?0:1);return}case"errors":{let o=n.positional[0];o||C(JSON.stringify({error:"usage: daimon errors <name> [--since 2m] [--since-last] [--client <id>] [--structured]"}));let i=new URLSearchParams,a=`/api/apps/${encodeURIComponent(o)}/errors`;n.sinceLast?(a+="/since-last",n.client&&i.set("client",n.client)):n.since&&i.set("since",n.since);let c=i.toString(),l=await H(a+(c?"?"+c:""));l.status===404&&C(JSON.stringify({error:"unknown app"}));let d=l.body;n.structured&&Array.isArray(d)&&(d=d.map(p=>p.parsed??{message:p.message})),N(d);return}case"events":{let o=new URLSearchParams;n.since&&o.set("since",n.since),n.app&&o.set("app",n.app);let i=o.toString(),a=await H("/api/events"+(i?"?"+i:""));N(a.body);return}case"wait":{let o=n.positional[0];o||C(JSON.stringify({error:"usage: daimon wait <name> [--until serving|healthy|stopped|error] [--timeout 60s]"}));let i=new URLSearchParams;n.until&&i.set("until",n.until);let a=120;if(n.timeout){let l=ua(n.timeout);l==null&&C(JSON.stringify({error:`invalid --timeout: ${n.timeout}`})),a=Math.min(l,600)}i.set("timeout",String(Math.ceil(a)));let c=await H(`/api/apps/${encodeURIComponent(o)}/wait?${i.toString()}`);c.status===404&&C(JSON.stringify({error:"unknown app"})),N(c.body),c.body?.timedOut&&process.exit(2);return}case"up":case"down":{let o=n.positional[0],i=await H("/api/apps"),a=Array.isArray(i.body)?i.body:[],c=(await ca()).config,l;if(!o)l=c.autoStart||[],t==="up"&&l.length===0&&C(JSON.stringify({error:"no autoStart configured and no profile given"})),t==="down"&&l.length===0&&(l=a.map(u=>u.name));else{let u=c.profiles?.[o];u||C(JSON.stringify({error:`unknown profile: ${o}`})),l=u}let d=t==="up"?"start":"stop";if(t==="up"?await Promise.all(l.map(u=>H(`/api/apps/${encodeURIComponent(u)}/start?withDeps=1`,"POST"))):await Promise.all(l.map(u=>H(`/api/apps/${encodeURIComponent(u)}/${d}`,"POST"))),t==="up"){let m=Date.now(),y=()=>Math.max(5,Math.floor((12e4-(Date.now()-m))/1e3));await Promise.all(l.map(f=>H(`/api/apps/${encodeURIComponent(f)}/wait?until=serving&timeout=${y()}`)))}else await Promise.all(l.map(u=>H(`/api/apps/${encodeURIComponent(u)}/wait?until=stopped&timeout=10`)));let p=await H("/api/apps"),w=(Array.isArray(p.body)?p.body:[]).filter(u=>l.includes(u.name)).map(u=>({name:u.name,status:u.status,health:u.health}));N(w);return}case"logs":{let o=n.positional[0];o||C(JSON.stringify({error:"usage: daimon logs <name> [--tail N] [--since 30s]"}));let i=new URLSearchParams;n.tail!=null&&!Number.isNaN(n.tail)&&i.set("tail",String(n.tail)),n.since&&i.set("since",n.since);let a=i.toString(),c=await H(`/api/apps/${encodeURIComponent(o)}/logs${a?"?"+a:""}`);c.status===404&&C(JSON.stringify({error:"unknown app"})),N(c.body);return}default:C(JSON.stringify({error:`unknown command: ${t}. ${Nn()}`}))}}ha().catch(r=>C(JSON.stringify({error:r?.message||String(r)})));
|